OMAP4: Smartreflex and Voltage layer support
Subsystems (5)
v4 cover OMAP4: Smartreflex and Voltage layer support
This patch series adds support for OMAP4 support in the smartreflex and voltage layer. The series involves extensions to voltage layer and smartreflex layer for supporting OMAP4.
This series in based against kernel.org 2.6.37-rc3 and is dependent on the "OMAP3: Adding Smartreflex and Voltage driver support" series.
All these patches are also available at
http://dev.omapzoom.org/?p=thara/omap-dvfs.git;a=summary
head: pm-sr
This patch series has been tested on OMAP4430 SDP with omap2plus_defconfig with the following menuconfig options enabled
System type -> TI OMAP Implementations -> Smartreflex Support
System type -> TI OMAP Implementations ->
Class 3 mode of Smartreflex ImplementationBenoit Cousson (1):
OMAP4: hwmod: Add inital data for smartreflex modules.
Thara Gopinath (4):
OMAP4: Register voltage PMIC parameters with the voltage layer
OMAP4: Adding voltage driver support
OMAP4: PM: Program correct init voltages for scalable VDDs
OMAP4: Smartreflex framework extensions
arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/control.h | 12 ++ arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 167 +++++++++++++++++++ arch/arm/mach-omap2/omap_twl.c | 166 ++++++++++++++++++ arch/arm/mach-omap2/pm.c | 12 ++ arch/arm/mach-omap2/pm.h | 5 + arch/arm/mach-omap2/smartreflex.c | 8 +- arch/arm/mach-omap2/sr_device.c | 17 ++- arch/arm/mach-omap2/voltage.c | 249 ++++++++++++++++++++++++++++ arch/arm/plat-omap/Kconfig | 2 +- arch/arm/plat-omap/include/plat/voltage.h | 12 ++ 11 files changed, 647 insertions(+), 5 deletions(-)
PATCH v4 1/5 OMAP4: Register voltage PMIC parameters with the voltage layer
TWL6030 is the power IC used along with OMAP4 in OMAP4 SDPs, blaze boards and panda boards. This patch registers the OMAP4 PMIC specific information with the voltage layer. This also involves implementing a different formula for voltage to vsel and vsel to voltage calculations from TWL4030.
--- arch/arm/mach-omap2/omap_twl.c | 166 ++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/pm.c | 1 + arch/arm/mach-omap2/pm.h | 5 + 3 files changed, 172 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_twl.c +166 -0
@@ -16,6 +16,7 @@#include <linux/err.h> #include <linux/io.h> #include <linux/kernel.h> +#include <linux/i2c/twl.h> #include <plat/voltage.h>
@@ -37,6 +38,28 @@#define OMAP3630_VP2_VLIMITTO_VDDMIN 0x18#define OMAP3630_VP2_VLIMITTO_VDDMAX 0x30 +#define OMAP4_SRI2C_SLAVE_ADDR 0x12 +#define OMAP4_VDD_MPU_SR_VOLT_REG 0x55 +#define OMAP4_VDD_IVA_SR_VOLT_REG 0x5B +#define OMAP4_VDD_CORE_SR_VOLT_REG 0x61 + +#define OMAP4_VP_CONFIG_ERROROFFSET 0x00 +#define OMAP4_VP_VSTEPMIN_VSTEPMIN 0x01 +#define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04 +#define OMAP4_VP_VLIMITTO_TIMEOUT_US 200 + +#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 0xA +#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 0x39 +#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 0xA +#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 0x2D +#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 0xA +#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 0x28 + +static bool is_offset_valid; +static u8 smps_offset; + +#define REG_SMPS_OFFSET 0xE0 +unsigned long twl4030_vsel_to_uv (const u8 vsel) {return (((vsel *125 ) +6000 )) *100 ;
@@ -47,6 +70,70 @@ u8 twl4030_uv_to_vsel(unsigned long uv)return DIV_ROUND_UP (uv -600000 ,12500 ); } +unsigned long twl6030_vsel_to_uv (const u8 vsel) +{ +/* +* In TWL6030 depending on the value of SMPS_OFFSET +* efuse register the voltage range supported in +* standard mode can be either between 0.6V - 1.3V or +* 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse +* is programmed to all 0's where as starting from +* TWL6030 ES1.1 the efuse is programmed to 1 +*/ +if (!is_offset_valid) { +twl_i2c_read_u8 (TWL6030_MODULE_ID0 , &smps_offset, +REG_SMPS_OFFSET ); + is_offset_valid = true; + } + +/* +* There is no specific formula for voltage to vsel +* conversion above 1.3V. There are special hardcoded +* values for voltages above 1.3V. Currently we are +* hardcoding only for 1.35 V which is used for 1GH OPP for +* OMAP4430. +*/ +if (vsel ==0x3A ) +return 1350000 ; + +if (smps_offset &0x8 ) +return ((((vsel -1 ) *125 ) +7000 )) *100 ; +else +return ((((vsel -1 ) *125 ) +6000 )) *100 ; +} + +u8 twl6030_uv_to_vsel (unsigned long uv) +{ +/* +* In TWL6030 depending on the value of SMPS_OFFSET +* efuse register the voltage range supported in +* standard mode can be either between 0.6V - 1.3V or +* 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse +* is programmed to all 0's where as starting from +* TWL6030 ES1.1 the efuse is programmed to 1 +*/ +if (!is_offset_valid) { +twl_i2c_read_u8 (TWL6030_MODULE_ID0 , &smps_offset, +REG_SMPS_OFFSET ); + is_offset_valid = true; + } + +/* +* There is no specific formula for voltage to vsel +* conversion above 1.3V. There are special hardcoded +* values for voltages above 1.3V. Currently we are +* hardcoding only for 1.35 V which is used for 1GH OPP for +* OMAP4430. +*/ +if (uv ==1350000 ) +return 0x3A ; + +if (smps_offset &0x8 ) +return DIV_ROUND_UP (uv -700000 ,12500 ) +1 ; +else +return DIV_ROUND_UP (uv -600000 ,12500 ) +1 ; +} +static struct omap_volt_pmic_info omap3_mpu_volt_info = { .slew_rate =4000 , .step_size =12500 ,
@@ -87,6 +174,85 @@ static struct omap_volt_pmic_info omap3_core_volt_info = { .uv_to_vsel = twl4030_uv_to_vsel, }; +static struct omap_volt_pmic_info omap4_mpu_volt_info = { + .slew_rate =4000 , + .step_size =12500 , + .on_volt =1350000 , + .onlp_volt =1350000 , + .ret_volt =837500 , + .off_volt =600000 , + .volt_setup_time =0 , + .vp_erroroffset =OMAP4_VP_CONFIG_ERROROFFSET , + .vp_vstepmin =OMAP4_VP_VSTEPMIN_VSTEPMIN , + .vp_vstepmax =OMAP4_VP_VSTEPMAX_VSTEPMAX , + .vp_vddmin =OMAP4_VP_MPU_VLIMITTO_VDDMIN , + .vp_vddmax =OMAP4_VP_MPU_VLIMITTO_VDDMAX , + .vp_timeout_us =OMAP4_VP_VLIMITTO_TIMEOUT_US , + .i2c_slave_addr =OMAP4_SRI2C_SLAVE_ADDR , + .pmic_reg =OMAP4_VDD_MPU_SR_VOLT_REG , + .vsel_to_uv = twl6030_vsel_to_uv, + .uv_to_vsel = twl6030_uv_to_vsel, +}; + +static struct omap_volt_pmic_info omap4_iva_volt_info = { + .slew_rate =4000 , + .step_size =12500 , + .on_volt =1100000 , + .onlp_volt =1100000 , + .ret_volt =837500 , + .off_volt =600000 , + .volt_setup_time =0 , + .vp_erroroffset =OMAP4_VP_CONFIG_ERROROFFSET , + .vp_vstepmin =OMAP4_VP_VSTEPMIN_VSTEPMIN , + .vp_vstepmax =OMAP4_VP_VSTEPMAX_VSTEPMAX , + .vp_vddmin =OMAP4_VP_IVA_VLIMITTO_VDDMIN , + .vp_vddmax =OMAP4_VP_IVA_VLIMITTO_VDDMAX , + .vp_timeout_us =OMAP4_VP_VLIMITTO_TIMEOUT_US , + .i2c_slave_addr =OMAP4_SRI2C_SLAVE_ADDR , + .pmic_reg =OMAP4_VDD_IVA_SR_VOLT_REG , + .vsel_to_uv = twl6030_vsel_to_uv, + .uv_to_vsel = twl6030_uv_to_vsel, +}; + +static struct omap_volt_pmic_info omap4_core_volt_info = { + .slew_rate =4000 , + .step_size =12500 , + .on_volt =1100000 , + .onlp_volt =1100000 , + .ret_volt =837500 , + .off_volt =600000 , + .volt_setup_time =0 , + .vp_erroroffset =OMAP4_VP_CONFIG_ERROROFFSET , + .vp_vstepmin =OMAP4_VP_VSTEPMIN_VSTEPMIN , + .vp_vstepmax =OMAP4_VP_VSTEPMAX_VSTEPMAX , + .vp_vddmin =OMAP4_VP_CORE_VLIMITTO_VDDMIN , + .vp_vddmax =OMAP4_VP_CORE_VLIMITTO_VDDMAX , + .vp_timeout_us =OMAP4_VP_VLIMITTO_TIMEOUT_US , + .i2c_slave_addr =OMAP4_SRI2C_SLAVE_ADDR , + .pmic_reg =OMAP4_VDD_CORE_SR_VOLT_REG , + .vsel_to_uv = twl6030_vsel_to_uv, + .uv_to_vsel = twl6030_uv_to_vsel, +}; + +int __init omap4_twl_init (void ) +{ +struct voltagedomain *voltdm; + +if (!cpu_is_omap44xx ()) +return -ENODEV ; + + voltdm =omap_voltage_domain_lookup ("mpu" ); +omap_voltage_register_pmic (voltdm, &omap4_mpu_volt_info); + + voltdm =omap_voltage_domain_lookup ("iva" ); +omap_voltage_register_pmic (voltdm, &omap4_iva_volt_info); + + voltdm =omap_voltage_domain_lookup ("core" ); +omap_voltage_register_pmic (voltdm, &omap4_core_volt_info); + +return 0 ; +} +int __init omap3_twl_init (void ) {struct voltagedomain *voltdm;
arch/arm/mach-omap2/pm.c +1 -0
@@ -223,6 +223,7 @@ static int __init omap2_common_pm_late_init(void) {/* Init the OMAP TWL parameters */ omap3_twl_init (); +omap4_twl_init ();/* Init the voltage layer */ omap_voltage_late_init ();
arch/arm/mach-omap2/pm.h +5 -0
@@ -114,11 +114,16 @@ static inline void omap_enable_smartreflex_on_init(void) {}#ifdef CONFIG_TWL4030_CORE extern int omap3_twl_init (void ); +extern int omap4_twl_init (void );#else static inline int omap3_twl_init (void ) {return -EINVAL ; } +static inline int omap4_twl_init (void ) +{ +return -EINVAL ; +}#endif #endif
Signature · 1 line
1.7.0.4
PATCH v4 2/5 OMAP4: Adding voltage driver support
In reply to Thara GopinathOMAP4 has three scalable voltage domains vdd_mpu, vdd_iva and vdd_core. This patch adds the voltage tables and other configurable voltage processor and voltage controller settings to control these three scalable domains in OMAP4.
---
This patch has 9 checkpatch.pl above 80-chars warnings for the definitions of omap44xx_vdd_mpu_volt_data, omap44xx_vdd_iva_volt_data and omap44xx_vdd_core_volt_data.
IMHO splitting of the entries in these structures affects readability and looks very ugly. Hence they are left as is.
arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/control.h | 12 ++ arch/arm/mach-omap2/voltage.c | 249 +++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/voltage.h | 12 ++ 4 files changed, 274 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/Makefile +1 -1
@@ -62,7 +62,7 @@ obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o voltage.o \ cpuidle34xx.o pm_bus.o -obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o pm_bus.o +obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o voltage.o pm_bus.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
arch/arm/mach-omap2/control.h +12 -0
@@ -181,6 +181,18 @@#define OMAP3630_CONTROL_FUSE_OPP50_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128)#define OMAP3630_CONTROL_FUSE_OPP100_VDD2 (OMAP2_CONTROL_GENERAL + 0x012C) +/* OMAP44xx control efuse offsets */ +#define OMAP44XX_CONTROL_FUSE_IVA_OPP50 0x22C +#define OMAP44XX_CONTROL_FUSE_IVA_OPP100 0x22F +#define OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO 0x232 +#define OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO 0x235 +#define OMAP44XX_CONTROL_FUSE_MPU_OPP50 0x240 +#define OMAP44XX_CONTROL_FUSE_MPU_OPP100 0x243 +#define OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO 0x246 +#define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO 0x249 +#define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254 +#define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257 +/* AM35XX only CONTROL_GENERAL register offsets */ #define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310)
arch/arm/mach-omap2/voltage.c +249 -0
279 lines not on this page · raw message
arch/arm/plat-omap/include/plat/voltage.h +12 -0
@@ -44,6 +44,18 @@#define OMAP3630_VDD_CORE_OPP50_UV 1000000#define OMAP3630_VDD_CORE_OPP100_UV 1200000 +#define OMAP4430_VDD_MPU_OPP50_UV 930000 +#define OMAP4430_VDD_MPU_OPP100_UV 1100000 +#define OMAP4430_VDD_MPU_OPPTURBO_UV 1260000 +#define OMAP4430_VDD_MPU_OPPNITRO_UV 1350000 + +#define OMAP4430_VDD_IVA_OPP50_UV 930000 +#define OMAP4430_VDD_IVA_OPP100_UV 1100000 +#define OMAP4430_VDD_IVA_OPPTURBO_UV 1260000 + +#define OMAP4430_VDD_CORE_OPP50_UV 930000 +#define OMAP4430_VDD_CORE_OPP100_UV 1100000 +/** * struct voltagedomain - omap voltage domain global structure. * @name: Name of the voltage domain which can be used as a unique
Signature · 1 line
1.7.0.4
PATCH v4 3/5 OMAP4: PM: Program correct init voltages for scalable VDDs
In reply to Thara GopinathBy default the system boots up at nominal voltage for every voltage domain in the system. This patch puts vdd_mpu, vdd_iva and vdd_core to the correct boot up voltage as per the opp tables specified. This patch implements this by matching the rate of the main clock of the voltage domain with the opp table and picking up the correct voltage.
--- arch/arm/mach-omap2/pm.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm.c +11 -0
@@ -210,6 +210,16 @@ static void __init omap3_init_voltages(void)omap2_set_init_voltage ("core" ,"l3_ick" , l3_dev); } +static void __init omap4_init_voltages (void ) +{ +if (!cpu_is_omap44xx ()) +return ; + +omap2_set_init_voltage ("mpu" ,"dpll_mpu_ck" , mpu_dev); +omap2_set_init_voltage ("core" ,"l3_div_ck" , l3_dev); +omap2_set_init_voltage ("iva" ,"dpll_iva_m5x2_ck" , iva_dev); +} +static int __init omap2_common_pm_init (void ) {omap2_init_processor_devices ();
@@ -230,6 +240,7 @@ static int __init omap2_common_pm_late_init(void)/* Initialize the voltages */ omap3_init_voltages (); +omap4_init_voltages ();/* Smartreflex device init */ omap_devinit_smartreflex ();
Signature · 1 line
1.7.0.4
PATCH v4 4/5 OMAP4: hwmod: Add inital data for smartreflex modules.
In reply to Thara GopinathFrom: Benoit Cousson <[email protected]>
This patch adds the hwmod details for OMAP4 smartreflex modules.
--- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 167 ++++++++++++++++++++++++++++ 1 files changed, 167 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +167 -0
@@ -811,6 +811,169 @@ static struct omap_hwmod omap44xx_uart4_hwmod = { .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; +/* +* 'smartreflex' class +* smartreflex module (monitor silicon performance and outputs a measure of +* performance error) +*/ + +/* The IP is not compliant to type1 / type2 scheme */ +static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_smartreflex = { + .sidle_shift =24 , + .enwkup_shift =26 , +}; + +static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = { + .sysc_offs =0x0038 , + .sysc_flags = (SYSC_HAS_ENAWAKEUP |SYSC_HAS_SIDLEMODE ), + .idlemodes = (SIDLE_FORCE |SIDLE_NO |SIDLE_SMART ), + .sysc_fields = &omap_hwmod_sysc_type_smartreflex, +}; + +static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = { + .name ="smartreflex" , + .sysc = &omap44xx_smartreflex_sysc, + .rev =2 , +}; + +/* smartreflex_core */ +static struct omap_hwmod omap44xx_smartreflex_core_hwmod; +static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = { + { .irq =19 +OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_smartreflex_core_addrs[] = { + { + .pa_start =0x4a0dd000 , + .pa_end =0x4a0dd03f , + .flags =ADDR_TYPE_RT + }, +}; + +/* l4_cfg -> smartreflex_core */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_core = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_smartreflex_core_hwmod, + .clk ="l4_div_ck" , + .addr = omap44xx_smartreflex_core_addrs, + .addr_cnt =ARRAY_SIZE (omap44xx_smartreflex_core_addrs), + .user =OCP_USER_MPU |OCP_USER_SDMA , +}; + +/* smartreflex_core slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_smartreflex_core_slaves[] = { + &omap44xx_l4_cfg__smartreflex_core, +}; + +static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { + .name ="smartreflex_core" , + .class = &omap44xx_smartreflex_hwmod_class, + .mpu_irqs = omap44xx_smartreflex_core_irqs, + .mpu_irqs_cnt =ARRAY_SIZE (omap44xx_smartreflex_core_irqs), + .main_clk ="smartreflex_core_fck" , + .vdd_name ="core" , + .prcm = { + .omap4 = { + .clkctrl_reg =OMAP4430_CM_ALWON_SR_CORE_CLKCTRL , + }, + }, + .slaves = omap44xx_smartreflex_core_slaves, + .slaves_cnt =ARRAY_SIZE (omap44xx_smartreflex_core_slaves), + .omap_chip =OMAP_CHIP_INIT (CHIP_IS_OMAP4430 ), +}; + +/* smartreflex_iva */ +static struct omap_hwmod omap44xx_smartreflex_iva_hwmod; +static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = { + { .irq =102 +OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_smartreflex_iva_addrs[] = { + { + .pa_start =0x4a0db000 , + .pa_end =0x4a0db03f , + .flags =ADDR_TYPE_RT + }, +}; + +/* l4_cfg -> smartreflex_iva */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_iva = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_smartreflex_iva_hwmod, + .clk ="l4_div_ck" , + .addr = omap44xx_smartreflex_iva_addrs, + .addr_cnt =ARRAY_SIZE (omap44xx_smartreflex_iva_addrs), + .user =OCP_USER_MPU |OCP_USER_SDMA , +}; + +/* smartreflex_iva slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_smartreflex_iva_slaves[] = { + &omap44xx_l4_cfg__smartreflex_iva, +}; + +static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { + .name ="smartreflex_iva" , + .class = &omap44xx_smartreflex_hwmod_class, + .mpu_irqs = omap44xx_smartreflex_iva_irqs, + .mpu_irqs_cnt =ARRAY_SIZE (omap44xx_smartreflex_iva_irqs), + .main_clk ="smartreflex_iva_fck" , + .vdd_name ="iva" , + .prcm = { + .omap4 = { + .clkctrl_reg =OMAP4430_CM_ALWON_SR_IVA_CLKCTRL , + }, + }, + .slaves = omap44xx_smartreflex_iva_slaves, + .slaves_cnt =ARRAY_SIZE (omap44xx_smartreflex_iva_slaves), + .omap_chip =OMAP_CHIP_INIT (CHIP_IS_OMAP4430 ), +}; + +/* smartreflex_mpu */ +static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod; +static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = { + { .irq =18 +OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_smartreflex_mpu_addrs[] = { + { + .pa_start =0x4a0d9000 , + .pa_end =0x4a0d903f , + .flags =ADDR_TYPE_RT + }, +}; + +/* l4_cfg -> smartreflex_mpu */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_mpu = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_smartreflex_mpu_hwmod, + .clk ="l4_div_ck" , + .addr = omap44xx_smartreflex_mpu_addrs, + .addr_cnt =ARRAY_SIZE (omap44xx_smartreflex_mpu_addrs), + .user =OCP_USER_MPU |OCP_USER_SDMA , +}; + +/* smartreflex_mpu slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_smartreflex_mpu_slaves[] = { + &omap44xx_l4_cfg__smartreflex_mpu, +}; + +static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { + .name ="smartreflex_mpu" , + .class = &omap44xx_smartreflex_hwmod_class, + .mpu_irqs = omap44xx_smartreflex_mpu_irqs, + .mpu_irqs_cnt =ARRAY_SIZE (omap44xx_smartreflex_mpu_irqs), + .main_clk ="smartreflex_mpu_fck" , + .vdd_name ="mpu" , + .prcm = { + .omap4 = { + .clkctrl_reg =OMAP4430_CM_ALWON_SR_MPU_CLKCTRL , + }, + }, + .slaves = omap44xx_smartreflex_mpu_slaves, + .slaves_cnt =ARRAY_SIZE (omap44xx_smartreflex_mpu_slaves), + .omap_chip =OMAP_CHIP_INIT (CHIP_IS_OMAP4430 ), +}; +static __initdata struct omap_hwmod *omap44xx_hwmods[] = {/* dmm class */ &omap44xx_dmm_hwmod,
@@ -840,6 +1003,10 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = { &omap44xx_uart2_hwmod, &omap44xx_uart3_hwmod, &omap44xx_uart4_hwmod, + + &omap44xx_smartreflex_core_hwmod, + &omap44xx_smartreflex_iva_hwmod, + &omap44xx_smartreflex_mpu_hwmod, NULL, };
Signature · 1 line
1.7.0.4
PATCH v4 5/5 OMAP4: Smartreflex framework extensions
In reply to Thara GopinathThis patch extends the smartreflex framework to support OMAP4. The changes are minor like compiling smartreflex Kconfig option for OMAP4 also, and a couple of OMAP4 checks in the smartreflex framework.
The change in sr_device.c where new logic has to be introduced for reading the efuse registers is due to the fact that in OMAP4 the efuse registers are 24 bit aligned. A __raw_readl will fail for non-32 bit aligned address and hence the 8-bit read and shift.
--- arch/arm/mach-omap2/smartreflex.c | 8 ++++++-- arch/arm/mach-omap2/sr_device.c | 17 ++++++++++++++++- arch/arm/plat-omap/Kconfig | 2 +- 3 files changed, 23 insertions(+), 4 deletions(-)
arch/arm/mach-omap2/smartreflex.c +6 -2
@@ -153,7 +153,11 @@ static void sr_set_clk_length(struct omap_sr *sr)struct clk *sys_ck;u32 sys_clk_speed; - sys_ck =clk_get (NULL ,"sys_ck" ); +if (cpu_is_omap34xx ()) + sys_ck =clk_get (NULL ,"sys_ck" ); +else + sys_ck =clk_get (NULL ,"sys_clkin_ck" ); +if (IS_ERR (sys_ck)) {dev_err (&sr->pdev->dev,"%s: unable to get sys clk\n" , __func__);
@@ -193,7 +197,7 @@ static void sr_set_regfields(struct omap_sr *sr)* file or pmic specific data structure. In that case these structure * fields will have to be populated using the pdata or pmic structure. */ -if (cpu_is_omap34xx ()) { +if (cpu_is_omap34xx () ||cpu_is_omap44xx ()) { sr->err_weight =OMAP3430_SR_ERRWEIGHT ; sr->err_maxlimit =OMAP3430_SR_ERRMAXLIMIT ; sr->accum_data =OMAP3430_SR_ACCUMDATA ;
arch/arm/mach-omap2/sr_device.c +16 -1
@@ -20,6 +20,7 @@#include <linux/err.h> #include <linux/slab.h> +#include <linux/io.h> #include <plat/omap_device.h> #include <plat/smartreflex.h>
@@ -51,7 +52,21 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, GFP_KERNEL);for (i =0 ; i < count; i++) { -u32 v =omap_ctrl_readl (volt_data[i].sr_efuse_offs); +u32 v; +/* +* In OMAP4 the efuse registers are 24 bit aligned. +* A __raw_readl will fail for non-32 bit aligned address +* and hence the 8-bit read and shift. +*/ +if (cpu_is_omap44xx ()) { +u16 offset = volt_data[i].sr_efuse_offs; + + v =omap_ctrl_readb (offset) | +omap_ctrl_readb (offset +1 ) <<8 | +omap_ctrl_readb (offset +2 ) <<16 ; + }else { + v =omap_ctrl_readl (volt_data[i].sr_efuse_offs); + } nvalue_table[i].efuse_offs = volt_data[i].sr_efuse_offs; nvalue_table[i].nvalue = v;
arch/arm/plat-omap/Kconfig +1 -1
@@ -37,7 +37,7 @@ config OMAP_DEBUG_LEDS config OMAP_SMARTREFLEX bool "SmartReflex support" - depends on ARCH_OMAP3 && PM + depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM help Say Y if you want to enable SmartReflex.
Signature · 1 line
1.7.0.4