diff options
Diffstat (limited to 'arch/arm/cpu/arm926ejs/mxs')
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/Makefile | 10 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/clock.c | 93 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/mxs.c | 65 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/spl_boot.c | 7 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c | 46 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 50 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/u-boot-imx23.bd | 4 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd | 4 |
8 files changed, 176 insertions, 103 deletions
diff --git a/arch/arm/cpu/arm926ejs/mxs/Makefile b/arch/arm/cpu/arm926ejs/mxs/Makefile index eeecf89f8b..038c1c1d82 100644 --- a/arch/arm/cpu/arm926ejs/mxs/Makefile +++ b/arch/arm/cpu/arm926ejs/mxs/Makefile @@ -40,6 +40,16 @@ all: $(obj).depend $(LIB) $(LIB): $(OBJS) $(call cmd_link_o_target, $(OBJS)) +# Specify the target for use in elftosb call +ELFTOSB_TARGET-$(CONFIG_MX23) = imx23 +ELFTOSB_TARGET-$(CONFIG_MX28) = imx28 + +$(OBJTREE)/u-boot.bd: $(SRCTREE)/$(CPUDIR)/$(SOC)/u-boot-$(ELFTOSB_TARGET-y).bd + sed "s@OBJTREE@$(OBJTREE)@g" $^ > $@ + +$(OBJTREE)/u-boot.sb: $(OBJTREE)/u-boot.bin $(OBJTREE)/spl/u-boot-spl.bin $(OBJTREE)/u-boot.bd + elftosb -zf $(ELFTOSB_TARGET-y) -c $(OBJTREE)/u-boot.bd -o $(OBJTREE)/u-boot.sb + ######################################################################### # defines $(obj).depend target diff --git a/arch/arm/cpu/arm926ejs/mxs/clock.c b/arch/arm/cpu/arm926ejs/mxs/clock.c index 43e766334c..f94107fc15 100644 --- a/arch/arm/cpu/arm926ejs/mxs/clock.c +++ b/arch/arm/cpu/arm926ejs/mxs/clock.c @@ -325,6 +325,99 @@ void mxs_set_ssp_busclock(unsigned int bus, uint32_t freq) bus, tgtclk, freq); } +void mxs_set_lcdclk(uint32_t freq) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + uint32_t fp, x, k_rest, k_best, x_best, tk; + int32_t k_best_l = 999, k_best_t = 0, x_best_l = 0xff, x_best_t = 0xff; + + if (freq == 0) + return; + +#if defined(CONFIG_MX23) + writel(CLKCTRL_CLKSEQ_BYPASS_PIX, &clkctrl_regs->hw_clkctrl_clkseq_clr); +#elif defined(CONFIG_MX28) + writel(CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF, &clkctrl_regs->hw_clkctrl_clkseq_clr); +#endif + + /* + * / 18 \ 1 1 + * freq kHz = | 480000000 Hz * -- | * --- * ------ + * \ x / k 1000 + * + * 480000000 Hz 18 + * ------------ * -- + * freq kHz x + * k = ------------------- + * 1000 + */ + + fp = ((PLL_FREQ_KHZ * 1000) / freq) * 18; + + for (x = 18; x <= 35; x++) { + tk = fp / x; + if ((tk / 1000 == 0) || (tk / 1000 > 255)) + continue; + + k_rest = tk % 1000; + + if (k_rest < (k_best_l % 1000)) { + k_best_l = tk; + x_best_l = x; + } + + if (k_rest > (k_best_t % 1000)) { + k_best_t = tk; + x_best_t = x; + } + } + + if (1000 - (k_best_t % 1000) > (k_best_l % 1000)) { + k_best = k_best_l; + x_best = x_best_l; + } else { + k_best = k_best_t; + x_best = x_best_t; + } + + k_best /= 1000; + +#if defined(CONFIG_MX23) + writeb(CLKCTRL_FRAC_CLKGATE, + &clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_PIX]); + writeb(CLKCTRL_FRAC_CLKGATE | (x_best & CLKCTRL_FRAC_FRAC_MASK), + &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_PIX]); + writeb(CLKCTRL_FRAC_CLKGATE, + &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_PIX]); + + writel(CLKCTRL_PIX_CLKGATE, + &clkctrl_regs->hw_clkctrl_pix_set); + clrsetbits_le32(&clkctrl_regs->hw_clkctrl_pix, + CLKCTRL_PIX_DIV_MASK | CLKCTRL_PIX_CLKGATE, + k_best << CLKCTRL_PIX_DIV_OFFSET); + + while (readl(&clkctrl_regs->hw_clkctrl_pix) & CLKCTRL_PIX_BUSY) + ; +#elif defined(CONFIG_MX28) + writeb(CLKCTRL_FRAC_CLKGATE, + &clkctrl_regs->hw_clkctrl_frac1_set[CLKCTRL_FRAC1_PIX]); + writeb(CLKCTRL_FRAC_CLKGATE | (x_best & CLKCTRL_FRAC_FRAC_MASK), + &clkctrl_regs->hw_clkctrl_frac1[CLKCTRL_FRAC1_PIX]); + writeb(CLKCTRL_FRAC_CLKGATE, + &clkctrl_regs->hw_clkctrl_frac1_clr[CLKCTRL_FRAC1_PIX]); + + writel(CLKCTRL_DIS_LCDIF_CLKGATE, + &clkctrl_regs->hw_clkctrl_lcdif_set); + clrsetbits_le32(&clkctrl_regs->hw_clkctrl_lcdif, + CLKCTRL_DIS_LCDIF_DIV_MASK | CLKCTRL_DIS_LCDIF_CLKGATE, + k_best << CLKCTRL_DIS_LCDIF_DIV_OFFSET); + + while (readl(&clkctrl_regs->hw_clkctrl_lcdif) & CLKCTRL_DIS_LCDIF_BUSY) + ; +#endif +} + uint32_t mxc_get_clock(enum mxc_clock clk) { switch (clk) { diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c index e2b41965db..a5e388b5ad 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxs.c +++ b/arch/arm/cpu/arm926ejs/mxs/mxs.c @@ -30,7 +30,7 @@ #include <asm/errno.h> #include <asm/io.h> #include <asm/arch/clock.h> -#include <asm/arch/dma.h> +#include <asm/imx-common/dma.h> #include <asm/arch/gpio.h> #include <asm/arch/iomux.h> #include <asm/arch/imx-regs.h> @@ -39,12 +39,6 @@ DECLARE_GLOBAL_DATA_PTR; -/* 1 second delay should be plenty of time for block reset. */ -#define RESET_MAX_TIMEOUT 1000000 - -#define MXS_BLOCK_SFTRST (1 << 31) -#define MXS_BLOCK_CLKGATE (1 << 30) - /* Lowlevel init isn't used on i.MX28, so just have a dummy here */ inline void lowlevel_init(void) {} @@ -82,63 +76,6 @@ void enable_caches(void) #endif } -int mxs_wait_mask_set(struct mxs_register_32 *reg, uint32_t mask, unsigned - int timeout) -{ - while (--timeout) { - if ((readl(®->reg) & mask) == mask) - break; - udelay(1); - } - - return !timeout; -} - -int mxs_wait_mask_clr(struct mxs_register_32 *reg, uint32_t mask, unsigned - int timeout) -{ - while (--timeout) { - if ((readl(®->reg) & mask) == 0) - break; - udelay(1); - } - - return !timeout; -} - -int mxs_reset_block(struct mxs_register_32 *reg) -{ - /* Clear SFTRST */ - writel(MXS_BLOCK_SFTRST, ®->reg_clr); - - if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) - return 1; - - /* Clear CLKGATE */ - writel(MXS_BLOCK_CLKGATE, ®->reg_clr); - - /* Set SFTRST */ - writel(MXS_BLOCK_SFTRST, ®->reg_set); - - /* Wait for CLKGATE being set */ - if (mxs_wait_mask_set(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) - return 1; - - /* Clear SFTRST */ - writel(MXS_BLOCK_SFTRST, ®->reg_clr); - - if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) - return 1; - - /* Clear CLKGATE */ - writel(MXS_BLOCK_CLKGATE, ®->reg_clr); - - if (mxs_wait_mask_clr(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) - return 1; - - return 0; -} - void mx28_fixup_vt(uint32_t start_addr) { uint32_t *vt = (uint32_t *)0x20; diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index 7e7044033e..ed525e58f3 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c @@ -148,10 +148,3 @@ inline void board_init_r(gd_t *id, ulong dest_addr) for (;;) ; } - -void hang(void) __attribute__ ((noreturn)); -void hang(void) -{ - for (;;) - ; -} diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c index bc2d69c857..07db27927f 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c @@ -110,6 +110,7 @@ __weak void mxs_adjust_memory_params(uint32_t *dram_vals) { } +#ifdef CONFIG_MX28 static void initialize_dram_values(void) { int i; @@ -118,15 +119,36 @@ static void initialize_dram_values(void) for (i = 0; i < ARRAY_SIZE(dram_vals); i++) writel(dram_vals[i], MXS_DRAM_BASE + (4 * i)); +} +#else +static void initialize_dram_values(void) +{ + int i; + + mxs_adjust_memory_params(dram_vals); + + /* + * HW_DRAM_CTL27, HW_DRAM_CTL28 and HW_DRAM_CTL35 are not initialized as + * per FSL bootlets code. + * + * mx23 Reference Manual marks HW_DRAM_CTL27 and HW_DRAM_CTL28 as + * "reserved". + * HW_DRAM_CTL8 is setup as the last element. + * So skip the initialization of these HW_DRAM_CTL registers. + */ + for (i = 0; i < ARRAY_SIZE(dram_vals); i++) { + if (i == 8 || i == 27 || i == 28 || i == 35) + continue; + writel(dram_vals[i], MXS_DRAM_BASE + (4 * i)); + } -#ifdef CONFIG_MX23 /* * Enable tRAS lockout in HW_DRAM_CTL08 ; it must be the last * element to be set */ writel((1 << 24), MXS_DRAM_BASE + (4 * 8)); -#endif } +#endif static void mxs_mem_init_clock(void) { @@ -234,17 +256,9 @@ static void mx23_mem_setup_vddmem(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; - writel((0x10 << POWER_VDDMEMCTRL_TRG_OFFSET) | - POWER_VDDMEMCTRL_ENABLE_ILIMIT | - POWER_VDDMEMCTRL_ENABLE_LINREG | - POWER_VDDMEMCTRL_PULLDOWN_ACTIVE, - &power_regs->hw_power_vddmemctrl); + clrbits_le32(&power_regs->hw_power_vddmemctrl, + POWER_VDDMEMCTRL_ENABLE_ILIMIT); - early_delay(10000); - - writel((0x10 << POWER_VDDMEMCTRL_TRG_OFFSET) | - POWER_VDDMEMCTRL_ENABLE_LINREG, - &power_regs->hw_power_vddmemctrl); } static void mx23_mem_init(void) @@ -267,22 +281,18 @@ static void mx23_mem_init(void) initialize_dram_values(); - /* Set START bit in DRAM_CTL16 */ + /* Set START bit in DRAM_CTL8 */ setbits_le32(MXS_DRAM_BASE + 0x20, 1 << 16); clrbits_le32(MXS_DRAM_BASE + 0x40, 1 << 17); early_delay(20000); /* Adjust EMI port priority. */ - clrsetbits_le32(0x80020000, 0x1f << 16, 0x8); + clrsetbits_le32(0x80020000, 0x1f << 16, 0x2); early_delay(20000); setbits_le32(MXS_DRAM_BASE + 0x40, 1 << 19); setbits_le32(MXS_DRAM_BASE + 0x40, 1 << 11); - - /* Wait for bit 10 (DRAM init complete) in DRAM_CTL18 */ - while (!(readl(MXS_DRAM_BASE + 0x48) & (1 << 10))) - ; } #endif diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c index 287c698ff7..21cac7b332 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c @@ -687,6 +687,12 @@ static void mxs_power_configure_power_source(void) mxs_init_batt_bo(); mxs_switch_vddd_to_dcdc_source(); + +#ifdef CONFIG_MX23 + /* Fire up the VDDMEM LinReg now that we're all set. */ + writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT, + &power_regs->hw_power_vddmemctrl); +#endif } static void mxs_enable_output_rail_protection(void) @@ -781,7 +787,11 @@ struct mxs_vddx_cfg { static const struct mxs_vddx_cfg mxs_vddio_cfg = { .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)-> hw_power_vddioctrl), +#if defined(CONFIG_MX23) + .step_mV = 25, +#else .step_mV = 50, +#endif .lowest_mV = 2800, .powered_by_linreg = mxs_get_vddio_power_source_off, .trg_mask = POWER_VDDIOCTRL_TRG_MASK, @@ -804,6 +814,21 @@ static const struct mxs_vddx_cfg mxs_vddd_cfg = { .bo_offset_offset = POWER_VDDDCTRL_BO_OFFSET_OFFSET, }; +#ifdef CONFIG_MX23 +static const struct mxs_vddx_cfg mxs_vddmem_cfg = { + .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)-> + hw_power_vddmemctrl), + .step_mV = 50, + .lowest_mV = 1700, + .powered_by_linreg = NULL, + .trg_mask = POWER_VDDMEMCTRL_TRG_MASK, + .bo_irq = 0, + .bo_enirq = 0, + .bo_offset_mask = 0, + .bo_offset_offset = 0, +}; +#endif + static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg, uint32_t new_target, uint32_t new_brownout) { @@ -821,9 +846,10 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg, cur_target += cfg->lowest_mV; adjust_up = new_target > cur_target; - powered_by_linreg = cfg->powered_by_linreg(); + if (cfg->powered_by_linreg) + powered_by_linreg = cfg->powered_by_linreg(); - if (adjust_up) { + if (adjust_up && cfg->bo_irq) { if (powered_by_linreg) { bo_int = readl(cfg->reg); clrbits_le32(cfg->reg, cfg->bo_enirq); @@ -864,14 +890,16 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg, cur_target += cfg->lowest_mV; } while (new_target > cur_target); - if (adjust_up && powered_by_linreg) { - writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr); - if (bo_int & cfg->bo_enirq) - setbits_le32(cfg->reg, cfg->bo_enirq); - } + if (cfg->bo_irq) { + if (adjust_up && powered_by_linreg) { + writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr); + if (bo_int & cfg->bo_enirq) + setbits_le32(cfg->reg, cfg->bo_enirq); + } - clrsetbits_le32(cfg->reg, cfg->bo_offset_mask, - new_brownout << cfg->bo_offset_offset); + clrsetbits_le32(cfg->reg, cfg->bo_offset_mask, + new_brownout << cfg->bo_offset_offset); + } } static void mxs_setup_batt_detect(void) @@ -910,7 +938,9 @@ void mxs_power_init(void) mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150); mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000); - +#ifdef CONFIG_MX23 + mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700); +#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 | diff --git a/arch/arm/cpu/arm926ejs/mxs/u-boot-imx23.bd b/arch/arm/cpu/arm926ejs/mxs/u-boot-imx23.bd index 3a51879d5e..8b6c30e8e9 100644 --- a/arch/arm/cpu/arm926ejs/mxs/u-boot-imx23.bd +++ b/arch/arm/cpu/arm926ejs/mxs/u-boot-imx23.bd @@ -4,8 +4,8 @@ options { } sources { - u_boot_spl="spl/u-boot-spl.bin"; - u_boot="u-boot.bin"; + u_boot_spl="OBJTREE/spl/u-boot-spl.bin"; + u_boot="OBJTREE/u-boot.bin"; } section (0) { diff --git a/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd b/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd index c60615a456..a5fa6483a9 100644 --- a/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd +++ b/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd @@ -1,6 +1,6 @@ sources { - u_boot_spl="spl/u-boot-spl.bin"; - u_boot="u-boot.bin"; + u_boot_spl="OBJTREE/spl/u-boot-spl.bin"; + u_boot="OBJTREE/u-boot.bin"; } section (0) { |