diff options
Diffstat (limited to 'arch/arm/mach-mxs/power-init.c')
-rw-r--r-- | arch/arm/mach-mxs/power-init.c | 277 |
1 files changed, 158 insertions, 119 deletions
diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index 977c6e4e27..595b51c5ba 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -25,6 +25,56 @@ #include <mach/regs-lradc.h> /* + * has_battery - true when this board has a battery. + */ +static int has_battery; + +/* + * use_battery_input - true when this board is supplied from the + * battery input, but has a DC source instead of a real battery + */ +static int use_battery_input; + +/* + * use_5v_input - true when this board can use the 5V input + */ +static int use_5v_input; + +static void mxs_power_status(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)IMX_POWER_BASE; + static int linregofs[] = { 0, 1, -1, -2 }; + + uint32_t vddio = readl(&power_regs->hw_power_vddioctrl); + uint32_t vdda = readl(&power_regs->hw_power_vddactrl); + uint32_t vddd = readl(&power_regs->hw_power_vdddctrl); + uint32_t vddmem = readl(&power_regs->hw_power_vddmemctrl); + + printf("vddio: %dmV (BO -%dmV), Linreg enabled, Linreg offset: %d, FET %sabled\n", + (vddio & 0x1f) * 50 + 2800, + ((vddio >> 8) & 0x7) * 50, + linregofs[((vdda >> 12) & 0x3)], + (vddio & (1 << 16)) ? "dis" : "en"); + printf("vdda: %dmV (BO -%dmV), Linreg %sabled, Linreg offset: %d, FET %sabled\n", + (vdda & 0x1f) * 25 + 1500, + ((vdda >> 8) & 0x7) * 25, + (vdda & (1 << 17)) ? "en" : "dis", + linregofs[((vdda >> 12) & 0x3)], + (vdda & (1 << 16)) ? "dis" : "en"); + printf("vddd: %dmV (BO -%dmV), Linreg %sabled, Linreg offset: %d, FET %sabled\n", + (vddd & 0x1f) * 25 + 800, + ((vddd >> 8) & 0x7) * 25, + (vddd & (1 << 21)) ? "en" : "dis", + linregofs[((vdda >> 16) & 0x3)], + (vdda & (1 << 20)) ? "dis" : "en"); + printf("vddmem: %dmV (BO -%dmV), Linreg %sabled\n", + (vddmem & 0x1f) * 25 + 1100, + ((vddmem >> 5) & 0x7) * 25, + (vddmem & (1 << 8)) ? "en" : "dis"); +} + +/* * This delay function is intended to be used only in early stage of boot, where * clock are not set up yet. The timer used here is reset on every boot and * takes a few seconds to roll. The boot doesn't take that long, so to keep the @@ -299,36 +349,6 @@ static void mxs_src_power_init(void) } /** - * mxs_power_init_4p2_params() - Configure the parameters of the 4P2 regulator - * - * This function configures the necessary parameters for the 4P2 linear - * regulator to supply the DC-DC converter from 5V input. - */ -static void mxs_power_init_4p2_params(void) -{ - struct mxs_power_regs *power_regs = - (struct mxs_power_regs *)IMX_POWER_BASE; - - /* Setup 4P2 parameters */ - clrsetbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK, - POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET)); - - clrsetbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_HEADROOM_ADJ_MASK, - 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET); - - clrsetbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_DROPOUT_CTRL_MASK, - POWER_DCDC4P2_DROPOUT_CTRL_100MV | - POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL); - - clrsetbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, - 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); -} - -/** * mxs_enable_4p2_dcdc_input() - Enable or disable the DCDC input from 4P2 * @xfer: Select if the input shall be enabled or disabled * @@ -431,16 +451,82 @@ static void mxs_enable_4p2_dcdc_input(int xfer) } /** - * mxs_power_init_4p2_regulator() - Start the 4P2 regulator + * mxs_power_init_dcdc_4p2_source() - Switch DC-DC converter to 4P2 source + * + * This function configures the DC-DC converter to be supplied from the 4P2 + * linear regulator. + */ +static void mxs_power_init_dcdc_4p2_source(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)IMX_POWER_BASE; + + if (!(readl(&power_regs->hw_power_dcdc4p2) & + POWER_DCDC4P2_ENABLE_DCDC)) { + hang(); + } + + mxs_enable_4p2_dcdc_input(1); + + if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) { + clrbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_ENABLE_DCDC); + writel(POWER_5VCTRL_ENABLE_DCDC, + &power_regs->hw_power_5vctrl_clr); + charger_4p2_disable(); + } +} + +/** + * mxs_power_enable_4p2() - Power up the 4P2 regulator * - * This function enables the 4P2 regulator and switches the DC-DC converter - * to use the 4P2 input. + * This function drives the process of powering up the 4P2 linear regulator + * and switching the DC-DC converter input over to the 4P2 linear regulator. */ -static void mxs_power_init_4p2_regulator(void) +static void mxs_power_enable_4p2(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)IMX_POWER_BASE; - uint32_t tmp, tmp2; + uint32_t vdddctrl, vddactrl, vddioctrl; + uint32_t tmp, tmp2, dropout_ctrl; + + vdddctrl = readl(&power_regs->hw_power_vdddctrl); + vddactrl = readl(&power_regs->hw_power_vddactrl); + vddioctrl = readl(&power_regs->hw_power_vddioctrl); + + setbits_le32(&power_regs->hw_power_vdddctrl, + POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG | + POWER_VDDDCTRL_PWDN_BRNOUT); + + setbits_le32(&power_regs->hw_power_vddactrl, + POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG | + POWER_VDDACTRL_PWDN_BRNOUT); + + setbits_le32(&power_regs->hw_power_vddioctrl, + POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT); + + /* Setup 4P2 parameters */ + clrsetbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK, + POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET)); + + clrsetbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_HEADROOM_ADJ_MASK, + 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET); + + if (has_battery || use_battery_input) + dropout_ctrl = POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL; + else + dropout_ctrl = POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2; + + clrsetbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_DROPOUT_CTRL_MASK, + POWER_DCDC4P2_DROPOUT_CTRL_100MV | + dropout_ctrl); + + clrsetbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, + 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2); @@ -516,65 +602,6 @@ static void mxs_power_init_4p2_regulator(void) clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK); writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr); -} - -/** - * mxs_power_init_dcdc_4p2_source() - Switch DC-DC converter to 4P2 source - * - * This function configures the DC-DC converter to be supplied from the 4P2 - * linear regulator. - */ -static void mxs_power_init_dcdc_4p2_source(void) -{ - struct mxs_power_regs *power_regs = - (struct mxs_power_regs *)IMX_POWER_BASE; - - if (!(readl(&power_regs->hw_power_dcdc4p2) & - POWER_DCDC4P2_ENABLE_DCDC)) { - hang(); - } - - mxs_enable_4p2_dcdc_input(1); - - if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) { - clrbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_ENABLE_DCDC); - writel(POWER_5VCTRL_ENABLE_DCDC, - &power_regs->hw_power_5vctrl_clr); - charger_4p2_disable(); - } -} - -/** - * mxs_power_enable_4p2() - Power up the 4P2 regulator - * - * This function drives the process of powering up the 4P2 linear regulator - * and switching the DC-DC converter input over to the 4P2 linear regulator. - */ -static void mxs_power_enable_4p2(void) -{ - struct mxs_power_regs *power_regs = - (struct mxs_power_regs *)IMX_POWER_BASE; - uint32_t vdddctrl, vddactrl, vddioctrl; - uint32_t tmp; - - vdddctrl = readl(&power_regs->hw_power_vdddctrl); - vddactrl = readl(&power_regs->hw_power_vddactrl); - vddioctrl = readl(&power_regs->hw_power_vddioctrl); - - setbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG | - POWER_VDDDCTRL_PWDN_BRNOUT); - - setbits_le32(&power_regs->hw_power_vddactrl, - POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG | - POWER_VDDACTRL_PWDN_BRNOUT); - - setbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT); - - mxs_power_init_4p2_params(); - mxs_power_init_4p2_regulator(); /* Shutdown battery (none present) */ if (!mxs_is_batt_ready()) { @@ -1021,6 +1048,19 @@ static const struct mxs_vddx_cfg mxs_vddmem_cfg = { .bo_offset_offset = 0, }; +static const struct mxs_vddx_cfg mxs_vdda_cfg = { + .reg = &(((struct mxs_power_regs *)IMX_POWER_BASE)-> + hw_power_vddactrl), + .step_mV = 25, + .lowest_mV = 1500, + .powered_by_linreg = NULL, + .trg_mask = POWER_VDDACTRL_TRG_MASK, + .bo_irq = POWER_CTRL_VDDA_BO_IRQ, + .bo_enirq = POWER_CTRL_ENIRQ_VDDA_BO, + .bo_offset_mask = POWER_VDDACTRL_BO_OFFSET_MASK, + .bo_offset_offset = POWER_VDDACTRL_BO_OFFSET_OFFSET, +}; + /** * mxs_power_set_vddx() - Configure voltage on DC-DC converter rail * @cfg: Configuration data of the DC-DC converter rail @@ -1143,11 +1183,16 @@ static void mx23_ungate_power(void) * This function calls all the power block initialization functions in * proper sequence to start the power block. */ -static void __mx23_power_init(int has_battery) +void mx23_power_init(int __has_battery, int __use_battery_input, + int __use_5v_input) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)IMX_POWER_BASE; + has_battery = __has_battery; + use_battery_input = __use_battery_input; + use_5v_input = __use_5v_input; + mx23_ungate_power(); mxs_power_clock2xtal(); @@ -1161,8 +1206,10 @@ static void __mx23_power_init(int has_battery) if (has_battery) mxs_power_configure_power_source(); - else + else if (use_battery_input) mxs_enable_battery_input(); + else if (use_5v_input) + mxs_boot_valid_5v(); mxs_power_clock2pll(); @@ -1177,8 +1224,9 @@ static void __mx23_power_init(int has_battery) mxs_enable_output_rail_protection(); mxs_power_set_vddx(&mx23_vddio_cfg, 3300, 3150); - mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000); + mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1325); mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700); + mxs_power_set_vddx(&mxs_vdda_cfg, 1800, 1650); writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ | @@ -1190,27 +1238,23 @@ static void __mx23_power_init(int has_battery) mxs_early_delay(1000); } -void mx23_power_init(void) -{ - __mx23_power_init(1); -} - -void mx23_power_init_battery_input(void) -{ - __mx23_power_init(0); -} - /** * mx28_power_init() - The power block init main function * * This function calls all the power block initialization functions in * proper sequence to start the power block. */ -static void __mx28_power_init(int has_battery) +void mx28_power_init(int __has_battery, int __use_battery_input, + int __use_5v_input) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)IMX_POWER_BASE; + has_battery = __has_battery; + use_battery_input = __use_battery_input; + use_5v_input = __use_5v_input; + + mxs_power_status(); mxs_power_clock2xtal(); mxs_power_set_auto_restart(); mxs_power_set_linreg(); @@ -1222,8 +1266,10 @@ static void __mx28_power_init(int has_battery) if (has_battery) mxs_power_configure_power_source(); - else + else if (use_battery_input) mxs_enable_battery_input(); + else if (use_5v_input) + mxs_boot_valid_5v(); mxs_power_clock2pll(); @@ -1234,7 +1280,8 @@ static void __mx28_power_init(int has_battery) mxs_enable_output_rail_protection(); mxs_power_set_vddx(&mx28_vddio_cfg, 3300, 3150); - mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000); + mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1325); + mxs_power_set_vddx(&mxs_vdda_cfg, 1800, 1650); writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ | @@ -1244,16 +1291,8 @@ static void __mx28_power_init(int has_battery) writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set); mxs_early_delay(1000); -} -void mx28_power_init(void) -{ - __mx28_power_init(1); -} - -void mx28_power_init_battery_input(void) -{ - __mx28_power_init(0); + mxs_power_status(); } /** |