// 功能:彙編初始化時鐘
//配置步驟:
// 1. 設置各PLL的LOCK_TIME,對應的寄存器爲APLL_LOCK,MPLL_LOCK,EPLL_LOCK
// 2. 設置爲異步模式(Asynchronous mode) ,對應的寄存器爲OTHERS
// 3. 設置分頻係數
// 4. 設置PLL,放大時鐘
// 5.切換時鐘,選擇PLL的輸出作爲時鐘源
//具體配置參照下面的時鐘系統圖,和6410數據手冊
.global clock_initclock_init:
// 1. 設置各PLL的LOCK_TIME,使用默認值,LOCK_TIME成爲鎖定時間,
//設置這些的目的是因爲時鐘的倍頻需要一定時間才能達到穩定,這裏三個PLL的LOCK_TIME用的都是
//6410手冊中的默認值,其實也可以不用設置。
ldr r0, =0x7E00F000 // APLL_LOCK,供cpu使用
ldr r1, =0x0000FFFF
str r1, [r0]
str r1, [r0, #4] // MPLL_LOCK,供AHB(存儲/中斷/lcd等控制器)/APB(看門狗,定時器,SD等)總線上的設備使用
str r1, [r0, #8] // EPLL_LOCK,供UART,IIS,IIC使用
// 2. 設置爲異步模式(Asynchronous mode)
ldr r0, =0x7E00F900 // OTHERS
// 《linux installation for u-boot》3.7中:用MPLL作爲HCLK和PCLK的Source是異步(ASYNC)模式
// 用APLL是同步(SYNC)模式
ldr r1, [r0]
bic r1, r1, #0xc0 // bit[6:7]清0,即SYNCMODE=0/SYNCMUXSEL=0
str r1, [r0]
loop:
ldr r0, =0x7E00F900 //循環等待,直到讀出的bit[8:11]爲0,表明異步模式設置成功,CPU已進入異步模式
ldr r1, [r0]
and r1, r1, #0xf00
cmp r1, #0
bne loop
// 3. 設置分頻係數
#define ARM_RATIO 0 // ARMCLK = DOUTAPLL / (ARM_RATIO + 1) = 532/(0+1) = 532 MHz
#define MPLL_RATIO 0 // DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1) = 532/(0+1) = 532 MHz
#define HCLKX2_RATIO 1 // HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1) = 532/(1+1) = 266 MHz
#define HCLK_RATIO 1 // HCLK = HCLKX2 / (HCLK_RATIO + 1) = 266/(1+1) = 133 MHz
#define PCLK_RATIO 3 // PCLK = HCLKX2 / (PCLK_RATIO + 1) = 266/(3+1) = 66.5 MHz
ldr r0, =0x7E00F020 // CLK_DIV0
ldr r1, =(ARM_RATIO) | (MPLL_RATIO << 4) | (HCLK_RATIO << 8) | (HCLKX2_RATIO << 9) | (PCLK_RATIO << 12)
str r1, [r0]
// 4. 設置PLL,放大時鐘
// 4.1 配置APLL
#define APLL_CON_VAL ((1<<31) | (266 << 16) | (3 << 8) | (1))
ldr r0, =0x7E00F00C // APLL_CON
ldr r1, =APLL_CON_VAL // FOUT = MDIV X FIN / (PDIV X 2SDIV) = 266*12/(3*2^1) = 532MHz
str r1, [r0]
// 4.2 配置MPLL
#define MPLL_CON_VAL ((1<<31) | (266 << 16) | (3 << 8) | (1))
ldr r0, =0x7E00F010 // MPLL_CON
ldr r1, =MPLL_CON_VAL // FOUT = MDIV X FIN / (PDIV X 2SDIV) = 266*12/(3*2^1) = 532MHz
str r1, [r0]
#define MPLL_SEL 1
#define APLL_SEL 1
// 5.選擇PLL的輸出作爲時鐘源
ldr r0, =0x7E00F01C // CLK_SRC
ldr r1, =(MPLL_SEL<<1) | (APLL_SEL<<0)
str r1, [r0]
mov pc, lr
// 功能:c語言初始化時鐘
#define APLL_LOCK (*((volatile unsigned long *)0x7E00F000))
#define MPLL_LOCK (*((volatile unsigned long *)0x7E00F004))
#define EPLL_LOCK (*((volatile unsigned long *)0x7E00F008))
#define OTHERS (*((volatile unsigned long *)0x7e00f900))
#define CLK_DIV0 (*((volatile unsigned long *)0x7E00F020))
#define ARM_RATIO 0 // ARMCLK
= DOUTAPLL / (ARM_RATIO + 1) = 532/(0+1) = 532 MHz
#define MPLL_RATIO 0 // DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1) = 532/(0+1) = 532 MHz
#define HCLKX2_RATIO 1 // HCLKX2
= HCLKX2IN / (HCLKX2_RATIO + 1) = 532/(1+1) = 266 MHz
#define HCLK_RATIO 1 // HCLK
= HCLKX2 / (HCLK_RATIO + 1) = 266/(1+1) = 133 MHz
#define PCLK_RATIO 3 // PCLK
= HCLKX2 / (PCLK_RATIO + 1) = 266/(3+1) = 66.5 MHz
#define APLL_CON (*((volatile unsigned long *)0x7E00F00C))
#define APLL_CON_VAL ((1<<31) | (266 << 16) | (3 << 8) | (1))
#define MPLL_CON (*((volatile unsigned long *)0x7E00F010))
#define MPLL_CON_VAL ((1<<31) | (266 << 16) | (3 << 8) | (1))
#define CLK_SRC (*((volatile unsigned long *)0x7E00F01C))
void clock_init(void)
{
/* 1. 設置各PLL的LOCK_TIME,使用默認值 */
APLL_LOCK = 0xffff;
// APLL_LOCK,供cpu使用
MPLL_LOCK = 0xffff;
// MPLL_LOCK,供AHB(存儲/中斷/lcd等控制器)/APB(看 //門狗,定時器,SD等)總線上的設備使用
EPLL_LOCK = 0xffff;
// EPLL_LOCK,供UART,IIS,IIC使用
/* 2. 設置爲異步模式(Asynchronous mode) */
OTHERS &= ~0xc0;
//《linux installation for u-boot》3.7中:用MPLL作爲 //HCLK和PCLK的Source是異步(ASYNC)模式,用APLL是同步(SYNC)模式
while ((OTHERS & 0xf00) != 0);
/* 3. 設置分頻係數 */
CLK_DIV0 = (ARM_RATIO) | (MPLL_RATIO << 4) | (HCLK_RATIO << 8) | (HCLKX2_RATIO << 9) | (PCLK_RATIO << 12);
/* 4. 設置PLL,放大時鐘 */
APLL_CON = APLL_CON_VAL;
MPLL_CON = MPLL_CON_VAL;
/* 5. 選擇PLL的輸出作爲時鐘源 */
CLK_SRC = 0x03;
}