diff options
Diffstat (limited to 'arch/arm/mach-omap2')
68 files changed, 1091 insertions, 916 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index fd3557d7ea7..08cc94474d1 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -113,7 +113,7 @@ obj-y += prm_common.o cm_common.o obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o -omap-prcm-4-5-common = cminst44xx.o cm44xx.o prm44xx.o \ +omap-prcm-4-5-common = cminst44xx.o prm44xx.o \ prcm_mpu44xx.o prminst44xx.o \ vc44xx_data.o vp44xx_data.o obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common) diff --git a/arch/arm/mach-omap2/am33xx-restart.c b/arch/arm/mach-omap2/am33xx-restart.c index c88d8df753c..5bace6a45ff 100644 --- a/arch/arm/mach-omap2/am33xx-restart.c +++ b/arch/arm/mach-omap2/am33xx-restart.c @@ -9,8 +9,7 @@ #include <linux/reboot.h> #include "common.h" -#include "prm-regbits-33xx.h" -#include "prm33xx.h" +#include "prm.h" /** * am3xx_restart - trigger a software restart of the SoC @@ -24,12 +23,5 @@ void am33xx_restart(enum reboot_mode mode, const char *cmd) { /* TODO: Handle mode and cmd if necessary */ - am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK, - AM33XX_RST_GLOBAL_WARM_SW_MASK, - AM33XX_PRM_DEVICE_MOD, - AM33XX_PRM_RSTCTRL_OFFSET); - - /* OCP barrier */ - (void)am33xx_prm_read_reg(AM33XX_PRM_DEVICE_MOD, - AM33XX_PRM_RSTCTRL_OFFSET); + omap_prm_reset_system(); } diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 49c3c25808e..b6443a4e0c7 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -21,7 +21,9 @@ #include <linux/i2c.h> #include <linux/spi/spi.h> #include <linux/usb/musb.h> +#include <linux/mmc/host.h> #include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/platform_data/mmc-omap.h> #include <linux/mfd/menelaus.h> #include <sound/tlv320aic3x.h> diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index e2ad48b5d9c..03502abe4f2 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -482,7 +482,7 @@ static struct omap_mux_partition *partition; * Current flows to eMMC when eMMC is off and the data lines are pulled up, * so pull them down. N.B. we pull 8 lines because we are using 8 lines. */ -static void rx51_mmc2_remux(struct device *dev, int slot, int power_on) +static void rx51_mmc2_remux(struct device *dev, int power_on) { if (power_on) omap_mux_write_array(partition, rx51_mmc2_on_mux); @@ -498,7 +498,6 @@ static struct omap2_hsmmc_info mmc[] __initdata = { .cover_only = true, .gpio_cd = 160, .gpio_wp = -EINVAL, - .power_saving = true, }, { .name = "internal", @@ -508,7 +507,6 @@ static struct omap2_hsmmc_info mmc[] __initdata = { .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, .nonremovable = true, - .power_saving = true, .remux = rx51_mmc2_remux, }, {} /* Terminator */ diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c index eb8c75ec3b1..5c5ebb4db5f 100644 --- a/arch/arm/mach-omap2/cclock3xxx_data.c +++ b/arch/arm/mach-omap2/cclock3xxx_data.c @@ -257,6 +257,9 @@ static const struct clk_ops dpll1_ck_ops = { .get_parent = &omap2_init_dpll_parent, .recalc_rate = &omap3_dpll_recalc, .set_rate = &omap3_noncore_dpll_set_rate, + .set_parent = &omap3_noncore_dpll_set_parent, + .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, + .determine_rate = &omap3_noncore_dpll_determine_rate, .round_rate = &omap2_dpll_round_rate, }; @@ -367,6 +370,9 @@ static const struct clk_ops dpll4_ck_ops = { .get_parent = &omap2_init_dpll_parent, .recalc_rate = &omap3_dpll_recalc, .set_rate = &omap3_dpll4_set_rate, + .set_parent = &omap3_noncore_dpll_set_parent, + .set_rate_and_parent = &omap3_dpll4_set_rate_and_parent, + .determine_rate = &omap3_noncore_dpll_determine_rate, .round_rate = &omap2_dpll_round_rate, }; diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 500530d1364..6ad5b4dbd33 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -171,7 +171,8 @@ static void _omap2_module_wait_ready(struct clk_hw_omap *clk) _wait_idlest_generic(clk, idlest_reg, (1 << idlest_bit), idlest_val, __clk_get_name(clk->hw.clk)); } else { - cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit); + omap_cm_wait_module_ready(0, prcm_mod, idlest_reg_id, + idlest_bit); }; } @@ -771,4 +772,8 @@ void __init ti_clk_init_features(void) ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL; else if (cpu_is_omap34xx()) ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL; + + /* On OMAP3430 ES1.0, DPLL4 can't be re-programmed */ + if (omap_rev() == OMAP3430_REV_ES1_0) + ti_clk_features.flags |= TI_CLK_DPLL4_DENY_REPROGRAM; } diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 4592a276259..641337c6cde 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -234,6 +234,7 @@ struct ti_clk_features { }; #define TI_CLK_DPLL_HAS_FREQSEL (1 << 0) +#define TI_CLK_DPLL4_DENY_REPROGRAM (1 << 1) extern struct ti_clk_features ti_clk_features; diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c index 0b02b4161d7..a9e86db5daf 100644 --- a/arch/arm/mach-omap2/clock3xxx.c +++ b/arch/arm/mach-omap2/clock3xxx.c @@ -38,6 +38,18 @@ /* needed by omap3_core_dpll_m2_set_rate() */ struct clk *sdrc_ick_p, *arm_fck_p; + +/** + * omap3_dpll4_set_rate - set rate for omap3 per-dpll + * @hw: clock to change + * @rate: target rate for clock + * @parent_rate: rate of the parent clock + * + * Check if the current SoC supports the per-dpll reprogram operation + * or not, and then do the rate change if supported. Returns -EINVAL + * if not supported, 0 for success, and potential error codes from the + * clock rate change. + */ int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -46,7 +58,7 @@ int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, * on 3430ES1 prevents us from changing DPLL multipliers or dividers * on DPLL4. */ - if (omap_rev() == OMAP3430_REV_ES1_0) { + if (ti_clk_features.flags & TI_CLK_DPLL4_DENY_REPROGRAM) { pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n"); return -EINVAL; } @@ -54,6 +66,30 @@ int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, return omap3_noncore_dpll_set_rate(hw, rate, parent_rate); } +/** + * omap3_dpll4_set_rate_and_parent - set rate and parent for omap3 per-dpll + * @hw: clock to change + * @rate: target rate for clock + * @parent_rate: rate of the parent clock + * @index: parent index, 0 - reference clock, 1 - bypass clock + * + * Check if the current SoC support the per-dpll reprogram operation + * or not, and then do the rate + parent change if supported. Returns + * -EINVAL if not supported, 0 for success, and potential error codes + * from the clock rate change. + */ +int omap3_dpll4_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate, u8 index) +{ + if (ti_clk_features.flags & TI_CLK_DPLL4_DENY_REPROGRAM) { + pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n"); + return -EINVAL; + } + + return omap3_noncore_dpll_set_rate_and_parent(hw, rate, parent_rate, + index); +} + void __init omap3_clk_lock_dpll5(void) { struct clk *dpll5_clk; diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index 93473f9a551..6222e87a79b 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -45,17 +45,29 @@ extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2); * struct cm_ll_data - fn ptrs to per-SoC CM function implementations * @split_idlest_reg: ptr to the SoC CM-specific split_idlest_reg impl * @wait_module_ready: ptr to the SoC CM-specific wait_module_ready impl + * @wait_module_idle: ptr to the SoC CM-specific wait_module_idle impl + * @module_enable: ptr to the SoC CM-specific module_enable impl + * @module_disable: ptr to the SoC CM-specific module_disable impl */ struct cm_ll_data { int (*split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst, u8 *idlest_reg_id); - int (*wait_module_ready)(s16 prcm_mod, u8 idlest_id, u8 idlest_shift); + int (*wait_module_ready)(u8 part, s16 prcm_mod, u16 idlest_reg, + u8 idlest_shift); + int (*wait_module_idle)(u8 part, s16 prcm_mod, u16 idlest_reg, + u8 idlest_shift); + void (*module_enable)(u8 mode, u8 part, u16 inst, u16 clkctrl_offs); + void (*module_disable)(u8 part, u16 inst, u16 clkctrl_offs); }; extern int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, u8 *idlest_reg_id); -extern int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift); - +int omap_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_reg, + u8 idlest_shift); +int omap_cm_wait_module_idle(u8 part, s16 prcm_mod, u16 idlest_reg, + u8 idlest_shift); +int omap_cm_module_enable(u8 mode, u8 part, u16 inst, u16 clkctrl_offs); +int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs); extern int cm_register(struct cm_ll_data *cld); extern int cm_unregister(struct cm_ll_data *cld); diff --git a/arch/arm/mach-omap2/cm1_44xx.h b/arch/arm/mach-omap2/cm1_44xx.h index 5ae8fe39d6e..a5949927b66 100644 --- a/arch/arm/mach-omap2/cm1_44xx.h +++ b/arch/arm/mach-omap2/cm1_44xx.h @@ -25,8 +25,6 @@ #ifndef __ARCH_ARM_MACH_OMAP2_CM1_44XX_H #define __ARCH_ARM_MACH_OMAP2_CM1_44XX_H -#include "cm_44xx_54xx.h" - /* CM1 base address */ #define OMAP4430_CM1_BASE 0x4a004000 diff --git a/arch/arm/mach-omap2/cm1_54xx.h b/arch/arm/mach-omap2/cm1_54xx.h index 90b3348e667..fd245dfa739 100644 --- a/arch/arm/mach-omap2/cm1_54xx.h +++ b/arch/arm/mach-omap2/cm1_54xx.h @@ -22,8 +22,6 @@ #ifndef __ARCH_ARM_MACH_OMAP2_CM1_54XX_H #define __ARCH_ARM_MACH_OMAP2_CM1_54XX_H -#include "cm_44xx_54xx.h" - /* CM1 base address */ #define OMAP54XX_CM_CORE_AON_BASE 0x4a004000 diff --git a/arch/arm/mach-omap2/cm1_7xx.h b/arch/arm/mach-omap2/cm1_7xx.h index ca6fa1febaa..2f1c09eea02 100644 --- a/arch/arm/mach-omap2/cm1_7xx.h +++ b/arch/arm/mach-omap2/cm1_7xx.h @@ -23,8 +23,6 @@ #ifndef __ARCH_ARM_MACH_OMAP2_CM1_7XX_H #define __ARCH_ARM_MACH_OMAP2_CM1_7XX_H -#include "cm_44xx_54xx.h" - /* CM1 base address */ #define DRA7XX_CM_CORE_AON_BASE 0x4a005000 diff --git a/arch/arm/mach-omap2/cm2_44xx.h b/arch/arm/mach-omap2/cm2_44xx.h index ee5136d7cdd..7521abf3d83 100644 --- a/arch/arm/mach-omap2/cm2_44xx.h +++ b/arch/arm/mach-omap2/cm2_44xx.h @@ -25,8 +25,6 @@ #ifndef __ARCH_ARM_MACH_OMAP2_CM2_44XX_H #define __ARCH_ARM_MACH_OMAP2_CM2_44XX_H -#include "cm_44xx_54xx.h" - /* CM2 base address */ #define OMAP4430_CM2_BASE 0x4a008000 diff --git a/arch/arm/mach-omap2/cm2_54xx.h b/arch/arm/mach-omap2/cm2_54xx.h index 2683231b299..ff4040c196d 100644 --- a/arch/arm/mach-omap2/cm2_54xx.h +++ b/arch/arm/mach-omap2/cm2_54xx.h @@ -21,8 +21,6 @@ #ifndef __ARCH_ARM_MACH_OMAP2_CM2_54XX_H #define __ARCH_ARM_MACH_OMAP2_CM2_54XX_H -#include "cm_44xx_54xx.h" - /* CM2 base address */ #define OMAP54XX_CM_CORE_BASE 0x4a008000 diff --git a/arch/arm/mach-omap2/cm2_7xx.h b/arch/arm/mach-omap2/cm2_7xx.h index e966e3a3c93..ce63fdb6805 100644 --- a/arch/arm/mach-omap2/cm2_7xx.h +++ b/arch/arm/mach-omap2/cm2_7xx.h @@ -22,8 +22,6 @@ #ifndef __ARCH_ARM_MACH_OMAP2_CM2_7XX_H #define __ARCH_ARM_MACH_OMAP2_CM2_7XX_H -#include "cm_44xx_54xx.h" - /* CM2 base address */ #define DRA7XX_CM_CORE_BASE 0x4a008000 diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c index 8be6ea50c09..a96d901b1d5 100644 --- a/arch/arm/mach-omap2/cm2xxx.c +++ b/arch/arm/mach-omap2/cm2xxx.c @@ -53,7 +53,7 @@ static void _write_clktrctrl(u8 c, s16 module, u32 mask) omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL); } -bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) +static bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) { u32 v; @@ -64,12 +64,12 @@ bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) return (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0; } -void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) +static void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) { _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask); } -void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) +static void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) { _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask); } @@ -150,7 +150,7 @@ static int _omap2xxx_apll_enable(u8 enable_bit, u8 status_bit) v |= m; omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN); - omap2xxx_cm_wait_module_ready(PLL_MOD, 1, status_bit); + omap2xxx_cm_wait_module_ready(0, PLL_MOD, 1, status_bit); /* * REVISIT: Should we return an error code if @@ -204,8 +204,9 @@ void omap2xxx_cm_apll96_disable(void) * XXX This function is only needed until absolute register addresses are * removed from the OMAP struct clk records. */ -int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, - u8 *idlest_reg_id) +static int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, + s16 *prcm_inst, + u8 *idlest_reg_id) { unsigned long offs; u8 idlest_offs; @@ -238,6 +239,7 @@ int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, /** * omap2xxx_cm_wait_module_ready - wait for a module to leave idle or standby + * @part: PRCM partition, ignored for OMAP2 * @prcm_mod: PRCM module offset * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) * @idlest_shift: shift of the bit in the CM_IDLEST* register to check @@ -246,7 +248,8 @@ int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon * success or -EBUSY if the module doesn't enable in time. */ -int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) +int omap2xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id, + u8 idlest_shift) { int ena = 0, i = 0; u8 cm_idlest_reg; diff --git a/arch/arm/mach-omap2/cm2xxx.h b/arch/arm/mach-omap2/cm2xxx.h index 891d81c3c8f..c89502b168a 100644 --- a/arch/arm/mach-omap2/cm2xxx.h +++ b/arch/arm/mach-omap2/cm2xxx.h @@ -46,9 +46,6 @@ #ifndef __ASSEMBLER__ -extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask); -extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); - extern void omap2xxx_cm_set_dpll_disable_autoidle(void); extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void); @@ -57,11 +54,8 @@ extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void); extern void omap2xxx_cm_set_apll96_disable_autoidle(void); extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void); -extern bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask); -extern int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, - u8 idlest_shift); -extern int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, - s16 *prcm_inst, u8 *idlest_reg_id); +int omap2xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id, + u8 idlest_shift); extern int omap2xxx_cm_fclks_active(void); extern int omap2xxx_cm_mpu_retention_allowed(void); extern u32 omap2xxx_cm_get_core_clk_src(void); diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index b3f99e93def..b9ad463a368 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c @@ -96,13 +96,12 @@ static inline u32 am33xx_cm_read_reg_bits(u16 inst, s16 idx, u32 mask) /** * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield * @inst: CM instance register offset (*_INST macro) - * @cdoffs: Clockdomain register offset (*_CDOFFS macro) * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) * * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to * bit 0. */ -static u32 _clkctrl_idlest(u16 inst, s16 cdoffs, u16 clkctrl_offs) +static u32 _clkctrl_idlest(u16 inst, u16 clkctrl_offs) { u32 v = am33xx_cm_read_reg(inst, clkctrl_offs); v &= AM33XX_IDLEST_MASK; @@ -113,17 +112,16 @@ static u32 _clkctrl_idlest(u16 inst, s16 cdoffs, u16 clkctrl_offs) /** * _is_module_ready - can module registers be accessed without causing an abort? * @inst: CM instance register offset (*_INST macro) - * @cdoffs: Clockdomain register offset (*_CDOFFS macro) * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) * * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. */ -static bool _is_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) +static bool _is_module_ready(u16 inst, u16 clkctrl_offs) { u32 v; - v = _clkctrl_idlest(inst, cdoffs, clkctrl_offs); + v = _clkctrl_idlest(inst, clkctrl_offs); return (v == CLKCTRL_IDLEST_FUNCTIONAL || v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false; @@ -158,7 +156,7 @@ static void _clktrctrl_write(u8 c, u16 inst, u16 cdoffs) * Returns true if the clockdomain referred to by (@inst, @cdoffs) * is in hardware-supervised idle mode, or 0 otherwise. */ -bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs) +static bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs) { u32 v; @@ -177,7 +175,7 @@ bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs) * Put a clockdomain referred to by (@inst, @cdoffs) into * hardware-supervised idle mode. No return value. */ -void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs) +static void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, inst, cdoffs); } @@ -191,7 +189,7 @@ void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs) * software-supervised idle mode, i.e., controlled manually by the * Linux OMAP clockdomain code. No return value. */ -void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs) +static void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, inst, cdoffs); } @@ -204,7 +202,7 @@ void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs) * Put a clockdomain referred to by (@inst, @cdoffs) into idle * No return value. */ -void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs) +static void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, inst, cdoffs); } @@ -217,7 +215,7 @@ void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs) * Take a clockdomain referred to by (@inst, @cdoffs) out of idle, * waking it up. No return value. */ -void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs) +static void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, inst, cdoffs); } @@ -228,20 +226,22 @@ void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs) /** * am33xx_cm_wait_module_ready - wait for a module to be in 'func' state + * @part: PRCM partition, ignored for AM33xx * @inst: CM instance register offset (*_INST macro) - * @cdoffs: Clockdomain register offset (*_CDOFFS macro) * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * @bit_shift: bit shift for the register, ignored for AM33xx * * Wait for the module IDLEST to be functional. If the idle state is in any * the non functional state (trans, idle or disabled), module and thus the * sysconfig cannot be accessed and will probably lead to an "imprecise * external abort" */ -int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) +static int am33xx_cm_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs, + u8 bit_shift) { int i = 0; - omap_test_timeout(_is_module_ready(inst, cdoffs, clkctrl_offs), + omap_test_timeout(_is_module_ready(inst, clkctrl_offs), MAX_MODULE_READY_TIME, i); return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; @@ -250,22 +250,24 @@ int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) /** * am33xx_cm_wait_module_idle - wait for a module to be in 'disabled' * state + * @part: CM partition, ignored for AM33xx * @inst: CM instance register offset (*_INST macro) - * @cdoffs: Clockdomain register offset (*_CDOFFS macro) * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * @bit_shift: bit shift for the register, ignored for AM33xx * * Wait for the module IDLEST to be disabled. Some PRCM transition, * like reset assertion or parent clock de-activation must wait the * module to be fully disabled. */ -int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, u16 clkctrl_offs) +static int am33xx_cm_wait_module_idle(u8 part, s16 inst, u16 clkctrl_offs, + u8 bit_shift) { int i = 0; if (!clkctrl_offs) return 0; - omap_test_timeout((_clkctrl_idlest(inst, cdoffs, clkctrl_offs) == + omap_test_timeout((_clkctrl_idlest(inst, clkctrl_offs) == CLKCTRL_IDLEST_DISABLED), MAX_MODULE_READY_TIME, i); @@ -275,13 +277,14 @@ int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, u16 clkctrl_offs) /** * am33xx_cm_module_enable - Enable the modulemode inside CLKCTRL * @mode: Module mode (SW or HW) + * @part: CM partition, ignored for AM33xx * @inst: CM instance register offset (*_INST macro) - * @cdoffs: Clockdomain register offset (*_CDOFFS macro) * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) * * No return value. */ -void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, u16 clkctrl_offs) +static void am33xx_cm_module_enable(u8 mode, u8 part, u16 inst, + u16 clkctrl_offs) { u32 v; @@ -293,13 +296,13 @@ void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, u16 clkctrl_offs) /** * am33xx_cm_module_disable - Disable the module inside CLKCTRL + * @part: CM partition, ignored for AM33xx * @inst: CM instance register offset (*_INST macro) - * @cdoffs: Clockdomain register offset (*_CDOFFS macro) * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) * * No return value. */ -void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs) +static void am33xx_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs) { u32 v; @@ -362,3 +365,21 @@ struct clkdm_ops am33xx_clkdm_operations = { .clkdm_clk_enable = am33xx_clkdm_clk_enable, .clkdm_clk_disable = am33xx_clkdm_clk_disable, }; + +static struct cm_ll_data am33xx_cm_ll_data = { + .wait_module_ready = &am33xx_cm_wait_module_ready, + .wait_module_idle = &am33xx_cm_wait_module_idle, + .module_enable = &am33xx_cm_module_enable, + .module_disable = &am33xx_cm_module_disable, +}; + +int __init am33xx_cm_init(void) +{ + return cm_register(&am33xx_cm_ll_data); +} + +static void __exit am33xx_cm_exit(void) +{ + cm_unregister(&am33xx_cm_ll_data); +} +__exitcall(am33xx_cm_exit); diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h index bd244179077..046b4b2bc9d 100644 --- a/arch/arm/mach-omap2/cm33xx.h +++ b/arch/arm/mach-omap2/cm33xx.h @@ -374,41 +374,6 @@ #ifndef __ASSEMBLER__ -bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs); -void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs); -void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs); -void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs); -void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs); - -#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) -extern int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, - u16 clkctrl_offs); -extern void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, - u16 clkctrl_offs); -extern void am33xx_cm_module_disable(u16 inst, s16 cdoffs, - u16 clkctrl_offs); -extern int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, - u16 clkctrl_offs); -#else -static inline int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, - u16 clkctrl_offs) -{ - return 0; -} -static inline void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, - u16 clkctrl_offs) -{ -} -static inline void am33xx_cm_module_disable(u16 inst, s16 cdoffs, - u16 clkctrl_offs) -{ -} -static inline int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, - u16 clkctrl_offs) -{ - return 0; -} -#endif - +int am33xx_cm_init(void); #endif /* ASSEMBLER */ #endif diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c index 129a4e7f6ef..ebead8f035f 100644 --- a/arch/arm/mach-omap2/cm3xxx.c +++ b/arch/arm/mach-omap2/cm3xxx.c @@ -42,7 +42,7 @@ static void _write_clktrctrl(u8 c, s16 module, u32 mask) omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL); } -bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) +static bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) { u32 v; @@ -53,22 +53,22 @@ bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0; } -void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) +static void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) { _write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask); } -void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) +static void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) { _write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask); } -void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask) +static void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask) { _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask); } -void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask) +static void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask) { _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask); } @@ -79,6 +79,7 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask) /** * omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby + * @part: PRCM partition, ignored for OMAP3 * @prcm_mod: PRCM module offset * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) * @idlest_shift: shift of the bit in the CM_IDLEST* register to check @@ -87,7 +88,8 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask) * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon * success or -EBUSY if the module doesn't enable in time. */ -int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) +static int omap3xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id, + u8 idlest_shift) { int ena = 0, i = 0; u8 cm_idlest_reg; @@ -116,8 +118,9 @@ int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) * XXX This function is only needed until absolute register addresses are * removed from the OMAP struct clk records. */ -int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, - u8 *idlest_reg_id) +static int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg, + s16 *prcm_inst, + u8 *idlest_reg_id) { unsigned long offs; u8 idlest_offs; diff --git a/arch/arm/mach-omap2/cm3xxx.h b/arch/arm/mach-omap2/cm3xxx.h index 7a16b559812..734a8581c0c 100644 --- a/arch/arm/mach-omap2/cm3xxx.h +++ b/arch/arm/mach-omap2/cm3xxx.h @@ -68,18 +68,6 @@ #ifndef __ASSEMBLER__ -extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask); -extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); -extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask); -extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask); - -extern bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask); -extern int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, - u8 idlest_shift); - -extern int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg, - s16 *prcm_inst, u8 *idlest_reg_id); - extern void omap3_cm_save_context(void); extern void omap3_cm_restore_context(void); extern void omap3_cm_save_scratchpad_contents(u32 *ptr); diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c deleted file mode 100644 index fe5cc7bae48..00000000000 --- a/arch/arm/mach-omap2/cm44xx.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * OMAP4 CM1, CM2 module low-level functions - * - * Copyright (C) 2010 Nokia Corporation - * Paul Walmsley - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * These functions are intended to be used only by the cminst44xx.c file. - * XXX Perhaps we should just move them there and make them static. - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/err.h> -#include <linux/io.h> - -#include "cm.h" -#include "cm1_44xx.h" -#include "cm2_44xx.h" - -/* CM1 hardware module low-level functions */ - -/* Read a register in CM1 */ -u32 omap4_cm1_read_inst_reg(s16 inst, u16 reg) -{ - return readl_relaxed(cm_base + inst + reg); -} - -/* Write into a register in CM1 */ -void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 reg) -{ - writel_relaxed(val, cm_base + inst + reg); -} - -/* Read a register in CM2 */ -u32 omap4_cm2_read_inst_reg(s16 inst, u16 reg) -{ - return readl_relaxed(cm2_base + inst + reg); -} - -/* Write into a register in CM2 */ -void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) -{ - writel_relaxed(val, cm2_base + inst + reg); -} diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h index 3380beeace6..728d06a4af1 100644 --- a/arch/arm/mach-omap2/cm44xx.h +++ b/arch/arm/mach-omap2/cm44xx.h @@ -23,4 +23,7 @@ #define OMAP4_CM_CLKSTCTRL 0x0000 #define OMAP4_CM_STATICDEP 0x0004 +void omap_cm_base_init(void); +int omap4_cm_init(void); + #endif diff --git a/arch/arm/mach-omap2/cm_44xx_54xx.h b/arch/arm/mach-omap2/cm_44xx_54xx.h deleted file mode 100644 index cbb21169032..00000000000 --- a/arch/arm/mach-omap2/cm_44xx_54xx.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * OMAP44xx and OMAP54xx CM1/CM2 function prototypes - * - * Copyright (C) 2009-2013 Texas Instruments, Inc. - * Copyright (C) 2009-2010 Nokia Corporation - * - * Paul Walmsley (paul@pwsan.com) - * Rajendra Nayak (rnayak@ti.com) - * Benoit Cousson (b-cousson@ti.com) - * - * This file is automatically generated from the OMAP hardware databases. - * We respectfully ask that any modifications to this file be coordinated - * with the public linux-omap@vger.kernel.org mailing list and the - * authors above to ensure that the autogeneration scripts are kept - * up-to-date with the file contents. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#ifndef __ARCH_ARM_MACH_OMAP2_CM_44XX_54XX_H -#define __ARCH_ARM_MACH_OMAP2_CM_44XX_55XX_H - -/* CM1 Function prototypes */ -extern u32 omap4_cm1_read_inst_reg(s16 inst, u16 idx); -extern void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 idx); -extern u32 omap4_cm1_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); - -/* CM2 Function prototypes */ -extern u32 omap4_cm2_read_inst_reg(s16 inst, u16 idx); -extern void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 idx); -extern u32 omap4_cm2_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); - -#endif diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c index 8f6c4710877..8fe02fcedc4 100644 --- a/arch/arm/mach-omap2/cm_common.c +++ b/arch/arm/mach-omap2/cm_common.c @@ -72,9 +72,10 @@ int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, } /** - * cm_wait_module_ready - wait for a module to leave idle or standby + * omap_cm_wait_module_ready - wait for a module to leave idle or standby + * @part: PRCM partition * @prcm_mod: PRCM module offset - * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) + * @idlest_reg: CM_IDLESTx register * @idlest_shift: shift of the bit in the CM_IDLEST* register to check * * Wait for the PRCM to indicate that the module identified by @@ -83,7 +84,8 @@ int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, * no per-SoC wait_module_ready() function pointer has been registered * or if the idlest register is unknown on the SoC. */ -int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) +int omap_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_reg, + u8 idlest_shift) { if (!cm_ll_data->wait_module_ready) { WARN_ONCE(1, "cm: %s: no low-level function defined\n", @@ -91,7 +93,79 @@ int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) return -EINVAL; } - return cm_ll_data->wait_module_ready(prcm_mod, idlest_id, idlest_shift); + return cm_ll_data->wait_module_ready(part, prcm_mod, idlest_reg, + idlest_shift); +} + +/** + * omap_cm_wait_module_idle - wait for a module to enter idle or standby + * @part: PRCM partition + * @prcm_mod: PRCM module offset + * @idlest_reg: CM_IDLESTx register + * @idlest_shift: shift of the bit in the CM_IDLEST* register to check + * + * Wait for the PRCM to indicate that the module identified by + * (@prcm_mod, @idlest_id, @idlest_shift) is no longer clocked. Return + * 0 upon success, -EBUSY if the module doesn't enable in time, or + * -EINVAL if no per-SoC wait_module_idle() function pointer has been + * registered or if the idlest register is unknown on the SoC. + */ +int omap_cm_wait_module_idle(u8 part, s16 prcm_mod, u16 idlest_reg, + u8 idlest_shift) +{ + if (!cm_ll_data->wait_module_idle) { + WARN_ONCE(1, "cm: %s: no low-level function defined\n", + __func__); + return -EINVAL; + } + + return cm_ll_data->wait_module_idle(part, prcm_mod, idlest_reg, + idlest_shift); +} + +/** + * omap_cm_module_enable - enable a module + * @mode: target mode for the module + * @part: PRCM partition + * @inst: PRCM instance + * @clkctrl_offs: CM_CLKCTRL register offset for the module + * + * Enables clocks for a module identified by (@part, @inst, @clkctrl_offs) + * making its IO space accessible. Return 0 upon success, -EINVAL if no + * per-SoC module_enable() function pointer has been registered. + */ +int omap_cm_module_enable(u8 mode, u8 part, u16 inst, u16 clkctrl_offs) +{ + if (!cm_ll_data->module_enable) { + WARN_ONCE(1, "cm: %s: no low-level function defined\n", + __func__); + return -EINVAL; + } + + cm_ll_data->module_enable(mode, part, inst, clkctrl_offs); + return 0; +} + +/** + * omap_cm_module_disable - disable a module + * @part: PRCM partition + * @inst: PRCM instance + * @clkctrl_offs: CM_CLKCTRL register offset for the module + * + * Disables clocks for a module identified by (@part, @inst, @clkctrl_offs) + * makings its IO space inaccessible. Return 0 upon success, -EINVAL if + * no per-SoC module_disable() function pointer has been registered. + */ +int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs) +{ + if (!cm_ll_data->module_disable) { + WARN_ONCE(1, "cm: %s: no low-level function defined\n", + __func__); + return -EINVAL; + } + + cm_ll_data->module_disable(part, inst, clkctrl_offs); + return 0; } /** diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 12aca56942c..95a8cff66af 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -26,7 +26,6 @@ #include "cm1_44xx.h" #include "cm2_44xx.h" #include "cm44xx.h" -#include "cminst44xx.h" #include "cm-regbits-34xx.h" #include "prcm44xx.h" #include "prm44xx.h" @@ -74,17 +73,18 @@ void omap_cm_base_init(void) /* Private functions */ +static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx); + /** * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield * @part: PRCM partition ID that the CM_CLKCTRL register exists in * @inst: CM instance register offset (*_INST macro) - * @cdoffs: Clockdomain register offset (*_CDOFFS macro) * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) * * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to * bit 0. */ -static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) +static u32 _clkctrl_idlest(u8 part, u16 inst, u16 clkctrl_offs) { u32 v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs); v &= OMAP4430_IDLEST_MASK; @@ -96,26 +96,23 @@ static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) * _is_module_ready - can module registers be accessed without causing an abort? * @part: PRCM partition ID that the CM_CLKCTRL register exists in * @inst: CM instance register offset (*_INST macro) - * @cdoffs: Clockdomain register offset (*_CDOFFS macro) * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) * * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. */ -static bool _is_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) +static bool _is_module_ready(u8 part, u16 inst, u16 clkctrl_offs) { u32 v; - v = _clkctrl_idlest(part, inst, cdoffs, clkctrl_offs); + v = _clkctrl_idlest(part, inst, clkctrl_offs); return (v == CLKCTRL_IDLEST_FUNCTIONAL || v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false; } -/* Public functions */ - /* Read a register in a CM instance */ -u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) +static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) { BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || @@ -124,7 +121,7 @@ u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) } /* Write into a register in a CM instance */ -void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) +static void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) { BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || @@ -133,8 +130,8 @@ void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) } /* Read-modify-write a register in CM1. Caller must lock */ -u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 inst, - s16 idx) +static u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 inst, + s16 idx) { u32 v; @@ -146,17 +143,18 @@ u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 inst, return v; } -u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx) +static u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx) { return omap4_cminst_rmw_inst_reg_bits(bits, bits, part, inst, idx); } -u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx) +static u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst, + s16 idx) { return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx); } -u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask) +static u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask) { u32 v; @@ -200,7 +198,7 @@ static void _clktrctrl_write(u8 c, u8 part, u16 inst, u16 cdoffs) * Returns true if the clockdomain referred to by (@part, @inst, @cdoffs) * is in hardware-supervised idle mode, or 0 otherwise. */ -bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs) +static bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs) { u32 v; @@ -220,7 +218,7 @@ bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs) * Put a clockdomain referred to by (@part, @inst, @cdoffs) into * hardware-supervised idle mode. No return value. */ -void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs) +static void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, part, inst, cdoffs); } @@ -235,7 +233,7 @@ void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs) * software-supervised idle mode, i.e., controlled manually by the * Linux OMAP clockdomain code. No return value. */ -void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs) +static void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, part, inst, cdoffs); } @@ -249,7 +247,7 @@ void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs) * Take a clockdomain referred to by (@part, @inst, @cdoffs) out of idle, * waking it up. No return value. */ -void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs) +static void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, part, inst, cdoffs); } @@ -258,7 +256,7 @@ void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs) * */ -void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs) +static void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs); } @@ -267,23 +265,23 @@ void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs) * omap4_cminst_wait_module_ready - wait for a module to be in 'func' state * @part: PRCM partition ID that the CM_CLKCTRL register exists in * @inst: CM instance register offset (*_INST macro) - * @cdoffs: Clockdomain register offset (*_CDOFFS macro) * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * @bit_shift: bit shift for the register, ignored for OMAP4+ * * Wait for the module IDLEST to be functional. If the idle state is in any * the non functional state (trans, idle or disabled), module and thus the * sysconfig cannot be accessed and will probably lead to an "imprecise * external abort" */ -int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, - u16 clkctrl_offs) +static int omap4_cminst_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs, + u8 bit_shift) { int i = 0; if (!clkctrl_offs) return 0; - omap_test_timeout(_is_module_ready(part, inst, cdoffs, clkctrl_offs), + omap_test_timeout(_is_module_ready(part, inst, clkctrl_offs), MAX_MODULE_READY_TIME, i); return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; @@ -294,21 +292,22 @@ int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, * state * @part: PRCM partition ID that the CM_CLKCTRL register exists in * @inst: CM instance register offset (*_INST macro) - * @cdoffs: Clockdomain register offset (*_CDOFFS macro) * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * @bit_shift: Bit shift for the register, ignored for OMAP4+ * * Wait for the module IDLEST to be disabled. Some PRCM transition, * like reset assertion or parent clock de-activation must wait the * module to be fully disabled. */ -int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) +static int omap4_cminst_wait_module_idle(u8 part, s16 inst, u16 clkctrl_offs, + u8 bit_shift) { int i = 0; if (!clkctrl_offs) return 0; - omap_test_timeout((_clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) == + omap_test_timeout((_clkctrl_idlest(part, inst, clkctrl_offs) == CLKCTRL_IDLEST_DISABLED), MAX_MODULE_DISABLE_TIME, i); @@ -320,13 +319,12 @@ int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_off * @mode: Module mode (SW or HW) * @part: PRCM partition ID that the CM_CLKCTRL register exists in * @inst: CM instance register offset (*_INST macro) - * @cdoffs: Clockdomain register offset (*_CDOFFS macro) * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) * * No return value. */ -void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, - u16 clkctrl_offs) +static void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, + u16 clkctrl_offs) { u32 v; @@ -340,13 +338,11 @@ void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, * omap4_cminst_module_disable - Disable the module inside CLKCTRL * @part: PRCM partition ID that the CM_CLKCTRL register exists in * @inst: CM instance register offset (*_INST macro) - * @cdoffs: Clockdomain register offset (*_CDOFFS macro) * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) * * No return value. */ -void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, - u16 clkctrl_offs) +static void omap4_cminst_module_disable(u8 part, u16 inst, u16 clkctrl_offs) { u32 v; @@ -510,3 +506,21 @@ struct clkdm_ops am43xx_clkdm_operations = { .clkdm_clk_enable = omap4_clkdm_clk_enable, .clkdm_clk_disable = omap4_clkdm_clk_disable, }; + +static struct cm_ll_data omap4xxx_cm_ll_data = { + .wait_module_ready = &omap4_cminst_wait_module_ready, + .wait_module_idle = &omap4_cminst_wait_module_idle, + .module_enable = &omap4_cminst_module_enable, + .module_disable = &omap4_cminst_module_disable, +}; + +int __init omap4_cm_init(void) +{ + return cm_register(&omap4xxx_cm_ll_data); +} + +static void __exit omap4_cm_exit(void) +{ + cm_unregister(&omap4xxx_cm_ll_data); +} +__exitcall(omap4_cm_exit); diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h deleted file mode 100644 index 7f56ea444bc..00000000000 --- a/arch/arm/mach-omap2/cminst44xx.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * OMAP4 Clock Management (CM) function prototypes - * - * Copyright (C) 2010 Nokia Corporation - * Paul Walmsley - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ARCH_ASM_MACH_OMAP2_CMINST44XX_H -#define __ARCH_ASM_MACH_OMAP2_CMINST44XX_H - -bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs); -void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs); -void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs); -void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs); -void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs); -extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs); -extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, - u16 clkctrl_offs); -extern void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, - u16 clkctrl_offs); -extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, - u16 clkctrl_offs); -/* - * In an ideal world, we would not export these low-level functions, - * but this will probably take some time to fix properly - */ -u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx); -void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx); -u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, - u16 inst, s16 idx); -u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, - s16 idx); -u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst, - s16 idx); -extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, - u32 mask); - -extern void omap_cm_base_init(void); - -#endif diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 110256a5663..a7bc4ce81e1 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -49,7 +49,7 @@ static int __init omap3_l3_init(void) * To avoid code running on other OMAPs in * multi-omap builds */ - if (!(cpu_is_omap34xx())) + if (!(cpu_is_omap34xx()) || of_have_populated_dt()) return -ENODEV; snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main"); @@ -67,40 +67,6 @@ static int __init omap3_l3_init(void) } omap_postcore_initcall(omap3_l3_init); -static int __init omap4_l3_init(void) -{ - int i; - struct omap_hwmod *oh[3]; - struct platform_device *pdev; - char oh_name[L3_MODULES_MAX_LEN]; - - /* If dtb is there, the devices will be created dynamically */ - if (of_have_populated_dt()) - return -ENODEV; - - /* - * To avoid code running on other OMAPs in - * multi-omap builds - */ - if (!cpu_is_omap44xx() && !soc_is_omap54xx()) - return -ENODEV; - - for (i = 0; i < L3_MODULES; i++) { - snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main_%d", i+1); - - oh[i] = omap_hwmod_lookup(oh_name); - if (!(oh[i])) - pr_err("could not look up %s\n", oh_name); - } - - pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL, 0); - - WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); - - return PTR_RET(pdev); -} -omap_postcore_initcall(omap4_l3_init); - #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) static struct resource omap2cam_resources[] = { diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index ac3d789ac3c..20e120d071d 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -460,25 +460,24 @@ void omap3_noncore_dpll_disable(struct clk_hw *hw) /* Non-CORE DPLL rate set code */ /** - * omap3_noncore_dpll_set_rate - set non-core DPLL rate - * @clk: struct clk * of DPLL to set - * @rate: rounded target rate + * omap3_noncore_dpll_determine_rate - determine rate for a DPLL + * @hw: pointer to the clock to determine rate for + * @rate: target rate for the DPLL + * @best_parent_rate: pointer for returning best parent rate + * @best_parent_clk: pointer for returning best parent clock * - * Set the DPLL CLKOUT to the target rate. If the DPLL can enter - * low-power bypass, and the target rate is the bypass source clock - * rate, then configure the DPLL for bypass. Otherwise, round the - * target rate if it hasn't been done already, then program and lock - * the DPLL. Returns -EINVAL upon error, or 0 upon success. + * Determines which DPLL mode to use for reaching a desired target rate. + * Checks whether the DPLL shall be in bypass or locked mode, and if + * locked, calculates the M,N values for the DPLL via round-rate. + * Returns a positive clock rate with success, negative error value + * in failure. */ -int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) +long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_clk) { struct clk_hw_omap *clk = to_clk_hw_omap(hw); - struct clk *new_parent = NULL; - unsigned long rrate; - u16 freqsel = 0; struct dpll_data *dd; - int ret; if (!hw || !rate) return -EINVAL; @@ -489,61 +488,121 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, if (__clk_get_rate(dd->clk_bypass) == rate && (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { - pr_debug("%s: %s: set rate: entering bypass.\n", - __func__, __clk_get_name(hw->clk)); + *best_parent_clk = dd->clk_bypass; + } else { + rate = omap2_dpll_round_rate(hw, rate, best_parent_rate); + *best_parent_clk = dd->clk_ref; + } + + *best_parent_rate = rate; + + return rate; +} + +/** + * omap3_noncore_dpll_set_parent - set parent for a DPLL clock + * @hw: pointer to the clock to set parent for + * @index: parent index to select + * + * Sets parent for a DPLL clock. This sets the DPLL into bypass or + * locked mode. Returns 0 with success, negative error value otherwise. + */ +int omap3_noncore_dpll_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + int ret; - __clk_prepare(dd->clk_bypass); - clk_enable(dd->clk_bypass); + if (!hw) + return -EINVAL; + + if (index) ret = _omap3_noncore_dpll_bypass(clk); - if (!ret) - new_parent = dd->clk_bypass; - clk_disable(dd->clk_bypass); - __clk_unprepare(dd->clk_bypass); - } else { - __clk_prepare(dd->clk_ref); - clk_enable(dd->clk_ref); - - /* XXX this check is probably pointless in the CCF context */ - if (dd->last_rounded_rate != rate) { - rrate = __clk_round_rate(hw->clk, rate); - if (rrate != rate) { - pr_warn("%s: %s: final rate %lu does not match desired rate %lu\n", - __func__, __clk_get_name(hw->clk), - rrate, rate); - rate = rrate; - } - } + else + ret = _omap3_noncore_dpll_lock(clk); - if (dd->last_rounded_rate == 0) - return -EINVAL; + return ret; +} - /* Freqsel is available only on OMAP343X devices */ - if (ti_clk_features.flags & TI_CLK_DPLL_HAS_FREQSEL) { - freqsel = _omap3_dpll_compute_freqsel(clk, - dd->last_rounded_n); - WARN_ON(!freqsel); - } +/** + * omap3_noncore_dpll_set_rate - set rate for a DPLL clock + * @hw: pointer to the clock to set parent for + * @rate: target rate for the clock + * @parent_rate: rate of the parent clock + * + * Sets rate for a DPLL clock. First checks if the clock parent is + * reference clock (in bypass mode, the rate of the clock can't be + * changed) and proceeds with the rate change operation. Returns 0 + * with success, negative error value otherwise. + */ +int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + struct dpll_data *dd; + u16 freqsel = 0; + int ret; + + if (!hw || !rate) + return -EINVAL; + + dd = clk->dpll_data; + if (!dd) + return -EINVAL; - pr_debug("%s: %s: set rate: locking rate to %lu.\n", - __func__, __clk_get_name(hw->clk), rate); + if (__clk_get_parent(hw->clk) != dd->clk_ref) + return -EINVAL; + + if (dd->last_rounded_rate == 0) + return -EINVAL; - ret = omap3_noncore_dpll_program(clk, freqsel); - if (!ret) - new_parent = dd->clk_ref; - clk_disable(dd->clk_ref); - __clk_unprepare(dd->clk_ref); + /* Freqsel is available only on OMAP343X devices */ + if (ti_clk_features.flags & TI_CLK_DPLL_HAS_FREQSEL) { + freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n); + WARN_ON(!freqsel); } - /* - * FIXME - this is all wrong. common code handles reparenting and - * migrating prepare/enable counts. dplls should be a multiplexer - * clock and this should be a set_parent operation so that all of that - * stuff is inherited for free - */ - if (!ret && clk_get_parent(hw->clk) != new_parent) - __clk_reparent(hw->clk, new_parent); + pr_debug("%s: %s: set rate: locking rate to %lu.\n", __func__, + __clk_get_name(hw->clk), rate); - return 0; + ret = omap3_noncore_dpll_program(clk, freqsel); + + return ret; +} + +/** + * omap3_noncore_dpll_set_rate_and_parent - set rate and parent for a DPLL clock + * @hw: pointer to the clock to set rate and parent for + * @rate: target rate for the DPLL + * @parent_rate: clock rate of the DPLL parent + * @index: new parent index for the DPLL, 0 - reference, 1 - bypass + * + * Sets rate and parent for a DPLL clock. If new parent is the bypass + * clock, only selects the parent. Otherwise proceeds with a rate + * change, as this will effectively also change the parent as the + * DPLL is put into locked mode. Returns 0 with success, negative error + * value otherwise. + */ +int omap3_noncore_dpll_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate, + u8 index) +{ + int ret; + + if (!hw || !rate) + return -EINVAL; + + /* + * clk-ref at index[0], in which case we only need to set rate, + * the parent will be changed automatically with the lock sequence. + * With clk-bypass case we only need to change parent. + */ + if (index) + ret = omap3_noncore_dpll_set_parent(hw, index); + else + ret = omap3_noncore_dpll_set_rate(hw, rate, parent_rate); + + return ret; } /* DPLL autoidle read/set code */ diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c index 4613f1e8698..535822fcf4b 100644 --- a/arch/arm/mach-omap2/dpll44xx.c +++ b/arch/arm/mach-omap2/dpll44xx.c @@ -207,3 +207,44 @@ out: return dd->last_rounded_rate; } + +/** + * omap4_dpll_regm4xen_determine_rate - determine rate for a DPLL + * @hw: pointer to the clock to determine rate for + * @rate: target rate for the DPLL + * @best_parent_rate: pointer for returning best parent rate + * @best_parent_clk: pointer for returning best parent clock + * + * Determines which DPLL mode to use for reaching a desired rate. + * Checks whether the DPLL shall be in bypass or locked mode, and if + * locked, calculates the M,N values for the DPLL via round-rate. + * Returns a positive clock rate with success, negative error value + * in failure. + */ +long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_clk) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + struct dpll_data *dd; + + if (!hw || !rate) + return -EINVAL; + + dd = clk->dpll_data; + if (!dd) + return -EINVAL; + + if (__clk_get_rate(dd->clk_bypass) == rate && + (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { + *best_parent_clk = dd->clk_bypass; + } else { + rate = omap4_dpll_regm4xen_round_rate(hw, rate, + best_parent_rate); + *best_parent_clk = dd->clk_ref; + } + + *best_parent_rate = rate; + + return rate; +} diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 07d4c7b3575..dc6e79c4484 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -14,14 +14,15 @@ #include <linux/string.h> #include <linux/delay.h> #include <linux/gpio.h> +#include <linux/mmc/host.h> #include <linux/platform_data/gpio-omap.h> +#include <linux/platform_data/hsmmc-omap.h> #include "soc.h" #include "omap_device.h" #include "omap-pm.h" #include "mux.h" -#include "mmc.h" #include "hsmmc.h" #include "control.h" @@ -32,25 +33,14 @@ static u16 control_devconf1_offset; #define HSMMC_NAME_LEN 9 -#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) - -static int hsmmc_get_context_loss(struct device *dev) -{ - return omap_pm_get_dev_context_loss_count(dev); -} - -#else -#define hsmmc_get_context_loss NULL -#endif - -static void omap_hsmmc1_before_set_reg(struct device *dev, int slot, - int power_on, int vdd) +static void omap_hsmmc1_before_set_reg(struct device *dev, + int power_on, int vdd) { u32 reg, prog_io; - struct omap_mmc_platform_data *mmc = dev->platform_data; + struct omap_hsmmc_platform_data *mmc = dev->platform_data; - if (mmc->slots[0].remux) - mmc->slots[0].remux(dev, slot, power_on); + if (mmc->remux) + mmc->remux(dev, power_on); /* * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the @@ -72,7 +62,7 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, int slot, omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1); } - if (mmc->slots[0].internal_clock) { + if (mmc->internal_clock) { reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); reg |= OMAP2_MMCSDIO1ADPCLKISEL; omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0); @@ -96,8 +86,7 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, int slot, } } -static void omap_hsmmc1_after_set_reg(struct device *dev, int slot, - int power_on, int vdd) +static void omap_hsmmc1_after_set_reg(struct device *dev, int power_on, int vdd) { u32 reg; @@ -120,34 +109,32 @@ static void omap_hsmmc1_after_set_reg(struct device *dev, int slot, } } -static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc) +static void hsmmc2_select_input_clk_src(struct omap_hsmmc_platform_data *mmc) { u32 reg; reg = omap_ctrl_readl(control_devconf1_offset); - if (mmc->slots[0].internal_clock) + if (mmc->internal_clock) reg |= OMAP2_MMCSDIO2ADPCLKISEL; else reg &= ~OMAP2_MMCSDIO2ADPCLKISEL; omap_ctrl_writel(reg, control_devconf1_offset); } -static void hsmmc2_before_set_reg(struct device *dev, int slot, - int power_on, int vdd) +static void hsmmc2_before_set_reg(struct device *dev, int power_on, int vdd) { - struct omap_mmc_platform_data *mmc = dev->platform_data; + struct omap_hsmmc_platform_data *mmc = dev->platform_data; - if (mmc->slots[0].remux) - mmc->slots[0].remux(dev, slot, power_on); + if (mmc->remux) + mmc->remux(dev, power_on); if (power_on) hsmmc2_select_input_clk_src(mmc); } -static int am35x_hsmmc2_set_power(struct device *dev, int slot, - int power_on, int vdd) +static int am35x_hsmmc2_set_power(struct device *dev, int power_on, int vdd) { - struct omap_mmc_platform_data *mmc = dev->platform_data; + struct omap_hsmmc_platform_data *mmc = dev->platform_data; if (power_on) hsmmc2_select_input_clk_src(mmc); @@ -155,23 +142,22 @@ static int am35x_hsmmc2_set_power(struct device *dev, int slot, return 0; } -static int nop_mmc_set_power(struct device *dev, int slot, int power_on, - int vdd) +static int nop_mmc_set_power(struct device *dev, int power_on, int vdd) { return 0; } -static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, - int controller_nr) +static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data + *mmc_controller, int controller_nr) { - if (gpio_is_valid(mmc_controller->slots[0].switch_pin) && - (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES)) - omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, - OMAP_PIN_INPUT_PULLUP); - if (gpio_is_valid(mmc_controller->slots[0].gpio_wp) && - (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) - omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, - OMAP_PIN_INPUT_PULLUP); + if (gpio_is_valid(mmc_controller->switch_pin) && + (mmc_controller->switch_pin < OMAP_MAX_GPIO_LINES)) + omap_mux_init_gpio(mmc_controller->switch_pin, + OMAP_PIN_INPUT_PULLUP); + if (gpio_is_valid(mmc_controller->gpio_wp) && + (mmc_controller->gpio_wp < OMAP_MAX_GPIO_LINES)) + omap_mux_init_gpio(mmc_controller->gpio_wp, + OMAP_PIN_INPUT_PULLUP); if (cpu_is_omap34xx()) { if (controller_nr == 0) { omap_mux_init_signal("sdmmc1_clk", @@ -180,7 +166,7 @@ static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("sdmmc1_dat0", OMAP_PIN_INPUT_PULLUP); - if (mmc_controller->slots[0].caps & + if (mmc_controller->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { omap_mux_init_signal("sdmmc1_dat1", OMAP_PIN_INPUT_PULLUP); @@ -189,7 +175,7 @@ static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, omap_mux_init_signal("sdmmc1_dat3", OMAP_PIN_INPUT_PULLUP); } - if (mmc_controller->slots[0].caps & + if (mmc_controller->caps & MMC_CAP_8_BIT_DATA) { omap_mux_init_signal("sdmmc1_dat4", OMAP_PIN_INPUT_PULLUP); @@ -214,7 +200,7 @@ static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, * For 8 wire configurations, Lines DAT4, 5, 6 and 7 * need to be muxed in the board-*.c files */ - if (mmc_controller->slots[0].caps & + if (mmc_controller->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { omap_mux_init_signal("sdmmc2_dat1", OMAP_PIN_INPUT_PULLUP); @@ -223,7 +209,7 @@ static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, omap_mux_init_signal("sdmmc2_dat3", OMAP_PIN_INPUT_PULLUP); } - if (mmc_controller->slots[0].caps & + if (mmc_controller->caps & MMC_CAP_8_BIT_DATA) { omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4", OMAP_PIN_INPUT_PULLUP); @@ -243,7 +229,7 @@ static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, } static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, - struct omap_mmc_platform_data *mmc) + struct omap_hsmmc_platform_data *mmc) { char *hc_name; @@ -259,38 +245,22 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, else snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i", c->mmc, 1); - mmc->slots[0].name = hc_name; - mmc->nr_slots = 1; - mmc->slots[0].caps = c->caps; - mmc->slots[0].pm_caps = c->pm_caps; - mmc->slots[0].internal_clock = !c->ext_clock; - mmc->max_freq = c->max_freq; + mmc->name = hc_name; + mmc->caps = c->caps; + mmc->internal_clock = !c->ext_clock; mmc->reg_offset = 0; - mmc->get_context_loss_count = hsmmc_get_context_loss; - mmc->slots[0].switch_pin = c->gpio_cd; - mmc->slots[0].gpio_wp = c->gpio_wp; + mmc->switch_pin = c->gpio_cd; + mmc->gpio_wp = c->gpio_wp; - mmc->slots[0].remux = c->remux; - mmc->slots[0].init_card = c->init_card; + mmc->remux = c->remux; + mmc->init_card = c->init_card; if (c->cover_only) - mmc->slots[0].cover = 1; + mmc->cover = 1; if (c->nonremovable) - mmc->slots[0].nonremovable = 1; - - if (c->power_saving) - mmc->slots[0].power_saving = 1; - - if (c->no_off) - mmc->slots[0].no_off = 1; - - if (c->no_off_init) - mmc->slots[0].no_regulator_off_init = c->no_off_init; - - if (c->vcc_aux_disable_is_sleep) - mmc->slots[0].vcc_aux_disable_is_sleep = 1; + mmc->nonremovable = 1; /* * NOTE: MMC slots should have a Vcc regulator set up. @@ -300,42 +270,42 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, * temporary HACK: ocr_mask instead of fixed supply */ if (soc_is_am35xx()) - mmc->slots[0].ocr_mask = MMC_VDD_165_195 | + mmc->ocr_mask = MMC_VDD_165_195 | MMC_VDD_26_27 | MMC_VDD_27_28 | MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32; else - mmc->slots[0].ocr_mask = c->ocr_mask; + mmc->ocr_mask = c->ocr_mask; if (!soc_is_am35xx()) - mmc->slots[0].features |= HSMMC_HAS_PBIAS; + mmc->features |= HSMMC_HAS_PBIAS; switch (c->mmc) { case 1: - if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { + if (mmc->features & HSMMC_HAS_PBIAS) { /* on-chip level shifting via PBIAS0/PBIAS1 */ - mmc->slots[0].before_set_reg = + mmc->before_set_reg = omap_hsmmc1_before_set_reg; - mmc->slots[0].after_set_reg = + mmc->after_set_reg = omap_hsmmc1_after_set_reg; } if (soc_is_am35xx()) - mmc->slots[0].set_power = nop_mmc_set_power; + mmc->set_power = nop_mmc_set_power; /* OMAP3630 HSMMC1 supports only 4-bit */ if (cpu_is_omap3630() && (c->caps & MMC_CAP_8_BIT_DATA)) { c->caps &= ~MMC_CAP_8_BIT_DATA; c->caps |= MMC_CAP_4_BIT_DATA; - mmc->slots[0].caps = c->caps; + mmc->caps = c->caps; } break; case 2: if (soc_is_am35xx()) - mmc->slots[0].set_power = am35x_hsmmc2_set_power; + mmc->set_power = am35x_hsmmc2_set_power; if (c->ext_clock) c->transceiver = 1; @@ -343,17 +313,17 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, c->caps &= ~MMC_CAP_8_BIT_DATA; c->caps |= MMC_CAP_4_BIT_DATA; } - if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { + if (mmc->features & HSMMC_HAS_PBIAS) { /* off-chip level shifting, or none */ - mmc->slots[0].before_set_reg = hsmmc2_before_set_reg; - mmc->slots[0].after_set_reg = NULL; + mmc->before_set_reg = hsmmc2_before_set_reg; + mmc->after_set_reg = NULL; } break; case 3: case 4: case 5: - mmc->slots[0].before_set_reg = NULL; - mmc->slots[0].after_set_reg = NULL; + mmc->before_set_reg = NULL; + mmc->after_set_reg = NULL; break; default: pr_err("MMC%d configuration not supported!\n", c->mmc); @@ -368,7 +338,7 @@ static int omap_hsmmc_done; void omap_hsmmc_late_init(struct omap2_hsmmc_info *c) { struct platform_device *pdev; - struct omap_mmc_platform_data *mmc_pdata; + struct omap_hsmmc_platform_data *mmc_pdata; int res; if (omap_hsmmc_done != 1) @@ -388,8 +358,8 @@ void omap_hsmmc_late_init(struct omap2_hsmmc_info *c) if (!mmc_pdata) continue; - mmc_pdata->slots[0].switch_pin = c->gpio_cd; - mmc_pdata->slots[0].gpio_wp = c->gpio_wp; + mmc_pdata->switch_pin = c->gpio_cd; + mmc_pdata->gpio_wp = c->gpio_wp; res = omap_device_register(pdev); if (res) @@ -408,12 +378,12 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, struct omap_device *od; struct platform_device *pdev; char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN]; - struct omap_mmc_platform_data *mmc_data; - struct omap_mmc_dev_attr *mmc_dev_attr; + struct omap_hsmmc_platform_data *mmc_data; + struct omap_hsmmc_dev_attr *mmc_dev_attr; char *name; int res; - mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); + mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL); if (!mmc_data) { pr_err("Cannot allocate memory for mmc device!\n"); return; @@ -463,7 +433,7 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, } res = platform_device_add_data(pdev, mmc_data, - sizeof(struct omap_mmc_platform_data)); + sizeof(struct omap_hsmmc_platform_data)); if (res) { pr_err("Could not add pdata for %s\n", name); goto put_pdev; @@ -489,7 +459,7 @@ put_pdev: platform_device_put(pdev); free_name: - kfree(mmc_data->slots[0].name); + kfree(mmc_data->name); free_mmc: kfree(mmc_data); diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h index 7f2e790e092..148cd9b1549 100644 --- a/arch/arm/mach-omap2/hsmmc.h +++ b/arch/arm/mach-omap2/hsmmc.h @@ -12,25 +12,18 @@ struct omap2_hsmmc_info { u8 mmc; /* controller 1/2/3 */ u32 caps; /* 4/8 wires and any additional host * capabilities OR'd (ref. linux/mmc/host.h) */ - u32 pm_caps; /* PM capabilities */ bool transceiver; /* MMC-2 option */ bool ext_clock; /* use external pin for input clock */ bool cover_only; /* No card detect - just cover switch */ bool nonremovable; /* Nonremovable e.g. eMMC */ - bool power_saving; /* Try to sleep or power off when possible */ - bool no_off; /* power_saving and power is not to go off */ - bool no_off_init; /* no power off when not in MMC sleep state */ - bool vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */ bool deferred; /* mmc needs a deferred probe */ int gpio_cd; /* or -EINVAL */ int gpio_wp; /* or -EINVAL */ char *name; /* or NULL for default */ struct platform_device *pdev; /* mmc controller instance */ int ocr_mask; /* temporary HACK */ - int max_freq; /* maximum clock, if constrained by external - * circuitry, or 0 for default */ /* Remux (pad configuration) when powering on/off */ - void (*remux)(struct device *dev, int slot, int power_on); + void (*remux)(struct device *dev, int power_on); /* init some special card */ void (*init_card)(struct mmc_card *card); }; diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 03cbb16898a..4fc838354e3 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -45,13 +45,15 @@ #include "sram.h" #include "cm2xxx.h" #include "cm3xxx.h" +#include "cm33xx.h" +#include "cm44xx.h" #include "prm.h" #include "cm.h" #include "prcm_mpu44xx.h" #include "prminst44xx.h" -#include "cminst44xx.h" #include "prm2xxx.h" #include "prm3xxx.h" +#include "prm33xx.h" #include "prm44xx.h" #include "opp2xxx.h" @@ -565,6 +567,8 @@ void __init am33xx_init_early(void) omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), NULL); omap3xxx_check_revision(); am33xx_check_features(); + am33xx_prm_init(); + am33xx_cm_init(); am33xx_powerdomains_init(); am33xx_clockdomains_init(); am33xx_hwmod_init(); @@ -591,6 +595,8 @@ void __init am43xx_init_early(void) omap_cm_base_init(); omap3xxx_check_revision(); am33xx_check_features(); + omap44xx_prm_init(); + omap4_cm_init(); am43xx_powerdomains_init(); am43xx_clockdomains_init(); am43xx_hwmod_init(); @@ -620,6 +626,7 @@ void __init omap4430_init_early(void) omap_cm_base_init(); omap4xxx_check_revision(); omap4xxx_check_features(); + omap4_cm_init(); omap4_pm_init_early(); omap44xx_prm_init(); omap44xx_voltagedomains_init(); @@ -655,6 +662,7 @@ void __init omap5_init_early(void) omap_cm_base_init(); omap44xx_prm_init(); omap5xxx_check_revision(); + omap4_cm_init(); omap54xx_voltagedomains_init(); omap54xx_powerdomains_init(); omap54xx_clockdomains_init(); @@ -686,6 +694,7 @@ void __init dra7xx_init_early(void) omap_cm_base_init(); omap44xx_prm_init(); dra7xxx_check_revision(); + omap4_cm_init(); dra7xx_powerdomains_init(); dra7xx_clockdomains_init(); dra7xx_hwmod_init(); diff --git a/arch/arm/mach-omap2/mmc.h b/arch/arm/mach-omap2/mmc.h index 0cd4b089da9..30d39b97e7d 100644 --- a/arch/arm/mach-omap2/mmc.h +++ b/arch/arm/mach-omap2/mmc.h @@ -1,5 +1,3 @@ -#include <linux/mmc/host.h> -#include <linux/platform_data/mmc-omap.h> #define OMAP24XX_NR_MMC 2 #define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE @@ -7,14 +5,6 @@ #define OMAP4_MMC_REG_OFFSET 0x100 -#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) -void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data); -#else -static inline void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) -{ -} -#endif - struct omap_hwmod; int omap_msdi_reset(struct omap_hwmod *oh); diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 6944ae3674e..79f49d904a0 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -227,7 +227,7 @@ static void __init save_l2x0_context(void) int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) { struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); - unsigned int save_state = 0; + unsigned int save_state = 0, cpu_logic_state = PWRDM_POWER_RET; unsigned int wakeup_cpu; if (omap_rev() == OMAP4430_REV_ES1_0) @@ -239,6 +239,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) save_state = 0; break; case PWRDM_POWER_OFF: + cpu_logic_state = PWRDM_POWER_OFF; save_state = 1; break; case PWRDM_POWER_RET: @@ -270,6 +271,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) cpu_clear_prev_logic_pwrst(cpu); pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); + pwrdm_set_logic_retst(pm_info->pwrdm, cpu_logic_state); set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume)); omap_pm_ops.scu_prepare(cpu, power_state); l2x0_pwrst_prepare(cpu, save_state); diff --git a/arch/arm/mach-omap2/omap2-restart.c b/arch/arm/mach-omap2/omap2-restart.c index 68423e26399..d937b2e4040 100644 --- a/arch/arm/mach-omap2/omap2-restart.c +++ b/arch/arm/mach-omap2/omap2-restart.c @@ -15,7 +15,7 @@ #include "soc.h" #include "common.h" -#include "prm2xxx.h" +#include "prm.h" /* * reset_virt_prcm_set_ck, reset_sys_ck: pointers to the virt_prcm_set @@ -40,8 +40,7 @@ void omap2xxx_restart(enum reboot_mode mode, const char *cmd) /* XXX Should save the cmd argument for use after the reboot */ - omap2xxx_prm_dpll_reset(); /* never returns */ - while (1); + omap_prm_reset_system(); } /** diff --git a/arch/arm/mach-omap2/omap3-restart.c b/arch/arm/mach-omap2/omap3-restart.c index 5de2a0c2979..103a49f68bc 100644 --- a/arch/arm/mach-omap2/omap3-restart.c +++ b/arch/arm/mach-omap2/omap3-restart.c @@ -14,10 +14,8 @@ #include <linux/init.h> #include <linux/reboot.h> -#include "iomap.h" -#include "common.h" #include "control.h" -#include "prm3xxx.h" +#include "prm.h" /* Global address base setup code */ @@ -32,6 +30,5 @@ void omap3xxx_restart(enum reboot_mode mode, const char *cmd) { omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0)); - omap3xxx_prm_dpll3_reset(); /* never returns */ - while (1); + omap_prm_reset_system(); } diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 16b20cedc38..b7cb44abe49 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -36,7 +36,6 @@ #include "soc.h" #include "iomap.h" #include "common.h" -#include "mmc.h" #include "prminst44xx.h" #include "prcm_mpu44xx.h" #include "omap4-sar-layout.h" diff --git a/arch/arm/mach-omap2/omap4-restart.c b/arch/arm/mach-omap2/omap4-restart.c index 41dfd7da817..a99e7f7fb5b 100644 --- a/arch/arm/mach-omap2/omap4-restart.c +++ b/arch/arm/mach-omap2/omap4-restart.c @@ -9,7 +9,7 @@ #include <linux/types.h> #include <linux/reboot.h> -#include "prminst44xx.h" +#include "prm.h" /** * omap44xx_restart - trigger a software restart of the SoC @@ -22,7 +22,5 @@ void omap44xx_restart(enum reboot_mode mode, const char *cmd) { /* XXX Should save 'cmd' into scratchpad for use after reboot */ - omap4_prminst_global_warm_sw_reset(); /* never returns */ - while (1) - ; + omap_prm_reset_system(); } diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index d22c30d3ccf..8c58b71c272 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -917,6 +917,10 @@ static int __init omap_device_late_idle(struct device *dev, void *data) static int __init omap_device_late_init(void) { bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle); + + WARN(!of_have_populated_dt(), + "legacy booting deprecated, please update to boot with .dts\n"); + return 0; } omap_late_initcall_sync(omap_device_late_init); diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 716247ed9e0..cbb908dc5cf 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -153,7 +153,6 @@ #include "powerdomain.h" #include "cm2xxx.h" #include "cm3xxx.h" -#include "cminst44xx.h" #include "cm33xx.h" #include "prm.h" #include "prm3xxx.h" @@ -979,31 +978,9 @@ static void _omap4_enable_module(struct omap_hwmod *oh) pr_debug("omap_hwmod: %s: %s: %d\n", oh->name, __func__, oh->prcm.omap4.modulemode); - omap4_cminst_module_enable(oh->prcm.omap4.modulemode, - oh->clkdm->prcm_partition, - oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); -} - -/** - * _am33xx_enable_module - enable CLKCTRL modulemode on AM33XX - * @oh: struct omap_hwmod * - * - * Enables the PRCM module mode related to the hwmod @oh. - * No return value. - */ -static void _am33xx_enable_module(struct omap_hwmod *oh) -{ - if (!oh->clkdm || !oh->prcm.omap4.modulemode) - return; - - pr_debug("omap_hwmod: %s: %s: %d\n", - oh->name, __func__, oh->prcm.omap4.modulemode); - - am33xx_cm_module_enable(oh->prcm.omap4.modulemode, oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); + omap_cm_module_enable(oh->prcm.omap4.modulemode, + oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, oh->prcm.omap4.clkctrl_offs); } /** @@ -1026,35 +1003,9 @@ static int _omap4_wait_target_disable(struct omap_hwmod *oh) if (oh->flags & HWMOD_NO_IDLEST) return 0; - return omap4_cminst_wait_module_idle(oh->clkdm->prcm_partition, - oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); -} - -/** - * _am33xx_wait_target_disable - wait for a module to be disabled on AM33XX - * @oh: struct omap_hwmod * - * - * Wait for a module @oh to enter slave idle. Returns 0 if the module - * does not have an IDLEST bit or if the module successfully enters - * slave idle; otherwise, pass along the return value of the - * appropriate *_cm*_wait_module_idle() function. - */ -static int _am33xx_wait_target_disable(struct omap_hwmod *oh) -{ - if (!oh) - return -EINVAL; - - if (oh->_int_flags & _HWMOD_NO_MPU_PORT) - return 0; - - if (oh->flags & HWMOD_NO_IDLEST) - return 0; - - return am33xx_cm_wait_module_idle(oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); + return omap_cm_wait_module_idle(oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->prcm.omap4.clkctrl_offs, 0); } /** @@ -1859,10 +1810,8 @@ static int _omap4_disable_module(struct omap_hwmod *oh) pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); - omap4_cminst_module_disable(oh->clkdm->prcm_partition, - oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); + omap_cm_module_disable(oh->clkdm->prcm_partition, oh->clkdm->cm_inst, + oh->prcm.omap4.clkctrl_offs); v = _omap4_wait_target_disable(oh); if (v) @@ -1873,36 +1822,6 @@ static int _omap4_disable_module(struct omap_hwmod *oh) } /** - * _am33xx_disable_module - enable CLKCTRL modulemode on AM33XX - * @oh: struct omap_hwmod * - * - * Disable the PRCM module mode related to the hwmod @oh. - * Return EINVAL if the modulemode is not supported and 0 in case of success. - */ -static int _am33xx_disable_module(struct omap_hwmod *oh) -{ - int v; - - if (!oh->clkdm || !oh->prcm.omap4.modulemode) - return -EINVAL; - - pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); - - if (_are_any_hardreset_lines_asserted(oh)) - return 0; - - am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); - - v = _am33xx_wait_target_disable(oh); - if (v) - pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", - oh->name); - - return 0; -} - -/** * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit * @oh: struct omap_hwmod * * @@ -2065,10 +1984,7 @@ static void _reconfigure_io_chain(void) spin_lock_irqsave(&io_chain_lock, flags); - if (cpu_is_omap34xx()) - omap3xxx_prm_reconfigure_io_chain(); - else if (cpu_is_omap44xx()) - omap44xx_prm_reconfigure_io_chain(); + omap_prm_reconfigure_io_chain(); spin_unlock_irqrestore(&io_chain_lock, flags); } @@ -2719,11 +2635,33 @@ static int __init _setup(struct omap_hwmod *oh, void *data) if (oh->_state != _HWMOD_STATE_INITIALIZED) return 0; + if (oh->parent_hwmod) { + int r; + + r = _enable(oh->parent_hwmod); + WARN(r, "hwmod: %s: setup: failed to enable parent hwmod %s\n", + oh->name, oh->parent_hwmod->name); + } + _setup_iclk_autoidle(oh); if (!_setup_reset(oh)) _setup_postsetup(oh); + if (oh->parent_hwmod) { + u8 postsetup_state; + + postsetup_state = oh->parent_hwmod->_postsetup_state; + + if (postsetup_state == _HWMOD_STATE_IDLE) + _idle(oh->parent_hwmod); + else if (postsetup_state == _HWMOD_STATE_DISABLED) + _shutdown(oh->parent_hwmod); + else if (postsetup_state != _HWMOD_STATE_ENABLED) + WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n", + oh->parent_hwmod->name, postsetup_state); + } + return 0; } @@ -2832,12 +2770,10 @@ static int __init _add_link(struct omap_hwmod_ocp_if *oi) _alloc_links(&ml, &sl); ml->ocp_if = oi; - INIT_LIST_HEAD(&ml->node); list_add(&ml->node, &oi->master->master_ports); oi->master->masters_cnt++; sl->ocp_if = oi; - INIT_LIST_HEAD(&sl->node); list_add(&sl->node, &oi->slave->slave_ports); oi->slave->slaves_cnt++; @@ -2927,34 +2863,7 @@ static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois) /* Static functions intended only for use in soc_ops field function pointers */ /** - * _omap2xxx_wait_target_ready - wait for a module to leave slave idle - * @oh: struct omap_hwmod * - * - * Wait for a module @oh to leave slave idle. Returns 0 if the module - * does not have an IDLEST bit or if the module successfully leaves - * slave idle; otherwise, pass along the return value of the - * appropriate *_cm*_wait_module_ready() function. - */ -static int _omap2xxx_wait_target_ready(struct omap_hwmod *oh) -{ - if (!oh) - return -EINVAL; - - if (oh->flags & HWMOD_NO_IDLEST) - return 0; - - if (!_find_mpu_rt_port(oh)) - return 0; - - /* XXX check module SIDLEMODE, hardreset status, enabled clocks */ - - return omap2xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs, - oh->prcm.omap2.idlest_reg_id, - oh->prcm.omap2.idlest_idle_bit); -} - -/** - * _omap3xxx_wait_target_ready - wait for a module to leave slave idle + * _omap2xxx_3xxx_wait_target_ready - wait for a module to leave slave idle * @oh: struct omap_hwmod * * * Wait for a module @oh to leave slave idle. Returns 0 if the module @@ -2962,7 +2871,7 @@ static int _omap2xxx_wait_target_ready(struct omap_hwmod *oh) * slave idle; otherwise, pass along the return value of the * appropriate *_cm*_wait_module_ready() function. */ -static int _omap3xxx_wait_target_ready(struct omap_hwmod *oh) +static int _omap2xxx_3xxx_wait_target_ready(struct omap_hwmod *oh) { if (!oh) return -EINVAL; @@ -2975,9 +2884,9 @@ static int _omap3xxx_wait_target_ready(struct omap_hwmod *oh) /* XXX check module SIDLEMODE, hardreset status, enabled clocks */ - return omap3xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs, - oh->prcm.omap2.idlest_reg_id, - oh->prcm.omap2.idlest_idle_bit); + return omap_cm_wait_module_ready(0, oh->prcm.omap2.module_offs, + oh->prcm.omap2.idlest_reg_id, + oh->prcm.omap2.idlest_idle_bit); } /** @@ -3002,37 +2911,9 @@ static int _omap4_wait_target_ready(struct omap_hwmod *oh) /* XXX check module SIDLEMODE, hardreset status */ - return omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition, - oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); -} - -/** - * _am33xx_wait_target_ready - wait for a module to leave slave idle - * @oh: struct omap_hwmod * - * - * Wait for a module @oh to leave slave idle. Returns 0 if the module - * does not have an IDLEST bit or if the module successfully leaves - * slave idle; otherwise, pass along the return value of the - * appropriate *_cm*_wait_module_ready() function. - */ -static int _am33xx_wait_target_ready(struct omap_hwmod *oh) -{ - if (!oh || !oh->clkdm) - return -EINVAL; - - if (oh->flags & HWMOD_NO_IDLEST) - return 0; - - if (!_find_mpu_rt_port(oh)) - return 0; - - /* XXX check module SIDLEMODE, hardreset status */ - - return am33xx_cm_wait_module_ready(oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); + return omap_cm_wait_module_ready(oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->prcm.omap4.clkctrl_offs, 0); } /** @@ -3049,8 +2930,8 @@ static int _am33xx_wait_target_ready(struct omap_hwmod *oh) static int _omap2_assert_hardreset(struct omap_hwmod *oh, struct omap_hwmod_rst_info *ohri) { - return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, - ohri->rst_shift); + return omap_prm_assert_hardreset(ohri->rst_shift, 0, + oh->prcm.omap2.module_offs, 0); } /** @@ -3067,9 +2948,8 @@ static int _omap2_assert_hardreset(struct omap_hwmod *oh, static int _omap2_deassert_hardreset(struct omap_hwmod *oh, struct omap_hwmod_rst_info *ohri) { - return omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs, - ohri->rst_shift, - ohri->st_shift); + return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0, + oh->prcm.omap2.module_offs, 0, 0); } /** @@ -3087,8 +2967,8 @@ static int _omap2_deassert_hardreset(struct omap_hwmod *oh, static int _omap2_is_hardreset_asserted(struct omap_hwmod *oh, struct omap_hwmod_rst_info *ohri) { - return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, - ohri->st_shift); + return omap_prm_is_hardreset_asserted(ohri->st_shift, 0, + oh->prcm.omap2.module_offs, 0); } /** @@ -3109,10 +2989,10 @@ static int _omap4_assert_hardreset(struct omap_hwmod *oh, if (!oh->clkdm) return -EINVAL; - return omap4_prminst_assert_hardreset(ohri->rst_shift, - oh->clkdm->pwrdm.ptr->prcm_partition, - oh->clkdm->pwrdm.ptr->prcm_offs, - oh->prcm.omap4.rstctrl_offs); + return omap_prm_assert_hardreset(ohri->rst_shift, + oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); } /** @@ -3136,10 +3016,10 @@ static int _omap4_deassert_hardreset(struct omap_hwmod *oh, if (ohri->st_shift) pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", oh->name, ohri->name); - return omap4_prminst_deassert_hardreset(ohri->rst_shift, - oh->clkdm->pwrdm.ptr->prcm_partition, - oh->clkdm->pwrdm.ptr->prcm_offs, - oh->prcm.omap4.rstctrl_offs); + return omap_prm_deassert_hardreset(ohri->rst_shift, 0, + oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs, 0); } /** @@ -3160,10 +3040,11 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh, if (!oh->clkdm) return -EINVAL; - return omap4_prminst_is_hardreset_asserted(ohri->rst_shift, - oh->clkdm->pwrdm.ptr->prcm_partition, - oh->clkdm->pwrdm.ptr->prcm_offs, - oh->prcm.omap4.rstctrl_offs); + return omap_prm_is_hardreset_asserted(ohri->rst_shift, + oh->clkdm->pwrdm.ptr-> + prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); } /** @@ -3182,9 +3063,9 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh, struct omap_hwmod_rst_info *ohri) { - return am33xx_prm_assert_hardreset(ohri->rst_shift, - oh->clkdm->pwrdm.ptr->prcm_offs, - oh->prcm.omap4.rstctrl_offs); + return omap_prm_assert_hardreset(ohri->rst_shift, 0, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); } /** @@ -3202,11 +3083,10 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh, static int _am33xx_deassert_hardreset(struct omap_hwmod *oh, struct omap_hwmod_rst_info *ohri) { - return am33xx_prm_deassert_hardreset(ohri->rst_shift, - ohri->st_shift, - oh->clkdm->pwrdm.ptr->prcm_offs, - oh->prcm.omap4.rstctrl_offs, - oh->prcm.omap4.rstst_offs); + return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs, + oh->prcm.omap4.rstst_offs); } /** @@ -3224,9 +3104,9 @@ static int _am33xx_deassert_hardreset(struct omap_hwmod *oh, static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh, struct omap_hwmod_rst_info *ohri) { - return am33xx_prm_is_hardreset_asserted(ohri->rst_shift, - oh->clkdm->pwrdm.ptr->prcm_offs, - oh->prcm.omap4.rstctrl_offs); + return omap_prm_is_hardreset_asserted(ohri->rst_shift, 0, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); } /* Public functions */ @@ -4234,12 +4114,12 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx) void __init omap_hwmod_init(void) { if (cpu_is_omap24xx()) { - soc_ops.wait_target_ready = _omap2xxx_wait_target_ready; + soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready; soc_ops.assert_hardreset = _omap2_assert_hardreset; soc_ops.deassert_hardreset = _omap2_deassert_hardreset; soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; } else if (cpu_is_omap34xx()) { - soc_ops.wait_target_ready = _omap3xxx_wait_target_ready; + soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready; soc_ops.assert_hardreset = _omap2_assert_hardreset; soc_ops.deassert_hardreset = _omap2_deassert_hardreset; soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; @@ -4258,14 +4138,14 @@ void __init omap_hwmod_init(void) soc_ops.enable_module = _omap4_enable_module; soc_ops.disable_module = _omap4_disable_module; soc_ops.wait_target_ready = _omap4_wait_target_ready; - soc_ops.assert_hardreset = _am33xx_assert_hardreset; - soc_ops.deassert_hardreset = _am33xx_deassert_hardreset; - soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted; + soc_ops.assert_hardreset = _omap4_assert_hardreset; + soc_ops.deassert_hardreset = _omap4_deassert_hardreset; + soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; soc_ops.init_clkdm = _init_clkdm; } else if (soc_is_am33xx()) { - soc_ops.enable_module = _am33xx_enable_module; - soc_ops.disable_module = _am33xx_disable_module; - soc_ops.wait_target_ready = _am33xx_wait_target_ready; + soc_ops.enable_module = _omap4_enable_module; + soc_ops.disable_module = _omap4_disable_module; + soc_ops.wait_target_ready = _omap4_wait_target_ready; soc_ops.assert_hardreset = _am33xx_assert_hardreset; soc_ops.deassert_hardreset = _am33xx_deassert_hardreset; soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted; diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 512f809a3f4..35ca6efbec3 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -633,6 +633,7 @@ struct omap_hwmod_link { * @flags: hwmod flags (documented below) * @_lock: spinlock serializing operations on this hwmod * @node: list node for hwmod list (internal use) + * @parent_hwmod: (temporary) a pointer to the hierarchical parent of this hwmod * * @main_clk refers to this module's "main clock," which for our * purposes is defined as "the functional clock needed for register @@ -643,6 +644,12 @@ struct omap_hwmod_link { * the omap_hwmod code and should not be set during initialization. * * @masters and @slaves are now deprecated. + * + * @parent_hwmod is temporary; there should be no need for it, as this + * information should already be expressed in the OCP interface + * structures. @parent_hwmod is present as a workaround until we improve + * handling for hwmods with multiple parents (e.g., OMAP4+ DSS with + * multiple register targets across different interconnects). */ struct omap_hwmod { const char *name; @@ -680,6 +687,7 @@ struct omap_hwmod { u8 _int_flags; u8 _state; u8 _postsetup_state; + struct omap_hwmod *parent_hwmod; }; struct omap_hwmod *omap_hwmod_lookup(const char *name); diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index c2555cb95e7..79127b35fe6 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -15,12 +15,12 @@ #include <linux/i2c-omap.h> #include <linux/platform_data/asoc-ti-mcbsp.h> +#include <linux/platform_data/hsmmc-omap.h> #include <linux/platform_data/spi-omap2-mcspi.h> #include <linux/omap-dma.h> #include <plat/dmtimer.h> #include "omap_hwmod.h" -#include "mmc.h" #include "l3_2xxx.h" #include "soc.h" @@ -372,7 +372,7 @@ static struct omap_hwmod_opt_clk omap2430_mmc1_opt_clks[] = { { .role = "dbck", .clk = "mmchsdb1_fck" }, }; -static struct omap_mmc_dev_attr mmc1_dev_attr = { +static struct omap_hsmmc_dev_attr mmc1_dev_attr = { .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c index a579b89ce9b..cabc5695b50 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c @@ -15,10 +15,10 @@ */ #include <linux/platform_data/gpio-omap.h> +#include <linux/platform_data/hsmmc-omap.h> #include <linux/platform_data/spi-omap2-mcspi.h> #include "omap_hwmod.h" #include "i2c.h" -#include "mmc.h" #include "wd_timer.h" #include "cm33xx.h" #include "prm33xx.h" @@ -836,7 +836,7 @@ static struct omap_hwmod_class am33xx_mmc_hwmod_class = { }; /* mmc0 */ -static struct omap_mmc_dev_attr am33xx_mmc0_dev_attr = { +static struct omap_hsmmc_dev_attr am33xx_mmc0_dev_attr = { .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, }; @@ -854,7 +854,7 @@ struct omap_hwmod am33xx_mmc0_hwmod = { }; /* mmc1 */ -static struct omap_mmc_dev_attr am33xx_mmc1_dev_attr = { +static struct omap_hsmmc_dev_attr am33xx_mmc1_dev_attr = { .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, }; @@ -872,7 +872,7 @@ struct omap_hwmod am33xx_mmc1_hwmod = { }; /* mmc2 */ -static struct omap_mmc_dev_attr am33xx_mmc2_dev_attr = { +static struct omap_hsmmc_dev_attr am33xx_mmc2_dev_attr = { .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, }; struct omap_hwmod am33xx_mmc2_hwmod = { diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 6b406ca4bd3..0cf7b563dcd 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -27,7 +27,6 @@ #include "prm33xx.h" #include "prm-regbits-33xx.h" #include "i2c.h" -#include "mmc.h" #include "wd_timer.h" #include "omap_hwmod_33xx_43xx_common_data.h" diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 2a78b093c0c..11468eea387 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -18,6 +18,7 @@ #include <linux/i2c-omap.h> #include <linux/power/smartreflex.h> #include <linux/platform_data/gpio-omap.h> +#include <linux/platform_data/hsmmc-omap.h> #include <linux/omap-dma.h> #include "l3_3xxx.h" @@ -37,7 +38,6 @@ #include "cm-regbits-34xx.h" #include "i2c.h" -#include "mmc.h" #include "wd_timer.h" #include "serial.h" @@ -1786,12 +1786,12 @@ static struct omap_hwmod_opt_clk omap34xx_mmc1_opt_clks[] = { { .role = "dbck", .clk = "omap_32k_fck", }, }; -static struct omap_mmc_dev_attr mmc1_dev_attr = { +static struct omap_hsmmc_dev_attr mmc1_dev_attr = { .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, }; /* See 35xx errata 2.1.1.128 in SPRZ278F */ -static struct omap_mmc_dev_attr mmc1_pre_es3_dev_attr = { +static struct omap_hsmmc_dev_attr mmc1_pre_es3_dev_attr = { .flags = (OMAP_HSMMC_SUPPORTS_DUAL_VOLT | OMAP_HSMMC_BROKEN_MULTIBLOCK_READ), }; @@ -1854,7 +1854,7 @@ static struct omap_hwmod_opt_clk omap34xx_mmc2_opt_clks[] = { }; /* See 35xx errata 2.1.1.128 in SPRZ278F */ -static struct omap_mmc_dev_attr mmc2_pre_es3_dev_attr = { +static struct omap_hsmmc_dev_attr mmc2_pre_es3_dev_attr = { .flags = OMAP_HSMMC_BROKEN_MULTIBLOCK_READ, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c index fea01aa3ef4..5c6c8410160 100644 --- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c @@ -417,6 +417,37 @@ static struct omap_hwmod am43xx_qspi_hwmod = { }, }; +/* + * 'adc/tsc' class + * TouchScreen Controller (Analog-To-Digital Converter) + */ +static struct omap_hwmod_class_sysconfig am43xx_adc_tsc_sysc = { + .rev_offs = 0x00, + .sysc_offs = 0x10, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class am43xx_adc_tsc_hwmod_class = { + .name = "adc_tsc", + .sysc = &am43xx_adc_tsc_sysc, +}; + +static struct omap_hwmod am43xx_adc_tsc_hwmod = { + .name = "adc_tsc", + .class = &am43xx_adc_tsc_hwmod_class, + .clkdm_name = "l3s_tsc_clkdm", + .main_clk = "adc_tsc_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + /* dss */ static struct omap_hwmod am43xx_dss_core_hwmod = { @@ -547,6 +578,13 @@ static struct omap_hwmod_ocp_if am43xx_l4_wkup__gpio0 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +static struct omap_hwmod_ocp_if am43xx_l4_wkup__adc_tsc = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am43xx_adc_tsc_hwmod, + .clk = "dpll_core_m4_div2_ck", + .user = OCP_USER_MPU, +}; + static struct omap_hwmod_ocp_if am43xx_l4_hs__cpgmac0 = { .master = &am43xx_l4_hs_hwmod, .slave = &am33xx_cpgmac0_hwmod, @@ -789,6 +827,7 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { &am43xx_l4_wkup__i2c1, &am43xx_l4_wkup__gpio0, &am43xx_l4_wkup__wd_timer1, + &am43xx_l4_wkup__adc_tsc, &am43xx_l3_s__qspi, &am33xx_l4_per__dcan0, &am33xx_l4_per__dcan1, diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 44e5634bba3..c314b3c3111 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -22,6 +22,7 @@ #include <linux/io.h> #include <linux/platform_data/gpio-omap.h> +#include <linux/platform_data/hsmmc-omap.h> #include <linux/power/smartreflex.h> #include <linux/i2c-omap.h> @@ -39,7 +40,6 @@ #include "prm44xx.h" #include "prm-regbits-44xx.h" #include "i2c.h" -#include "mmc.h" #include "wd_timer.h" /* Base offset for all OMAP4 interrupts external to MPUSS */ @@ -589,6 +589,7 @@ static struct omap_hwmod omap44xx_dss_hwmod = { .omap4 = { .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .opt_clks = dss_opt_clks, @@ -647,7 +648,8 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = { .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, }, }, - .dev_attr = &omap44xx_dss_dispc_dev_attr + .dev_attr = &omap44xx_dss_dispc_dev_attr, + .parent_hwmod = &omap44xx_dss_hwmod, }; /* @@ -701,6 +703,7 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = { }, .opt_clks = dss_dsi1_opt_clks, .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks), + .parent_hwmod = &omap44xx_dss_hwmod, }; /* dss_dsi2 */ @@ -733,6 +736,7 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = { }, .opt_clks = dss_dsi2_opt_clks, .opt_clks_cnt = ARRAY_SIZE(dss_dsi2_opt_clks), + .parent_hwmod = &omap44xx_dss_hwmod, }; /* @@ -790,6 +794,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { }, .opt_clks = dss_hdmi_opt_clks, .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), + .parent_hwmod = &omap44xx_dss_hwmod, }; /* @@ -819,7 +824,7 @@ static struct omap_hwmod_dma_info omap44xx_dss_rfbi_sdma_reqs[] = { }; static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { - { .role = "ick", .clk = "dss_fck" }, + { .role = "ick", .clk = "l3_div_ck" }, }; static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { @@ -836,6 +841,7 @@ static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { }, .opt_clks = dss_rfbi_opt_clks, .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), + .parent_hwmod = &omap44xx_dss_hwmod, }; /* @@ -859,6 +865,7 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = { .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, }, }, + .parent_hwmod = &omap44xx_dss_hwmod, }; /* @@ -1952,7 +1959,7 @@ static struct omap_hwmod_dma_info omap44xx_mmc1_sdma_reqs[] = { }; /* mmc1 dev_attr */ -static struct omap_mmc_dev_attr mmc1_dev_attr = { +static struct omap_hsmmc_dev_attr mmc1_dev_attr = { .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, }; @@ -3671,7 +3678,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_hwmod, - .clk = "dss_fck", + .clk = "l3_div_ck", .addr = omap44xx_dss_dma_addrs, .user = OCP_USER_SDMA, }; @@ -3707,7 +3714,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dispc_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dispc = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_dispc_hwmod, - .clk = "dss_fck", + .clk = "l3_div_ck", .addr = omap44xx_dss_dispc_dma_addrs, .user = OCP_USER_SDMA, }; @@ -3743,7 +3750,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dsi1_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi1 = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_dsi1_hwmod, - .clk = "dss_fck", + .clk = "l3_div_ck", .addr = omap44xx_dss_dsi1_dma_addrs, .user = OCP_USER_SDMA, }; @@ -3779,7 +3786,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dsi2_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi2 = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_dsi2_hwmod, - .clk = "dss_fck", + .clk = "l3_div_ck", .addr = omap44xx_dss_dsi2_dma_addrs, .user = OCP_USER_SDMA, }; @@ -3815,7 +3822,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_hdmi_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_hdmi = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_hdmi_hwmod, - .clk = "dss_fck", + .clk = "l3_div_ck", .addr = omap44xx_dss_hdmi_dma_addrs, .user = OCP_USER_SDMA, }; @@ -3851,7 +3858,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_rfbi_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_rfbi = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_rfbi_hwmod, - .clk = "dss_fck", + .clk = "l3_div_ck", .addr = omap44xx_dss_rfbi_dma_addrs, .user = OCP_USER_SDMA, }; @@ -3887,7 +3894,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_venc_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_venc = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_venc_hwmod, - .clk = "dss_fck", + .clk = "l3_div_ck", .addr = omap44xx_dss_venc_dma_addrs, .user = OCP_USER_SDMA, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c index 1103aa0e0d2..3e9523084b2 100644 --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c @@ -19,6 +19,7 @@ #include <linux/io.h> #include <linux/platform_data/gpio-omap.h> +#include <linux/platform_data/hsmmc-omap.h> #include <linux/power/smartreflex.h> #include <linux/i2c-omap.h> @@ -33,7 +34,6 @@ #include "cm2_54xx.h" #include "prm54xx.h" #include "i2c.h" -#include "mmc.h" #include "wd_timer.h" /* Base offset for all OMAP5 interrupts external to MPUSS */ @@ -421,6 +421,7 @@ static struct omap_hwmod omap54xx_dss_dispc_hwmod = { .opt_clks = dss_dispc_opt_clks, .opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks), .dev_attr = &dss_dispc_dev_attr, + .parent_hwmod = &omap54xx_dss_hwmod, }; /* @@ -462,6 +463,7 @@ static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = { }, .opt_clks = dss_dsi1_a_opt_clks, .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_a_opt_clks), + .parent_hwmod = &omap54xx_dss_hwmod, }; /* dss_dsi1_c */ @@ -482,6 +484,7 @@ static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = { }, .opt_clks = dss_dsi1_c_opt_clks, .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_c_opt_clks), + .parent_hwmod = &omap54xx_dss_hwmod, }; /* @@ -521,6 +524,7 @@ static struct omap_hwmod omap54xx_dss_hdmi_hwmod = { }, .opt_clks = dss_hdmi_opt_clks, .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), + .parent_hwmod = &omap54xx_dss_hwmod, }; /* @@ -560,6 +564,7 @@ static struct omap_hwmod omap54xx_dss_rfbi_hwmod = { }, .opt_clks = dss_rfbi_opt_clks, .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), + .parent_hwmod = &omap54xx_dss_hwmod, }; /* @@ -1269,7 +1274,7 @@ static struct omap_hwmod_opt_clk mmc1_opt_clks[] = { }; /* mmc1 dev_attr */ -static struct omap_mmc_dev_attr mmc1_dev_attr = { +static struct omap_hsmmc_dev_attr mmc1_dev_attr = { .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index 5684f112654..ffd6604cd54 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -19,6 +19,7 @@ #include <linux/io.h> #include <linux/platform_data/gpio-omap.h> +#include <linux/platform_data/hsmmc-omap.h> #include <linux/power/smartreflex.h> #include <linux/i2c-omap.h> @@ -33,7 +34,6 @@ #include "cm2_7xx.h" #include "prm7xx.h" #include "i2c.h" -#include "mmc.h" #include "wd_timer.h" #include "soc.h" @@ -1301,7 +1301,7 @@ static struct omap_hwmod_opt_clk mmc1_opt_clks[] = { }; /* mmc1 dev_attr */ -static struct omap_mmc_dev_attr mmc1_dev_attr = { +static struct omap_hsmmc_dev_attr mmc1_dev_attr = { .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, }; @@ -2075,6 +2075,70 @@ static struct omap_hwmod dra7xx_uart6_hwmod = { }, }; +/* uart7 */ +static struct omap_hwmod dra7xx_uart7_hwmod = { + .name = "uart7", + .class = &dra7xx_uart_hwmod_class, + .clkdm_name = "l4per2_clkdm", + .main_clk = "uart7_gfclk_mux", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER2_UART7_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER2_UART7_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart8 */ +static struct omap_hwmod dra7xx_uart8_hwmod = { + .name = "uart8", + .class = &dra7xx_uart_hwmod_class, + .clkdm_name = "l4per2_clkdm", + .main_clk = "uart8_gfclk_mux", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER2_UART8_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER2_UART8_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart9 */ +static struct omap_hwmod dra7xx_uart9_hwmod = { + .name = "uart9", + .class = &dra7xx_uart_hwmod_class, + .clkdm_name = "l4per2_clkdm", + .main_clk = "uart9_gfclk_mux", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER2_UART9_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER2_UART9_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart10 */ +static struct omap_hwmod dra7xx_uart10_hwmod = { + .name = "uart10", + .class = &dra7xx_uart_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .main_clk = "uart10_gfclk_mux", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_WKUPAON_UART10_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_WKUPAON_UART10_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + /* * 'usb_otg_ss' class * @@ -3095,6 +3159,38 @@ static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart6 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* l4_per2 -> uart7 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart7 = { + .master = &dra7xx_l4_per2_hwmod, + .slave = &dra7xx_uart7_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per2 -> uart8 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart8 = { + .master = &dra7xx_l4_per2_hwmod, + .slave = &dra7xx_uart8_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per2 -> uart9 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart9 = { + .master = &dra7xx_l4_per2_hwmod, + .slave = &dra7xx_uart9_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> uart10 */ +static struct omap_hwmod_ocp_if dra7xx_l4_wkup__uart10 = { + .master = &dra7xx_l4_wkup_hwmod, + .slave = &dra7xx_uart10_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* l4_per3 -> usb_otg_ss1 */ static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss1 = { .master = &dra7xx_l4_per3_hwmod, @@ -3259,6 +3355,10 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { &dra7xx_l4_per1__uart4, &dra7xx_l4_per1__uart5, &dra7xx_l4_per1__uart6, + &dra7xx_l4_per2__uart7, + &dra7xx_l4_per2__uart8, + &dra7xx_l4_per2__uart9, + &dra7xx_l4_wkup__uart10, &dra7xx_l4_per3__usb_otg_ss1, &dra7xx_l4_per3__usb_otg_ss2, &dra7xx_l4_per3__usb_otg_ss3, diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c index 50640b38f0b..1a19fa096ba 100644 --- a/arch/arm/mach-omap2/omap_phy_internal.c +++ b/arch/arm/mach-omap2/omap_phy_internal.c @@ -21,6 +21,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/types.h> #include <linux/delay.h> #include <linux/clk.h> @@ -97,13 +99,13 @@ void am35x_musb_phy_power(u8 on) omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); - pr_info(KERN_INFO "Waiting for PHY clock good...\n"); + pr_info("Waiting for PHY clock good...\n"); while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2) & CONF2_PHYCLKGD)) { cpu_relax(); if (time_after(jiffies, timeout)) { - pr_err(KERN_ERR "musb PHY clock good timed out\n"); + pr_err("musb PHY clock good timed out\n"); break; } } @@ -145,7 +147,7 @@ void am35x_set_mode(u8 musb_mode) devconf2 |= CONF2_NO_OVERRIDE; break; default: - pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode); + pr_info("Unsupported mode %u\n", musb_mode); } omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 2156f69fc28..3d7eee1d3cf 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -131,13 +131,11 @@ static void __init omap3_sbc_t3730_legacy_init(void) { omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub"); legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 136); - omap_ads7846_init(1, 57, 0, NULL); } static void __init omap3_sbc_t3530_legacy_init(void) { omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub"); - omap_ads7846_init(1, 57, 0, NULL); } struct ti_st_plat_data wilink_pdata = { @@ -249,7 +247,6 @@ static void __init omap3_sbc_t3517_legacy_init(void) hsmmc2_internal_input_clk(); omap3_sbc_t3517_wifi_init(); legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 145); - omap_ads7846_init(1, 57, 0, NULL); } static void __init am3517_evm_legacy_init(void) diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 503097c72b8..d697cecf762 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -37,6 +37,16 @@ struct power_state { struct list_head node; }; +/** + * struct static_dep_map - Static dependency map + * @from: from clockdomain + * @to: to clockdomain + */ +struct static_dep_map { + const char *from; + const char *to; +}; + static u32 cpu_suspend_state = PWRDM_POWER_OFF; static LIST_HEAD(pwrst_list); @@ -148,94 +158,61 @@ static void omap_default_idle(void) omap_do_wfi(); } -/** - * omap4_init_static_deps - Add OMAP4 static dependencies - * - * Add needed static clockdomain dependencies on OMAP4 devices. - * Return: 0 on success or 'err' on failures +/* + * The dynamic dependency between MPUSS -> MEMIF and + * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as + * expected. The hardware recommendation is to enable static + * dependencies for these to avoid system lock ups or random crashes. + * The L4 wakeup depedency is added to workaround the OCP sync hardware + * BUG with 32K synctimer which lead to incorrect timer value read + * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which + * are part of L4 wakeup clockdomain. */ -static inline int omap4_init_static_deps(void) -{ - struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; - struct clockdomain *ducati_clkdm, *l3_2_clkdm; - int ret = 0; - - if (omap_rev() == OMAP4430_REV_ES1_0) { - WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); - return -ENODEV; - } - - pr_err("Power Management for TI OMAP4.\n"); - /* - * OMAP4 chip PM currently works only with certain (newer) - * versions of bootloaders. This is due to missing code in the - * kernel to properly reset and initialize some devices. - * http://www.spinics.net/lists/arm-kernel/msg218641.html - */ - pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n"); - - ret = pwrdm_for_each(pwrdms_setup, NULL); - if (ret) { - pr_err("Failed to setup powerdomains\n"); - return ret; - } - - /* - * The dynamic dependency between MPUSS -> MEMIF and - * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as - * expected. The hardware recommendation is to enable static - * dependencies for these to avoid system lock ups or random crashes. - * The L4 wakeup depedency is added to workaround the OCP sync hardware - * BUG with 32K synctimer which lead to incorrect timer value read - * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which - * are part of L4 wakeup clockdomain. - */ - mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); - emif_clkdm = clkdm_lookup("l3_emif_clkdm"); - l3_1_clkdm = clkdm_lookup("l3_1_clkdm"); - l3_2_clkdm = clkdm_lookup("l3_2_clkdm"); - ducati_clkdm = clkdm_lookup("ducati_clkdm"); - if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || - (!l3_2_clkdm) || (!ducati_clkdm)) - return -EINVAL; - - ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); - ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); - ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm); - ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm); - ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); - if (ret) { - pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n"); - return -EINVAL; - } +static const struct static_dep_map omap4_static_dep_map[] = { + {.from = "mpuss_clkdm", .to = "l3_emif_clkdm"}, + {.from = "mpuss_clkdm", .to = "l3_1_clkdm"}, + {.from = "mpuss_clkdm", .to = "l3_2_clkdm"}, + {.from = "ducati_clkdm", .to = "l3_1_clkdm"}, + {.from = "ducati_clkdm", .to = "l3_2_clkdm"}, + {.from = NULL} /* TERMINATION */ +}; - return ret; -} +static const struct static_dep_map omap5_dra7_static_dep_map[] = { + {.from = "mpu_clkdm", .to = "emif_clkdm"}, + {.from = NULL} /* TERMINATION */ +}; /** - * omap5_dra7_init_static_deps - Init static clkdm dependencies on OMAP5 and - * DRA7 - * - * The dynamic dependency between MPUSS -> EMIF is broken and has - * not worked as expected. The hardware recommendation is to - * enable static dependencies for these to avoid system - * lock ups or random crashes. + * omap4plus_init_static_deps() - Initialize a static dependency map + * @map: Mapping of clock domains */ -static inline int omap5_dra7_init_static_deps(void) +static inline int omap4plus_init_static_deps(const struct static_dep_map *map) { - struct clockdomain *mpuss_clkdm, *emif_clkdm; int ret; + struct clockdomain *from, *to; + + if (!map) + return 0; - mpuss_clkdm = clkdm_lookup("mpu_clkdm"); - emif_clkdm = clkdm_lookup("emif_clkdm"); - if (!mpuss_clkdm || !emif_clkdm) - return -EINVAL; + while (map->from) { + from = clkdm_lookup(map->from); + to = clkdm_lookup(map->to); + if (!from || !to) { + pr_err("Failed lookup %s or %s for wakeup dependency\n", + map->from, map->to); + return -EINVAL; + } + ret = clkdm_add_wkdep(from, to); + if (ret) { + pr_err("Failed to add %s -> %s wakeup dependency(%d)\n", + map->from, map->to, ret); + return ret; + } - ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); - if (ret) - pr_err("Failed to add MPUSS -> EMIF wakeup dependency\n"); + map++; + }; - return ret; + return 0; } /** @@ -272,6 +249,15 @@ int __init omap4_pm_init(void) pr_info("Power Management for TI OMAP4+ devices.\n"); + /* + * OMAP4 chip PM currently works only with certain (newer) + * versions of bootloaders. This is due to missing code in the + * kernel to properly reset and initialize some devices. + * http://www.spinics.net/lists/arm-kernel/msg218641.html + */ + if (cpu_is_omap44xx()) + pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n"); + ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { pr_err("Failed to setup powerdomains.\n"); @@ -279,9 +265,9 @@ int __init omap4_pm_init(void) } if (cpu_is_omap44xx()) - ret = omap4_init_static_deps(); + ret = omap4plus_init_static_deps(omap4_static_dep_map); else if (soc_is_omap54xx() || soc_is_dra7xx()) - ret = omap5_dra7_init_static_deps(); + ret = omap4plus_init_static_deps(omap5_dra7_static_dep_map); if (ret) { pr_err("Failed to initialise static dependencies.\n"); diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 48480d557b6..77752e49d8d 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -29,6 +29,7 @@ int of_prcm_init(void); * PRM_HAS_VOLTAGE: has voltage domains */ #define PRM_HAS_IO_WAKEUP (1 << 0) +#define PRM_HAS_VOLTAGE (1 << 1) /* * MAX_MODULE_SOFTRESET_WAIT: Maximum microseconds to wait for OMAP @@ -127,6 +128,8 @@ struct prm_reset_src_map { * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn * @late_init: ptr to the late init function + * @assert_hardreset: ptr to the SoC PRM hardreset assert impl + * @deassert_hardreset: ptr to the SoC PRM hardreset deassert impl * * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are * deprecated. @@ -136,14 +139,27 @@ struct prm_ll_data { bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx); void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx); int (*late_init)(void); + int (*assert_hardreset)(u8 shift, u8 part, s16 prm_mod, u16 offset); + int (*deassert_hardreset)(u8 shift, u8 st_shift, u8 part, s16 prm_mod, + u16 offset, u16 st_offset); + int (*is_hardreset_asserted)(u8 shift, u8 part, s16 prm_mod, + u16 offset); + void (*reset_system)(void); }; extern int prm_register(struct prm_ll_data *pld); extern int prm_unregister(struct prm_ll_data *pld); +int omap_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset); +int omap_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 prm_mod, + u16 offset, u16 st_offset); +int omap_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset); extern u32 prm_read_reset_sources(void); extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx); extern void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx); +void omap_prm_reset_system(void); + +void omap_prm_reconfigure_io_chain(void); #endif diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c index 86958050547..af0f15278fc 100644 --- a/arch/arm/mach-omap2/prm2xxx.c +++ b/arch/arm/mach-omap2/prm2xxx.c @@ -106,7 +106,7 @@ static int omap2xxx_pwrst_to_common_pwrst(u8 omap2xxx_pwrst) * Set the DPLL reset bit, which should reboot the SoC. This is the * recommended way to restart the SoC. No return value. */ -void omap2xxx_prm_dpll_reset(void) +static void omap2xxx_prm_dpll_reset(void) { omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, WKUP_MOD, OMAP2_RM_RSTCTRL); @@ -212,6 +212,10 @@ struct pwrdm_ops omap2_pwrdm_operations = { static struct prm_ll_data omap2xxx_prm_ll_data = { .read_reset_sources = &omap2xxx_prm_read_reset_sources, + .assert_hardreset = &omap2_prm_assert_hardreset, + .deassert_hardreset = &omap2_prm_deassert_hardreset, + .is_hardreset_asserted = &omap2_prm_is_hardreset_asserted, + .reset_system = &omap2xxx_prm_dpll_reset, }; int __init omap2xxx_prm_init(void) diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h index d7341413929..1d51643062f 100644 --- a/arch/arm/mach-omap2/prm2xxx.h +++ b/arch/arm/mach-omap2/prm2xxx.h @@ -124,7 +124,6 @@ extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm); extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm); -extern void omap2xxx_prm_dpll_reset(void); void omap2xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask); extern int __init omap2xxx_prm_init(void); diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index c13b4e293ff..cc3341f263c 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -24,14 +24,16 @@ /** * omap2_prm_is_hardreset_asserted - read the HW reset line state of * submodules contained in the hwmod module - * @prm_mod: PRM submodule base (e.g. CORE_MOD) * @shift: register bit shift corresponding to the reset line to check + * @part: PRM partition, ignored for OMAP2 + * @prm_mod: PRM submodule base (e.g. CORE_MOD) + * @offset: register offset, ignored for OMAP2 * * Returns 1 if the (sub)module hardreset line is currently asserted, * 0 if the (sub)module hardreset line is not currently asserted, or * -EINVAL if called while running on a non-OMAP2/3 chip. */ -int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) +int omap2_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset) { return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, (1 << shift)); @@ -39,8 +41,10 @@ int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) /** * omap2_prm_assert_hardreset - assert the HW reset line of a submodule - * @prm_mod: PRM submodule base (e.g. CORE_MOD) * @shift: register bit shift corresponding to the reset line to assert + * @part: PRM partition, ignored for OMAP2 + * @prm_mod: PRM submodule base (e.g. CORE_MOD) + * @offset: register offset, ignored for OMAP2 * * Some IPs like dsp or iva contain processors that require an HW * reset line to be asserted / deasserted in order to fully enable the @@ -49,7 +53,7 @@ int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) * place the submodule into reset. Returns 0 upon success or -EINVAL * upon an argument error. */ -int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) +int omap2_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset) { u32 mask; @@ -64,6 +68,10 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) * @prm_mod: PRM submodule base (e.g. CORE_MOD) * @rst_shift: register bit shift corresponding to the reset line to deassert * @st_shift: register bit shift for the status of the deasserted submodule + * @part: PRM partition, not used for OMAP2 + * @prm_mod: PRM submodule base (e.g. CORE_MOD) + * @rst_offset: reset register offset, not used for OMAP2 + * @st_offset: reset status register offset, not used for OMAP2 * * Some IPs like dsp or iva contain processors that require an HW * reset line to be asserted / deasserted in order to fully enable the @@ -74,7 +82,8 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) * -EINVAL upon an argument error, -EEXIST if the submodule was already out * of reset, or -EBUSY if the submodule did not exit reset promptly. */ -int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift) +int omap2_prm_deassert_hardreset(u8 rst_shift, u8 st_shift, u8 part, + s16 prm_mod, u16 rst_offset, u16 st_offset) { u32 rst, st; int c; diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h index 1a3a96392b9..f57e29b0e04 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h @@ -100,9 +100,12 @@ static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) } /* These omap2_ PRM functions apply to both OMAP2 and 3 */ -extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift); -extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift); -extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift); +int omap2_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset); +int omap2_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, + u16 offset); +int omap2_prm_deassert_hardreset(u8 rst_shift, u8 st_shift, u8 part, + s16 prm_mod, u16 reset_offset, + u16 st_offset); extern int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst); extern int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm); diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c index 62709cd2f9c..02f628601b0 100644 --- a/arch/arm/mach-omap2/prm33xx.c +++ b/arch/arm/mach-omap2/prm33xx.c @@ -23,20 +23,24 @@ #include "prm33xx.h" #include "prm-regbits-33xx.h" +#define AM33XX_PRM_RSTCTRL_OFFSET 0x0000 + +#define AM33XX_RST_GLOBAL_WARM_SW_MASK (1 << 0) + /* Read a register in a PRM instance */ -u32 am33xx_prm_read_reg(s16 inst, u16 idx) +static u32 am33xx_prm_read_reg(s16 inst, u16 idx) { return readl_relaxed(prm_base + inst + idx); } /* Write into a register in a PRM instance */ -void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) +static void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) { writel_relaxed(val, prm_base + inst + idx); } /* Read-modify-write a register in PRM. Caller must lock */ -u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) +static u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) { u32 v; @@ -52,6 +56,7 @@ u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) * am33xx_prm_is_hardreset_asserted - read the HW reset line state of * submodules contained in the hwmod module * @shift: register bit shift corresponding to the reset line to check + * @part: PRM partition, ignored for AM33xx * @inst: CM instance register offset (*_INST macro) * @rstctrl_offs: RM_RSTCTRL register address offset for this module * @@ -59,7 +64,8 @@ u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) * 0 if the (sub)module hardreset line is not currently asserted, or * -EINVAL upon parameter error. */ -int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs) +static int am33xx_prm_is_hardreset_asserted(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs) { u32 v; @@ -73,6 +79,7 @@ int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs) /** * am33xx_prm_assert_hardreset - assert the HW reset line of a submodule * @shift: register bit shift corresponding to the reset line to assert + * @part: CM partition, ignored for AM33xx * @inst: CM instance register offset (*_INST macro) * @rstctrl_reg: RM_RSTCTRL register address for this module * @@ -83,7 +90,8 @@ int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs) * place the submodule into reset. Returns 0 upon success or -EINVAL * upon an argument error. */ -int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs) +static int am33xx_prm_assert_hardreset(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs) { u32 mask = 1 << shift; @@ -96,6 +104,8 @@ int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs) * am33xx_prm_deassert_hardreset - deassert a submodule hardreset line and * wait * @shift: register bit shift corresponding to the reset line to deassert + * @st_shift: reset status register bit shift corresponding to the reset line + * @part: PRM partition, not used for AM33xx * @inst: CM instance register offset (*_INST macro) * @rstctrl_reg: RM_RSTCTRL register address for this module * @rstst_reg: RM_RSTST register address for this module @@ -109,14 +119,15 @@ int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs) * -EINVAL upon an argument error, -EEXIST if the submodule was already out * of reset, or -EBUSY if the submodule did not exit reset promptly. */ -int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst, - u16 rstctrl_offs, u16 rstst_offs) +static int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, + s16 inst, u16 rstctrl_offs, + u16 rstst_offs) { int c; u32 mask = 1 << st_shift; /* Check the current status to avoid de-asserting the line twice */ - if (am33xx_prm_is_hardreset_asserted(shift, inst, rstctrl_offs) == 0) + if (am33xx_prm_is_hardreset_asserted(shift, 0, inst, rstctrl_offs) == 0) return -EEXIST; /* Clear the reset status by writing 1 to the status bit */ @@ -128,7 +139,7 @@ int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst, am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs); /* wait the status to be set */ - omap_test_timeout(am33xx_prm_is_hardreset_asserted(st_shift, inst, + omap_test_timeout(am33xx_prm_is_hardreset_asserted(st_shift, 0, inst, rstst_offs), MAX_MODULE_HARDRESET_WAIT, c); @@ -325,6 +336,23 @@ static int am33xx_check_vcvp(void) return 0; } +/** + * am33xx_prm_global_warm_sw_reset - reboot the device via warm reset + * + * Immediately reboots the device through warm reset. + */ +static void am33xx_prm_global_warm_sw_reset(void) +{ + am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK, + AM33XX_RST_GLOBAL_WARM_SW_MASK, + AM33XX_PRM_DEVICE_MOD, + AM33XX_PRM_RSTCTRL_OFFSET); + + /* OCP barrier */ + (void)am33xx_prm_read_reg(AM33XX_PRM_DEVICE_MOD, + AM33XX_PRM_RSTCTRL_OFFSET); +} + struct pwrdm_ops am33xx_pwrdm_operations = { .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst, .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst, @@ -342,3 +370,21 @@ struct pwrdm_ops am33xx_pwrdm_operations = { .pwrdm_wait_transition = am33xx_pwrdm_wait_transition, .pwrdm_has_voltdm = am33xx_check_vcvp, }; + +static struct prm_ll_data am33xx_prm_ll_data = { + .assert_hardreset = am33xx_prm_assert_hardreset, + .deassert_hardreset = am33xx_prm_deassert_hardreset, + .is_hardreset_asserted = am33xx_prm_is_hardreset_asserted, + .reset_system = am33xx_prm_global_warm_sw_reset, +}; + +int __init am33xx_prm_init(void) +{ + return prm_register(&am33xx_prm_ll_data); +} + +static void __exit am33xx_prm_exit(void) +{ + prm_unregister(&am33xx_prm_ll_data); +} +__exitcall(am33xx_prm_exit); diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h index 9b9918dfb11..98ac41f271d 100644 --- a/arch/arm/mach-omap2/prm33xx.h +++ b/arch/arm/mach-omap2/prm33xx.h @@ -118,14 +118,7 @@ #define AM33XX_PM_CEFUSE_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004) #ifndef __ASSEMBLER__ -extern u32 am33xx_prm_read_reg(s16 inst, u16 idx); -extern void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx); -extern u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); -extern void am33xx_prm_global_warm_sw_reset(void); -extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, - u16 rstctrl_offs); -extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs); -extern int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst, - u16 rstctrl_offs, u16 rstst_offs); +int am33xx_prm_init(void); + #endif /* ASSEMBLER */ #endif diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index ff08da385a2..c5e00c6714b 100644 --- a/arch/arm/mach-omap2/prm3xxx.c +++ b/arch/arm/mach-omap2/prm3xxx.c @@ -30,6 +30,11 @@ #include "cm3xxx.h" #include "cm-regbits-34xx.h" +static void omap3xxx_prm_read_pending_irqs(unsigned long *events); +static void omap3xxx_prm_ocp_barrier(void); +static void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask); +static void omap3xxx_prm_restore_irqen(u32 *saved_mask); + static const struct omap_prcm_irq omap3_prcm_irqs[] = { OMAP_PRCM_IRQ("wkup", 0, 0), OMAP_PRCM_IRQ("io", 9, 1), @@ -131,7 +136,7 @@ u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) * recommended way to restart the SoC, considering Errata i520. No * return value. */ -void omap3xxx_prm_dpll3_reset(void) +static void omap3xxx_prm_dpll3_reset(void) { omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, OMAP3430_GR_MOD, OMAP2_RM_RSTCTRL); @@ -147,7 +152,7 @@ void omap3xxx_prm_dpll3_reset(void) * MPU IRQs, and store the result into the u32 pointed to by @events. * No return value. */ -void omap3xxx_prm_read_pending_irqs(unsigned long *events) +static void omap3xxx_prm_read_pending_irqs(unsigned long *events) { u32 mask, st; @@ -166,7 +171,7 @@ void omap3xxx_prm_read_pending_irqs(unsigned long *events) * block, to avoid race conditions after acknowledging or clearing IRQ * bits. No return value. */ -void omap3xxx_prm_ocp_barrier(void) +static void omap3xxx_prm_ocp_barrier(void) { omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET); } @@ -182,7 +187,7 @@ void omap3xxx_prm_ocp_barrier(void) * returning; otherwise, spurious interrupts might occur. No return * value. */ -void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask) +static void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask) { saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); @@ -202,7 +207,7 @@ void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask) * barrier should be needed here; any pending PRM interrupts will fire * once the writes reach the PRM. No return value. */ -void omap3xxx_prm_restore_irqen(u32 *saved_mask) +static void omap3xxx_prm_restore_irqen(u32 *saved_mask) { omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); @@ -375,7 +380,7 @@ void __init omap3_prm_init_pm(bool has_uart4, bool has_iva) * The ST_IO_CHAIN bit does not exist in 3430 before es3.1. The only * thing we can do is toggle EN_IO bit for earlier omaps. */ -void omap3430_pre_es3_1_reconfigure_io_chain(void) +static void omap3430_pre_es3_1_reconfigure_io_chain(void) { omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); @@ -393,7 +398,7 @@ void omap3430_pre_es3_1_reconfigure_io_chain(void) * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No * return value. These registers are only available in 3430 es3.1 and later. */ -void omap3_prm_reconfigure_io_chain(void) +static void omap3_prm_reconfigure_io_chain(void) { int i = 0; @@ -416,15 +421,6 @@ void omap3_prm_reconfigure_io_chain(void) } /** - * omap3xxx_prm_reconfigure_io_chain - reconfigure I/O chain - */ -void omap3xxx_prm_reconfigure_io_chain(void) -{ - if (omap3_prcm_irq_setup.reconfigure_io_chain) - omap3_prcm_irq_setup.reconfigure_io_chain(); -} - -/** * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches * * Activates the I/O wakeup event latches and allows events logged by @@ -664,6 +660,10 @@ static int omap3xxx_prm_late_init(void); static struct prm_ll_data omap3xxx_prm_ll_data = { .read_reset_sources = &omap3xxx_prm_read_reset_sources, .late_init = &omap3xxx_prm_late_init, + .assert_hardreset = &omap2_prm_assert_hardreset, + .deassert_hardreset = &omap2_prm_deassert_hardreset, + .is_hardreset_asserted = &omap2_prm_is_hardreset_asserted, + .reset_system = &omap3xxx_prm_dpll3_reset, }; int __init omap3xxx_prm_init(void) diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h index bc37d42a870..cfde3f4a03c 100644 --- a/arch/arm/mach-omap2/prm3xxx.h +++ b/arch/arm/mach-omap2/prm3xxx.h @@ -144,22 +144,6 @@ extern u32 omap3_prm_vcvp_read(u8 offset); extern void omap3_prm_vcvp_write(u32 val, u8 offset); extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); -#ifdef CONFIG_ARCH_OMAP3 -void omap3xxx_prm_reconfigure_io_chain(void); -#else -static inline void omap3xxx_prm_reconfigure_io_chain(void) -{ -} -#endif - -/* PRM interrupt-related functions */ -extern void omap3xxx_prm_read_pending_irqs(unsigned long *events); -extern void omap3xxx_prm_ocp_barrier(void); -extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask); -extern void omap3xxx_prm_restore_irqen(u32 *saved_mask); - -extern void omap3xxx_prm_dpll3_reset(void); - extern int __init omap3xxx_prm_init(void); extern u32 omap3xxx_prm_get_reset_sources(void); int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits); diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 0958d070d3d..cc170fb81ff 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -32,6 +32,12 @@ /* Static data */ +static void omap44xx_prm_read_pending_irqs(unsigned long *events); +static void omap44xx_prm_ocp_barrier(void); +static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); +static void omap44xx_prm_restore_irqen(u32 *saved_mask); +static void omap44xx_prm_reconfigure_io_chain(void); + static const struct omap_prcm_irq omap4_prcm_irqs[] = { OMAP_PRCM_IRQ("io", 9, 1), }; @@ -80,19 +86,19 @@ static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = { /* PRM low-level functions */ /* Read a register in a CM/PRM instance in the PRM module */ -u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) +static u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) { return readl_relaxed(prm_base + inst + reg); } /* Write into a register in a CM/PRM instance in the PRM module */ -void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) +static void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) { writel_relaxed(val, prm_base + inst + reg); } /* Read-modify-write a register in a PRM module. Caller must lock */ -u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) +static u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) { u32 v; @@ -207,7 +213,7 @@ static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs) * MPU IRQs, and store the result into the two u32s pointed to by @events. * No return value. */ -void omap44xx_prm_read_pending_irqs(unsigned long *events) +static void omap44xx_prm_read_pending_irqs(unsigned long *events) { events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET, OMAP4_PRM_IRQSTATUS_MPU_OFFSET); @@ -224,7 +230,7 @@ void omap44xx_prm_read_pending_irqs(unsigned long *events) * block, to avoid race conditions after acknowledging or clearing IRQ * bits. No return value. */ -void omap44xx_prm_ocp_barrier(void) +static void omap44xx_prm_ocp_barrier(void) { omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_REVISION_PRM_OFFSET); @@ -241,7 +247,7 @@ void omap44xx_prm_ocp_barrier(void) * interrupts reaches the PRM before returning; otherwise, spurious * interrupts might occur. No return value. */ -void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) +static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) { saved_mask[0] = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, @@ -270,7 +276,7 @@ void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) * No OCP barrier should be needed here; any pending PRM interrupts will fire * once the writes reach the PRM. No return value. */ -void omap44xx_prm_restore_irqen(u32 *saved_mask) +static void omap44xx_prm_restore_irqen(u32 *saved_mask) { omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_PRM_IRQENABLE_MPU_OFFSET); @@ -287,7 +293,7 @@ void omap44xx_prm_restore_irqen(u32 *saved_mask) * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted. * No return value. XXX Are the final two steps necessary? */ -void omap44xx_prm_reconfigure_io_chain(void) +static void omap44xx_prm_reconfigure_io_chain(void) { int i = 0; s32 inst = omap4_prmst_get_prm_dev_inst(); @@ -652,11 +658,10 @@ static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) static int omap4_check_vcvp(void) { - /* No VC/VP on dra7xx devices */ - if (soc_is_dra7xx()) - return 0; + if (prm_features & PRM_HAS_VOLTAGE) + return 1; - return 1; + return 0; } struct pwrdm_ops omap4_pwrdm_operations = { @@ -689,6 +694,10 @@ static struct prm_ll_data omap44xx_prm_ll_data = { .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old, .late_init = &omap44xx_prm_late_init, + .assert_hardreset = omap4_prminst_assert_hardreset, + .deassert_hardreset = omap4_prminst_deassert_hardreset, + .is_hardreset_asserted = omap4_prminst_is_hardreset_asserted, + .reset_system = omap4_prminst_global_warm_sw_reset, }; int __init omap44xx_prm_init(void) @@ -696,6 +705,9 @@ int __init omap44xx_prm_init(void) if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) prm_features |= PRM_HAS_IO_WAKEUP; + if (!soc_is_dra7xx()) + prm_features |= PRM_HAS_VOLTAGE; + return prm_register(&omap44xx_prm_ll_data); } diff --git a/arch/arm/mach-omap2/prm44xx_54xx.h b/arch/arm/mach-omap2/prm44xx_54xx.h index 8d95aa543ef..f7512515fde 100644 --- a/arch/arm/mach-omap2/prm44xx_54xx.h +++ b/arch/arm/mach-omap2/prm44xx_54xx.h @@ -26,10 +26,6 @@ /* Function prototypes */ #ifndef __ASSEMBLER__ -extern u32 omap4_prm_read_inst_reg(s16 inst, u16 idx); -extern void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 idx); -extern u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); - /* OMAP4/OMAP5-specific VP functions */ u32 omap4_prm_vp_check_txdone(u8 vp_id); void omap4_prm_vp_clear_txdone(u8 vp_id); @@ -42,21 +38,6 @@ extern u32 omap4_prm_vcvp_read(u8 offset); extern void omap4_prm_vcvp_write(u32 val, u8 offset); extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); -#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ - defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX) -void omap44xx_prm_reconfigure_io_chain(void); -#else -static inline void omap44xx_prm_reconfigure_io_chain(void) -{ -} -#endif - -/* PRM interrupt-related functions */ -extern void omap44xx_prm_read_pending_irqs(unsigned long *events); -extern void omap44xx_prm_ocp_barrier(void); -extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); -extern void omap44xx_prm_restore_irqen(u32 *saved_mask); - extern int __init omap44xx_prm_init(void); extern u32 omap44xx_prm_get_reset_sources(void); diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index ee2b5222eac..779940cb6e5 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -423,6 +423,105 @@ void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx) } /** + * omap_prm_assert_hardreset - assert hardreset for an IP block + * @shift: register bit shift corresponding to the reset line + * @part: PRM partition + * @prm_mod: PRM submodule base or instance offset + * @offset: register offset + * + * Asserts a hardware reset line for an IP block. + */ +int omap_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset) +{ + if (!prm_ll_data->assert_hardreset) { + WARN_ONCE(1, "prm: %s: no mapping function defined\n", + __func__); + return -EINVAL; + } + + return prm_ll_data->assert_hardreset(shift, part, prm_mod, offset); +} + +/** + * omap_prm_deassert_hardreset - deassert hardreset for an IP block + * @shift: register bit shift corresponding to the reset line + * @st_shift: reset status bit shift corresponding to the reset line + * @part: PRM partition + * @prm_mod: PRM submodule base or instance offset + * @offset: register offset + * @st_offset: status register offset + * + * Deasserts a hardware reset line for an IP block. + */ +int omap_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 prm_mod, + u16 offset, u16 st_offset) +{ + if (!prm_ll_data->deassert_hardreset) { + WARN_ONCE(1, "prm: %s: no mapping function defined\n", + __func__); + return -EINVAL; + } + + return prm_ll_data->deassert_hardreset(shift, st_shift, part, prm_mod, + offset, st_offset); +} + +/** + * omap_prm_is_hardreset_asserted - check the hardreset status for an IP block + * @shift: register bit shift corresponding to the reset line + * @part: PRM partition + * @prm_mod: PRM submodule base or instance offset + * @offset: register offset + * + * Checks if a hardware reset line for an IP block is enabled or not. + */ +int omap_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset) +{ + if (!prm_ll_data->is_hardreset_asserted) { + WARN_ONCE(1, "prm: %s: no mapping function defined\n", + __func__); + return -EINVAL; + } + + return prm_ll_data->is_hardreset_asserted(shift, part, prm_mod, offset); +} + +/** + * omap_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain + * + * Clear any previously-latched I/O wakeup events and ensure that the + * I/O wakeup gates are aligned with the current mux settings. + * Calls SoC specific I/O chain reconfigure function if available, + * otherwise does nothing. + */ +void omap_prm_reconfigure_io_chain(void) +{ + if (!prcm_irq_setup || !prcm_irq_setup->reconfigure_io_chain) + return; + + prcm_irq_setup->reconfigure_io_chain(); +} + +/** + * omap_prm_reset_system - trigger global SW reset + * + * Triggers SoC specific global warm reset to reboot the device. + */ +void omap_prm_reset_system(void) +{ + if (!prm_ll_data->reset_system) { + WARN_ONCE(1, "prm: %s: no mapping function defined\n", + __func__); + return; + } + + prm_ll_data->reset_system(); + + while (1) + cpu_relax(); +} + +/** * prm_register - register per-SoC low-level data with the PRM * @pld: low-level per-SoC OMAP PRM data & function pointers to register * diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c index 225e0258d76..8adf7b1a1dc 100644 --- a/arch/arm/mach-omap2/prminst44xx.c +++ b/arch/arm/mach-omap2/prminst44xx.c @@ -148,8 +148,12 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, /** * omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and * wait - * @rstctrl_reg: RM_RSTCTRL register address for this module * @shift: register bit shift corresponding to the reset line to deassert + * @st_shift: status bit offset, not used for OMAP4+ + * @part: PRM partition + * @inst: PRM instance offset + * @rstctrl_offs: reset register offset + * @st_offs: reset status register offset, not used for OMAP4+ * * Some IPs like dsp, ipu or iva contain processors that require an HW * reset line to be asserted / deasserted in order to fully enable the @@ -160,8 +164,8 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, * -EINVAL upon an argument error, -EEXIST if the submodule was already out * of reset, or -EBUSY if the submodule did not exit reset promptly. */ -int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst, - u16 rstctrl_offs) +int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst, + u16 rstctrl_offs, u16 st_offs) { int c; u32 mask = 1 << shift; diff --git a/arch/arm/mach-omap2/prminst44xx.h b/arch/arm/mach-omap2/prminst44xx.h index 583aa377457..fb1c9d7a2f9 100644 --- a/arch/arm/mach-omap2/prminst44xx.h +++ b/arch/arm/mach-omap2/prminst44xx.h @@ -30,8 +30,9 @@ extern int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst, u16 rstctrl_offs); extern int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, u16 rstctrl_offs); -extern int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst, - u16 rstctrl_offs); +int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, + s16 inst, u16 rstctrl_offs, + u16 rstst_offs); extern void omap_prm_base_init(void); diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index a388f8c1bcb..57dee0c7cd2 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -263,9 +263,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, omap_up.dma_rx_timeout = info->dma_rx_timeout; omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate; omap_up.autosuspend_timeout = info->autosuspend_timeout; - omap_up.DTR_gpio = info->DTR_gpio; - omap_up.DTR_inverted = info->DTR_inverted; - omap_up.DTR_present = info->DTR_present; pdata = &omap_up; pdata_size = sizeof(struct omap_uart_port_info); |