summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorTom Rini <trini@ti.com>2015-02-10 10:40:43 -0500
committerTom Rini <trini@ti.com>2015-02-10 10:40:43 -0500
commit307367eaffc8638e10ba1784fc66bfe623ae79e2 (patch)
tree087641ed4c29320f8759cda28e377e36ff82cb78 /arch/arm
parenta4fb5df214c7e8d5bc949c1068d92252f105427a (diff)
parentaee0013e53b339a573e2a8d66062fe87765aa3bd (diff)
downloadu-boot-imx-307367eaffc8638e10ba1784fc66bfe623ae79e2.zip
u-boot-imx-307367eaffc8638e10ba1784fc66bfe623ae79e2.tar.gz
u-boot-imx-307367eaffc8638e10ba1784fc66bfe623ae79e2.tar.bz2
Merge branch 'master' of git://www.denx.de/git/u-boot-imx
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig13
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/spl_boot.c6
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c13
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c18
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/spl_power_init.c110
-rw-r--r--arch/arm/cpu/armv7/mx6/ddr.c96
-rw-r--r--arch/arm/cpu/armv7/mx6/soc.c2
-rw-r--r--arch/arm/include/asm/arch-mx6/imx-regs.h16
-rw-r--r--arch/arm/include/asm/arch-mx6/mx6-ddr.h46
-rw-r--r--arch/arm/include/asm/arch-mxs/sys_proto.h17
10 files changed, 309 insertions, 28 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 47806f8..2a83f26 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -646,6 +646,7 @@ config TARGET_MX6SLEVK
config TARGET_MX6SXSABRESD
bool "Support mx6sxsabresd"
select CPU_V7
+ select SUPPORT_SPL
config TARGET_GW_VENTANA
bool "Support gw_ventana"
@@ -672,6 +673,17 @@ config TARGET_TQMA6
config TARGET_OT1200
bool "Bachmann OT1200"
select CPU_V7
+ select SUPPORT_SPL
+
+config TARGET_PLATINUM_PICON
+ bool "Support platinum-picon"
+ select CPU_V7
+ select SUPPORT_SPL
+
+config TARGET_PLATINUM_TITANIUM
+ bool "Support platinum-titanium"
+ select CPU_V7
+ select SUPPORT_SPL
config OMAP34XX
bool "OMAP34XX SoC"
@@ -887,6 +899,7 @@ source "board/atmel/sama5d4_xplained/Kconfig"
source "board/atmel/sama5d4ek/Kconfig"
source "board/bachmann/ot1200/Kconfig"
source "board/balloon3/Kconfig"
+source "board/barco/platinum/Kconfig"
source "board/barco/titanium/Kconfig"
source "board/bluegiga/apx4devkit/Kconfig"
source "board/bluewater/snapper9260/Kconfig"
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
index d29b9aa..d7956e5 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
@@ -147,6 +147,7 @@ void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr,
mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size);
mxs_spl_console_init();
+ debug("SPL: Serial Console Initialised\n");
mxs_power_init();
@@ -156,6 +157,11 @@ void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr,
data->boot_mode_idx = bootmode;
mxs_power_wait_pswitch();
+
+ if (mxs_boot_modes[data->boot_mode_idx].boot_pads == MXS_BM_JTAG) {
+ debug("SPL: Waiting for JTAG user\n");
+ asm volatile ("x: b x");
+ }
}
/* Support aparatus */
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c
index cdfcddd..96bd32f 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c
@@ -18,6 +18,8 @@ void mxs_lradc_init(void)
{
struct mxs_lradc_regs *regs = (struct mxs_lradc_regs *)MXS_LRADC_BASE;
+ debug("SPL: Initialisating LRADC\n");
+
writel(LRADC_CTRL0_SFTRST, &regs->hw_lradc_ctrl0_clr);
writel(LRADC_CTRL0_CLKGATE, &regs->hw_lradc_ctrl0_clr);
writel(LRADC_CTRL0_ONCHIP_GROUNDREF, &regs->hw_lradc_ctrl0_clr);
@@ -37,9 +39,15 @@ void mxs_lradc_enable_batt_measurement(void)
{
struct mxs_lradc_regs *regs = (struct mxs_lradc_regs *)MXS_LRADC_BASE;
+ debug("SPL: Enabling LRADC battery measurement\n");
+
/* Check if the channel is present at all. */
- if (!(readl(&regs->hw_lradc_status) & LRADC_STATUS_CHANNEL7_PRESENT))
+ if (!(readl(&regs->hw_lradc_status) & LRADC_STATUS_CHANNEL7_PRESENT)) {
+ debug("SPL: LRADC channel 7 is not present - aborting\n");
return;
+ }
+
+ debug("SPL: LRADC channel 7 is present - configuring\n");
writel(LRADC_CTRL1_LRADC7_IRQ_EN, &regs->hw_lradc_ctrl1_clr);
writel(LRADC_CTRL1_LRADC7_IRQ, &regs->hw_lradc_ctrl1_clr);
@@ -65,6 +73,7 @@ void mxs_lradc_enable_batt_measurement(void)
100, &regs->hw_lradc_delay3);
writel(0xffffffff, &regs->hw_lradc_ch7_clr);
-
writel(LRADC_DELAY_KICK, &regs->hw_lradc_delay3_set);
+
+ debug("SPL: LRADC channel 7 configuration complete\n");
}
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
index 97ef67d..a744e5d 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
@@ -92,6 +92,7 @@ static uint32_t dram_vals[] = {
__weak void mxs_adjust_memory_params(uint32_t *dram_vals)
{
+ debug("SPL: Using default SDRAM parameters\n");
}
#ifdef CONFIG_MX28
@@ -99,8 +100,10 @@ static void initialize_dram_values(void)
{
int i;
+ debug("SPL: Setting mx28 board specific SDRAM parameters\n");
mxs_adjust_memory_params(dram_vals);
+ debug("SPL: Applying SDRAM parameters\n");
for (i = 0; i < ARRAY_SIZE(dram_vals); i++)
writel(dram_vals[i], MXS_DRAM_BASE + (4 * i));
}
@@ -109,6 +112,7 @@ static void initialize_dram_values(void)
{
int i;
+ debug("SPL: Setting mx23 board specific SDRAM parameters\n");
mxs_adjust_memory_params(dram_vals);
/*
@@ -120,6 +124,7 @@ static void initialize_dram_values(void)
* HW_DRAM_CTL8 is setup as the last element.
* So skip the initialization of these HW_DRAM_CTL registers.
*/
+ debug("SPL: Applying SDRAM parameters\n");
for (i = 0; i < ARRAY_SIZE(dram_vals); i++) {
if (i == 8 || i == 27 || i == 28 || i == 35)
continue;
@@ -146,6 +151,8 @@ static void mxs_mem_init_clock(void)
const unsigned char divider = 21;
#endif
+ debug("SPL: Initialising FRAC0\n");
+
/* Gate EMI clock */
writeb(CLKCTRL_FRAC_CLKGATE,
&clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_EMI]);
@@ -170,6 +177,7 @@ static void mxs_mem_init_clock(void)
&clkctrl_regs->hw_clkctrl_clkseq_clr);
early_delay(10000);
+ debug("SPL: FRAC0 Initialised\n");
}
static void mxs_mem_setup_cpu_and_hbus(void)
@@ -177,6 +185,8 @@ static void mxs_mem_setup_cpu_and_hbus(void)
struct mxs_clkctrl_regs *clkctrl_regs =
(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ debug("SPL: Setting CPU and HBUS clock frequencies\n");
+
/* Set fractional divider for ref_cpu to 480 * 18 / 19 = 454MHz
* and ungate CPU clock */
writeb(19 & CLKCTRL_FRAC_FRAC_MASK,
@@ -209,6 +219,8 @@ static void mxs_mem_setup_vdda(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Configuring VDDA\n");
+
writel((0xc << POWER_VDDACTRL_TRG_OFFSET) |
(0x7 << POWER_VDDACTRL_BO_OFFSET_OFFSET) |
POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW,
@@ -240,6 +252,8 @@ static void mx23_mem_setup_vddmem(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Setting mx23 VDDMEM\n");
+
/* We must wait before and after disabling the current limiter! */
early_delay(10000);
@@ -252,6 +266,8 @@ static void mx23_mem_setup_vddmem(void)
static void mx23_mem_init(void)
{
+ debug("SPL: Initialising mx23 SDRAM Controller\n");
+
/*
* Reset/ungate the EMI block. This is essential, otherwise the system
* suffers from memory instability. This thing is mx23 specific and is
@@ -297,6 +313,8 @@ static void mx28_mem_init(void)
struct mxs_pinctrl_regs *pinctrl_regs =
(struct mxs_pinctrl_regs *)MXS_PINCTRL_BASE;
+ debug("SPL: Initialising mx28 SDRAM Controller\n");
+
/* Set DDR2 mode */
writel(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2,
&pinctrl_regs->hw_pinctrl_emi_ds_ctrl_set);
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
index 1c54ab7..c342217 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
@@ -14,6 +14,13 @@
#include "mxs_init.h"
+#ifdef CONFIG_SYS_MXS_VDD5V_ONLY
+#define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \
+ POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2
+#else
+#define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \
+ POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL
+#endif
/**
* mxs_power_clock2xtal() - Switch CPU core clock source to 24MHz XTAL
*
@@ -26,6 +33,8 @@ static void mxs_power_clock2xtal(void)
struct mxs_clkctrl_regs *clkctrl_regs =
(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ debug("SPL: Switching CPU clock to 24MHz XTAL\n");
+
/* Set XTAL as CPU reference clock */
writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
&clkctrl_regs->hw_clkctrl_clkseq_set);
@@ -43,9 +52,23 @@ static void mxs_power_clock2pll(void)
struct mxs_clkctrl_regs *clkctrl_regs =
(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ debug("SPL: Switching CPU core clock source to PLL\n");
+
+ /*
+ * TODO: Are we really? It looks like we turn on PLL0, but we then
+ * set the CLKCTRL_CLKSEQ_BYPASS_CPU bit of the (which was already
+ * set by mxs_power_clock2xtal()). Clearing this bit here seems to
+ * introduce some instability (causing the CPU core to hang). Maybe
+ * we aren't giving PLL0 enough time to stabilise?
+ */
setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
CLKCTRL_PLL0CTRL0_POWER);
early_delay(100);
+
+ /*
+ * TODO: Should the PLL0 FORCE_LOCK bit be set here followed be a
+ * wait on the PLL0 LOCK bit?
+ */
setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
CLKCTRL_CLKSEQ_BYPASS_CPU);
}
@@ -62,6 +85,8 @@ static void mxs_power_set_auto_restart(void)
struct mxs_rtc_regs *rtc_regs =
(struct mxs_rtc_regs *)MXS_RTC_BASE;
+ debug("SPL: Setting auto-restart bit\n");
+
writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
;
@@ -101,14 +126,17 @@ static void mxs_power_set_linreg(void)
(struct mxs_power_regs *)MXS_POWER_BASE;
/* Set linear regulator 25mV below switching converter */
+ debug("SPL: Setting VDDD 25mV below DC-DC converters\n");
clrsetbits_le32(&power_regs->hw_power_vdddctrl,
POWER_VDDDCTRL_LINREG_OFFSET_MASK,
POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
+ debug("SPL: Setting VDDA 25mV below DC-DC converters\n");
clrsetbits_le32(&power_regs->hw_power_vddactrl,
POWER_VDDACTRL_LINREG_OFFSET_MASK,
POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW);
+ debug("SPL: Setting VDDIO 25mV below DC-DC converters\n");
clrsetbits_le32(&power_regs->hw_power_vddioctrl,
POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
@@ -127,6 +155,8 @@ static int mxs_get_batt_volt(void)
volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
volt *= 8;
+
+ debug("SPL: Battery Voltage = %dmV\n", volt);
return volt;
}
@@ -154,8 +184,10 @@ static int mxs_is_batt_good(void)
(struct mxs_power_regs *)MXS_POWER_BASE;
uint32_t volt = mxs_get_batt_volt();
- if ((volt >= 2400) && (volt <= 4300))
+ if ((volt >= 2400) && (volt <= 4300)) {
+ debug("SPL: Battery is good\n");
return 1;
+ }
clrsetbits_le32(&power_regs->hw_power_5vctrl,
POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
@@ -175,16 +207,21 @@ static int mxs_is_batt_good(void)
volt = mxs_get_batt_volt();
- if (volt >= 3500)
+ if (volt >= 3500) {
+ debug("SPL: Battery Voltage too high\n");
return 0;
+ }
- if (volt >= 2400)
+ if (volt >= 2400) {
+ debug("SPL: Battery is good\n");
return 1;
+ }
writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
&power_regs->hw_power_charge_clr);
writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
+ debug("SPL: Battery Voltage too low\n");
return 0;
}
@@ -203,6 +240,7 @@ static void mxs_power_setup_5v_detect(void)
(struct mxs_power_regs *)MXS_POWER_BASE;
/* Start 5V detection */
+ debug("SPL: Starting 5V input detection comparator\n");
clrsetbits_le32(&power_regs->hw_power_5vctrl,
POWER_5VCTRL_VBUSVALID_TRSH_MASK,
POWER_5VCTRL_VBUSVALID_TRSH_4V4 |
@@ -220,6 +258,8 @@ static void mxs_src_power_init(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Pre-Configuring power block\n");
+
/* Improve efficieny and reduce transient ripple */
writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
@@ -257,6 +297,8 @@ static void mxs_power_init_4p2_params(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Configuring common 4P2 regulator params\n");
+
/* Setup 4P2 parameters */
clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
@@ -268,8 +310,7 @@ static void mxs_power_init_4p2_params(void)
clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
POWER_DCDC4P2_DROPOUT_CTRL_MASK,
- POWER_DCDC4P2_DROPOUT_CTRL_100MV |
- POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL);
+ DCDC4P2_DROPOUT_CONFIG);
clrsetbits_le32(&power_regs->hw_power_5vctrl,
POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
@@ -289,6 +330,8 @@ static void mxs_enable_4p2_dcdc_input(int xfer)
uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
uint32_t prev_5v_brnout, prev_5v_droop;
+ debug("SPL: %s 4P2 DC-DC Input\n", xfer ? "Enabling" : "Disabling");
+
prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
POWER_5VCTRL_PWDN_5VBRNOUT;
prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
@@ -390,6 +433,8 @@ static void mxs_power_init_4p2_regulator(void)
(struct mxs_power_regs *)MXS_POWER_BASE;
uint32_t tmp, tmp2;
+ debug("SPL: Enabling 4P2 regulator\n");
+
setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
@@ -407,6 +452,7 @@ static void mxs_power_init_4p2_regulator(void)
* gradually to avoid large inrush current from the 5V cable which can
* cause transients/problems
*/
+ debug("SPL: Charging 4P2 capacitor\n");
mxs_enable_4p2_dcdc_input(0);
if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
@@ -420,6 +466,8 @@ static void mxs_power_init_4p2_regulator(void)
POWER_DCDC4P2_ENABLE_DCDC);
writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
&power_regs->hw_power_5vctrl_set);
+
+ debug("SPL: Unable to recover from mx23 errata 5837\n");
hang();
}
@@ -433,6 +481,7 @@ static void mxs_power_init_4p2_regulator(void)
* current limit until the brownout status is false or until we've
* reached our maximum defined 4p2 current limit.
*/
+ debug("SPL: Setting 4P2 brownout level\n");
clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
POWER_DCDC4P2_BO_MASK,
22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */
@@ -479,8 +528,11 @@ static void mxs_power_init_dcdc_4p2_source(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Switching DC-DC converters to 4P2\n");
+
if (!(readl(&power_regs->hw_power_dcdc4p2) &
POWER_DCDC4P2_ENABLE_DCDC)) {
+ debug("SPL: Already switched - aborting\n");
hang();
}
@@ -509,6 +561,8 @@ static void mxs_power_enable_4p2(void)
uint32_t vdddctrl, vddactrl, vddioctrl;
uint32_t tmp;
+ debug("SPL: Powering up 4P2 regulator\n");
+
vdddctrl = readl(&power_regs->hw_power_vdddctrl);
vddactrl = readl(&power_regs->hw_power_vddactrl);
vddioctrl = readl(&power_regs->hw_power_vddioctrl);
@@ -559,6 +613,8 @@ static void mxs_power_enable_4p2(void)
if (tmp)
writel(POWER_CHARGE_ENABLE_LOAD,
&power_regs->hw_power_charge_clr);
+
+ debug("SPL: 4P2 regulator powered-up\n");
}
/**
@@ -574,6 +630,8 @@ static void mxs_boot_valid_5v(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Booting from 5V supply\n");
+
/*
* Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
* disconnect event. FIXME
@@ -601,6 +659,9 @@ static void mxs_powerdown(void)
{
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("Powering Down\n");
+
writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
&power_regs->hw_power_reset);
@@ -617,6 +678,8 @@ static void mxs_batt_boot(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Configuring power block to boot from battery\n");
+
clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
@@ -672,6 +735,8 @@ static void mxs_handle_5v_conflict(void)
(struct mxs_power_regs *)MXS_POWER_BASE;
uint32_t tmp;
+ debug("SPL: Resolving 5V conflict\n");
+
setbits_le32(&power_regs->hw_power_vddioctrl,
POWER_VDDIOCTRL_BO_OFFSET_MASK);
@@ -683,19 +748,27 @@ static void mxs_handle_5v_conflict(void)
* VDDIO has a brownout, then the VDD5V_GT_VDDIO becomes
* unreliable
*/
+ debug("SPL: VDDIO has a brownout\n");
mxs_powerdown();
break;
}
if (tmp & POWER_STS_VDD5V_GT_VDDIO) {
+ debug("SPL: POWER_STS_VDD5V_GT_VDDIO is set\n");
mxs_boot_valid_5v();
break;
} else {
+ debug("SPL: POWER_STS_VDD5V_GT_VDDIO is not set\n");
mxs_powerdown();
break;
}
+ /*
+ * TODO: I can't see this being reached. We'll either
+ * powerdown or boot from a stable 5V supply.
+ */
if (tmp & POWER_STS_PSWITCH_MASK) {
+ debug("SPL: POWER_STS_PSWITCH_MASK is set\n");
mxs_batt_boot();
break;
}
@@ -713,21 +786,26 @@ static void mxs_5v_boot(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Configuring power block to boot from 5V input\n");
+
/*
* NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
* but their implementation always returns 1 so we omit it here.
*/
if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+ debug("SPL: 5V VDD good\n");
mxs_boot_valid_5v();
return;
}
early_delay(1000);
if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+ debug("SPL: 5V VDD good (after delay)\n");
mxs_boot_valid_5v();
return;
}
+ debug("SPL: 5V VDD not good\n");
mxs_handle_5v_conflict();
}
@@ -742,6 +820,8 @@ static void mxs_init_batt_bo(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Initialising battery brown-out level to 3.0V\n");
+
/* Brownout at 3V */
clrsetbits_le32(&power_regs->hw_power_battmonitor,
POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
@@ -762,6 +842,8 @@ static void mxs_switch_vddd_to_dcdc_source(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Switching VDDD to DC-DC converters\n");
+
clrsetbits_le32(&power_regs->hw_power_vdddctrl,
POWER_VDDDCTRL_LINREG_OFFSET_MASK,
POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
@@ -788,6 +870,8 @@ static void mxs_power_configure_power_source(void)
struct mxs_lradc_regs *lradc_regs =
(struct mxs_lradc_regs *)MXS_LRADC_BASE;
+ debug("SPL: Configuring power source\n");
+
mxs_src_power_init();
if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
@@ -811,6 +895,10 @@ static void mxs_power_configure_power_source(void)
mxs_batt_boot();
}
+ /*
+ * TODO: Do not switch CPU clock to PLL if we are VDD5V is sourced
+ * from USB VBUS
+ */
mxs_power_clock2pll();
mxs_init_batt_bo();
@@ -819,6 +907,7 @@ static void mxs_power_configure_power_source(void)
#ifdef CONFIG_MX23
/* Fire up the VDDMEM LinReg now that we're all set. */
+ debug("SPL: Enabling mx23 VDDMEM linear regulator\n");
writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT,
&power_regs->hw_power_vddmemctrl);
#endif
@@ -838,6 +927,8 @@ static void mxs_enable_output_rail_protection(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Enabling output rail protection\n");
+
writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
@@ -1077,6 +1168,8 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
*/
static void mxs_setup_batt_detect(void)
{
+ debug("SPL: Starting battery voltage measurement logic\n");
+
mxs_lradc_init();
mxs_lradc_enable_batt_measurement();
early_delay(10);
@@ -1111,6 +1204,8 @@ void mxs_power_init(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Initialising Power Block\n");
+
mxs_ungate_power();
mxs_power_clock2xtal();
@@ -1123,9 +1218,13 @@ void mxs_power_init(void)
mxs_power_configure_power_source();
mxs_enable_output_rail_protection();
+ debug("SPL: Setting VDDIO to 3V3 (brownout @ 3v15)\n");
mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
+
+ debug("SPL: Setting VDDD to 1V5 (brownout @ 1v0)\n");
mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000);
#ifdef CONFIG_MX23
+ debug("SPL: Setting mx23 VDDMEM to 2V5 (brownout @ 1v7)\n");
mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700);
#endif
writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
@@ -1150,6 +1249,7 @@ void mxs_power_wait_pswitch(void)
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)MXS_POWER_BASE;
+ debug("SPL: Waiting for power switch input\n");
while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
;
}
diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index 7a9b03a..fef2231 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -12,6 +12,65 @@
#include <asm/io.h>
#include <asm/types.h>
+#if defined(CONFIG_MX6SX)
+/* Configure MX6SX mmdc iomux */
+void mx6sx_dram_iocfg(unsigned width,
+ const struct mx6sx_iomux_ddr_regs *ddr,
+ const struct mx6sx_iomux_grp_regs *grp)
+{
+ struct mx6sx_iomux_ddr_regs *mx6_ddr_iomux;
+ struct mx6sx_iomux_grp_regs *mx6_grp_iomux;
+
+ mx6_ddr_iomux = (struct mx6sx_iomux_ddr_regs *)MX6SX_IOM_DDR_BASE;
+ mx6_grp_iomux = (struct mx6sx_iomux_grp_regs *)MX6SX_IOM_GRP_BASE;
+
+ /* DDR IO TYPE */
+ writel(grp->grp_ddr_type, &mx6_grp_iomux->grp_ddr_type);
+ writel(grp->grp_ddrpke, &mx6_grp_iomux->grp_ddrpke);
+
+ /* CLOCK */
+ writel(ddr->dram_sdclk_0, &mx6_ddr_iomux->dram_sdclk_0);
+
+ /* ADDRESS */
+ writel(ddr->dram_cas, &mx6_ddr_iomux->dram_cas);
+ writel(ddr->dram_ras, &mx6_ddr_iomux->dram_ras);
+ writel(grp->grp_addds, &mx6_grp_iomux->grp_addds);
+
+ /* Control */
+ writel(ddr->dram_reset, &mx6_ddr_iomux->dram_reset);
+ writel(ddr->dram_sdba2, &mx6_ddr_iomux->dram_sdba2);
+ writel(ddr->dram_sdcke0, &mx6_ddr_iomux->dram_sdcke0);
+ writel(ddr->dram_sdcke1, &mx6_ddr_iomux->dram_sdcke1);
+ writel(ddr->dram_odt0, &mx6_ddr_iomux->dram_odt0);
+ writel(ddr->dram_odt1, &mx6_ddr_iomux->dram_odt1);
+ writel(grp->grp_ctlds, &mx6_grp_iomux->grp_ctlds);
+
+ /* Data Strobes */
+ writel(grp->grp_ddrmode_ctl, &mx6_grp_iomux->grp_ddrmode_ctl);
+ writel(ddr->dram_sdqs0, &mx6_ddr_iomux->dram_sdqs0);
+ writel(ddr->dram_sdqs1, &mx6_ddr_iomux->dram_sdqs1);
+ if (width >= 32) {
+ writel(ddr->dram_sdqs2, &mx6_ddr_iomux->dram_sdqs2);
+ writel(ddr->dram_sdqs3, &mx6_ddr_iomux->dram_sdqs3);
+ }
+
+ /* Data */
+ writel(grp->grp_ddrmode, &mx6_grp_iomux->grp_ddrmode);
+ writel(grp->grp_b0ds, &mx6_grp_iomux->grp_b0ds);
+ writel(grp->grp_b1ds, &mx6_grp_iomux->grp_b1ds);
+ if (width >= 32) {
+ writel(grp->grp_b2ds, &mx6_grp_iomux->grp_b2ds);
+ writel(grp->grp_b3ds, &mx6_grp_iomux->grp_b3ds);
+ }
+ writel(ddr->dram_dqm0, &mx6_ddr_iomux->dram_dqm0);
+ writel(ddr->dram_dqm1, &mx6_ddr_iomux->dram_dqm1);
+ if (width >= 32) {
+ writel(ddr->dram_dqm2, &mx6_ddr_iomux->dram_dqm2);
+ writel(ddr->dram_dqm3, &mx6_ddr_iomux->dram_dqm3);
+ }
+}
+#endif
+
#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
/* Configure MX6DQ mmdc iomux */
void mx6dq_dram_iocfg(unsigned width,
@@ -184,12 +243,19 @@ void mx6sdl_dram_iocfg(unsigned width,
*/
#define MR(val, ba, cmd, cs1) \
((val << 16) | (1 << 15) | (cmd << 4) | (cs1 << 3) | ba)
+#ifdef CONFIG_MX6SX
+#define MMDC1(entry, value) do {} while (0)
+#else
+#define MMDC1(entry, value) do { mmdc1->entry = value; } while (0)
+#endif
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;
+#ifndef CONFIG_MX6SX
volatile struct mmdc_p_regs *mmdc1;
+#endif
u32 val;
u8 tcke, tcksrx, tcksre, txpdll, taofpd, taonpd, trrd;
u8 todtlon, taxpd, tanpd, tcwl, txp, tfaw, tcl;
@@ -203,7 +269,9 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
int cs;
mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
+#ifndef CONFIG_MX6SX
mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;
+#endif
/* MX6D/MX6Q: 1066 MHz memory clock, clkper = 1.894ns = 1894ps */
if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) {
@@ -362,12 +430,12 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
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;
+ 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 */
@@ -379,23 +447,23 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
}
if (sysinfo->dsize > 1) {
- mmdc1->mprddqby0dl = 0x33333333;
- mmdc1->mprddqby1dl = 0x33333333;
- mmdc1->mprddqby2dl = 0x33333333;
- mmdc1->mprddqby3dl = 0x33333333;
+ 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) */
val = (sysinfo->rtt_nom == 2) ? 0x00011117 : 0x00022227;
mmdc0->mpodtctrl = val;
if (sysinfo->dsize > 1)
- mmdc1->mpodtctrl = val;
+ MMDC1(mpodtctrl, val);
/* complete calibration */
val = (1 << 11); /* Force measurement on delay-lines */
mmdc0->mpmur0 = val;
if (sysinfo->dsize > 1)
- mmdc1->mpmur0 = val;
+ MMDC1(mpmur0, val);
/* Step 1: configuration request */
mmdc0->mdscr = (u32)(1 << 15); /* config request */
@@ -435,7 +503,7 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
val = 0xa1390001; /* one-time HW ZQ calib */
mmdc0->mpzqhwctrl = val;
if (sysinfo->dsize > 1)
- mmdc1->mpzqhwctrl = val;
+ MMDC1(mpzqhwctrl, val);
/* Step 7: Enable MMDC with desired chip select */
mmdc0->mdctl |= (1 << 31) | /* SDE_0 for CS0 */
@@ -477,7 +545,7 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
val = 0xa1390003;
mmdc0->mpzqhwctrl = val;
if (sysinfo->dsize > 1)
- mmdc1->mpzqhwctrl = val;
+ MMDC1(mpzqhwctrl, val);
/* Step 12: Configure and activate periodic refresh */
mmdc0->mdref = (1 << 14) | /* REF_SEL: Periodic refresh cycle: 32kHz */
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index 5f5f497..e599a12 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -109,7 +109,7 @@ void init_aips(void)
aips1 = (struct aipstz_regs *)AIPS1_BASE_ADDR;
aips2 = (struct aipstz_regs *)AIPS2_BASE_ADDR;
#ifdef CONFIG_MX6SX
- aips3 = (struct aipstz_regs *)AIPS3_BASE_ADDR;
+ aips3 = (struct aipstz_regs *)AIPS3_CONFIG_BASE_ADDR;
#endif
/*
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
index c968600..ae88b6e 100644
--- a/arch/arm/include/asm/arch-mx6/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
@@ -88,8 +88,8 @@
#define AIPS2_ARB_BASE_ADDR 0x02100000
#define AIPS2_ARB_END_ADDR 0x021FFFFF
#ifdef CONFIG_MX6SX
-#define AIPS3_BASE_ADDR 0x02200000
-#define AIPS3_END_ADDR 0x022FFFFF
+#define AIPS3_ARB_BASE_ADDR 0x02200000
+#define AIPS3_ARB_END_ADDR 0x022FFFFF
#define WEIM_ARB_BASE_ADDR 0x50000000
#define WEIM_ARB_END_ADDR 0x57FFFFFF
#define QSPI0_AMBA_BASE 0x60000000
@@ -624,12 +624,16 @@ struct fuse_bank0_regs {
u32 rsvd1[3];
u32 uid_high;
u32 rsvd2[3];
- u32 rsvd3[4];
- u32 rsvd4[4];
- u32 rsvd5[4];
+ u32 cfg2;
+ u32 rsvd3[3];
+ u32 cfg3;
+ u32 rsvd4[3];
+ u32 cfg4;
+ u32 rsvd5[3];
u32 cfg5;
u32 rsvd6[3];
- u32 rsvd7[4];
+ u32 cfg6;
+ u32 rsvd7[3];
};
#ifdef CONFIG_MX6SX
diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
index 5ebabfa..8e0d7d1 100644
--- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
+++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
@@ -62,6 +62,49 @@ struct mmdc_p_regs {
u32 mpmur0;
};
+#define MX6SX_IOM_DDR_BASE 0x020e0200
+struct mx6sx_iomux_ddr_regs {
+ u32 res1[59];
+ u32 dram_dqm0;
+ u32 dram_dqm1;
+ u32 dram_dqm2;
+ u32 dram_dqm3;
+ u32 dram_ras;
+ u32 dram_cas;
+ u32 res2[2];
+ u32 dram_sdwe_b;
+ u32 dram_odt0;
+ u32 dram_odt1;
+ u32 dram_sdba0;
+ u32 dram_sdba1;
+ u32 dram_sdba2;
+ u32 dram_sdcke0;
+ u32 dram_sdcke1;
+ u32 dram_sdclk_0;
+ u32 dram_sdqs0;
+ u32 dram_sdqs1;
+ u32 dram_sdqs2;
+ u32 dram_sdqs3;
+ u32 dram_reset;
+};
+
+#define MX6SX_IOM_GRP_BASE 0x020e0500
+struct mx6sx_iomux_grp_regs {
+ u32 res1[61];
+ u32 grp_addds;
+ u32 grp_ddrmode_ctl;
+ u32 grp_ddrpke;
+ u32 grp_ddrpk;
+ u32 grp_ddrhys;
+ u32 grp_ddrmode;
+ u32 grp_b0ds;
+ u32 grp_b1ds;
+ u32 grp_ctlds;
+ u32 grp_ddr_type;
+ u32 grp_b2ds;
+ u32 grp_b3ds;
+};
+
/*
* MMDC iomux registers (pinctl/padctl) - (different for IMX6DQ vs IMX6SDL)
*/
@@ -243,6 +286,9 @@ void mx6dq_dram_iocfg(unsigned width,
void mx6sdl_dram_iocfg(unsigned width,
const struct mx6sdl_iomux_ddr_regs *,
const struct mx6sdl_iomux_grp_regs *);
+void mx6sx_dram_iocfg(unsigned width,
+ const struct mx6sx_iomux_ddr_regs *,
+ const struct mx6sx_iomux_grp_regs *);
/* configure mx6 mmdc registers */
void mx6_dram_cfg(const struct mx6_ddr_sysinfo *,
diff --git a/arch/arm/include/asm/arch-mxs/sys_proto.h b/arch/arm/include/asm/arch-mxs/sys_proto.h
index 062f3de..4678723 100644
--- a/arch/arm/include/asm/arch-mxs/sys_proto.h
+++ b/arch/arm/include/asm/arch-mxs/sys_proto.h
@@ -74,6 +74,23 @@ static const struct mxs_pair mxs_boot_modes[] = {
#endif
};
+#define MXS_BM_USB 0x00
+#define MXS_BM_I2C_MASTER_3V3 0x01
+#define MXS_BM_I2C_MASTER_1V8 0x11
+#define MXS_BM_SPI2_MASTER_3V3_NOR 0x02
+#define MXS_BM_SPI2_MASTER_1V8_NOR 0x12
+#define MXS_BM_SPI3_MASTER_3V3_NOR 0x03
+#define MXS_BM_SPI3_MASTER_1V8_NOR 0x13
+#define MXS_BM_NAND_3V3 0x04
+#define MXS_BM_NAND_1V8 0x14
+#define MXS_BM_JTAG 0x06
+#define MXS_BM_SPI3_MASTER_3V3_EEPROM 0x08
+#define MXS_BM_SPI3_MASTER_1V8_EEPROM 0x18
+#define MXS_BM_SDMMC0_3V3 0x09
+#define MXS_BM_SDMMC0_1V8 0x19
+#define MXS_BM_SDMMC1_3V3 0x0a
+#define MXS_BM_SDMMC1_1V8 0x1a
+
struct mxs_spl_data {
uint8_t boot_mode_idx;
uint32_t mem_dram_size;