From ec49f5d906703b571fda57d41a0e65055b62b490 Mon Sep 17 00:00:00 2001 From: Samul Kyull Date: Fri, 18 Oct 2024 00:22:08 +0800 Subject: [PATCH] [driver] fix clk driver issue --- board/avaota-cam/cdk/avaota_cam.cdkproj | 4 +- board/avaota-cam/hello_world/main.c | 4 -- src/drivers/chips/sun20iw5/sys-clk.c | 95 +++++++++++-------------- src/drivers/chips/sun20iw5/sys-dram.c | 66 +---------------- 4 files changed, 44 insertions(+), 125 deletions(-) diff --git a/board/avaota-cam/cdk/avaota_cam.cdkproj b/board/avaota-cam/cdk/avaota_cam.cdkproj index 56a02196..95c392b0 100644 --- a/board/avaota-cam/cdk/avaota_cam.cdkproj +++ b/board/avaota-cam/cdk/avaota_cam.cdkproj @@ -407,7 +407,7 @@ - + @@ -624,7 +624,7 @@ Optimize for debug (-Og) Default (-g) $(ProjectPath);../../../include/;../../../include/arch/riscv/;../../../include/cli/;../../../include/drivers/chips/sun20iw5/;../../../include/drivers/mmc/;../../../include/drivers/pmu/reg/;../../../include/drivers/pmu/;../../../include/drivers/reg/;../../../include/drivers/usb/;../../../include/image/;../../../include/lib/elf/;../../../include/lib/fatfs/;../../../include/lib/fdt/;../../../include/drivers/;../../../include/drivers/chips/ - -nostdlib -g -ggdb -O0 -nostdinc -march=rv32imafcxthead -mabi=ilp32f -Wno-int-to-pointer-cast -Wno-int-to-pointer-cast -Wno-shift-count-overflow -Wno-builtin-declaration-mismatch -Wno-pointer-to-int-cast -Wno-implicit-function-declaration -Wno-discarded-qualifiers -Wno-unused-function -Wno-unused-variable + -nostdlib -g -ggdb -O0 -nostdinc -march=rv32imafcxthead -mabi=ilp32f -Wno-int-to-pointer-cast -Wno-int-to-pointer-cast -Wno-shift-count-overflow -Wno-builtin-declaration-mismatch -Wno-pointer-to-int-cast -Wno-implicit-function-declaration -Wno-discarded-qualifiers -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable no no no diff --git a/board/avaota-cam/hello_world/main.c b/board/avaota-cam/hello_world/main.c index 817c57b9..4b50ee60 100644 --- a/board/avaota-cam/hello_world/main.c +++ b/board/avaota-cam/hello_world/main.c @@ -25,10 +25,6 @@ int main(void) { sunxi_clk_dump(); - printk_info("test Store address misaligned exception\n"); - - asm volatile(".word 0x23232323"); - abort(); return 0; diff --git a/src/drivers/chips/sun20iw5/sys-clk.c b/src/drivers/chips/sun20iw5/sys-clk.c index 5a968dca..82ae8fc7 100644 --- a/src/drivers/chips/sun20iw5/sys-clk.c +++ b/src/drivers/chips/sun20iw5/sys-clk.c @@ -13,25 +13,6 @@ #include -typedef struct { - uint32_t pll_en; - uint32_t pll_ldo_en; - uint32_t pll_lock_en; - uint32_t pll_output_gate; - uint32_t pll_n; - uint32_t pll_m; -} ccu_pll_peri_cfg_info_t; - -typedef struct { - uint32_t pll_en; - uint32_t pll_ldo_en; - uint32_t pll_lock_en; - uint32_t pll_output_gate; - uint32_t pll_n; - uint32_t pll_m; - uint32_t pll_d; -} ccu_pll_general_cfg_info_t; - int wait_until_pll_timeout(uint32_t time_cnt) { uint32_t ret = 1; do { @@ -44,25 +25,26 @@ int wait_until_pll_timeout(uint32_t time_cnt) { } static void set_pll_general(uint32_t pll_addr, uint32_t en, uint32_t output_gate_en, uint32_t pll_d, uint32_t pll_d_off, uint32_t pll_n) { - ccu_pll_general_cfg_info_t pll_general_cfg; + uint32_t pll_en; + uint32_t pll_ldo_en; + uint32_t pll_lock_en; + uint32_t pll_output_gate; + uint32_t pll_m; if (en == 1) { - pll_general_cfg.pll_en = PLL_Enable; - pll_general_cfg.pll_ldo_en = PLL_LDO_Enable; - pll_general_cfg.pll_lock_en = PLL_LOCK_EN_Enable; + pll_en = PLL_Enable; + pll_ldo_en = PLL_LDO_Enable; + pll_lock_en = PLL_LOCK_EN_Enable; } else { - pll_general_cfg.pll_en = PLL_Disable; - pll_general_cfg.pll_ldo_en = PLL_LDO_Disable; - pll_general_cfg.pll_lock_en = PLL_LOCK_EN_Disable; + pll_en = PLL_Disable; + pll_ldo_en = PLL_LDO_Disable; + pll_lock_en = PLL_LOCK_EN_Disable; } - pll_general_cfg.pll_output_gate = PLL_OUTPUT_GATE_Disable; + pll_output_gate = PLL_OUTPUT_GATE_Disable; clrsetbits_le32(pll_addr, PLL_D_MASK, pll_d << pll_d_off); - // clrsetbits_le32(pll_addr, PLL_M_MASK, pll_m << PLL_M_OFFSET); clrsetbits_le32(pll_addr, PLL_N_MASK, pll_n << PLL_N_OFFSET); - - clrsetbits_le32(pll_addr, PLL_LDO_MASK | PLL_OUTPUT_GATE_MASK | PLL_EN_MASK, pll_general_cfg.pll_en | pll_general_cfg.pll_ldo_en | pll_general_cfg.pll_lock_en); - + clrsetbits_le32(pll_addr, PLL_LDO_MASK | PLL_OUTPUT_GATE_MASK | PLL_EN_MASK, pll_en | pll_ldo_en | pll_lock_en); clrsetbits_le32(pll_addr, PLL_LOCK_EN_MASK, PLL_LOCK_EN_Enable); while ((!(readl(pll_addr) & PLL_LOCK_MASK)) & wait_until_pll_timeout(0xffff)) @@ -74,16 +56,12 @@ static void set_pll_general(uint32_t pll_addr, uint32_t en, uint32_t output_gate } static void set_pll_e90x(void) { - /* Low freq --> High freq */ - /* clock 1024/3 = 512M */ clrsetbits_le32(CCU_E90X_CLK_REG, E907_CLK_REG_E907_CLK_DIV_CLEAR_MASK, CCU_E90X_CLK_CPU_M_1 << E907_CLK_REG_E907_CLK_DIV_OFFSET); clrsetbits_le32(CCU_E90X_CLK_REG, E907_CLK_REG_E907_CLK_SEL_CLEAR_MASK, E907_CLK_REG_E907_CLK_SEL_PERI_PLL_614M << E907_CLK_REG_E907_CLK_SEL_OFFSET); return; } static void set_pll_a27l2(void) { - /* Low freq --> High freq */ - /* clock 768/3 = 256M */ clrsetbits_le32(CCU_A27_CLK_REG, A27L2_CLK_REG_A27L2_CLK_DIV_CLEAR_MASK, CCU_A27_CLK_CPU_M_1 << A27L2_CLK_REG_A27L2_CLK_DIV_OFFSET); clrsetbits_le32(CCU_A27_CLK_REG, A27L2_CLK_REG_A27L2_CLK_SEL_CLEAR_MASK, A27L2_CLK_REG_A27L2_CLK_SEL_CPU_PLL << A27L2_CLK_REG_A27L2_CLK_SEL_OFFSET); clrsetbits_le32(CCU_A27_CLK_REG, A27L2_CLK_REG_A27L2_CLK_EN_CLEAR_MASK, A27L2_CLK_REG_A27L2_CLK_EN_CLOCK_IS_ON << A27L2_CLK_REG_A27L2_CLK_EN_OFFSET); @@ -91,36 +69,39 @@ static void set_pll_a27l2(void) { } static void set_pll_peri_ctrl0(uint32_t en, uint32_t output_gate_en, uint32_t pll_n, uint32_t pll_m) { - ccu_pll_peri_cfg_info_t pll_peri_cfg; + uint32_t pll_en; + uint32_t pll_ldo_en; + uint32_t pll_lock_en; + uint32_t pll_output_gate; if (en == 1) { - pll_peri_cfg.pll_en = PLL_PERI_CTRL0_REG_PLL_EN_ENABLE << PLL_PERI_CTRL0_REG_PLL_EN_OFFSET; - pll_peri_cfg.pll_ldo_en = PLL_PERI_CTRL0_REG_PLL_LDO_EN_ENABLE << PLL_PERI_CTRL0_REG_PLL_LDO_EN_OFFSET; - pll_peri_cfg.pll_lock_en = PLL_PERI_CTRL0_REG_LOCK_ENABLE_ENABLE << PLL_PERI_CTRL0_REG_LOCK_ENABLE_OFFSET; + pll_en = PLL_PERI_CTRL0_REG_PLL_EN_ENABLE << PLL_PERI_CTRL0_REG_PLL_EN_OFFSET; + pll_ldo_en = PLL_PERI_CTRL0_REG_PLL_LDO_EN_ENABLE << PLL_PERI_CTRL0_REG_PLL_LDO_EN_OFFSET; + pll_lock_en = PLL_PERI_CTRL0_REG_LOCK_ENABLE_ENABLE << PLL_PERI_CTRL0_REG_LOCK_ENABLE_OFFSET; } else { - pll_peri_cfg.pll_en = PLL_PERI_CTRL0_REG_PLL_EN_DISABLE << PLL_PERI_CTRL0_REG_PLL_EN_OFFSET; - pll_peri_cfg.pll_ldo_en = PLL_PERI_CTRL0_REG_PLL_LDO_EN_DISABLE << PLL_PERI_CTRL0_REG_PLL_LDO_EN_OFFSET; - pll_peri_cfg.pll_lock_en = PLL_PERI_CTRL0_REG_LOCK_ENABLE_DISABLE << PLL_PERI_CTRL0_REG_LOCK_ENABLE_OFFSET; + pll_en = PLL_PERI_CTRL0_REG_PLL_EN_DISABLE << PLL_PERI_CTRL0_REG_PLL_EN_OFFSET; + pll_ldo_en = PLL_PERI_CTRL0_REG_PLL_LDO_EN_DISABLE << PLL_PERI_CTRL0_REG_PLL_LDO_EN_OFFSET; + pll_lock_en = PLL_PERI_CTRL0_REG_LOCK_ENABLE_DISABLE << PLL_PERI_CTRL0_REG_LOCK_ENABLE_OFFSET; } - pll_peri_cfg.pll_output_gate = PLL_VIDEO_CTRL_REG_PLL_OUTPUT_GATE_DISABLE << PLL_VIDEO_CTRL_REG_PLL_OUTPUT_GATE_OFFSET; - pll_peri_cfg.pll_n = pll_n << PLL_PERI_CTRL0_REG_PLL_N_OFFSET; - pll_peri_cfg.pll_m = pll_m << PLL_PERI_CTRL0_REG_PLL_INPUT_DIV_OFFSET; + pll_output_gate = PLL_VIDEO_CTRL_REG_PLL_OUTPUT_GATE_DISABLE << PLL_VIDEO_CTRL_REG_PLL_OUTPUT_GATE_OFFSET; + pll_n = pll_n << PLL_PERI_CTRL0_REG_PLL_N_OFFSET; + pll_m = pll_m << PLL_PERI_CTRL0_REG_PLL_INPUT_DIV_OFFSET; - clrsetbits_le32(CCU_PLL_PERI_CTRL0_REG, PLL_PERI_CTRL0_REG_PLL_INPUT_DIV_CLEAR_MASK, pll_peri_cfg.pll_m); - clrsetbits_le32(CCU_PLL_PERI_CTRL0_REG, PLL_PERI_CTRL0_REG_PLL_N_CLEAR_MASK, pll_peri_cfg.pll_n); + clrsetbits_le32(CCU_PLL_PERI_CTRL0_REG, PLL_PERI_CTRL0_REG_PLL_INPUT_DIV_CLEAR_MASK, pll_m); + clrsetbits_le32(CCU_PLL_PERI_CTRL0_REG, PLL_PERI_CTRL0_REG_PLL_N_CLEAR_MASK, pll_n); clrsetbits_le32(CCU_PLL_PERI_CTRL0_REG, PLL_PERI_CTRL0_REG_PLL_EN_CLEAR_MASK | PLL_PERI_CTRL0_REG_PLL_LDO_EN_CLEAR_MASK | PLL_PERI_CTRL0_REG_PLL_OUTPUT_GATE_CLEAR_MASK, - pll_peri_cfg.pll_en | pll_peri_cfg.pll_ldo_en | pll_peri_cfg.pll_output_gate); + pll_en | pll_ldo_en | pll_output_gate); - clrsetbits_le32(CCU_PLL_PERI_CTRL0_REG, PLL_PERI_CTRL0_REG_LOCK_ENABLE_CLEAR_MASK, pll_peri_cfg.pll_lock_en); + clrsetbits_le32(CCU_PLL_PERI_CTRL0_REG, PLL_PERI_CTRL0_REG_LOCK_ENABLE_CLEAR_MASK, pll_lock_en); while ((!(readl(CCU_PLL_PERI_CTRL0_REG) & PLL_PERI_CTRL0_REG_LOCK_CLEAR_MASK)) & wait_until_pll_timeout(0xffff)) ; if (output_gate_en == 1) { - pll_peri_cfg.pll_output_gate = PLL_PERI_CTRL0_REG_PLL_OUTPUT_GATE_ENABLE << PLL_PERI_CTRL0_REG_PLL_OUTPUT_GATE_OFFSET; - clrsetbits_le32(CCU_PLL_PERI_CTRL0_REG, PLL_PERI_CTRL0_REG_PLL_OUTPUT_GATE_CLEAR_MASK, pll_peri_cfg.pll_output_gate); + pll_output_gate = PLL_PERI_CTRL0_REG_PLL_OUTPUT_GATE_ENABLE << PLL_PERI_CTRL0_REG_PLL_OUTPUT_GATE_OFFSET; + clrsetbits_le32(CCU_PLL_PERI_CTRL0_REG, PLL_PERI_CTRL0_REG_PLL_OUTPUT_GATE_CLEAR_MASK, pll_output_gate); } } @@ -134,9 +115,8 @@ static void set_pll_peri_ctrl1(void) { return; } -/* pll peri hosc*2N/M = 3072M hardware *2 */ +/* pll peri hosc*2N/M = 3072M hardware * 2 */ void set_pll_peri(void) { - // When efuse is burned, brom will initialize the peri clock in advance. if (!(readl(CCU_PLL_PERI_CTRL0_REG) & PLL_PERI_CTRL0_REG_PLL_EN_CLEAR_MASK)) { if (sunxi_clk_get_hosc_type() == HOSC_FREQ_40M) { set_pll_peri_ctrl0(PLL_PERI_CTRL0_REG_PLL_EN_ENABLE, PLL_PERI_CTRL0_REG_PLL_OUTPUT_GATE_ENABLE, CCU_AON_PLL_CPU_N_192, CCU_AON_PLL_CPU_M_5); @@ -252,7 +232,6 @@ void sunxi_clk_init(void) { } else { writel(readl(CCU_FUNC_CFG_REG) & (~PLL_FUNC_CFG_REG_DCXO_ST_CLEAR_MASK), CCU_FUNC_CFG_REG); set_pll_general(CCU_PLL_CPUX_CTRL_REG, PLL_CPU_CTRL_REG_PLL_EN_ENABLE, PLL_CPU_CTRL_REG_PLL_OUTPUT_GATE_ENABLE, CCU_AON_PLL_CPU_D_1, 2, CCU_AON_PLL_CPU_N_45); - // When efuse is burned, brom will initialize the vedio clock in advance. if (!(readl(CCU_PLL_VIDEO_CTRL_REG) & PLL_CPU_CTRL_REG_PLL_EN_CLEAR_MASK)) { set_pll_general(CCU_PLL_VIDEO_CTRL_REG, PLL_CPU_CTRL_REG_PLL_EN_ENABLE, PLL_CPU_CTRL_REG_PLL_OUTPUT_GATE_ENABLE, CCU_AON_PLL_CPU_D_2, 1, CCU_AON_PLL_CPU_N_99); } @@ -267,6 +246,14 @@ void sunxi_clk_init(void) { } void sunxi_clk_dump() { + uint32_t reg_val = 0; + uint32_t n, m; + + reg_val = read32(CCU_PLL_PERI_CTRL0_REG); + n = (reg_val & PLL_PERI_CTRL0_REG_PLL_N_CLEAR_MASK) >> PLL_PERI_CTRL0_REG_PLL_N_OFFSET; + m = reg_val & PLL_PERI_CTRL0_REG_PLL_INPUT_DIV_CLEAR_MASK; + + printk_debug("CLK: PERI FREQ=%luMHz\r\n", (sunxi_clk_get_hosc_type() * 2 * (n + 1)) / (m + 1)); } /* we got hosc freq in arch/timer.c */ diff --git a/src/drivers/chips/sun20iw5/sys-dram.c b/src/drivers/chips/sun20iw5/sys-dram.c index 57e64c76..7224f184 100644 --- a/src/drivers/chips/sun20iw5/sys-dram.c +++ b/src/drivers/chips/sun20iw5/sys-dram.c @@ -469,77 +469,13 @@ static void mctl_set_timing_params(dram_para_t *para) { // the MBUS and sdram. // static int ccu_set_pll_ddr_clk(int index, dram_para_t *para) { - unsigned int val, clk, n; - - if (para->dram_tpr13 & (1 << 6)) - clk = para->dram_tpr9; - else - clk = para->dram_clk; - - // set VCO clock divider - n = (clk * 2) / 24; - - val = readl((CCU_BASE + CCU_PLL_DDR_CTRL_REG)); - val &= 0xfff800fc; // clear dividers - val |= (n - 1) << 8;// set PLL division - val |= 0xc0000000; // enable PLL and LDO - val &= 0xdfffffff; - writel(val | 0x20000000, (CCU_BASE + CCU_PLL_DDR_CTRL_REG)); - - // wait for PLL to lock - while ((readl((CCU_BASE + CCU_PLL_DDR_CTRL_REG)) & 0x10000000) == 0) { - ; - } - - udelay(20); - - // enable PLL output - val = readl(CCU_BASE); - val |= 0x08000000; - writel(val, CCU_BASE); - - // turn clock gate on - val = readl((CCU_BASE + CCU_DRAM_CLK_REG)); - val &= 0xfcfffcfc;// select DDR clk source, n=1, m=1 - val |= 0x80000000;// turn clock on - writel(val, (CCU_BASE + CCU_DRAM_CLK_REG)); - - return n * 24; + return 0x0; } // Main purpose of sys_init seems to be to initalise the clocks for // the sdram controller. // static void mctl_sys_init(dram_para_t *para) { - // assert MBUS reset - clrbits_le32((CCU_BASE + CCU_MBUS_CLK_REG), (1 << 30)); - - // turn off sdram clock gate, assert sdram reset - clrbits_le32((CCU_BASE + CCU_DRAM_BGR_REG), 0x10001); - clrsetbits_le32((CCU_BASE + CCU_DRAM_CLK_REG), (1 << 31) | (1 << 30), (1 << 27)); - udelay(10); - - // set ddr pll clock - para->dram_clk = ccu_set_pll_ddr_clk(0, para) / 2; - udelay(100); - dram_disable_all_master(); - - // release sdram reset - setbits_le32((CCU_BASE + CCU_DRAM_BGR_REG), (1 << 16)); - - // release MBUS reset - setbits_le32((CCU_BASE + CCU_MBUS_CLK_REG), (1 << 30)); - setbits_le32((CCU_BASE + CCU_DRAM_CLK_REG), (1 << 30)); - - udelay(5); - - // turn on sdram clock gate - setbits_le32((CCU_BASE + CCU_DRAM_BGR_REG), (1 << 0)); - - // turn dram clock gate on, trigger sdr clock update - setbits_le32((CCU_BASE + CCU_DRAM_CLK_REG), (1 << 31) | (1 << 27)); - udelay(5); - // mCTL clock enable writel(0x8000, (MCTL_PHY_BASE + MCTL_PHY_CLKEN)); udelay(10);