diff options
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/clock.c | 2 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/spl_boot.c | 4 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c | 38 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 305 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/board.c | 85 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/clock.c | 8 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/exynos/clock.c | 17 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/exynos/pinmux.c | 80 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap3/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap3/am35x_musb.c | 75 |
10 files changed, 358 insertions, 257 deletions
diff --git a/arch/arm/cpu/arm926ejs/mxs/clock.c b/arch/arm/cpu/arm926ejs/mxs/clock.c index bfea6abeb0..4ff19c37ef 100644 --- a/arch/arm/cpu/arm926ejs/mxs/clock.c +++ b/arch/arm/cpu/arm926ejs/mxs/clock.c @@ -333,6 +333,8 @@ uint32_t mxc_get_clock(enum mxc_clock clk) return mx28_get_sspclk(MXC_SSPCLK2); case MXC_SSP3_CLK: return mx28_get_sspclk(MXC_SSPCLK3); + case MXC_XTAL_CLK: + return XTAL_FREQ_KHZ * 1000; } return 0; diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index 8ea7c36f46..1b8502eb9d 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c @@ -50,7 +50,7 @@ void early_delay(int delay) } #define MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL) -const iomux_cfg_t iomux_boot[] = { +static 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, @@ -59,7 +59,7 @@ const iomux_cfg_t iomux_boot[] = { MX28_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD, }; -uint8_t mxs_get_bootmode_index(void) +static uint8_t mxs_get_bootmode_index(void) { uint8_t bootmode = 0; int i; diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c index e693145b90..401c51362b 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c @@ -30,7 +30,11 @@ #include "mxs_init.h" -static uint32_t mx28_dram_vals[] = { +static uint32_t dram_vals[] = { +/* + * i.MX28 DDR2 at 200MHz + */ +#if defined(CONFIG_MX28) 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -79,6 +83,9 @@ static uint32_t mx28_dram_vals[] = { 0x06120612, 0x04320432, 0x04320432, 0x00040004, 0x00040004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010001 +#else +#error Unsupported memory initialization +#endif }; void __mxs_adjust_memory_params(uint32_t *dram_vals) @@ -87,17 +94,17 @@ void __mxs_adjust_memory_params(uint32_t *dram_vals) void mxs_adjust_memory_params(uint32_t *dram_vals) __attribute__((weak, alias("__mxs_adjust_memory_params"))); -void init_mx28_200mhz_ddr2(void) +static void initialize_dram_values(void) { int i; - mxs_adjust_memory_params(mx28_dram_vals); + mxs_adjust_memory_params(dram_vals); - for (i = 0; i < ARRAY_SIZE(mx28_dram_vals); i++) - writel(mx28_dram_vals[i], MXS_DRAM_BASE + (4 * i)); + for (i = 0; i < ARRAY_SIZE(dram_vals); i++) + writel(dram_vals[i], MXS_DRAM_BASE + (4 * i)); } -void mxs_mem_init_clock(void) +static void mxs_mem_init_clock(void) { struct mxs_clkctrl_regs *clkctrl_regs = (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; @@ -128,7 +135,7 @@ void mxs_mem_init_clock(void) early_delay(10000); } -void mxs_mem_setup_cpu_and_hbus(void) +static void mxs_mem_setup_cpu_and_hbus(void) { struct mxs_clkctrl_regs *clkctrl_regs = (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; @@ -160,7 +167,7 @@ void mxs_mem_setup_cpu_and_hbus(void) early_delay(15000); } -void mxs_mem_setup_vdda(void) +static void mxs_mem_setup_vdda(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -171,17 +178,6 @@ void mxs_mem_setup_vdda(void) &power_regs->hw_power_vddactrl); } -void mxs_mem_setup_vddd(void) -{ - struct mxs_power_regs *power_regs = - (struct mxs_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); -} - uint32_t mxs_mem_get_size(void) { uint32_t sz, da; @@ -229,7 +225,7 @@ void mxs_mem_init(void) /* Clear START bit from DRAM_CTL16 */ clrbits_le32(MXS_DRAM_BASE + 0x40, 1); - init_mx28_200mhz_ddr2(); + initialize_dram_values(); /* Clear SREFRESH bit from DRAM_CTL17 */ clrbits_le32(MXS_DRAM_BASE + 0x44, 1); @@ -241,8 +237,6 @@ void mxs_mem_init(void) while (!(readl(MXS_DRAM_BASE + 0xe8) & (1 << 20))) ; - mxs_mem_setup_vddd(); - early_delay(10000); mxs_mem_setup_cpu_and_hbus(); diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c index 4b917bd186..be44c22976 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c @@ -30,7 +30,7 @@ #include "mxs_init.h" -void mxs_power_clock2xtal(void) +static void mxs_power_clock2xtal(void) { struct mxs_clkctrl_regs *clkctrl_regs = (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; @@ -40,7 +40,7 @@ void mxs_power_clock2xtal(void) &clkctrl_regs->hw_clkctrl_clkseq_set); } -void mxs_power_clock2pll(void) +static void mxs_power_clock2pll(void) { struct mxs_clkctrl_regs *clkctrl_regs = (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; @@ -52,7 +52,7 @@ void mxs_power_clock2pll(void) CLKCTRL_CLKSEQ_BYPASS_CPU); } -void mxs_power_clear_auto_restart(void) +static void mxs_power_clear_auto_restart(void) { struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE; @@ -85,7 +85,7 @@ void mxs_power_clear_auto_restart(void) ; } -void mxs_power_set_linreg(void) +static void mxs_power_set_linreg(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -104,7 +104,7 @@ void mxs_power_set_linreg(void) POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW); } -int mxs_get_batt_volt(void) +static int mxs_get_batt_volt(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -115,12 +115,12 @@ int mxs_get_batt_volt(void) return volt; } -int mxs_is_batt_ready(void) +static int mxs_is_batt_ready(void) { return (mxs_get_batt_volt() >= 3600); } -int mxs_is_batt_good(void) +static int mxs_is_batt_good(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -160,7 +160,7 @@ int mxs_is_batt_good(void) return 0; } -void mxs_power_setup_5v_detect(void) +static void mxs_power_setup_5v_detect(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -172,7 +172,7 @@ void mxs_power_setup_5v_detect(void) POWER_5VCTRL_PWRUP_VBUS_CMPS); } -void mxs_src_power_init(void) +static void mxs_src_power_init(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -203,7 +203,7 @@ void mxs_src_power_init(void) clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); } -void mxs_power_init_4p2_params(void) +static void mxs_power_init_4p2_params(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -227,7 +227,7 @@ void mxs_power_init_4p2_params(void) 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); } -void mxs_enable_4p2_dcdc_input(int xfer) +static void mxs_enable_4p2_dcdc_input(int xfer) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -323,7 +323,7 @@ void mxs_enable_4p2_dcdc_input(int xfer) POWER_CTRL_ENIRQ_VDD5V_DROOP); } -void mxs_power_init_4p2_regulator(void) +static void mxs_power_init_4p2_regulator(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -407,7 +407,7 @@ void mxs_power_init_4p2_regulator(void) writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr); } -void mxs_power_init_dcdc_4p2_source(void) +static void mxs_power_init_dcdc_4p2_source(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -429,7 +429,7 @@ void mxs_power_init_dcdc_4p2_source(void) } } -void mxs_power_enable_4p2(void) +static void mxs_power_enable_4p2(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -488,7 +488,7 @@ void mxs_power_enable_4p2(void) &power_regs->hw_power_charge_clr); } -void mxs_boot_valid_5v(void) +static void mxs_boot_valid_5v(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -511,7 +511,7 @@ void mxs_boot_valid_5v(void) mxs_power_enable_4p2(); } -void mxs_powerdown(void) +static void mxs_powerdown(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -520,7 +520,7 @@ void mxs_powerdown(void) &power_regs->hw_power_reset); } -void mxs_batt_boot(void) +static void mxs_batt_boot(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -564,7 +564,7 @@ void mxs_batt_boot(void) 0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); } -void mxs_handle_5v_conflict(void) +static void mxs_handle_5v_conflict(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -600,7 +600,7 @@ void mxs_handle_5v_conflict(void) } } -void mxs_5v_boot(void) +static void mxs_5v_boot(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -623,7 +623,7 @@ void mxs_5v_boot(void) mxs_handle_5v_conflict(); } -void mxs_init_batt_bo(void) +static void mxs_init_batt_bo(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -637,7 +637,7 @@ void mxs_init_batt_bo(void) writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr); } -void mxs_switch_vddd_to_dcdc_source(void) +static void mxs_switch_vddd_to_dcdc_source(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -651,7 +651,7 @@ void mxs_switch_vddd_to_dcdc_source(void) POWER_VDDDCTRL_DISABLE_STEPPING); } -void mxs_power_configure_power_source(void) +static void mxs_power_configure_power_source(void) { int batt_ready, batt_good; struct mxs_power_regs *power_regs = @@ -689,7 +689,7 @@ void mxs_power_configure_power_source(void) mxs_switch_vddd_to_dcdc_source(); } -void mxs_enable_output_rail_protection(void) +static void mxs_enable_output_rail_protection(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -707,7 +707,7 @@ void mxs_enable_output_rail_protection(void) POWER_VDDIOCTRL_PWDN_BRNOUT); } -int mxs_get_vddio_power_source_off(void) +static int mxs_get_vddio_power_source_off(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -735,7 +735,7 @@ int mxs_get_vddio_power_source_off(void) } -int mxs_get_vddd_power_source_off(void) +static int mxs_get_vddd_power_source_off(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; @@ -766,201 +766,115 @@ int mxs_get_vddd_power_source_off(void) return 0; } -void mxs_power_set_vddio(uint32_t new_target, uint32_t new_brownout) +struct mxs_vddx_cfg { + uint32_t *reg; + uint8_t step_mV; + uint16_t lowest_mV; + int (*powered_by_linreg)(void); + uint32_t trg_mask; + uint32_t bo_irq; + uint32_t bo_enirq; + uint32_t bo_offset_mask; + uint32_t bo_offset_offset; +}; + +static const struct mxs_vddx_cfg mxs_vddio_cfg = { + .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)-> + hw_power_vddioctrl), + .step_mV = 50, + .lowest_mV = 2800, + .powered_by_linreg = mxs_get_vddio_power_source_off, + .trg_mask = POWER_VDDIOCTRL_TRG_MASK, + .bo_irq = POWER_CTRL_VDDIO_BO_IRQ, + .bo_enirq = POWER_CTRL_ENIRQ_VDDIO_BO, + .bo_offset_mask = POWER_VDDIOCTRL_BO_OFFSET_MASK, + .bo_offset_offset = POWER_VDDIOCTRL_BO_OFFSET_OFFSET, +}; + +static const struct mxs_vddx_cfg mxs_vddd_cfg = { + .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)-> + hw_power_vdddctrl), + .step_mV = 25, + .lowest_mV = 800, + .powered_by_linreg = mxs_get_vddd_power_source_off, + .trg_mask = POWER_VDDDCTRL_TRG_MASK, + .bo_irq = POWER_CTRL_VDDD_BO_IRQ, + .bo_enirq = POWER_CTRL_ENIRQ_VDDD_BO, + .bo_offset_mask = POWER_VDDDCTRL_BO_OFFSET_MASK, + .bo_offset_offset = POWER_VDDDCTRL_BO_OFFSET_OFFSET, +}; + +static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg, + uint32_t new_target, uint32_t new_brownout) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; uint32_t cur_target, diff, bo_int = 0; uint32_t powered_by_linreg = 0; + int adjust_up, tmp; - new_brownout = (new_target - new_brownout + 25) / 50; + new_brownout = DIV_ROUND(new_target - new_brownout, cfg->step_mV); - cur_target = readl(&power_regs->hw_power_vddioctrl); - cur_target &= POWER_VDDIOCTRL_TRG_MASK; - cur_target *= 50; /* 50 mV step*/ - cur_target += 2800; /* 2800 mV lowest */ + cur_target = readl(cfg->reg); + cur_target &= cfg->trg_mask; + cur_target *= cfg->step_mV; + cur_target += cfg->lowest_mV; - powered_by_linreg = mxs_get_vddio_power_source_off(); - if (new_target > cur_target) { + adjust_up = new_target > cur_target; + powered_by_linreg = cfg->powered_by_linreg(); + if (adjust_up) { if (powered_by_linreg) { - bo_int = readl(&power_regs->hw_power_vddioctrl); - clrbits_le32(&power_regs->hw_power_vddioctrl, - POWER_CTRL_ENIRQ_VDDIO_BO); + bo_int = readl(cfg->reg); + clrbits_le32(cfg->reg, cfg->bo_enirq); } + setbits_le32(cfg->reg, cfg->bo_offset_mask); + } - setbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_BO_OFFSET_MASK); - do { - if (new_target - cur_target > 100) + do { + if (abs(new_target - cur_target) > 100) { + if (adjust_up) diff = cur_target + 100; else - diff = new_target; - - diff -= 2800; - diff /= 50; - - clrsetbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_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)) - ; - - } - - cur_target = readl(&power_regs->hw_power_vddioctrl); - cur_target &= POWER_VDDIOCTRL_TRG_MASK; - cur_target *= 50; /* 50 mV step*/ - cur_target += 2800; /* 2800 mV lowest */ - } while (new_target > cur_target); - - 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); - } - } else { - do { - if (cur_target - new_target > 100) diff = cur_target - 100; - else - diff = new_target; - - diff -= 2800; - diff /= 50; - - clrsetbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_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)) - ; - - } - - cur_target = readl(&power_regs->hw_power_vddioctrl); - cur_target &= POWER_VDDIOCTRL_TRG_MASK; - cur_target *= 50; /* 50 mV step*/ - cur_target += 2800; /* 2800 mV lowest */ - } while (new_target < cur_target); - } - - clrsetbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_BO_OFFSET_MASK, - new_brownout << POWER_VDDIOCTRL_BO_OFFSET_OFFSET); -} - -void mxs_power_set_vddd(uint32_t new_target, uint32_t new_brownout) -{ - struct mxs_power_regs *power_regs = - (struct mxs_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 + 12) / 25; - - 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 = mxs_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); + } else { + diff = new_target; } - 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; - - diff -= 800; - diff /= 25; - - clrsetbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_TRG_MASK, diff); + diff -= cfg->lowest_mV; + diff /= cfg->step_mV; - 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)) - ; + clrsetbits_le32(cfg->reg, cfg->trg_mask, diff); + if (powered_by_linreg || + (readl(&power_regs->hw_power_sts) & + POWER_STS_VDD5V_GT_VDDIO)) + early_delay(500); + else { + for (;;) { + tmp = readl(&power_regs->hw_power_sts); + if (tmp & POWER_STS_DC_OK) + break; } - - 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) { - 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; - diff -= 800; - diff /= 25; + cur_target = readl(cfg->reg); + cur_target &= cfg->trg_mask; + cur_target *= cfg->step_mV; + cur_target += cfg->lowest_mV; + } while (new_target > cur_target); - 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)) - ; - - } - - 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 (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(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_BO_OFFSET_MASK, - new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET); + clrsetbits_le32(cfg->reg, cfg->bo_offset_mask, + new_brownout << cfg->bo_offset_offset); } -void mxs_setup_batt_detect(void) +static void mxs_setup_batt_detect(void) { mxs_lradc_init(); mxs_lradc_enable_batt_measurement(); @@ -982,9 +896,8 @@ void mxs_power_init(void) mxs_power_configure_power_source(); mxs_enable_output_rail_protection(); - mxs_power_set_vddio(3300, 3150); - - mxs_power_set_vddd(1350, 1200); + mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150); + mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000); writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ | diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index e4c123cd21..da5bc73185 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -33,6 +33,11 @@ #include <i2c.h> #include <miiphy.h> #include <cpsw.h> +#include <asm/errno.h> +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> +#include <linux/usb/musb.h> +#include <asm/omap_musb.h> DECLARE_GLOBAL_DATA_PTR; @@ -63,3 +68,83 @@ void setup_clocks_for_console(void) /* Not yet implemented */ return; } + +/* AM33XX has two MUSB controllers which can be host or gadget */ +#if (defined(CONFIG_MUSB_GADGET) || defined(CONFIG_MUSB_HOST)) && \ + (defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1)) +static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; + +/* USB 2.0 PHY Control */ +#define CM_PHY_PWRDN (1 << 0) +#define CM_PHY_OTG_PWRDN (1 << 1) +#define OTGVDET_EN (1 << 19) +#define OTGSESSENDEN (1 << 20) + +static void am33xx_usb_set_phy_power(u8 on, u32 *reg_addr) +{ + if (on) { + clrsetbits_le32(reg_addr, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN, + OTGVDET_EN | OTGSESSENDEN); + } else { + clrsetbits_le32(reg_addr, 0, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN); + } +} + +static struct musb_hdrc_config musb_config = { + .multipoint = 1, + .dyn_fifo = 1, + .num_eps = 16, + .ram_bits = 12, +}; + +#ifdef CONFIG_AM335X_USB0 +static void am33xx_otg0_set_phy_power(u8 on) +{ + am33xx_usb_set_phy_power(on, &cdev->usb_ctrl0); +} + +struct omap_musb_board_data otg0_board_data = { + .set_phy_power = am33xx_otg0_set_phy_power, +}; + +static struct musb_hdrc_platform_data otg0_plat = { + .mode = CONFIG_AM335X_USB0_MODE, + .config = &musb_config, + .power = 50, + .platform_ops = &musb_dsps_ops, + .board_data = &otg0_board_data, +}; +#endif + +#ifdef CONFIG_AM335X_USB1 +static void am33xx_otg1_set_phy_power(u8 on) +{ + am33xx_usb_set_phy_power(on, &cdev->usb_ctrl1); +} + +struct omap_musb_board_data otg1_board_data = { + .set_phy_power = am33xx_otg1_set_phy_power, +}; + +static struct musb_hdrc_platform_data otg1_plat = { + .mode = CONFIG_AM335X_USB1_MODE, + .config = &musb_config, + .power = 50, + .platform_ops = &musb_dsps_ops, + .board_data = &otg1_board_data, +}; +#endif +#endif + +int arch_misc_init(void) +{ +#ifdef CONFIG_AM335X_USB0 + musb_register(&otg0_plat, &otg0_board_data, + (void *)AM335X_USB0_OTG_BASE); +#endif +#ifdef CONFIG_AM335X_USB1 + musb_register(&otg1_plat, &otg1_board_data, + (void *)AM335X_USB1_OTG_BASE); +#endif + return 0; +} diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c index bc2abb657c..0b4cb4e529 100644 --- a/arch/arm/cpu/armv7/am33xx/clock.c +++ b/arch/arm/cpu/armv7/am33xx/clock.c @@ -40,6 +40,7 @@ #define CLK_MODE_MASK 0xfffffff8 #define CLK_DIV_SEL 0xFFFFFFE0 #define CPGMAC0_IDLE 0x30000 +#define DPLL_CLKDCOLDO_GATE_CTRL 0x300 const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER; const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP; @@ -194,6 +195,11 @@ static void enable_per_clocks(void) writel(PRCM_MOD_EN, &cmrtc->rtcclkctrl); while (readl(&cmrtc->rtcclkctrl) != PRCM_MOD_EN) ; + + /* MUSB */ + writel(PRCM_MOD_EN, &cmper->usb0clkctrl); + while (readl(&cmper->usb0clkctrl) != PRCM_MOD_EN) + ; } static void mpu_pll_config(void) @@ -290,6 +296,8 @@ static void per_pll_config(void) while (readl(&cmwkup->idlestdpllper) != ST_DPLL_CLK) ; + + writel(DPLL_CLKDCOLDO_GATE_CTRL, &cmwkup->clkdcoldodpllper); } void ddr_pll_config(unsigned int ddrpll_m) diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index fe61f88af4..74599798c4 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -921,6 +921,21 @@ static int exynos5_set_spi_clk(enum periph_id periph_id, return 0; } +static unsigned long exynos4_get_i2c_clk(void) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + unsigned long sclk, aclk_100; + unsigned int ratio; + + sclk = get_pll_clk(APLL); + + ratio = (readl(&clk->div_top)) >> 4; + ratio &= 0xf; + aclk_100 = sclk / (ratio + 1); + return aclk_100; +} + unsigned long get_pll_clk(int pllreg) { if (cpu_is_exynos5()) @@ -941,6 +956,8 @@ unsigned long get_i2c_clk(void) { if (cpu_is_exynos5()) { return exynos5_get_i2c_clk(); + } else if (cpu_is_exynos4()) { + return exynos4_get_i2c_clk(); } else { debug("I2C clock is not set for this CPU\n"); return 0; diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index f02f441a8b..20a4b8414a 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -329,54 +329,60 @@ static int exynos5_pinmux_config(int peripheral, int flags) return 0; } -static int exynos4_mmc_config(int peripheral, int flags) +static void exynos4_i2c_config(int peripheral, int flags) { - struct exynos4_gpio_part2 *gpio2 = - (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2(); - struct s5p_gpio_bank *bank, *bank_ext; - int i; + struct exynos4_gpio_part1 *gpio1 = + (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1(); switch (peripheral) { - case PERIPH_ID_SDMMC0: - bank = &gpio2->k0; - bank_ext = &gpio2->k1; + case PERIPH_ID_I2C0: + s5p_gpio_cfg_pin(&gpio1->d1, 0, GPIO_FUNC(0x2)); + s5p_gpio_cfg_pin(&gpio1->d1, 1, GPIO_FUNC(0x2)); break; - case PERIPH_ID_SDMMC2: - bank = &gpio2->k2; - bank_ext = &gpio2->k3; + case PERIPH_ID_I2C1: + s5p_gpio_cfg_pin(&gpio1->d1, 2, GPIO_FUNC(0x2)); + s5p_gpio_cfg_pin(&gpio1->d1, 3, GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C2: + s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C3: + s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C4: + s5p_gpio_cfg_pin(&gpio1->b, 2, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->b, 3, GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C5: + s5p_gpio_cfg_pin(&gpio1->b, 6, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->b, 7, GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C6: + s5p_gpio_cfg_pin(&gpio1->c1, 3, GPIO_FUNC(0x4)); + s5p_gpio_cfg_pin(&gpio1->c1, 4, GPIO_FUNC(0x4)); + break; + case PERIPH_ID_I2C7: + s5p_gpio_cfg_pin(&gpio1->d0, 2, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->d0, 3, GPIO_FUNC(0x3)); break; - default: - return -1; - } - for (i = 0; i < 7; i++) { - if (i == 2) - continue; - s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); - s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); - s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); - } - if (flags & PINMUX_FLAG_8BIT_MODE) { - for (i = 3; i < 7; i++) { - s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x3)); - s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_NONE); - s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X); - } } - - return 0; } static int exynos4_pinmux_config(int peripheral, int flags) { switch (peripheral) { - case PERIPH_ID_SDMMC0: - case PERIPH_ID_SDMMC2: - return exynos4_mmc_config(peripheral, flags); - case PERIPH_ID_SDMMC1: - case PERIPH_ID_SDMMC3: - case PERIPH_ID_SDMMC4: - printf("SDMMC device %d not implemented\n", peripheral); - return -1; + case PERIPH_ID_I2C0: + case PERIPH_ID_I2C1: + case PERIPH_ID_I2C2: + case PERIPH_ID_I2C3: + case PERIPH_ID_I2C4: + case PERIPH_ID_I2C5: + case PERIPH_ID_I2C6: + case PERIPH_ID_I2C7: + exynos4_i2c_config(peripheral, flags); + break; default: debug("%s: invalid peripheral %d", __func__, peripheral); return -1; diff --git a/arch/arm/cpu/armv7/omap3/Makefile b/arch/arm/cpu/armv7/omap3/Makefile index ac597be25a..de167eea56 100644 --- a/arch/arm/cpu/armv7/omap3/Makefile +++ b/arch/arm/cpu/armv7/omap3/Makefile @@ -38,6 +38,7 @@ endif COBJS-$(CONFIG_DRIVER_TI_EMAC) += emac.o COBJS-$(CONFIG_EMIF4) += emif4.o COBJS-$(CONFIG_SDRC) += sdrc.o +COBJS-$(CONFIG_USB_MUSB_AM35X) += am35x_musb.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS)) diff --git a/arch/arm/cpu/armv7/omap3/am35x_musb.c b/arch/arm/cpu/armv7/omap3/am35x_musb.c new file mode 100644 index 0000000000..7183c4f248 --- /dev/null +++ b/arch/arm/cpu/armv7/omap3/am35x_musb.c @@ -0,0 +1,75 @@ +/* + * This file configures the internal USB PHY in AM35X. + * + * Copyright (C) 2012 Ilya Yanok <ilya.yanok@gmail.com> + * + * Based on omap_phy_internal.c code from Linux by + * Hema HK <hemahk@ti.com> + * + * 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. + * + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/am35x_def.h> + +void am35x_musb_reset(void) +{ + /* Reset the musb interface */ + clrsetbits_le32(&am35x_scm_general_regs->ip_sw_reset, + 0, USBOTGSS_SW_RST); + clrsetbits_le32(&am35x_scm_general_regs->ip_sw_reset, + USBOTGSS_SW_RST, 0); +} + +void am35x_musb_phy_power(u8 on) +{ + unsigned long start = get_timer(0); + + if (on) { + /* + * Start the on-chip PHY and its PLL. + */ + clrsetbits_le32(&am35x_scm_general_regs->devconf2, + CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN, + CONF2_PHY_PLLON); + + debug("Waiting for PHY clock good...\n"); + while (!(readl(&am35x_scm_general_regs->devconf2) + & CONF2_PHYCLKGD)) { + + if (get_timer(start) > CONFIG_SYS_HZ / 10) { + printf("musb PHY clock good timed out\n"); + break; + } + } + } else { + /* + * Power down the on-chip PHY. + */ + clrsetbits_le32(&am35x_scm_general_regs->devconf2, + CONF2_PHY_PLLON, + CONF2_PHYPWRDN | CONF2_OTGPWRDN); + } +} + +void am35x_musb_clear_irq(void) +{ + clrsetbits_le32(&am35x_scm_general_regs->lvl_intr_clr, + 0, USBOTGSS_INT_CLR); + readl(&am35x_scm_general_regs->lvl_intr_clr); +} + |