diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig | 4 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx6/clock.c | 107 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx6/ddr.c | 277 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx6/soc.c | 11 | ||||
-rw-r--r-- | arch/arm/dts/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/dts/imx6q-sabreauto.dts | 13 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx6/clock.h | 5 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx6/imx-regs.h | 13 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx6/iomux.h | 9 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx6/sys_proto.h | 5 | ||||
-rw-r--r-- | arch/arm/include/asm/imx-common/mxc_i2c.h | 33 |
11 files changed, 313 insertions, 165 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 22f0f09..f933123 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -424,6 +424,9 @@ config OMAP54XX config RMOBILE bool "Renesas ARM SoCs" +config TARGET_CM_FX6 + bool "Support cm_fx6" + config TARGET_S5P_GONI bool "Support s5p_goni" @@ -579,6 +582,7 @@ source "board/cirrus/edb93xx/Kconfig" source "board/cm4008/Kconfig" source "board/cm41xx/Kconfig" source "board/compulab/cm_t335/Kconfig" +source "board/compulab/cm_fx6/Kconfig" source "board/congatec/cgtqmx6eval/Kconfig" source "board/creative/xfi3/Kconfig" source "board/davedenx/qong/Kconfig" diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c index 820b8d5..336e557 100644 --- a/arch/arm/cpu/armv7/mx6/clock.c +++ b/arch/arm/cpu/armv7/mx6/clock.c @@ -36,6 +36,35 @@ void enable_ocotp_clk(unsigned char enable) } #endif +#ifdef CONFIG_NAND_MXS +void setup_gpmi_io_clk(u32 cfg) +{ + /* Disable clocks per ERR007177 from MX6 errata */ + clrbits_le32(&imx_ccm->CCGR4, + MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK | + MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK); + + clrbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); + + clrsetbits_le32(&imx_ccm->cs2cdr, + MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK | + MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK | + MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK, + cfg); + + setbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); + setbits_le32(&imx_ccm->CCGR4, + MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK | + MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK); +} +#endif + void enable_usboh3_clk(unsigned char enable) { u32 reg; @@ -49,6 +78,67 @@ void enable_usboh3_clk(unsigned char enable) } +#if defined(CONFIG_FEC_MXC) && !defined(CONFIG_MX6SX) +void enable_enet_clk(unsigned char enable) +{ + u32 mask = MXC_CCM_CCGR1_ENET_CLK_ENABLE_MASK; + + if (enable) + setbits_le32(&imx_ccm->CCGR1, mask); + else + clrbits_le32(&imx_ccm->CCGR1, mask); +} +#endif + +#ifdef CONFIG_MXC_UART +void enable_uart_clk(unsigned char enable) +{ + u32 mask = MXC_CCM_CCGR5_UART_MASK | MXC_CCM_CCGR5_UART_SERIAL_MASK; + + if (enable) + setbits_le32(&imx_ccm->CCGR5, mask); + else + clrbits_le32(&imx_ccm->CCGR5, mask); +} +#endif + +#ifdef CONFIG_SPI +/* spi_num can be from 0 - 4 */ +int enable_cspi_clock(unsigned char enable, unsigned spi_num) +{ + u32 mask; + + if (spi_num > 4) + return -EINVAL; + + mask = MXC_CCM_CCGR_CG_MASK << (spi_num * 2); + if (enable) + setbits_le32(&imx_ccm->CCGR1, mask); + else + clrbits_le32(&imx_ccm->CCGR1, mask); + + return 0; +} +#endif + +#ifdef CONFIG_MMC +int enable_usdhc_clk(unsigned char enable, unsigned bus_num) +{ + u32 mask; + + if (bus_num > 3) + return -EINVAL; + + mask = MXC_CCM_CCGR_CG_MASK << (bus_num * 2 + 2); + if (enable) + setbits_le32(&imx_ccm->CCGR6, mask); + else + clrbits_le32(&imx_ccm->CCGR6, mask); + + return 0; +} +#endif + #ifdef CONFIG_SYS_I2C_MXC /* i2c_num can be from 0 - 2 */ int enable_i2c_clk(unsigned char enable, unsigned i2c_num) @@ -509,6 +599,7 @@ int enable_pcie_clock(void) struct anatop_regs *anatop_regs = (struct anatop_regs *)ANATOP_BASE_ADDR; struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + u32 lvds1_clk_sel; /* * Here be dragons! @@ -518,17 +609,25 @@ int enable_pcie_clock(void) * marked as ANATOP_MISC1 is actually documented in the PMU section * of the datasheet as PMU_MISC1. * - * Switch LVDS clock source to SATA (0xb), disable clock INPUT and - * enable clock OUTPUT. This is important for PCI express link that - * is clocked from the i.MX6. + * Switch LVDS clock source to SATA (0xb) on mx6q/dl or PCI (0xa) on + * mx6sx, disable clock INPUT and enable clock OUTPUT. This is important + * for PCI express link that is clocked from the i.MX6. */ #define ANADIG_ANA_MISC1_LVDSCLK1_IBEN (1 << 12) #define ANADIG_ANA_MISC1_LVDSCLK1_OBEN (1 << 10) #define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK 0x0000001F +#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF 0xa +#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF 0xb + + if (is_cpu_type(MXC_CPU_MX6SX)) + lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF; + else + lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF; + clrsetbits_le32(&anatop_regs->ana_misc1, ANADIG_ANA_MISC1_LVDSCLK1_IBEN | ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK, - ANADIG_ANA_MISC1_LVDSCLK1_OBEN | 0xb); + ANADIG_ANA_MISC1_LVDSCLK1_OBEN | lvds1_clk_sel); /* PCIe reference clock sourced from AXI. */ clrbits_le32(&ccm_regs->cbcmr, MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL); diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c index 1ab69f6..7b5c1e4 100644 --- a/arch/arm/cpu/armv7/mx6/ddr.c +++ b/arch/arm/cpu/armv7/mx6/ddr.c @@ -184,18 +184,18 @@ void mx6sdl_dram_iocfg(unsigned width, */ #define MR(val, ba, cmd, cs1) \ ((val << 16) | (1 << 15) | (cmd << 4) | (cs1 << 3) | ba) -void mx6_dram_cfg(const struct mx6_ddr_sysinfo *i, - const struct mx6_mmdc_calibration *c, - const struct mx6_ddr3_cfg *m) +void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, + const struct mx6_mmdc_calibration *calib, + const struct mx6_ddr3_cfg *ddr3_cfg) { volatile struct mmdc_p_regs *mmdc0; volatile struct mmdc_p_regs *mmdc1; - u32 reg; + u32 val; u8 tcke, tcksrx, tcksre, txpdll, taofpd, taonpd, trrd; u8 todtlon, taxpd, tanpd, tcwl, txp, tfaw, tcl; u8 todt_idle_off = 0x4; /* from DDR3 Script Aid spreadsheet */ u16 trcd, trc, tras, twr, tmrd, trtp, trp, twtr, trfc, txs, txpr; - u16 CS0_END; + u16 cs0_end; u16 tdllk = 0x1ff; /* DLL locking time: 512 cycles (JEDEC DDR3) */ u8 coladdr; int clkper; /* clock period in picoseconds */ @@ -215,13 +215,12 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *i, clock = 400; tcwl = 3; } - clkper = (1000*1000)/clock; /* ps */ + clkper = (1000 * 1000) / clock; /* pico seconds */ todtlon = tcwl; taxpd = tcwl; tanpd = tcwl; - tcwl = tcwl; - switch (m->density) { + switch (ddr3_cfg->density) { case 1: /* 1Gb per chip */ trfc = DIV_ROUND_UP(110000, clkper) - 1; txs = DIV_ROUND_UP(120000, clkper) - 1; @@ -240,80 +239,82 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *i, break; default: /* invalid density */ - printf("invalid chip density\n"); + puts("invalid chip density\n"); hang(); break; } txpr = txs; - switch (m->mem_speed) { + switch (ddr3_cfg->mem_speed) { case 800: - txp = DIV_ROUND_UP(MAX(3*clkper, 7500), clkper) - 1; - tcke = DIV_ROUND_UP(MAX(3*clkper, 7500), clkper) - 1; - if (m->pagesz == 1) { + txp = DIV_ROUND_UP(MAX(3 * clkper, 7500), clkper) - 1; + tcke = DIV_ROUND_UP(MAX(3 * clkper, 7500), clkper) - 1; + if (ddr3_cfg->pagesz == 1) { tfaw = DIV_ROUND_UP(40000, clkper) - 1; - trrd = DIV_ROUND_UP(MAX(4*clkper, 10000), clkper) - 1; + trrd = DIV_ROUND_UP(MAX(4 * clkper, 10000), clkper) - 1; } else { tfaw = DIV_ROUND_UP(50000, clkper) - 1; - trrd = DIV_ROUND_UP(MAX(4*clkper, 10000), clkper) - 1; + trrd = DIV_ROUND_UP(MAX(4 * clkper, 10000), clkper) - 1; } break; case 1066: - txp = DIV_ROUND_UP(MAX(3*clkper, 7500), clkper) - 1; - tcke = DIV_ROUND_UP(MAX(3*clkper, 5625), clkper) - 1; - if (m->pagesz == 1) { + txp = DIV_ROUND_UP(MAX(3 * clkper, 7500), clkper) - 1; + tcke = DIV_ROUND_UP(MAX(3 * clkper, 5625), clkper) - 1; + if (ddr3_cfg->pagesz == 1) { tfaw = DIV_ROUND_UP(37500, clkper) - 1; - trrd = DIV_ROUND_UP(MAX(4*clkper, 7500), clkper) - 1; + trrd = DIV_ROUND_UP(MAX(4 * clkper, 7500), clkper) - 1; } else { tfaw = DIV_ROUND_UP(50000, clkper) - 1; - trrd = DIV_ROUND_UP(MAX(4*clkper, 10000), clkper) - 1; + trrd = DIV_ROUND_UP(MAX(4 * clkper, 10000), clkper) - 1; } break; case 1333: - txp = DIV_ROUND_UP(MAX(3*clkper, 6000), clkper) - 1; - tcke = DIV_ROUND_UP(MAX(3*clkper, 5625), clkper) - 1; - if (m->pagesz == 1) { + txp = DIV_ROUND_UP(MAX(3 * clkper, 6000), clkper) - 1; + tcke = DIV_ROUND_UP(MAX(3 * clkper, 5625), clkper) - 1; + if (ddr3_cfg->pagesz == 1) { tfaw = DIV_ROUND_UP(30000, clkper) - 1; - trrd = DIV_ROUND_UP(MAX(4*clkper, 6000), clkper) - 1; + trrd = DIV_ROUND_UP(MAX(4 * clkper, 6000), clkper) - 1; } else { tfaw = DIV_ROUND_UP(45000, clkper) - 1; - trrd = DIV_ROUND_UP(MAX(4*clkper, 7500), clkper) - 1; + trrd = DIV_ROUND_UP(MAX(4 * clkper, 7500), clkper) - 1; } break; case 1600: - txp = DIV_ROUND_UP(MAX(3*clkper, 6000), clkper) - 1; - tcke = DIV_ROUND_UP(MAX(3*clkper, 5000), clkper) - 1; - if (m->pagesz == 1) { + txp = DIV_ROUND_UP(MAX(3 * clkper, 6000), clkper) - 1; + tcke = DIV_ROUND_UP(MAX(3 * clkper, 5000), clkper) - 1; + if (ddr3_cfg->pagesz == 1) { tfaw = DIV_ROUND_UP(30000, clkper) - 1; - trrd = DIV_ROUND_UP(MAX(4*clkper, 6000), clkper) - 1; + trrd = DIV_ROUND_UP(MAX(4 * clkper, 6000), clkper) - 1; } else { tfaw = DIV_ROUND_UP(40000, clkper) - 1; - trrd = DIV_ROUND_UP(MAX(4*clkper, 7500), clkper) - 1; + trrd = DIV_ROUND_UP(MAX(4 * clkper, 7500), clkper) - 1; } break; default: - printf("invalid memory speed\n"); + puts("invalid memory speed\n"); hang(); break; } - txpdll = DIV_ROUND_UP(MAX(10*clkper, 24000), clkper) - 1; - tcl = DIV_ROUND_UP(m->trcd, clkper/10) - 3; - tcksre = DIV_ROUND_UP(MAX(5*clkper, 10000), clkper); - tcksrx = tcksre; + txpdll = DIV_ROUND_UP(MAX(10 * clkper, 24000), clkper) - 1; + tcksre = DIV_ROUND_UP(MAX(5 * clkper, 10000), clkper); taonpd = DIV_ROUND_UP(2000, clkper) - 1; + tcksrx = tcksre; taofpd = taonpd; - trp = DIV_ROUND_UP(m->trcd, clkper/10) - 1; + twr = DIV_ROUND_UP(15000, clkper) - 1; + tmrd = DIV_ROUND_UP(MAX(12 * clkper, 15000), clkper) - 1; + trc = DIV_ROUND_UP(ddr3_cfg->trcmin, clkper / 10) - 1; + tras = DIV_ROUND_UP(ddr3_cfg->trasmin, clkper / 10) - 1; + tcl = DIV_ROUND_UP(ddr3_cfg->trcd, clkper / 10) - 3; + trp = DIV_ROUND_UP(ddr3_cfg->trcd, clkper / 10) - 1; + twtr = ROUND(MAX(4 * clkper, 7500) / clkper, 1) - 1; trcd = trp; - trc = DIV_ROUND_UP(m->trcmin, clkper/10) - 1; - tras = DIV_ROUND_UP(m->trasmin, clkper/10) - 1; - twr = DIV_ROUND_UP(15000, clkper) - 1; - tmrd = DIV_ROUND_UP(MAX(12*clkper, 15000), clkper) - 1; - twtr = ROUND(MAX(4*clkper, 7500)/clkper, 1) - 1; trtp = twtr; - CS0_END = ((4*i->cs_density) <= 120) ? (4*i->cs_density)+7 : 127; - debug("density:%d Gb (%d Gb per chip)\n", i->cs_density, m->density); + cs0_end = 4 * sysinfo->cs_density - 1; + + debug("density:%d Gb (%d Gb per chip)\n", + sysinfo->cs_density, ddr3_cfg->density); debug("clock: %dMHz (%d ps)\n", clock, clkper); - debug("memspd:%d\n", m->mem_speed); + debug("memspd:%d\n", ddr3_cfg->mem_speed); debug("tcke=%d\n", tcke); debug("tcksrx=%d\n", tcksrx); debug("tcksre=%d\n", tcksre); @@ -340,11 +341,11 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *i, debug("twtr=%d\n", twtr); debug("trrd=%d\n", trrd); debug("txpr=%d\n", txpr); - debug("CS0_END=%d\n", CS0_END); - debug("ncs=%d\n", i->ncs); - debug("Rtt_wr=%d\n", i->rtt_wr); - debug("Rtt_nom=%d\n", i->rtt_nom); - debug("SRT=%d\n", m->SRT); + debug("cs0_end=%d\n", cs0_end); + debug("ncs=%d\n", sysinfo->ncs); + debug("Rtt_wr=%d\n", sysinfo->rtt_wr); + debug("Rtt_nom=%d\n", sysinfo->rtt_nom); + debug("SRT=%d\n", ddr3_cfg->SRT); debug("tcl=%d\n", tcl); debug("twr=%d\n", twr); @@ -354,142 +355,136 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *i, * see: * appnote, ddr3 spreadsheet */ - mmdc0->mpwldectrl0 = c->p0_mpwldectrl0; - mmdc0->mpwldectrl1 = c->p0_mpwldectrl1; - mmdc0->mpdgctrl0 = c->p0_mpdgctrl0; - mmdc0->mpdgctrl1 = c->p0_mpdgctrl1; - mmdc0->mprddlctl = c->p0_mprddlctl; - mmdc0->mpwrdlctl = c->p0_mpwrdlctl; - if (i->dsize > 1) { - mmdc1->mpwldectrl0 = c->p1_mpwldectrl0; - mmdc1->mpwldectrl1 = c->p1_mpwldectrl1; - mmdc1->mpdgctrl0 = c->p1_mpdgctrl0; - mmdc1->mpdgctrl1 = c->p1_mpdgctrl1; - mmdc1->mprddlctl = c->p1_mprddlctl; - mmdc1->mpwrdlctl = c->p1_mpwrdlctl; + 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; + if (sysinfo->dsize > 1) { + mmdc1->mpwldectrl0 = calib->p1_mpwldectrl0; + mmdc1->mpwldectrl1 = calib->p1_mpwldectrl1; + mmdc1->mpdgctrl0 = calib->p1_mpdgctrl0; + mmdc1->mpdgctrl1 = calib->p1_mpdgctrl1; + mmdc1->mprddlctl = calib->p1_mprddlctl; + mmdc1->mpwrdlctl = calib->p1_mpwrdlctl; } /* Read data DQ Byte0-3 delay */ - mmdc0->mprddqby0dl = (u32)0x33333333; - mmdc0->mprddqby1dl = (u32)0x33333333; - if (i->dsize > 0) { - mmdc0->mprddqby2dl = (u32)0x33333333; - mmdc0->mprddqby3dl = (u32)0x33333333; + mmdc0->mprddqby0dl = 0x33333333; + mmdc0->mprddqby1dl = 0x33333333; + if (sysinfo->dsize > 0) { + mmdc0->mprddqby2dl = 0x33333333; + mmdc0->mprddqby3dl = 0x33333333; } - if (i->dsize > 1) { - mmdc1->mprddqby0dl = (u32)0x33333333; - mmdc1->mprddqby1dl = (u32)0x33333333; - mmdc1->mprddqby2dl = (u32)0x33333333; - mmdc1->mprddqby3dl = (u32)0x33333333; + + if (sysinfo->dsize > 1) { + mmdc1->mprddqby0dl = 0x33333333; + mmdc1->mprddqby1dl = 0x33333333; + mmdc1->mprddqby2dl = 0x33333333; + mmdc1->mprddqby3dl = 0x33333333; } /* MMDC Termination: rtt_nom:2 RZQ/2(120ohm), rtt_nom:1 RZQ/4(60ohm) */ - reg = (i->rtt_nom == 2) ? 0x00011117 : 0x00022227; - mmdc0->mpodtctrl = reg; - if (i->dsize > 1) - mmdc1->mpodtctrl = reg; + val = (sysinfo->rtt_nom == 2) ? 0x00011117 : 0x00022227; + mmdc0->mpodtctrl = val; + if (sysinfo->dsize > 1) + mmdc1->mpodtctrl = val; /* complete calibration */ - reg = (1 << 11); /* Force measurement on delay-lines */ - mmdc0->mpmur0 = reg; - if (i->dsize > 1) - mmdc1->mpmur0 = reg; + val = (1 << 11); /* Force measurement on delay-lines */ + mmdc0->mpmur0 = val; + if (sysinfo->dsize > 1) + mmdc1->mpmur0 = val; /* Step 1: configuration request */ mmdc0->mdscr = (u32)(1 << 15); /* config request */ /* Step 2: Timing configuration */ - reg = (trfc << 24) | (txs << 16) | (txp << 13) | (txpdll << 9) | - (tfaw << 4) | tcl; - mmdc0->mdcfg0 = reg; - reg = (trcd << 29) | (trp << 26) | (trc << 21) | (tras << 16) | - (1 << 15) | /* trpa */ - (twr << 9) | (tmrd << 5) | tcwl; - mmdc0->mdcfg1 = reg; - reg = (tdllk << 16) | (trtp << 6) | (twtr << 3) | trrd; - mmdc0->mdcfg2 = reg; - reg = (taofpd << 27) | (taonpd << 24) | (tanpd << 20) | (taxpd << 16) | - (todtlon << 12) | (todt_idle_off << 4); - mmdc0->mdotc = reg; - mmdc0->mdasp = CS0_END; /* CS addressing */ + mmdc0->mdcfg0 = (trfc << 24) | (txs << 16) | (txp << 13) | + (txpdll << 9) | (tfaw << 4) | tcl; + mmdc0->mdcfg1 = (trcd << 29) | (trp << 26) | (trc << 21) | + (tras << 16) | (1 << 15) /* trpa */ | + (twr << 9) | (tmrd << 5) | tcwl; + mmdc0->mdcfg2 = (tdllk << 16) | (trtp << 6) | (twtr << 3) | trrd; + mmdc0->mdotc = (taofpd << 27) | (taonpd << 24) | (tanpd << 20) | + (taxpd << 16) | (todtlon << 12) | (todt_idle_off << 4); + mmdc0->mdasp = cs0_end; /* CS addressing */ /* Step 3: Configure DDR type */ - reg = (i->cs1_mirror << 19) | (i->walat << 16) | (i->bi_on << 12) | - (i->mif3_mode << 9) | (i->ralat << 6); - mmdc0->mdmisc = reg; + mmdc0->mdmisc = (sysinfo->cs1_mirror << 19) | (sysinfo->walat << 16) | + (sysinfo->bi_on << 12) | (sysinfo->mif3_mode << 9) | + (sysinfo->ralat << 6); /* Step 4: Configure delay while leaving reset */ - reg = (txpr << 16) | (i->sde_to_rst << 8) | (i->rst_to_cke << 0); - mmdc0->mdor = reg; + mmdc0->mdor = (txpr << 16) | (sysinfo->sde_to_rst << 8) | + (sysinfo->rst_to_cke << 0); /* Step 5: Configure DDR physical parameters (density and burst len) */ - coladdr = m->coladdr; - if (m->coladdr == 8) /* 8-bit COL is 0x3 */ + coladdr = ddr3_cfg->coladdr; + if (ddr3_cfg->coladdr == 8) /* 8-bit COL is 0x3 */ coladdr += 4; - else if (m->coladdr == 12) /* 12-bit COL is 0x4 */ + else if (ddr3_cfg->coladdr == 12) /* 12-bit COL is 0x4 */ coladdr += 1; - reg = (m->rowaddr - 11) << 24 | /* ROW */ - (coladdr - 9) << 20 | /* COL */ - (1 << 19) | /* Burst Length = 8 for DDR3 */ - (i->dsize << 16); /* DDR data bus size */ - mmdc0->mdctl = reg; + mmdc0->mdctl = (ddr3_cfg->rowaddr - 11) << 24 | /* ROW */ + (coladdr - 9) << 20 | /* COL */ + (1 << 19) | /* Burst Length = 8 for DDR3 */ + (sysinfo->dsize << 16); /* DDR data bus size */ /* Step 6: Perform ZQ calibration */ - reg = (u32)0xa1390001; /* one-time HW ZQ calib */ - mmdc0->mpzqhwctrl = reg; - if (i->dsize > 1) - mmdc1->mpzqhwctrl = reg; + val = 0xa1390001; /* one-time HW ZQ calib */ + mmdc0->mpzqhwctrl = val; + if (sysinfo->dsize > 1) + mmdc1->mpzqhwctrl = val; /* Step 7: Enable MMDC with desired chip select */ - reg = mmdc0->mdctl | - (1 << 31) | /* SDE_0 for CS0 */ - ((i->ncs == 2) ? 1 : 0) << 30; /* SDE_1 for CS1 */ - mmdc0->mdctl = reg; + 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 DDR3 devices */ - for (cs = 0; cs < i->ncs; cs++) { + for (cs = 0; cs < sysinfo->ncs; cs++) { /* MR2 */ - reg = (i->rtt_wr & 3) << 9 | (m->SRT & 1) << 7 | + val = (sysinfo->rtt_wr & 3) << 9 | (ddr3_cfg->SRT & 1) << 7 | ((tcwl - 3) & 3) << 3; - mmdc0->mdscr = (u32)MR(reg, 2, 3, cs); + mmdc0->mdscr = MR(val, 2, 3, cs); /* MR3 */ - mmdc0->mdscr = (u32)MR(0, 3, 3, cs); + mmdc0->mdscr = MR(0, 3, 3, cs); /* MR1 */ - reg = ((i->rtt_nom & 1) ? 1 : 0) << 2 | - ((i->rtt_nom & 2) ? 1 : 0) << 6; - mmdc0->mdscr = (u32)MR(reg, 1, 3, cs); - reg = ((tcl - 1) << 4) | /* CAS */ + val = ((sysinfo->rtt_nom & 1) ? 1 : 0) << 2 | + ((sysinfo->rtt_nom & 2) ? 1 : 0) << 6; + mmdc0->mdscr = MR(val, 1, 3, cs); + /* MR0 */ + val = ((tcl - 1) << 4) | /* CAS */ (1 << 8) | /* DLL Reset */ ((twr - 3) << 9); /* Write Recovery */ - /* MR0 */ - mmdc0->mdscr = (u32)MR(reg, 0, 3, cs); + mmdc0->mdscr = MR(val, 0, 3, cs); /* ZQ calibration */ - reg = (1 << 10); - mmdc0->mdscr = (u32)MR(reg, 0, 4, cs); + val = (1 << 10); + mmdc0->mdscr = MR(val, 0, 4, cs); } /* Step 10: Power down control and self-refresh */ - reg = (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->mdpdc = reg; - mmdc0->mapsr = (u32)0x00011006; /* ADOPT power down enabled */ + mmdc0->mdpdc = (tcke & 0x7) << 16 | + 5 << 12 | /* PWDT_1: 256 cycles */ + 5 << 8 | /* PWDT_0: 256 cycles */ + 1 << 7 | /* SLOW_PD */ + 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 */ - mmdc0->mpzqhwctrl = (u32)0xa1390003; - if (i->dsize > 1) - mmdc1->mpzqhwctrl = (u32)0xa1390003; + val = 0xa1390003; + mmdc0->mpzqhwctrl = val; + if (sysinfo->dsize > 1) + mmdc1->mpzqhwctrl = val; /* Step 12: Configure and activate periodic refresh */ - reg = (1 << 14) | /* REF_SEL: Periodic refresh cycles of 32kHz */ - (7 << 11); /* REFR: Refresh Rate - 8 refreshes */ - mmdc0->mdref = reg; + mmdc0->mdref = (1 << 14) | /* REF_SEL: Periodic refresh cycle: 32kHz */ + (7 << 11); /* REFR: Refresh Rate - 8 refreshes */ /* Step 13: Deassert config request - init complete */ - mmdc0->mdscr = (u32)0x00000000; + mmdc0->mdscr = 0x00000000; /* wait for auto-ZQ calibration to complete */ mdelay(1); diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index ac84a1f..ba21cfe 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -324,10 +324,10 @@ const struct boot_mode soc_boot_modes[] = { /* reserved value should start rom usb */ {"usb", MAKE_CFGVAL(0x01, 0x00, 0x00, 0x00)}, {"sata", MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)}, - {"escpi1:0", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)}, - {"escpi1:1", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)}, - {"escpi1:2", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)}, - {"escpi1:3", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)}, + {"ecspi1:0", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)}, + {"ecspi1:1", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)}, + {"ecspi1:2", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)}, + {"ecspi1:3", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)}, /* 4 bit bus width */ {"esdhc1", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)}, {"esdhc2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)}, @@ -430,6 +430,9 @@ void v7_outer_cache_enable(void) } #endif + /* Must disable the L2 before changing the latency parameters */ + clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); + writel(0x132, &pl310->pl310_tag_latency_ctrl); writel(0x132, &pl310->pl310_data_latency_ctrl); diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 1ccd827..5f2b946 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -9,7 +9,6 @@ dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \ exynos5250-smdk5250.dtb \ exynos5420-smdk5420.dtb \ exynos5420-peach-pit.dtb -dtb-$(CONFIG_MX6) += imx6q-sabreauto.dtb dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \ tegra20-medcom-wide.dtb \ tegra20-paz00.dtb \ diff --git a/arch/arm/dts/imx6q-sabreauto.dts b/arch/arm/dts/imx6q-sabreauto.dts deleted file mode 100644 index 7af2a88..0000000 --- a/arch/arm/dts/imx6q-sabreauto.dts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * Copyright 2011 Linaro Ltd. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/dts-v1/; - -/ { - model = "Freescale i.MX6 Quad SABRE Automotive Board"; - compatible = "fsl,imx6q-sabreauto", "fsl,imx6q"; -}; diff --git a/arch/arm/include/asm/arch-mx6/clock.h b/arch/arm/include/asm/arch-mx6/clock.h index 339c789..c11674f 100644 --- a/arch/arm/include/asm/arch-mx6/clock.h +++ b/arch/arm/include/asm/arch-mx6/clock.h @@ -52,12 +52,17 @@ enum enet_freq { u32 imx_get_uartclk(void); u32 imx_get_fecclk(void); unsigned int mxc_get_clock(enum mxc_clock clk); +void setup_gpmi_io_clk(u32 cfg); void enable_ocotp_clk(unsigned char enable); void enable_usboh3_clk(unsigned char enable); +void enable_uart_clk(unsigned char enable); +int enable_cspi_clock(unsigned char enable, unsigned spi_num); +int enable_usdhc_clk(unsigned char enable, unsigned bus_num); int enable_sata_clock(void); int enable_pcie_clock(void); int enable_i2c_clk(unsigned char enable, unsigned i2c_num); int enable_spi_clk(unsigned char enable, unsigned spi_num); void enable_ipu_clock(void); int enable_fec_anatop_clock(enum enet_freq freq); +void enable_enet_clk(unsigned char enable); #endif /* __ASM_ARCH_CLOCK_H */ diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 2631beb..22614fc 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -419,6 +419,19 @@ struct iomuxc { u32 gpr[14]; }; +struct gpc { + u32 cntr; + u32 pgr; + u32 imr1; + u32 imr2; + u32 imr3; + u32 imr4; + u32 isr1; + u32 isr2; + u32 isr3; + u32 isr4; +}; + #define IOMUXC_GPR2_COUNTER_RESET_VAL_OFFSET 20 #define IOMUXC_GPR2_COUNTER_RESET_VAL_MASK (3<<IOMUXC_GPR2_COUNTER_RESET_VAL_OFFSET) #define IOMUXC_GPR2_LVDS_CLK_SHIFT_OFFSET 16 diff --git a/arch/arm/include/asm/arch-mx6/iomux.h b/arch/arm/include/asm/arch-mx6/iomux.h index f54db69..9b3a91f 100644 --- a/arch/arm/include/asm/arch-mx6/iomux.h +++ b/arch/arm/include/asm/arch-mx6/iomux.h @@ -19,6 +19,12 @@ #define IOMUXC_GPR1_TEST_POWERDOWN (1 << 18) /* + * IOMUXC_GPR5 bit fields + */ +#define IOMUXC_GPR5_PCIE_BTNRST (1 << 19) +#define IOMUXC_GPR5_PCIE_PERST (1 << 18) + +/* * IOMUXC_GPR8 bit fields */ #define IOMUXC_GPR8_PCS_TX_DEEMPH_GEN1_MASK (0x3f << 0) @@ -35,12 +41,15 @@ /* * IOMUXC_GPR12 bit fields */ +#define IOMUXC_GPR12_RX_EQ_2 (0x2 << 0) +#define IOMUXC_GPR12_RX_EQ_MASK (0x7 << 0) #define IOMUXC_GPR12_LOS_LEVEL_9 (0x9 << 4) #define IOMUXC_GPR12_LOS_LEVEL_MASK (0x1f << 4) #define IOMUXC_GPR12_APPS_LTSSM_ENABLE (1 << 10) #define IOMUXC_GPR12_DEVICE_TYPE_EP (0x0 << 12) #define IOMUXC_GPR12_DEVICE_TYPE_RC (0x4 << 12) #define IOMUXC_GPR12_DEVICE_TYPE_MASK (0xf << 12) +#define IOMUXC_GPR12_TEST_POWERDOWN (1 << 30) /* * IOMUXC_GPR13 bit fields diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index 306d699..c35a9051 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -20,8 +20,9 @@ u32 get_cpu_rev(void); /* returns MXC_CPU_ value */ #define cpu_type(rev) (((rev) >> 12)&0xff) -/* use with MXC_CPU_ constants */ -#define is_cpu_type(cpu) (cpu_type(get_cpu_rev()) == cpu) +/* both macros return/take MXC_CPU_ constants */ +#define get_cpu_type() (cpu_type(get_cpu_rev())) +#define is_cpu_type(cpu) (get_cpu_type() == cpu) const char *get_imx_type(u32 imxtype); unsigned imx_ddr_size(void); diff --git a/arch/arm/include/asm/imx-common/mxc_i2c.h b/arch/arm/include/asm/imx-common/mxc_i2c.h index 47a9edc..182c2f3 100644 --- a/arch/arm/include/asm/imx-common/mxc_i2c.h +++ b/arch/arm/include/asm/imx-common/mxc_i2c.h @@ -19,6 +19,39 @@ struct i2c_pads_info { struct i2c_pin_ctrl sda; }; +#if defined(CONFIG_MX6QDL) +#define I2C_PADS(name, scl_i2c, scl_gpio, scl_gp, sda_i2c, sda_gpio, sda_gp) \ + struct i2c_pads_info mx6q_##name = { \ + .scl = { \ + .i2c_mode = MX6Q_##scl_i2c, \ + .gpio_mode = MX6Q_##scl_gpio, \ + .gp = scl_gp, \ + }, \ + .sda = { \ + .i2c_mode = MX6Q_##sda_i2c, \ + .gpio_mode = MX6Q_##sda_gpio, \ + .gp = sda_gp, \ + } \ + }; \ + struct i2c_pads_info mx6s_##name = { \ + .scl = { \ + .i2c_mode = MX6DL_##scl_i2c, \ + .gpio_mode = MX6DL_##scl_gpio, \ + .gp = scl_gp, \ + }, \ + .sda = { \ + .i2c_mode = MX6DL_##sda_i2c, \ + .gpio_mode = MX6DL_##sda_gpio, \ + .gp = sda_gp, \ + } \ + }; + + +#define I2C_PADS_INFO(name) \ + (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) ? \ + &mx6q_##name : &mx6s_##name +#endif + void setup_i2c(unsigned i2c_index, int speed, int slave_addr, struct i2c_pads_info *p); void bus_i2c_init(void *base, int speed, int slave_addr, |