field : 11-10 是 DDR clock multiplexer
決定 DDR 的 clock source: (1.0) * 00 : axi a * 01 : axi b * 10 : emi_slow_clk_root * 11 : ahb clock root 配合 u-boot 的 source code 就是:
static u32 __get_ddr_clk(void)
{
u32 ret_val = 0;
u32 cbcmr = __REG(MXC_CCM_CBCMR);
u32 ddr_clk_sel = (cbcmr & MXC_CCM_CBCMR_DDR_CLK_SEL_MASK) \
>> MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET;
switch (ddr_clk_sel) {
case 0:
ret_val = __get_axi_a_clk();
break;
case 1:
ret_val = __get_axi_b_clk();
break;
case 2:
ret_val = __get_emi_slow_clk();
break;
case 3:
ret_val = __get_ahb_clk();
break;
default:
break;
}
return ret_val;
}
現在debug output cbcmr - 0x0020C2. 所以 11.10 是 0 -- axi_a_clk.然後 code 是去看 CBCDR ( CCM Bus Clock Divider Register ) 算出 DDR Speed。
source 有:
enum pll_clocks {
PLL1_CLK = MXC_DPLL1_BASE,
PLL2_CLK = MXC_DPLL2_BASE,
PLL3_CLK = MXC_DPLL3_BASE,
};
分別是:
#define AIPS2_BASE_ADDR 0x83F00000
#define PLL1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000)
#define PLL2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00084000)
#define PLL3_BASE_ADDR (AIPS2_BASE_ADDR + 0x00088000)
source code : lowlevel_init.S 設定 DDR 速度是修改 CBCDR.
- ldr r1, =0x61E35100
+ ldr r1, =0x71E35100
str r1, [r0, #CLKCTL_CBCDR]
DDR_CLK,有兩個 source 可以選,由CBCDR的 ddr_high_freq_clk_sel 決定。
- 0 -- 有四個 source 可以選,由 CBCMR 的ddr_clk_sel 選擇
- 1 -- 從 pll1_sw_clk (800MHz) 除頻, 除以 CBCDR 的ddr_clk_podf.(default 是 4,所以選這個會是 200MHz.
現在選的是 0,所以由四個 source 中選一個。 -- 選 0 -- form source 8.(axi_a)
這個就是 axi_a
axi_a 的第一階 source 有兩個,由CBCDR 的periph_clk_sel 決定 (這裡是選0 - pll2_sw_clk 665MHz)。
所以 最後 axi_a 就是 pll2_sw_clk 除頻,div = CBCDR:axi_a_podf+1 (預設是 3+1),所以預設的 axi_a 是 665MHz/4 = 166MHz。
所以 source code 寫錯了,沒有 考率到 ddr_clk 第一個 source select : CBCDR 的 ddr_high_freq_clk_sel 是 1 的狀況..
沒有留言:
張貼留言