diff options
Diffstat (limited to 'arch/arm/cpu/armv7/mx6')
| -rw-r--r-- | arch/arm/cpu/armv7/mx6/Kconfig | 138 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/mx6/clock.c | 23 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/mx6/ddr.c | 379 | 
3 files changed, 524 insertions, 16 deletions
| diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig index dce7ffc022a..8b0120fea50 100644 --- a/arch/arm/cpu/armv7/mx6/Kconfig +++ b/arch/arm/cpu/armv7/mx6/Kconfig @@ -33,25 +33,159 @@ choice  	prompt "MX6 board select"  	optional +config TARGET_ARISTAINETOS +	bool "aristainetos" +	select CPU_V7 + +config TARGET_ARISTAINETOS2 +	bool "aristainetos2" +	select CPU_V7 + +config TARGET_ARISTAINETOS2B +	bool "Support aristainetos2-revB" +	select CPU_V7 + +config TARGET_CGTQMX6EVAL +	bool "cgtqmx6eval" +	select CPU_V7 +  config TARGET_CM_FX6 -	bool "Support CM-FX6" +	bool "CM-FX6"  	select SUPPORT_SPL  	select DM  	select DM_SERIAL  	select DM_GPIO +config TARGET_EMBESTMX6BOARDS +	bool "embestmx6boards" +	select CPU_V7 + +config TARGET_GW_VENTANA +	bool "gw_ventana" +	select CPU_V7 +	select SUPPORT_SPL + +config TARGET_KOSAGI_NOVENA +	bool "Kosagi Novena" +	select CPU_V7 +	select SUPPORT_SPL + +config TARGET_MX6CUBOXI +	bool "Solid-run mx6 boards" +	select CPU_V7 +	select SUPPORT_SPL + +config TARGET_MX6QARM2 +	bool "mx6qarm2" +	select CPU_V7 + +config TARGET_MX6QSABREAUTO +	bool "mx6qsabreauto" +	select CPU_V7 +	select DM +	select DM_THERMAL + +config TARGET_MX6SABRESD +	bool "mx6sabresd" +	select CPU_V7 +	select SUPPORT_SPL +	select DM +	select DM_THERMAL + +config TARGET_MX6SLEVK +	bool "mx6slevk" +	select CPU_V7 +	select SUPPORT_SPL + +config TARGET_MX6SXSABRESD +	bool "mx6sxsabresd" +	select CPU_V7 +	select SUPPORT_SPL +	select DM +	select DM_THERMAL + +config TARGET_MX6UL_14X14_EVK +	bool "mx6ul_14x14_evk" +	select MX6UL +	select CPU_V7 +	select DM +	select DM_THERMAL +	select SUPPORT_SPL + +config TARGET_NITROGEN6X +	bool "nitrogen6x" +	select CPU_V7 + +config TARGET_OT1200 +	bool "Bachmann OT1200" +	select CPU_V7 +	select SUPPORT_SPL + +config TARGET_PLATINUM_PICON +	bool "platinum-picon" +	select CPU_V7 +	select SUPPORT_SPL + +config TARGET_PLATINUM_TITANIUM +	bool "platinum-titanium" +	select CPU_V7 +	select SUPPORT_SPL +  config TARGET_SECOMX6 -	bool "Support secomx6 boards" +	bool "secomx6 boards" + +config TARGET_TBS2910 +	bool "TBS2910 Matrix ARM mini PC" +	select CPU_V7 + +config TARGET_TITANIUM +	bool "titanium" +	select CPU_V7  config TARGET_TQMA6  	bool "TQ Systems TQMa6 board" +config TARGET_UDOO +	bool "udoo" +	select CPU_V7 +	select SUPPORT_SPL + +config TARGET_WANDBOARD +	bool "wandboard" +	select CPU_V7 +	select SUPPORT_SPL + +config TARGET_WARP +	bool "WaRP" +	select CPU_V7 +  endchoice  config SYS_SOC  	default "mx6" +source "board/aristainetos/Kconfig" +source "board/bachmann/ot1200/Kconfig" +source "board/barco/platinum/Kconfig" +source "board/barco/titanium/Kconfig" +source "board/boundary/nitrogen6x/Kconfig" +source "board/compulab/cm_fx6/Kconfig" +source "board/congatec/cgtqmx6eval/Kconfig" +source "board/embest/mx6boards/Kconfig" +source "board/freescale/mx6qarm2/Kconfig" +source "board/freescale/mx6qsabreauto/Kconfig" +source "board/freescale/mx6sabresd/Kconfig" +source "board/freescale/mx6slevk/Kconfig" +source "board/freescale/mx6sxsabresd/Kconfig" +source "board/freescale/mx6ul_14x14_evk/Kconfig" +source "board/gateworks/gw_ventana/Kconfig" +source "board/kosagi/novena/Kconfig"  source "board/seco/Kconfig" +source "board/solidrun/mx6cuboxi/Kconfig" +source "board/tbs/tbs2910/Kconfig"  source "board/tqc/tqma6/Kconfig" +source "board/udoo/Kconfig" +source "board/wandboard/Kconfig" +source "board/warp/Kconfig"  endif diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c index 9cf4eece137..ba6cc75a7b2 100644 --- a/arch/arm/cpu/armv7/mx6/clock.c +++ b/arch/arm/cpu/armv7/mx6/clock.c @@ -524,7 +524,7 @@ void enable_qspi_clk(int qspi_num)  #endif  #ifdef CONFIG_FEC_MXC -int enable_fec_anatop_clock(enum enet_freq freq) +int enable_fec_anatop_clock(int fec_id, enum enet_freq freq)  {  	u32 reg = 0;  	s32 timeout = 100000; @@ -535,9 +535,19 @@ int enable_fec_anatop_clock(enum enet_freq freq)  	if (freq < ENET_25MHZ || freq > ENET_125MHZ)  		return -EINVAL; -	reg = readl(&anatop->pll_enet); -	reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT; -	reg |= freq; +	if (fec_id == 0) { +		reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT; +		reg |= BF_ANADIG_PLL_ENET_DIV_SELECT(freq); +	} else if (fec_id == 1) { +		/* Only i.MX6SX/UL support ENET2 */ +		if (!(is_cpu_type(MXC_CPU_MX6SX) || +		      is_cpu_type(MXC_CPU_MX6UL))) +			return -EINVAL; +		reg &= ~BM_ANADIG_PLL_ENET2_DIV_SELECT; +		reg |= BF_ANADIG_PLL_ENET2_DIV_SELECT(freq); +	} else { +		return -EINVAL; +	}  	if ((reg & BM_ANADIG_PLL_ENET_POWERDOWN) ||  	    (!(reg & BM_ANADIG_PLL_ENET_LOCK))) { @@ -552,7 +562,10 @@ int enable_fec_anatop_clock(enum enet_freq freq)  	}  	/* Enable FEC clock */ -	reg |= BM_ANADIG_PLL_ENET_ENABLE; +	if (fec_id == 0) +		reg |= BM_ANADIG_PLL_ENET_ENABLE; +	else +		reg |= BM_ANADIG_PLL_ENET2_ENABLE;  	reg &= ~BM_ANADIG_PLL_ENET_BYPASS;  	writel(reg, &anatop->pll_enet); diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c index b808627a427..cf5587be54b 100644 --- a/arch/arm/cpu/armv7/mx6/ddr.c +++ b/arch/arm/cpu/armv7/mx6/ddr.c @@ -7,6 +7,7 @@  #include <common.h>  #include <linux/types.h> +#include <asm/arch/clock.h>  #include <asm/arch/mx6-ddr.h>  #include <asm/arch/sys_proto.h>  #include <asm/io.h> @@ -115,6 +116,61 @@ void mx6ul_dram_iocfg(unsigned width,  }  #endif +#if defined(CONFIG_MX6SL) +void mx6sl_dram_iocfg(unsigned width, +		      const struct mx6sl_iomux_ddr_regs *ddr, +		      const struct mx6sl_iomux_grp_regs *grp) +{ +	struct mx6sl_iomux_ddr_regs *mx6_ddr_iomux; +	struct mx6sl_iomux_grp_regs *mx6_grp_iomux; + +	mx6_ddr_iomux = (struct mx6sl_iomux_ddr_regs *)MX6SL_IOM_DDR_BASE; +	mx6_grp_iomux = (struct mx6sl_iomux_grp_regs *)MX6SL_IOM_GRP_BASE; + +	/* DDR IO TYPE */ +	mx6_grp_iomux->grp_ddr_type = grp->grp_ddr_type; +	mx6_grp_iomux->grp_ddrpke = grp->grp_ddrpke; + +	/* CLOCK */ +	mx6_ddr_iomux->dram_sdclk_0 = ddr->dram_sdclk_0; + +	/* ADDRESS */ +	mx6_ddr_iomux->dram_cas = ddr->dram_cas; +	mx6_ddr_iomux->dram_ras = ddr->dram_ras; +	mx6_grp_iomux->grp_addds = grp->grp_addds; + +	/* Control */ +	mx6_ddr_iomux->dram_reset = ddr->dram_reset; +	mx6_ddr_iomux->dram_sdba2 = ddr->dram_sdba2; +	mx6_grp_iomux->grp_ctlds = grp->grp_ctlds; + +	/* Data Strobes */ +	mx6_grp_iomux->grp_ddrmode_ctl = grp->grp_ddrmode_ctl; +	mx6_ddr_iomux->dram_sdqs0 = ddr->dram_sdqs0; +	mx6_ddr_iomux->dram_sdqs1 = ddr->dram_sdqs1; +	if (width >= 32) { +		mx6_ddr_iomux->dram_sdqs2 = ddr->dram_sdqs2; +		mx6_ddr_iomux->dram_sdqs3 = ddr->dram_sdqs3; +	} + +	/* Data */ +	mx6_grp_iomux->grp_ddrmode = grp->grp_ddrmode; +	mx6_grp_iomux->grp_b0ds = grp->grp_b0ds; +	mx6_grp_iomux->grp_b1ds = grp->grp_b1ds; +	if (width >= 32) { +		mx6_grp_iomux->grp_b2ds = grp->grp_b2ds; +		mx6_grp_iomux->grp_b3ds = grp->grp_b3ds; +	} + +	mx6_ddr_iomux->dram_dqm0 = ddr->dram_dqm0; +	mx6_ddr_iomux->dram_dqm1 = ddr->dram_dqm1; +	if (width >= 32) { +		mx6_ddr_iomux->dram_dqm2 = ddr->dram_dqm2; +		mx6_ddr_iomux->dram_dqm3 = ddr->dram_dqm3; +	} +} +#endif +  #if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)  /* Configure MX6DQ mmdc iomux */  void mx6dq_dram_iocfg(unsigned width, @@ -275,24 +331,314 @@ void mx6sdl_dram_iocfg(unsigned width,   * Configure mx6 mmdc registers based on:   *  - board-specific memory configuration   *  - board-specific calibration data - *  - ddr3 chip details + *  - ddr3/lpddr2 chip details   *   * The various calculations here are derived from the Freescale - * i.Mx6DQSDL DDR3 Script Aid spreadsheet (DOC-94917) designed to generate MMDC - * configuration registers based on memory system and memory chip parameters. + * 1. i.Mx6DQSDL DDR3 Script Aid spreadsheet (DOC-94917) designed to generate + *    MMDC configuration registers based on memory system and memory chip + *    parameters. + * + * 2. i.Mx6SL LPDDR2 Script Aid spreadsheet V0.04 designed to generate MMDC + *    configuration registers based on memory system and memory chip + *    parameters.   *   * The defaults here are those which were specified in the spreadsheet.   * For details on each register, refer to the IMX6DQRM and/or IMX6SDLRM - * section titled MMDC initialization + * and/or IMX6SLRM section titled MMDC initialization.   */  #define MR(val, ba, cmd, cs1) \  	((val << 16) | (1 << 15) | (cmd << 4) | (cs1 << 3) | ba)  #define MMDC1(entry, value) do {					  \ -	if (!is_cpu_type(MXC_CPU_MX6SX) && !is_cpu_type(MXC_CPU_MX6UL))	  \ +	if (!is_cpu_type(MXC_CPU_MX6SX) && !is_cpu_type(MXC_CPU_MX6UL) && \ +	    !is_cpu_type(MXC_CPU_MX6SL))				  \  		mmdc1->entry = value;					  \  	} while (0) -void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, +/* + * According JESD209-2B-LPDDR2: Table 103 + * WL: write latency + */ +static int lpddr2_wl(uint32_t mem_speed) +{ +	switch (mem_speed) { +	case 1066: +	case 933: +		return 4; +	case 800: +		return 3; +	case 677: +	case 533: +		return 2; +	case 400: +	case 333: +		return 1; +	default: +		puts("invalid memory speed\n"); +		hang(); +	} + +	return 0; +} + +/* + * According JESD209-2B-LPDDR2: Table 103 + * RL: read latency + */ +static int lpddr2_rl(uint32_t mem_speed) +{ +	switch (mem_speed) { +	case 1066: +		return 8; +	case 933: +		return 7; +	case 800: +		return 6; +	case 677: +		return 5; +	case 533: +		return 4; +	case 400: +	case 333: +		return 3; +	default: +		puts("invalid memory speed\n"); +		hang(); +	} + +	return 0; +} + +void mx6_lpddr2_cfg(const struct mx6_ddr_sysinfo *sysinfo, +		    const struct mx6_mmdc_calibration *calib, +		    const struct mx6_lpddr2_cfg *lpddr2_cfg) +{ +	volatile struct mmdc_p_regs *mmdc0; +	u32 val; +	u8 tcke, tcksrx, tcksre, trrd; +	u8 twl, txp, tfaw, tcl; +	u16 tras, twr, tmrd, trtp, twtr, trfc, txsr; +	u16 trcd_lp, trppb_lp, trpab_lp, trc_lp; +	u16 cs0_end; +	u8 coladdr; +	int clkper; /* clock period in picoseconds */ +	int clock;  /* clock freq in mHz */ +	int cs; + +	/* only support 16/32 bits */ +	if (sysinfo->dsize > 1) +		hang(); + +	mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; + +	clock = mxc_get_clock(MXC_DDR_CLK) / 1000000U; +	clkper = (1000 * 1000) / clock; /* pico seconds */ + +	twl = lpddr2_wl(lpddr2_cfg->mem_speed) - 1; + +	/* LPDDR2-S2 and LPDDR2-S4 have the same tRFC value. */ +	switch (lpddr2_cfg->density) { +	case 1: +	case 2: +	case 4: +		trfc = DIV_ROUND_UP(130000, clkper) - 1; +		txsr = DIV_ROUND_UP(140000, clkper) - 1; +		break; +	case 8: +		trfc = DIV_ROUND_UP(210000, clkper) - 1; +		txsr = DIV_ROUND_UP(220000, clkper) - 1; +		break; +	default: +		/* +		 * 64Mb, 128Mb, 256Mb, 512Mb are not supported currently. +		 */ +		hang(); +		break; +	} +	/* +	 * txpdll, txpr, taonpd and taofpd are not relevant in LPDDR2 mode, +	 * set them to 0. */ +	txp = DIV_ROUND_UP(7500, clkper) - 1; +	tcke = 3; +	if (lpddr2_cfg->mem_speed == 333) +		tfaw = DIV_ROUND_UP(60000, clkper) - 1; +	else +		tfaw = DIV_ROUND_UP(50000, clkper) - 1; +	trrd = DIV_ROUND_UP(10000, clkper) - 1; + +	/* tckesr for LPDDR2 */ +	tcksre = DIV_ROUND_UP(15000, clkper); +	tcksrx = tcksre; +	twr  = DIV_ROUND_UP(15000, clkper) - 1; +	/* +	 * tMRR: 2, tMRW: 5 +	 * tMRD should be set to max(tMRR, tMRW) +	 */ +	tmrd = 5; +	tras = DIV_ROUND_UP(lpddr2_cfg->trasmin, clkper / 10) - 1; +	/* LPDDR2 mode use tRCD_LP filed in MDCFG3. */ +	trcd_lp = DIV_ROUND_UP(lpddr2_cfg->trcd_lp, clkper / 10) - 1; +	trc_lp = DIV_ROUND_UP(lpddr2_cfg->trasmin + lpddr2_cfg->trppb_lp, +			      clkper / 10) - 1; +	trppb_lp = DIV_ROUND_UP(lpddr2_cfg->trppb_lp, clkper / 10) - 1; +	trpab_lp = DIV_ROUND_UP(lpddr2_cfg->trpab_lp, clkper / 10) - 1; +	/* To LPDDR2, CL in MDCFG0 refers to RL */ +	tcl = lpddr2_rl(lpddr2_cfg->mem_speed) - 3; +	twtr = DIV_ROUND_UP(7500, clkper) - 1; +	trtp = DIV_ROUND_UP(7500, clkper) - 1; + +	cs0_end = 4 * sysinfo->cs_density - 1; + +	debug("density:%d Gb (%d Gb per chip)\n", +	      sysinfo->cs_density, lpddr2_cfg->density); +	debug("clock: %dMHz (%d ps)\n", clock, clkper); +	debug("memspd:%d\n", lpddr2_cfg->mem_speed); +	debug("trcd_lp=%d\n", trcd_lp); +	debug("trppb_lp=%d\n", trppb_lp); +	debug("trpab_lp=%d\n", trpab_lp); +	debug("trc_lp=%d\n", trc_lp); +	debug("tcke=%d\n", tcke); +	debug("tcksrx=%d\n", tcksrx); +	debug("tcksre=%d\n", tcksre); +	debug("trfc=%d\n", trfc); +	debug("txsr=%d\n", txsr); +	debug("txp=%d\n", txp); +	debug("tfaw=%d\n", tfaw); +	debug("tcl=%d\n", tcl); +	debug("tras=%d\n", tras); +	debug("twr=%d\n", twr); +	debug("tmrd=%d\n", tmrd); +	debug("twl=%d\n", twl); +	debug("trtp=%d\n", trtp); +	debug("twtr=%d\n", twtr); +	debug("trrd=%d\n", trrd); +	debug("cs0_end=%d\n", cs0_end); +	debug("ncs=%d\n", sysinfo->ncs); + +	/* +	 * board-specific configuration: +	 *  These values are determined empirically and vary per board layout +	 */ +	mmdc0->mpwldectrl0 = calib->p0_mpwldectrl0; +	mmdc0->mpwldectrl1 = calib->p0_mpwldectrl1; +	mmdc0->mpdgctrl0 = calib->p0_mpdgctrl0; +	mmdc0->mpdgctrl1 = calib->p0_mpdgctrl1; +	mmdc0->mprddlctl = calib->p0_mprddlctl; +	mmdc0->mpwrdlctl = calib->p0_mpwrdlctl; +	mmdc0->mpzqlp2ctl = calib->mpzqlp2ctl; + +	/* Read data DQ Byte0-3 delay */ +	mmdc0->mprddqby0dl = 0x33333333; +	mmdc0->mprddqby1dl = 0x33333333; +	if (sysinfo->dsize > 0) { +		mmdc0->mprddqby2dl = 0x33333333; +		mmdc0->mprddqby3dl = 0x33333333; +	} + +	/* Write data DQ Byte0-3 delay */ +	mmdc0->mpwrdqby0dl = 0xf3333333; +	mmdc0->mpwrdqby1dl = 0xf3333333; +	if (sysinfo->dsize > 0) { +		mmdc0->mpwrdqby2dl = 0xf3333333; +		mmdc0->mpwrdqby3dl = 0xf3333333; +	} + +	/* +	 * In LPDDR2 mode this register should be cleared, +	 * so no termination will be activated. +	 */ +	mmdc0->mpodtctrl = 0; + +	/* complete calibration */ +	val = (1 << 11); /* Force measurement on delay-lines */ +	mmdc0->mpmur0 = val; + +	/* Step 1: configuration request */ +	mmdc0->mdscr = (u32)(1 << 15); /* config request */ + +	/* Step 2: Timing configuration */ +	mmdc0->mdcfg0 = (trfc << 24) | (txsr << 16) | (txp << 13) | +			(tfaw << 4) | tcl; +	mmdc0->mdcfg1 = (tras << 16) | (twr << 9) | (tmrd << 5) | twl; +	mmdc0->mdcfg2 = (trtp << 6) | (twtr << 3) | trrd; +	mmdc0->mdcfg3lp = (trc_lp << 16) | (trcd_lp << 8) | +			  (trppb_lp << 4) | trpab_lp; +	mmdc0->mdotc = 0; + +	mmdc0->mdasp = cs0_end; /* CS addressing */ + +	/* Step 3: Configure DDR type */ +	mmdc0->mdmisc = (sysinfo->cs1_mirror << 19) | (sysinfo->walat << 16) | +			(sysinfo->bi_on << 12) | (sysinfo->mif3_mode << 9) | +			(sysinfo->ralat << 6) | (1 << 3); + +	/* Step 4: Configure delay while leaving reset */ +	mmdc0->mdor = (sysinfo->sde_to_rst << 8) | +		      (sysinfo->rst_to_cke << 0); + +	/* Step 5: Configure DDR physical parameters (density and burst len) */ +	coladdr = lpddr2_cfg->coladdr; +	if (lpddr2_cfg->coladdr == 8)		/* 8-bit COL is 0x3 */ +		coladdr += 4; +	else if (lpddr2_cfg->coladdr == 12)	/* 12-bit COL is 0x4 */ +		coladdr += 1; +	mmdc0->mdctl =  (lpddr2_cfg->rowaddr - 11) << 24 |	/* ROW */ +			(coladdr - 9) << 20 |			/* COL */ +			(0 << 19) |	/* Burst Length = 4 for LPDDR2 */ +			(sysinfo->dsize << 16);	/* DDR data bus size */ + +	/* Step 6: Perform ZQ calibration */ +	val = 0xa1390003; /* one-time HW ZQ calib */ +	mmdc0->mpzqhwctrl = val; + +	/* Step 7: Enable MMDC with desired chip select */ +	mmdc0->mdctl |= (1 << 31) |			     /* SDE_0 for CS0 */ +			((sysinfo->ncs == 2) ? 1 : 0) << 30; /* SDE_1 for CS1 */ + +	/* Step 8: Write Mode Registers to Init LPDDR2 devices */ +	for (cs = 0; cs < sysinfo->ncs; cs++) { +		/* MR63: reset */ +		mmdc0->mdscr = MR(63, 0, 3, cs); +		/* MR10: calibration, +		 * 0xff is calibration command after intilization. +		 */ +		val = 0xA | (0xff << 8); +		mmdc0->mdscr = MR(val, 0, 3, cs); +		/* MR1 */ +		val = 0x1 | (0x82 << 8); +		mmdc0->mdscr = MR(val, 0, 3, cs); +		/* MR2 */ +		val = 0x2 | (0x04 << 8); +		mmdc0->mdscr = MR(val, 0, 3, cs); +		/* MR3 */ +		val = 0x3 | (0x02 << 8); +		mmdc0->mdscr = MR(val, 0, 3, cs); +	} + +	/* Step 10: Power down control and self-refresh */ +	mmdc0->mdpdc = (tcke & 0x7) << 16 | +			5            << 12 |  /* PWDT_1: 256 cycles */ +			5            <<  8 |  /* PWDT_0: 256 cycles */ +			1            <<  6 |  /* BOTH_CS_PD */ +			(tcksrx & 0x7) << 3 | +			(tcksre & 0x7); +	mmdc0->mapsr = 0x00001006; /* ADOPT power down enabled */ + +	/* Step 11: Configure ZQ calibration: one-time and periodic 1ms */ +	val = 0xa1310003; +	mmdc0->mpzqhwctrl = val; + +	/* Step 12: Configure and activate periodic refresh */ +	mmdc0->mdref = (0 << 14) | /* REF_SEL: Periodic refresh cycle: 64kHz */ +		       (3 << 11);  /* REFR: Refresh Rate - 4 refreshes */ + +	/* Step 13: Deassert config request - init complete */ +	mmdc0->mdscr = 0x00000000; + +	/* wait for auto-ZQ calibration to complete */ +	mdelay(1); +} + +void mx6_ddr3_cfg(const struct mx6_ddr_sysinfo *sysinfo,  		  const struct mx6_mmdc_calibration *calib,  		  const struct mx6_ddr3_cfg *ddr3_cfg)  { @@ -312,7 +658,8 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,  	u16 mem_speed = ddr3_cfg->mem_speed;  	mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; -	if (!is_cpu_type(MXC_CPU_MX6SX) && !is_cpu_type(MXC_CPU_MX6UL)) +	if (!is_cpu_type(MXC_CPU_MX6SX) && !is_cpu_type(MXC_CPU_MX6UL) && +	    !is_cpu_type(MXC_CPU_MX6SL))  		mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;  	/* Limit mem_speed for MX6D/MX6Q */ @@ -355,8 +702,8 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,  		txs = DIV_ROUND_UP(170000, clkper) - 1;  		break;  	case 4: /* 4Gb per chip */ -		trfc = DIV_ROUND_UP(260000, clkper) - 1; -		txs = DIV_ROUND_UP(270000, clkper) - 1; +		trfc = DIV_ROUND_UP(300000, clkper) - 1; +		txs = DIV_ROUND_UP(310000, clkper) - 1;  		break;  	case 8: /* 8Gb per chip */  		trfc = DIV_ROUND_UP(350000, clkper) - 1; @@ -598,3 +945,17 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,  	/* wait for auto-ZQ calibration to complete */  	mdelay(1);  } + +void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, +		  const struct mx6_mmdc_calibration *calib, +		  const void *ddr_cfg) +{ +	if (sysinfo->ddr_type == DDR_TYPE_DDR3) { +		mx6_ddr3_cfg(sysinfo, calib, ddr_cfg); +	} else if (sysinfo->ddr_type == DDR_TYPE_LPDDR2) { +		mx6_lpddr2_cfg(sysinfo, calib, ddr_cfg); +	} else { +		puts("Unsupported ddr type\n"); +		hang(); +	} +} | 
