PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__
- # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
- PF_CPPFLAGS_ARM := $(call cc-option,-marm,)
+ # Choose between ARM/Thumb instruction sets
+ ifeq ($(CONFIG_SYS_THUMB_BUILD),y)
+ PF_CPPFLAGS_ARM := $(call cc-option, -mthumb -mthumb-interwork,\
+ $(call cc-option,-marm,)\
+ $(call cc-option,-mno-thumb-interwork,)\
+ )
+ else
+ PF_CPPFLAGS_ARM := $(call cc-option,-marm,) \
+ $(call cc-option,-mno-thumb-interwork,)
+ endif
+
+ # Only test once
+ ifneq ($(CONFIG_SPL_BUILD),y)
+ ALL-$(CONFIG_SYS_THUMB_BUILD) += checkthumb
+ endif
-# Try if EABI is supported, else fall back to old API,
+# Try if EABI is supported, else fall back to old ABI,
# i. e. for example:
# - with ELDK 4.2 (EABI supported), use:
- # -mabi=aapcs-linux -mno-thumb-interwork
+ # -mabi=aapcs-linux
# - with ELDK 4.1 (gcc 4.x, no EABI), use:
- # -mabi=apcs-gnu -mno-thumb-interwork
+ # -mabi=apcs-gnu
# - with ELDK 3.1 (gcc 3.x), use:
- # -mapcs-32 -mno-thumb-interwork
+ # -mapcs-32
PF_CPPFLAGS_ABI := $(call cc-option,\
- -mabi=aapcs-linux -mno-thumb-interwork,\
+ -mabi=aapcs-linux,\
$(call cc-option,\
-mapcs-32,\
$(call cc-option,\
void early_delay(int delay)
{
uint32_t st = readl(HW_DIGCTRL_MICROSECONDS);
- st += delay;
- while (st > readl(HW_DIGCTRL_MICROSECONDS))
- ;
+
+ while (readl(HW_DIGCTRL_MICROSECONDS) - st < delay);
}
+ #define MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
+ const iomux_cfg_t iomux_boot[] = {
+ MX28_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD,
+ MX28_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD,
+ MX28_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD,
+ MX28_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD,
+ MX28_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD,
+ MX28_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD,
+ };
+
+ uint8_t mx28_get_bootmode_index(void)
+ {
+ uint8_t bootmode = 0;
+ int i;
+ uint8_t masked;
+
+ /* Setup IOMUX of bootmode pads to GPIO */
+ mxs_iomux_setup_multiple_pads(iomux_boot, ARRAY_SIZE(iomux_boot));
+
+ /* Setup bootmode pins as GPIO input */
+ gpio_direction_input(MX28_PAD_LCD_D00__GPIO_1_0);
+ gpio_direction_input(MX28_PAD_LCD_D01__GPIO_1_1);
+ gpio_direction_input(MX28_PAD_LCD_D02__GPIO_1_2);
+ gpio_direction_input(MX28_PAD_LCD_D03__GPIO_1_3);
+ gpio_direction_input(MX28_PAD_LCD_D04__GPIO_1_4);
+ gpio_direction_input(MX28_PAD_LCD_D05__GPIO_1_5);
+
+ /* Read bootmode pads */
+ bootmode |= (gpio_get_value(MX28_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0;
+ bootmode |= (gpio_get_value(MX28_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1;
+ bootmode |= (gpio_get_value(MX28_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2;
+ bootmode |= (gpio_get_value(MX28_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3;
+ bootmode |= (gpio_get_value(MX28_PAD_LCD_D04__GPIO_1_4) ? 1 : 0) << 4;
+ bootmode |= (gpio_get_value(MX28_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5;
+
+ for (i = 0; i < ARRAY_SIZE(mx28_boot_modes); i++) {
+ masked = bootmode & mx28_boot_modes[i].boot_mask;
+ if (masked == mx28_boot_modes[i].boot_pads)
+ break;
+ }
+
+ return i;
+ }
+
void mx28_common_spl_init(const iomux_cfg_t *iomux_setup,
const unsigned int iomux_size)
{
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
/* Gate EMI clock */
- writel(CLKCTRL_FRAC0_CLKGATEEMI,
- &clkctrl_regs->hw_clkctrl_frac0_set);
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_EMI]);
- /* EMI = 205MHz */
- clrsetbits_le32(&clkctrl_regs->hw_clkctrl_frac0,
- CLKCTRL_FRAC0_CLKGATEEMI | CLKCTRL_FRAC0_EMIFRAC_MASK,
- 21 << CLKCTRL_FRAC0_EMIFRAC_OFFSET);
+ /* Set fractional divider for ref_emi to 480 * 18 / 21 = 411MHz */
+ writeb(CLKCTRL_FRAC_CLKGATE | (21 & CLKCTRL_FRAC_FRAC_MASK),
+ &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_EMI]);
- early_delay(11000);
+ /* Ungate EMI clock */
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_EMI]);
+
+
+ /* Set EMI clock divider for EMI clock to 411 / 2 = 205MHz */
writel((2 << CLKCTRL_EMI_DIV_EMI_OFFSET) |
(1 << CLKCTRL_EMI_DIV_XTAL_OFFSET),
&clkctrl_regs->hw_clkctrl_emi);
/* Disable CPU bypass */
writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
&clkctrl_regs->hw_clkctrl_clkseq_clr);
+
+ early_delay(15000);
}
-void mx28_mem_setup_vdda(void)
+#define HW_DIGCTRL_SCRATCH0 0x8001c280
+#define HW_DIGCTRL_SCRATCH1 0x8001c290
+static void data_abort_memdetect_handler(void) __attribute__((naked));
+static void data_abort_memdetect_handler(void)
{
- struct mx28_power_regs *power_regs =
- (struct mx28_power_regs *)MXS_POWER_BASE;
-
- writel((0xc << POWER_VDDACTRL_TRG_OFFSET) |
- (0x7 << POWER_VDDACTRL_BO_OFFSET_OFFSET) |
- POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW,
- &power_regs->hw_power_vddactrl);
-}
-
-void mx28_mem_setup_vddd(void)
-{
- struct mx28_power_regs *power_regs =
- (struct mx28_power_regs *)MXS_POWER_BASE;
-
- writel((0x1c << POWER_VDDDCTRL_TRG_OFFSET) |
- (0x7 << POWER_VDDDCTRL_BO_OFFSET_OFFSET) |
- POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW,
- &power_regs->hw_power_vdddctrl);
+ asm volatile("subs pc, r14, #4");
}
- static void mx28_mem_get_size(void)
+ uint32_t mx28_mem_get_size(void)
{
uint32_t sz, da;
uint32_t *vt = (uint32_t *)0x20;
/* Replace the DABT handler. */
da = vt[4];
- vt[4] = (uint32_t)&data_abort_memdetect_handler;
- vt[4] = data_abort_memdetect_handler;
++ vt[4] = (uint32_t)data_abort_memdetect_handler;
sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
- writel(sz, HW_DIGCTRL_SCRATCH0);
- writel(sz, HW_DIGCTRL_SCRATCH1);
/* Restore the old DABT handler. */
vt[4] = da;
while (!(readl(MXS_DRAM_BASE + 0xe8) & (1 << 20)))
;
- mx28_mem_setup_vddd();
-
- early_delay(10000);
-
mx28_mem_setup_cpu_and_hbus();
-
- mx28_mem_get_size();
}
struct mx28_clkctrl_regs *clkctrl_regs =
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
- writel(CLKCTRL_PLL0CTRL0_POWER,
- &clkctrl_regs->hw_clkctrl_pll0ctrl0_set);
+ setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
+ CLKCTRL_PLL0CTRL0_POWER);
early_delay(100);
- writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
- &clkctrl_regs->hw_clkctrl_clkseq_clr);
+ setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
+ CLKCTRL_CLKSEQ_BYPASS_CPU);
}
-void mx28_power_clear_auto_restart(void)
+static void mx28_power_clear_auto_restart(void)
{
struct mx28_rtc_regs *rtc_regs =
(struct mx28_rtc_regs *)MXS_RTC_BASE;
POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
}
-void mx28_power_setup_5v_detect(void)
+ int mx28_get_batt_volt(void)
+ {
+ struct mx28_power_regs *power_regs =
+ (struct mx28_power_regs *)MXS_POWER_BASE;
+ uint32_t volt = readl(&power_regs->hw_power_battmonitor);
+ volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
+ volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
+ volt *= 8;
+ return volt;
+ }
+
+ int mx28_is_batt_ready(void)
+ {
+ return (mx28_get_batt_volt() >= 3600);
+ }
+
+ int mx28_is_batt_good(void)
+ {
+ struct mx28_power_regs *power_regs =
+ (struct mx28_power_regs *)MXS_POWER_BASE;
+ uint32_t volt = mx28_get_batt_volt();
+
+ if ((volt >= 2400) && (volt <= 4300))
+ return 1;
+
+ clrsetbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+ 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+ writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+ &power_regs->hw_power_5vctrl_clr);
+
+ clrsetbits_le32(&power_regs->hw_power_charge,
+ POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
+ POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
+
+ writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
+ writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+ &power_regs->hw_power_5vctrl_clr);
+
+ early_delay(500000);
+
+ volt = mx28_get_batt_volt();
+
+ if (volt >= 3500)
+ return 0;
+
+ if (volt >= 2400)
+ 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);
+
+ return 0;
+ }
+
+static void mx28_power_setup_5v_detect(void)
{
- struct mx28_power_regs *power_regs =
- (struct mx28_power_regs *)MXS_POWER_BASE;
-
/* Start 5V detection */
clrsetbits_le32(&power_regs->hw_power_5vctrl,
POWER_5VCTRL_VBUSVALID_TRSH_MASK,
&power_regs->hw_power_reset);
}
- static void mx28_handle_5v_conflict(void)
+ void mx28_batt_boot(void)
+ {
+ struct mx28_power_regs *power_regs =
+ (struct mx28_power_regs *)MXS_POWER_BASE;
+
+ clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
+ clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
+
+ clrbits_le32(&power_regs->hw_power_dcdc4p2,
+ POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2);
+ writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr);
+
+ /* 5V to battery handoff. */
+ setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+ early_delay(30);
+ clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+
+ writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
+
+ clrsetbits_le32(&power_regs->hw_power_minpwr,
+ POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
+
+ mx28_power_set_linreg();
+
+ clrbits_le32(&power_regs->hw_power_vdddctrl,
+ POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG);
+
+ clrbits_le32(&power_regs->hw_power_vddactrl,
+ POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG);
+
+ clrbits_le32(&power_regs->hw_power_vddioctrl,
+ POWER_VDDIOCTRL_DISABLE_FET);
+
+ setbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
+
+ setbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_ENABLE_DCDC);
+
+ clrsetbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+ 0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+ }
+
+ void mx28_handle_5v_conflict(void)
{
- struct mx28_power_regs *power_regs =
- (struct mx28_power_regs *)MXS_POWER_BASE;
uint32_t tmp;
setbits_le32(&power_regs->hw_power_vddioctrl,
mx28_powerdown();
break;
}
- }
- }
- static inline int mx28_get_batt_volt(void)
- {
- uint32_t volt = readl(&power_regs->hw_power_battmonitor);
-
- volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
- volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
- volt *= 8;
- return volt;
- }
-
- static inline int mx28_is_batt_ready(void)
- {
- return mx28_get_batt_volt() >= 3600;
+ if (tmp & POWER_STS_PSWITCH_MASK) {
+ mx28_batt_boot();
+ break;
+ }
+ }
}
-void mx28_5v_boot(void)
+static void mx28_5v_boot(void)
{
- struct mx28_power_regs *power_regs =
- (struct mx28_power_regs *)MXS_POWER_BASE;
-
/*
* NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
* but their implementation always returns 1 so we omit it here.
POWER_VDDDCTRL_DISABLE_STEPPING);
}
- static inline int mx28_is_batt_good(void)
- {
- uint32_t volt;
-
- volt = mx28_get_batt_volt();
-
- if ((volt >= 2400) && (volt <= 4300))
- return 1;
-
- clrsetbits_le32(&power_regs->hw_power_5vctrl,
- POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
- 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
- writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
- &power_regs->hw_power_5vctrl_clr);
-
- clrsetbits_le32(&power_regs->hw_power_charge,
- POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
- POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
-
- writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
- writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
- &power_regs->hw_power_5vctrl_clr);
-
- early_delay(500000);
-
- volt = mx28_get_batt_volt();
-
- if (volt >= 3500)
- return 0;
-
- if (volt >= 2400)
- 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);
-
- return 0;
- }
-
-void mx28_power_configure_power_source(void)
+static void mx28_power_configure_power_source(void)
{
- int batt_ready, batt_good;
- struct mx28_power_regs *power_regs =
- (struct mx28_power_regs *)MXS_POWER_BASE;
- struct mx28_lradc_regs *lradc_regs =
- (struct mx28_lradc_regs *)MXS_LRADC_BASE;
-
mx28_src_power_init();
- batt_ready = mx28_is_batt_ready();
-
- if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
- batt_good = mx28_is_batt_good();
- if (batt_ready) {
- /* 5V source detected, good battery detected. */
- mx28_batt_boot();
- } else {
- if (batt_good) {
- /* 5V source detected, low battery detceted. */
- } else {
- /* 5V source detected, bad battery detected. */
- writel(LRADC_CONVERSION_AUTOMATIC,
- &lradc_regs->hw_lradc_conversion_clr);
- clrbits_le32(&power_regs->hw_power_battmonitor,
- POWER_BATTMONITOR_BATT_VAL_MASK);
- }
- mx28_5v_boot();
- }
- } else {
- /* 5V not detected, booting from battery. */
- mx28_batt_boot();
- }
+ if (!fixed_batt_supply)
+ mx28_5v_boot();
+ else
+ mx28_fixed_batt_boot();
mx28_power_clock2pll();
} while (new_target < cur_target);
}
- clrsetbits_le32(&power_regs->hw_power_vddioctrl,
- POWER_VDDDCTRL_BO_OFFSET_MASK,
- new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET);
+ clrsetbits_le32(reg, bo_mask, (new_brownout / step_size) << bo_shift);
}
-void mx28_power_set_vddd(uint32_t new_target, uint32_t new_brownout)
-{
- struct mx28_power_regs *power_regs =
- (struct mx28_power_regs *)MXS_POWER_BASE;
- uint32_t cur_target, diff, bo_int = 0;
- uint32_t powered_by_linreg = 0;
-
- new_brownout = new_target - new_brownout;
-
- cur_target = readl(&power_regs->hw_power_vdddctrl);
- cur_target &= POWER_VDDDCTRL_TRG_MASK;
- cur_target *= 25; /* 25 mV step*/
- cur_target += 800; /* 800 mV lowest */
-
- powered_by_linreg = mx28_get_vddd_power_source_off();
- if (new_target > cur_target) {
- if (powered_by_linreg) {
- bo_int = readl(&power_regs->hw_power_vdddctrl);
- clrbits_le32(&power_regs->hw_power_vdddctrl,
- POWER_CTRL_ENIRQ_VDDD_BO);
- }
-
- setbits_le32(&power_regs->hw_power_vdddctrl,
- POWER_VDDDCTRL_BO_OFFSET_MASK);
-
- do {
- if (new_target - cur_target > 100)
- diff = cur_target + 100;
- else
- diff = new_target;
+#define __mx28_power_set_vddx(trg, bo, min, max, step, reg, name, lr) \
+ mx28_power_set_vddx(trg, bo, \
+ &power_regs->hw_power_##reg##ctrl, #name, \
+ min, max, step, \
+ POWER_##name##CTRL_TRG_MASK, \
+ POWER_##name##CTRL_TRG_OFFSET, \
+ POWER_##name##CTRL_BO_OFFSET_MASK, \
+ POWER_##name##CTRL_BO_OFFSET_OFFSET, lr)
- diff -= 800;
- diff /= 25;
-
- clrsetbits_le32(&power_regs->hw_power_vdddctrl,
- POWER_VDDDCTRL_TRG_MASK, diff);
-
- if (powered_by_linreg ||
- (readl(&power_regs->hw_power_sts) &
- POWER_STS_VDD5V_GT_VDDIO))
- early_delay(500);
- else {
- while (!(readl(&power_regs->hw_power_sts) &
- POWER_STS_DC_OK))
- ;
-
- }
+static inline void mx28_power_set_vddd(uint32_t target, uint32_t brownout)
+{
+ int powered_by_linreg = mx28_get_vddd_power_source_off();
+ uint32_t bo_int = 0;
- cur_target = readl(&power_regs->hw_power_vdddctrl);
- cur_target &= POWER_VDDDCTRL_TRG_MASK;
- cur_target *= 25; /* 25 mV step*/
- cur_target += 800; /* 800 mV lowest */
- } while (new_target > cur_target);
+ if (powered_by_linreg) {
+ bo_int = readl(&power_regs->hw_power_vdddctrl);
+ clrbits_le32(&power_regs->hw_power_vdddctrl,
+ POWER_CTRL_ENIRQ_VDDD_BO);
+ }
- if (powered_by_linreg) {
- writel(POWER_CTRL_VDDD_BO_IRQ,
- &power_regs->hw_power_ctrl_clr);
- if (bo_int & POWER_CTRL_ENIRQ_VDDD_BO)
- setbits_le32(&power_regs->hw_power_vdddctrl,
- POWER_CTRL_ENIRQ_VDDD_BO);
- }
- } else {
- do {
- if (cur_target - new_target > 100)
- diff = cur_target - 100;
- else
- diff = new_target;
+ __mx28_power_set_vddx(target, brownout, 800, 1575, 25, vddd, VDDD,
+ powered_by_linreg);
- diff -= 800;
- diff /= 25;
+ if (powered_by_linreg) {
+ writel(POWER_CTRL_VDDD_BO_IRQ,
+ &power_regs->hw_power_ctrl_clr);
+ if (bo_int & POWER_CTRL_ENIRQ_VDDD_BO)
+ setbits_le32(&power_regs->hw_power_vdddctrl,
+ POWER_CTRL_ENIRQ_VDDD_BO);
+ }
+}
- clrsetbits_le32(&power_regs->hw_power_vdddctrl,
- POWER_VDDDCTRL_TRG_MASK, diff);
+static inline void mx28_power_set_vddio(uint32_t target, uint32_t brownout)
+{
+ int powered_by_linreg = mx28_get_vddio_power_source_off();
+ uint32_t bo_int = 0;
- if (powered_by_linreg ||
- (readl(&power_regs->hw_power_sts) &
- POWER_STS_VDD5V_GT_VDDIO))
- early_delay(500);
- else {
- while (!(readl(&power_regs->hw_power_sts) &
- POWER_STS_DC_OK))
- ;
+ if (powered_by_linreg) {
+ bo_int = readl(&power_regs->hw_power_vddioctrl);
+ clrbits_le32(&power_regs->hw_power_vddioctrl,
+ POWER_CTRL_ENIRQ_VDDIO_BO);
+ }
+ __mx28_power_set_vddx(target, brownout, 2800, 3600, 50, vddio, VDDIO,
+ powered_by_linreg);
+ if (powered_by_linreg) {
+ writel(POWER_CTRL_VDDIO_BO_IRQ,
+ &power_regs->hw_power_ctrl_clr);
+ if (bo_int & POWER_CTRL_ENIRQ_VDDIO_BO)
+ setbits_le32(&power_regs->hw_power_vddioctrl,
+ POWER_CTRL_ENIRQ_VDDIO_BO);
+ }
+}
- }
+static inline void mx28_power_set_vdda(uint32_t target, uint32_t brownout)
+{
+ int powered_by_linreg = mx28_get_vdda_power_source_off();
+ uint32_t bo_int = 0;
- cur_target = readl(&power_regs->hw_power_vdddctrl);
- cur_target &= POWER_VDDDCTRL_TRG_MASK;
- cur_target *= 25; /* 25 mV step*/
- cur_target += 800; /* 800 mV lowest */
- } while (new_target < cur_target);
+ if (powered_by_linreg) {
+ bo_int = readl(&power_regs->hw_power_vddioctrl);
+ clrbits_le32(&power_regs->hw_power_vddioctrl,
+ POWER_CTRL_ENIRQ_VDDIO_BO);
+ }
+ __mx28_power_set_vddx(target, brownout, 1500, 2275, 25, vdda, VDDA,
+ powered_by_linreg);
+ if (powered_by_linreg) {
+ writel(POWER_CTRL_VDDIO_BO_IRQ,
+ &power_regs->hw_power_ctrl_clr);
+ if (bo_int & POWER_CTRL_ENIRQ_VDDIO_BO)
+ setbits_le32(&power_regs->hw_power_vddioctrl,
+ POWER_CTRL_ENIRQ_VDDIO_BO);
}
+}
- clrsetbits_le32(&power_regs->hw_power_vdddctrl,
- POWER_VDDDCTRL_BO_OFFSET_MASK,
- new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET);
+static inline void mx28_power_set_vddmem(uint32_t target, uint32_t brownout)
+{
+ __mx28_power_set_vddx(target, brownout, 1100, 1750, 25, vddmem, VDDMEM,
+ 0);
+
+ clrbits_le32(&power_regs->hw_power_vddmemctrl,
+ POWER_VDDMEMCTRL_ENABLE_LINREG |
+ POWER_VDDMEMCTRL_ENABLE_ILIMIT);
}
+ void mx28_setup_batt_detect(void)
+ {
+ mx28_lradc_init();
+ mx28_lradc_enable_batt_measurement();
+ early_delay(10);
+ }
+
void mx28_power_init(void)
{
- struct mx28_power_regs *power_regs =
- (struct mx28_power_regs *)MXS_POWER_BASE;
-
mx28_power_clock2xtal();
mx28_power_clear_auto_restart();
mx28_power_set_linreg();
{
struct mx28_timrot_regs *timrot_regs =
(struct mx28_timrot_regs *)MXS_TIMROT_BASE;
-
- /* Current tick value */
- uint32_t now = readl(&timrot_regs->hw_timrot_running_count0);
-
- if (lastdec >= now) {
- /*
- * normal mode (non roll)
- * move stamp forward with absolut diff ticks
- */
- timestamp += (lastdec - now);
- } else {
- /* we have rollover of decrementer */
- timestamp += (TIMER_LOAD_VAL - now) + lastdec;
-
- }
- lastdec = now;
-
- return timestamp;
+ /* The timer is counting down, so subtract the register value from
+ * the counter period length to get an incrementing timestamp
+ */
+ unsigned long now = -readl(&timrot_regs->hw_timrot_running_count0);
+ ulong inc = now - gd->lastinc;
+
+ gd->tbl += inc;
+ gd->lastinc = now;
+ /* Since the get_timer() function only uses a 32bit value
+ * it doesn't make sense to return a real 64 bit value here.
+ */
+ return gd->tbl;
}
+ ulong get_timer_masked(void)
+ {
+ return tick_to_time(get_ticks());
+ }
+
ulong get_timer(ulong base)
{
- return get_timer_masked() - base;
-}
-
-/* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */
-#define MX28_HW_DIGCTL_MICROSECONDS 0x8001c0c0
-
-void __udelay(unsigned long usec)
-{
- uint32_t old, new, incr;
- uint32_t counter = 0;
-
- old = readl(MX28_HW_DIGCTL_MICROSECONDS);
-
- while (counter < usec) {
- new = readl(MX28_HW_DIGCTL_MICROSECONDS);
-
- /* Check if the timer wrapped. */
- if (new < old) {
- incr = 0xffffffff - old;
- incr += new;
- } else {
- incr = new - old;
- }
-
- /*
- * Check if we are close to the maximum time and the counter
- * would wrap if incremented. If that's the case, break out
- * from the loop as the requested delay time passed.
- */
- if (counter + incr < counter)
- break;
-
- counter += incr;
- old = new;
- }
+ /* NOTE: time_to_tick(base) is required to correctly handle rollover! */
+ return tick_to_time(get_ticks() - time_to_tick(base));
}
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
ulong get_tbclk(void)
{
- return MX28_INCREMENTER_HZ;
+ return gd->timer_rate_hz;
}
* IRQ Stack: 00ebff7c
* FIQ Stack: 00ebef7c
*/
++#define DEBUG
#include <common.h>
#include <command.h>
if ((*init_fnc_ptr)() != 0) {
hang ();
}
++#if 1
++ {
++ u32 *data = (u32 *)(CONFIG_SYS_TEXT_BASE - 16);
++ int i;
++
++ debug("ip=%d\n", init_fnc_ptr - init_sequence);
++ debug("gd=%p..%p\n", gd, gd + 1);
++ debug("FDT=%p\n", gd->fdt_blob);
++ debug("spl_data=%p:\n", data);
++ for (i = 0; i < 16 / 4; i++) {
++ debug("%08x ", data[i]);
++ }
++ debug("\n");
++ }
++#endif
}
+ #ifdef CONFIG_OF_CONTROL
+ /* For now, put this check after the console is ready */
+ if (fdtdec_prepare_fdt()) {
+ panic("** CONFIG_OF_CONTROL defined but no FDT - please see "
+ "doc/README.fdt-control");
+ }
+ #endif
+
debug("monitor len: %08lX\n", gd->mon_len);
/*
* Ram is setup, size stored in gd !!
--- /dev/null
- CONFIG_SYS_TEXT_BASE := 0x40001000
+# stack is allocated below CONFIG_SYS_TEXT_BASE
++CONFIG_SYS_TEXT_BASE := 0x40100000
+CONFIG_SPL_TEXT_BASE := 0x00000000
+
+PLATFORM_CPPFLAGS += -Werror
+ifneq ($(CONFIG_SPL_BUILD),y)
+ ALL-y += $(obj)u-boot.sb
+endif
"fdt rsvmem delete <index> - Delete a mem reserves\n"
"fdt chosen [<start> <end>] - Add/update the /chosen branch in the tree\n"
" <start>/<end> - initrd start/end addr\n"
-- "NOTE: Dereference aliases by omiting the leading '/', "
++ "NOTE: Dereference aliases by omitting the leading '/', "
"e.g. fdt print ethernet0."
);
# but they don't make much sense in the u-boot world, so disable them.
CFLAGS_WARN := $(call cc-option,-Wno-format-nonliteral) \
$(call cc-option,-Wno-format-security)
-CFLAGS += $(CFLAGS_WARN)
+
+CFLAGS := $(CFLAGS_SSP) $(CFLAGS_WARN) $(CPPFLAGS) -Wall -Wstrict-prototypes
+ifdef BUILD_TAG
+ CFLAGS += -DBUILD_TAG='"$(BUILD_TAG)"'
+endif
+ # Report stack usage if supported
+ CFLAGS_STACK := $(call cc-option,-fstack-usage)
+ CFLAGS += $(CFLAGS_STACK)
+
# $(CPPFLAGS) sets -g, which causes gcc to pass a suitable -g<format>
# option to the assembler.
AFLAGS_DEBUG :=
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
struct mmc *mmc = NULL;
struct mxsmmc_priv *priv = NULL;
+ int ret;
- mmc = malloc(sizeof(struct mmc));
+ mmc = calloc(sizeof(struct mmc), 1);
if (!mmc)
return -ENOMEM;
* CLOCK_DIVIDE has to be an even value from 2 to 254, and
* CLOCK_RATE could be any integer from 0 to 255.
*/
+ writel(CLKCTRL_SSP_DIV_FRAC_EN | 29, priv->clkctrl_ssp);
+
mmc->f_min = 400000;
mmc->f_max = mxc_get_clock(MXC_SSP0_CLK + id) * 1000 / 2;
- mmc->b_max = 0;
+ mmc->b_max = 0x40;
mmc_register(mmc);
return 0;
return buf;
}
- static void invalidate_buffers(struct mtd_info *mtd, struct mxs_nand_info *nand_info)
- {
- invalidate_dcache_range((unsigned long)nand_info->data_buf,
- (unsigned long)nand_info->data_buf +
- mtd->writesize);
- invalidate_dcache_range((unsigned long)nand_info->oob_buf,
- (unsigned long)nand_info->oob_buf +
- mtd->oobsize);
- }
-
+static void flush_buffers(struct mtd_info *mtd, struct mxs_nand_info *nand_info)
+{
+ flush_dcache_range((unsigned long)nand_info->data_buf,
+ (unsigned long)nand_info->data_buf +
+ mtd->writesize);
+ flush_dcache_range((unsigned long)nand_info->oob_buf,
+ (unsigned long)nand_info->oob_buf +
+ mtd->oobsize);
+}
+
/*
* Read a page from NAND.
*/
d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
+ flush_buffers(mtd, nand_info);
+
mxs_dma_desc_append(channel, d);
+ /* Flush caches */
+ mxs_nand_flush_data_buf(nand_info);
+
/* Execute the DMA chain. */
ret = mxs_dma_go(channel);
if (ret) {
#error "CONFIG_MII has to be defined!"
#endif
- #ifndef CONFIG_FEC_XCV_TYPE
- #define CONFIG_FEC_XCV_TYPE MII100
+ #ifndef CONFIG_FEC_XCV_TYPE
+ #define CONFIG_FEC_XCV_TYPE MII100
#endif
+#if !defined(CONDIF_SYS_DCACHE_OFF) && !defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+/* Due to multiple RX and TX buffer descriptors sharing a cache line
+ * the driver can only work with DMA coherent memory.
+ * Since U-Boot does not provide this, cache must be disabled or
+ * write-through.
+ */
+#error This driver cannot be used with Writeback DCACHE
+#endif
/*
* The i.MX28 operates with packets in big endian. We need to swap them before
* sending and after receiving.
return 0;
}
+ #endif
-static int fec_rx_task_enable(struct fec_priv *fec)
+static inline void fec_rx_task_enable(struct fec_priv *fec)
{
writel(1 << 24, &fec->eth->r_des_active);
- return 0;
}
-static int fec_rx_task_disable(struct fec_priv *fec)
+static inline void fec_rx_task_disable(struct fec_priv *fec)
{
- return 0;
}
-static int fec_tx_task_enable(struct fec_priv *fec)
+static inline void fec_tx_task_enable(struct fec_priv *fec)
{
writel(1 << 24, &fec->eth->x_des_active);
- return 0;
}
-static int fec_tx_task_disable(struct fec_priv *fec)
+static inline void fec_tx_task_disable(struct fec_priv *fec)
{
- return 0;
+}
+
+static inline void fec_invalidate_bd(struct fec_bd *bd)
+{
+ invalidate_dcache_range((unsigned long)bd,
+ (unsigned long)bd + sizeof(*bd));
+}
+
+static inline void fec_flush_bd(struct fec_bd *bd)
+{
+ flush_dcache_range((unsigned long)bd,
+ (unsigned long)bd + sizeof(*bd));
}
/**
*/
static void fec_tbd_init(struct fec_priv *fec)
{
+ unsigned addr = (unsigned)fec->tbd_base;
+ unsigned size = roundup(2 * sizeof(struct fec_bd),
+ ARCH_DMA_MINALIGN);
writew(0x0000, &fec->tbd_base[0].status);
+ fec_flush_bd(&fec->tbd_base[0]);
writew(FEC_TBD_WRAP, &fec->tbd_base[1].status);
+ fec_flush_bd(&fec->tbd_base[1]);
fec->tbd_index = 0;
+ flush_dcache_range(addr, addr+size);
}
/**
*/
static int fec_open(struct eth_device *edev)
{
- struct fec_priv *fec = (struct fec_priv *)edev->priv;
+ struct fec_priv *fec = edev->priv;
+ int speed;
+ uint32_t addr, size;
+ int i;
debug("fec_open: fec_open(dev)\n");
/* full-duplex, heartbeat disabled */
static int fec_send(struct eth_device *dev, volatile void *packet, int length)
{
unsigned int status;
+ int timeout = 1000;
+ uint32_t size;
+ uint32_t addr;
/*
* This routine transmits one frame. This routine only accepts
status = readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_WRAP;
status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
writew(status, &fec->tbd_base[fec->tbd_index].status);
+ fec_flush_bd(&fec->tbd_base[fec->tbd_index]);
+ /*
+ * Flush data cache. This code flushes both TX descriptors to RAM.
+ * After this code, the descriptors will be safely in RAM and we
+ * can start DMA.
+ */
+ size = roundup(2 * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
+ addr = (uint32_t)fec->tbd_base;
+ flush_dcache_range(addr, addr + size);
+
/*
* Enable SmartDMA transmit task
*/
fec_tx_task_enable(fec);
/*
- * wait until frame is sent .
+ * Wait until frame is sent. On each turn of the wait cycle, we must
+ * invalidate data cache to see what's really in RAM. Also, we need
+ * barrier here.
*/
+ invalidate_dcache_range(addr, addr + size);
while (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) {
+ if (--timeout < 0)
+ return -ETIMEDOUT;
udelay(1);
- fec_invalidate_bd(&fec->tbd_base[fec->tbd_index]);
+ invalidate_dcache_range(addr, addr + size);
}
+
debug("fec_send: status 0x%x index %d\n",
readw(&fec->tbd_base[fec->tbd_index].status),
fec->tbd_index);
*/
frame = (struct nbuf *)readl(&rbd->data_pointer);
frame_length = readw(&rbd->data_length) - 4;
+
+ invalidate_dcache_range((unsigned long)frame,
+ (unsigned long)frame +
+ sizeof(*frame));
+
+ /*
+ * Invalidate data cache over the buffer
+ */
+ addr = (uint32_t)frame;
+ size = roundup(frame_length, ARCH_DMA_MINALIGN);
+ invalidate_dcache_range(addr, addr + size);
+
/*
* Fill the buffer and pass it to upper layers
*/
#define AHCI_PCI_BAR 0x24
#define AHCI_MAX_SG 56 /* hardware max is 64K */
+#define AHCI_MAX_CMD_SLOT 32
#define AHCI_CMD_SLOT_SZ 32
+ #define AHCI_MAX_CMD_SLOT 32
#define AHCI_RX_FIS_SZ 256
#define AHCI_CMD_TBL_HDR 0x80
#define AHCI_CMD_TBL_CDB 0x40
--- /dev/null
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <asm/sizes.h>
+#include <asm/arch/regs-base.h>
+
+/*
+ * Ka-Ro TX28 board - SoC configuration
+ */
+#define CONFIG_MX28 /* i.MX28 SoC */
+#define CONFIG_MXS_GPIO /* GPIO control */
+#define CONFIG_SYS_HZ 1000 /* Ticks per second */
+#define CONFIG_IDENT_STRING "\nBoard: Ka-Ro TX28-40xx"
+#define CONFIG_SHOW_ACTIVITY
+
+#define CONFIG_SPL
+#define CONFIG_SPL_NO_CPU_SUPPORT_CODE
+#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/arm926ejs/mx28"
+#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mx28/u-boot-spl.lds"
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SYS_SPL_FIXED_BATT_SUPPLY
+#define CONFIG_SYS_SPL_VDDD_VAL 1500
+#define CONFIG_SYS_SPL_BATT_BO_LEVEL 2800
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+/*
+ * Memory configurations
+ */
+#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */
+#define PHYS_SDRAM_1 0x40000000 /* Base address */
+#define PHYS_SDRAM_1_SIZE SZ_128M
+#define CONFIG_STACKSIZE 0x00010000 /* 128 KB stack */
+#define CONFIG_SYS_MALLOC_LEN 0x00400000 /* 4 MB for malloc */
+#define CONFIG_SYS_GBL_DATA_SIZE 128 /* Reserved for initial data */
+#define CONFIG_SYS_MEMTEST_START 0x40000000 /* Memtest start address */
+#define CONFIG_SYS_MEMTEST_END 0x40400000 /* 4 MB RAM test */
+
+/*
+ * U-Boot general configurations
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT "MX28 U-Boot > "
+#define CONFIG_SYS_CBSIZE 2048 /* Console I/O buffer size */
+#define CONFIG_SYS_PBSIZE \
+ (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+ /* Print buffer size */
+#define CONFIG_SYS_MAXARGS 64 /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+ /* Boot argument buffer size */
+#define CONFIG_VERSION_VARIABLE /* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE /* Command auto complete */
+#define CONFIG_CMDLINE_EDITING /* Command history etc */
+
+#define CONFIG_SYS_64BIT_VSPRINTF
+
++/*
++ * Flattened Device Tree (FDT) support
++*/
++#define CONFIG_OF_LIBFDT
++/*
++#define CONFIG_OF_BOARD_SETUP
++*/
++#define CONFIG_OF_EMBED
++#define CONFIG_DEFAULT_DEVICE_TREE karo-tx28
++#define CONFIG_ARCH_DEVICE_TREE mx28
++
+/*
+ * Boot Linux
+ */
+#define xstr(s) str(s)
+#define str(s) #s
+
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTDELAY 3
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+#define CONFIG_BOOTFILE "uImage"
+#define CONFIG_BOOTARGS "console=ttyAMA0,115200 tx28_base=stkv3" \
+ " tx28_otg_mode=device ro debug panic=1"
+#define CONFIG_BOOTCOMMAND "run bootcmd_nand"
+#define CONFIG_LOADADDR 0x40100000
+#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+
+/*
+ * Extra Environments
+ */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "autostart=no\0" \
+ "bootcmd_mmc=set autostart yes;run bootargs_mmc;" \
+ " mmc read ${loadaddr} 100 3000\0" \
+ "bootcmd_nand=set autostart yes;run bootargs_nand;" \
+ " nboot linux\0" \
+ "bootcmd_net=setenv autostart yes;run bootargs_nfs; dhcp\0" \
+ "bootargs_mmc=run default_bootargs;setenv bootargs ${bootargs}" \
+ " root=/dev/mmcblk0p3 rootwait\0" \
+ "bootargs_nand=run default_bootargs;setenv bootargs ${bootargs}"\
+ " ${mtdparts} root=/dev/mtdblock3 rootfstype=jffs2\0" \
+ "nfsroot=/tftpboot/rootfs\0" \
+ "bootargs_nfs=run default_bootargs;setenv bootargs ${bootargs}" \
+ " root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},nolock\0"\
+ "default_bootargs=set bootargs " CONFIG_BOOTARGS \
+ " mxsfb.mode=${video_mode}\0" \
+ "mtdids=" MTDIDS_DEFAULT "\0" \
+ "mtdparts=" MTDPARTS_DEFAULT "\0" \
+ "video_mode=VGA\0"
+
+#define MTD_NAME "gpmi-nand"
+#define MTDIDS_DEFAULT "nand0=" MTD_NAME
+
+/*
+ * U-Boot Commands
+ */
+#define CONFIG_SYS_NO_FLASH
+#include <config_cmd_default.h>
+#define CONFIG_ARCH_CPU_INIT
+#define CONFIG_DISPLAY_CPUINFO
+
+/*
+ * Serial Driver
+ */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_PL011_CLOCK 24000000
+#define CONFIG_PL01x_PORTS { (void *)MXS_UARTDBG_BASE }
+#define CONFIG_CONS_INDEX 0
+#define CONFIG_BAUDRATE 115200 /* Default baud rate */
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++#define CONFIG_SPL_SERIAL_SUPPORT
+
+/*
+ * FEC Driver
+ */
+#define CONFIG_FEC_MXC
+#ifdef CONFIG_FEC_MXC
+/* This is required for the FEC driver to work with cache enabled */
+#define CONFIG_SYS_ARM_CACHE_WRITETHROUGH
+
+#define CONFIG_FEC_MXC_MULTI
+
+#define CONFIG_MII
+#define CONFIG_FEC_XCV_TYPE RMII
+#define CONFIG_GET_FEC_MAC_ADDR_FROM_IIM
+#define CONFIG_NET_MULTI
+#define CONFIG_ETH_PRIME
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_PING
+/* Add for working with "strict" DHCP server */
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_DNS
+#endif
+
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_MTDPARTS
+
+/*
+ * NAND flash driver
+ */
+#ifdef CONFIG_CMD_NAND
+#define CONFIG_MTD_DEVICE
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_NAND_MXS
+#define CONFIG_APBH_DMA
+#define CONFIG_APBH_DMA_BURST
+#define CONFIG_APBH_DMA_BURST8
+#define CONFIG_CMD_NAND_TRIMFFS
+#define CONFIG_SYS_MXS_DMA_CHANNEL 4
+#define CONFIG_SYS_MAX_FLASH_SECT 1024
+#define CONFIG_SYS_MAX_FLASH_BANKS 1
+#define CONFIG_SYS_NAND_MAX_CHIPS 1
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define CONFIG_SYS_NAND_USE_FLASH_BBT
+#ifdef CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_ENV_OFFSET 0x20000
+#define CONFIG_ENV_SIZE 0x20000 /* 128 KiB */
+#if 0
+#define CONFIG_ENV_OFFSET_REDUND 0x40000
+#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
+#endif
+#endif
+#ifndef CONFIG_SYS_NO_FLASH
+#define CONFIG_CMD_FLASH
+#define CONFIG_SYS_NAND_BASE 0xa0000000
+#define CONFIG_FIT
+#define CONFIG_OF_LIBFDT
+#else
+#define CONFIG_SYS_NAND_BASE 0x00000000
+#define CONFIG_CMD_ROMUPDATE
+#endif
+#endif /* CONFIG_CMD_NAND */
+
+/*
+ * MMC Driver
+ */
+#ifdef CONFIG_CMD_MMC
+#ifndef CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_IS_IN_MMC
+#endif
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_MXS_MMC
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_FAT
+
+#define CONFIG_BOOT_PARTITION_ACCESS
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+
+/*
+ * Environments on MMC
+ */
+#ifdef CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV 0
+#define CONFIG_CMD_ENV
+#define CONFIG_ENV_OVERWRITE
+/* Assoiated with the MMC layout defined in mmcops.c */
+#define CONFIG_ENV_OFFSET 0x400 /* 1 KB */
+#define CONFIG_ENV_SIZE (0x20000 - 0x400) /* 127 KB */
+#define CONFIG_DYNAMIC_MMC_DEVNO
+#endif /* CONFIG_ENV_IS_IN_MMC */
+#endif /* CONFIG_CMD_MMC */
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+#define MTDPARTS_DEFAULT "mtdparts=" MTD_NAME ":128k@" \
+ xstr(CONFIG_ENV_OFFSET) \
+ "(env)," \
+ xstr(CONFIG_ENV_OFFSET_REDUND) \
+ "(env2),1m(u-boot),4m(linux),16m(rootfs),-(userfs)"
+#else
+#define MTDPARTS_DEFAULT "mtdparts=" MTD_NAME ":128k@" \
+ xstr(CONFIG_ENV_OFFSET) \
+ "(env),1m(u-boot),4m(linux),16m(rootfs),-(userfs)"
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \
+ GENERATED_GBL_DATA_SIZE)
+
+#endif /* __CONFIG_H */
u_long mmio; /* Memory mapped registers */
} vidinfo_t;
+ #elif defined(CONFIG_EXYNOS_FB)
+
+ enum {
+ FIMD_RGB_INTERFACE = 1,
+ FIMD_CPU_INTERFACE = 2,
+ };
+
+ typedef struct vidinfo {
+ ushort vl_col; /* Number of columns (i.e. 640) */
+ ushort vl_row; /* Number of rows (i.e. 480) */
+ ushort vl_width; /* Width of display area in millimeters */
+ ushort vl_height; /* Height of display area in millimeters */
+
+ /* LCD configuration register */
+ u_char vl_freq; /* Frequency */
+ u_char vl_clkp; /* Clock polarity */
+ u_char vl_oep; /* Output Enable polarity */
+ u_char vl_hsp; /* Horizontal Sync polarity */
+ u_char vl_vsp; /* Vertical Sync polarity */
+ u_char vl_dp; /* Data polarity */
+ u_char vl_bpix; /* Bits per pixel */
+
+ /* Horizontal control register. Timing from data sheet */
+ u_char vl_hspw; /* Horz sync pulse width */
+ u_char vl_hfpd; /* Wait before of line */
+ u_char vl_hbpd; /* Wait end of line */
+
+ /* Vertical control register. */
+ u_char vl_vspw; /* Vertical sync pulse width */
+ u_char vl_vfpd; /* Wait before of frame */
+ u_char vl_vbpd; /* Wait end of frame */
+ u_char vl_cmd_allow_len; /* Wait end of frame */
+
+ void (*cfg_gpio)(void);
+ void (*backlight_on)(unsigned int onoff);
+ void (*reset_lcd)(void);
+ void (*lcd_power_on)(void);
+ void (*cfg_ldo)(void);
+ void (*enable_ldo)(unsigned int onoff);
+ void (*mipi_power)(void);
+ void (*backlight_reset)(void);
+
+ unsigned int win_id;
+ unsigned int init_delay;
+ unsigned int power_on_delay;
+ unsigned int reset_delay;
+ unsigned int interface_mode;
+ unsigned int mipi_enabled;
+ unsigned int cs_setup;
+ unsigned int wr_setup;
+ unsigned int wr_act;
+ unsigned int wr_hold;
+
+ /* parent clock name(MPLL, EPLL or VPLL) */
+ unsigned int pclk_name;
+ /* ratio value for source clock from parent clock. */
+ unsigned int sclk_div;
+
+ unsigned int dual_lcd_enabled;
+
+ } vidinfo_t;
+
+ void init_panel_info(vidinfo_t *vid);
+
+#elif defined(CONFIG_MXC2_LCD)
+
+typedef struct vidinfo {
+ u_long vl_refresh; /* Refresh Rate Hz */
+ u_long vl_row; /* resolution in x */
+ u_long vl_col; /* resolution in y */
+ u_long vl_pixclock; /* pixel clock in picoseconds */
+ u_long vl_left_margin; /* Horizontal back porch */
+ u_long vl_right_margin; /* Horizontal front porch */
+ u_long vl_upper_margin; /* Vertical back porch */
+ u_long vl_lower_margin; /* Vertical front porch */
+ u_long vl_hsync; /* Horizontal sync pulse length */
+ u_long vl_vsync; /* Vertical sync pulse length */
+ u_long vl_sync; /* Polarity on data enable */
+ u_long vl_mode; /* Video Mode */
+ u_long vl_flag;
+ u_char vl_bpix;
+ ushort *cmap;
+} vidinfo_t;
+
+#elif defined(CONFIG_MXC_EPDC)
+
+struct waveform_modes {
+ int mode_init;
+ int mode_du;
+ int mode_gc4;
+ int mode_gc8;
+ int mode_gc16;
+ int mode_gc32;
+};
+
+struct epdc_data_struct {
+ /* EPDC buffer pointers */
+ u_long working_buf_addr;
+ u_long waveform_buf_addr;
+
+ /* Waveform mode definitions */
+ struct waveform_modes wv_modes;
+};
+
+typedef struct vidinfo {
+ u_long vl_refresh; /* Refresh Rate Hz */
+ u_long vl_row; /* resolution in x */
+ u_long vl_col; /* resolution in y */
+ u_long vl_pixclock; /* pixel clock in picoseconds */
+ u_long vl_left_margin; /* Horizontal back porch */
+ u_long vl_right_margin; /* Horizontal front porch */
+ u_long vl_upper_margin; /* Vertical back porch */
+ u_long vl_lower_margin; /* Vertical front porch */
+ u_long vl_hsync; /* Horizontal sync pulse length */
+ u_long vl_vsync; /* Vertical sync pulse length */
+ u_long vl_sync; /* Polarity on data enable */
+ u_long vl_mode; /* Video Mode */
+ u_long vl_flag;
+ u_char vl_bpix;
+ ushort *cmap;
+ struct epdc_data_struct epdc_data;
+} vidinfo_t;
+
#else
typedef struct vidinfo {