×
单片机 > 单片机程序设计 > 详情

U-boot1.1.6移植到TQ2440开发板(上)

发布时间:2020-05-23 发布时间:
|
U-Boot主要目录结构

- board 目标板相关文件,主要包含SDRAM、FLASH驱动;

- common 独立于处理器体系结构的通用代码,如内存大小探测与故障检测;

- cpu 与处理器相关的文件。如mpc8xx子目录下含串口、网口、LCD驱动及中断初始化等文件;

- driver 通用设备驱动,如CFI FLASH驱动(目前对INTEL FLASH支持较好)

- doc U-Boot的说明文档;

- examples可在U-Boot下运行的示例程序;如hello_world.c,timer.c;

- include U-Boot头文件;尤其configs子目录下与目标板相关的配置头文件是移植过程中经常要修改的文件;

- lib_xxx 处理器体系相关的文件,如lib_ppc, lib_arm目录分别包含与PowerPC、ARM体系结构相关的文件;

- net 与网络功能相关的文件目录,如bootp,nfs,tftp;

- post 上电自检文件目录。尚有待于进一步完善;

- rtc RTC驱动程序;

- tools 用于创建U-Boot S-RECORD和BIN镜像文件的工具;

 

 

一、建立自己的开发板文件

1.在borad文件夹中新建自己的板子目录,复制sbc2410x中的文件到此目录,作为蓝本,加快移植进度,修改板子目录下的makefile文件COBJS := tq2440.o flash.o(其中tq2440.o文件的生成必须要修改此目录下的sbc2410x.c文件)

2.在include/configs文件夹下以sbc2410x.h为蓝本,创建tq2440.h文件

3.修改uboot根目录下的makefile文件,确定CROSS_COMPLE即编译器选项,加入make选项:

tq2440_config:unconfig

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

其中:

arm: CPU的架构(ARCH)

arm920t: CPU的类型(CPU),其对应于cpu/arm920t子目录。

tq2440: 开发板的型号(BOARD),对应于board/tq2440目录。

NULL: 开发者/或经销商(vender)。

s3c24x0: 片上系统(SOC)。

4.接下来测试是否能编译通过,执行:make disclean--删除原来的编译结果

make tqconfig

成功后出现Configuring for xxx board.....

make –可以生成uboot.bin文件

 

 

二、修改源码

 

1、修改start.S

 

修改如下代码:

 

#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

 

//把堆栈初始化拿到前面来,应为后面要写的时钟初始化函数会用到堆栈

 

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

//跳转到时钟初始话函数

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

 

//屏蔽原先代码,重写代码搬运函数

#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

 

 

 

接着在include/configs/tq2440.h添加

#define CONFIG_S3C2440 1

#define CONFIG_TQ2440 1

并屏蔽原先的芯片和开发板定义,与此同时s3c24x0.h中的S3C24X0_GPIO结构体也要改写,使其支持2440,而且要添加

 

S3C24X0_REG32 res9[4];

S3C24X0_REG32 GPJCON;

S3C24X0_REG32 GPJDAT;

S3C24X0_REG32 GPJUP;

此为GPIO_J口的定义

添加typedefstruct{

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;

其他结构体也要修改

修改lowlevel_init.S,修改54,58,126行即可,即外部存储器控制器。

54 #defineB1_BWSCON (DW16)

58 #defineB5_BWSCON (DW8)

126 #defineREFCNT 0x4f4

lowlevel_init.S 主要设置SDRAM配置

ARM的存储器控制器

位宽和等待控制寄存器BWSCON中每4位控制一个BANK,最高4位对应BANK7、接下来4位对应BANK6,依此类推

8 个存储器 banks

6 个是 ROM,SRAM 等类型存储器 bank

2 个是可以作为 ROM、SRAM、SDRAM 等存储器 bank

BANK控制寄存器BANKCONx(BANKCON1~5)这几个寄存器用来控制BANK0~BANK5外接设备的访问时序,一般使用默认的0x0700即可。

BANK控制寄存器BANKCONx(BANKCON6~7,在8个BANK中,只有BANK6和BANK7可以外接SRAM和SDRAM,所以BANKCON6~BANKCON7与BANKCON0~BANKCON5有点不同。

 

在board文件夹中添加boot_init.c文件,并修改makefile(boot_init.c文件主要包含nand的读写,时钟的初始化,和代码的拷贝函数)

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); // 复位命令

s3c2440_wait_idle();

s3c2440_nand_deselect_chip();

}

 

 

staticvoids3c2440_wait_idle(void)

{

inti;

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)

{

inti;

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)

{

inti;

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)

{

inti;

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)

{

inti;

 

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

 

//设置时序

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

// 使能NAND Flash控制器, 初始化ECC, 禁止片选

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

 

// 复位NAND Flash

nand_reset();

}

#if1

intNF_ReadID(void)

{

charpMID;

charpDID;

int nBuff;

char n4thcycle;

inti;

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)

{

inti, j;

chardat;

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(dat != 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)

{

inti, j;

chardat;

 

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(dat != 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;

inti;

 

 

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);

}

 

 

 

修改cpu/arm920t/s3c24x0/speed.c中get_HCLK等函数,首先在前面添加DECLARE_GLOBAL_DATA_PTR;使其能使用gd_t全局数据结构的指针

FLCK、HCLK和PCLK的关系

S3C2440有三个时钟FLCK、HCLK和PCLK

FCLK is used by ARM920T,内核时钟,主频。

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. 也就是总线时钟,包括USB时钟。

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.即IO接口时钟,例如串口的时钟设置就是从PCLK来的;

具体代码:

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);

}

}

关键字:U-boot1  1  6  TQ2440开发板 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
浅谈AVR中定时器几种工作模式