[U-Boot] [PATCH 0/5] Add support for G2C1 mx28 board (which has no battery)

This series adds support for booting mx28 based boards which do not include a battery as per Freescale application note AN4199
Patch 2 (which implements booting without a battery) is based on a patch submitted to the Freescale community forums by Damien Gotfroi (Cc'd)
The patch series adds the following functionality (in oreder of implementation) - Debug output for mxs SPL (define DEBUG and CONFIG_SPL_SERIAL_SUPPORT in order to enable) - Ability to boot mx28 boards without a battery as per AN4199 (define CONFIG_SYS_MXS_VDD5V_ONLY to enable) - A tight loop (with 'Waiting for JTAG user') at the completion of SPL init if booting with the bootmode jumpers set to JTAG - Move the PLL power-up to a more logical location and properly initialise and check for PLL lock - Finally, add the G2C1 board
Graeme Russ (5): Add debug output to mx29 SPL source files Enable booting of mx28 without battery Add 'Wait for JTAG user' if booted in JTAG mode Move PLL power-up from power init to memory init Add support for ReachTech G2C1 board
arch/arm/Kconfig | 13 + arch/arm/cpu/arm926ejs/mxs/spl_boot.c | 7 + arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c | 13 +- arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c | 49 +++ arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 287 ++++++++++++++++-- board/reachtech/g2c1/Kconfig | 15 + board/reachtech/g2c1/MAINTAINERS | 9 + board/reachtech/g2c1/Makefile | 12 + board/reachtech/g2c1/README | 58 ++++ board/reachtech/g2c1/g2c1.c | 79 +++++ board/reachtech/g2c1/spl_boot.c | 452 ++++++++++++++++++++++++++++ configs/g2c1_defconfig | 3 + doc/README.mxs | 10 + include/configs/g2c1.h | 303 +++++++++++++++++++ 14 files changed, 1281 insertions(+), 29 deletions(-) create mode 100644 board/reachtech/g2c1/Kconfig create mode 100644 board/reachtech/g2c1/MAINTAINERS create mode 100644 board/reachtech/g2c1/Makefile create mode 100644 board/reachtech/g2c1/README create mode 100644 board/reachtech/g2c1/g2c1.c create mode 100644 board/reachtech/g2c1/spl_boot.c create mode 100644 configs/g2c1_defconfig create mode 100644 include/configs/g2c1.h

Signed-off-by: Graeme Russ gruss@tss-engineering.com ---
arch/arm/cpu/arm926ejs/mxs/spl_boot.c | 1 + arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c | 13 +++- arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c | 18 +++++ arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 100 +++++++++++++++++++++++++++- 4 files changed, 127 insertions(+), 5 deletions(-)
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index d29b9aa..2a5f817 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();
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c index cdfcddd..9e6f24a 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"); + writel(LRADC_CTRL0_SFTRST, ®s->hw_lradc_ctrl0_clr); writel(LRADC_CTRL0_CLKGATE, ®s->hw_lradc_ctrl0_clr); writel(LRADC_CTRL0_ONCHIP_GROUNDREF, ®s->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(®s->hw_lradc_status) & LRADC_STATUS_CHANNEL7_PRESENT)) + if (!(readl(®s->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, ®s->hw_lradc_ctrl1_clr); writel(LRADC_CTRL1_LRADC7_IRQ, ®s->hw_lradc_ctrl1_clr); @@ -65,6 +73,7 @@ void mxs_lradc_enable_batt_measurement(void) 100, ®s->hw_lradc_delay3);
writel(0xffffffff, ®s->hw_lradc_ch7_clr); - writel(LRADC_DELAY_KICK, ®s->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..7fb734e 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c @@ -26,6 +26,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 +45,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 +78,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 +119,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 +148,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 +177,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 +200,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 +233,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 +251,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 +290,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, @@ -289,6 +324,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 +427,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 +446,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 +460,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 +475,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 +522,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 +555,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 +607,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 +624,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 +653,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 +672,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 +729,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 +742,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 +780,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 +814,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 +836,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 +864,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 +889,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 +901,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 +921,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 +1162,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 +1198,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 +1212,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 +1243,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)) ; }

On Wed, Jan 21, 2015 at 9:55 AM, Graeme Russ gruss@tss-engineering.com wrote:
Signed-off-by: Graeme Russ gruss@tss-engineering.com
In the subject I guess you meant 'mxs' instead of mx29.
Also, if you send a v2, please keep Marek on Cc.

On Wednesday, January 21, 2015 at 12:55:14 PM, Graeme Russ wrote:
Signed-off-by: Graeme Russ gruss@tss-engineering.com
Hi!
- Commit message is missing. - Some of the debug outputs are missing newline (\n) character - You can use __func__ and __LINE__ in the debug output to better specify where the debug spit happened.
Oh, and the CC list looks pretty random. You can just add "Cc: " tag into the patches so that git handles it correctly.
Best regards, Marek Vasut

On 22/01/15 10:24, Marek Vasut wrote:
On Wednesday, January 21, 2015 at 12:55:14 PM, Graeme Russ wrote:
Signed-off-by: Graeme Russ gruss@tss-engineering.com
Hi!
- Commit message is missing.
- Some of the debug outputs are missing newline (\n) character
- You can use __func__ and __LINE__ in the debug output to better specify where the debug spit happened.
I saw something earlier on the list about this - I thought the feeling was to use descriptive strings that are easy to grep rather than __func__ and __LINE__, or maybe I misread
Oh, and the CC list looks pretty random. You can just add "Cc: " tag into the patches so that git handles it correctly.
Cc list was generated by patman (I added Damien as his patch is what mine are based on)
Regards,
Graeme

Section 4.1.2 of Freescale Application Note AN4199 describes the configuration required to operate the mx28 from a 5V source without a battery. This patch implements the changes to the Freescale bootlets which allow this configuration to properly boot the mx28 processor
Signed-off-by: Graeme Russ gruss@tss-engineering.com ---
arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 190 +++++++++++++++++++++++++++- doc/README.mxs | 10 ++ 2 files changed, 197 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c index 7fb734e..e469381 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c @@ -14,6 +14,22 @@
#include "mxs_init.h"
+#if defined(CONFIG_MX28) +/* + * The minimum DCDC operating voltage for i.MX28 with loading is 3.3V. + * we will set the BRWNOUT_LVL bitfield the 3.2V value for 0.1V margin. + */ +#define BATTERY_BRWNOUT_BITFIELD_VALUE 20 /* 20 = 3.2V */ +#else +/* + * At the time of this writing, 3V is greater than the minimum DCDC + * operating voltage for i.MX233 as listed in by the "Battery / DCDC Input + * Voltage" parameter listed in the reference manual so we will set the + * BRWNOUT_LVL bitfield to 3V value. + */ +#define BATTERY_BRWNOUT_BITFIELD_VALUE 15 /* 15 = 3.0V */ +#endif + /** * mxs_power_clock2xtal() - Switch CPU core clock source to 24MHz XTAL * @@ -88,6 +104,7 @@ static void mxs_power_set_auto_restart(void) while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE) ;
+#ifdef CONFIG_SYS_MXS_VDD5V_ONLY /* Do nothing if flag already set */ if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART) return; @@ -103,6 +120,7 @@ static void mxs_power_set_auto_restart(void) ; while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK) ; +#endif }
/** @@ -135,6 +153,7 @@ static void mxs_power_set_linreg(void) POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW); }
+#ifndef CONFIG_SYS_MXS_VDD5V_ONLY /** * mxs_get_batt_volt() - Measure battery input voltage * @@ -217,6 +236,7 @@ static int mxs_is_batt_good(void) debug("SPL: Battery Voltage too low\n"); return 0; } +#endif
/** * mxs_power_setup_5v_detect() - Start the 5V input detection comparator @@ -301,10 +321,19 @@ static void mxs_power_init_4p2_params(void) POWER_5VCTRL_HEADROOM_ADJ_MASK, 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET);
+#ifdef CONFIG_SYS_MXS_VDD5V_ONLY + debug("SPL: Configuring 4P2 VDD5V only regulator params\n"); + clrsetbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_DROPOUT_CTRL_MASK, + POWER_DCDC4P2_DROPOUT_CTRL_100MV | + POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2); +#else + debug("SPL: Configuring VDD5V + Battery 4P2 regulator params\n"); clrsetbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_DROPOUT_CTRL_MASK, POWER_DCDC4P2_DROPOUT_CTRL_100MV | POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL); +#endif
clrsetbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, @@ -387,9 +416,11 @@ static void mxs_enable_4p2_dcdc_input(int xfer) if (!pwd_bo) clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO);
- while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) - writel(POWER_CTRL_VBUS_VALID_IRQ, - &power_regs->hw_power_ctrl_clr); + if (xfer) + while (readl(&power_regs->hw_power_ctrl) & + POWER_CTRL_VBUS_VALID_IRQ) + writel(POWER_CTRL_VBUS_VALID_IRQ, + &power_regs->hw_power_ctrl_clr);
if (prev_5v_brnout) { writel(POWER_5VCTRL_PWDN_5VBRNOUT, @@ -480,6 +511,23 @@ static void mxs_power_init_4p2_regulator(void) POWER_DCDC4P2_BO_MASK, 22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */
+#ifdef CONFIG_SYS_MXS_VDD5V_ONLY + debug("SPL: Ramping up current limit (VDD5V only)\n"); + + tmp = (readl(&power_regs->hw_power_5vctrl) & + POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >> + POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET; + while (tmp < 0x3f) { + tmp++; + tmp2 = readl(&power_regs->hw_power_5vctrl); + tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK; + tmp2 |= tmp << + POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET; + writel(tmp2, &power_regs->hw_power_5vctrl); + early_delay(100); + } +#else + debug("SPL: Ramping up current limit (VDD5V + Battery)\n"); if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) { setbits_le32(&power_regs->hw_power_5vctrl, 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); @@ -506,6 +554,30 @@ static void mxs_power_init_4p2_regulator(void) } } } +#endif + /* + * TODO: If VDD5V is sourced from USB VBUS, we need to set the + * current limit so we don't exceed the USB specifications. The + * USB standard states that a device can only draw 100mA unless it + * requests more from the host - after which it may draw up to + * 500mA. Then we have Charging Ports which may deliver up to 1.5A + * (without needing a request from the device). + * + * NOTE: The source code for the Freescale bootlets seems to be + * internally inconsistent - The printf() claims 100mA, while + * VBUS_CURRENT_LIMIT is defined as 400mA. + * + * NOTE: We should also limit the CPU clock frequency in order to + * reduce the likelyhood of the USB VBUS current limit being exceeded + * + * The following would limit the USB VBUS current draw to 100mA + * + * clrsetbits_le32(&power_regs->hw_power_5vctrl, + * POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, + * 0x10 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); + * + * early_delay(10000); + */
clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK); writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr); @@ -524,11 +596,13 @@ static void mxs_power_init_dcdc_4p2_source(void)
debug("SPL: Switching DC-DC converters to 4P2\n");
+#ifndef CONFIG_SYS_MXS_VDD5V_ONLY if (!(readl(&power_regs->hw_power_dcdc4p2) & POWER_DCDC4P2_ENABLE_DCDC)) { debug("SPL: Already switched - aborting\n"); hang(); } +#endif
mxs_enable_4p2_dcdc_input(1);
@@ -576,6 +650,14 @@ static void mxs_power_enable_4p2(void) mxs_power_init_4p2_regulator();
/* Shutdown battery (none present) */ +#ifdef CONFIG_SYS_MXS_VDD5V_ONLY + clrbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_BO_MASK); + writel(POWER_CTRL_DCDC4P2_BO_IRQ, + &power_regs->hw_power_ctrl_clr); + writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, + &power_regs->hw_power_ctrl_set); +#else if (!mxs_is_batt_ready()) { clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK); @@ -584,6 +666,7 @@ static void mxs_power_enable_4p2(void) writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr); } +#endif
mxs_power_init_dcdc_4p2_source();
@@ -661,6 +744,7 @@ static void mxs_powerdown(void) &power_regs->hw_power_reset); }
+#ifndef CONFIG_SYS_MXS_VDD5V_ONLY /** * mxs_batt_boot() - Configure the power block to boot from battery input * @@ -714,6 +798,7 @@ static void mxs_batt_boot(void)
mxs_power_enable_4p2(); } +#endif
/** * mxs_handle_5v_conflict() - Test if the 5V input is reliable @@ -757,6 +842,7 @@ static void mxs_handle_5v_conflict(void) break; }
+#ifndef CONFIG_SYS_MXS_VDD5V_ONLY /* * TODO: I can't see this being reached. We'll either * powerdown or boot from a stable 5V supply. @@ -766,6 +852,7 @@ static void mxs_handle_5v_conflict(void) mxs_batt_boot(); break; } +#endif } }
@@ -803,6 +890,7 @@ static void mxs_5v_boot(void) mxs_handle_5v_conflict(); }
+#ifndef CONFIG_SYS_MXS_VDD5V_ONLY /** * mxs_init_batt_bo() - Configure battery brownout threshold * @@ -824,6 +912,7 @@ static void mxs_init_batt_bo(void) writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr); writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr); } +#endif
/** * mxs_switch_vddd_to_dcdc_source() - Switch VDDD rail to DC-DC converter @@ -858,7 +947,12 @@ static void mxs_switch_vddd_to_dcdc_source(void) */ static void mxs_power_configure_power_source(void) { +#ifndef CONFIG_SYS_MXS_VDD5V_ONLY int batt_ready, batt_good; +#else + struct mxs_rtc_regs *rtc_regs = + (struct mxs_rtc_regs *)MXS_RTC_BASE; +#endif struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; struct mxs_lradc_regs *lradc_regs = @@ -868,6 +962,44 @@ static void mxs_power_configure_power_source(void)
mxs_src_power_init();
+#ifdef CONFIG_SYS_MXS_VDD5V_ONLY + /* + * device configured for no source to DCDC_BATT input (5V only power + * source). This boot option doesn't waste time looking for a good + * battery. Battery powered operation and automatic voltage + * measurements are disabled. + */ + + /* TODO: Find out what the purpose of these two lines is */ + setbits_le32(&rtc_regs->hw_rtc_persistent1, + TC_PERSISTENT1_GENERAL_USB_BOOT_PLAYER); + clrbits_le32(&rtc_regs->hw_rtc_persistent1, + RTC_PERSISTENT1_GENERAL_ENUM_500MA_2X); + + /* + * Disable automatic battery voltage measurements which seem + * unnecessary for this configuration. + */ + debug("SPL: Disabling automatic battery voltage measurements\n"); + setbits_le32(&power_regs->hw_power_battmonitor, + POWER_BATTMONITOR_EN_BATADJ); + writel(LRADC_CONVERSION_AUTOMATIC, + &lradc_regs->hw_lradc_conversion_clr); + writel(525 << POWER_BATTMONITOR_BATT_VAL_OFFSET, + &power_regs->hw_power_battmonitor); + + clrsetbits_le32(&power_regs->hw_power_battmonitor, + POWER_BATTMONITOR_BRWNOUT_LVL_MASK, + BATTERY_BRWNOUT_BITFIELD_VALUE << + POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET); + mxs_5v_boot(); + + /* + * TODO: Do not switch CPU clock to PLL if we are VDD5V is sourced + * from USB VBUS + */ + mxs_power_clock2pll(); +#else if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { batt_ready = mxs_is_batt_ready(); if (batt_ready) { @@ -896,6 +1028,7 @@ static void mxs_power_configure_power_source(void) mxs_power_clock2pll();
mxs_init_batt_bo(); +#endif
mxs_switch_vddd_to_dcdc_source();
@@ -1197,9 +1330,24 @@ void mxs_power_init(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; +#ifdef CONFIG_SYS_MXS_VDD5V_ONLY + struct mxs_pinctrl_regs *pinctrl_regs = + (struct mxs_pinctrl_regs *)MXS_PINCTRL_BASE; + struct mxs_lradc_regs *lradc_regs = + (struct mxs_lradc_regs *)MXS_LRADC_BASE; +#endif
debug("SPL: Initialising Power Block\n");
+#ifdef CONFIG_SYS_MXS_VDD5V_ONLY + debug("SPL: Configured for VDD 5V only (no battery)\n"); + /* Set high drive strength to SSP0 */ + clrsetbits_le32(&pinctrl_regs->hw_pinctrl_drive8, + 0x33333333, 0x22222222); + clrsetbits_le32(&pinctrl_regs->hw_pinctrl_drive9, + 0x333, 0x222); +#endif + mxs_ungate_power();
mxs_power_clock2xtal(); @@ -1215,12 +1363,26 @@ void mxs_power_init(void) debug("SPL: Setting VDDIO to 3V3 (brownout @ 3v15)\n"); mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
+#ifdef CONFIG_SYS_MXS_VDD5V_ONLY + setbits_le32(&power_regs->hw_power_vddioctrl, + 0x7 << POWER_VDDIOCTRL_BO_OFFSET_OFFSET); + clrbits_le32(&power_regs->hw_power_vddioctrl, + 0x1 << POWER_VDDIOCTRL_BO_OFFSET_OFFSET); + + debug("SPL: Setting VDDD to 1V35 (brownout @ 1v2)\n"); + mxs_power_set_vddx(&mxs_vddd_cfg, 1350, 1200); +#ifdef CONFIG_MX23 + debug("SPL: Setting VDDMEM to 3V3 (brownout @ 3v15)\n"); + mxs_power_set_vddx(&mxs_vddmem_cfg, 3300, 3150); +#endif +#else 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 +#endif writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ | POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ | @@ -1228,6 +1390,28 @@ void mxs_power_init(void)
writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
+#ifdef CONFIG_SYS_MXS_VDD5V_ONLY +#if defined(CONFIG_MX28) + /* + * On i.MX28, a new bit has been added to allow automatic hardware + * shutdown if VDD4P2 browns out. If we permanently only have a VDD5V + * source, we want to enable this bit. For devices with dead batteries, + * we could also temporarily set this bit until the kernel battery + * charger sufficiently charges the battery but we won't do this for + * now as the latest release kernel versions aren't aware of it + * and thus don't handle the proper setting/clearing of this bit. + */ + writel(1<<7, &power_regs->hw_power_refctrl); +#endif + setbits_le32(&power_regs->hw_power_battmonitor, + POWER_BATTMONITOR_PWDN_BATTBRNOUT_5VDETECT_EN | + POWER_BATTMONITOR_EN_BATADJ | + POWER_BATTMONITOR_PWDN_BATTBRNOUT); + clrsetbits_le32(&lradc_regs->hw_lradc_ctrl4, + LRADC_CTRL4_LRADC6SELECT_MASK, + LRADC_CTRL4_LRADC6SELECT_CHANNEL6); +#endif + early_delay(1000); }
diff --git a/doc/README.mxs b/doc/README.mxs index ed2e568..ba0408e 100644 --- a/doc/README.mxs +++ b/doc/README.mxs @@ -185,6 +185,16 @@ NOTE: If the user needs to adjust the start sector, the "mxsboot" tool contains a "-p" switch for that purpose. The "-p" switch takes the sector number as an argument.
+3.1) MXS Specific Configuration Variables +----------------------------------------- +The following C pre-processor defines can be included in the board specific +configuration file: + +CONFIG_SYS_MXS_VDD5V_ONLY - Board designs implementing a power circuit +consisting of a 5V DC supply only (i.e. without a battery), as per Section +4.1.2 of Freescale Semiconductor Application Note AN4199 MUST include this +configuration variable in the board configuration file + 4) Installation of U-Boot into NAND flash on a MX28 based board ---------------------------------------------------------------

Hi Guys,
@@ -868,6 +962,44 @@ static void mxs_power_configure_power_source(void)
mxs_src_power_init();
+#ifdef CONFIG_SYS_MXS_VDD5V_ONLY
- /*
* device configured for no source to DCDC_BATT input (5V only power
* source). This boot option doesn't waste time looking for a good
* battery. Battery powered operation and automatic voltage
* measurements are disabled.
*/
- /* TODO: Find out what the purpose of these two lines is */
- setbits_le32(&rtc_regs->hw_rtc_persistent1,
TC_PERSISTENT1_GENERAL_USB_BOOT_PLAYER);
Never make simple, last minute changes without testing them...
This should be RTC_PERSISTENT1_GENERAL_USB_BOOT_PLAYER
I'll fix it in the next version
- clrbits_le32(&rtc_regs->hw_rtc_persistent1,
RTC_PERSISTENT1_GENERAL_ENUM_500MA_2X);
Regards,
Graeme

On Wed, Jan 21, 2015 at 10:03 AM, Graeme Russ gruss@tss-engineering.com wrote:
Never make simple, last minute changes without testing them...
This should be RTC_PERSISTENT1_GENERAL_USB_BOOT_PLAYER
I'll fix it in the next version
This looks great, Graeme! Thanks for working on upstream this.
Regards,
Fabio Estevam

On Wednesday, January 21, 2015 at 12:55:15 PM, Graeme Russ wrote:
Section 4.1.2 of Freescale Application Note AN4199 describes the configuration required to operate the mx28 from a 5V source without a battery. This patch implements the changes to the Freescale bootlets which allow this configuration to properly boot the mx28 processor
Signed-off-by: Graeme Russ gruss@tss-engineering.com
I have to admit I don't really like this boatload of new ifdeffery. Isn't it possible to detect if the battery is or isn't connected at runtime ?
Best regards, Marek Vasut

Hi Marek,
On 22/01/15 10:27, Marek Vasut wrote:
On Wednesday, January 21, 2015 at 12:55:15 PM, Graeme Russ wrote:
Section 4.1.2 of Freescale Application Note AN4199 describes the configuration required to operate the mx28 from a 5V source without a battery. This patch implements the changes to the Freescale bootlets which allow this configuration to properly boot the mx28 processor
Signed-off-by: Graeme Russ gruss@tss-engineering.com
I have to admit I don't really like this boatload of new ifdeffery. Isn't it possible to detect if the battery is or isn't connected at runtime ?
I doubt it. If you look at the circuit in AN4199, the BATTERY and DCDC_BATT pins are hooked up to VDD4P2 via 1k resistors. What the mx28 does internally is measure the voltages on the VDD5V and either BATTERY/DCDC_BATT pins and decides which to use (preferencing the battery unless it goes below a threshold).
Without this patch, the mx28 sees a good battery voltage and switches to battery mode which is drawn of DCDC4P2 which is now trying to be driven by the battery input which, of course, will not work.
So the only way to figure it out at runtime would be to have the battery inputs at 0v so you could see there is no battery.
The only other option would be to use a GPIO pin
Regards,
Graeme

Hi Graeme,
On Wed, Jan 21, 2015 at 9:55 AM, Graeme Russ gruss@tss-engineering.com wrote:
Section 4.1.2 of Freescale Application Note AN4199 describes the configuration required to operate the mx28 from a 5V source without a battery. This patch implements the changes to the Freescale bootlets which allow this configuration to properly boot the mx28 processor
Signed-off-by: Graeme Russ gruss@tss-engineering.com
arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 190 +++++++++++++++++++++++++++- doc/README.mxs | 10 ++
Damien posted today a new version of this patch in the imx community, which is a lot simpler.
Could you please try it?
Thanks

On Thursday, January 22, 2015 at 01:42:10 PM, Fabio Estevam wrote:
Hi Graeme,
On Wed, Jan 21, 2015 at 9:55 AM, Graeme Russ gruss@tss-engineering.com
wrote:
Section 4.1.2 of Freescale Application Note AN4199 describes the configuration required to operate the mx28 from a 5V source without a battery. This patch implements the changes to the Freescale bootlets which allow this configuration to properly boot the mx28 processor
Signed-off-by: Graeme Russ gruss@tss-engineering.com
arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 190 +++++++++++++++++++++++++++- doc/README.mxs | 10 ++
Damien posted today a new version of this patch in the imx community, which is a lot simpler.
Guys, we have U-Boot mailing list for posting U-Boot patches. It'd be nice if you could use it to prevent fragmentation of efforts ;-)
But of course, the effort is appreciated, just a rant.
Best regards, Marek Vasut

Hi Fabio,
On 22/01/15 23:42, Fabio Estevam wrote:
Hi Graeme,
On Wed, Jan 21, 2015 at 9:55 AM, Graeme Russ gruss@tss-engineering.com wrote:
Section 4.1.2 of Freescale Application Note AN4199 describes the configuration required to operate the mx28 from a 5V source without a battery. This patch implements the changes to the Freescale bootlets which allow this configuration to properly boot the mx28 processor
Signed-off-by: Graeme Russ gruss@tss-engineering.com
arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 190 +++++++++++++++++++++++++++- doc/README.mxs | 10 ++
Damien posted today a new version of this patch in the imx community, which is a lot simpler.
Could you please try it?
I've taken a look at it, but decided to leave this patch as-is. Here is what I wrote on the Freescale forum:
~~~~ I'm going to keep my U-Boot patch mostly as-is for a few reasons: - The patch disables battery voltage measurement when there is no battery - The patch disables all code paths relating to booting from battery - The power block configuration is based primarily on the Fressscale bootlets which I think should be retained unless we can come up with some pretty clear and convincing arguments as to why an alternative approach is better
I think there is scope for some refactoring of the power block setup code in U-Boot, but for now I think it best to leave it as close to the bootlet code sequence as practical ~~~~
Regards,
Graeme

On Fri, Jan 23, 2015 at 12:58 AM, Graeme Russ gruss@tss-engineering.com wrote:
I've taken a look at it, but decided to leave this patch as-is. Here is what I wrote on the Freescale forum:
Still curious: does the updated patch from Damien allow your system to boot or not?
I'm going to keep my U-Boot patch mostly as-is for a few reasons: - The patch disables battery voltage measurement when there is no battery - The patch disables all code paths relating to booting from battery - The power block configuration is based primarily on the Fressscale bootlets which I think should be retained unless we can come up with some pretty clear and convincing arguments as to why an alternative approach is better
,but my understanding is that the original patch does not work on Damien's board as it gives DDR errors.
Regards,
Fabio Estevam

Hi Fabio,
On 23/01/15 14:01, Fabio Estevam wrote:
On Fri, Jan 23, 2015 at 12:58 AM, Graeme Russ gruss@tss-engineering.com wrote:
I've taken a look at it, but decided to leave this patch as-is. Here is what I wrote on the Freescale forum:
Still curious: does the updated patch from Damien allow your system to boot or not?
It is on today's todo list
I'm going to keep my U-Boot patch mostly as-is for a few reasons: - The patch disables battery voltage measurement when there is no battery - The patch disables all code paths relating to booting from battery - The power block configuration is based primarily on the Fressscale bootlets which I think should be retained unless we can come up with some pretty clear and convincing arguments as to why an alternative approach is better
,but my understanding is that the original patch does not work on Damien's board as it gives DDR errors.
I thought the DDR errors were fixed with Damien's DDR patch. Damien, can you please confirm?
Regards,
Graeme

On Fri, Jan 23, 2015 at 1:27 AM, Graeme Russ gruss@tss-engineering.com wrote:
I thought the DDR errors were fixed with Damien's DDR patch. Damien, can you please confirm?
His response in the forum was:
"About the patch posted on January, 6th, you can simply delete it, and empty your recycle bin . It generate DDR errors (I searched a long time in spl_mem_init to find why my DDR was not stable, but it was not a DDR configuration mistake, but a power mistake caused by my patch)."
Regards,
Fabio Estevam

Hi Fabio,
On 23/01/15 14:49, Fabio Estevam wrote:
On Fri, Jan 23, 2015 at 1:27 AM, Graeme Russ gruss@tss-engineering.com wrote:
I thought the DDR errors were fixed with Damien's DDR patch. Damien, can you please confirm?
His response in the forum was:
"About the patch posted on January, 6th, you can simply delete it, and empty your recycle bin . It generate DDR errors (I searched a long time in spl_mem_init to find why my DDR was not stable, but it was not a DDR configuration mistake, but a power mistake caused by my patch)."
Ah - I missed that - my bad.
I'll check if his newer patch works. If it does, I'll implement it instead. Best to make these kind of changes one small step at a time :)
Regards,
Graeme

When booting in JTAG mode, there is no way to use soft break-points, and no way of knowing when SPL has finished executing (so the user can issue a 'halt' command to load u-boot.bin for example)
Add a debug output and simple loop to stop execution at the completion of the SPL initialisation as a pseudo break-point when booting in JTAG mode
Signed-off-by: Graeme Russ gruss@tss-engineering.com ---
arch/arm/cpu/arm926ejs/mxs/spl_boot.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index 2a5f817..7bfc623 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c @@ -157,6 +157,12 @@ 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 == 0x06) { + debug("SPL: Waiting for JTAG user\n"); + asm volatile ("x: b x"); + } }
/* Support aparatus */

On 21.01.2015 12:55, Graeme Russ wrote:
When booting in JTAG mode, there is no way to use soft break-points, and no way of knowing when SPL has finished executing (so the user can issue a 'halt' command to load u-boot.bin for example)
Add a debug output and simple loop to stop execution at the completion of the SPL initialisation as a pseudo break-point when booting in JTAG mode
Signed-off-by: Graeme Russ gruss@tss-engineering.com
arch/arm/cpu/arm926ejs/mxs/spl_boot.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index 2a5f817..7bfc623 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c @@ -157,6 +157,12 @@ void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr, data->boot_mode_idx = bootmode;
mxs_power_wait_pswitch();
Nitpicking, but please don't add 2 empty lines.
- if (mxs_boot_modes[data->boot_mode_idx].boot_pads == 0x06) {
Would it be possible to add a macro here instead of using this fixed 0x06?
debug("SPL: Waiting for JTAG user\n");
asm volatile ("x: b x");
- }
Thanks. Stefan

mxs_power_clock2pll() does not actually switch the CPU clock to the PLL. All it does is power-up the PLL and set the CLKCTRL_CLKSEQ_BYPASS_CPU bit (which was already set by mxs_power_clock2xtal() anyway)
spl_mem_init.c sets up the fractional divisor (which is required to run the CPU from the PLL) and clears the CLKCTRL_CLKSEQ_BYPASS_CPU bit (which switches the CPU clock to the PLL)
It makes more sense to power-up the PLL in spl_mem_init.c. While moving the PLL power-up, we may as well properly configure how the PLL lock is started and confirmed
Signed-off-by: Graeme Russ gruss@tss-engineering.com ---
arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c | 31 ++++++++++++++++++++ arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 45 ----------------------------- 2 files changed, 31 insertions(+), 45 deletions(-)
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c index a744e5d..af4ed8c 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c @@ -340,10 +340,41 @@ static void mx28_mem_init(void) } #endif
+/** + * mxs_mem_powerup_pll() - Powerup PLL0 + * + * This function turns on power to PLL0. The CPU clock will be switched to + * PLL0 after the fractional divider and SDRAM have been configured. + */ +static void mxs_mem_powerup_pll(void) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + + /* Power up PLL0 */ + debug("SPL: Powering up PLL0\n"); + setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0, + CLKCTRL_PLL0CTRL0_POWER); + + /* Toggle FORCE_LOCK to initiate the PLL lock procedure */ + setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl1, + CLKCTRL_PLL0CTRL1_FORCE_LOCK); + + clrbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl1, + CLKCTRL_PLL0CTRL1_FORCE_LOCK); + + /* Wait until the PLL has a stable lock - takes ~50us */ + while (!(readl(&clkctrl_regs->hw_clkctrl_pll0ctrl1) & + CLKCTRL_PLL0CTRL1_LOCK)) + ; +} + void mxs_mem_init(void) { early_delay(11000);
+ mxs_mem_powerup_pll(); + mxs_mem_init_clock();
mxs_mem_setup_vdda(); diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c index e469381..7267fd5 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c @@ -50,39 +50,6 @@ static void mxs_power_clock2xtal(void) }
/** - * mxs_power_clock2pll() - Switch CPU core clock source to PLL - * - * This function switches the CPU core clock from 24MHz XTAL oscilator - * to PLL. This can only be called once the PLL has re-locked and once - * the PLL is stable after reconfiguration. - */ -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); -} - -/** * mxs_power_set_auto_restart() - Set the auto-restart bit * * This function ungates the RTC block and sets the AUTO_RESTART @@ -993,12 +960,6 @@ static void mxs_power_configure_power_source(void) BATTERY_BRWNOUT_BITFIELD_VALUE << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET); mxs_5v_boot(); - - /* - * TODO: Do not switch CPU clock to PLL if we are VDD5V is sourced - * from USB VBUS - */ - mxs_power_clock2pll(); #else if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { batt_ready = mxs_is_batt_ready(); @@ -1021,12 +982,6 @@ 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(); #endif

On Wednesday, January 21, 2015 at 12:55:17 PM, Graeme Russ wrote:
mxs_power_clock2pll() does not actually switch the CPU clock to the PLL. All it does is power-up the PLL and set the CLKCTRL_CLKSEQ_BYPASS_CPU bit (which was already set by mxs_power_clock2xtal() anyway)
spl_mem_init.c sets up the fractional divisor (which is required to run the CPU from the PLL) and clears the CLKCTRL_CLKSEQ_BYPASS_CPU bit (which switches the CPU clock to the PLL)
It makes more sense to power-up the PLL in spl_mem_init.c. While moving the PLL power-up, we may as well properly configure how the PLL lock is started and confirmed
Signed-off-by: Graeme Russ gruss@tss-engineering.com
arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c | 31 ++++++++++++++++++++ arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 45 ----------------------------- 2 files changed, 31 insertions(+), 45 deletions(-)
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c index a744e5d..af4ed8c 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c @@ -340,10 +340,41 @@ static void mx28_mem_init(void) } #endif
+/**
- mxs_mem_powerup_pll() - Powerup PLL0
- This function turns on power to PLL0. The CPU clock will be switched to
- PLL0 after the fractional divider and SDRAM have been configured.
- */
+static void mxs_mem_powerup_pll(void) +{
- struct mxs_clkctrl_regs *clkctrl_regs =
(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
- /* Power up PLL0 */
- debug("SPL: Powering up PLL0\n");
- setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
CLKCTRL_PLL0CTRL0_POWER);
- /* Toggle FORCE_LOCK to initiate the PLL lock procedure */
- setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl1,
CLKCTRL_PLL0CTRL1_FORCE_LOCK);
Are you positive that this write really hits the hardware ? You might want to read the register back before issuing another write to it.
- clrbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl1,
CLKCTRL_PLL0CTRL1_FORCE_LOCK);
- /* Wait until the PLL has a stable lock - takes ~50us */
- while (!(readl(&clkctrl_regs->hw_clkctrl_pll0ctrl1) &
CLKCTRL_PLL0CTRL1_LOCK))
;
Use mxs_wait_mask_ here I'd say. [...]

Signed-off-by: Graeme Russ gruss@tss-engineering.com ---
arch/arm/Kconfig | 13 ++ board/reachtech/g2c1/Kconfig | 15 ++ board/reachtech/g2c1/MAINTAINERS | 9 + board/reachtech/g2c1/Makefile | 12 ++ board/reachtech/g2c1/README | 58 +++++ board/reachtech/g2c1/g2c1.c | 79 +++++++ board/reachtech/g2c1/spl_boot.c | 452 +++++++++++++++++++++++++++++++++++++++ configs/g2c1_defconfig | 3 + include/configs/g2c1.h | 303 ++++++++++++++++++++++++++ 9 files changed, 944 insertions(+) create mode 100644 board/reachtech/g2c1/Kconfig create mode 100644 board/reachtech/g2c1/MAINTAINERS create mode 100644 board/reachtech/g2c1/Makefile create mode 100644 board/reachtech/g2c1/README create mode 100644 board/reachtech/g2c1/g2c1.c create mode 100644 board/reachtech/g2c1/spl_boot.c create mode 100644 configs/g2c1_defconfig create mode 100644 include/configs/g2c1.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5eb1d03..320041e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -278,6 +278,18 @@ config TARGET_XFI3 select CPU_ARM926EJS select SUPPORT_SPL
+config TARGET_G2C1 + bool "Support ReachTech G2C1" + select CPU_ARM926EJS + select SUPPORT_SPL + help + This is the Reachtech G2C1 development board. It contains a + Freescale MX28 SoC, 128MB DDR2 SDRAM, 128MB SLC NAND, 1x Ethernet + port, 2x USB Host ports, 1x USB OTG port, 1x RS-232 Debug port, + 1x RS-232 User port, 2x RS485 ports, Onboard audio, LCD Touch + screen interface, SD Card slot, I2C and SPI (with 2x slave select + lines) interfaces, CAN interface, and 8 GPIO (I2C slave interface) + config TARGET_M28EVK bool "Support m28evk" select CPU_ARM926EJS @@ -940,6 +952,7 @@ source "board/phytec/pcm051/Kconfig" source "board/ppcag/bg0900/Kconfig" source "board/pxa255_idp/Kconfig" source "board/raspberrypi/rpi/Kconfig" +source "board/reachtech/g2c1/Kconfig" source "board/ronetix/pm9261/Kconfig" source "board/ronetix/pm9263/Kconfig" source "board/ronetix/pm9g45/Kconfig" diff --git a/board/reachtech/g2c1/Kconfig b/board/reachtech/g2c1/Kconfig new file mode 100644 index 0000000..5ef821f --- /dev/null +++ b/board/reachtech/g2c1/Kconfig @@ -0,0 +1,15 @@ +if TARGET_G2C1 + +config SYS_BOARD + default "g2c1" + +config SYS_VENDOR + default "reachtech" + +config SYS_SOC + default "mxs" + +config SYS_CONFIG_NAME + default "g2c1" + +endif diff --git a/board/reachtech/g2c1/MAINTAINERS b/board/reachtech/g2c1/MAINTAINERS new file mode 100644 index 0000000..e4e948d --- /dev/null +++ b/board/reachtech/g2c1/MAINTAINERS @@ -0,0 +1,9 @@ +G2C1 BOARD +M: Graeme Russ gruss@tss-engineering.com +S: Maintained +F: board/reachtech/g2c1/ +F: include/configs/mx28evk.h +F: configs/g2c1_defconfig +F: configs/g2c1_auart_console_defconfig +F: configs/g2c1_nand_defconfig +F: configs/g2c1_spi_defconfig diff --git a/board/reachtech/g2c1/Makefile b/board/reachtech/g2c1/Makefile new file mode 100644 index 0000000..9bb55e8 --- /dev/null +++ b/board/reachtech/g2c1/Makefile @@ -0,0 +1,12 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifndef CONFIG_SPL_BUILD +obj-y := g2c1.o +else +obj-y := spl_boot.o +endif diff --git a/board/reachtech/g2c1/README b/board/reachtech/g2c1/README new file mode 100644 index 0000000..41c7984 --- /dev/null +++ b/board/reachtech/g2c1/README @@ -0,0 +1,58 @@ +ReachTech G2C1 +================== + +Supported hardware: ReachTech G2C1 is supported in U-boot. + +Files of the MX28EVK port +-------------------------- + +arch/arm/cpu/arm926ejs/mxs/ - The CPU support code for the Freescale i.MX28 +arch/arm/include/asm/arch-mxs/ - Header files for the Freescale i.MX28 +board/reachtech/g2c1/ - G2C1 board specific files +include/configs/g2c1.h - G2C1 configuration file + +Jumper configuration +--------------------- + +To boot G2C1 from an SD card, set the boot mode DIP switches as: + + * Boot Mode Select: 1 0 0 1 (Boot from SD card Slot 0 - U42) + * JTAG PSWITCH RESET: To the right (reset disabled) + * Battery Source: Down + * Wall 5V: Up + * VDD 5V: To the left (off) + * Hold Button: Down (off) + +To boot MX28EVK from SPI NOR flash, set the boot mode DIP switches as: + + * Boot Mode Select: 0 0 1 0 (Boot from SSP2) + * JTAG PSWITCH RESET: To the right (reset disabled) + * Battery Source: Down + * Wall 5V: Up + * VDD 5V: To the left (off) + * Hold Button: Down (off) + +Environment Storage +------------------- + +There are three targets for mx28evk: + +"make mx28evk_config" - store environment variables into MMC + +or + +"make mx28evk_nand_config" - store environment variables into NAND flash + +or + +"make mx28evk_spi_config" - store enviroment variables into SPI NOR flash + +Choose the target accordingly. + +mx28evk does not come with SPI NOR flash populated from the factory either. +It is possible to solder a SOIC memory on U49 or use a DIP8 on J89. +To get SPI communication to work R320, R321,R322 and C178 need to be populated. +Look in the schematics for the proper component values. + +Follow the instructions from doc/README.mxs to generate a bootable SD card or +to generate a binary to be flashed into SPI NOR. diff --git a/board/reachtech/g2c1/g2c1.c b/board/reachtech/g2c1/g2c1.c new file mode 100644 index 0000000..5bf437d --- /dev/null +++ b/board/reachtech/g2c1/g2c1.c @@ -0,0 +1,79 @@ +/* + * Reachtech G2C1 board + * + * Copyright (C) 2015 Graeme Russ gruss@tss-engineering.com + * on behalf of DENX Software Engineering GmbH + * + * Author: Graeme Russ gruss@tss-engineering.com + * + * Based on m28evk.c: + * Copyright (C) 2011 Marek Vasut marek.vasut@gmail.com + * on behalf of DENX Software Engineering GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/iomux-mx28.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <linux/mii.h> +#include <miiphy.h> +#include <netdev.h> +#include <errno.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Functions + */ +int board_early_init_f(void) +{ + /* IO0 clock at 480MHz */ + mxs_set_ioclk(MXC_IOCLK0, 480000); + /* IO1 clock at 480MHz */ + mxs_set_ioclk(MXC_IOCLK1, 480000); + + /* SSP0 clock at 96MHz */ + mxs_set_sspclk(MXC_SSPCLK0, 96000, 0); + /* SSP2 clock at 160MHz */ + mxs_set_sspclk(MXC_SSPCLK2, 160000, 0); + + /* Turn the Run LED On */ + gpio_direction_output(MX28_PAD_SPDIF__GPIO_3_27, 0); + + /* Write Protect NAND */ + gpio_direction_output(MX28_PAD_GPMI_RESETN__GPIO_0_28, 0); + + /* Power on LCD */ + gpio_direction_output(MX28_PAD_LCD_RESET__GPIO_3_30, 1); + + /* Turn on DEBUG port CTS */ + gpio_direction_output(MX28_PAD_SSP0_DATA5__GPIO_2_5, 1); + + return 0; +} + +int dram_init(void) +{ + return mxs_dram_init(); +} + +int board_init(void) +{ + /* Adress of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; + + return 0; +} + +#ifdef CONFIG_CMD_MMC + +int board_mmc_init(bd_t *bis) +{ + return mxsmmc_initialize(bis, 0, NULL /* g2c1_mmc_wp */, NULL); +} +#endif diff --git a/board/reachtech/g2c1/spl_boot.c b/board/reachtech/g2c1/spl_boot.c new file mode 100644 index 0000000..25ee0e2 --- /dev/null +++ b/board/reachtech/g2c1/spl_boot.c @@ -0,0 +1,452 @@ +/* + * DENX M28 Boot setup + * + * Copyright (C) 2011 Marek Vasut marek.vasut@gmail.com + * on behalf of DENX Software Engineering GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <config.h> +#include <asm/io.h> +#include <asm/arch/iomux-mx28.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h> + +/* + * Bank. SoC + * Pin Pin Function Comments + * ---------------------------------------------------------------------- + * 0.0 U8 GPMI_D0 + * 0.1 T8 GPMI_D1 + * 0.2 R8 GPMI_D2 + * 0.3 U7 GPMI_D3 + * 0.4 T7 GPMI_D4 + * 0.5 R7 GPMI_D5 + * 0.6 U6 GPMI_D6 + * 0.7 T6 GPMI_D7 + * 0.8 - - Reserved + * 0.9 - - Reserved + * 0.10 - - Reserved + * 0.11 - - Reserved + * 0.12 - - Reserved + * 0.13 - - Reserved + * 0.14 - - Reserved + * 0.15 - - Reserved + * 0.16 N7 GPMI_CE0N + * 0.17 N9 GPMI_CE1N + * 0.18 M7 GPIO_INTERUPT TODO: GPIO, Input, 3V3, 4mA, + * External Pullup + * 0.19 M9 DISP_ON TODO: GPIO, (Input or Output?), ?V?, + * ?mA + * 0.20 N6 GPMI_READY0 + * 0.21 N8 GPMI_READY1 + * 0.22 M8 CAN0_TX + * 0.23 L8 CAN0_RX + * 0.24 R6 GPMI_RDN + * 0.25 P8 GPMI_WRN + * 0.26 P6 GPMI_ALE + * 0.27 P7 GPMI_CLE + * 0.28 L9 NAND_WP GPIO, 3V3, 4mA, External Pullup, + * Active Low + * 0.29 - - Reserved + * 0.30 - - Reserved + * 0.31 - - Reserved + * + * Bank. SoC + * Pin Pin Function Comments + * ---------------------------------------------------------------------- + * 1.0 K2 LCD_D0 + * 1.1 K3 LCD_D1 + * 1.2 L2 LCD_D2 + * 1.3 L3 LCD_D3 + * 1.4 M2 LCD_D4 + * 1.5 M3 LCD_D5 + * 1.6 N2 LCD_D6 + * 1.7 P1 LCD_D7 + * 1.8 P2 LCD_D8 + * 1.9 P3 LCD_D9 + * 1.10 R1 LCD_D10 + * 1.11 R2 LCD_D11 + * 1.12 T1 LCD_D12 + * 1.13 T2 LCD_D13 + * 1.14 U2 LCD_D14 + * 1.15 U3 LCD_D15 + * 1.16 T3 LCD_D16 + * 1.17 R3 LCD_D17 + * 1.18 U4 LCD_D18 + * 1.19 T4 LCD_D19 + * 1.20 R4 LCD_D20 + * 1.21 U5 LCD_D21 + * 1.22 T5 LCD_D22 + * 1.23 R5 LCD_D23 + * 1.24 P4 LCD_VSYNC + * 1.25 K1 LCD_HSYNC + * 1.26 M4 LCD_DOTCLK + * 1.27 P5 LCD_ENABLE + * 1.28 L1 LCD_VSYNC Not Connected + * 1.29 M1 LCD_HSYNC Not Connected + * 1.30 N1 LCD_DOTCLK Not Connected + * 1.31 N5 LCD_ENABLE Not Connected + * + * Bank. SoC + * Pin Pin Function Comments + * ---------------------------------------------------------------------- + * 2.0 B6 SSP0_D0 + * 2.1 C6 SSP0_D1 + * 2.2 D6 SSP0_D2 + * 2.3 A5 SSP0_D3 + * 2.4 B5 USB_0_PWR_EN GPIO, Output, 3V3, 4mA, + * External Pulldown + * 2.5 C5 DUART_CTS GPIO, Output, 3V3, 4mA, + * External Pullup + * 2.6 D5 ENET_INTERUPT TODO: GPIO, Input, 3V3, 4mA, + * External Pullup + * 2.7 B4 USB_RESET_B TODO: GPIO, Output, 3V3, 4mA, + * External Pullup + * 2.8 A4 SSP0_CMD + * 2.9 D10 SSP0_CARD_DTCT + * 2.10 A6 SSP0_SCK + * 2.11 - - Reserved + * 2.12 B1 SSP1_SCK Not Connected + * 2.13 C1 SSP1_CMD Not Connected + * 2.14 D1 SSP1_DATA0 Not Connected + * 2.15 E1 SSP1_DATA3 Not Connected + * 2.16 A3 SSP2_SCK TODO: SPI Clock + * 2.17 C3 SSP2_MOSI TODO: SPI MOSI + * 2.18 B3 SSP2_MISO TODO: SPI MISO + * 2.19 C4 SSP2_SS0 TODO: SPI Slave Select 0 + * 2.20 D3 SSP2_SS1 TODO: SPI Slave Select 1 + * 2.21 D4 USB0_OVRCURRENT TODO + * 2.22 - - Reserved + * 2.23 - - Reserved + * 2.24 A2 SSP3_SCK Not Connected + * 2.25 C2 SSP3_MOSI Not Connected + * 2.26 B2 SSP3_MISO Not Connected + * 2.27 D2 SSP3_SS0 Not Connected + * 2.28 - - Reserved + * 2.29 - - Reserved + * 2.30 - - Reserved + * 2.31 - - Reserved + * + * Bank. SoC + * Pin Pin Function Comments + * ---------------------------------------------------------------------- + * 3.0 G5 AUART0_RX TODO: RS485 hardware issue + * 3.1 H5 AUART0_TX TODO: RS485 hardware issue + * 3.2 J6 BACKLIGHT_EN GPIO, Output, 3V3, 4mA, + * External Pulldown + * 3.3 J7 AUART0_RTS TODO: RS485 hardware issue + * 3.4 L4 AUART1_RX + * 3.5 K4 AUART1_TX + * 3.6 K5 AUART1_CTS Not Connected + * 3.7 J5 AUART1_RTS Not Connected + * 3.8 F6 AUART2_RX Not Connected + * 3.9 F5 AUART2_TX Not Connected + * 3.10 H6 AUART2_CTS Not Connected + * 3.11 H7 AUART2_RTS Not Connected + * 3.12 M5 AUART3_RX Not Connected + * 3.13 L5 AUART3_TX Not Connected + * 3.14 L6 AUART3_CTS Not Connected + * 3.15 K6 AUART3_RTS Not Connected + * 3.16 K7 I2C1_SCL + * 3.17 L7 I2C1_SDA + * 3.18 K8 USB0_ID TODO + * 3.19 - - Reserved + * 3.20 G7 ENET_FEC_RESET GPIO, Output, 3V3, 4mA, + * External Pullup, Active Low + * 3.21 G6 AUART4_RTS TODO: RS485 hardware issue + * 3.22 F7 AUART4_RX TODO: RS485 hardware issue + * 3.23 E7 AUART4_TX TODO: RS485 hardware issue + * 3.24 C7 DUART_RX + * 3.25 D8 DUART_TX + * 3.26 E8 PWM7 TODO: Onboard Audio (Frequency or + * Volume?) + * 3.27 D7 RUN_LED GPIO, Output, 3V3, Active Low + * 3.28 E9 PWM_3 TODO: LCD Backlight Brightness + * 3.29 E10 PWM_4 TODO: Onboard Audio (Frequency or + * Volume?) + * 3.30 M6 LCD_PWR_EN GPIO, Output, 3V3, 4mA, External Pullup + * 3.31 - - Reserved + * + * Bank. SoC + * Pin Pin Function Comments + * ---------------------------------------------------------------------- + * 4.0 G4 ENET0_MDC 3V3, 4mA, Internal Pullup + * 4.1 H4 ENET0_MDIO 3V3, 4mA, Internal Pullup + * 4.2 E4 ENET0_RX_EN 3V3, 4mA, Internal Pullup + * 4.3 H1 ENET0_RXD0 3V3, 4mA, Internal Pullup + * 4.4 H2 ENET0_RXD1 3V3, 4mA, Internal Pullup + * 4.5 E3 ENET0_TX_CLK Not Connected + * 4.6 F4 ENET0_TX_EN + * 4.7 F1 ENET0_TXD0 + * 4.8 F2 ENET0_TXD1 + * 4.9 J1 ENET0_RX_D2 Not Connected + * 4.10 J2 ENET0_RX_D3 Not Connected + * 4.11 G1 ENET0_TX_D2 Not Connected + * 4.12 G2 ENET0_TX_D2 Not Connected + * 4.13 F3 ENET0_RX_CLK Not Connected + * 4.14 J4 ENET0_COL Not Connected + * 4.15 J3 ENET0_CRS Not Connected + * 4.16 E2 CLKCTRL_ENET + * 4.17 - - Reserved + * 4.18 - - Reserved + * 4.19 - - Reserved + * 4.20 E14 JTAG_RTCK 3V3, 4mA, External Pullup + * 4.21 - - Reserved + * 4.22 - - Reserved + * 4.23 - - Reserved + * 4.24 - - Reserved + * 4.25 - - Reserved + * 4.26 - - Reserved + * 4.27 - - Reserved + * 4.28 - - Reserved + * 4.29 - - Reserved + * 4.30 - - Reserved + * 4.31 - - Reserved + * + * Bank. SoC + * Pin Pin Function Comments + * ---------------------------------------------------------------------- + * 5.0 N16 EMI_DATA0 + * 5.1 M13 EMI_DATA1 + * 5.2 P15 EMI_DATA2 + * 5.3 N14 EMI_DATA3 + * 5.4 P13 EMI_DATA4 + * 5.5 P17 EMI_DATA5 + * 5.6 L14 EMI_DATA6 + * 5.7 M17 EMI_DATA7 + * 5.8 G16 EMI_DATA8 + * 5.9 H15 EMI_DATA9 + * 5.10 G14 EMI_DATA10 + * 5.11 J14 EMI_DATA11 + * 5.12 H13 EMI_DATA12 + * 5.13 H17 EMI_DATA13 + * 5.14 F13 EMI_DATA14 + * 5.15 F17 EMI_DATA15 + * 5.16 R17 EMI_ODT0 + * 5.17 M15 EMI_DQM0 + * 5.18 T17 EMI_ODT1 Not Connected + * 5.19 F15 EMI_DQM1 + * 5.20 L15 EMI_DDR_OPEN_FB + * 5.21 L16/L17 EMI_CLK + * 5.22 K16/K17 EMI_DQS0 + * 5.23 J16/J17 EMI_DQS1 + * 5.24 - - Reserved + * 5.25 - - Reserved + * 5.26 K14 EMI_DDR_OPEN + * 5.27 - - Reserved + * 5.28 - - Reserved + * 5.29 - - Reserved + * 5.30 - - Reserved + * 5.31 - - Reserved + * + * Bank. SoC + * Pin Pin Function Comments + * ---------------------------------------------------------------------- + * 6.0 U15 EMI_ADDR0 + * 6.1 U12 EMI_ADDR1 + * 6.2 U14 EMI_ADDR2 + * 6.3 T11 EMI_ADDR3 + * 6.4 U10 EMI_ADDR4 + * 6.5 R11 EMI_ADDR5 + * 6.6 R9 EMI_ADDR6 + * 6.7 N11 EMI_ADDR7 + * 6.8 U9 EMI_ADDR8 + * 6.9 P10 EMI_ADDR9 + * 6.10 U13 EMI_ADDR10 + * 6.11 T10 EMI_ADDR11 + * 6.12 U11 EMI_ADDR12 + * 6.13 T9 EMI_ADDR13 + * 6.14 N10 EMI_ADDR14 + * 6.15 - - Reserved + * 6.16 T16 EMI_BA0 + * 6.17 T12 EMI_BA1 + * 6.18 N12 EMI_BA2 + * 6.19 U16 EMI_CASN + * 6.20 R16 EMI_RASN + * 6.21 T15 EMI_WEN + * 6.22 P12 EMI_CE0N + * 6.23 P9 EMI_CE1N Not Connected + * 6.24 T13 EMI_CKE + * 6.25 - - Reserved + * 6.26 - - Reserved + * 6.27 - - Reserved + * 6.28 - - Reserved + * 6.29 - - Reserved + * 6.30 - - Reserved + * 6.31 - - Reserved + */ +#define MUX_CONFIG_I2C (MXS_PAD_1V8 | MXS_PAD_4MA | MXS_PAD_NOPULL) +#define MUX_CONFIG_CAN (MXS_PAD_1V8 | MXS_PAD_4MA | MXS_PAD_NOPULL) +#define MUX_CONFIG_LED (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL) +#define MUX_CONFIG_LCD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL) +#define MUX_CONFIG_SSP0 (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_PULLUP) +#define MUX_CONFIG_GPMI (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL) +#define MUX_CONFIG_ENET (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP) +#define MUX_CONFIG_EMI (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_NOPULL) +#define MUX_CONFIG_JTAG (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL) +#define MUX_CONFIG_UART (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL) + +const iomux_cfg_t iomux_setup[] = { + /* Run LED */ + MX28_PAD_SPDIF__GPIO_3_27 | MUX_CONFIG_LED, + + /* JTAG */ + MX28_PAD_JTAG_RTCK__JTAG_RTCK | MUX_CONFIG_JTAG, + + /* LCD Framebuffer */ + MX28_PAD_LCD_D00__LCD_D0 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D01__LCD_D1 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D02__LCD_D2 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D03__LCD_D3 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D04__LCD_D4 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D05__LCD_D5 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D06__LCD_D6 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D07__LCD_D7 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D08__LCD_D8 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D09__LCD_D9 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D10__LCD_D10 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D11__LCD_D11 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D12__LCD_D12 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D13__LCD_D13 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D14__LCD_D14 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D15__LCD_D15 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D16__LCD_D16 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D17__LCD_D17 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D18__LCD_D18 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D19__LCD_D19 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D20__LCD_D20 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D21__LCD_D21 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D22__LCD_D22 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D23__LCD_D23 | MUX_CONFIG_LCD, + MX28_PAD_LCD_RD_E__LCD_VSYNC | MUX_CONFIG_LCD, + MX28_PAD_LCD_WR_RWN__LCD_HSYNC | MUX_CONFIG_LCD, + MX28_PAD_LCD_RS__LCD_DOTCLK | MUX_CONFIG_LCD, + MX28_PAD_LCD_CS__LCD_ENABLE | MUX_CONFIG_LCD, + + /* LCD Panel Power Enable */ + MX28_PAD_LCD_RESET__GPIO_3_30 | (MXS_PAD_3V3 | MXS_PAD_4MA), + + /* LCD Backlight Enable */ + MX28_PAD_AUART0_CTS__GPIO_3_2 | (MXS_PAD_3V3 | MXS_PAD_4MA), + + /* DEBUG Port - DUART with GPIO CTS Control */ + MX28_PAD_I2C0_SDA__DUART_TX | MUX_CONFIG_UART, + MX28_PAD_I2C0_SCL__DUART_RX | MUX_CONFIG_UART, + MX28_PAD_SSP0_DATA5__GPIO_2_5 | MUX_CONFIG_UART, + + /* RS232 Port - AUART1 */ + MX28_PAD_AUART1_RX__AUART1_RX | MUX_CONFIG_UART, + MX28_PAD_AUART1_TX__AUART1_TX | MUX_CONFIG_UART, + + /* I2C */ + MX28_PAD_PWM0__I2C1_SCL | MUX_CONFIG_I2C, + MX28_PAD_PWM1__I2C1_SDA | MUX_CONFIG_I2C, + + /* CAN */ + MX28_PAD_GPMI_RDY2__CAN0_TX | MUX_CONFIG_CAN, + MX28_PAD_GPMI_RDY3__CAN0_RX | MUX_CONFIG_CAN, + + /* MMC0 */ + MX28_PAD_SSP0_DATA0__SSP0_D0 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA1__SSP0_D1 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA2__SSP0_D2 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA3__SSP0_D3 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_CMD__SSP0_CMD | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_SCK__SSP0_SCK | MUX_CONFIG_SSP0, + + /* GPMI NAND */ + MX28_PAD_GPMI_D00__GPMI_D0 | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_D01__GPMI_D1 | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_D02__GPMI_D2 | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_D03__GPMI_D3 | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_D04__GPMI_D4 | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_D05__GPMI_D5 | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_D06__GPMI_D6 | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_D07__GPMI_D7 | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_CE0N__GPMI_CE0N | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_CE1N__GPMI_CE1N | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_RDY0__GPMI_READY0 | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_RDY1__GPMI_READY1 | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_RDN__GPMI_RDN | (MXS_PAD_3V3 | + MXS_PAD_8MA | + MXS_PAD_PULLUP), + MX28_PAD_GPMI_WRN__GPMI_WRN | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_ALE__GPMI_ALE | MUX_CONFIG_GPMI, + MX28_PAD_GPMI_CLE__GPMI_CLE | MUX_CONFIG_GPMI, + + /* NAND WP */ + MX28_PAD_GPMI_RESETN__GPIO_0_28 | MUX_CONFIG_GPMI, + + /* FEC Ethernet */ + MX28_PAD_ENET0_MDC__ENET0_MDC | MUX_CONFIG_ENET, + MX28_PAD_ENET0_MDIO__ENET0_MDIO | MUX_CONFIG_ENET, + MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | MUX_CONFIG_ENET, + MX28_PAD_ENET0_TX_EN__ENET0_TX_EN | MUX_CONFIG_ENET, + MX28_PAD_ENET0_RXD0__ENET0_RXD0 | MUX_CONFIG_ENET, + MX28_PAD_ENET0_RXD1__ENET0_RXD1 | MUX_CONFIG_ENET, + MX28_PAD_ENET0_TXD0__ENET0_TXD0 | MUX_CONFIG_ENET, + MX28_PAD_ENET0_TXD1__ENET0_TXD1 | MUX_CONFIG_ENET, + MX28_PAD_ENET_CLK__CLKCTRL_ENET | MUX_CONFIG_ENET, + + /* PHY reset */ + MX28_PAD_SAIF0_MCLK__GPIO_3_20 | MUX_CONFIG_ENET, + + /* EMI */ + MX28_PAD_EMI_D00__EMI_DATA0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D01__EMI_DATA1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D02__EMI_DATA2 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D03__EMI_DATA3 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D04__EMI_DATA4 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D05__EMI_DATA5 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D06__EMI_DATA6 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D07__EMI_DATA7 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D08__EMI_DATA8 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D09__EMI_DATA9 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D10__EMI_DATA10 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D11__EMI_DATA11 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D12__EMI_DATA12 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D13__EMI_DATA13 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D14__EMI_DATA14 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D15__EMI_DATA15 | MUX_CONFIG_EMI, + MX28_PAD_EMI_ODT0__EMI_ODT0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DQM0__EMI_DQM0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DQM1__EMI_DQM1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK | MUX_CONFIG_EMI, + MX28_PAD_EMI_CLK__EMI_CLK | MUX_CONFIG_EMI, + MX28_PAD_EMI_DQS0__EMI_DQS0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DQS1__EMI_DQS1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN | MUX_CONFIG_EMI, + + MX28_PAD_EMI_A00__EMI_ADDR0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A01__EMI_ADDR1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A02__EMI_ADDR2 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A03__EMI_ADDR3 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A04__EMI_ADDR4 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A05__EMI_ADDR5 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A06__EMI_ADDR6 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A07__EMI_ADDR7 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A08__EMI_ADDR8 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A09__EMI_ADDR9 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A10__EMI_ADDR10 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A11__EMI_ADDR11 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A12__EMI_ADDR12 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A13__EMI_ADDR13 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A14__EMI_ADDR14 | MUX_CONFIG_EMI, + MX28_PAD_EMI_BA0__EMI_BA0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_BA1__EMI_BA1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_BA2__EMI_BA2 | MUX_CONFIG_EMI, + MX28_PAD_EMI_CASN__EMI_CASN | MUX_CONFIG_EMI, + MX28_PAD_EMI_RASN__EMI_RASN | MUX_CONFIG_EMI, + MX28_PAD_EMI_WEN__EMI_WEN | MUX_CONFIG_EMI, + MX28_PAD_EMI_CE0N__EMI_CE0N | MUX_CONFIG_EMI, + MX28_PAD_EMI_CKE__EMI_CKE | MUX_CONFIG_EMI, +}; + +void board_init_ll(const uint32_t arg, const uint32_t *resptr) +{ + mxs_common_spl_init(arg, resptr, iomux_setup, ARRAY_SIZE(iomux_setup)); +} diff --git a/configs/g2c1_defconfig b/configs/g2c1_defconfig new file mode 100644 index 0000000..926fcc2 --- /dev/null +++ b/configs/g2c1_defconfig @@ -0,0 +1,3 @@ +CONFIG_SPL=y ++S:CONFIG_ARM=y ++S:CONFIG_TARGET_G2C1=y diff --git a/include/configs/g2c1.h b/include/configs/g2c1.h new file mode 100644 index 0000000..65d16b8 --- /dev/null +++ b/include/configs/g2c1.h @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2015 Graeme Russ gruss@tss-engineering.com + * on behalf of DENX Software Engineering GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __CONFIGS_G2C1_H__ +#define __CONFIGS_G2C1_H__ + +#ifdef DEBUG +#define CONFIG_SPL_SERIAL_SUPPORT +#endif + +/* System configurations */ +#define CONFIG_MX28 /* i.MX28 SoC */ +#define CONFIG_SYS_MXS_VDD5V_ONLY /* No Battery */ + +/* TODO: Remove all references to MACH_TYPE +#define MACH_TYPE_G2C1 3613 +#define CONFIG_MACH_TYPE MACH_TYPE_G2C1 +*/ + +#define CONFIG_FIT + +#define CONFIG_TIMESTAMP /* Print image info with timestamp */ + +/* U-Boot Commands */ +#define CONFIG_SYS_NO_FLASH +#include <config_cmd_default.h> +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DOS_PARTITION +#define CONFIG_FAT_WRITE + +#define CONFIG_CMD_ASKENV +#define CONFIG_CMD_BMP +#define CONFIG_CMD_CACHE +#define CONFIG_CMD_DATE +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_EEPROM +#define CONFIG_CMD_EXT4 +#define CONFIG_CMD_EXT4_WRITE +#define CONFIG_CMD_FAT +#define CONFIG_CMD_FS_GENERIC +#define CONFIG_CMD_GPIO +#define CONFIG_CMD_GREPENV +#define CONFIG_CMD_I2C +#define CONFIG_CMD_MII +#define CONFIG_CMD_MMC +#define CONFIG_CMD_NAND +#define CONFIG_CMD_NAND_TRIMFFS +#define CONFIG_CMD_NET +#define CONFIG_CMD_NFS +#define CONFIG_CMD_PING +#define CONFIG_CMD_SETEXPR +#define CONFIG_CMD_SF +#define CONFIG_CMD_SPI +#define CONFIG_CMD_USB +#define CONFIG_VIDEO + +#define CONFIG_REGEX /* Enable regular expression support */ + +/* Memory configuration */ +#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */ +#define PHYS_SDRAM_1 0x40000000 /* Base address */ +#define PHYS_SDRAM_1_SIZE 0x08000000 /* Max 128 MB RAM */ +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 + +/* Environment */ +#define CONFIG_ENV_SIZE (16 * 1024) +#define CONFIG_ENV_IS_IN_NAND + +/* Environment is in NAND */ +#if defined(CONFIG_CMD_NAND) && defined(CONFIG_ENV_IS_IN_NAND) +#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE +#define CONFIG_ENV_SECT_SIZE (128 * 1024) +#define CONFIG_ENV_RANGE (4 * CONFIG_ENV_SECT_SIZE) +#define CONFIG_ENV_OFFSET (24 * CONFIG_ENV_SECT_SIZE) /* 3 MiB */ +#define CONFIG_ENV_OFFSET_REDUND \ + (CONFIG_ENV_OFFSET + CONFIG_ENV_RANGE) + +#define CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS +#define CONFIG_CMD_MTDPARTS +#define CONFIG_RBTREE +#define CONFIG_LZO +#define CONFIG_MTD_DEVICE +#define CONFIG_MTD_PARTITIONS +#define MTDIDS_DEFAULT "nand0=gpmi-nand" +#define MTDPARTS_DEFAULT \ + "mtdparts=gpmi-nand:" \ + "3m(u-boot)," \ + "512k(env1)," \ + "512k(env2)," \ + "14m(boot)," \ + "238m(data)," \ + "-@4096k(UBI)" +#else +#define CONFIG_ENV_IS_NOWHERE +#endif + +/* FEC Ethernet on SoC */ +#ifdef CONFIG_CMD_NET +#define CONFIG_FEC_MXC +#endif + +/* EEPROM */ +#ifdef CONFIG_CMD_EEPROM +#define CONFIG_SYS_I2C_MULTI_EEPROMS +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 +#endif + +/* RTC */ +#ifdef CONFIG_CMD_DATE +/* Use the internal RTC in the MXS chip */ +#define CONFIG_RTC_INTERNAL +#ifdef CONFIG_RTC_INTERNAL +#define CONFIG_RTC_MXS +#else +#define CONFIG_RTC_M41T62 +#define CONFIG_SYS_I2C_RTC_ADDR 0x68 +#define CONFIG_SYS_M41T11_BASE_YEAR 2000 +#endif +#endif + +/* USB */ +#ifdef CONFIG_CMD_USB +#define CONFIG_EHCI_MXS_PORT0 +#define CONFIG_EHCI_MXS_PORT1 +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2 +#define CONFIG_USB_STORAGE +#endif + +/* SPI */ +#ifdef CONFIG_CMD_SPI +#define CONFIG_DEFAULT_SPI_BUS 2 +#define CONFIG_DEFAULT_SPI_CS 0 +#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0 + +/* SPI FLASH */ +#ifdef CONFIG_CMD_SF +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_STMICRO +#define CONFIG_SF_DEFAULT_BUS 2 +#define CONFIG_SF_DEFAULT_CS 0 +#define CONFIG_SF_DEFAULT_SPEED 40000000 +#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 + +#define CONFIG_ENV_SPI_BUS 2 +#define CONFIG_ENV_SPI_CS 0 +#define CONFIG_ENV_SPI_MAX_HZ 40000000 +#define CONFIG_ENV_SPI_MODE SPI_MODE_0 +#endif + +#endif + +/* LCD */ +#ifdef CONFIG_VIDEO +#define CONFIG_VIDEO_LOGO +#define CONFIG_SPLASH_SCREEN +#define CONFIG_CMD_BMP +#define CONFIG_BMP_16BPP +#define CONFIG_VIDEO_BMP_RLE8 +#define CONFIG_VIDEO_BMP_GZIP +#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE (2 << 20) +#endif + +/* Booting Linux */ +#define CONFIG_BOOTDELAY 3 +#define CONFIG_BOOTFILE "fitImage" +#define CONFIG_BOOTARGS "console=ttyAMA0,115200n8 " +#define CONFIG_BOOTCOMMAND "run mmc_mmc" +#define CONFIG_LOADADDR 0x42000000 +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +/* Extra Environment */ +#define CONFIG_PREBOOT "run try_bootscript" +#define CONFIG_HOSTNAME g2c1 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "consdev=ttyAMA0\0" \ + "baudrate=115200\0" \ + "bootscript=boot.scr\0" \ + "bootdev=/dev/mmcblk0p2\0" \ + "rootdev=/dev/mmcblk0p3\0" \ + "netdev=eth0\0" \ + "hostname=g2c1\0" \ + "rootpath=/opt/eldk-5.5/armv5te/rootfs-qte-sdk\0" \ + "kernel_addr_r=0x42000000\0" \ + "videomode=video=ctfb:x:800,y:480,depth:18,mode:0,pclk:30066," \ + "le:0,ri:256,up:0,lo:45,hs:1,vs:1,sync:100663296," \ + "vmode:0\0" \ + "update_nand_full_filename=u-boot.nand\0" \ + "update_nand_firmware_filename=u-boot.sb\0" \ + "update_sd_firmware_filename=u-boot.sd\0" \ + "update_nand_firmware_maxsz=0x100000\0" \ + "update_nand_stride=0x40\0" /* MX28 datasheet ch. 12.12 */ \ + "update_nand_count=0x4\0" /* MX28 datasheet ch. 12.12 */ \ + "update_nand_get_fcb_size=" /* Get size of FCB blocks */ \ + "nand device 0 ; " \ + "nand info ; " \ + "setexpr fcb_sz ${update_nand_stride} * ${update_nand_count};" \ + "setexpr update_nand_fcb ${fcb_sz} * ${nand_writesize}\0" \ + "update_nand_full=" /* Update FCB, DBBT and FW */ \ + "if tftp ${update_nand_full_filename} ; then " \ + "run update_nand_get_fcb_size ; " \ + "nand scrub -y 0x0 ${filesize} ; " \ + "nand write.raw ${loadaddr} 0x0 ${fcb_sz} ; " \ + "setexpr update_off ${loadaddr} + ${update_nand_fcb} ; " \ + "setexpr update_sz ${filesize} - ${update_nand_fcb} ; " \ + "nand write ${update_off} ${update_nand_fcb} ${update_sz} ; " \ + "fi\0" \ + "update_nand_firmware=" /* Update only firmware */ \ + "if tftp ${update_nand_firmware_filename} ; then " \ + "run update_nand_get_fcb_size ; " \ + "setexpr fcb_sz ${update_nand_fcb} * 2 ; " /* FCB + DBBT */ \ + "setexpr fw_sz ${update_nand_firmware_maxsz} * 2 ; " \ + "setexpr fw_off ${fcb_sz} + ${update_nand_firmware_maxsz};" \ + "nand erase ${fcb_sz} ${fw_sz} ; " \ + "nand write ${loadaddr} ${fcb_sz} ${filesize} ; " \ + "nand write ${loadaddr} ${fw_off} ${filesize} ; " \ + "fi\0" \ + "update_sd_firmware=" /* Update the SD firmware partition */ \ + "if mmc rescan ; then " \ + "if tftp ${update_sd_firmware_filename} ; then " \ + "setexpr fw_sz ${filesize} / 0x200 ; " /* SD block size */ \ + "setexpr fw_sz ${fw_sz} + 1 ; " \ + "mmc write ${loadaddr} 0x800 ${fw_sz} ; " \ + "fi ; " \ + "fi\0" \ + "addcons=" \ + "setenv bootargs ${bootargs} " \ + "console=${consdev},${baudrate}\0" \ + "addip=" \ + "setenv bootargs ${bootargs} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:" \ + "${netmask}:${hostname}:${netdev}:off\0" \ + "addmisc=" \ + "setenv bootargs ${bootargs} ${miscargs}\0" \ + "adddfltmtd=" \ + "if test "x${mtdparts}" == "x" ; then " \ + "mtdparts default ; " \ + "fi\0" \ + "addmtd=" \ + "run adddfltmtd ; " \ + "setenv bootargs ${bootargs} ${mtdparts}\0" \ + "addargs=run addcons addmtd addmisc\0" \ + "mmcload=" \ + "mmc rescan ; " \ + "load mmc 0:2 ${kernel_addr_r} ${bootfile}\0" \ + "ubiload=" \ + "ubi part UBI ; ubifsmount ubi0:rootfs ; " \ + "ubifsload ${kernel_addr_r} /boot/${bootfile}\0" \ + "netload=" \ + "tftp ${kernel_addr_r} ${hostname}/${bootfile}\0" \ + "miscargs=nohlt panic=1\0" \ + "mmcargs=setenv bootargs root=${rootdev} rw rootwait\0" \ + "ubiargs=" \ + "setenv bootargs ubi.mtd=5 " \ + "root=ubi0:rootfs rootfstype=ubifs\0" \ + "nfsargs=" \ + "setenv bootargs root=/dev/nfs rw " \ + "nfsroot=${serverip}:${rootpath},v3,tcp\0" \ + "mmc_mmc=" \ + "run mmcload mmcargs addargs ; " \ + "bootm ${kernel_addr_r}\0" \ + "mmc_ubi=" \ + "run mmcload ubiargs addargs ; " \ + "bootm ${kernel_addr_r}\0" \ + "mmc_nfs=" \ + "run mmcload nfsargs addip addargs ; " \ + "bootm ${kernel_addr_r}\0" \ + "ubi_mmc=" \ + "run ubiload mmcargs addargs ; " \ + "bootm ${kernel_addr_r}\0" \ + "ubi_ubi=" \ + "run ubiload ubiargs addargs ; " \ + "bootm ${kernel_addr_r}\0" \ + "ubi_nfs=" \ + "run ubiload nfsargs addip addargs ; " \ + "bootm ${kernel_addr_r}\0" \ + "net_mmc=" \ + "run netload mmcargs addargs ; " \ + "bootm ${kernel_addr_r}\0" \ + "net_ubi=" \ + "run netload ubiargs addargs ; " \ + "bootm ${kernel_addr_r}\0" \ + "net_nfs=" \ + "run netload nfsargs addip addargs ; " \ + "bootm ${kernel_addr_r}\0" \ + "try_bootscript=" \ + "mmc rescan;" \ + "if test -e mmc 0:2 ${bootscript} ; then " \ + "if load mmc 0:2 ${kernel_addr_r} ${bootscript};" \ + "then ; " \ + "echo Running bootscript... ; " \ + "source ${kernel_addr_r} ; " \ + "fi ; " \ + "fi\0" + +/* The rest of the configuration is shared */ +#include <configs/mxs.h> + +#endif /* __CONFIGS_G2C1_H__ */

On Wed, Jan 21, 2015 at 9:55 AM, Graeme Russ gruss@tss-engineering.com wrote:
Signed-off-by: Graeme Russ gruss@tss-engineering.com
It would be nice to have a commit log with the text you put in the help section that describes the board.
--- /dev/null +++ b/board/reachtech/g2c1/README @@ -0,0 +1,58 @@ +ReachTech G2C1 +==================
+Supported hardware: ReachTech G2C1 is supported in U-boot.
+Files of the MX28EVK port
You should remove the references for mx28evk.
+--------------------------
+arch/arm/cpu/arm926ejs/mxs/ - The CPU support code for the Freescale i.MX28 +arch/arm/include/asm/arch-mxs/ - Header files for the Freescale i.MX28 +board/reachtech/g2c1/ - G2C1 board specific files +include/configs/g2c1.h - G2C1 configuration file
+Jumper configuration +---------------------
+To boot G2C1 from an SD card, set the boot mode DIP switches as:
- Boot Mode Select: 1 0 0 1 (Boot from SD card Slot 0 - U42)
- JTAG PSWITCH RESET: To the right (reset disabled)
- Battery Source: Down
- Wall 5V: Up
- VDD 5V: To the left (off)
- Hold Button: Down (off)
+To boot MX28EVK from SPI NOR flash, set the boot mode DIP switches as:
Same here.
- Boot Mode Select: 0 0 1 0 (Boot from SSP2)
- JTAG PSWITCH RESET: To the right (reset disabled)
- Battery Source: Down
- Wall 5V: Up
- VDD 5V: To the left (off)
- Hold Button: Down (off)
+Environment Storage +-------------------
+There are three targets for mx28evk:
+"make mx28evk_config" - store environment variables into MMC
+or
+"make mx28evk_nand_config" - store environment variables into NAND flash
+or
+"make mx28evk_spi_config" - store enviroment variables into SPI NOR flash
+Choose the target accordingly.
+mx28evk does not come with SPI NOR flash populated from the factory either. +It is possible to solder a SOIC memory on U49 or use a DIP8 on J89. +To get SPI communication to work R320, R321,R322 and C178 need to be populated. +Look in the schematics for the proper component values.
And here too.

On Wednesday, January 21, 2015 at 09:53:30 PM, Fabio Estevam wrote:
On Wed, Jan 21, 2015 at 9:55 AM, Graeme Russ gruss@tss-engineering.com
wrote:
Signed-off-by: Graeme Russ gruss@tss-engineering.com
It would be nice to have a commit log with the text you put in the help section that describes the board.
Also, the subject should contain proper tags (arm: mxs: blah blah ...)
Best regards, Marek Vasut

On 22/01/15 10:03, Marek Vasut wrote:
On Wednesday, January 21, 2015 at 09:53:30 PM, Fabio Estevam wrote:
On Wed, Jan 21, 2015 at 9:55 AM, Graeme Russ gruss@tss-engineering.com
wrote:
Signed-off-by: Graeme Russ gruss@tss-engineering.com
It would be nice to have a commit log with the text you put in the help section that describes the board.
Also, the subject should contain proper tags (arm: mxs: blah blah ...)
I know - I had them in, but patman complained :(

On Wednesday, January 21, 2015 at 12:55:18 PM, Graeme Russ wrote:
Signed-off-by: Graeme Russ gruss@tss-engineering.com
Commit message again ;-)
[...]
diff --git a/board/reachtech/g2c1/g2c1.c b/board/reachtech/g2c1/g2c1.c new file mode 100644 index 0000000..5bf437d --- /dev/null +++ b/board/reachtech/g2c1/g2c1.c @@ -0,0 +1,79 @@
[...]
+#ifdef CONFIG_CMD_MMC
+int board_mmc_init(bd_t *bis) +{
- return mxsmmc_initialize(bis, 0, NULL /* g2c1_mmc_wp */, NULL);
Where's the WP function?
+} +#endif diff --git a/board/reachtech/g2c1/spl_boot.c b/board/reachtech/g2c1/spl_boot.c new file mode 100644 index 0000000..25ee0e2 --- /dev/null +++ b/board/reachtech/g2c1/spl_boot.c @@ -0,0 +1,452 @@ +/*
- DENX M28 Boot setup
- Copyright (C) 2011 Marek Vasut marek.vasut@gmail.com
- on behalf of DENX Software Engineering GmbH
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <config.h> +#include <asm/io.h> +#include <asm/arch/iomux-mx28.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h>
+/*
- Bank. SoC
- Pin Pin Function Comments
All this stuff should be in some README instead .
[...]
+#define CONFIG_EXTRA_ENV_SETTINGS \
- "consdev=ttyAMA0\0" \
- "baudrate=115200\0" \
- "bootscript=boot.scr\0" \
- "bootdev=/dev/mmcblk0p2\0" \
- "rootdev=/dev/mmcblk0p3\0" \
- "netdev=eth0\0" \
- "hostname=g2c1\0" \
- "rootpath=/opt/eldk-5.5/armv5te/rootfs-qte-sdk\0" \
Remove this rootpath var from here.
Thanks!
participants (4)
-
Fabio Estevam
-
Graeme Russ
-
Marek Vasut
-
Stefan Roese