Porting U-Boot.1.2.0 to FriendlyARM S3C2440 (2)

Publisher:红尘清梦Latest update time:2020-05-12 Source: eefocusKeywords:U-Boo  S3C2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

8. Add "CONFIG_S3C2440" to the file so that the original s3c2410 code can be compiled in.

(1) Line 454 of the /include/common.h file:

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X) || defined(CONFIG_S3C2440)

(2) Lines 85, 95, 99, 110, 148, and 404 of the /include/s3c24x0.h file:

#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)

(3) Line 33 of the /cpu/arm920t/s3c24x0/interrupts.c file:

#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) || defined (CONFIG_S3C2440)

Line 38: #elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)

(4) Line 22 of the /cpu/arm920t/s3c24x0/serial.c file:

#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) || defined (CONFIG_S3C2440)

Line 26: #elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)

void serial_setbrg (void)

{

         S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);

         int i;

         unsigned int reg = 0;

 

         /* value is calculated so : (int)(PCLK/16./baudrate) -1 */

         reg = get_PCLK() / (16 * gd->baudrate) - 1;

         /* FIFO enable, Tx/Rx FIFO clear */

         uart->UFCON = 0x00;

         uart->UMCON = 0x0;

         /* Normal,No parity,1 stop,8 bit */

         uart->ULCON = 0x3;

......

}

(5) Line 33 of the /cpu/arm920t/s3c24x0/speed.c file:

#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) || defined (CONFIG_S3C2440)

Line 37: #elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)

By the way, modify the source code to match s3c2440:

static ulong get_PLLCLK(int pllreg)
{
   ......

    m = ((r & 0xFF000) >> 12) + 8;
    p = ((r & 0x003F0) >> 4) + 2;
    s = r & 0x3;
//tekkaman
#if defined(CONFIG_S3C2440)
   if (pllreg == MPLL)
    return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));
    else if (pllreg == UPLL)
#endif
//tekkaman
    return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
}

......

/* return FCLK frequency */

ulong get_FCLK(void)

{

    return(get_PLLCLK(MPLL));

}

 

/* return HCLK frequency */

ulong get_HCLK(void)

{

    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();

 

      

              if (clk_power->CLKDIVN & 0x6)   

                            {

                            if ((clk_power->CLKDIVN & 0x6)==2)        return(get_FCLK()/2);

                            if ((clk_power->CLKDIVN & 0x6)==6)        return((clk_power->CAMDIVN & 0x100) ? get_FCLK()/6 : get_FCLK()/3);        

                            if ((clk_power->CLKDIVN & 0x6)==4)        return((clk_power->CAMDIVN & 0x200) ? get_FCLK()/8 : get_FCLK()/4);        

                            return(get_FCLK());

                            }

 

              else       {

                            return(get_FCLK());

                            }

}

......

(6) Line 45 of the /cpu/arm920t/s3c24x0/usb_ohci.c file:

#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

(The i2c file has not been modified because it is not used)

(7) Line 35 of the /rtc/s3c24x0_rtc.c file:

#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

 

Add "defined(CONFIG_tekkaman2440)" to the file so that the original SBC2410X code can be compiled in.

(1) Line 181 of the /cpu/arm920t/s3c24x0/interrupts.c file: 

    defined(CONFIG_VCMA9) || defined(CONFIG_tekkaman2440)

 

9. Add the structure nand_flash_ids in include/linux/mtd/nand_ids.h

static struct nand_flash_dev nand_flash_ids[] = {

......
    {"Samsung KM29N16000",NAND_MFR_SAMSUNG, 0x64, 21, 1, 2, 0x1000, 0},
    {"Samsung K9F1208U0B",  NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},
    {"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0x6b, 22, 0, 2, 0x2000, 0},
......

};

 

 

10. Modify board.c in /lib_arm.

......

#include
#include
#include
#include
#include
#include
#include

 

......

 

static int display_banner (void)
{      

         S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

         gpio->GPBDAT = 0x100;  //tekkamanninja

//After the serial port initialization and console initialization are completed and before the serial port outputs information, LED1, LED2, and LED3 will light up!

    printf ("nn%snn", version_string);
    debug ("U-Boot code: %08lX -> %08lX  BSS: -> %08lXn",
           _armboot_start, _bss_start, _bss_end);
    printf ("U-Boot code: %08lX -> %08lX  BSS: -> %08lXn",    //tekkaman
        _armboot_start, _bss_start, _bss_end);      //tekkaman
#ifdef CONFIG_MODEM_SUPPORT
    debug ("Modem Support enabledn");
#endif
#ifdef CONFIG_USE_IRQ
    debug ("IRQ Stack: %08lxn", IRQ_STACK_START);
    debug ("FIQ Stack: %08lxn", FIQ_STACK_START);
#endif

    return (0);
}

 

......

void start_armboot (void)

{

         init_fnc_t **init_fnc_ptr;

         char *s;

#ifndef CFG_NO_FLASH

         head size;

#endif

#if defined(CONFIG_VFD) || defined(CONFIG_LCD)

         unsigned long addr;

#endif

         S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

......

         gpio->GPBDAT = 0x0;  //tekkamanninja

// Before entering the command prompt, all four LEDs will light up at the same time!

         /* main_loop() can return to retry autoboot, if so just run it again. */

         for (;;) {

                   main_loop ();

         }

 

         /* NOTREACHED - no way out of command loop except booting */

}






11. Modify common/env_nand.c

......
#ifdef CONFIG_INFERNO
#error CONFIG_INFERNO not supported yet
#endif

int nand_legacy_rw (struct nand_chip* nand, int cmd,
        size_t start, size_t len,
        size_t * retlen, u_char * buf);
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, size_t len, int clean);

/* info for NAND chips, defined in drivers/nand/nand.c */
extern nand_info_t nand_info[CFG_MAX_NAND_DEVICE];

......

#else /* ! CFG_ENV_OFFSET_REDUND */
int saveenv(void)
{
    ulong total;
    int ret = 0;

    puts ("Erasing Nand...");
    //if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))

if (nand_legacy_erase(nand_dev_desc + 0, CFG_ENV_OFFSET, CFG_ENV_SIZE, 0))
        return 1;


    puts ("Writing to Nand... ");
    total = CFG_ENV_SIZE;
    //ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);

ret = nand_legacy_rw(nand_dev_desc + 0,

0x00 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE,

&total, (u_char*)env_ptr);


    if (ret || total != CFG_ENV_SIZE)
        return 1;

    puts ("donen");
    return ret;
......
#else /* ! CFG_ENV_OFFSET_REDUND */
/*
 * The legacy NAND code saved the environment in the first NAND device i.e.,
 * nand_dev_desc + 0. This is also the behaviour using the new NAND code.
 */
void env_relocate_spec (void)
{
#if !defined(ENV_IS_EMBEDDED)
    ulong total;
    int ret;

    total = CFG_ENV_SIZE;
    //ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
    ret = nand_legacy_rw(nand_dev_desc + 0, 0x01 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE, &total, (u_char*)env_ptr);

......



12. Add the initialization function for Nand Flash at the end of the /board/tekkaman/tekkaman2440/tekkaman2440.c file (it will be used in the following Nand Flash operations)




u-boot runs to the second stage and enters the start_armboot() function. Among them, the nand_init() function is the initialization function of the nand flash. The Nand_init() function is implemented in two files. Its call is related to the CFG_NAND_LEGACY macro. If this macro is not defined, the system calls nand_init() in drivers/nand/nand.c; otherwise, it calls its own nand_init() function in board/tekkaman/tekkaman2440/tekkaman2440.c. Here I choose the second method.

 

#if (CONFIG_COMMANDS & CFG_CMD_NAND)
typedef enum {
NFCE_LOW,
NFCE_HIGH
} NFCE_STATE;

static inline void NF_Conf(u16 conf)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

nand->NFCONF = conf;
}


static inline void NF_Cont(u16 cont)


{

S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

nand->NFCONT = cont;

}

static inline void NF_Cmd(u8 cmd)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

nand->NFCMD = cmd;
}

static inline void NF_CmdW(u8 cmd)
{
NF_Cmd(cmd);
udelay(1);
}

static inline void NF_Addr(u8 addr)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

nand->NFADDR = addr;
}

static inline void NF_SetCE(NFCE_STATE s)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

switch (s) {
case NFCE_LOW:
nand->NFCONT &= ~(1<<1);
break;

case NFCE_HIGH:
nand->NFCONT |= (1<<1);
break;
}
}

static inline void NF_WaitRB(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

while (!(nand->NFSTAT & (1<<0)));
}

static inline void NF_Write(u8 data)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

nand->NFDATA = data;
}

static inline u8 NF_Read(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

return(nand->NFDATA);
}

static inline void NF_Init_ECC(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

nand->NFCONT |= (1<<4);
}

static inline u32 NF_Read_ECC(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

return(nand->NFECC);
}

#endif


#if (CONFIG_COMMANDS & CFG_CMD_NAND)
extern ulong nand_probe(ulong physadr);


static inline void NF_Reset(void)
{
int i;

NF_SetCE(NFCE_LOW);
NF_Cmd(0xFF); /* reset command */
for(i = 0; i < 10; i++); /* tWB = 100ns. */
NF_WaitRB(); /* wait 200~500us; */
NF_SetCE(NFCE_HIGH);
}


static inline void NF_Init(void)
{
#if 0 /* a little bit too optimistic */
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
#else
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
#endif

       NF_Conf((TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4));

       NF_Cont((1<<6)|(1<<4)|(1<<1)|(1<<0));
/*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
/* 1 1 1 1, 1 xxx, r xxx, r xxx */
/* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */

NF_Reset();
}

void
nand_init(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

NF_Init();
#ifdef DEBUG
printf("NAND flash probing at 0x%.8lXn", (ulong)nand);
#endif
printf ("%4lu MBn", nand_probe((ulong)nand) >> 20);
}
#endif

[1] [2]
Keywords:U-Boo  S3C2440 Reference address:Porting U-Boot.1.2.0 to FriendlyARM S3C2440 (2)

Previous article:Detailed analysis of the s3c2440 startup process
Next article:Friendly Arm Mini2440NORflash bootloader programming details --- personally tested and available

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号