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>
			
			
This commit is contained in:
		
				
					committed by
					
						 Stefan Reinauer
						Stefan Reinauer
					
				
			
			
				
	
			
			
			
						parent
						
							94e230aa93
						
					
				
				
					commit
					0d4f97e270
				
			| @@ -26,17 +26,107 @@ | ||||
| #include <stdlib.h> | ||||
| //#include <fdtdec.h> | ||||
| #include <arch/io.h> | ||||
| //#include <asm/arch/clock.h> | ||||
| //#include <asm/arch/clk.h> | ||||
| #include <cpu/samsung/exynos5-common/clk.h> | ||||
| #include <cpu/samsung/exynos5250/clk.h> | ||||
| #include <cpu/samsung/exynos5250/clock_init.h> | ||||
| #include <cpu/samsung/exynos5250/cpu.h> | ||||
| #include <cpu/samsung/exynos5250/periph.h> | ||||
| #include <cpu/samsung/s5p-common/clk.h> | ||||
|  | ||||
| /* input clock of PLL: SMDK5250 has 24MHz input clock */ | ||||
| #define CONFIG_SYS_CLK_FREQ            24000000 | ||||
|  | ||||
| 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, | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| /* src_bit div_bit prediv_bit */ | ||||
| static struct clk_bit_info clk_bit_info[PERIPH_ID_COUNT] = { | ||||
| @@ -269,6 +359,21 @@ unsigned long get_arm_clk(void) | ||||
| 	return armclk; | ||||
| } | ||||
|  | ||||
| struct arm_clk_ratios *get_arm_clk_ratios(void) | ||||
| { | ||||
| 	struct arm_clk_ratios *arm_ratio; | ||||
| 	unsigned long arm_freq = 1700;	/* FIXME: use get_arm_clk() */ | ||||
| 	int i; | ||||
|  | ||||
| 	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; | ||||
| 	} | ||||
|  | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| /* exynos5: set the mmc clock */ | ||||
| void set_mmc_clk(int dev_index, unsigned int div) | ||||
| { | ||||
|   | ||||
| @@ -29,772 +29,27 @@ | ||||
|  | ||||
| #include <console/console.h> | ||||
|  | ||||
| #include <cpu/samsung/exynos5-common/spl.h> | ||||
| /* FIXME: remove unneeded #includes */ | ||||
| #include <cpu/samsung/exynos5250/clk.h> | ||||
| #include <cpu/samsung/exynos5250/clock_init.h> | ||||
| #include <cpu/samsung/exynos5250/cpu.h> | ||||
| #include <cpu/samsung/exynos5250/dmc.h> | ||||
| #include <cpu/samsung/exynos5250/s5p-dp.h> | ||||
| #include <cpu/samsung/s5p-common/clk.h> | ||||
|  | ||||
| #include "clock_init.h" | ||||
| #include "setup.h" | ||||
|  | ||||
| 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 mem_timings 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, | ||||
| 	}, { | ||||
| 		.mem_manuf = MEM_MANUF_SAMSUNG, | ||||
| 		.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, 0x00010000, 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 = 0x8, | ||||
| 		.phy1_tFS = 0x8, | ||||
| 		.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 = 0x5, | ||||
| 		.zq_mode_term = 0x1, | ||||
| 		.zq_mode_noterm = 1, | ||||
|  | ||||
| 		/* | ||||
| 		* 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_40_OHM, | ||||
| 		.gate_leveling_enable = 1, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.mem_manuf = MEM_MANUF_ELPIDA, | ||||
| 		.mem_type = DDR_MODE_DDR3, | ||||
| 		.frequency_mhz = 780, | ||||
| 		.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 = 0x82, | ||||
| 		.bpll_pdiv = 0x4, | ||||
| 		.bpll_sdiv = 0x0, | ||||
| 		.use_bpll = 1, | ||||
| 		.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, | ||||
| 	}, { | ||||
| 		.mem_manuf = MEM_MANUF_SAMSUNG, | ||||
| 		.mem_type = DDR_MODE_DDR3, | ||||
| 		.frequency_mhz = 780, | ||||
| 		.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 = 0x82, | ||||
| 		.bpll_pdiv = 0x4, | ||||
| 		.bpll_sdiv = 0x0, | ||||
| 		.use_bpll = 1, | ||||
| 		.pclk_cdrex_ratio = 0x5, | ||||
| 		.direct_cmd_msr = { | ||||
| 			0x00020018, 0x00030000, 0x00010000, 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 = 0x8, | ||||
| 		.phy1_tFS = 0x8, | ||||
| 		.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 = 0x5, | ||||
| 		.zq_mode_term = 0x1, | ||||
| 		.zq_mode_noterm = 1, | ||||
|  | ||||
| 		/* | ||||
| 		* 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_40_OHM, | ||||
| 		.gate_leveling_enable = 1, | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Detect what memory is present based on board strappings | ||||
|  * | ||||
|  * Boards have various resistor stuff options that are supposed to match | ||||
|  * which SDRAM is present (and which revision of the board this is).  This | ||||
|  * uses the resistor stuff options to figure out what memory manufacturer | ||||
|  * to use for matching in the memory tables. | ||||
|  * | ||||
|  * @return A MEM_MANUF_XXX constant, or -1 if an error occurred. | ||||
|  */ | ||||
| /* | ||||
|  * FIXME(dhendrix): This unwinds into a mess of board-specific code. The | ||||
|  * board's romstage.c file should detect the memory type and pass in | ||||
|  * appropriate parameters to whatever calls this. | ||||
|  */ | ||||
| #define BOARD_REV_ELPIDA_MEMORY		3 | ||||
| #define BOARD_REV_SAMSUNG_MEMORY	4 | ||||
|  | ||||
| static inline int board_get_revision(void) | ||||
| { | ||||
| 	/* FIXME: yuck! */ | ||||
| 	return BOARD_REV_ELPIDA_MEMORY; | ||||
| } | ||||
|  | ||||
| static int autodetect_memory(void) | ||||
| { | ||||
| 	int board_rev = board_get_revision(); | ||||
|  | ||||
| 	if (board_rev == -1) | ||||
| 		return -1; | ||||
|  | ||||
| 	switch (board_rev) { | ||||
| 	case BOARD_REV_SAMSUNG_MEMORY: | ||||
| 		return MEM_MANUF_SAMSUNG; | ||||
| 	case BOARD_REV_ELPIDA_MEMORY: | ||||
| 		return MEM_MANUF_ELPIDA; | ||||
| 	} | ||||
|  | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| #ifdef CONFIG_SPL_BUILD | ||||
|  | ||||
| #define SIGNATURE	0xdeadbeef | ||||
|  | ||||
| /* Parameters of early board initialization in SPL */ | ||||
| static struct spl_machine_param machine_param = { | ||||
| 	.signature	= SIGNATURE, | ||||
| 	.version	= 1, | ||||
| 	.params		= "vmubfasirMw", | ||||
| 	.size		= sizeof(machine_param), | ||||
|  | ||||
| 	.mem_iv_size	= 0x1f, | ||||
| 	.mem_type	= DDR_MODE_DDR3, | ||||
|  | ||||
| 	/* | ||||
| 	 * Set uboot_size to 0x100000 bytes. | ||||
| 	 * | ||||
| 	 * This is an overly conservative value chosen to accommodate all | ||||
| 	 * possible U-Boot image.  You are advised to set this value to a | ||||
| 	 * smaller realistic size via scripts that modifies the .machine_param | ||||
| 	 * section of output U-Boot image. | ||||
| 	 */ | ||||
| 	.uboot_size	= 0x100000, | ||||
|  | ||||
| 	.boot_source	= BOOT_MODE_OM, | ||||
| 	.frequency_mhz	= 800, | ||||
| 	.arm_freq_mhz	= 1700, | ||||
| 	.serial_base	= 0x12c30000, | ||||
| 	.i2c_base	= 0x12c60000, | ||||
| //	.board_rev_gpios = GPIO_D00 | (GPIO_D01 << 16), | ||||
| 	.mem_manuf	= MEM_MANUF_SAMSUNG, | ||||
| //	.bad_wake_gpio	= GPIO_Y10, | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Get the required memory type and speed (SPL version). | ||||
|  * | ||||
|  * In SPL we have no device tree, so we use the machine parameters | ||||
|  */ | ||||
| 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 = &machine_param; | ||||
| 	*mem_type = params->mem_type; | ||||
| 	*frequency_mhz = params->frequency_mhz; | ||||
| 	*arm_freq = params->arm_freq_mhz; | ||||
| 	if (params->mem_manuf == MEM_MANUF_AUTODETECT) { | ||||
| 		*mem_manuf = autodetect_memory(); | ||||
| 		if (*mem_manuf == -1) | ||||
| 			return -1; | ||||
| 	} else { | ||||
| 		*mem_manuf = params->mem_manuf; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| static const char *mem_types[DDR_MODE_COUNT] = { | ||||
| 	"DDR2", "DDR3", "LPDDR2", "LPDDR3" | ||||
| }; | ||||
|  | ||||
| static const char *mem_manufs[MEM_MANUF_COUNT] = { | ||||
| 	"autodetect", "Elpida", "Samsung" | ||||
| }; | ||||
|  | ||||
| int clock_get_mem_selection(enum ddr_mode *mem_type, | ||||
| 		unsigned *frequency_mhz, unsigned *arm_freq, | ||||
| 		enum mem_manuf *mem_manuf) | ||||
| { | ||||
| 	const char *typestr; | ||||
| 	int node, i; | ||||
|  | ||||
| 	node = fdtdec_next_compatible(gd->fdt_blob, 0, | ||||
| 				      COMPAT_SAMSUNG_EXYNOS_DMC); | ||||
| 	if (node < 0) | ||||
| 		die("No memory information available in device tree"); | ||||
| 	typestr = fdt_getprop(gd->fdt_blob, node, "mem-type", NULL); | ||||
| 	for (i = 0; i < DDR_MODE_COUNT; i++) { | ||||
| 		if (!stricmp(typestr, mem_types[i])) | ||||
| 			break; | ||||
| 	} | ||||
| 	if (i == DDR_MODE_COUNT) | ||||
| 		die("Invalid memory type in device tree"); | ||||
| 	*mem_type = i; | ||||
|  | ||||
| 	typestr = fdt_getprop(gd->fdt_blob, node, "mem-manuf", NULL); | ||||
| 	for (i = 0; i < MEM_MANUF_COUNT; i++) { | ||||
| 		if (!stricmp(typestr, mem_manufs[i])) | ||||
| 			break; | ||||
| 	} | ||||
| 	if (i == MEM_MANUF_COUNT) | ||||
| 		die("Invalid memory manufacturer in device tree"); | ||||
|  | ||||
| 	if (i == MEM_MANUF_AUTODETECT) { | ||||
| 		*mem_manuf = autodetect_memory(); | ||||
| 		if (*mem_manuf == -1) | ||||
| 			return -1; | ||||
| 	} else { | ||||
| 		*mem_manuf = i; | ||||
| 	} | ||||
|  | ||||
| 	*frequency_mhz = fdtdec_get_int(gd->fdt_blob, node, "clock-frequency", | ||||
| 					0); | ||||
| 	if (!*frequency_mhz) | ||||
| 		die("Invalid memory frequency in device tree"); | ||||
|  | ||||
| 	*arm_freq = fdtdec_get_int(gd->fdt_blob, node, "arm-frequency", 0); | ||||
| 	/* TODO: Remove all these panics/dies, and just return an error code */ | ||||
| 	if (!*arm_freq) | ||||
| 		die("Invalid ARM frequency in device tree"); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| const char *clock_get_mem_type_name(enum ddr_mode mem_type) | ||||
| { | ||||
| 	if (mem_type >= 0 && mem_type < DDR_MODE_COUNT) | ||||
| 		return mem_types[mem_type]; | ||||
|  | ||||
| 	return "<unknown>"; | ||||
| } | ||||
|  | ||||
| const char *clock_get_mem_manuf_name(enum mem_manuf mem_manuf) | ||||
| { | ||||
| 	if (mem_manuf >= 0 && mem_manuf < MEM_MANUF_COUNT) | ||||
| 		return mem_manufs[mem_manuf]; | ||||
|  | ||||
| 	return "<unknown>"; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /* Get the ratios for setting ARM clock */ | ||||
| struct arm_clk_ratios *get_arm_ratios(void);	/* FIXME: silence compiler... */ | ||||
| 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; | ||||
|  | ||||
| 	/* TODO(sjg@chromium.org): Return NULL and have caller deal with it */ | ||||
| 	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; | ||||
| 	} | ||||
|  | ||||
| //	die("get_arm_ratios: Failed to find ratio\n"); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| struct mem_timings *clock_get_mem_timings(void) | ||||
| { | ||||
| 	/* FIXME: hard-coded for now */ | ||||
| 	return &mem_timings[0]; | ||||
| #if 0 | ||||
| 	struct mem_timings *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_timings; i < ARRAY_SIZE(mem_timings); | ||||
| 				i++, mem++) { | ||||
| 			if (mem->mem_type == mem_type && | ||||
| 					mem->frequency_mhz == frequency_mhz && | ||||
| 					mem->mem_manuf == mem_manuf) | ||||
| 				return mem; | ||||
| 		} | ||||
| 	} | ||||
| 	return NULL; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void system_clock_init(void) | ||||
| void system_clock_init(struct mem_timings *mem, | ||||
| 		struct arm_clk_ratios *arm_clk_ratio) | ||||
| { | ||||
| 	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; | ||||
| 	struct arm_clk_ratios *arm_clk_ratio; | ||||
| 	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); | ||||
|   | ||||
| @@ -25,10 +25,6 @@ | ||||
| #ifndef __EXYNOS_CLOCK_INIT_H | ||||
| #define __EXYNOS_CLOCK_INIT_H | ||||
|  | ||||
| enum { | ||||
| 	MEM_TIMINGS_MSR_COUNT	= 4, | ||||
| }; | ||||
|  | ||||
| /* These are the ratio's for configuring ARM clock */ | ||||
| struct arm_clk_ratios { | ||||
| 	unsigned int arm_freq_mhz;	/* Frequency of ARM core in MHz */ | ||||
| @@ -47,104 +43,17 @@ struct arm_clk_ratios { | ||||
| 	unsigned int arm_ratio; | ||||
| }; | ||||
|  | ||||
| /* These are the memory timings for a particular memory type and speed */ | ||||
| struct mem_timings { | ||||
| 	enum mem_manuf mem_manuf;	/* Memory manufacturer */ | ||||
| 	enum ddr_mode mem_type;		/* Memory type */ | ||||
| 	unsigned int frequency_mhz;	/* Frequency of memory in MHz */ | ||||
|  | ||||
| 	/* Here follow the timing parameters for the selected memory */ | ||||
| 	uint8_t apll_mdiv; | ||||
| 	uint8_t apll_pdiv; | ||||
| 	uint8_t apll_sdiv; | ||||
| 	uint8_t mpll_mdiv; | ||||
| 	uint8_t mpll_pdiv; | ||||
| 	uint8_t mpll_sdiv; | ||||
| 	uint8_t cpll_mdiv; | ||||
| 	uint8_t cpll_pdiv; | ||||
| 	uint8_t cpll_sdiv; | ||||
| 	uint8_t gpll_pdiv; | ||||
| 	uint16_t gpll_mdiv; | ||||
| 	uint8_t gpll_sdiv; | ||||
| 	uint8_t epll_mdiv; | ||||
| 	uint8_t epll_pdiv; | ||||
| 	uint8_t epll_sdiv; | ||||
| 	uint8_t vpll_mdiv; | ||||
| 	uint8_t vpll_pdiv; | ||||
| 	uint8_t vpll_sdiv; | ||||
| 	uint8_t bpll_mdiv; | ||||
| 	uint8_t bpll_pdiv; | ||||
| 	uint8_t bpll_sdiv; | ||||
| 	uint8_t use_bpll;       /* 1 to use BPLL for cdrex, 0 to use MPLL */ | ||||
| 	uint8_t pclk_cdrex_ratio; | ||||
| 	unsigned int direct_cmd_msr[MEM_TIMINGS_MSR_COUNT]; | ||||
|  | ||||
| 	unsigned int timing_ref; | ||||
| 	unsigned int timing_row; | ||||
| 	unsigned int timing_data; | ||||
| 	unsigned int timing_power; | ||||
|  | ||||
| 	/* DQS, DQ, DEBUG offsets */ | ||||
| 	unsigned int phy0_dqs; | ||||
| 	unsigned int phy1_dqs; | ||||
| 	unsigned int phy0_dq; | ||||
| 	unsigned int phy1_dq; | ||||
| 	uint8_t phy0_tFS; | ||||
| 	uint8_t phy1_tFS; | ||||
| 	uint8_t phy0_pulld_dqs; | ||||
| 	uint8_t phy1_pulld_dqs; | ||||
|  | ||||
| 	uint8_t lpddr3_ctrl_phy_reset; | ||||
| 	uint8_t ctrl_start_point; | ||||
| 	uint8_t ctrl_inc; | ||||
| 	uint8_t ctrl_start; | ||||
| 	uint8_t ctrl_dll_on; | ||||
| 	uint8_t ctrl_ref; | ||||
|  | ||||
| 	uint8_t ctrl_force; | ||||
| 	uint8_t ctrl_rdlat; | ||||
| 	uint8_t ctrl_bstlen; | ||||
|  | ||||
| 	uint8_t fp_resync; | ||||
| 	uint8_t iv_size; | ||||
| 	uint8_t dfi_init_start; | ||||
| 	uint8_t aref_en; | ||||
|  | ||||
| 	uint8_t rd_fetch; | ||||
|  | ||||
| 	uint8_t zq_mode_dds; | ||||
| 	uint8_t zq_mode_term; | ||||
| 	uint8_t zq_mode_noterm;	/* 1 to allow termination disable */ | ||||
|  | ||||
| 	unsigned int memcontrol; | ||||
| 	unsigned int memconfig; | ||||
|  | ||||
| 	unsigned int membaseconfig0; | ||||
| 	unsigned int membaseconfig1; | ||||
| 	unsigned int prechconfig_tp_cnt; | ||||
| 	unsigned int dpwrdn_cyc; | ||||
| 	unsigned int dsref_cyc; | ||||
| 	unsigned int concontrol; | ||||
| 	/* Channel and Chip Selection */ | ||||
| 	uint8_t dmc_channels;		/* number of memory channels */ | ||||
| 	uint8_t chips_per_channel;	/* number of chips per channel */ | ||||
| 	uint8_t chips_to_configure;	/* number of chips to configure */ | ||||
| 	uint8_t send_zq_init;		/* 1 to send this command */ | ||||
| 	unsigned int impedance;		/* drive strength impedeance */ | ||||
| 	uint8_t gate_leveling_enable;	/* check gate leveling is enabled */ | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Get the correct memory timings for our selected memory type and speed. | ||||
|  * Get the clock ratios for CPU configuration | ||||
|  * | ||||
|  * This function can be called from SPL or the main U-Boot. | ||||
|  * | ||||
|  * @return pointer to the memory timings that we should use | ||||
|  * @return pointer to the clock ratios that we should use | ||||
|  */ | ||||
| struct mem_timings *clock_get_mem_timings(void); | ||||
| struct arm_clk_ratios *get_arm_clk_ratios(void); | ||||
|  | ||||
| /* | ||||
|  * Initialize clock for the device | ||||
|  */ | ||||
| void system_clock_init(void); | ||||
| struct mem_timings; | ||||
| void system_clock_init(struct mem_timings *mem, | ||||
| 		struct arm_clk_ratios *arm_clk_ratio); | ||||
| #endif | ||||
|   | ||||
| @@ -175,6 +175,10 @@ enum mem_manuf { | ||||
| 	MEM_MANUF_COUNT = 2, // fancy that. | ||||
| }; | ||||
|  | ||||
| enum { | ||||
| 	MEM_TIMINGS_MSR_COUNT	= 4, | ||||
| }; | ||||
|  | ||||
| #define DMC_INTERLEAVE_SIZE		0x1f | ||||
|  | ||||
| /* CONCONTROL register fields */ | ||||
| @@ -224,5 +228,99 @@ enum mem_manuf { | ||||
| #define PHY_CON42_CTRL_RDLAT_SHIFT	0 | ||||
| #define PHY_CON42_CTRL_RDLAT_MASK	(0x1f << PHY_CON42_CTRL_RDLAT_SHIFT) | ||||
|  | ||||
| /* These are the memory timings for a particular memory type and speed */ | ||||
| struct mem_timings { | ||||
| 	enum mem_manuf mem_manuf;	/* Memory manufacturer */ | ||||
| 	enum ddr_mode mem_type;		/* Memory type */ | ||||
| 	unsigned int frequency_mhz;	/* Frequency of memory in MHz */ | ||||
|  | ||||
| 	/* Here follow the timing parameters for the selected memory */ | ||||
| 	uint8_t apll_mdiv; | ||||
| 	uint8_t apll_pdiv; | ||||
| 	uint8_t apll_sdiv; | ||||
| 	uint8_t mpll_mdiv; | ||||
| 	uint8_t mpll_pdiv; | ||||
| 	uint8_t mpll_sdiv; | ||||
| 	uint8_t cpll_mdiv; | ||||
| 	uint8_t cpll_pdiv; | ||||
| 	uint8_t cpll_sdiv; | ||||
| 	uint8_t gpll_pdiv; | ||||
| 	uint16_t gpll_mdiv; | ||||
| 	uint8_t gpll_sdiv; | ||||
| 	uint8_t epll_mdiv; | ||||
| 	uint8_t epll_pdiv; | ||||
| 	uint8_t epll_sdiv; | ||||
| 	uint8_t vpll_mdiv; | ||||
| 	uint8_t vpll_pdiv; | ||||
| 	uint8_t vpll_sdiv; | ||||
| 	uint8_t bpll_mdiv; | ||||
| 	uint8_t bpll_pdiv; | ||||
| 	uint8_t bpll_sdiv; | ||||
| 	uint8_t use_bpll;       /* 1 to use BPLL for cdrex, 0 to use MPLL */ | ||||
| 	uint8_t pclk_cdrex_ratio; | ||||
| 	unsigned int direct_cmd_msr[MEM_TIMINGS_MSR_COUNT]; | ||||
|  | ||||
| 	unsigned int timing_ref; | ||||
| 	unsigned int timing_row; | ||||
| 	unsigned int timing_data; | ||||
| 	unsigned int timing_power; | ||||
|  | ||||
| 	/* DQS, DQ, DEBUG offsets */ | ||||
| 	unsigned int phy0_dqs; | ||||
| 	unsigned int phy1_dqs; | ||||
| 	unsigned int phy0_dq; | ||||
| 	unsigned int phy1_dq; | ||||
| 	uint8_t phy0_tFS; | ||||
| 	uint8_t phy1_tFS; | ||||
| 	uint8_t phy0_pulld_dqs; | ||||
| 	uint8_t phy1_pulld_dqs; | ||||
|  | ||||
| 	uint8_t lpddr3_ctrl_phy_reset; | ||||
| 	uint8_t ctrl_start_point; | ||||
| 	uint8_t ctrl_inc; | ||||
| 	uint8_t ctrl_start; | ||||
| 	uint8_t ctrl_dll_on; | ||||
| 	uint8_t ctrl_ref; | ||||
|  | ||||
| 	uint8_t ctrl_force; | ||||
| 	uint8_t ctrl_rdlat; | ||||
| 	uint8_t ctrl_bstlen; | ||||
|  | ||||
| 	uint8_t fp_resync; | ||||
| 	uint8_t iv_size; | ||||
| 	uint8_t dfi_init_start; | ||||
| 	uint8_t aref_en; | ||||
|  | ||||
| 	uint8_t rd_fetch; | ||||
|  | ||||
| 	uint8_t zq_mode_dds; | ||||
| 	uint8_t zq_mode_term; | ||||
| 	uint8_t zq_mode_noterm;	/* 1 to allow termination disable */ | ||||
|  | ||||
| 	unsigned int memcontrol; | ||||
| 	unsigned int memconfig; | ||||
|  | ||||
| 	unsigned int membaseconfig0; | ||||
| 	unsigned int membaseconfig1; | ||||
| 	unsigned int prechconfig_tp_cnt; | ||||
| 	unsigned int dpwrdn_cyc; | ||||
| 	unsigned int dsref_cyc; | ||||
| 	unsigned int concontrol; | ||||
| 	/* Channel and Chip Selection */ | ||||
| 	uint8_t dmc_channels;		/* number of memory channels */ | ||||
| 	uint8_t chips_per_channel;	/* number of chips per channel */ | ||||
| 	uint8_t chips_to_configure;	/* number of chips to configure */ | ||||
| 	uint8_t send_zq_init;		/* 1 to send this command */ | ||||
| 	unsigned int impedance;		/* drive strength impedeance */ | ||||
| 	uint8_t gate_leveling_enable;	/* check gate leveling is enabled */ | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Get the correct memory timings for our selected memory type and speed. | ||||
|  * | ||||
|  * @return pointer to the memory timings that we should use | ||||
|  */ | ||||
| struct mem_timings *get_mem_timings(void); | ||||
|  | ||||
| #endif | ||||
| #endif | ||||
|   | ||||
| @@ -20,6 +20,7 @@ | ||||
|  | ||||
| /* FIXME(dhendrix): fix this up so it doesn't require a bunch of #ifdefs... */ | ||||
| #include <common.h> | ||||
| #include <gpio.h> | ||||
| //#include <arch/io.h> | ||||
| #include <gpio.h> | ||||
| #include <arch/gpio.h> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user