diff options
author | David Hendricks <dhendrix@chromium.org> | 2013-02-03 18:09:58 -0800 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2013-02-06 02:11:14 +0100 |
commit | 0d4f97e27045209fdb9af452b013a6cfaebcaebc (patch) | |
tree | bf42e136f4809489725de88cb03bd052716f4687 /src/mainboard/google/snow/bootblock.c | |
parent | 94e230aa9319ca3421867efc080c985f9bcaaef4 (diff) | |
download | coreboot-0d4f97e27045209fdb9af452b013a6cfaebcaebc.tar.xz |
exynos/snow: Move core/memory clock-related and board ID code
This patch moves ARM core and DRAM timing functions around to simplify
the dependencies for system_clock_init().
The original code was architected such that the system_clock_init()
function called other functions to obtain core and memory timings.
Due to the way memory timing information must be obtained on Snow,
which entails decoding platform-specific board straps, the bottom-
up approach resulted in having the low-level clock init code
implicitly depend on board and vendor-specific info:
main()
->system_clock_init()
-> get_arm_ratios()
-> CPU-specific code
-> clock_get_mem_timings()
-> board_get_revision()
-> read GPIOs (3-state logic)
-> Decode GPIOs in a vendor-specific manner
-> Choose memory timings from module-specific look-up table
...then proceed to init clocks
...come back to main()
The new approach gathers all board and vendor-specific info in a
more appropriate location and passes it into system_clock_init():
main()
-> get_arm_ratios()
-> CPU-specific code
-> get_mem_timings()
-> board_get_config()
-> read GPIOs (3-state logic)
-> Decode GPIOs in a vendor-specific manner
-> Choose memory timings from module-specific look-up table
-> system_clock_init()
...back to main()
Change-Id: Ie237ebff76fc2d8a4d2f4577a226ac3909e4d4e8
Signed-off-by: David Hendricks <dhendrix@chromium.org>
Reviewed-on: http://review.coreboot.org/2271
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/mainboard/google/snow/bootblock.c')
-rw-r--r-- | src/mainboard/google/snow/bootblock.c | 394 |
1 files changed, 6 insertions, 388 deletions
diff --git a/src/mainboard/google/snow/bootblock.c b/src/mainboard/google/snow/bootblock.c index 1985662c9a..90a2de188e 100644 --- a/src/mainboard/google/snow/bootblock.c +++ b/src/mainboard/google/snow/bootblock.c @@ -345,393 +345,6 @@ static void power_init(void) REG_ENABLE, MAX77686_MV); } -/* FIXME(dhendrix): this will be removed in a follow-up patch */ -struct mem_timings my_mem_timings[] = { - { - .mem_manuf = MEM_MANUF_ELPIDA, - .mem_type = DDR_MODE_DDR3, - .frequency_mhz = 800, - .mpll_mdiv = 0x64, - .mpll_pdiv = 0x3, - .mpll_sdiv = 0x0, - .cpll_mdiv = 0xde, - .cpll_pdiv = 0x4, - .cpll_sdiv = 0x2, - .gpll_mdiv = 0x215, - .gpll_pdiv = 0xc, - .gpll_sdiv = 0x1, - .epll_mdiv = 0x60, - .epll_pdiv = 0x3, - .epll_sdiv = 0x3, - .vpll_mdiv = 0x96, - .vpll_pdiv = 0x3, - .vpll_sdiv = 0x2, - - .bpll_mdiv = 0x64, - .bpll_pdiv = 0x3, - .bpll_sdiv = 0x0, - .use_bpll = 0, - .pclk_cdrex_ratio = 0x5, - .direct_cmd_msr = { - 0x00020018, 0x00030000, 0x00010042, 0x00000d70 - }, - .timing_ref = 0x000000bb, - .timing_row = 0x8c36660f, - .timing_data = 0x3630580b, - .timing_power = 0x41000a44, - .phy0_dqs = 0x08080808, - .phy1_dqs = 0x08080808, - .phy0_dq = 0x08080808, - .phy1_dq = 0x08080808, - .phy0_tFS = 0x4, - .phy1_tFS = 0x4, - .phy0_pulld_dqs = 0xf, - .phy1_pulld_dqs = 0xf, - - .lpddr3_ctrl_phy_reset = 0x1, - .ctrl_start_point = 0x10, - .ctrl_inc = 0x10, - .ctrl_start = 0x1, - .ctrl_dll_on = 0x1, - .ctrl_ref = 0x8, - - .ctrl_force = 0x1a, - .ctrl_rdlat = 0x0b, - .ctrl_bstlen = 0x08, - - .fp_resync = 0x8, - .iv_size = 0x7, - .dfi_init_start = 1, - .aref_en = 1, - - .rd_fetch = 0x3, - - .zq_mode_dds = 0x7, - .zq_mode_term = 0x1, - .zq_mode_noterm = 0, - - /* - * Dynamic Clock: Always Running - * Memory Burst length: 8 - * Number of chips: 1 - * Memory Bus width: 32 bit - * Memory Type: DDR3 - * Additional Latancy for PLL: 0 Cycle - */ - .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE | - DMC_MEMCONTROL_DPWRDN_DISABLE | - DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE | - DMC_MEMCONTROL_TP_DISABLE | - DMC_MEMCONTROL_DSREF_ENABLE | - DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) | - DMC_MEMCONTROL_MEM_TYPE_DDR3 | - DMC_MEMCONTROL_MEM_WIDTH_32BIT | - DMC_MEMCONTROL_NUM_CHIP_1 | - DMC_MEMCONTROL_BL_8 | - DMC_MEMCONTROL_PZQ_DISABLE | - DMC_MEMCONTROL_MRR_BYTE_7_0, - .memconfig = DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED | - DMC_MEMCONFIGx_CHIP_COL_10 | - DMC_MEMCONFIGx_CHIP_ROW_15 | - DMC_MEMCONFIGx_CHIP_BANK_8, - .membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40), - .membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80), - .prechconfig_tp_cnt = 0xff, - .dpwrdn_cyc = 0xff, - .dsref_cyc = 0xffff, - .concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE | - DMC_CONCONTROL_TIMEOUT_LEVEL0 | - DMC_CONCONTROL_RD_FETCH_DISABLE | - DMC_CONCONTROL_EMPTY_DISABLE | - DMC_CONCONTROL_AREF_EN_DISABLE | - DMC_CONCONTROL_IO_PD_CON_DISABLE, - .dmc_channels = 2, - .chips_per_channel = 2, - .chips_to_configure = 1, - .send_zq_init = 1, - .impedance = IMP_OUTPUT_DRV_30_OHM, - .gate_leveling_enable = 0, - }, -}; - -/* FIXME(dhendrix): this will be removed in a follow-up patch */ -struct arm_clk_ratios my_arm_clk_ratios[] = { - { - .arm_freq_mhz = 1700, - - .apll_mdiv = 0x1a9, - .apll_pdiv = 0x6, - .apll_sdiv = 0x0, - - .arm2_ratio = 0x0, - .apll_ratio = 0x3, - .pclk_dbg_ratio = 0x1, - .atb_ratio = 0x6, - .periph_ratio = 0x7, - .acp_ratio = 0x7, - .cpud_ratio = 0x3, - .arm_ratio = 0x0, - } -}; - -static void clock_init(void) -{ - struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; - struct exynos5_mct_regs *mct_regs = - (struct exynos5_mct_regs *)EXYNOS5_MULTI_CORE_TIMER_BASE; - struct mem_timings *mem = &my_mem_timings[0]; - struct arm_clk_ratios *arm_clk_ratio = &my_arm_clk_ratios[0]; - u32 val, tmp; - - /* Turn on the MCT as early as possible. */ - mct_regs->g_tcon |= (1 << 8); - -// mem = clock_get_mem_timings(); -// arm_clk_ratio = get_arm_ratios(); - - clrbits_le32(&clk->src_cpu, MUX_APLL_SEL_MASK); - do { - val = readl(&clk->mux_stat_cpu); - } while ((val | MUX_APLL_SEL_MASK) != val); - - clrbits_le32(&clk->src_core1, MUX_MPLL_SEL_MASK); - do { - val = readl(&clk->mux_stat_core1); - } while ((val | MUX_MPLL_SEL_MASK) != val); - - clrbits_le32(&clk->src_top2, MUX_CPLL_SEL_MASK); - clrbits_le32(&clk->src_top2, MUX_EPLL_SEL_MASK); - clrbits_le32(&clk->src_top2, MUX_VPLL_SEL_MASK); - clrbits_le32(&clk->src_top2, MUX_GPLL_SEL_MASK); - tmp = MUX_CPLL_SEL_MASK | MUX_EPLL_SEL_MASK | MUX_VPLL_SEL_MASK - | MUX_GPLL_SEL_MASK; - do { - val = readl(&clk->mux_stat_top2); - } while ((val | tmp) != val); - - clrbits_le32(&clk->src_cdrex, MUX_BPLL_SEL_MASK); - do { - val = readl(&clk->mux_stat_cdrex); - } while ((val | MUX_BPLL_SEL_MASK) != val); - - /* PLL locktime */ - writel(APLL_LOCK_VAL, &clk->apll_lock); - - writel(MPLL_LOCK_VAL, &clk->mpll_lock); - - writel(BPLL_LOCK_VAL, &clk->bpll_lock); - - writel(CPLL_LOCK_VAL, &clk->cpll_lock); - - writel(GPLL_LOCK_VAL, &clk->gpll_lock); - - writel(EPLL_LOCK_VAL, &clk->epll_lock); - - writel(VPLL_LOCK_VAL, &clk->vpll_lock); - - writel(CLK_REG_DISABLE, &clk->pll_div2_sel); - - writel(MUX_HPM_SEL_MASK, &clk->src_cpu); - do { - val = readl(&clk->mux_stat_cpu); - } while ((val | HPM_SEL_SCLK_MPLL) != val); - - val = arm_clk_ratio->arm2_ratio << 28 - | arm_clk_ratio->apll_ratio << 24 - | arm_clk_ratio->pclk_dbg_ratio << 20 - | arm_clk_ratio->atb_ratio << 16 - | arm_clk_ratio->periph_ratio << 12 - | arm_clk_ratio->acp_ratio << 8 - | arm_clk_ratio->cpud_ratio << 4 - | arm_clk_ratio->arm_ratio; - writel(val, &clk->div_cpu0); - do { - val = readl(&clk->div_stat_cpu0); - } while (0 != val); - - writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1); - do { - val = readl(&clk->div_stat_cpu1); - } while (0 != val); - - /* Set APLL */ - writel(APLL_CON1_VAL, &clk->apll_con1); - val = set_pll(arm_clk_ratio->apll_mdiv, arm_clk_ratio->apll_pdiv, - arm_clk_ratio->apll_sdiv); - writel(val, &clk->apll_con0); - while ((readl(&clk->apll_con0) & APLL_CON0_LOCKED) == 0) - ; - - /* Set MPLL */ - writel(MPLL_CON1_VAL, &clk->mpll_con1); - val = set_pll(mem->mpll_mdiv, mem->mpll_pdiv, mem->mpll_sdiv); - writel(val, &clk->mpll_con0); - while ((readl(&clk->mpll_con0) & MPLL_CON0_LOCKED) == 0) - ; - - /* - * Configure MUX_MPLL_FOUT to choose the direct clock source - * path and avoid the fixed DIV/2 block to save power - */ - setbits_le32(&clk->pll_div2_sel, MUX_MPLL_FOUT_SEL); - - /* Set BPLL */ - if (mem->use_bpll) { - writel(BPLL_CON1_VAL, &clk->bpll_con1); - val = set_pll(mem->bpll_mdiv, mem->bpll_pdiv, mem->bpll_sdiv); - writel(val, &clk->bpll_con0); - while ((readl(&clk->bpll_con0) & BPLL_CON0_LOCKED) == 0) - ; - - setbits_le32(&clk->pll_div2_sel, MUX_BPLL_FOUT_SEL); - } - - /* Set CPLL */ - writel(CPLL_CON1_VAL, &clk->cpll_con1); - val = set_pll(mem->cpll_mdiv, mem->cpll_pdiv, mem->cpll_sdiv); - writel(val, &clk->cpll_con0); - while ((readl(&clk->cpll_con0) & CPLL_CON0_LOCKED) == 0) - ; - - /* Set GPLL */ - writel(GPLL_CON1_VAL, &clk->gpll_con1); - val = set_pll(mem->gpll_mdiv, mem->gpll_pdiv, mem->gpll_sdiv); - writel(val, &clk->gpll_con0); - while ((readl(&clk->gpll_con0) & GPLL_CON0_LOCKED) == 0) - ; - - /* Set EPLL */ - writel(EPLL_CON2_VAL, &clk->epll_con2); - writel(EPLL_CON1_VAL, &clk->epll_con1); - val = set_pll(mem->epll_mdiv, mem->epll_pdiv, mem->epll_sdiv); - writel(val, &clk->epll_con0); - while ((readl(&clk->epll_con0) & EPLL_CON0_LOCKED) == 0) - ; - - /* Set VPLL */ - writel(VPLL_CON2_VAL, &clk->vpll_con2); - writel(VPLL_CON1_VAL, &clk->vpll_con1); - val = set_pll(mem->vpll_mdiv, mem->vpll_pdiv, mem->vpll_sdiv); - writel(val, &clk->vpll_con0); - while ((readl(&clk->vpll_con0) & VPLL_CON0_LOCKED) == 0) - ; - - writel(CLK_SRC_CORE0_VAL, &clk->src_core0); - writel(CLK_DIV_CORE0_VAL, &clk->div_core0); - while (readl(&clk->div_stat_core0) != 0) - ; - - writel(CLK_DIV_CORE1_VAL, &clk->div_core1); - while (readl(&clk->div_stat_core1) != 0) - ; - - writel(CLK_DIV_SYSRGT_VAL, &clk->div_sysrgt); - while (readl(&clk->div_stat_sysrgt) != 0) - ; - - writel(CLK_DIV_ACP_VAL, &clk->div_acp); - while (readl(&clk->div_stat_acp) != 0) - ; - - writel(CLK_DIV_SYSLFT_VAL, &clk->div_syslft); - while (readl(&clk->div_stat_syslft) != 0) - ; - - writel(CLK_SRC_TOP0_VAL, &clk->src_top0); - writel(CLK_SRC_TOP1_VAL, &clk->src_top1); - writel(TOP2_VAL, &clk->src_top2); - writel(CLK_SRC_TOP3_VAL, &clk->src_top3); - - writel(CLK_DIV_TOP0_VAL, &clk->div_top0); - while (readl(&clk->div_stat_top0)) - ; - - writel(CLK_DIV_TOP1_VAL, &clk->div_top1); - while (readl(&clk->div_stat_top1)) - ; - - writel(CLK_SRC_LEX_VAL, &clk->src_lex); - while (1) { - val = readl(&clk->mux_stat_lex); - if (val == (val | 1)) - break; - } - - writel(CLK_DIV_LEX_VAL, &clk->div_lex); - while (readl(&clk->div_stat_lex)) - ; - - writel(CLK_DIV_R0X_VAL, &clk->div_r0x); - while (readl(&clk->div_stat_r0x)) - ; - - writel(CLK_DIV_R0X_VAL, &clk->div_r0x); - while (readl(&clk->div_stat_r0x)) - ; - - writel(CLK_DIV_R1X_VAL, &clk->div_r1x); - while (readl(&clk->div_stat_r1x)) - ; - - if (mem->use_bpll) { - writel(MUX_BPLL_SEL_MASK | MUX_MCLK_CDREX_SEL | - MUX_MCLK_DPHY_SEL, &clk->src_cdrex); - } else { - writel(CLK_REG_DISABLE, &clk->src_cdrex); - } - - writel(CLK_DIV_CDREX_VAL, &clk->div_cdrex); - while (readl(&clk->div_stat_cdrex)) - ; - - val = readl(&clk->src_cpu); - val |= CLK_SRC_CPU_VAL; - writel(val, &clk->src_cpu); - - val = readl(&clk->src_top2); - val |= CLK_SRC_TOP2_VAL; - writel(val, &clk->src_top2); - - val = readl(&clk->src_core1); - val |= CLK_SRC_CORE1_VAL; - writel(val, &clk->src_core1); - - writel(CLK_SRC_FSYS0_VAL, &clk->src_fsys); - writel(CLK_DIV_FSYS0_VAL, &clk->div_fsys0); - while (readl(&clk->div_stat_fsys0)) - ; - - writel(CLK_REG_DISABLE, &clk->clkout_cmu_cpu); - writel(CLK_REG_DISABLE, &clk->clkout_cmu_core); - writel(CLK_REG_DISABLE, &clk->clkout_cmu_acp); - writel(CLK_REG_DISABLE, &clk->clkout_cmu_top); - writel(CLK_REG_DISABLE, &clk->clkout_cmu_lex); - writel(CLK_REG_DISABLE, &clk->clkout_cmu_r0x); - writel(CLK_REG_DISABLE, &clk->clkout_cmu_r1x); - writel(CLK_REG_DISABLE, &clk->clkout_cmu_cdrex); - - writel(CLK_SRC_PERIC0_VAL, &clk->src_peric0); - writel(CLK_DIV_PERIC0_VAL, &clk->div_peric0); - - writel(CLK_SRC_PERIC1_VAL, &clk->src_peric1); - writel(CLK_DIV_PERIC1_VAL, &clk->div_peric1); - writel(CLK_DIV_PERIC2_VAL, &clk->div_peric2); - writel(SCLK_SRC_ISP_VAL, &clk->sclk_src_isp); - writel(SCLK_DIV_ISP_VAL, &clk->sclk_div_isp); - writel(CLK_DIV_ISP0_VAL, &clk->div_isp0); - writel(CLK_DIV_ISP1_VAL, &clk->div_isp1); - writel(CLK_DIV_ISP2_VAL, &clk->div_isp2); - - /* FIMD1 SRC CLK SELECTION */ - writel(CLK_SRC_DISP1_0_VAL, &clk->src_disp1_0); - - val = MMC2_PRE_RATIO_VAL << MMC2_PRE_RATIO_OFFSET - | MMC2_RATIO_VAL << MMC2_RATIO_OFFSET - | MMC3_PRE_RATIO_VAL << MMC3_PRE_RATIO_OFFSET - | MMC3_RATIO_VAL << MMC3_RATIO_OFFSET; - writel(val, &clk->div_fsys2); -} - #include <console/vtxprintf.h> #include <string.h> #define ZEROPAD 1 /* pad with zero */ @@ -1025,12 +638,17 @@ int do_printk(int msg_level, const char *fmt, ...) void bootblock_mainboard_init(void); void bootblock_mainboard_init(void) { + struct mem_timings *mem; + struct arm_clk_ratios *arm_ratios; + /* FIXME: we should not need UART in bootblock, this is only done for testing purposes */ i2c_set_early_reg(I2C0_BASE); i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); power_init(); - clock_init(); + mem = get_mem_timings(); + arm_ratios = get_arm_clk_ratios(); + system_clock_init(mem, arm_ratios); do_serial(); printk(BIOS_INFO, "%s: UART initialized\n", __func__); |