`
xiaoer_1982
  • 浏览: 1819557 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

head.s分析(8):配置PLL及SDRAM

阅读更多

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

本文适用于

ADI bf561 DSP

uclinux-2008r1.5-rc3 (移植到vdsp5)

Visual DSP++ 5.0(update 5)

欢迎转载,但请保留作者信息

/* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */

call _bf53x_relocate_l1_mem;

#if CONFIG_BFIN_KERNEL_CLOCK

call _start_dma_code;

#endif

这里调用了两个函数,第一个函数bf53x_relocate_l1_mem的实现在linux-2.6.x\arch\blackfin\kernel\setup.c中,其用意是将定义在l1 cache里的代码和数据由SDRAM复制到l1 cache,但是当在vdsp下编译时直接通过LDF的控制将这些内容放在了l1 cache里面,因此第一个函数可跳过。

第二个函数start_dma_code的实现也在head.s中,用于设置PLLSDRAM的参数,下面主要看看这个函数:

#if CONFIG_BFIN_KERNEL_CLOCK

ENTRY(_start_dma_code)

p0.h = hi(SICA_IWR0);

p0.l = lo(SICA_IWR0);

r0.l = 0x1;

[p0] = r0;

SSYNC;

/*

* Set PLL_CTL

* - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors

* - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK

* - [7] = output delay (add 200ps of delay to mem signals)

* - [6] = input delay (add 200ps of input delay to mem signals)

* - [5] = PDWN : 1=All Clocks off

* - [3] = STOPCK : 1=Core Clock off

* - [1] = PLL_OFF : 1=Disable Power to PLL

* - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL

* all other bits set to zero

*/

p0.h = hi(PLL_LOCKCNT);

p0.l = lo(PLL_LOCKCNT);

r0 = 0x300(Z);

w[p0] = r0.l;

ssync;

P2.H = hi(EBIU_SDGCTL);

P2.L = lo(EBIU_SDGCTL);

R0 = [P2];

BITSET (R0, 24);

[P2] = R0;

SSYNC;

r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */

r0 = r0 << 9; /* Shift it over, */

r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/

r0 = r1 | r0;

r1 = PLL_BYPASS; /* Bypass the PLL? */

r1 = r1 << 8; /* Shift it over */

r0 = r1 | r0; /* add them all together */

p0.h = hi(PLL_CTL);

p0.l = lo(PLL_CTL); /* Load the address */

cli r2; /* Disable interrupts */

ssync;

w[p0] = r0.l; /* Set the value */

idle; /* Wait for the PLL to stablize */

sti r2; /* Enable interrupts */

.Lcheck_again:

p0.h = hi(PLL_STAT);

p0.l = lo(PLL_STAT);

R0 = W[P0](Z);

CC = BITTST(R0,5);

if ! CC jump .Lcheck_again;

/* Configure SCLK & CCLK Dividers */

r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);

p0.h = hi(PLL_DIV);

p0.l = lo(PLL_DIV);

w[p0] = r0.l;

ssync;

p0.l = lo(EBIU_SDRRC);

p0.h = hi(EBIU_SDRRC);

r0 = mem_SDRRC;

w[p0] = r0.l;

ssync;

p0.l = LO(EBIU_SDBCTL);

p0.h = HI(EBIU_SDBCTL); /* SDRAM Memory Bank Control Register */

r0 = mem_SDBCTL;

w[p0] = r0.l;

ssync;

P2.H = hi(EBIU_SDGCTL);

P2.L = lo(EBIU_SDGCTL);

R0 = [P2];

BITCLR (R0, 24);

p0.h = hi(EBIU_SDSTAT);

p0.l = lo(EBIU_SDSTAT);

r2.l = w[p0];

cc = bittst(r2,3);

if !cc jump .Lskip;

NOP;

BITSET (R0, 23);

.Lskip:

[P2] = R0;

SSYNC;

R0.L = lo(mem_SDGCTL);

R0.H = hi(mem_SDGCTL);

R1 = [p2];

R1 = R1 | R0;

[P2] = R1;

SSYNC;

RTS;

ENDPROC(_start_dma_code)

#endif /* CONFIG_BFIN_KERNEL_CLOCK */

这段代码的注释已经相当清晰了,当在vdsp下调试的时候,在运行到

w[p0] = r0.l; /* Set the value */

idle; /* Wait for the PLL to stablize */

sti r2; /* Enable interrupts */

中的idle的时候,dsp进入idle状态,vdsp仍然显示a核在running,中断下来后pc将停在sti r2语句上,此时可以继续往下执行,但是PLL的配置并不会生效,除非此时B核处于idle状态。

1 参考资料

head.s分析(1):保存u-boot传递过来的指针(2009-1-19)

head.s分析(2)SYSCFG配置(2009-1-19)

head.s分析(3):数据及指针寄存器清0(2009-1-19)

head.s分析(4):关闭CACHE(2009-01-19)

head.s分析(5):关闭串口(2009-01-19)

head.s分析(6):栈指针初始化(2009-01-19)

head.s分析(7)init_early_exception_vectors(2009-1-19)

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics