diff options
author | Tom Rini <trini@konsulko.com> | 2015-09-02 10:39:28 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2015-09-02 10:39:28 -0400 |
commit | 0ffadab1b9ab59816a0f71c927604bb6c402d863 (patch) | |
tree | 8338cea40ce53158387da4f708b09487cdebeaf9 /arch/arm/cpu | |
parent | 6923b069bd50b3ac519b16b6ae6aabbd2984c391 (diff) | |
parent | 37cf215253a488ba6b903989b1eff072f59d266e (diff) | |
download | u-boot-0ffadab1b9ab59816a0f71c927604bb6c402d863.tar.gz u-boot-0ffadab1b9ab59816a0f71c927604bb6c402d863.tar.xz u-boot-0ffadab1b9ab59816a0f71c927604bb6c402d863.zip |
Merge branch 'master' of git://www.denx.de/git/u-boot-imx
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r-- | arch/arm/cpu/arm1136/mx31/generic.c | 2 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx27/generic.c | 6 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/Makefile | 10 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/mxs.c | 52 | ||||
-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 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/vf610/generic.c | 6 |
8 files changed, 565 insertions, 51 deletions
diff --git a/arch/arm/cpu/arm1136/mx31/generic.c b/arch/arm/cpu/arm1136/mx31/generic.c index 060d46b82c..fe966702fa 100644 --- a/arch/arm/cpu/arm1136/mx31/generic.c +++ b/arch/arm/cpu/arm1136/mx31/generic.c @@ -175,7 +175,7 @@ u32 get_cpu_rev(void) for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) if (srev == mx31_cpu_type[i].srev) - return mx31_cpu_type[i].v; + return mx31_cpu_type[i].v | (MXC_CPU_MX31 << 12); return srev | 0x8000; } diff --git a/arch/arm/cpu/arm926ejs/mx27/generic.c b/arch/arm/cpu/arm926ejs/mx27/generic.c index 5ee9f07d87..b713c84519 100644 --- a/arch/arm/cpu/arm926ejs/mx27/generic.c +++ b/arch/arm/cpu/arm926ejs/mx27/generic.c @@ -12,6 +12,7 @@ #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> #include <asm/arch/gpio.h> +#include <asm/imx-common/sys_proto.h> #ifdef CONFIG_MXC_MMC #include <asm/arch/mxcmmc.h> #endif @@ -159,6 +160,11 @@ unsigned int mxc_get_clock(enum mxc_clock clk) } +u32 get_cpu_rev(void) +{ + return MXC_CPU_MX27 << 12; +} + #if defined(CONFIG_DISPLAY_CPUINFO) int print_cpuinfo (void) { diff --git a/arch/arm/cpu/arm926ejs/mxs/Makefile b/arch/arm/cpu/arm926ejs/mxs/Makefile index 6c59494558..71c2c0e7b4 100644 --- a/arch/arm/cpu/arm926ejs/mxs/Makefile +++ b/arch/arm/cpu/arm926ejs/mxs/Makefile @@ -74,12 +74,10 @@ u-boot.csf: u-boot.ivt u-boot.bin board/$(VENDOR)/$(BOARD)/sign/u-boot.csf %.sig: %.csf $(call if_changed,mkcst_mxs) -quiet_cmd_mkimage_mxs = MKIMAGE $@ -cmd_mkimage_mxs = $(objtree)/tools/mkimage -n $< -T mxsimage $@ \ - $(if $(KBUILD_VERBOSE:1=), >/dev/null) - +MKIMAGEFLAGS_u-boot.sb = -n $< -T mxsimage u-boot.sb: $(src)/$(MKIMAGE_TARGET-y) u-boot.bin spl/u-boot-spl.bin FORCE - $(call if_changed,mkimage_mxs) + $(call if_changed,mkimage) +MKIMAGEFLAGS_u-boot-signed.sb = -n $< -T mxsimage u-boot-signed.sb: $(src)/mxsimage-signed.cfg u-boot.ivt u-boot.sig spl/u-boot-spl.ivt spl/u-boot-spl.sig FORCE - $(call if_changed,mkimage_mxs) + $(call if_changed,mkimage) diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c index b1d8721213..a6af0fcb36 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxs.c +++ b/arch/arm/cpu/arm926ejs/mxs/mxs.c @@ -132,23 +132,7 @@ int arch_cpu_init(void) return 0; } -#if defined(CONFIG_DISPLAY_CPUINFO) -static const char *get_cpu_type(void) -{ - struct mxs_digctl_regs *digctl_regs = - (struct mxs_digctl_regs *)MXS_DIGCTL_BASE; - - switch (readl(&digctl_regs->hw_digctl_chipid) & HW_DIGCTL_CHIPID_MASK) { - case HW_DIGCTL_CHIPID_MX23: - return "23"; - case HW_DIGCTL_CHIPID_MX28: - return "28"; - default: - return "??"; - } -} - -static const char *get_cpu_rev(void) +u32 get_cpu_rev(void) { struct mxs_digctl_regs *digctl_regs = (struct mxs_digctl_regs *)MXS_DIGCTL_BASE; @@ -158,38 +142,50 @@ static const char *get_cpu_rev(void) case HW_DIGCTL_CHIPID_MX23: switch (rev) { case 0x0: - return "1.0"; case 0x1: - return "1.1"; case 0x2: - return "1.2"; case 0x3: - return "1.3"; case 0x4: - return "1.4"; + return (MXC_CPU_MX23 << 12) | (rev + 0x10); default: - return "??"; + return 0; } case HW_DIGCTL_CHIPID_MX28: switch (rev) { case 0x1: - return "1.2"; + return (MXC_CPU_MX28 << 12) | 0x12; default: - return "??"; + return 0; } default: + return 0; + } +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +const char *get_imx_type(u32 imxtype) +{ + switch (imxtype) { + case MXC_CPU_MX23: + return "23"; /* Quad-Plus version of the mx6 */ + case MXC_CPU_MX28: + return "28"; /* Dual-Plus version of the mx6 */ + default: return "??"; } } int print_cpuinfo(void) { + u32 cpurev; struct mxs_spl_data *data = (struct mxs_spl_data *) ((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf); - printf("CPU: Freescale i.MX%s rev%s at %d MHz\n", - get_cpu_type(), - get_cpu_rev(), + cpurev = get_cpu_rev(); + printf("CPU: Freescale i.MX%s rev%d.%d at %d MHz\n", + get_imx_type((cpurev & 0xFF000) >> 12), + (cpurev & 0x000F0) >> 4, + (cpurev & 0x0000F) >> 0, mxc_get_clock(MXC_ARM_CLK) / 1000000); printf("BOOT: %s\n", mxs_boot_modes[data->boot_mode_idx].mode); return 0; diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig index dce7ffc022..8b0120fea5 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 9cf4eece13..ba6cc75a7b 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 b808627a42..cf5587be54 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(); + } +} diff --git a/arch/arm/cpu/armv7/vf610/generic.c b/arch/arm/cpu/armv7/vf610/generic.c index 05c401dc73..08b9ef42a1 100644 --- a/arch/arm/cpu/armv7/vf610/generic.c +++ b/arch/arm/cpu/armv7/vf610/generic.c @@ -9,6 +9,7 @@ #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> #include <asm/arch/crm_regs.h> +#include <asm/imx-common/sys_proto.h> #include <netdev.h> #ifdef CONFIG_FSL_ESDHC #include <fsl_esdhc.h> @@ -266,6 +267,11 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) } #endif +u32 get_cpu_rev(void) +{ + return MXC_CPU_VF610 << 12; +} + #if defined(CONFIG_DISPLAY_CPUINFO) static char *get_reset_cause(void) { |