U-boot1.1.6 ported to TQ2440 development board (Part 1)

Publisher:数字梦想Latest update time:2015-11-02 Source: eefocusKeywords:U-boot1  6 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
U-Boot main directory structure

- board target board related files, mainly including SDRAM and FLASH drivers;

- common Common code that is independent of the processor architecture, such as memory size detection and fault detection;

- cpu is files related to the processor. For example, the mpc8xx subdirectory contains files such as serial port, network port, LCD driver and interrupt initialization;

- driver General device driver, such as CFI FLASH driver (currently supports INTEL FLASH better)

-doc U-Boot documentation;

- examples are sample programs that can be run under U-Boot; such as hello_world.c, timer.c;

- include U-Boot header files; especially the configuration header files related to the target board in the configs subdirectory are files that are often modified during the porting process;

- lib_xxx processor architecture related files, such as lib_ppc, lib_arm directories contain files related to PowerPC and ARM architectures respectively;

- net is the file directory related to network functions, such as bootp, nfs, tftp;

- post Power-on self-test file directory. Still needs to be further improved;

- rtc RTC driver;

- tools Tools for creating U-Boot S-RECORD and BIN image files;

 

 

1. Create your own development board file

1. Create your own board directory in the borad folder, copy the files in sbc2410x to this directory as a blueprint to speed up the transplantation process, and modify the makefile file COBJS := tq2440.o flash.o in the board directory (the generation of tq2440.o file must modify the sbc2410x.c file in this directory)

2. Create tq2440.h file in include/configs folder based on sbc2410x.h

3. Modify the makefile file in the uboot root directory, confirm CROSS_COMPLE, the compiler option, and add the make option:

tq2440_config:unconfig

(TAB)@./mkconfig $(@:_config=) arm arm920t tq2440 NULL s3c24x0

in:

arm: CPU architecture (ARCH)

arm920t: CPU type (CPU), which corresponds to the cpu/arm920t subdirectory.

tq2440: development board model (BOARD), corresponding to the board/tq2440 directory.

NULL: developer and/or vender.

s3c24x0: System on chip (SOC).

4. Next, test whether the compilation can pass, execute: make disclean--delete the original compilation result

make tqconfig

After success, Configuring for xxx board..... appears

make – can generate uboot.bin file

 

 

2. Modify the source code

 

1. Modify start.S

 

Modify the following code:

 

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

ldr r0, =pWTCON

mov r1, #0x0

str r1, [r0]

 

 

mov r1, #0xffffffff

ldr r0, =INTMSK

str r1, [r0]

# if defined(CONFIG_S3C2410)

ldr r1, =0x3ff

ldr r0, =INTSUBMSK

str r1, [r0]

# endif

#ifdefined(CONFIG_S3C2440)

ldr r1, =0x7fff

ldr r0, =INTSUBMSK

str r1, [r0]

# endif

 

 

#if0

 

 

ldr r0, =CLKDIVN

mov r1, #3

str r1, [r0]

#endif

#endif

 

#ifndefCONFIG_SKIP_LOWLEVEL_INIT

bl cpu_init_crit

#endif

 

// Bring the stack initialization to the front, because the clock initialization function to be written later will use the stack

 

stack_setup:

ldr r0, _TEXT_BASE

sub r0, r0, #CFG_MALLOC_LEN

sub r0, r0, #CFG_GBL_DATA_SIZE

#ifdefCONFIG_USE_IRQ

sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

#endif

sub sp, r0, #12

// Jump to the clock initialization function

bl clock_init

 

 

#ifndefCONFIG_SKIP_RELOCATE_UBOOT

relocate:

adr r0, _start

ldr r1, _TEXT_BASE

cmp r0, r1

beq stack_setup

 

ldr r2, _armboot_start

ldr r3, _bss_start

sub r2, r3, r2

 

//Shield the original code and rewrite the code transfer function

#if1

bl CopyCode2Ram

#else

add r2, r0, r2

 

copy_loop:

ldmia r0!, {r3-r10}

stmia r1!, {r3-r10}

cmp r0, r2

ble copy_loop

#endif

#endif

 

 

 

Then add in include/configs/tq2440.h

#define CONFIG_S3C2440 1

#define CONFIG_TQ2440 1

And shield the original chip and development board definitions, at the same time, the S3C24X0_GPIO structure in s3c24x0.h should also be rewritten to support 2440, and add

 

S3C24X0_REG32 res9[4];

S3C24X0_REG32 GPJCON;

S3C24X0_REG32 GPJDAT;

S3C24X0_REG32 GPJUP;

This is the definition of GPIO_J port

Add typedef struct {

S3C24X0_REG32 NFCONF;

S3C24X0_REG32 NFCONT;

S3C24X0_REG32 NFCMD;

S3C24X0_REG32 NFADDR;

S3C24X0_REG32 NFDATA;

S3C24X0_REG32 NFMECCD0;

S3C24X0_REG32 NFMECCD1;

S3C24X0_REG32 NFSECCD;

S3C24X0_REG32 NFSTAT;

S3C24X0_REG32 NFESTAT0;

S3C24X0_REG32 NFESTAT1;

S3C24X0_REG32 NFMECC0;

S3C24X0_REG32 NFMECC1;

S3C24X0_REG32 NFSECC;

S3C24X0_REG32 NFSBLK;

S3C24X0_REG32 NFEBLK;

} S3C2440_NAND;

Other structures should also be modified

Modify lowlevel_init.S, modify lines 54, 58, and 126, that is, the external memory controller.

54 #defineB1_BWSCON (DW16)

58 #defineB5_BWSCON (DW8)

126 #defineREFCNT 0x4f4

lowlevel_init.S mainly sets SDRAM configuration

ARM memory controller

Every 4 bits in the bit width and wait control register BWSCON controls a BANK, the highest 4 bits correspond to BANK7, the next 4 bits correspond to BANK6, and so on.

8 memory banks

6 are ROM, SRAM and other types of memory banks

2 can be used as ROM, SRAM, SDRAM and other memory banks

BANK control registers BANKCONx (BANKCON1~5) are used to control the access timing of BANK0~BANK5 external devices. Generally, the default value 0x0700 is sufficient.

BANK control register BANKCONx (BANKCON6~7, among the 8 BANKs, only BANK6 and BANK7 can be connected to SRAM and SDRAM, so BANKCON6~BANKCON7 are a little different from BANKCON0~BANKCON5.

 

Add the boot_init.c file in the board folder and modify the makefile (the boot_init.c file mainly contains nand reading and writing, clock initialization, and code copying functions)

boot_init.c

#include

#include

 

#defineGSTATUS1 (*(volatileunsignedint*)0x560000B0)

#defineBUSY 1

 

#defineNAND_SECTOR_SIZE 512

#defineNAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)

 

#defineNAND_SECTOR_SIZE_LP 2048

#defineNAND_BLOCK_MASK_LP (NAND_SECTOR_SIZE_LP - 1)

 

 

charbLARGEBLOCK; //HJ_add 20090807

charb128MB; //HJ_add 20090807

 

 

 

voidnand_init_ll(void);

intnand_read_ll(unsignedchar*buf, unsignedlongstart_addr, intsize);

intnand_read_ll_lp(unsignedchar*buf, unsignedlongstart_addr, intsize);

 

 

staticvoidnand_reset(void);

staticvoidwait_idle(void);

staticvoidnand_select_chip(void);

staticvoidnand_deselect_chip(void);

staticvoidwrite_cmd(intcmd);

staticvoidwrite_addr(unsignedintaddr);

staticvoidwrite_addr_lp(unsignedintaddr);

staticunsignedcharread_data(void);

intNF_ReadID(void); //HJ_add 20090807

[page]

 

staticvoids3c2440_nand_reset(void);

staticvoids3c2440_wait_idle(void);

staticvoids3c2440_nand_select_chip(void);

staticvoids3c2440_nand_deselect_chip(void);

staticvoids3c2440_write_cmd(intcmd);

staticvoids3c2440_write_addr(unsignedintaddr);

staticvoids3c2440_write_addr_lp(unsignedintaddr);

staticunsignedchars3c2440_read_data(void);

 

 

 

 

staticvoids3c2440_nand_reset(void)

{

s3c2440_nand_select_chip();

s3c2440_write_cmd(0xff); // reset command

s3c2440_wait_idle();

s3c2440_nand_deselect_chip();

}

 

 

staticvoids3c2440_wait_idle(void)

{

you;

S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;

volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFSTAT;

 

while(!(*p & BUSY))

for(i=0; i<10; i++);

}

 

 

staticvoids3c2440_nand_select_chip(void)

{

you;

S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;

 

s3c2440nand->NFCONT&= ~(1<<1);

for(i=0; i<10; i++);

}

 

 

staticvoids3c2440_nand_deselect_chip(void)

{

S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;

 

s3c2440nand->NFCONT|= (1<<1);

}

 

 

staticvoids3c2440_write_cmd(intcmd)

{

S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;

 

volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFCMD;

*p = cmd;

}

 

 

staticvoids3c2440_write_addr(unsignedintaddr)

{

you;

S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;

volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;

 

*p = addr & 0xff;

for(i=0; i<10; i++);

*p = (addr >> 9) & 0xff;

for(i=0; i<10; i++);

*p = (addr >> 17) & 0xff;

for(i=0; i<10; i++);

*p = (addr >> 25) & 0xff;

for(i=0; i<10; i++);

}

 

 

 

staticvoids3c2440_write_addr_lp(unsignedintaddr)

{

you;

S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;

volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;

intcol, page;

 

col = addr & NAND_BLOCK_MASK_LP;

page = addr / NAND_SECTOR_SIZE_LP;

 

*p = col & 0xff;

for(i=0; i<10; i++);

*p = (col >> 8) & 0x0f;

for(i=0; i<10; i++);

*p = page & 0xff;

for(i=0; i<10; i++);

*p = (page >> 8) & 0xff;

for(i=0; i<10; i++);

if(b128MB == 0)

*p = (page >> 16) & 0x03;

for(i=0; i<10; i++);

}

 

 

staticunsignedchars3c2440_read_data(void)

{

S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;

volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFDATA;

return*p;

}

 

 

 

staticvoidnand_reset(void)

{

s3c2440_nand_reset();

}

 

staticvoidwait_idle(void)

{

s3c2440_wait_idle();

}

 

staticvoidnand_select_chip(void)

{

you;

 

s3c2440_nand_select_chip();

 

for(i=0; i<10; i++);

}

 

staticvoidnand_deselect_chip(void)

{

s3c2440_nand_deselect_chip();

}

 

staticvoidwrite_cmd(intcmd)

{

s3c2440_write_cmd(cmd);

}

staticvoidwrite_addr(unsignedintaddr)

{

s3c2440_write_addr(addr);

}

 

staticvoidwrite_addr_lp(unsignedintaddr)

{

s3c2440_write_addr_lp(addr);

}

 

staticunsignedcharread_data(void)

{

returns3c2440_read_data();

}

 

 

voidnand_init_ll(void)

{

S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;

 

#defineTACLS 0

#defineTWRPH0 3

#defineTWRPH1 0

 

//Set timing

s3c2440nand->NFCONF= (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);

// Enable NAND Flash controller, initialize ECC, disable chip select

s3c2440nand->NFCONT= (1<<4)|(1<<1)|(1<<0);

 

// Reset NAND Flash

nand_reset();

}

#if1

intNF_ReadID(void)

{

charpMID;

charpDID;

int nBuff;

char n4thcycle;

you;

S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;

volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;

 

b128MB = 1;

n4thcycle = nBuff = 0;

 

nand_init_ll();

nand_select_chip();

write_cmd(0x90); // read id command

*p=0x00 & 0xff;

for( i = 0; i < 100; i++ );

 

pMID = read_data();

pDID = read_data();

nBuff = read_data();

n4thcycle = read_data();

 

nand_deselect_chip();

 

if(pDID >= 0xA0)

{

b128MB = 0;

}

 

return(pDID);

}

#endif

 

 

intnand_read_ll(unsignedchar*buf, unsignedlongstart_addr, intsize)

{

you, j;

chard;

S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;

volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;

 

 

if((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK))

{

return-1;

}

 

 

nand_select_chip();

 

for(i=start_addr; i < (start_addr + size);)

{

 

if(1){

 

write_cmd(0x50);

 

*p = 5;

for(j=0; j<10; j++);

*p = (i >> 9) & 0xff;

for(j=0; j<10; j++);

*p = (i >> 17) & 0xff;

for(j=0; j<10; j++);

*p = (i >> 25) & 0xff;

for(j=0; j<10; j++);

wait_idle();

 

dat = read_data();

write_cmd(0);

 

 

nand_deselect_chip();

if(that != 0xff)

{

i += 16384; // 1 Block = 512*32= 16384

printf("Bad block at 0x%lx,will be skipped1n",i);

}

 

nand_select_chip();

}

 

write_cmd(0);

 

 

write_addr(i);

wait_idle();

 

for(j=0; j < NAND_SECTOR_SIZE; j++, i++)

{

*buf = read_data();

buf++;

}

}

 

 

nand_deselect_chip();

 

return0;

}

 

 

intnand_read_ll_lp(unsignedchar*buf, unsignedlongstart_addr, intsize)

{

you, j;

chard;

 

S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;

volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;

 

if((start_addr & NAND_BLOCK_MASK_LP) || (size & NAND_BLOCK_MASK_LP))

{

return-1;

}

 

 

nand_select_chip();

 

for(i=start_addr; i < (start_addr + size);)

{

 

if(1){

intcol, page;

 

col = i & NAND_BLOCK_MASK_LP;

page = i / NAND_SECTOR_SIZE_LP;

 

write_cmd(0x00);

 

*p = 5;

for(j=0; j<10; j++);

*p = 8;

for(j=0; j<10; j++);

*p = page & 0xff;

for(j=0; j<10; j++);

*p = (page >> 8) & 0xff;

for(j=0; j<10; j++);

if(b128MB == 0)

*p = (page >> 16) & 0x03;

for(j=0; j<10; j++);

 

write_cmd(0x30);

wait_idle();

 

dat = read_data();

 

 

nand_deselect_chip();

if(that != 0xff)

{

i += 131072; // 1 Block = 2048*64= 131072

 

}

 

 

nand_select_chip();

}

 

write_cmd(0);

 

 

write_addr_lp(i);

write_cmd(0x30);

wait_idle();

 

for(j=0; j < NAND_SECTOR_SIZE_LP; j++, i++)

{

*buf = read_data();

buf++;

}

}

 

 

 

nand_deselect_chip();

 

return0;

}

 

intbBootFrmNORFlash(void)

{

volatileunsignedint*pdw = (volatileunsignedint*)0;

unsignedintdwVal;

 

 

 

dwVal = *pdw;

*pdw = 0x12345678;

if(*pdw != 0x12345678)

{

return1;

}

else

{

*pdw = dwVal;

return0;

}

}

 

intCopyCode2Ram(unsignedlongstart_addr, unsignedchar*buf, intsize)

{

unsignedint*pdwDest;

unsignedint*pdwSrc;

you;

 

 

long*GPBCON=0x56000010;

long*GPBDAT=0x56000014;

long*GPBUP =0x56000018;

 

*GPBCON=0x295551;

*GPBUP=0xff;

*GPBDAT=0x7be;

[page]

 

 

if(bBootFrmNORFlash())

{

pdwDest = (unsignedint*)buf;

pdwSrc = (unsignedint*)start_addr;

 

for(i = 0; i < size / 4; i++)

{

pdwDest[i] = pdwSrc[i];

}

return0;

}

else

{

 

 

nand_init_ll();

 

 

if(NF_ReadID() == 0x76 )

{

nand_read_ll(buf, start_addr, (size + NAND_BLOCK_MASK)&~(NAND_BLOCK_MASK));}

else

{

nand_read_ll_lp(buf, start_addr, (size + NAND_BLOCK_MASK_LP)&~(NAND_BLOCK_MASK_LP));}

return0;

}

 

 

}

 

staticinlinevoiddelay(unsignedlongloops)

{

__asm__volatile("1:n"

"subs %0, %1, #1n"

"bne1b":"=r"(loops):"0"(loops));

}

 

 

 

#defineS3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01)) //HJ 400MHz

#defineS3C2440_MPLL_405MHZ ((0x7f<<12)|(0x02<<4)|(0x01)) //HJ 405MHz

#defineS3C2440_MPLL_440MHZ ((0x66<<12)|(0x01<<4)|(0x01)) //HJ 440MHz

#defineS3C2440_MPLL_480MHZ ((0x98<<12)|(0x02<<4)|(0x01)) //HJ 480MHz

#defineS3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))

#defineS3C2440_MPLL_100MHZ ((0x5c<<12)|(0x01<<4)|(0x03))

 

#defineS3C2440_UPLL_48MHZ ((0x38<<12)|(0x02<<4)|(0x02)) //HJ 100MHz

 

#defineS3C2440_CLKDIV 0x05 //HJ 100MHz

#defineS3C2440_CLKDIV136 0x07 //HJ 133MHz

#defineS3C2440_CLKDIV188 0x04

#defineS3C2440_CAMDIVN188 ((0<<8)|(1<<9))

 

 

#defineS3C2440_MPLL_399MHz ((0x6e<<12)|(0x03<<4)|(0x01))

#defineS3C2440_UPLL_48MHZ_Fin16MHz ((60<<12)|(4<<4)|(2))

 

voidclock_init(void)

{

S3C24X0_CLOCK_POWER*clk_power = (S3C24X0_CLOCK_POWER*)0x4C000000;

 

 

#ifCONFIG_133MHZ_SDRAM

clk_power->CLKDIVN = S3C2440_CLKDIV136; //HJ 1:3:6

#else

clk_power->CLKDIVN= S3C2440_CLKDIV; //HJ 1:4:8

#endif

 

__asm__( "mrc p15, 0, r1, c1, c0, 0n"

"orr r1, r1, #0xc0000000n"

"mcr p15, 0, r1, c1, c0, 0n"

:::"r1"

);

 

 

clk_power->LOCKTIME= 0xFFFFFF;

 

 

clk_power->UPLLCON= S3C2440_UPLL_48MHZ; //fin=12.000MHz

// clk_power->UPLLCON = S3C2440_UPLL_48MHZ_Fin16MHz; //fin=16.934MHz

 

 

delay (4000);

 

 

clk_power->MPLLCON= S3C2440_MPLL_400MHZ; //fin=12.000MHz

// clk_power->MPLLCON = S3C2440_MPLL_405MHZ; //HJ 405MHz

// clk_power->MPLLCON = S3C2440_MPLL_440MHZ; //HJ 440MHz

// clk_power->MPLLCON = S3C2440_MPLL_480MHZ; //HJ 480MHz

// clk_power->MPLLCON = S3C2440_MPLL_399MHz; //fin=16.934MHz

 

delay (8000);

}

 

 

 

Modify the get_HCLK and other functions in cpu/arm920t/s3c24x0/speed.c. First, add DECLARE_GLOBAL_DATA_PTR in front; so that it can use the pointer of the gd_t global data structure

Relationship between FLCK, HCLK and PCLK

S3C2440 has three clocks: FLCK, HCLK and PCLK

FCLK is used by ARM920T, core clock, main frequency.

HCLK is used for AHB bus, which is used by the ARM920T, the memory controller, the interrupt controller, the LCD controller, the DMA and USB host block. That is, the bus clock, including the USB clock.

PCLK is used for APB bus, which is used by the peripherals such as WDT, IIS, I2C, PWM timer, MMC interface, ADC, UART, GPIO, RTC and SPI. That is, the IO interface clock, for example, the serial port clock setting comes from PCLK;

Specific code:

staticulongget_PLLCLK(intpllreg)

{

S3C24X0_CLOCK_POWER* constclk_power = S3C24X0_GetBase_CLOCK_POWER();

ulongr, m, p, s;

 

if(pllreg == MPLL)

r = clk_power->MPLLCON;

elseif(pllreg == UPLL)

r = clk_power->UPLLCON;

else

hang();

 

m = ((r & 0xFF000) >> 12) + 8;

p = ((r & 0x003F0) >> 4) + 2;

s = r & 0x3;

 

if(gd->bd->bi_arch_number== MACH_TYPE_SMDK2410)

return((CONFIG_SYS_CLK_FREQ * m) / (p << s));

else

return((CONFIG_SYS_CLK_FREQ * m *2) / (p << s));

}

 

 

ulongget_FCLK(void)

{

return(get_PLLCLK(MPLL));

}

 

#defineS3C2440_CLKDIVN_PDIVN (1<<0)

#defineS3C2440_CLKDIVN_HDIVN_MASK (3<<1)

#defineS3C2440_CLKDIVN_HDIVN_1 (0<<1)

#defineS3C2440_CLKDIVN_HDIVN_2 (1<<1)

#defineS3C2440_CLKDIVN_HDIVN_4_8 (2<<1)

#defineS3C2440_CLKDIVN_HDIVN_3_6 (3<<1)

#defineS3C2440_CLKDIVN_UCLK (1<<3)

 

#defineS3C2440_CAMDIVN_CAMCLK_MASK (0xf<<0)

#defineS3C2440_CAMDIVN_CAMCLK_SEL (1<<4)

#defineS3C2440_CAMDIVN_HCLK3_HALF (1<<8)

#defineS3C2440_CAMDIVN_HCLK4_HALF (1<<9)

#defineS3C2440_CAMDIVN_DVSEN (1<<12)

 

ulongget_HCLK(void)

{

S3C24X0_CLOCK_POWER* constclk_power = S3C24X0_GetBase_CLOCK_POWER();

unsignedlongclkdiv;

unsignedlongcamdiv;

inthdiv = 1;

 

 

clkdiv = clk_power->CLKDIVN;

camdiv = clk_power->CAMDIVN;

 

 

if(gd->bd->bi_arch_number== MACH_TYPE_SMDK2410)

return((clk_power->CLKDIVN& 0x2) ? get_FCLK()/2 : get_FCLK());

else

{

switch(clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {

caseS3C2440_CLKDIVN_HDIVN_1:

hdiv = 1;

break;

 

caseS3C2440_CLKDIVN_HDIVN_2:

hdiv = 2;

break;

 

caseS3C2440_CLKDIVN_HDIVN_4_8:

hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;

break;

 

caseS3C2440_CLKDIVN_HDIVN_3_6:

hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;

break;

}

 

returnget_FCLK() / hdiv;

}

}

 

 

ulongget_PCLK(void)

{

S3C24X0_CLOCK_POWER* constclk_power = S3C24X0_GetBase_CLOCK_POWER();

unsignedlongclkdiv;

unsignedlongcamdiv;

inthdiv = 1;

 

 

clkdiv = clk_power->CLKDIVN;

camdiv = clk_power->CAMDIVN;

 

 

if(gd->bd->bi_arch_number== MACH_TYPE_SMDK2410)

return((clk_power->CLKDIVN& 0x1) ? get_HCLK()/2 : get_HCLK());

else

{

switch(clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {

caseS3C2440_CLKDIVN_HDIVN_1:

hdiv = 1;

break;

 

caseS3C2440_CLKDIVN_HDIVN_2:

hdiv = 2;

break;

 

caseS3C2440_CLKDIVN_HDIVN_4_8:

hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;

break;

 

caseS3C2440_CLKDIVN_HDIVN_3_6:

hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;

break;

}

 

returnget_FCLK() / hdiv / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);

}

}

Keywords:U-boot1  6 Reference address:U-boot1.1.6 ported to TQ2440 development board (Part 1)

Previous article:Reflection on STM32: Don’t be an irritable embedded engineer
Next article:U-boot1.1.6 ported to TQ2440 development board (Part 2)

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号