diff options
Diffstat (limited to 'board/samsung')
| -rw-r--r-- | board/samsung/common/Makefile | 43 | ||||
| -rw-r--r-- | board/samsung/common/multi_i2c.c | 65 | ||||
| -rw-r--r-- | board/samsung/goni/lowlevel_init.S | 120 | ||||
| -rw-r--r-- | board/samsung/smdk5250/Makefile | 3 | ||||
| -rw-r--r-- | board/samsung/smdk5250/clock_init.c | 672 | ||||
| -rw-r--r-- | board/samsung/smdk5250/clock_init.h | 149 | ||||
| -rw-r--r-- | board/samsung/smdk5250/dmc_common.c | 199 | ||||
| -rw-r--r-- | board/samsung/smdk5250/dmc_init.c | 462 | ||||
| -rw-r--r-- | board/samsung/smdk5250/dmc_init_ddr3.c | 228 | ||||
| -rw-r--r-- | board/samsung/smdk5250/setup.h | 739 | ||||
| -rw-r--r-- | board/samsung/smdk5250/smdk5250-uboot-spl.lds | 66 | ||||
| -rw-r--r-- | board/samsung/smdk5250/smdk5250.c | 6 | ||||
| -rw-r--r-- | board/samsung/smdk5250/smdk5250_spl.c | 68 | ||||
| -rw-r--r-- | board/samsung/smdkc100/lowlevel_init.S | 42 | ||||
| -rw-r--r-- | board/samsung/trats/trats.c | 23 | 
15 files changed, 1855 insertions, 1030 deletions
| diff --git a/board/samsung/common/Makefile b/board/samsung/common/Makefile new file mode 100644 index 000000000..0bcd5949a --- /dev/null +++ b/board/samsung/common/Makefile @@ -0,0 +1,43 @@ +# +# Copyright (C) 2012 Samsung Electronics +# Lukasz Majewski <l.majewski@samsung.com> +# +# 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 $(TOPDIR)/config.mk + +LIB	= $(obj)libsamsung.o + +COBJS-$(CONFIG_SOFT_I2C_MULTI_BUS) += multi_i2c.o + +SRCS    := $(COBJS-y:.o=.c) +OBJS	:= $(addprefix $(obj),$(COBJS-y)) + +$(LIB):	$(obj).depend $(OBJS) +	$(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/samsung/common/multi_i2c.c b/board/samsung/common/multi_i2c.c new file mode 100644 index 000000000..d6c3d37bb --- /dev/null +++ b/board/samsung/common/multi_i2c.c @@ -0,0 +1,65 @@ +/* + *  Copyright (C) 2012 Samsung Electronics + *  Lukasz Majewski <l.majewski@samsung.com> + * + * 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 <i2c.h> + +/* Handle multiple I2C buses instances */ +int get_multi_scl_pin(void) +{ +	unsigned int bus = I2C_GET_BUS(); + +	switch (bus) { +	case I2C_0: /* I2C_0 definition - compatibility layer */ +	case I2C_5: +		return CONFIG_SOFT_I2C_I2C5_SCL; +	case I2C_9: +		return CONFIG_SOFT_I2C_I2C9_SCL; +	default: +		printf("I2C_%d not supported!\n", bus); +	}; + +	return 0; +} + +int get_multi_sda_pin(void) +{ +	unsigned int bus = I2C_GET_BUS(); + +	switch (bus) { +	case I2C_0: /* I2C_0 definition - compatibility layer */ +	case I2C_5: +		return CONFIG_SOFT_I2C_I2C5_SDA; +	case I2C_9: +		return CONFIG_SOFT_I2C_I2C9_SDA; +	default: +		printf("I2C_%d not supported!\n", bus); +	}; + +	return 0; +} + +int multi_i2c_init(void) +{ +	return 0; +} diff --git a/board/samsung/goni/lowlevel_init.S b/board/samsung/goni/lowlevel_init.S index 30a5835ab..1effc9cdf 100644 --- a/board/samsung/goni/lowlevel_init.S +++ b/board/samsung/goni/lowlevel_init.S @@ -79,11 +79,7 @@ skip_check_didle:  	str	r1, [r0, #0x0]				@ GPIO_CON_OFFSET  	ldr	r1, [r0, #0x4]				@ GPIO_DAT_OFFSET -#ifdef CONFIG_ONENAND_IPL -	orr	r1, r1, #(1 << 1)			@ 1 * 1-bit -#else  	bic	r1, r1, #(1 << 1) -#endif  	str	r1, [r0, #0x4]				@ GPIO_DAT_OFFSET  	/* Don't setup at s5pc100 */ @@ -182,7 +178,6 @@ skip_check_didle:  	/* Do not release retention here for S5PC110 */  	streq	r1, [r0] -#ifndef CONFIG_ONENAND_IPL  	/* Disable Watchdog */  	ldreq	r0, =S5PC100_WATCHDOG_BASE		@ 0xEA200000  	ldrne	r0, =S5PC110_WATCHDOG_BASE		@ 0xE2700000 @@ -193,7 +188,6 @@ skip_check_didle:  	ldrne	r0, =S5PC110_SROMC_BASE  	ldr	r1, =0x9  	str	r1, [r0] -#endif  	/* S5PC100 has 3 groups of interrupt sources */  	ldreq	r0, =S5PC100_VIC0_BASE			@ 0xE4000000 @@ -207,7 +201,6 @@ skip_check_didle:  	str	r3, [r1, #0x14]				@ INTENCLEAR  	str	r3, [r2, #0x14]				@ INTENCLEAR -#ifndef CONFIG_ONENAND_IPL  	/* Set all interrupts as IRQ */  	str	r5, [r0, #0xc]				@ INTSELECT  	str	r5, [r1, #0xc]				@ INTSELECT @@ -217,120 +210,12 @@ skip_check_didle:  	str	r5, [r0, #0xf00]			@ INTADDRESS  	str	r5, [r1, #0xf00]			@ INTADDRESS  	str	r5, [r2, #0xf00]			@ INTADDRESS -#endif -#ifndef CONFIG_ONENAND_IPL  	/* for UART */  	bl	uart_asm_init  	bl	internal_ram_init -#endif -#ifdef CONFIG_ONENAND_IPL -	/* init system clock */ -	bl	system_clock_init - -	/* OneNAND Sync Read Support at S5PC110 only -	 * RM[15]	: Sync Read -	 * BRWL[14:12]	: 7 CLK -	 * BL[11:9]	: Continuous -	 * VHF[3]	: Very High Frequency Enable (Over 83MHz) -	 * HF[2]	: High Frequency Enable (Over 66MHz) -	 * WM[1]	: Sync Write -	 */ -	cmp	r7, r8 -	ldrne	r1, =0xE006 -	ldrne	r0, =0xB001E442 -	strneh	r1, [r0] - -	/* -	 * GCE[26]	: Gated Clock Enable -	 * RPE[17]	: Enables Read Prefetch -	 */ -	ldrne	r1, =((1 << 26) | (1 << 17) | 0xE006) -	ldrne	r0, =0xB0600000 -	strne	r1, [r0, #0x100]			@ ONENAND_IF_CTRL -	ldrne	r1, =0x1212 -	strne	r1, [r0, #0x108] - -	/* Board detection to set proper memory configuration */ -	cmp	r7, r8 -	moveq	r9, #1		/* r9 has 1Gib default at s5pc100 */ -	movne	r9, #2		/* r9 has 2Gib default at s5pc110 */ - -	ldr	r2, =0xE0200200 -	ldr	r4, [r2, #0x48] - -	bic	r1, r4, #(0x3F << 4)	/* PULLUP_DISABLE: 3 * 2-bit */ -	bic	r1, r1, #(0x3 << 2)	/* PULLUP_DISABLE: 2 * 2-bit */ -	bic	r1, r1, #(0x3 << 14)	/* PULLUP_DISABLE: 2 * 2-bit */ -	str	r1, [r2, #0x48] -	/* For write completion */ -	nop -	nop - -	ldr	r3, [r2, #0x44] -	and	r1, r3, #(0x7 << 2) -	mov	r1, r1, lsr #2 -	cmp	r1, #0x5 -	moveq	r9, #3 -	cmp	r1, #0x6 -	moveq	r9, #1 -	cmp	r1, #0x7 -	moveq	r9, #2 -	and	r0, r3, #(0x1 << 1) -	mov	r0, r0, lsr #1 -	orr	r1, r1, r0, lsl #3 -	cmp	r1, #0x8 -	moveq	r9, #3 -	and	r1, r3, #(0x7 << 2) -	mov	r1, r1, lsr #2 -	and	r0, r3, #(0x1 << 7) -	mov	r0, r0, lsr #7 -	orr	r1, r1, r0, lsl #3 -	cmp	r1, #0x9 -	moveq	r9, #3 -	str	r4, [r2, #0x48]		/* Restore PULLUP configuration */ - -	bl	mem_ctrl_asm_init - -	/* Wakeup support. Don't know if it's going to be used, untested. */ -	ldreq	r0, =S5PC100_RST_STAT -	ldrne	r0, =S5PC110_RST_STAT -	ldr	r1, [r0] -	biceq	r1, r1, #0xfffffff7 -	moveq	r2, #(1 << 3) -	bicne	r1, r1, #0xfffeffff -	movne	r2, #(1 << 16) -	cmp	r1, r2 -	bne	1f -wakeup: -	/* turn off L2 cache */ -	bl	l2_cache_disable - -	cmp	r7, r8 -	ldreq	r0, =0xC100 -	ldrne	r0, =0xC110 - -	/* invalidate L2 cache also */ -	bl	invalidate_dcache - -	/* turn on L2 cache */ -	bl	l2_cache_enable - -	cmp	r7, r8 -	/* Load return address and jump to kernel */ -	ldreq	r0, =S5PC100_INFORM0 -	ldrne	r0, =S5PC110_INFORM0 - -	/* r1 = physical address of s5pc1xx_cpu_resume function */ -	ldr	r1, [r0] - -	/* Jump to kernel (sleep-s5pc1xx.S) */ -	mov	pc, r1 -	nop -	nop -#else  	cmp	r7, r8  	/* Clear wakeup status register */  	ldreq	r0, =S5PC100_WAKEUP_STAT @@ -347,7 +232,6 @@ wakeup:  	orr	r1, r1, r2  	str	r1, [r0] -#endif  	b	1f  didle_wakeup: @@ -517,7 +401,6 @@ system_clock_init:  	mov	pc, lr -#ifndef CONFIG_ONENAND_IPL  internal_ram_init:  	ldreq	r0, =0xE3800000  	ldrne	r0, =0xF1500000 @@ -525,9 +408,7 @@ internal_ram_init:  	str	r1, [r0]  	mov	pc, lr -#endif -#ifndef CONFIG_ONENAND_IPL  /*   * uart_asm_init: Initialize UART's pins   */ @@ -582,4 +463,3 @@ uart_asm_init:  	str	r1, [r0, #0x4]			@ S5PC1XX_GPIO_DAT_OFFSET  200:  	mov	pc, lr -#endif diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile index 226db1f1f..1474fa8a1 100644 --- a/board/samsung/smdk5250/Makefile +++ b/board/samsung/smdk5250/Makefile @@ -27,8 +27,9 @@ LIB	= $(obj)lib$(BOARD).o  SOBJS	:= lowlevel_init.o  COBJS	:= clock_init.o -COBJS	+= dmc_init.o +COBJS	+= dmc_common.o dmc_init_ddr3.o  COBJS	+= tzpc_init.o +COBJS	+= smdk5250_spl.o  ifndef CONFIG_SPL_BUILD  COBJS	+= smdk5250.o diff --git a/board/samsung/smdk5250/clock_init.c b/board/samsung/smdk5250/clock_init.c index 305842d2f..c009ae579 100644 --- a/board/samsung/smdk5250/clock_init.c +++ b/board/samsung/smdk5250/clock_init.c @@ -22,120 +22,432 @@   * MA 02111-1307 USA   */ +#include <common.h>  #include <config.h> -#include <version.h>  #include <asm/io.h> +#include <asm/arch/clk.h>  #include <asm/arch/clock.h> -#include <asm/arch/cpu.h> -#include <asm/arch/gpio.h> +#include <asm/arch/spl.h> + +#include "clock_init.h"  #include "setup.h" -void system_clock_init() -{ -	struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; +DECLARE_GLOBAL_DATA_PTR; -	/* -	 * MUX_APLL_SEL[0]: FINPLL = 0 -	 * MUX_CPU_SEL[6]: MOUTAPLL = 0 -	 * MUX_HPM_SEL[20]: MOUTAPLL = 0 -	 */ -	writel(0x0, &clk->src_cpu); +struct arm_clk_ratios arm_clk_ratios[] = { +	{ +		.arm_freq_mhz = 600, -	/* MUX_MPLL_SEL[8]: FINPLL = 0 */ -	writel(0x0, &clk->src_core1); +		.apll_mdiv = 0xc8, +		.apll_pdiv = 0x4, +		.apll_sdiv = 0x1, -	/* -	 * VPLLSRC_SEL[0]: FINPLL = 0 -	 * MUX_{CPLL[8]}|{EPLL[12]}|{VPLL[16]}_SEL: FINPLL = 0 -	 */ -	writel(0x0, &clk->src_top2); +		.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, -	/* MUX_BPLL_SEL[0]: FINPLL = 0 */ -	writel(0x0, &clk->src_cdrex); +		.apll_mdiv = 0x64, +		.apll_pdiv = 0x3, +		.apll_sdiv = 0x0, -	/* MUX_ACLK_* Clock Selection */ -	writel(CLK_SRC_TOP0_VAL, &clk->src_top0); +		.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, -	/* MUX_ACLK_* Clock Selection */ -	writel(CLK_SRC_TOP1_VAL, &clk->src_top1); +		.apll_mdiv = 0x7d, +		.apll_pdiv = 0x3, +		.apll_sdiv = 0x0, -	/* MUX_ACLK_* Clock Selection */ -	writel(CLK_SRC_TOP3_VAL, &clk->src_top3); +		.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, -	/* MUX_PWI_SEL[19:16]: SCLKMPLL = 6 */ -	writel(CLK_SRC_CORE0_VAL, &clk->src_core0); +		.apll_mdiv = 0x96, +		.apll_pdiv = 0x3, +		.apll_sdiv = 0x0, -	/* MUX_ATCLK_LEX[0]: ACLK_200 = 0 */ -	writel(CLK_SRC_LEX_VAL, &clk->src_lex); +		.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, -	/* UART [0-5]: SCLKMPLL = 6 */ -	writel(CLK_SRC_PERIC0_VAL, &clk->src_peric0); +		.apll_mdiv = 0xaf, +		.apll_pdiv = 0x3, +		.apll_sdiv = 0x0, -	/* Set Clock Ratios */ -	writel(CLK_DIV_CPU0_VAL, &clk->div_cpu0); +		.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, -	/* Set COPY and HPM Ratio */ -	writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1); +		.apll_mdiv = 0x1a9, +		.apll_pdiv = 0x6, +		.apll_sdiv = 0x0, -	/* CORED_RATIO, COREP_RATIO */ -	writel(CLK_DIV_CORE0_VAL, &clk->div_core0); +		.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 = 0xc8, +		.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, -	/* PWI_RATIO[11:8], DVSEM_RATIO[22:16], DPM_RATIO[24:20] */ -	writel(CLK_DIV_CORE1_VAL, &clk->div_core1); +		.bpll_mdiv = 0x64, +		.bpll_pdiv = 0x3, +		.bpll_sdiv = 0x0, +		.pclk_cdrex_ratio = 0x5, +		.direct_cmd_msr = { +			0x00020018, 0x00030000, 0x00010042, 0x00000d70 +		}, +		.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_tFS = 0x4, +		.phy1_tFS = 0x4, +		.phy0_pulld_dqs = 0xf, +		.phy1_pulld_dqs = 0xf, -	/* ACLK_*_RATIO */ -	writel(CLK_DIV_TOP0_VAL, &clk->div_top0); +		.lpddr3_ctrl_phy_reset = 0x1, +		.ctrl_start_point = 0x10, +		.ctrl_inc = 0x10, +		.ctrl_start = 0x1, +		.ctrl_dll_on = 0x1, +		.ctrl_ref = 0x8, -	/* ACLK_*_RATIO */ -	writel(CLK_DIV_TOP1_VAL, &clk->div_top1); +		.ctrl_force = 0x1a, +		.ctrl_rdlat = 0x0b, +		.ctrl_bstlen = 0x08, -	/* CDREX Ratio */ -	writel(CLK_DIV_CDREX_INIT_VAL, &clk->div_cdrex); +		.fp_resync = 0x8, +		.iv_size = 0x7, +		.dfi_init_start = 1, +		.aref_en = 1, -	/* MCLK_EFPHY_RATIO[3:0] */ -	writel(CLK_DIV_CDREX2_VAL, &clk->div_cdrex2); +		.rd_fetch = 0x3, -	/* {PCLK[4:6]|ATCLK[10:8]}_RATIO */ -	writel(CLK_DIV_LEX_VAL, &clk->div_lex); +		.zq_mode_dds = 0x7, +		.zq_mode_term = 0x1, +		.zq_mode_noterm = 0, -	/* PCLK_R0X_RATIO[3:0] */ -	writel(CLK_DIV_R0X_VAL, &clk->div_r0x); +		/* +		* 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 = 0xc8, +		.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, -	/* PCLK_R1X_RATIO[3:0] */ -	writel(CLK_DIV_R1X_VAL, &clk->div_r1x); +		.bpll_mdiv = 0x64, +		.bpll_pdiv = 0x3, +		.bpll_sdiv = 0x0, +		.pclk_cdrex_ratio = 0x5, +		.direct_cmd_msr = { +			0x00020018, 0x00030000, 0x00010000, 0x00000d70 +		}, +		.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_tFS = 0x8, +		.phy1_tFS = 0x8, +		.phy0_pulld_dqs = 0xf, +		.phy1_pulld_dqs = 0xf, -	/* SATA[24]: SCLKMPLL=0, MMC[0-4]: SCLKMPLL = 6 */ -	writel(CLK_SRC_FSYS_VAL, &clk->src_fsys); +		.lpddr3_ctrl_phy_reset = 0x1, +		.ctrl_start_point = 0x10, +		.ctrl_inc = 0x10, +		.ctrl_start = 0x1, +		.ctrl_dll_on = 0x1, +		.ctrl_ref = 0x8, -	/* UART[0-4] */ -	writel(CLK_DIV_PERIC0_VAL, &clk->div_peric0); +		.ctrl_force = 0x1a, +		.ctrl_rdlat = 0x0b, +		.ctrl_bstlen = 0x08, -	/* PWM_RATIO[3:0] */ -	writel(CLK_DIV_PERIC3_VAL, &clk->div_peric3); +		.fp_resync = 0x8, +		.iv_size = 0x7, +		.dfi_init_start = 1, +		.aref_en = 1, -	/* SATA_RATIO, USB_DRD_RATIO */ -	writel(CLK_DIV_FSYS0_VAL, &clk->div_fsys0); +		.rd_fetch = 0x3, -	/* MMC[0-1] */ -	writel(CLK_DIV_FSYS1_VAL, &clk->div_fsys1); +		.zq_mode_dds = 0x5, +		.zq_mode_term = 0x1, +		.zq_mode_noterm = 1, -	/* MMC[2-3] */ -	writel(CLK_DIV_FSYS2_VAL, &clk->div_fsys2); +		/* +		* 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, +	} +}; -	/* MMC[4] */ -	writel(CLK_DIV_FSYS3_VAL, &clk->div_fsys3); +/** + * 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; -	/* ACLK|PLCK_ACP_RATIO */ -	writel(CLK_DIV_ACP_VAL, &clk->div_acp); +	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; -	/* ISPDIV0_RATIO, ISPDIV1_RATIO */ -	writel(CLK_DIV_ISP0_VAL, &clk->div_isp0); +	return 0; +} -	/* MCUISPDIV0_RATIO, MCUISPDIV1_RATIO */ -	writel(CLK_DIV_ISP1_VAL, &clk->div_isp1); +/* 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; -	/* MPWMDIV_RATIO */ -	writel(CLK_DIV_ISP2_VAL, &clk->div_isp2); +	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 mem_timings *clock_get_mem_timings(void) +{ +	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; +		} +	} + +	/* 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 mem_timings *mem; +	struct arm_clk_ratios *arm_clk_ratio; +	u32 val, tmp; + +	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_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); @@ -146,57 +458,209 @@ void system_clock_init()  	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); -	sdelay(0x10000); +	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); -	writel(APLL_CON0_VAL, &clk->apll_con0); -	sdelay(0x30000); +	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); -	writel(MPLL_CON0_VAL, &clk->mpll_con0); -	sdelay(0x30000); +	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) +		; + +	/* Set BPLL */  	writel(BPLL_CON1_VAL, &clk->bpll_con1); -	writel(BPLL_CON0_VAL, &clk->bpll_con0); -	sdelay(0x30000); +	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) +		;  	/* Set CPLL */  	writel(CPLL_CON1_VAL, &clk->cpll_con1); -	writel(CPLL_CON0_VAL, &clk->cpll_con0); -	sdelay(0x30000); +	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) +		; + +	/* 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) +		;  	/* Set EPLL */  	writel(EPLL_CON2_VAL, &clk->epll_con2);  	writel(EPLL_CON1_VAL, &clk->epll_con1); -	writel(EPLL_CON0_VAL, &clk->epll_con0); -	sdelay(0x30000); +	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) +		;  	/* Set VPLL */  	writel(VPLL_CON2_VAL, &clk->vpll_con2);  	writel(VPLL_CON1_VAL, &clk->vpll_con1); -	writel(VPLL_CON0_VAL, &clk->vpll_con0); -	sdelay(0x30000); +	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) +		; -	/* Set MPLL */ -	/* After Initiallising th PLL select the sources accordingly */ -	/* MUX_APLL_SEL[0]: MOUTAPLLFOUT = 1 */ -	writel(CLK_SRC_CPU_VAL, &clk->src_cpu); +	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)) +		; -	/* MUX_MPLL_SEL[8]: MOUTMPLLFOUT = 1 */ -	writel(CLK_SRC_CORE1_VAL, &clk->src_core1); +	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)) +		; + +	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(CLK_DIV_PERIC3_VAL, &clk->div_peric3); + +	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); +} + +void clock_init_dp_clock(void) +{ +	struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; -	/* MUX_BPLL_SEL[0]: FOUTBPLL = 1*/ -	writel(CLK_SRC_CDREX_INIT_VAL, &clk->src_cdrex); +	/* DP clock enable */ +	setbits_le32(&clk->gate_ip_disp1, CLK_GATE_DP1_ALLOW); -	/* -	 * VPLLSRC_SEL[0]: FINPLL = 0 -	 * MUX_{CPLL[8]}|{EPLL[12]}|{VPLL[16]}_SEL: MOUT{CPLL|EPLL|VPLL} = 1 -	 * MUX_{MPLL[20]}|{BPLL[24]}_USER_SEL: FOUT{MPLL|BPLL} = 1 -	 */ -	writel(CLK_SRC_TOP2_VAL, &clk->src_top2); +	/* 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 new file mode 100644 index 000000000..f751bcb65 --- /dev/null +++ b/board/samsung/smdk5250/clock_init.h @@ -0,0 +1,149 @@ +/* + * Clock initialization routines + * + * Copyright (c) 2011 The Chromium OS Authors. + * + * 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 + */ + +#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 arm_freq_mhz;		/* Frequency of ARM core in MHz */ + +	unsigned apll_mdiv; +	unsigned apll_pdiv; +	unsigned apll_sdiv; + +	unsigned arm2_ratio; +	unsigned apll_ratio; +	unsigned pclk_dbg_ratio; +	unsigned atb_ratio; +	unsigned periph_ratio; +	unsigned acp_ratio; +	unsigned cpud_ratio; +	unsigned 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 frequency_mhz;		/* Frequency of memory in MHz */ + +	/* Here follow the timing parameters for the selected memory */ +	unsigned apll_mdiv; +	unsigned apll_pdiv; +	unsigned apll_sdiv; +	unsigned mpll_mdiv; +	unsigned mpll_pdiv; +	unsigned mpll_sdiv; +	unsigned cpll_mdiv; +	unsigned cpll_pdiv; +	unsigned cpll_sdiv; +	unsigned gpll_mdiv; +	unsigned gpll_pdiv; +	unsigned gpll_sdiv; +	unsigned epll_mdiv; +	unsigned epll_pdiv; +	unsigned epll_sdiv; +	unsigned vpll_mdiv; +	unsigned vpll_pdiv; +	unsigned vpll_sdiv; +	unsigned bpll_mdiv; +	unsigned bpll_pdiv; +	unsigned bpll_sdiv; +	unsigned pclk_cdrex_ratio; +	unsigned direct_cmd_msr[MEM_TIMINGS_MSR_COUNT]; + +	unsigned timing_ref; +	unsigned timing_row; +	unsigned timing_data; +	unsigned timing_power; + +	/* DQS, DQ, DEBUG offsets */ +	unsigned phy0_dqs; +	unsigned phy1_dqs; +	unsigned phy0_dq; +	unsigned phy1_dq; +	unsigned phy0_tFS; +	unsigned phy1_tFS; +	unsigned phy0_pulld_dqs; +	unsigned phy1_pulld_dqs; + +	unsigned lpddr3_ctrl_phy_reset; +	unsigned ctrl_start_point; +	unsigned ctrl_inc; +	unsigned ctrl_start; +	unsigned ctrl_dll_on; +	unsigned ctrl_ref; + +	unsigned ctrl_force; +	unsigned ctrl_rdlat; +	unsigned ctrl_bstlen; + +	unsigned fp_resync; +	unsigned iv_size; +	unsigned dfi_init_start; +	unsigned aref_en; + +	unsigned rd_fetch; + +	unsigned zq_mode_dds; +	unsigned zq_mode_term; +	unsigned zq_mode_noterm;	/* 1 to allow termination disable */ + +	unsigned memcontrol; +	unsigned memconfig; + +	unsigned membaseconfig0; +	unsigned membaseconfig1; +	unsigned prechconfig_tp_cnt; +	unsigned dpwrdn_cyc; +	unsigned dsref_cyc; +	unsigned 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 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. + * + * This function can be called from SPL or the main U-Boot. + * + * @return pointer to the memory timings that we should use + */ +struct mem_timings *clock_get_mem_timings(void); + +/* + * Initialize clock for the device + */ +void system_clock_init(void); +#endif diff --git a/board/samsung/smdk5250/dmc_common.c b/board/samsung/smdk5250/dmc_common.c new file mode 100644 index 000000000..109602a2e --- /dev/null +++ b/board/samsung/smdk5250/dmc_common.c @@ -0,0 +1,199 @@ +/* + * Mem setup common file for different types of DDR present on SMDK5250 boards. + * + * 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 <asm/arch/spl.h> + +#include "clock_init.h" +#include "setup.h" + +#define ZQ_INIT_TIMEOUT	10000 + +int dmc_config_zq(struct mem_timings *mem, +		  struct exynos5_phy_control *phy0_ctrl, +		  struct exynos5_phy_control *phy1_ctrl) +{ +	unsigned long val = 0; +	int i; + +	/* +	 * ZQ Calibration: +	 * Select Driver Strength, +	 * long calibration for manual calibration +	 */ +	val = PHY_CON16_RESET_VAL; +	val |= mem->zq_mode_dds << PHY_CON16_ZQ_MODE_DDS_SHIFT; +	val |= mem->zq_mode_term << PHY_CON16_ZQ_MODE_TERM_SHIFT; +	val |= ZQ_CLK_DIV_EN; +	writel(val, &phy0_ctrl->phy_con16); +	writel(val, &phy1_ctrl->phy_con16); + +	/* Disable termination */ +	if (mem->zq_mode_noterm) +		val |= PHY_CON16_ZQ_MODE_NOTERM_MASK; +	writel(val, &phy0_ctrl->phy_con16); +	writel(val, &phy1_ctrl->phy_con16); + +	/* ZQ_MANUAL_START: Enable */ +	val |= ZQ_MANUAL_STR; +	writel(val, &phy0_ctrl->phy_con16); +	writel(val, &phy1_ctrl->phy_con16); + +	/* ZQ_MANUAL_START: Disable */ +	val &= ~ZQ_MANUAL_STR; + +	/* +	 * Since we are manaully calibrating the ZQ values, +	 * we are looping for the ZQ_init to complete. +	 */ +	i = ZQ_INIT_TIMEOUT; +	while ((readl(&phy0_ctrl->phy_con17) & ZQ_DONE) != ZQ_DONE && i > 0) { +		sdelay(100); +		i--; +	} +	if (!i) +		return -1; +	writel(val, &phy0_ctrl->phy_con16); + +	i = ZQ_INIT_TIMEOUT; +	while ((readl(&phy1_ctrl->phy_con17) & ZQ_DONE) != ZQ_DONE && i > 0) { +		sdelay(100); +		i--; +	} +	if (!i) +		return -1; +	writel(val, &phy1_ctrl->phy_con16); + +	return 0; +} + +void update_reset_dll(struct exynos5_dmc *dmc, enum ddr_mode mode) +{ +	unsigned long val; + +	if (mode == DDR_MODE_DDR3) { +		val = MEM_TERM_EN | PHY_TERM_EN | DMC_CTRL_SHGATE; +		writel(val, &dmc->phycontrol0); +	} + +	/* Update DLL Information: Force DLL Resyncronization */ +	val = readl(&dmc->phycontrol0); +	val |= FP_RSYNC; +	writel(val, &dmc->phycontrol0); + +	/* Reset Force DLL Resyncronization */ +	val = readl(&dmc->phycontrol0); +	val &= ~FP_RSYNC; +	writel(val, &dmc->phycontrol0); +} + +void dmc_config_mrs(struct mem_timings *mem, struct exynos5_dmc *dmc) +{ +	int channel, chip; + +	for (channel = 0; channel < mem->dmc_channels; channel++) { +		unsigned long mask; + +		mask = channel << DIRECT_CMD_CHANNEL_SHIFT; +		for (chip = 0; chip < mem->chips_to_configure; chip++) { +			int i; + +			mask |= chip << DIRECT_CMD_CHIP_SHIFT; + +			/* Sending NOP command */ +			writel(DIRECT_CMD_NOP | mask, &dmc->directcmd); + +			/* +			 * TODO(alim.akhtar@samsung.com): Do we need these +			 * delays? This one and the next were not there for +			 * DDR3. +			 */ +			sdelay(0x10000); + +			/* Sending EMRS/MRS commands */ +			for (i = 0; i < MEM_TIMINGS_MSR_COUNT; i++) { +				writel(mem->direct_cmd_msr[i] | mask, +				       &dmc->directcmd); +				sdelay(0x10000); +			} + +			if (mem->send_zq_init) { +				/* Sending ZQINIT command */ +				writel(DIRECT_CMD_ZQINIT | mask, +				       &dmc->directcmd); + +				sdelay(10000); +			} +		} +	} +} + +void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc) +{ +	int channel, chip; + +	for (channel = 0; channel < mem->dmc_channels; channel++) { +		unsigned long mask; + +		mask = channel << DIRECT_CMD_CHANNEL_SHIFT; +		for (chip = 0; chip < mem->chips_per_channel; chip++) { +			mask |= chip << DIRECT_CMD_CHIP_SHIFT; + +			/* PALL (all banks precharge) CMD */ +			writel(DIRECT_CMD_PALL | mask, &dmc->directcmd); +			sdelay(0x10000); +		} +	} +} + +void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc) +{ +	writel(mem->memconfig, &dmc->memconfig0); +	writel(mem->memconfig, &dmc->memconfig1); +	writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0); +	writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1); +} + +void mem_ctrl_init() +{ +	struct spl_machine_param *param = spl_get_machine_params(); +	struct mem_timings *mem; +	int ret; + +	mem = clock_get_mem_timings(); + +	/* If there are any other memory variant, add their init call below */ +	if (param->mem_type == DDR_MODE_DDR3) { +		ret = ddr3_mem_ctrl_init(mem, param->mem_iv_size); +		if (ret) { +			/* will hang if failed to init memory control */ +			while (1) +				; +		} +	} else { +		/* will hang if unknow memory type  */ +		while (1) +			; +	} +} diff --git a/board/samsung/smdk5250/dmc_init.c b/board/samsung/smdk5250/dmc_init.c deleted file mode 100644 index 788107465..000000000 --- a/board/samsung/smdk5250/dmc_init.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Memory 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 <config.h> -#include <asm/io.h> -#include <asm/arch/dmc.h> -#include <asm/arch/clock.h> -#include <asm/arch/cpu.h> -#include "setup.h" - -/* APLL : 1GHz */ -/* MCLK_CDREX: MCLK_CDREX_533*/ -/* LPDDR support: LPDDR2 */ -static void reset_phy_ctrl(void); -static void config_zq(struct exynos5_phy_control *, -			struct exynos5_phy_control *); -static void update_reset_dll(struct exynos5_dmc *); -static void config_cdrex(void); -static void config_mrs(struct exynos5_dmc *); -static void sec_sdram_phy_init(struct exynos5_dmc *); -static void config_prech(struct exynos5_dmc *); -static void config_rdlvl(struct exynos5_dmc *, -			struct exynos5_phy_control *, -			struct exynos5_phy_control *); -static void config_memory(struct exynos5_dmc *); - -static void config_offsets(unsigned int, -				struct exynos5_phy_control *, -				struct exynos5_phy_control *); - -static void reset_phy_ctrl(void) -{ -	struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; - -	writel(PHY_RESET_VAL, &clk->lpddr3phy_ctrl); -	sdelay(0x10000); -} - -static void config_zq(struct exynos5_phy_control *phy0_ctrl, -			struct exynos5_phy_control *phy1_ctrl) -{ -	unsigned long val = 0; -	/* -	 * ZQ Calibration: -	 * Select Driver Strength, -	 * long calibration for manual calibration -	 */ -	val = PHY_CON16_RESET_VAL; -	SET_ZQ_MODE_DDS_VAL(val); -	SET_ZQ_MODE_TERM_VAL(val); -	val |= ZQ_CLK_DIV_EN; -	writel(val, &phy0_ctrl->phy_con16); -	writel(val, &phy1_ctrl->phy_con16); - -	/* Disable termination */ -	val |= ZQ_MODE_NOTERM; -	writel(val, &phy0_ctrl->phy_con16); -	writel(val, &phy1_ctrl->phy_con16); - -	/* ZQ_MANUAL_START: Enable */ -	val |= ZQ_MANUAL_STR; -	writel(val, &phy0_ctrl->phy_con16); -	writel(val, &phy1_ctrl->phy_con16); -	sdelay(0x10000); - -	/* ZQ_MANUAL_START: Disable */ -	val &= ~ZQ_MANUAL_STR; -	writel(val, &phy0_ctrl->phy_con16); -	writel(val, &phy1_ctrl->phy_con16); -} - -static void update_reset_dll(struct exynos5_dmc *dmc) -{ -	unsigned long val; -	/* -	 * Update DLL Information: -	 * Force DLL Resyncronization -	 */ -	val = readl(&dmc->phycontrol0); -	val |= FP_RSYNC; -	writel(val, &dmc->phycontrol0); - -	/* Reset Force DLL Resyncronization */ -	val = readl(&dmc->phycontrol0); -	val &= ~FP_RSYNC; -	writel(val, &dmc->phycontrol0); -} - -static void config_mrs(struct exynos5_dmc *dmc) -{ -	unsigned long channel, chip, mask = 0, val; - -	for (channel = 0; channel < CONFIG_DMC_CHANNELS; channel++) { -		SET_CMD_CHANNEL(mask, channel); -		for (chip = 0; chip < CONFIG_CHIPS_PER_CHANNEL; chip++) { -			/* -			 * NOP CMD: -			 * Assert and hold CKE to logic high level -			 */ -			SET_CMD_CHIP(mask, chip); -			val = DIRECT_CMD_NOP | mask; -			writel(val, &dmc->directcmd); -			sdelay(0x10000); - -			/* EMRS, MRS Cmds(Mode Reg Settings) Using Direct Cmd */ -			val = DIRECT_CMD_MRS1 | mask; -			writel(val, &dmc->directcmd); -			sdelay(0x10000); - -			val = DIRECT_CMD_MRS2 | mask; -			writel(val, &dmc->directcmd); -			sdelay(0x10000); - -			/* MCLK_CDREX_533 */ -			val = DIRECT_CMD_MRS3 | mask; -			writel(val, &dmc->directcmd); -			sdelay(0x10000); - -			val = DIRECT_CMD_MRS4 | mask; -			writel(val, &dmc->directcmd); -			sdelay(0x10000); -		} -	} -} - -static void config_prech(struct exynos5_dmc *dmc) -{ -	unsigned long channel, chip, mask = 0, val; - -	for (channel = 0; channel < CONFIG_DMC_CHANNELS; channel++) { -		SET_CMD_CHANNEL(mask, channel); -		for (chip = 0; chip < CONFIG_CHIPS_PER_CHANNEL; chip++) { -			SET_CMD_CHIP(mask, chip); -			/* PALL (all banks precharge) CMD */ -			val = DIRECT_CMD_PALL | mask; -			writel(val, &dmc->directcmd); -			sdelay(0x10000); -		} -	} -} - -static void sec_sdram_phy_init(struct exynos5_dmc *dmc) -{ -	unsigned long val; -	val = readl(&dmc->concontrol); -	val |= DFI_INIT_START; -	writel(val, &dmc->concontrol); -	sdelay(0x10000); - -	val = readl(&dmc->concontrol); -	val &= ~DFI_INIT_START; -	writel(val, &dmc->concontrol); -} - -static void config_offsets(unsigned int state, -				struct exynos5_phy_control *phy0_ctrl, -				struct exynos5_phy_control *phy1_ctrl) -{ -	unsigned long val; -	/* Set Offsets to read DQS */ -	val = (state == SET) ? SET_DQS_OFFSET_VAL : RESET_DQS_OFFSET_VAL; -	writel(val, &phy0_ctrl->phy_con4); -	writel(val, &phy1_ctrl->phy_con4); - -	/* Set Offsets to read DQ */ -	val = (state == SET) ? SET_DQ_OFFSET_VAL : RESET_DQ_OFFSET_VAL; -	writel(val, &phy0_ctrl->phy_con6); -	writel(val, &phy1_ctrl->phy_con6); - -	/* Debug Offset */ -	val = (state == SET) ? SET_DEBUG_OFFSET_VAL : RESET_DEBUG_OFFSET_VAL; -	writel(val, &phy0_ctrl->phy_con10); -	writel(val, &phy1_ctrl->phy_con10); -} - -static void config_cdrex(void) -{ -	struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; -	writel(CLK_DIV_CDREX_VAL, &clk->div_cdrex); -	writel(CLK_SRC_CDREX_VAL, &clk->src_cdrex); -	sdelay(0x30000); -} - -static void config_ctrl_dll_on(unsigned int state, -			unsigned int ctrl_force_val, -			struct exynos5_phy_control *phy0_ctrl, -			struct exynos5_phy_control *phy1_ctrl) -{ -	unsigned long val; -	val = readl(&phy0_ctrl->phy_con12); -	CONFIG_CTRL_DLL_ON(val, state); -	SET_CTRL_FORCE_VAL(val, ctrl_force_val); -	writel(val, &phy0_ctrl->phy_con12); - -	val = readl(&phy1_ctrl->phy_con12); -	CONFIG_CTRL_DLL_ON(val, state); -	SET_CTRL_FORCE_VAL(val, ctrl_force_val); -	writel(val, &phy1_ctrl->phy_con12); -} - -static void config_ctrl_start(unsigned int state, -			struct exynos5_phy_control *phy0_ctrl, -			struct exynos5_phy_control *phy1_ctrl) -{ -	unsigned long val; -	val = readl(&phy0_ctrl->phy_con12); -	CONFIG_CTRL_START(val, state); -	writel(val, &phy0_ctrl->phy_con12); - -	val = readl(&phy1_ctrl->phy_con12); -	CONFIG_CTRL_START(val, state); -	writel(val, &phy1_ctrl->phy_con12); -} - -#if defined(CONFIG_RD_LVL) -static void config_rdlvl(struct exynos5_dmc *dmc, -			struct exynos5_phy_control *phy0_ctrl, -			struct exynos5_phy_control *phy1_ctrl) -{ -	unsigned long val; - -	/* Disable CTRL_DLL_ON and set ctrl_force */ -	config_ctrl_dll_on(RESET, 0x2D, phy0_ctrl, phy1_ctrl); - -	/* -	 * Set ctrl_gateadj, ctrl_readadj -	 * ctrl_gateduradj, rdlvl_pass_adj -	 * rdlvl_rddataPadj -	 */ -	val = SET_RDLVL_RDDATAPADJ; -	writel(val, &phy0_ctrl->phy_con1); -	writel(val, &phy1_ctrl->phy_con1); - -	/* LPDDR2 Address */ -	writel(LPDDR2_ADDR, &phy0_ctrl->phy_con22); -	writel(LPDDR2_ADDR, &phy1_ctrl->phy_con22); - -	/* Enable Byte Read Leveling set ctrl_ddr_mode */ -	val = readl(&phy0_ctrl->phy_con0); -	val |= BYTE_RDLVL_EN; -	writel(val, &phy0_ctrl->phy_con0); -	val = readl(&phy1_ctrl->phy_con0); -	val |= BYTE_RDLVL_EN; -	writel(val, &phy1_ctrl->phy_con0); - -	/* rdlvl_en: Use levelling offset instead ctrl_shiftc */ -	val = PHY_CON2_RESET_VAL | RDLVL_EN; -	writel(val, &phy0_ctrl->phy_con2); -	writel(val, &phy1_ctrl->phy_con2); -	sdelay(0x10000); - -	/* Enable Data Eye Training */ -	val = readl(&dmc->rdlvl_config); -	val |= CTRL_RDLVL_DATA_EN; -	writel(val, &dmc->rdlvl_config); -	sdelay(0x10000); - -	/* Disable Data Eye Training */ -	val = readl(&dmc->rdlvl_config); -	val &= ~CTRL_RDLVL_DATA_EN; -	writel(val, &dmc->rdlvl_config); - -	/* RdDeSkew_clear: Clear */ -	val = readl(&phy0_ctrl->phy_con2); -	val |= RDDSKEW_CLEAR; -	writel(val, &phy0_ctrl->phy_con2); -	val = readl(&phy1_ctrl->phy_con2); -	val |= RDDSKEW_CLEAR; -	writel(val, &phy1_ctrl->phy_con2); - -	/* Enable CTRL_DLL_ON */ -	config_ctrl_dll_on(SET, 0x0, phy0_ctrl, phy1_ctrl); - -	update_reset_dll(dmc); -	sdelay(0x10000); - -	/* ctrl_atgte: ctrl_gate_p*, ctrl_read_p* generated by PHY */ -	val = readl(&phy0_ctrl->phy_con0); -	val &= ~CTRL_ATGATE; -	writel(val, &phy0_ctrl->phy_con0); -	val = readl(&phy1_ctrl->phy_con0); -	val &= ~CTRL_ATGATE; -	writel(val, &phy1_ctrl->phy_con0); -} -#endif - -static void config_memory(struct exynos5_dmc *dmc) -{ -	/* -	 * Memory Configuration Chip 0 -	 * Address Mapping: Interleaved -	 * Number of Column address Bits: 10 bits -	 * Number of Rows Address Bits: 14 -	 * Number of Banks: 8 -	 */ -	writel(DMC_MEMCONFIG0_VAL, &dmc->memconfig0); - -	/* -	 * Memory Configuration Chip 1 -	 * Address Mapping: Interleaved -	 * Number of Column address Bits: 10 bits -	 * Number of Rows Address Bits: 14 -	 * Number of Banks: 8 -	 */ -	writel(DMC_MEMCONFIG1_VAL, &dmc->memconfig1); - -	/* -	 * Chip0: AXI -	 * AXI Base Address: 0x40000000 -	 * AXI Base Address Mask: 0x780 -	 */ -	writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0); - -	/* -	 * Chip1: AXI -	 * AXI Base Address: 0x80000000 -	 * AXI Base Address Mask: 0x780 -	 */ -	writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1); -} - -void mem_ctrl_init() -{ -	struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl; -	struct exynos5_dmc *dmc; -	unsigned long val; - -	phy0_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY0_BASE; -	phy1_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY1_BASE; -	dmc = (struct exynos5_dmc *)EXYNOS5_DMC_CTRL_BASE; - -	/* Reset PHY Controllor: PHY_RESET[0] */ -	reset_phy_ctrl(); - -	/*set Read Latancy and Burst Length for PHY0 and PHY1 */ -	writel(PHY_CON42_VAL, &phy0_ctrl->phy_con42); -	writel(PHY_CON42_VAL, &phy1_ctrl->phy_con42); - -	/* ZQ Cofiguration */ -	config_zq(phy0_ctrl, phy1_ctrl); - -	/* Operation Mode : LPDDR2 */ -	val = PHY_CON0_RESET_VAL; -	SET_CTRL_DDR_MODE(val, DDR_MODE_LPDDR2); -	writel(val, &phy0_ctrl->phy_con0); -	writel(val, &phy1_ctrl->phy_con0); - -	/* DQS, DQ: Signal, for LPDDR2: Always Set */ -	val = CTRL_PULLD_DQ | CTRL_PULLD_DQS; -	writel(val, &phy0_ctrl->phy_con14); -	writel(val, &phy1_ctrl->phy_con14); - -	/* Init SEC SDRAM PHY */ -	sec_sdram_phy_init(dmc); -	sdelay(0x10000); - -	update_reset_dll(dmc); - -	/* -	 * Dynamic Clock: Always Running -	 * Memory Burst length: 4 -	 * Number of chips: 2 -	 * Memory Bus width: 32 bit -	 * Memory Type: LPDDR2-S4 -	 * Additional Latancy for PLL: 1 Cycle -	 */ -	writel(DMC_MEMCONTROL_VAL, &dmc->memcontrol); - -	config_memory(dmc); - -	/* Precharge Configuration */ -	writel(DMC_PRECHCONFIG_VAL, &dmc->prechconfig); - -	/* Power Down mode Configuration */ -	writel(DMC_PWRDNCONFIG_VAL, &dmc->pwrdnconfig); - -	/* Periodic Refrese Interval */ -	writel(DMC_TIMINGREF_VAL, &dmc->timingref); - -	/* -	 * TimingRow, TimingData, TimingPower Setting: -	 * Values as per Memory AC Parameters -	 */ -	writel(DMC_TIMINGROW_VAL, &dmc->timingrow); - -	writel(DMC_TIMINGDATA_VAL, &dmc->timingdata); - -	writel(DMC_TIMINGPOWER_VAL, &dmc->timingpower); - -	/* Memory Channel Inteleaving Size: 128 Bytes */ -	writel(CONFIG_IV_SIZE, &dmc->ivcontrol); - -	/* Set DQS, DQ and DEBUG offsets */ -	config_offsets(SET, phy0_ctrl, phy1_ctrl); - -	/* Disable CTRL_DLL_ON and set ctrl_force */ -	config_ctrl_dll_on(RESET, 0x7F, phy0_ctrl, phy1_ctrl); -	sdelay(0x10000); - -	update_reset_dll(dmc); - -	/* Config MRS(Mode Register Settingg) */ -	config_mrs(dmc); - -	config_cdrex(); - -	/* Reset DQS DQ and DEBUG offsets */ -	config_offsets(RESET, phy0_ctrl, phy1_ctrl); - -	/* Enable CTRL_DLL_ON */ -	config_ctrl_dll_on(SET, 0x0, phy0_ctrl, phy1_ctrl); - -	/* Stop DLL Locking */ -	config_ctrl_start(RESET, phy0_ctrl, phy1_ctrl); -	sdelay(0x10000); - -	/* Start DLL Locking */ -	config_ctrl_start(SET, phy0_ctrl, phy1_ctrl); -	sdelay(0x10000); - -	update_reset_dll(dmc); - -#if defined(CONFIG_RD_LVL) -	config_rdlvl(dmc, phy0_ctrl, phy1_ctrl); -#endif -	config_prech(dmc); - -	/* -	 * Dynamic Clock: Stops During Idle Period -	 * Dynamic Power Down: Enable -	 * Dynamic Self refresh: Enable -	 */ -	val = readl(&dmc->memcontrol); -	val |= CLK_STOP_EN | DPWRDN_EN | DSREF_EN; -	writel(val, &dmc->memcontrol); - -	/* Start Auto refresh */ -	val = readl(&dmc->concontrol); -	val |= AREF_EN; -	writel(val, &dmc->concontrol); -} diff --git a/board/samsung/smdk5250/dmc_init_ddr3.c b/board/samsung/smdk5250/dmc_init_ddr3.c new file mode 100644 index 000000000..e05079028 --- /dev/null +++ b/board/samsung/smdk5250/dmc_init_ddr3.c @@ -0,0 +1,228 @@ +/* + * DDR3 mem setup file 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 <config.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/cpu.h> +#include <asm/arch/dmc.h> +#include "setup.h" +#include "clock_init.h" + +#define RDLVL_COMPLETE_TIMEOUT	10000 + +static void reset_phy_ctrl(void) +{ +	struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; + +	writel(DDR3PHY_CTRL_PHY_RESET_OFF, &clk->lpddr3phy_ctrl); +	writel(DDR3PHY_CTRL_PHY_RESET, &clk->lpddr3phy_ctrl); +} + +int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size) +{ +	unsigned int val; +	struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl; +	struct exynos5_dmc *dmc; +	int i; + +	phy0_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY0_BASE; +	phy1_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY1_BASE; +	dmc = (struct exynos5_dmc *)EXYNOS5_DMC_CTRL_BASE; + +	reset_phy_ctrl(); + +	/* Set Impedance Output Driver */ +	val = (mem->impedance << CA_CK_DRVR_DS_OFFSET) | +		(mem->impedance << CA_CKE_DRVR_DS_OFFSET) | +		(mem->impedance << CA_CS_DRVR_DS_OFFSET) | +		(mem->impedance << CA_ADR_DRVR_DS_OFFSET); +	writel(val, &phy0_ctrl->phy_con39); +	writel(val, &phy1_ctrl->phy_con39); + +	/* Set Read Latency and Burst Length for PHY0 and PHY1 */ +	val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) | +		(mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT); +	writel(val, &phy0_ctrl->phy_con42); +	writel(val, &phy1_ctrl->phy_con42); + +	/* ZQ Calibration */ +	if (dmc_config_zq(mem, phy0_ctrl, phy1_ctrl)) +		return SETUP_ERR_ZQ_CALIBRATION_FAILURE; + +	/* DQ Signal */ +	writel(mem->phy0_pulld_dqs, &phy0_ctrl->phy_con14); +	writel(mem->phy1_pulld_dqs, &phy1_ctrl->phy_con14); + +	writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT) +		| (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT), +		&dmc->concontrol); + +	update_reset_dll(dmc, DDR_MODE_DDR3); + +	/* DQS Signal */ +	writel(mem->phy0_dqs, &phy0_ctrl->phy_con4); +	writel(mem->phy1_dqs, &phy1_ctrl->phy_con4); + +	writel(mem->phy0_dq, &phy0_ctrl->phy_con6); +	writel(mem->phy1_dq, &phy1_ctrl->phy_con6); + +	writel(mem->phy0_tFS, &phy0_ctrl->phy_con10); +	writel(mem->phy1_tFS, &phy1_ctrl->phy_con10); + +	val = (mem->ctrl_start_point << PHY_CON12_CTRL_START_POINT_SHIFT) | +		(mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) | +		(mem->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) | +		(mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT); +	writel(val, &phy0_ctrl->phy_con12); +	writel(val, &phy1_ctrl->phy_con12); + +	/* Start DLL locking */ +	writel(val | (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT), +		&phy0_ctrl->phy_con12); +	writel(val | (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT), +		&phy1_ctrl->phy_con12); + +	update_reset_dll(dmc, DDR_MODE_DDR3); + +	writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT), +		&dmc->concontrol); + +	/* Memory Channel Inteleaving Size */ +	writel(mem->iv_size, &dmc->ivcontrol); + +	writel(mem->memconfig, &dmc->memconfig0); +	writel(mem->memconfig, &dmc->memconfig1); +	writel(mem->membaseconfig0, &dmc->membaseconfig0); +	writel(mem->membaseconfig1, &dmc->membaseconfig1); + +	/* Precharge Configuration */ +	writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT, +		&dmc->prechconfig); + +	/* Power Down mode Configuration */ +	writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT | +		mem->dsref_cyc << PWRDNCONFIG_DSREF_CYC_SHIFT, +		&dmc->pwrdnconfig); + +	/* TimingRow, TimingData, TimingPower and Timingaref +	 * values as per Memory AC parameters +	 */ +	writel(mem->timing_ref, &dmc->timingref); +	writel(mem->timing_row, &dmc->timingrow); +	writel(mem->timing_data, &dmc->timingdata); +	writel(mem->timing_power, &dmc->timingpower); + +	/* Send PALL command */ +	dmc_config_prech(mem, dmc); + +	/* Send NOP, MRS and ZQINIT commands */ +	dmc_config_mrs(mem, dmc); + +	if (mem->gate_leveling_enable) { +		val = PHY_CON0_RESET_VAL; +		val |= P0_CMD_EN; +		writel(val, &phy0_ctrl->phy_con0); +		writel(val, &phy1_ctrl->phy_con0); + +		val = PHY_CON2_RESET_VAL; +		val |= INIT_DESKEW_EN; +		writel(val, &phy0_ctrl->phy_con2); +		writel(val, &phy1_ctrl->phy_con2); + +		val = PHY_CON0_RESET_VAL; +		val |= P0_CMD_EN; +		val |= BYTE_RDLVL_EN; +		writel(val, &phy0_ctrl->phy_con0); +		writel(val, &phy1_ctrl->phy_con0); + +		val = (mem->ctrl_start_point << +				PHY_CON12_CTRL_START_POINT_SHIFT) | +			(mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) | +			(mem->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) | +			(mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT) | +			(mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT); +		writel(val, &phy0_ctrl->phy_con12); +		writel(val, &phy1_ctrl->phy_con12); + +		val = PHY_CON2_RESET_VAL; +		val |= INIT_DESKEW_EN; +		val |= RDLVL_GATE_EN; +		writel(val, &phy0_ctrl->phy_con2); +		writel(val, &phy1_ctrl->phy_con2); + +		val = PHY_CON0_RESET_VAL; +		val |= P0_CMD_EN; +		val |= BYTE_RDLVL_EN; +		val |= CTRL_SHGATE; +		writel(val, &phy0_ctrl->phy_con0); +		writel(val, &phy1_ctrl->phy_con0); + +		val = PHY_CON1_RESET_VAL; +		val &= ~(CTRL_GATEDURADJ_MASK); +		writel(val, &phy0_ctrl->phy_con1); +		writel(val, &phy1_ctrl->phy_con1); + +		writel(CTRL_RDLVL_GATE_ENABLE, &dmc->rdlvl_config); +		i = RDLVL_COMPLETE_TIMEOUT; +		while ((readl(&dmc->phystatus) & +			(RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1)) != +			(RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1) && i > 0) { +			/* +			 * TODO(waihong): Comment on how long this take to +			 * timeout +			 */ +			sdelay(100); +			i--; +		} +		if (!i) +			return SETUP_ERR_RDLV_COMPLETE_TIMEOUT; +		writel(CTRL_RDLVL_GATE_DISABLE, &dmc->rdlvl_config); + +		writel(0, &phy0_ctrl->phy_con14); +		writel(0, &phy1_ctrl->phy_con14); + +		val = (mem->ctrl_start_point << +				PHY_CON12_CTRL_START_POINT_SHIFT) | +			(mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) | +			(mem->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) | +			(mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT) | +			(mem->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) | +			(mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT); +		writel(val, &phy0_ctrl->phy_con12); +		writel(val, &phy1_ctrl->phy_con12); + +		update_reset_dll(dmc, DDR_MODE_DDR3); +	} + +	/* Send PALL command */ +	dmc_config_prech(mem, dmc); + +	writel(mem->memcontrol, &dmc->memcontrol); + +	/* Set DMC Concontrol and enable auto-refresh counter */ +	writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT) +		| (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol); +	return 0; +} diff --git a/board/samsung/smdk5250/setup.h b/board/samsung/smdk5250/setup.h index 1276fd3e6..a15960121 100644 --- a/board/samsung/smdk5250/setup.h +++ b/board/samsung/smdk5250/setup.h @@ -1,5 +1,5 @@  /* - * Machine Specific Values for SMDK5250 board based on S5PC520 + * Machine Specific Values for SMDK5250 board based on EXYNOS5   *   * Copyright (C) 2012 Samsung Electronics   * @@ -26,12 +26,7 @@  #define _SMDK5250_SETUP_H  #include <config.h> -#include <version.h> -#include <asm/arch/cpu.h> - -/* GPIO Offsets for UART: GPIO Contol Register */ -#define EXYNOS5_GPIO_A0_CON_OFFSET	0x0 -#define EXYNOS5_GPIO_A1_CON_OFFSET	0x20 +#include <asm/arch/dmc.h>  /* TZPC : Register Offsets */  #define TZPC0_BASE		0x10100000 @@ -45,295 +40,423 @@  #define TZPC8_BASE		0x10180000  #define TZPC9_BASE		0x10190000 -/* CLK_SRC_CPU */ -/* 0 = MOUTAPLL, 1 = SCLKMPLL */ -#define MUX_HPM_SEL		0 -#define MUX_CPU_SEL		0 -#define MUX_APLL_SEL		1 -#define CLK_SRC_CPU_VAL		((MUX_HPM_SEL << 20) \ -				| (MUX_CPU_SEL << 16) \ -				| (MUX_APLL_SEL)) - -/* CLK_DIV_CPU0 */ -#define ARM2_RATIO		0x0 -#define APLL_RATIO		0x1 -#define PCLK_DBG_RATIO		0x1 -#define ATB_RATIO		0x4 -#define PERIPH_RATIO		0x7 -#define ACP_RATIO		0x7 -#define CPUD_RATIO		0x2 -#define ARM_RATIO		0x0 -#define CLK_DIV_CPU0_VAL	((ARM2_RATIO << 28) \ -				| (APLL_RATIO << 24) \ -				| (PCLK_DBG_RATIO << 20) \ -				| (ATB_RATIO << 16) \ -				| (PERIPH_RATIO << 12) \ -				| (ACP_RATIO << 8) \ -				| (CPUD_RATIO << 4) \ -				| (ARM_RATIO)) - -/* CLK_DIV_CPU1 */ -#define HPM_RATIO		0x4 -#define COPY_RATIO		0x0 -#define CLK_DIV_CPU1_VAL	((HPM_RATIO << 4) \ -				| (COPY_RATIO)) - -#define APLL_MDIV		0x7D -#define APLL_PDIV		0x3 -#define APLL_SDIV		0x0 - -#define MPLL_MDIV		0x64 -#define MPLL_PDIV		0x3 -#define MPLL_SDIV		0x0 - -#define CPLL_MDIV		0x96 -#define CPLL_PDIV		0x4 -#define CPLL_SDIV		0x0 - -/* APLL_CON1 */ +/* APLL_CON1	*/  #define APLL_CON1_VAL	(0x00203800) -/* MPLL_CON1 */ -#define MPLL_CON1_VAL	(0x00203800) +/* MPLL_CON1	*/ +#define MPLL_CON1_VAL   (0x00203800) -/* CPLL_CON1 */ +/* CPLL_CON1	*/  #define CPLL_CON1_VAL	(0x00203800) -#define EPLL_MDIV	0x60 -#define EPLL_PDIV	0x3 -#define EPLL_SDIV	0x3 +/* GPLL_CON1	*/ +#define GPLL_CON1_VAL	(0x00203800) +/* EPLL_CON1, CON2	*/  #define EPLL_CON1_VAL	0x00000000  #define EPLL_CON2_VAL	0x00000080 -#define VPLL_MDIV	0x96 -#define VPLL_PDIV	0x3 -#define VPLL_SDIV	0x2 - +/* VPLL_CON1, CON2	*/  #define VPLL_CON1_VAL	0x00000000  #define VPLL_CON2_VAL	0x00000080 -#define BPLL_MDIV	0x215 -#define BPLL_PDIV	0xC -#define BPLL_SDIV	0x1 - +/* BPLL_CON1	*/  #define BPLL_CON1_VAL	0x00203800  /* Set PLL */  #define set_pll(mdiv, pdiv, sdiv)	(1<<31 | mdiv<<16 | pdiv<<8 | sdiv) -#define APLL_CON0_VAL	set_pll(APLL_MDIV, APLL_PDIV, APLL_SDIV) -#define MPLL_CON0_VAL	set_pll(MPLL_MDIV, MPLL_PDIV, MPLL_SDIV) -#define CPLL_CON0_VAL	set_pll(CPLL_MDIV, CPLL_PDIV, CPLL_SDIV) -#define EPLL_CON0_VAL	set_pll(EPLL_MDIV, EPLL_PDIV, EPLL_SDIV) -#define VPLL_CON0_VAL	set_pll(VPLL_MDIV, VPLL_PDIV, VPLL_SDIV) -#define BPLL_CON0_VAL	set_pll(BPLL_MDIV, BPLL_PDIV, BPLL_SDIV) +/* CLK_SRC_CPU	*/ +/* 0 = MOUTAPLL,  1 = SCLKMPLL	*/ +#define MUX_HPM_SEL             0 +#define MUX_CPU_SEL             0 +#define MUX_APLL_SEL            1 + +#define CLK_SRC_CPU_VAL		((MUX_HPM_SEL << 20)    \ +				| (MUX_CPU_SEL << 16)  \ +				| (MUX_APLL_SEL)) + +/* MEMCONTROL register bit fields */ +#define DMC_MEMCONTROL_CLK_STOP_DISABLE	(0 << 0) +#define DMC_MEMCONTROL_DPWRDN_DISABLE	(0 << 1) +#define DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE	(0 << 2) +#define DMC_MEMCONTROL_TP_DISABLE	(0 << 4) +#define DMC_MEMCONTROL_DSREF_DISABLE	(0 << 5) +#define DMC_MEMCONTROL_DSREF_ENABLE	(1 << 5) +#define DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(x)    (x << 6) + +#define DMC_MEMCONTROL_MEM_TYPE_LPDDR3  (7 << 8) +#define DMC_MEMCONTROL_MEM_TYPE_DDR3    (6 << 8) +#define DMC_MEMCONTROL_MEM_TYPE_LPDDR2  (5 << 8) + +#define DMC_MEMCONTROL_MEM_WIDTH_32BIT  (2 << 12) + +#define DMC_MEMCONTROL_NUM_CHIP_1       (0 << 16) +#define DMC_MEMCONTROL_NUM_CHIP_2       (1 << 16) + +#define DMC_MEMCONTROL_BL_8             (3 << 20) +#define DMC_MEMCONTROL_BL_4             (2 << 20) + +#define DMC_MEMCONTROL_PZQ_DISABLE      (0 << 24) + +#define DMC_MEMCONTROL_MRR_BYTE_7_0     (0 << 25) +#define DMC_MEMCONTROL_MRR_BYTE_15_8    (1 << 25) +#define DMC_MEMCONTROL_MRR_BYTE_23_16   (2 << 25) +#define DMC_MEMCONTROL_MRR_BYTE_31_24   (3 << 25) + +/* MEMCONFIG0 register bit fields */ +#define DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED     (1 << 12) +#define DMC_MEMCONFIGx_CHIP_COL_10              (3 << 8) +#define DMC_MEMCONFIGx_CHIP_ROW_14              (2 << 4) +#define DMC_MEMCONFIGx_CHIP_ROW_15              (3 << 4) +#define DMC_MEMCONFIGx_CHIP_BANK_8              (3 << 0) + +#define DMC_MEMBASECONFIGx_CHIP_BASE(x)         (x << 16) +#define DMC_MEMBASECONFIGx_CHIP_MASK(x)         (x << 0) +#define DMC_MEMBASECONFIG_VAL(x)        (       \ +	DMC_MEMBASECONFIGx_CHIP_BASE(x) |       \ +	DMC_MEMBASECONFIGx_CHIP_MASK(0x780)     \ +) + +#define DMC_MEMBASECONFIG0_VAL  DMC_MEMBASECONFIG_VAL(0x40) +#define DMC_MEMBASECONFIG1_VAL  DMC_MEMBASECONFIG_VAL(0x80) + +#define DMC_PRECHCONFIG_VAL             0xFF000000 +#define DMC_PWRDNCONFIG_VAL             0xFFFF00FF + +#define DMC_CONCONTROL_RESET_VAL	0x0FFF0000 +#define DFI_INIT_START		(1 << 28) +#define EMPTY			(1 << 8) +#define AREF_EN			(1 << 5) + +#define DFI_INIT_COMPLETE_CHO	(1 << 2) +#define DFI_INIT_COMPLETE_CH1	(1 << 3) + +#define RDLVL_COMPLETE_CHO	(1 << 14) +#define RDLVL_COMPLETE_CH1	(1 << 15) + +#define CLK_STOP_EN	(1 << 0) +#define DPWRDN_EN	(1 << 1) +#define DSREF_EN	(1 << 5) + +/* COJCONTROL register bit fields */ +#define DMC_CONCONTROL_IO_PD_CON_DISABLE	(0 << 3) +#define DMC_CONCONTROL_AREF_EN_DISABLE		(0 << 5) +#define DMC_CONCONTROL_EMPTY_DISABLE		(0 << 8) +#define DMC_CONCONTROL_EMPTY_ENABLE		(1 << 8) +#define DMC_CONCONTROL_RD_FETCH_DISABLE		(0x0 << 12) +#define DMC_CONCONTROL_TIMEOUT_LEVEL0		(0xFFF << 16) +#define DMC_CONCONTROL_DFI_INIT_START_DISABLE	(0 << 28) + +/* CLK_DIV_CPU0_VAL */ +#define CLK_DIV_CPU0_VAL	((ARM2_RATIO << 28)             \ +				| (APLL_RATIO << 24)            \ +				| (PCLK_DBG_RATIO << 20)        \ +				| (ATB_RATIO << 16)             \ +				| (PERIPH_RATIO << 12)          \ +				| (ACP_RATIO << 8)              \ +				| (CPUD_RATIO << 4)             \ +				| (ARM_RATIO)) + + +/* CLK_FSYS */ +#define CLK_SRC_FSYS0_VAL              0x66666 +#define CLK_DIV_FSYS0_VAL	       0x0BB00000 + +/* CLK_DIV_CPU1	*/ +#define HPM_RATIO               0x2 +#define COPY_RATIO              0x0 + +/* CLK_DIV_CPU1 = 0x00000003 */ +#define CLK_DIV_CPU1_VAL        ((HPM_RATIO << 4)		\ +				| (COPY_RATIO))  /* CLK_SRC_CORE0 */ -#define CLK_SRC_CORE0_VAL	0x00060000 +#define CLK_SRC_CORE0_VAL       0x00000000  /* CLK_SRC_CORE1 */ -#define CLK_SRC_CORE1_VAL	0x100 +#define CLK_SRC_CORE1_VAL       0x100  /* CLK_DIV_CORE0 */ -#define CLK_DIV_CORE0_VAL	0x120000 +#define CLK_DIV_CORE0_VAL       0x00120000  /* CLK_DIV_CORE1 */ -#define CLK_DIV_CORE1_VAL	0x07070700 +#define CLK_DIV_CORE1_VAL       0x07070700 + +/* CLK_DIV_SYSRGT */ +#define CLK_DIV_SYSRGT_VAL      0x00000111 + +/* CLK_DIV_ACP */ +#define CLK_DIV_ACP_VAL         0x12 + +/* CLK_DIV_SYSLFT */ +#define CLK_DIV_SYSLFT_VAL      0x00000311  /* CLK_SRC_CDREX */ -#define CLK_SRC_CDREX_INIT_VAL	0x1 -#define CLK_SRC_CDREX_VAL	0x111 +#define CLK_SRC_CDREX_VAL       0x1  /* CLK_DIV_CDREX */ -#define CLK_DIV_CDREX_INIT_VAL	0x71771111 - -#define MCLK_CDREX2_RATIO	0x0 -#define ACLK_EFCON_RATIO	0x1 -#define MCLK_DPHY_RATIO		0x0 -#define MCLK_CDREX_RATIO	0x0 +#define MCLK_CDREX2_RATIO       0x0 +#define ACLK_EFCON_RATIO        0x1 +#define MCLK_DPHY_RATIO		0x1 +#define MCLK_CDREX_RATIO	0x1  #define ACLK_C2C_200_RATIO	0x1  #define C2C_CLK_400_RATIO	0x1 -#define PCLK_CDREX_RATIO	0x3 +#define PCLK_CDREX_RATIO	0x1  #define ACLK_CDREX_RATIO	0x1 -#define CLK_DIV_CDREX_VAL	((MCLK_DPHY_RATIO << 20) \ -				| (MCLK_CDREX_RATIO << 16) \ -				| (ACLK_C2C_200_RATIO << 12) \ -				| (C2C_CLK_400_RATIO << 8) \ -				| (PCLK_CDREX_RATIO << 4) \ -				| (ACLK_CDREX_RATIO)) - -#define MCLK_EFPHY_RATIO	0x4 -#define CLK_DIV_CDREX2_VAL	MCLK_EFPHY_RATIO -/* CLK_DIV_ACP */ -#define CLK_DIV_ACP_VAL	0x12 +#define CLK_DIV_CDREX_VAL	((MCLK_DPHY_RATIO << 24)        \ +				| (C2C_CLK_400_RATIO << 6)	\ +				| (PCLK_CDREX_RATIO << 4)	\ +				| (ACLK_CDREX_RATIO)) -/* CLK_SRC_TOP0 */ -#define MUX_ACLK_300_GSCL_SEL		0x1 -#define MUX_ACLK_300_GSCL_MID_SEL	0x0 -#define MUX_ACLK_400_SEL		0x0 -#define MUX_ACLK_333_SEL		0x0 -#define MUX_ACLK_300_DISP1_SEL		0x1 -#define MUX_ACLK_300_DISP1_MID_SEL	0x0 -#define MUX_ACLK_200_SEL		0x0 -#define MUX_ACLK_166_SEL		0x0 -#define CLK_SRC_TOP0_VAL	((MUX_ACLK_300_GSCL_SEL << 25) \ -				| (MUX_ACLK_300_GSCL_MID_SEL << 24) \ -				| (MUX_ACLK_400_SEL << 20) \ -				| (MUX_ACLK_333_SEL << 16) \ -				| (MUX_ACLK_300_DISP1_SEL << 15) \ +/* CLK_SRC_TOP0	*/ +#define MUX_ACLK_300_GSCL_SEL           0x0 +#define MUX_ACLK_300_GSCL_MID_SEL       0x0 +#define MUX_ACLK_400_G3D_MID_SEL        0x0 +#define MUX_ACLK_333_SEL	        0x0 +#define MUX_ACLK_300_DISP1_SEL	        0x0 +#define MUX_ACLK_300_DISP1_MID_SEL      0x0 +#define MUX_ACLK_200_SEL	        0x0 +#define MUX_ACLK_166_SEL	        0x0 +#define CLK_SRC_TOP0_VAL	((MUX_ACLK_300_GSCL_SEL  << 25)		\ +				| (MUX_ACLK_300_GSCL_MID_SEL << 24)	\ +				| (MUX_ACLK_400_G3D_MID_SEL << 20)	\ +				| (MUX_ACLK_333_SEL << 16)		\ +				| (MUX_ACLK_300_DISP1_SEL << 15)	\  				| (MUX_ACLK_300_DISP1_MID_SEL << 14)	\ -				| (MUX_ACLK_200_SEL << 12) \ +				| (MUX_ACLK_200_SEL << 12)		\  				| (MUX_ACLK_166_SEL << 8)) -/* CLK_SRC_TOP1 */ -#define MUX_ACLK_400_ISP_SEL		0x0 -#define MUX_ACLK_400_IOP_SEL		0x0 -#define MUX_ACLK_MIPI_HSI_TXBASE_SEL	0x0 -#define CLK_SRC_TOP1_VAL		((MUX_ACLK_400_ISP_SEL << 24) \ -					|(MUX_ACLK_400_IOP_SEL << 20) \ -					|(MUX_ACLK_MIPI_HSI_TXBASE_SEL << 16)) +/* CLK_SRC_TOP1	*/ +#define MUX_ACLK_400_G3D_SEL            0x1 +#define MUX_ACLK_400_ISP_SEL            0x0 +#define MUX_ACLK_400_IOP_SEL            0x0 +#define MUX_ACLK_MIPI_HSI_TXBASE_SEL    0x0 +#define MUX_ACLK_300_GSCL_MID1_SEL      0x0 +#define MUX_ACLK_300_DISP1_MID1_SEL     0x0 +#define CLK_SRC_TOP1_VAL	((MUX_ACLK_400_G3D_SEL << 28)           \ +				|(MUX_ACLK_400_ISP_SEL << 24)           \ +				|(MUX_ACLK_400_IOP_SEL << 20)           \ +				|(MUX_ACLK_MIPI_HSI_TXBASE_SEL << 16)   \ +				|(MUX_ACLK_300_GSCL_MID1_SEL << 12)     \ +				|(MUX_ACLK_300_DISP1_MID1_SEL << 8))  /* CLK_SRC_TOP2 */ -#define MUX_BPLL_USER_SEL	0x1 -#define MUX_MPLL_USER_SEL	0x1 -#define MUX_VPLL_SEL		0x0 -#define MUX_EPLL_SEL		0x0 -#define MUX_CPLL_SEL		0x0 -#define VPLLSRC_SEL		0x0 -#define CLK_SRC_TOP2_VAL	((MUX_BPLL_USER_SEL << 24) \ -				| (MUX_MPLL_USER_SEL << 20) \ -				| (MUX_VPLL_SEL << 16) \ -				| (MUX_EPLL_SEL << 12) \ -				| (MUX_CPLL_SEL << 8) \ +#define MUX_GPLL_SEL                    0x1 +#define MUX_BPLL_USER_SEL               0x0 +#define MUX_MPLL_USER_SEL               0x0 +#define MUX_VPLL_SEL                    0x1 +#define MUX_EPLL_SEL                    0x1 +#define MUX_CPLL_SEL                    0x1 +#define VPLLSRC_SEL                     0x0 +#define CLK_SRC_TOP2_VAL	((MUX_GPLL_SEL << 28)		\ +				| (MUX_BPLL_USER_SEL << 24)	\ +				| (MUX_MPLL_USER_SEL << 20)	\ +				| (MUX_VPLL_SEL << 16)	        \ +				| (MUX_EPLL_SEL << 12)	        \ +				| (MUX_CPLL_SEL << 8)           \  				| (VPLLSRC_SEL))  /* CLK_SRC_TOP3 */ -#define MUX_ACLK_333_SUB_SEL		0x1 -#define MUX_ACLK_400_SUB_SEL		0x1 -#define MUX_ACLK_266_ISP_SUB_SEL	0x1 -#define MUX_ACLK_266_GPS_SUB_SEL	0x1 -#define MUX_ACLK_300_GSCL_SUB_SEL	0x1 -#define MUX_ACLK_266_GSCL_SUB_SEL	0x1 -#define MUX_ACLK_300_DISP1_SUB_SEL	0x1 -#define MUX_ACLK_200_DISP1_SUB_SEL	0x1 -#define CLK_SRC_TOP3_VAL		((MUX_ACLK_333_SUB_SEL << 24) \ -					| (MUX_ACLK_400_SUB_SEL << 20) \ -					| (MUX_ACLK_266_ISP_SUB_SEL << 16) \ -					| (MUX_ACLK_266_GPS_SUB_SEL << 12) \ -					| (MUX_ACLK_300_GSCL_SUB_SEL << 10) \ -					| (MUX_ACLK_266_GSCL_SUB_SEL << 8) \ -					| (MUX_ACLK_300_DISP1_SUB_SEL << 6) \ -					| (MUX_ACLK_200_DISP1_SUB_SEL << 4)) +#define MUX_ACLK_333_SUB_SEL            0x1 +#define MUX_ACLK_400_SUB_SEL            0x1 +#define MUX_ACLK_266_ISP_SUB_SEL        0x1 +#define MUX_ACLK_266_GPS_SUB_SEL        0x0 +#define MUX_ACLK_300_GSCL_SUB_SEL       0x1 +#define MUX_ACLK_266_GSCL_SUB_SEL       0x1 +#define MUX_ACLK_300_DISP1_SUB_SEL      0x1 +#define MUX_ACLK_200_DISP1_SUB_SEL      0x1 +#define CLK_SRC_TOP3_VAL	((MUX_ACLK_333_SUB_SEL << 24)	        \ +				| (MUX_ACLK_400_SUB_SEL << 20)	        \ +				| (MUX_ACLK_266_ISP_SUB_SEL << 16)	\ +				| (MUX_ACLK_266_GPS_SUB_SEL << 12)      \ +				| (MUX_ACLK_300_GSCL_SUB_SEL << 10)     \ +				| (MUX_ACLK_266_GSCL_SUB_SEL << 8)      \ +				| (MUX_ACLK_300_DISP1_SUB_SEL << 6)     \ +				| (MUX_ACLK_200_DISP1_SUB_SEL << 4)) -/* CLK_DIV_TOP0 */ -#define ACLK_300_RATIO		0x0 -#define ACLK_400_RATIO		0x3 -#define ACLK_333_RATIO		0x2 +/* CLK_DIV_TOP0	*/ +#define ACLK_300_DISP1_RATIO	0x2 +#define ACLK_400_G3D_RATIO	0x0 +#define ACLK_333_RATIO		0x0  #define ACLK_266_RATIO		0x2  #define ACLK_200_RATIO		0x3 -#define ACLK_166_RATIO		0x5 +#define ACLK_166_RATIO		0x1  #define ACLK_133_RATIO		0x1  #define ACLK_66_RATIO		0x5 -#define CLK_DIV_TOP0_VAL	((ACLK_300_RATIO << 28) \ -				| (ACLK_400_RATIO << 24) \ -				| (ACLK_333_RATIO << 20) \ -				| (ACLK_266_RATIO << 16) \ -				| (ACLK_200_RATIO << 12) \ -				| (ACLK_166_RATIO << 8) \ -				| (ACLK_133_RATIO << 4) \ + +#define CLK_DIV_TOP0_VAL	((ACLK_300_DISP1_RATIO << 28)	\ +				| (ACLK_400_G3D_RATIO << 24)	\ +				| (ACLK_333_RATIO  << 20)	\ +				| (ACLK_266_RATIO << 16)	\ +				| (ACLK_200_RATIO << 12)	\ +				| (ACLK_166_RATIO << 8)		\ +				| (ACLK_133_RATIO << 4)		\  				| (ACLK_66_RATIO)) -/* CLK_DIV_TOP1 */ -#define ACLK_MIPI_HSI_TX_BASE_RATIO	0x3 -#define ACLK_66_PRE_RATIO	0x1 -#define ACLK_400_ISP_RATIO	0x1 -#define ACLK_400_IOP_RATIO	0x1 -#define ACLK_300_GSCL_RATIO	0x0 -#define ACLK_266_GPS_RATIO	0x7 +/* CLK_DIV_TOP1	*/ +#define ACLK_MIPI_HSI_TX_BASE_RATIO     0x3 +#define ACLK_66_PRE_RATIO               0x1 +#define ACLK_400_ISP_RATIO              0x1 +#define ACLK_400_IOP_RATIO              0x1 +#define ACLK_300_GSCL_RATIO             0x2 -#define CLK_DIV_TOP1_VAL	((ACLK_MIPI_HSI_TX_BASE_RATIO << 28) \ -				| (ACLK_66_PRE_RATIO << 24) \ -				| (ACLK_400_ISP_RATIO << 20) \ -				| (ACLK_400_IOP_RATIO << 16) \ -				| (ACLK_300_GSCL_RATIO << 12) \ -				| (ACLK_266_GPS_RATIO << 8)) +#define CLK_DIV_TOP1_VAL	((ACLK_MIPI_HSI_TX_BASE_RATIO << 28)	\ +				| (ACLK_66_PRE_RATIO << 24)		\ +				| (ACLK_400_ISP_RATIO  << 20)		\ +				| (ACLK_400_IOP_RATIO << 16)		\ +				| (ACLK_300_GSCL_RATIO << 12)) -/* APLL_LOCK */ -#define APLL_LOCK_VAL		(0x3E8) -/* MPLL_LOCK */ -#define MPLL_LOCK_VAL		(0x2F1) -/* CPLL_LOCK */ -#define CPLL_LOCK_VAL		(0x3E8) -/* EPLL_LOCK */ -#define EPLL_LOCK_VAL		(0x2321) -/* VPLL_LOCK */ -#define VPLL_LOCK_VAL		(0x2321) -/* BPLL_LOCK */ -#define BPLL_LOCK_VAL		(0x3E8) +/* APLL_LOCK	*/ +#define APLL_LOCK_VAL	(0x546) +/* MPLL_LOCK	*/ +#define MPLL_LOCK_VAL	(0x546) +/* CPLL_LOCK	*/ +#define CPLL_LOCK_VAL	(0x546) +/* GPLL_LOCK	*/ +#define GPLL_LOCK_VAL	(0x546) +/* EPLL_LOCK	*/ +#define EPLL_LOCK_VAL	(0x3A98) +/* VPLL_LOCK	*/ +#define VPLL_LOCK_VAL	(0x3A98) +/* BPLL_LOCK	*/ +#define BPLL_LOCK_VAL	(0x546) + +#define MUX_APLL_SEL_MASK	(1 << 0) +#define MUX_MPLL_SEL_MASK	(1 << 8) +#define MPLL_SEL_MOUT_MPLLFOUT	(2 << 8) +#define MUX_CPLL_SEL_MASK	(1 << 8) +#define MUX_EPLL_SEL_MASK	(1 << 12) +#define MUX_VPLL_SEL_MASK	(1 << 16) +#define MUX_GPLL_SEL_MASK	(1 << 28) +#define MUX_BPLL_SEL_MASK	(1 << 0) +#define MUX_HPM_SEL_MASK	(1 << 20) +#define HPM_SEL_SCLK_MPLL	(1 << 21) +#define APLL_CON0_LOCKED	(1 << 29) +#define MPLL_CON0_LOCKED	(1 << 29) +#define BPLL_CON0_LOCKED	(1 << 29) +#define CPLL_CON0_LOCKED	(1 << 29) +#define EPLL_CON0_LOCKED	(1 << 29) +#define GPLL_CON0_LOCKED	(1 << 29) +#define VPLL_CON0_LOCKED	(1 << 29) +#define CLK_REG_DISABLE		0x0 +#define TOP2_VAL		0x0110000  /* CLK_SRC_PERIC0 */ +#define PWM_SEL		0 +#define UART3_SEL	6 +#define UART2_SEL	6 +#define UART1_SEL	6 +#define UART0_SEL	6  /* SRC_CLOCK = SCLK_MPLL */ -#define PWM_SEL			0 -#define UART4_SEL		6 -#define UART3_SEL		6 -#define UART2_SEL		6 -#define UART1_SEL		6 -#define UART0_SEL		6 -#define CLK_SRC_PERIC0_VAL	((PWM_SEL << 24) \ -				| (UART4_SEL << 16) \ -				| (UART3_SEL << 12) \ -				| (UART2_SEL << 8) \ -				| (UART1_SEL << 4) \ -				| (UART0_SEL << 0)) +#define CLK_SRC_PERIC0_VAL	((PWM_SEL << 24)        \ +				| (UART3_SEL << 12)     \ +				| (UART2_SEL << 8)       \ +				| (UART1_SEL << 4)      \ +				| (UART0_SEL)) + +/* CLK_SRC_PERIC1 */ +/* SRC_CLOCK = SCLK_MPLL */ +#define SPI0_SEL		6 +#define SPI1_SEL		6 +#define SPI2_SEL		6 +#define CLK_SRC_PERIC1_VAL	((SPI2_SEL << 24) \ +				| (SPI1_SEL << 20) \ +				| (SPI0_SEL << 16)) + +/* SCLK_SRC_ISP - set SPI0/1 to 6 = SCLK_MPLL_USER */ +#define SPI0_ISP_SEL		6 +#define SPI1_ISP_SEL		6 +#define SCLK_SRC_ISP_VAL	(SPI1_ISP_SEL << 4) \ +				| (SPI0_ISP_SEL << 0) + +/* SCLK_DIV_ISP - set SPI0/1 to 0xf = divide by 16 */ +#define SPI0_ISP_RATIO		0xf +#define SPI1_ISP_RATIO		0xf +#define SCLK_DIV_ISP_VAL	(SPI1_ISP_RATIO << 12) \ +				| (SPI0_ISP_RATIO << 0) -#define CLK_SRC_FSYS_VAL	0x66666 -#define CLK_DIV_FSYS0_VAL	0x0BB00000 -#define CLK_DIV_FSYS1_VAL	0x000f000f -#define CLK_DIV_FSYS2_VAL	0x020f020f -#define CLK_DIV_FSYS3_VAL	0x000f +/* CLK_DIV_PERIL0	*/ +#define UART5_RATIO	7 +#define UART4_RATIO	7 +#define UART3_RATIO	7 +#define UART2_RATIO	7 +#define UART1_RATIO	7 +#define UART0_RATIO	7 -/* CLK_DIV_PERIC0 */ -#define UART5_RATIO		8 -#define UART4_RATIO		8 -#define UART3_RATIO		8 -#define UART2_RATIO		8 -#define UART1_RATIO		8 -#define UART0_RATIO		8 -#define CLK_DIV_PERIC0_VAL	((UART4_RATIO << 16) \ -				| (UART3_RATIO << 12) \ -				| (UART2_RATIO << 8) \ -				| (UART1_RATIO << 4) \ -				| (UART0_RATIO << 0)) +#define CLK_DIV_PERIC0_VAL	((UART3_RATIO << 12)    \ +				| (UART2_RATIO << 8)    \ +				| (UART1_RATIO << 4)    \ +				| (UART0_RATIO)) +/* CLK_DIV_PERIC1 */ +#define SPI1_RATIO		0x7 +#define SPI0_RATIO		0xf +#define SPI1_SUB_RATIO		0x0 +#define SPI0_SUB_RATIO		0x0 +#define CLK_DIV_PERIC1_VAL	((SPI1_SUB_RATIO << 24) \ +				| ((SPI1_RATIO << 16) \ +				| (SPI0_SUB_RATIO << 8) \ +				| (SPI0_RATIO << 0))) + +/* CLK_DIV_PERIC2 */ +#define SPI2_RATIO		0xf +#define SPI2_SUB_RATIO		0x0 +#define CLK_DIV_PERIC2_VAL	((SPI2_SUB_RATIO << 8) \ +				| (SPI2_RATIO << 0))  /* CLK_DIV_PERIC3 */  #define PWM_RATIO		8  #define CLK_DIV_PERIC3_VAL	(PWM_RATIO << 0) +/* CLK_DIV_FSYS2 */ +#define MMC2_RATIO_MASK		0xf +#define MMC2_RATIO_VAL		0x3 +#define MMC2_RATIO_OFFSET	0 + +#define MMC2_PRE_RATIO_MASK	0xff +#define MMC2_PRE_RATIO_VAL	0x9 +#define MMC2_PRE_RATIO_OFFSET	8 + +#define MMC3_RATIO_MASK		0xf +#define MMC3_RATIO_VAL		0x1 +#define MMC3_RATIO_OFFSET	16 + +#define MMC3_PRE_RATIO_MASK	0xff +#define MMC3_PRE_RATIO_VAL	0x0 +#define MMC3_PRE_RATIO_OFFSET	24 +  /* CLK_SRC_LEX */ -#define CLK_SRC_LEX_VAL		0x0 +#define CLK_SRC_LEX_VAL         0x0  /* CLK_DIV_LEX */ -#define CLK_DIV_LEX_VAL		0x10 +#define CLK_DIV_LEX_VAL         0x10  /* CLK_DIV_R0X */ -#define CLK_DIV_R0X_VAL		0x10 +#define CLK_DIV_R0X_VAL         0x10  /* CLK_DIV_L0X */ -#define CLK_DIV_R1X_VAL		0x10 +#define CLK_DIV_R1X_VAL         0x10 -/* SCLK_SRC_ISP */ -#define SCLK_SRC_ISP_VAL	0x600  /* CLK_DIV_ISP0 */ -#define CLK_DIV_ISP0_VAL	0x31 +#define CLK_DIV_ISP0_VAL        0x31  /* CLK_DIV_ISP1 */ -#define CLK_DIV_ISP1_VAL	0x0 +#define CLK_DIV_ISP1_VAL        0x0  /* CLK_DIV_ISP2 */ -#define CLK_DIV_ISP2_VAL	0x1 +#define CLK_DIV_ISP2_VAL        0x1 -#define MPLL_DEC	(MPLL_MDIV * MPLL_MDIV / (MPLL_PDIV * 2^(MPLL_SDIV-1))) +/* CLK_SRC_DISP1_0 */ +#define CLK_SRC_DISP1_0_VAL	0x6 + +/* + * DIV_DISP1_0 + * For DP, divisor should be 2 + */ +#define CLK_DIV_DISP1_0_FIMD1	(2 << 0) + +/* CLK_GATE_IP_DISP1 */ +#define CLK_GATE_DP1_ALLOW	(1 << 4)  /*   * TZPC Register Value : @@ -347,105 +470,125 @@   */  #define DECPROTXSET		0xFF -/* DMC Init */ -#define SET			1 -#define RESET			0 -/* (Memory Interleaving Size = 1 << IV_SIZE) */ -#define CONFIG_IV_SIZE		0x07 +#define DDR3PHY_CTRL_PHY_RESET	(1 << 0) +#define DDR3PHY_CTRL_PHY_RESET_OFF	(0 << 0) + +#define PHY_CON0_RESET_VAL	0x17020a40 +#define P0_CMD_EN		(1 << 14) +#define BYTE_RDLVL_EN		(1 << 13) +#define CTRL_SHGATE		(1 << 8) + +#define PHY_CON1_RESET_VAL	0x09210100 +#define CTRL_GATEDURADJ_MASK	(0xf << 20) -#define PHY_RESET_VAL	(0 << 0) +#define PHY_CON2_RESET_VAL	0x00010004 +#define INIT_DESKEW_EN		(1 << 6) +#define RDLVL_GATE_EN		(1 << 24)  /*ZQ Configurations */  #define PHY_CON16_RESET_VAL	0x08000304 -#define ZQ_MODE_DDS_VAL		(0x5 << 24) -#define ZQ_MODE_TERM_VAL	(0x5 << 21) -#define SET_ZQ_MODE_DDS_VAL(x)	(x = (x & ~(0x7 << 24)) | ZQ_MODE_DDS_VAL) -#define SET_ZQ_MODE_TERM_VAL(x)	(x = (x & ~(0x7 << 21)) | ZQ_MODE_TERM_VAL) - -#define ZQ_MODE_NOTERM		(1 << 19)  #define ZQ_CLK_DIV_EN		(1 << 18)  #define ZQ_MANUAL_STR		(1 << 1) +#define ZQ_DONE			(1 << 0) -/* Channel and Chip Selection */ -#define CONFIG_DMC_CHANNELS		2 -#define CONFIG_CHIPS_PER_CHANNEL	2 - -#define SET_CMD_CHANNEL(x, y)	(x = (x & ~(1 << 28)) | y << 28) -#define SET_CMD_CHIP(x, y)	(x = (x & ~(1 << 20)) | y << 20) +#define CTRL_RDLVL_GATE_ENABLE	1 +#define CTRL_RDLVL_GATE_DISABLE	1 -/* Diret Command */ -#define	DIRECT_CMD_NOP		0x07000000 -#define DIRECT_CMD_MRS1		0x00071C00 -#define DIRECT_CMD_MRS2		0x00010BFC -#define DIRECT_CMD_MRS3		0x00000708 -#define DIRECT_CMD_MRS4		0x00000818 -#define	DIRECT_CMD_PALL		0x01000000 +/* Direct Command */ +#define DIRECT_CMD_NOP			0x07000000 +#define DIRECT_CMD_PALL			0x01000000 +#define DIRECT_CMD_ZQINIT		0x0a000000 +#define DIRECT_CMD_CHANNEL_SHIFT	28 +#define DIRECT_CMD_CHIP_SHIFT		20 -/* DLL Resync */ -#define FP_RSYNC		(1 << 3) - -#define CONFIG_CTRL_DLL_ON(x, y)	(x = (x & ~(1 << 5)) | y << 5) -#define CONFIG_CTRL_START(x, y)		(x = (x & ~(1 << 6)) | y << 6) -#define SET_CTRL_FORCE_VAL(x, y)	(x = (x & ~(0x7F << 8)) | y << 8) - -/* RDLVL */ -#define PHY_CON0_RESET_VAL	0x17023240 -#define DDR_MODE_LPDDR2		0x2 -#define BYTE_RDLVL_EN		(1 << 13) -#define CTRL_ATGATE		(1 << 6) -#define SET_CTRL_DDR_MODE(x, y)	(x = (x & ~(0x3 << 11)) | y << 11) +/* DMC PHY Control0 register */ +#define PHY_CONTROL0_RESET_VAL	0x0 +#define MEM_TERM_EN	(1 << 31)	/* Termination enable for memory */ +#define PHY_TERM_EN	(1 << 30)	/* Termination enable for PHY */ +#define DMC_CTRL_SHGATE	(1 << 29)	/* Duration of DQS gating signal */ +#define FP_RSYNC	(1 << 3)	/* Force DLL resyncronization */ -#define PHY_CON1_RESET_VAL	0x9210100 -#define RDLVL_RDDATAPADJ	0x1 -#define SET_RDLVL_RDDATAPADJ	((PHY_CON1_RESET_VAL & ~(0xFFFF << 0))\ -					| RDLVL_RDDATAPADJ << 0) +/* Driver strength for CK, CKE, CS & CA */ +#define IMP_OUTPUT_DRV_40_OHM	0x5 +#define IMP_OUTPUT_DRV_30_OHM	0x7 +#define CA_CK_DRVR_DS_OFFSET	9 +#define CA_CKE_DRVR_DS_OFFSET	6 +#define CA_CS_DRVR_DS_OFFSET	3 +#define CA_ADR_DRVR_DS_OFFSET	0 -#define PHY_CON2_RESET_VAL	0x00010004 -#define RDLVL_EN		(1 << 25) -#define RDDSKEW_CLEAR		(1 << 13) +#define PHY_CON42_CTRL_BSTLEN_SHIFT	8 +#define PHY_CON42_CTRL_RDLAT_SHIFT	0 -#define CTRL_RDLVL_DATA_EN	(1 << 1) -#define LPDDR2_ADDR		0x00000208 +struct mem_timings; -#define DMC_MEMCONFIG0_VAL	0x00001323 -#define DMC_MEMCONFIG1_VAL	0x00001323 -#define DMC_MEMBASECONFIG0_VAL	0x00400780 -#define DMC_MEMBASECONFIG1_VAL	0x00800780 -#define DMC_MEMCONTROL_VAL	0x00212500 -#define DMC_PRECHCONFIG_VAL		0xFF000000 -#define DMC_PWRDNCONFIG_VAL		0xFFFF00FF -#define DMC_TIMINGREF_VAL		0x0000005D -#define DMC_TIMINGROW_VAL		0x2336544C -#define DMC_TIMINGDATA_VAL		0x24202408 -#define DMC_TIMINGPOWER_VAL		0x38260235 +/* Errors that we can encourter in low-level setup */ +enum { +	SETUP_ERR_OK, +	SETUP_ERR_RDLV_COMPLETE_TIMEOUT = -1, +	SETUP_ERR_ZQ_CALIBRATION_FAILURE = -2, +}; -#define CTRL_BSTLEN		0x04 -#define CTRL_RDLAT		0x08 -#define PHY_CON42_VAL		(CTRL_BSTLEN << 8 | CTRL_RDLAT << 0) +/* + * Memory variant specific initialization code + * + * @param mem		Memory timings for this memory type. + * @param mem_iv_size	Memory interleaving size is a configurable parameter + *			which the DMC uses to decide how to split a memory + *			chunk into smaller chunks to support concurrent + *			accesses; may vary across boards. + * @return 0 if ok, SETUP_ERR_... if there is a problem + */ +int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size); -/* DQS, DQ, DEBUG offsets */ -#define	SET_DQS_OFFSET_VAL	0x7F7F7F7F -#define	SET_DQ_OFFSET_VAL	0x7F7F7F7F -#define	SET_DEBUG_OFFSET_VAL	0x7F +/* + * Configure ZQ I/O interface + * + * @param mem		Memory timings for this memory type. + * @param phy0_ctrl	Pointer to struct containing PHY0 control reg + * @param phy1_ctrl	Pointer to struct containing PHY1 control reg + * @return 0 if ok, -1 on error + */ +int dmc_config_zq(struct mem_timings *mem, +		  struct exynos5_phy_control *phy0_ctrl, +		  struct exynos5_phy_control *phy1_ctrl); -#define	RESET_DQS_OFFSET_VAL	0x08080808 -#define	RESET_DQ_OFFSET_VAL	0x08080808 -#define	RESET_DEBUG_OFFSET_VAL	0x8 +/* + * Send NOP and MRS/EMRS Direct commands + * + * @param mem		Memory timings for this memory type. + * @param dmc		Pointer to struct of DMC registers + */ +void dmc_config_mrs(struct mem_timings *mem, struct exynos5_dmc *dmc); -#define CTRL_PULLD_DQ		(0x0F << 8) -#define CTRL_PULLD_DQS		(0x0F << 0) +/* + * Send PALL Direct commands + * + * @param mem		Memory timings for this memory type. + * @param dmc		Pointer to struct of DMC registers + */ +void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc); -#define DFI_INIT_START		(1 << 28) +/* + * Configure the memconfig and membaseconfig registers + * + * @param mem		Memory timings for this memory type. + * @param exynos5_dmc	Pointer to struct of DMC registers + */ +void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc); -#define CLK_STOP_EN	(1 << 0) -#define DPWRDN_EN	(1 << 1) -#define DSREF_EN	(1 << 5) +/* + * Reset the DLL. This function is common between DDR3 and LPDDR2. + * However, the reset value is different. So we are passing a flag + * ddr_mode to distinguish between LPDDR2 and DDR3. + * + * @param exynos5_dmc	Pointer to struct of DMC registers + * @param ddr_mode	Type of DDR memory + */ +void update_reset_dll(struct exynos5_dmc *, enum ddr_mode); -#define AREF_EN			(1 << 5)  void sdelay(unsigned long);  void mem_ctrl_init(void);  void system_clock_init(void);  void tzpc_init(void); -  #endif diff --git a/board/samsung/smdk5250/smdk5250-uboot-spl.lds b/board/samsung/smdk5250/smdk5250-uboot-spl.lds new file mode 100644 index 000000000..d78dd77ef --- /dev/null +++ b/board/samsung/smdk5250/smdk5250-uboot-spl.lds @@ -0,0 +1,66 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * Copyright (C) 2012 Samsung Electronics + * + * Based on arch/arm/cpu/armv7/omap-common/u-boot-spl.lds + * + * 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 + */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE, \ +		LENGTH = CONFIG_SPL_MAX_SIZE } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) + +SECTIONS +{ +	.text : +	{ +		__start = .; +		arch/arm/cpu/armv7/start.o (.text) +		*(.text*) +	} >.sram +	. = ALIGN(4); + +	.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram +	. = ALIGN(4); + +	.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram +	. = ALIGN(4); + +	/* Align .machine_param on 256 byte boundary for easier searching */ +	.machine_param ALIGN(0x100) : { *(.machine_param) } >.sram +	. = ALIGN(4); + +	__image_copy_end = .; +	_end = .; + +	.bss : +	{ +		. = ALIGN(4); +		__bss_start = .; +		*(.bss*) +		. = ALIGN(4); +		__bss_end__ = .; +	} >.sram +} diff --git a/board/samsung/smdk5250/smdk5250.c b/board/samsung/smdk5250/smdk5250.c index fae7d6f0e..a5816e445 100644 --- a/board/samsung/smdk5250/smdk5250.c +++ b/board/samsung/smdk5250/smdk5250.c @@ -131,13 +131,13 @@ int board_mmc_init(bd_t *bis)  {  	int err; -	err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE); +	err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE);  	if (err) { -		debug("SDMMC2 not configured\n"); +		debug("SDMMC0 not configured\n");  		return err;  	} -	err = s5p_mmc_init(2, 4); +	err = s5p_mmc_init(0, 8);  	return err;  }  #endif diff --git a/board/samsung/smdk5250/smdk5250_spl.c b/board/samsung/smdk5250/smdk5250_spl.c new file mode 100644 index 000000000..1d453cafc --- /dev/null +++ b/board/samsung/smdk5250/smdk5250_spl.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * 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 <asm/arch/cpu.h> +#include <asm/arch/spl.h> +#include <asm/arch/clk.h> + +#define SIGNATURE	0xdeadbeef + +/* Parameters of early board initialization in SPL */ +static struct spl_machine_param machine_param +		__attribute__((section(".machine_param"))) = { +	.signature	= SIGNATURE, +	.version	= 1, +	.params		= "vmubfasirM", +	.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, +	.mem_manuf	= MEM_MANUF_SAMSUNG, +}; + +struct spl_machine_param *spl_get_machine_params(void) +{ +	if (machine_param.signature != SIGNATURE) { +		/* Will hang if SIGNATURE dont match */ +		while (1) +			; +	} + +	return &machine_param; +} diff --git a/board/samsung/smdkc100/lowlevel_init.S b/board/samsung/smdkc100/lowlevel_init.S index 6d18835ac..6f9a554d9 100644 --- a/board/samsung/smdkc100/lowlevel_init.S +++ b/board/samsung/smdkc100/lowlevel_init.S @@ -50,12 +50,10 @@ lowlevel_init:  	orr	r0, r0, #0x0  	str	r5, [r0] -#ifndef CONFIG_ONENAND_IPL  	/* setting SRAM */  	ldr	r0, =S5PC100_SROMC_BASE  	ldr	r1, =0x9  	str	r1, [r0] -#endif  	/* S5PC100 has 3 groups of interrupt sources */  	ldr	r0, =S5PC100_VIC0_BASE			@0xE4000000 @@ -68,7 +66,6 @@ lowlevel_init:  	str	r3, [r1, #0x14]				@INTENCLEAR  	str	r3, [r2, #0x14]				@INTENCLEAR -#ifndef CONFIG_ONENAND_IPL  	/* Set all interrupts as IRQ */  	str	r5, [r0, #0xc]				@INTSELECT  	str	r5, [r1, #0xc]				@INTSELECT @@ -78,54 +75,17 @@ lowlevel_init:  	str	r5, [r0, #0xf00]			@INTADDRESS  	str	r5, [r1, #0xf00]			@INTADDRESS  	str	r5, [r2, #0xf00]			@INTADDRESS -#endif -#ifndef CONFIG_ONENAND_IPL  	/* for UART */  	bl uart_asm_init  	/* for TZPC */  	bl tzpc_asm_init -#endif - -#ifdef CONFIG_ONENAND_IPL -	/* init system clock */ -	bl	system_clock_init - -	bl	mem_ctrl_asm_init - -	/* Wakeup support. Don't know if it's going to be used, untested. */ -	ldr	r0, =S5PC100_RST_STAT -	ldr	r1, [r0] -	bic	r1, r1, #0xfffffff7 -	cmp	r1, #0x8 -	beq	wakeup_reset -#endif  1:  	mov	lr, r9  	mov	pc, lr -#ifdef CONFIG_ONENAND_IPL -wakeup_reset: - -	/* Clear wakeup status register */ -	ldr	r0, =S5PC100_WAKEUP_STAT -	ldr	r1, [r0] -	str	r1, [r0] - -	/* Load return address and jump to kernel */ -	ldr	r0, =S5PC100_INFORM0 - -	/* r1 = physical address of s5pc100_cpu_resume function */ -	ldr	r1, [r0] - -	/* Jump to kernel (sleep.S) */ -	mov	pc, r1 -	nop -	nop -#endif -  /*   * system_clock_init: Initialize core clock and bus clock.   * void system_clock_init(void) @@ -178,7 +138,6 @@ system_clock_init:  	mov	pc, lr -#ifndef CONFIG_ONENAND_IPL  /*   * uart_asm_init: Initialize UART's pins   */ @@ -212,4 +171,3 @@ tzpc_asm_init:  	str	r1, [r0, #0x810]  	mov	pc, lr -#endif diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index a8b2b11c4..e11a8922f 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -59,6 +59,8 @@ static int hwrevision(int rev)  	return (board_rev & 0xf) == rev;  } +struct s3c_plat_otg_data s5pc210_otg_data; +  int board_init(void)  {  	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; @@ -73,6 +75,21 @@ int board_init(void)  	return 0;  } +void i2c_init_board(void) +{ +	struct exynos4_gpio_part1 *gpio1 = +		(struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1(); +	struct exynos4_gpio_part2 *gpio2 = +		(struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2(); + +	/* I2C_5 -> PMIC */ +	s5p_gpio_direction_output(&gpio1->b, 7, 1); +	s5p_gpio_direction_output(&gpio1->b, 6, 1); +	/* I2C_9 -> FG */ +	s5p_gpio_direction_output(&gpio2->y4, 0, 1); +	s5p_gpio_direction_output(&gpio2->y4, 1, 1); +} +  int dram_init(void)  {  	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) + @@ -259,6 +276,12 @@ struct s3c_plat_otg_data s5pc210_otg_data = {  	.usb_phy_ctrl	= EXYNOS4_USBPHY_CONTROL,  	.usb_flags	= PHY0_SLEEP,  }; + +void board_usb_init(void) +{ +	debug("USB_udc_probe\n"); +	s3c_udc_probe(&s5pc210_otg_data); +}  #endif  static void pmic_reset(void) |