summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/cpu.c4
-rw-r--r--arch/arm/mach-imx/mx6/Kconfig10
-rw-r--r--arch/arm/mach-imx/mx6/clock.c30
-rw-r--r--arch/arm/mach-imx/mx6/soc.c1
-rw-r--r--arch/arm/mach-imx/mx7/Kconfig8
-rw-r--r--arch/arm/mach-imx/mx7/Makefile2
-rw-r--r--arch/arm/mach-imx/mx7/ddr.c201
-rw-r--r--arch/arm/mach-imx/spl.c25
8 files changed, 262 insertions, 19 deletions
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c
index 1017eb84f9..18205dc984 100644
--- a/arch/arm/mach-imx/cpu.c
+++ b/arch/arm/mach-imx/cpu.c
@@ -25,7 +25,7 @@
#include <fsl_esdhc.h>
#endif
-#if defined(CONFIG_DISPLAY_CPUINFO)
+#if defined(CONFIG_DISPLAY_CPUINFO) && !defined(CONFIG_SPL_BUILD)
static u32 reset_cause = -1;
static char *get_reset_cause(void)
@@ -132,7 +132,7 @@ unsigned imx_ddr_size(void)
}
#endif
-#if defined(CONFIG_DISPLAY_CPUINFO)
+#if defined(CONFIG_DISPLAY_CPUINFO) && !defined(CONFIG_SPL_BUILD)
const char *get_imx_type(u32 imxtype)
{
diff --git a/arch/arm/mach-imx/mx6/Kconfig b/arch/arm/mach-imx/mx6/Kconfig
index 540f2b29b1..b82db3af22 100644
--- a/arch/arm/mach-imx/mx6/Kconfig
+++ b/arch/arm/mach-imx/mx6/Kconfig
@@ -129,6 +129,15 @@ config TARGET_COLIBRI_IMX6
select DM_SERIAL
select DM_THERMAL
+config TARGET_DHCOMIMX6
+ bool "dh_imx6"
+ select BOARD_LATE_INIT
+ select BOARD_EARLY_INIT_F
+ select SUPPORT_SPL
+ select DM
+ select DM_THERMAL
+ imply CMD_SPL
+
config TARGET_EMBESTMX6BOARDS
bool "embestmx6boards"
select BOARD_LATE_INIT
@@ -428,6 +437,7 @@ source "board/boundary/nitrogen6x/Kconfig"
source "board/ccv/xpress/Kconfig"
source "board/compulab/cm_fx6/Kconfig"
source "board/congatec/cgtqmx6eval/Kconfig"
+source "board/dhelectronics/dh_imx6/Kconfig"
source "board/el/el6x/Kconfig"
source "board/embest/mx6boards/Kconfig"
source "board/engicam/geam6ul/Kconfig"
diff --git a/arch/arm/mach-imx/mx6/clock.c b/arch/arm/mach-imx/mx6/clock.c
index 0e019c4262..71a9e6bca0 100644
--- a/arch/arm/mach-imx/mx6/clock.c
+++ b/arch/arm/mach-imx/mx6/clock.c
@@ -1220,6 +1220,20 @@ void enable_thermal_clk(void)
enable_pll3();
}
+#ifdef CONFIG_MTD_NOR_FLASH
+void enable_eim_clk(unsigned char enable)
+{
+ u32 reg;
+
+ reg = __raw_readl(&imx_ccm->CCGR6);
+ if (enable)
+ reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
+ else
+ reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK;
+ __raw_writel(reg, &imx_ccm->CCGR6);
+}
+#endif
+
unsigned int mxc_get_clock(enum mxc_clock clk)
{
switch (clk) {
@@ -1262,6 +1276,7 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
return 0;
}
+#ifndef CONFIG_SPL_BUILD
/*
* Dump some core clockes.
*/
@@ -1463,20 +1478,6 @@ void select_ldb_di_clock_source(enum ldb_di_clock clk)
}
#endif
-#ifdef CONFIG_MTD_NOR_FLASH
-void enable_eim_clk(unsigned char enable)
-{
- u32 reg;
-
- reg = __raw_readl(&imx_ccm->CCGR6);
- if (enable)
- reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
- else
- reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK;
- __raw_writel(reg, &imx_ccm->CCGR6);
-}
-#endif
-
/***************************************************/
U_BOOT_CMD(
@@ -1484,3 +1485,4 @@ U_BOOT_CMD(
"display clocks",
""
);
+#endif
diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c
index b72466808c..ad72c12511 100644
--- a/arch/arm/mach-imx/mx6/soc.c
+++ b/arch/arm/mach-imx/mx6/soc.c
@@ -13,6 +13,7 @@
#include <asm/arch/imx-regs.h>
#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
+#include <asm/bootm.h>
#include <asm/mach-imx/boot_mode.h>
#include <asm/mach-imx/dma.h>
#include <asm/mach-imx/hab.h>
diff --git a/arch/arm/mach-imx/mx7/Kconfig b/arch/arm/mach-imx/mx7/Kconfig
index aea85265ef..365501d518 100644
--- a/arch/arm/mach-imx/mx7/Kconfig
+++ b/arch/arm/mach-imx/mx7/Kconfig
@@ -18,6 +18,13 @@ choice
prompt "MX7 board select"
optional
+config TARGET_CL_SOM_IMX7
+ bool "CL-SOM-iMX7"
+ select MX7D
+ select DM
+ select DM_THERMAL
+ select SUPPORT_SPL
+
config TARGET_MX7DSABRESD
bool "mx7dsabresd"
select BOARD_LATE_INIT
@@ -51,6 +58,7 @@ endchoice
config SYS_SOC
default "mx7"
+source "board/compulab/cl-som-imx7/Kconfig"
source "board/freescale/mx7dsabresd/Kconfig"
source "board/technexion/pico-imx7d/Kconfig"
source "board/toradex/colibri_imx7/Kconfig"
diff --git a/arch/arm/mach-imx/mx7/Makefile b/arch/arm/mach-imx/mx7/Makefile
index d21f87f18c..ce289c1415 100644
--- a/arch/arm/mach-imx/mx7/Makefile
+++ b/arch/arm/mach-imx/mx7/Makefile
@@ -5,7 +5,7 @@
#
#
-obj-y := soc.o clock.o clock_slice.o
+obj-y := soc.o clock.o clock_slice.o ddr.o
ifdef CONFIG_ARMV7_PSCI
obj-y += psci-mx7.o psci.o
diff --git a/arch/arm/mach-imx/mx7/ddr.c b/arch/arm/mach-imx/mx7/ddr.c
new file mode 100644
index 0000000000..9268ad9470
--- /dev/null
+++ b/arch/arm/mach-imx/mx7/ddr.c
@@ -0,0 +1,201 @@
+/*
+ * DDR controller configuration for the i.MX7 architecture
+ *
+ * (C) Copyright 2017 CompuLab, Ltd. http://www.compulab.com
+ *
+ * Author: Uri Mashiach <uri.mashiach@compulab.co.il>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/mx7-ddr.h>
+#include <common.h>
+
+/*
+ * Routine: mx7_dram_cfg
+ * Description: DDR controller configuration
+ *
+ * @ddrc_regs_val: DDRC registers value
+ * @ddrc_mp_val: DDRC_MP registers value
+ * @ddr_phy_regs_val: DDR_PHY registers value
+ * @calib_param: calibration parameters
+ *
+ */
+void mx7_dram_cfg(struct ddrc *ddrc_regs_val, struct ddrc_mp *ddrc_mp_val,
+ struct ddr_phy *ddr_phy_regs_val,
+ struct mx7_calibration *calib_param)
+{
+ struct src *const src_regs = (struct src *)SRC_BASE_ADDR;
+ struct ddrc *const ddrc_regs = (struct ddrc *)DDRC_IPS_BASE_ADDR;
+ struct ddrc_mp *const ddrc_mp_reg = (struct ddrc_mp *)DDRC_MP_BASE_ADDR;
+ struct ddr_phy *const ddr_phy_regs =
+ (struct ddr_phy *)DDRPHY_IPS_BASE_ADDR;
+ struct iomuxc_gpr_base_regs *const iomuxc_gpr_regs =
+ (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
+ int i;
+
+ /* Assert DDR Controller preset and DDR PHY reset */
+ writel(SRC_DDRC_RCR_DDRC_CORE_RST_MASK, &src_regs->ddrc_rcr);
+
+ /* DDR controller configuration */
+ writel(ddrc_regs_val->mstr, &ddrc_regs->mstr);
+ writel(ddrc_regs_val->rfshtmg, &ddrc_regs->rfshtmg);
+ writel(ddrc_mp_val->pctrl_0, &ddrc_mp_reg->pctrl_0);
+ writel(ddrc_regs_val->init1, &ddrc_regs->init1);
+ writel(ddrc_regs_val->init0, &ddrc_regs->init0);
+ writel(ddrc_regs_val->init3, &ddrc_regs->init3);
+ writel(ddrc_regs_val->init4, &ddrc_regs->init4);
+ writel(ddrc_regs_val->init5, &ddrc_regs->init5);
+ writel(ddrc_regs_val->rankctl, &ddrc_regs->rankctl);
+ writel(ddrc_regs_val->dramtmg0, &ddrc_regs->dramtmg0);
+ writel(ddrc_regs_val->dramtmg1, &ddrc_regs->dramtmg1);
+ writel(ddrc_regs_val->dramtmg2, &ddrc_regs->dramtmg2);
+ writel(ddrc_regs_val->dramtmg3, &ddrc_regs->dramtmg3);
+ writel(ddrc_regs_val->dramtmg4, &ddrc_regs->dramtmg4);
+ writel(ddrc_regs_val->dramtmg5, &ddrc_regs->dramtmg5);
+ writel(ddrc_regs_val->dramtmg8, &ddrc_regs->dramtmg8);
+ writel(ddrc_regs_val->zqctl0, &ddrc_regs->zqctl0);
+ writel(ddrc_regs_val->dfitmg0, &ddrc_regs->dfitmg0);
+ writel(ddrc_regs_val->dfitmg1, &ddrc_regs->dfitmg1);
+ writel(ddrc_regs_val->dfiupd0, &ddrc_regs->dfiupd0);
+ writel(ddrc_regs_val->dfiupd1, &ddrc_regs->dfiupd1);
+ writel(ddrc_regs_val->dfiupd2, &ddrc_regs->dfiupd2);
+ writel(ddrc_regs_val->addrmap0, &ddrc_regs->addrmap0);
+ writel(ddrc_regs_val->addrmap1, &ddrc_regs->addrmap1);
+ writel(ddrc_regs_val->addrmap4, &ddrc_regs->addrmap4);
+ writel(ddrc_regs_val->addrmap5, &ddrc_regs->addrmap5);
+ writel(ddrc_regs_val->addrmap6, &ddrc_regs->addrmap6);
+ writel(ddrc_regs_val->odtcfg, &ddrc_regs->odtcfg);
+ writel(ddrc_regs_val->odtmap, &ddrc_regs->odtmap);
+
+ /* De-assert DDR Controller preset and DDR PHY reset */
+ clrbits_le32(&src_regs->ddrc_rcr, SRC_DDRC_RCR_DDRC_CORE_RST_MASK);
+
+ /* PHY configuration */
+ writel(ddr_phy_regs_val->phy_con0, &ddr_phy_regs->phy_con0);
+ writel(ddr_phy_regs_val->phy_con1, &ddr_phy_regs->phy_con1);
+ writel(ddr_phy_regs_val->phy_con4, &ddr_phy_regs->phy_con4);
+ writel(ddr_phy_regs_val->mdll_con0, &ddr_phy_regs->mdll_con0);
+ writel(ddr_phy_regs_val->drvds_con0, &ddr_phy_regs->drvds_con0);
+ writel(ddr_phy_regs_val->offset_wr_con0, &ddr_phy_regs->offset_wr_con0);
+ writel(ddr_phy_regs_val->offset_rd_con0, &ddr_phy_regs->offset_rd_con0);
+ writel(ddr_phy_regs_val->cmd_sdll_con0 |
+ DDR_PHY_CMD_SDLL_CON0_CTRL_RESYNC_MASK,
+ &ddr_phy_regs->cmd_sdll_con0);
+ writel(ddr_phy_regs_val->cmd_sdll_con0 &
+ ~DDR_PHY_CMD_SDLL_CON0_CTRL_RESYNC_MASK,
+ &ddr_phy_regs->cmd_sdll_con0);
+ writel(ddr_phy_regs_val->offset_lp_con0, &ddr_phy_regs->offset_lp_con0);
+
+ /* calibration */
+ for (i = 0; i < calib_param->num_val; i++)
+ writel(calib_param->values[i], &ddr_phy_regs->zq_con0);
+
+ /* Wake_up DDR PHY */
+ HW_CCM_CCGR_WR(CCGR_IDX_DDR, CCM_CLK_ON_N_N);
+ writel(IOMUXC_GPR_GPR8_ddr_phy_ctrl_wake_up(0xf) |
+ IOMUXC_GPR_GPR8_ddr_phy_dfi_init_start_MASK,
+ &iomuxc_gpr_regs->gpr[8]);
+ HW_CCM_CCGR_WR(CCGR_IDX_DDR, CCM_CLK_ON_R_W);
+}
+
+/*
+ * Routine: imx_ddr_size
+ * Description: extract the current DRAM size from the DDRC registers
+ *
+ * @return: DRAM size
+ */
+unsigned int imx_ddr_size(void)
+{
+ struct ddrc *const ddrc_regs = (struct ddrc *)DDRC_IPS_BASE_ADDR;
+ u32 reg_val, field_val;
+ int bits = 0;/* Number of address bits */
+
+ /* Count data bus width bits */
+ reg_val = readl(&ddrc_regs->mstr);
+ field_val = (reg_val & MSTR_DATA_BUS_WIDTH_MASK) >> MSTR_DATA_BUS_WIDTH_SHIFT;
+ bits += 2 - field_val;
+ /* Count rank address bits */
+ field_val = (reg_val & MSTR_DATA_ACTIVE_RANKS_MASK) >> MSTR_DATA_ACTIVE_RANKS_SHIFT;
+ if (field_val > 1)
+ bits += field_val - 1;
+ /* Count column address bits */
+ bits += 2;/* Column address 0 and 1 are fixed mapped */
+ reg_val = readl(&ddrc_regs->addrmap2);
+ field_val = (reg_val & ADDRMAP2_COL_B2_MASK) >> ADDRMAP2_COL_B2_SHIFT;
+ if (field_val <= 7)
+ bits++;
+ field_val = (reg_val & ADDRMAP2_COL_B3_MASK) >> ADDRMAP2_COL_B3_SHIFT;
+ if (field_val <= 7)
+ bits++;
+ field_val = (reg_val & ADDRMAP2_COL_B4_MASK) >> ADDRMAP2_COL_B4_SHIFT;
+ if (field_val <= 7)
+ bits++;
+ field_val = (reg_val & ADDRMAP2_COL_B5_MASK) >> ADDRMAP2_COL_B5_SHIFT;
+ if (field_val <= 7)
+ bits++;
+ reg_val = readl(&ddrc_regs->addrmap3);
+ field_val = (reg_val & ADDRMAP3_COL_B6_MASK) >> ADDRMAP3_COL_B6_SHIFT;
+ if (field_val <= 7)
+ bits++;
+ field_val = (reg_val & ADDRMAP3_COL_B7_MASK) >> ADDRMAP3_COL_B7_SHIFT;
+ if (field_val <= 7)
+ bits++;
+ field_val = (reg_val & ADDRMAP3_COL_B8_MASK) >> ADDRMAP3_COL_B8_SHIFT;
+ if (field_val <= 7)
+ bits++;
+ field_val = (reg_val & ADDRMAP3_COL_B9_MASK) >> ADDRMAP3_COL_B9_SHIFT;
+ if (field_val <= 7)
+ bits++;
+ reg_val = readl(&ddrc_regs->addrmap4);
+ field_val = (reg_val & ADDRMAP4_COL_B10_MASK) >> ADDRMAP4_COL_B10_SHIFT;
+ if (field_val <= 7)
+ bits++;
+ field_val = (reg_val & ADDRMAP4_COL_B11_MASK) >> ADDRMAP4_COL_B11_SHIFT;
+ if (field_val <= 7)
+ bits++;
+ /* Count row address bits */
+ reg_val = readl(&ddrc_regs->addrmap5);
+ field_val = (reg_val & ADDRMAP5_ROW_B0_MASK) >> ADDRMAP5_ROW_B0_SHIFT;
+ if (field_val <= 11)
+ bits++;
+ field_val = (reg_val & ADDRMAP5_ROW_B1_MASK) >> ADDRMAP5_ROW_B1_SHIFT;
+ if (field_val <= 11)
+ bits++;
+ field_val = (reg_val & ADDRMAP5_ROW_B2_10_MASK) >> ADDRMAP5_ROW_B2_10_SHIFT;
+ if (field_val <= 11)
+ bits += 9;
+ field_val = (reg_val & ADDRMAP5_ROW_B11_MASK) >> ADDRMAP5_ROW_B11_SHIFT;
+ if (field_val <= 11)
+ bits++;
+ reg_val = readl(&ddrc_regs->addrmap6);
+ field_val = (reg_val & ADDRMAP6_ROW_B12_MASK) >> ADDRMAP6_ROW_B12_SHIFT;
+ if (field_val <= 11)
+ bits++;
+ field_val = (reg_val & ADDRMAP6_ROW_B13_MASK) >> ADDRMAP6_ROW_B13_SHIFT;
+ if (field_val <= 11)
+ bits++;
+ field_val = (reg_val & ADDRMAP6_ROW_B14_MASK) >> ADDRMAP6_ROW_B14_SHIFT;
+ if (field_val <= 11)
+ bits++;
+ field_val = (reg_val & ADDRMAP6_ROW_B15_MASK) >> ADDRMAP6_ROW_B15_SHIFT;
+ if (field_val <= 11)
+ bits++;
+ /* Count bank bits */
+ reg_val = readl(&ddrc_regs->addrmap1);
+ field_val = (reg_val & ADDRMAP1_BANK_B0_MASK) >> ADDRMAP1_BANK_B0_SHIFT;
+ if (field_val <= 30)
+ bits++;
+ field_val = (reg_val & ADDRMAP1_BANK_B1_MASK) >> ADDRMAP1_BANK_B1_SHIFT;
+ if (field_val <= 30)
+ bits++;
+ field_val = (reg_val & ADDRMAP1_BANK_B2_MASK) >> ADDRMAP1_BANK_B2_SHIFT;
+ if (field_val <= 29)
+ bits++;
+
+ return 1 << bits;
+}
diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c
index 5944f99482..d0d1b73aa6 100644
--- a/arch/arm/mach-imx/spl.c
+++ b/arch/arm/mach-imx/spl.c
@@ -14,6 +14,7 @@
#include <asm/spl.h>
#include <spl.h>
#include <asm/mach-imx/hab.h>
+#include <asm/mach-imx/boot_mode.h>
#include <g_dnl.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -96,15 +97,35 @@ u32 spl_boot_device(void)
return BOOT_DEVICE_NONE;
}
+#elif defined(CONFIG_MX7)
+/* Translate iMX7 boot device to the SPL boot device enumeration */
+u32 spl_boot_device(void)
+{
+ enum boot_device boot_device_spl = get_boot_device();
+
+ switch (boot_device_spl) {
+ case SD1_BOOT:
+ case MMC1_BOOT:
+ return BOOT_DEVICE_MMC1;
+ case SD2_BOOT:
+ case MMC2_BOOT:
+ return BOOT_DEVICE_MMC2;
+ case SPI_NOR_BOOT:
+ return BOOT_DEVICE_SPI;
+ default:
+ return BOOT_DEVICE_NONE;
+ }
+}
+#endif /* CONFIG_MX6 || CONFIG_MX7 */
+
#ifdef CONFIG_SPL_USB_GADGET_SUPPORT
int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
{
- put_unaligned(CONFIG_G_DNL_PRODUCT_NUM + 0xfff, &dev->idProduct);
+ put_unaligned(CONFIG_USB_GADGET_PRODUCT_NUM + 0xfff, &dev->idProduct);
return 0;
}
#endif
-#endif
#if defined(CONFIG_SPL_MMC_SUPPORT)
/* called from spl_mmc to see type of boot mode for storage (RAW or FAT) */