This patch subtracts a part of clock init from spl and executes it after relocation. spl_clock_init executes in spl and system_clock_init executes after relocation in u-boot. This is done to gain some space by removing initially not necessary code.
Signed-off-by: Akshay Saraswat <aksha...@samsung.com> --- board/samsung/smdk5250/Makefile | 3 +- board/samsung/smdk5250/clock_init.c | 429 +--------------------------- board/samsung/smdk5250/clock_init.h | 2 + board/samsung/smdk5250/lowlevel_init.S | 4 +- board/samsung/smdk5250/setup.h | 1 + board/samsung/smdk5250/smdk5250.c | 4 + board/samsung/smdk5250/spl_clock_init.c | 469 +++++++++++++++++++++++++++++++ 7 files changed, 482 insertions(+), 430 deletions(-) create mode 100644 board/samsung/smdk5250/spl_clock_init.c diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile index 47c6a5a..3ceb7e2 100644 --- a/board/samsung/smdk5250/Makefile +++ b/board/samsung/smdk5250/Makefile @@ -26,12 +26,13 @@ LIB = $(obj)lib$(BOARD).o SOBJS := lowlevel_init.o -COBJS := clock_init.o +COBJS := spl_clock_init.o COBJS += dmc_common.o dmc_init_ddr3.o COBJS += tzpc_init.o COBJS += smdk5250_spl.o ifndef CONFIG_SPL_BUILD +COBJS += clock_init.o COBJS += smdk5250.o endif diff --git a/board/samsung/smdk5250/clock_init.c b/board/samsung/smdk5250/clock_init.c index 30cbdcf..fe3cd8a 100644 --- a/board/samsung/smdk5250/clock_init.c +++ b/board/samsung/smdk5250/clock_init.c @@ -34,109 +34,6 @@ DECLARE_GLOBAL_DATA_PTR; -struct arm_clk_ratios arm_clk_ratios[] = { - { - .arm_freq_mhz = 600, - - .apll_mdiv = 0xc8, - .apll_pdiv = 0x4, - .apll_sdiv = 0x1, - - .arm2_ratio = 0x0, - .apll_ratio = 0x1, - .pclk_dbg_ratio = 0x1, - .atb_ratio = 0x2, - .periph_ratio = 0x7, - .acp_ratio = 0x7, - .cpud_ratio = 0x1, - .arm_ratio = 0x0, - }, { - .arm_freq_mhz = 800, - - .apll_mdiv = 0x64, - .apll_pdiv = 0x3, - .apll_sdiv = 0x0, - - .arm2_ratio = 0x0, - .apll_ratio = 0x1, - .pclk_dbg_ratio = 0x1, - .atb_ratio = 0x3, - .periph_ratio = 0x7, - .acp_ratio = 0x7, - .cpud_ratio = 0x2, - .arm_ratio = 0x0, - }, { - .arm_freq_mhz = 1000, - - .apll_mdiv = 0x7d, - .apll_pdiv = 0x3, - .apll_sdiv = 0x0, - - .arm2_ratio = 0x0, - .apll_ratio = 0x1, - .pclk_dbg_ratio = 0x1, - .atb_ratio = 0x4, - .periph_ratio = 0x7, - .acp_ratio = 0x7, - .cpud_ratio = 0x2, - .arm_ratio = 0x0, - }, { - .arm_freq_mhz = 1200, - - .apll_mdiv = 0x96, - .apll_pdiv = 0x3, - .apll_sdiv = 0x0, - - .arm2_ratio = 0x0, - .apll_ratio = 0x3, - .pclk_dbg_ratio = 0x1, - .atb_ratio = 0x5, - .periph_ratio = 0x7, - .acp_ratio = 0x7, - .cpud_ratio = 0x3, - .arm_ratio = 0x0, - }, { - .arm_freq_mhz = 1400, - - .apll_mdiv = 0xaf, - .apll_pdiv = 0x3, - .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, - }, { - .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, - } -}; - -struct spl_clock_div spl_clock_div = { - .mpll_mdiv = 0xc8, - .mpll_pdiv = 0x3, - .mpll_sdiv = 0x0, - .bpll_mdiv = 0x64, - .bpll_pdiv = 0x3, - .bpll_sdiv = 0x0, -}; - struct non_spl_clock_div non_spl_clock_div = { .cpll_mdiv = 0xde, .cpll_pdiv = 0x4, @@ -152,255 +49,20 @@ struct non_spl_clock_div non_spl_clock_div = { .vpll_sdiv = 0x2, }; -struct mem_timings mem_timings = { - .pclk_cdrex_ratio = 0x5, - .timing_ref = 0x000000bb, - .timing_row = 0x8c36650e, - .timing_data = 0x3630580b, - .timing_power = 0x41000a44, - .phy0_dqs = 0x08080808, - .phy1_dqs = 0x08080808, - .phy0_dq = 0x08080808, - .phy1_dq = 0x08080808, - .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, - - /* - * 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, -}; - -struct mem_params mem_params[] = { - { - .mem_manuf = MEM_MANUF_ELPIDA, - .mem_type = DDR_MODE_DDR3, - .frequency_mhz = 800, - - .direct_cmd_msr = { - 0x00020018, 0x00030000, 0x00010042, 0x00000d70 - }, - - .phy0_tFS = 0x4, - .phy1_tFS = 0x4, - - .zq_mode_dds = 0x7, - .zq_mode_term = 0x1, - .zq_mode_noterm = 0, - - .impedance = IMP_OUTPUT_DRV_30_OHM, - .gate_leveling_enable = 0, - }, { - .mem_manuf = MEM_MANUF_SAMSUNG, - .mem_type = DDR_MODE_DDR3, - .frequency_mhz = 800, - - .direct_cmd_msr = { - 0x00020018, 0x00030000, 0x00010000, 0x00000d70 - }, - - .phy0_tFS = 0x8, - .phy1_tFS = 0x8, - - .zq_mode_dds = 0x5, - .zq_mode_term = 0x1, - .zq_mode_noterm = 1, - - .impedance = IMP_OUTPUT_DRV_40_OHM, - .gate_leveling_enable = 1, - } -}; - - -/** - * Get the required memory type and speed (SPL version). - * - * In SPL we have no device tree, so we use the machine parameters - * - * @param mem_type Returns memory type - * @param frequency_mhz Returns memory speed in MHz - * @param arm_freq Returns ARM clock speed in MHz - * @param mem_manuf Return Memory Manufacturer name - * @return 0 if all ok - */ -static int clock_get_mem_selection(enum ddr_mode *mem_type, - unsigned *frequency_mhz, unsigned *arm_freq, - enum mem_manuf *mem_manuf) -{ - struct spl_machine_param *params; - - params = spl_get_machine_params(); - *mem_type = params->mem_type; - *frequency_mhz = params->frequency_mhz; - *arm_freq = params->arm_freq_mhz; - *mem_manuf = params->mem_manuf; - - return 0; -} - -/* Get the ratios for setting ARM clock */ -struct arm_clk_ratios *get_arm_ratios(void) -{ - struct arm_clk_ratios *arm_ratio; - enum ddr_mode mem_type; - enum mem_manuf mem_manuf; - unsigned frequency_mhz, arm_freq; - int i; - - if (clock_get_mem_selection(&mem_type, &frequency_mhz, - &arm_freq, &mem_manuf)) - ; - for (i = 0, arm_ratio = arm_clk_ratios; i < ARRAY_SIZE(arm_clk_ratios); - i++, arm_ratio++) { - if (arm_ratio->arm_freq_mhz == arm_freq) - return arm_ratio; - } - - /* will hang if failed to find clock ratio */ - while (1) - ; - - return NULL; -} - -struct spl_clock_div *clock_get_spl_div(void) -{ - return &spl_clock_div; -} - struct non_spl_clock_div *clock_get_non_spl_div(void) { return &non_spl_clock_div; } -struct mem_timings *clock_get_mem_timings(void) -{ - return &mem_timings; -} - -struct mem_params *clock_get_mem_params(void) -{ - struct mem_params *mem; - enum ddr_mode mem_type; - enum mem_manuf mem_manuf; - unsigned frequency_mhz, arm_freq; - int i; - - if (!clock_get_mem_selection(&mem_type, &frequency_mhz, - &arm_freq, &mem_manuf)) { - for (i = 0, mem = mem_params; i < ARRAY_SIZE(mem_params); - i++, mem++) { - if (mem->mem_type == mem_type && - mem->frequency_mhz == frequency_mhz && - mem->mem_manuf == mem_manuf) - return mem; - } - } - - /* will hang if failed to find memory timings */ - while (1) - ; - - return NULL; -} - void system_clock_init() { struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; - struct arm_clk_ratios *arm_clk_ratio; - struct spl_clock_div *s_clk_div; struct non_spl_clock_div *ns_clk_div; - u32 val, tmp; + u32 val; - arm_clk_ratio = get_arm_ratios(); - s_clk_div = clock_get_spl_div(); ns_clk_div = clock_get_non_spl_div(); - 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_core1, MUX_CPLL_SEL_MASK); - clrbits_le32(&clk->src_core1, MUX_EPLL_SEL_MASK); - clrbits_le32(&clk->src_core1, MUX_VPLL_SEL_MASK); - clrbits_le32(&clk->src_core1, 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); @@ -409,55 +71,6 @@ void system_clock_init() 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) - ; - - /* Set MPLL */ - writel(MPLL_CON1_VAL, &clk->mpll_con1); - val = set_pll(s_clk_div->mpll_mdiv, - s_clk_div->mpll_pdiv, s_clk_div->mpll_sdiv); - writel(val, &clk->mpll_con0); - while (readl(&clk->mpll_con0) & MPLL_CON0_LOCKED) - ; - - /* Set BPLL */ - writel(BPLL_CON1_VAL, &clk->bpll_con1); - val = set_pll(s_clk_div->bpll_mdiv, - s_clk_div->bpll_pdiv, s_clk_div->bpll_sdiv); - writel(val, &clk->bpll_con0); - while (readl(&clk->bpll_con0) & BPLL_CON0_LOCKED) - ; - /* Set CPLL */ writel(CPLL_CON1_VAL, &clk->cpll_con1); val = set_pll(ns_clk_div->cpll_mdiv, @@ -488,19 +101,11 @@ void system_clock_init() writel(VPLL_CON1_VAL, &clk->vpll_con1); val = set_pll(ns_clk_div->vpll_mdiv, ns_clk_div->vpll_pdiv, ns_clk_div->vpll_sdiv); + writel(val, &clk->vpll_con0); while (readl(&clk->vpll_con0) & VPLL_CON0_LOCKED) ; - 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) ; @@ -549,29 +154,10 @@ void system_clock_init() while (readl(&clk->div_stat_r1x)) ; - 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); @@ -604,14 +190,3 @@ void system_clock_init() | MMC3_RATIO_VAL << MMC3_RATIO_OFFSET; writel(val, &clk->div_fsys2); } - -void clock_init_dp_clock(void) -{ - struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; - - /* DP clock enable */ - setbits_le32(&clk->gate_ip_disp1, CLK_GATE_DP1_ALLOW); - - /* We run DP at 267 Mhz */ - setbits_le32(&clk->div_disp1_0, CLK_DIV_DISP1_0_FIMD1); -} diff --git a/board/samsung/smdk5250/clock_init.h b/board/samsung/smdk5250/clock_init.h index 12b5c55..03580d8 100644 --- a/board/samsung/smdk5250/clock_init.h +++ b/board/samsung/smdk5250/clock_init.h @@ -162,5 +162,7 @@ struct mem_params *clock_get_mem_params(void); /* * Initialize clock for the device */ +void spl_clock_init(void); + void system_clock_init(void); #endif diff --git a/board/samsung/smdk5250/lowlevel_init.S b/board/samsung/smdk5250/lowlevel_init.S index bc6cb6f..1e69c02 100644 --- a/board/samsung/smdk5250/lowlevel_init.S +++ b/board/samsung/smdk5250/lowlevel_init.S @@ -69,7 +69,7 @@ lowlevel_init: beq 1f /* r0 == r1 then skip sdram init */ /* init system clock */ - bl system_clock_init + bl spl_clock_init /* Memory initialize */ bl mem_ctrl_init @@ -79,7 +79,7 @@ lowlevel_init: ldmia r13!, {ip,pc} wakeup_reset: - bl system_clock_init + bl spl_clock_init bl mem_ctrl_init bl tzpc_init diff --git a/board/samsung/smdk5250/setup.h b/board/samsung/smdk5250/setup.h index b30d7d0..074219f 100644 --- a/board/samsung/smdk5250/setup.h +++ b/board/samsung/smdk5250/setup.h @@ -595,5 +595,6 @@ void update_reset_dll(struct exynos5_dmc *, enum ddr_mode); void sdelay(unsigned long); void mem_ctrl_init(void); void system_clock_init(void); +void spl_clock_init(void); void tzpc_init(void); #endif diff --git a/board/samsung/smdk5250/smdk5250.c b/board/samsung/smdk5250/smdk5250.c index 7a5f132..01a1b5b 100644 --- a/board/samsung/smdk5250/smdk5250.c +++ b/board/samsung/smdk5250/smdk5250.c @@ -28,6 +28,7 @@ #include <netdev.h> #include <spi.h> #include <asm/arch/cpu.h> +#include <asm/arch/dmc.h> #include <asm/arch/gpio.h> #include <asm/arch/mmc.h> #include <asm/arch/pinmux.h> @@ -35,6 +36,7 @@ #include <asm/arch/sromc.h> #include <asm/arch/dp_info.h> #include <power/pmic.h> +#include "clock_init.h" DECLARE_GLOBAL_DATA_PTR; @@ -269,6 +271,8 @@ static int board_uart_init(void) int board_early_init_f(void) { int err; + + system_clock_init(); err = board_uart_init(); if (err) { debug("UART init failed\n"); diff --git a/board/samsung/smdk5250/spl_clock_init.c b/board/samsung/smdk5250/spl_clock_init.c new file mode 100644 index 0000000..cd6146e --- /dev/null +++ b/board/samsung/smdk5250/spl_clock_init.c @@ -0,0 +1,469 @@ +/* + * Clock setup for SMDK5250 board based on EXYNOS5 + * + * Copyright (C) 2012 Samsung Electronics + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <config.h> +#include <asm/io.h> +#include <asm/arch/clk.h> +#include <asm/arch/clock.h> +#include <asm/arch/spl.h> + +#include "clock_init.h" +#include "setup.h" + +DECLARE_GLOBAL_DATA_PTR; + +struct arm_clk_ratios arm_clk_ratios[] = { + { + .arm_freq_mhz = 600, + + .apll_mdiv = 0xc8, + .apll_pdiv = 0x4, + .apll_sdiv = 0x1, + + .arm2_ratio = 0x0, + .apll_ratio = 0x1, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x2, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x1, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 800, + + .apll_mdiv = 0x64, + .apll_pdiv = 0x3, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x1, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x3, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x2, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 1000, + + .apll_mdiv = 0x7d, + .apll_pdiv = 0x3, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x1, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x4, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x2, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 1200, + + .apll_mdiv = 0x96, + .apll_pdiv = 0x3, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x3, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x5, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x3, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 1400, + + .apll_mdiv = 0xaf, + .apll_pdiv = 0x3, + .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, + }, { + .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, + } +}; + +struct spl_clock_div spl_clock_div = { + .mpll_mdiv = 0xc8, + .mpll_pdiv = 0x3, + .mpll_sdiv = 0x0, + .bpll_mdiv = 0x64, + .bpll_pdiv = 0x3, + .bpll_sdiv = 0x0, +}; + +struct mem_timings mem_timings = { + .pclk_cdrex_ratio = 0x5, + .timing_ref = 0x000000bb, + .timing_row = 0x8c36650e, + .timing_data = 0x3630580b, + .timing_power = 0x41000a44, + .phy0_dqs = 0x08080808, + .phy1_dqs = 0x08080808, + .phy0_dq = 0x08080808, + .phy1_dq = 0x08080808, + .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, + + /* + * 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, +}; + +struct mem_params mem_params[] = { + { + .mem_manuf = MEM_MANUF_ELPIDA, + .mem_type = DDR_MODE_DDR3, + .frequency_mhz = 800, + + .direct_cmd_msr = { + 0x00020018, 0x00030000, 0x00010042, 0x00000d70 + }, + + .phy0_tFS = 0x4, + .phy1_tFS = 0x4, + + .zq_mode_dds = 0x7, + .zq_mode_term = 0x1, + .zq_mode_noterm = 0, + + .impedance = IMP_OUTPUT_DRV_30_OHM, + .gate_leveling_enable = 0, + }, { + .mem_manuf = MEM_MANUF_SAMSUNG, + .mem_type = DDR_MODE_DDR3, + .frequency_mhz = 800, + + .direct_cmd_msr = { + 0x00020018, 0x00030000, 0x00010000, 0x00000d70 + }, + + .phy0_tFS = 0x8, + .phy1_tFS = 0x8, + + .zq_mode_dds = 0x5, + .zq_mode_term = 0x1, + .zq_mode_noterm = 1, + + .impedance = IMP_OUTPUT_DRV_40_OHM, + .gate_leveling_enable = 1, + } +}; + + +/** + * Get the required memory type and speed (SPL version). + * + * In SPL we have no device tree, so we use the machine parameters + * + * @param mem_type Returns memory type + * @param frequency_mhz Returns memory speed in MHz + * @param arm_freq Returns ARM clock speed in MHz + * @param mem_manuf Return Memory Manufacturer name + * @return 0 if all ok + */ +static int clock_get_mem_selection(enum ddr_mode *mem_type, + unsigned *frequency_mhz, unsigned *arm_freq, + enum mem_manuf *mem_manuf) +{ + struct spl_machine_param *params; + + params = spl_get_machine_params(); + *mem_type = params->mem_type; + *frequency_mhz = params->frequency_mhz; + *arm_freq = params->arm_freq_mhz; + *mem_manuf = params->mem_manuf; + + return 0; +} + +/* Get the ratios for setting ARM clock */ +struct arm_clk_ratios *get_arm_ratios(void) +{ + struct arm_clk_ratios *arm_ratio; + enum ddr_mode mem_type; + enum mem_manuf mem_manuf; + unsigned frequency_mhz, arm_freq; + int i; + + if (clock_get_mem_selection(&mem_type, &frequency_mhz, + &arm_freq, &mem_manuf)) + ; + for (i = 0, arm_ratio = arm_clk_ratios; i < ARRAY_SIZE(arm_clk_ratios); + i++, arm_ratio++) { + if (arm_ratio->arm_freq_mhz == arm_freq) + return arm_ratio; + } + + /* will hang if failed to find clock ratio */ + while (1) + ; + + return NULL; +} + +struct spl_clock_div *clock_get_spl_div(void) +{ + return &spl_clock_div; +} + +struct mem_timings *clock_get_mem_timings(void) +{ + return &mem_timings; +} + +struct mem_params *clock_get_mem_params(void) +{ + struct mem_params *mem; + enum ddr_mode mem_type; + enum mem_manuf mem_manuf; + unsigned frequency_mhz, arm_freq; + int i; + + if (!clock_get_mem_selection(&mem_type, &frequency_mhz, + &arm_freq, &mem_manuf)) { + for (i = 0, mem = mem_params; i < ARRAY_SIZE(mem_params); + i++, mem++) { + if (mem->mem_type == mem_type && + mem->frequency_mhz == frequency_mhz && + mem->mem_manuf == mem_manuf) + return mem; + } + } + + /* will hang if failed to find memory timings */ + while (1) + ; + + return NULL; +} + +void spl_clock_init() +{ + struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; + struct arm_clk_ratios *arm_clk_ratio; + struct spl_clock_div *s_clk_div; + u32 val, tmp; + + arm_clk_ratio = get_arm_ratios(); + s_clk_div = clock_get_spl_div(); + + 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_core1, MUX_CPLL_SEL_MASK); + clrbits_le32(&clk->src_core1, MUX_EPLL_SEL_MASK); + clrbits_le32(&clk->src_core1, MUX_VPLL_SEL_MASK); + clrbits_le32(&clk->src_core1, 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(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) + ; + + /* Set MPLL */ + writel(MPLL_CON1_VAL, &clk->mpll_con1); + val = set_pll(s_clk_div->mpll_mdiv, + s_clk_div->mpll_pdiv, s_clk_div->mpll_sdiv); + writel(val, &clk->mpll_con0); + while (readl(&clk->mpll_con0) & MPLL_CON0_LOCKED) + ; + + /* Set BPLL */ + writel(BPLL_CON1_VAL, &clk->bpll_con1); + val = set_pll(s_clk_div->bpll_mdiv, + s_clk_div->bpll_pdiv, s_clk_div->bpll_sdiv); + writel(val, &clk->bpll_con0); + while (readl(&clk->bpll_con0) & BPLL_CON0_LOCKED) + ; + + 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_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_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)) + ; +} + +void clock_init_dp_clock(void) +{ + struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; + + /* DP clock enable */ + setbits_le32(&clk->gate_ip_disp1, CLK_GATE_DP1_ALLOW); + + /* We run DP at 267 Mhz */ + setbits_le32(&clk->div_disp1_0, CLK_DIV_DISP1_0_FIMD1); +} -- 1.7.9.5 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot