diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c index 5b16fd1fe373d86a5adcd5ad22718d351e30fefe..533ea389bb345b1292daf9489315309de6a79ac0 100644 --- a/arch/arm/mach-omap2/voltage.c +++ b/arch/arm/mach-omap2/voltage.c @@ -21,10 +21,10 @@ #include #include -#include #include #include #include +#include #include @@ -45,36 +45,12 @@ static LIST_HEAD(voltdm_list); static int __init _config_common_vdd_data(struct voltagedomain *voltdm) { - char *sys_ck_name; - struct clk *sys_ck; - u32 sys_clk_speed, timeout_val, waittime; struct omap_vdd_info *vdd = voltdm->vdd; + u32 sys_clk_rate, timeout_val, waittime; - /* - * XXX Clockfw should handle this, or this should be in a - * struct record - */ - if (cpu_is_omap24xx() || cpu_is_omap34xx()) - sys_ck_name = "sys_ck"; - else if (cpu_is_omap44xx()) - sys_ck_name = "sys_clkin_ck"; - else - return -EINVAL; - - /* - * Sys clk rate is require to calculate vp timeout value and - * smpswaittimemin and smpswaittimemax. - */ - sys_ck = clk_get(NULL, sys_ck_name); - if (IS_ERR(sys_ck)) { - pr_warning("%s: Could not get the sys clk to calculate" - "various vdd_%s params\n", __func__, voltdm->name); - return -EINVAL; - } - sys_clk_speed = clk_get_rate(sys_ck); - clk_put(sys_ck); /* Divide to avoid overflow */ - sys_clk_speed /= 1000; + sys_clk_rate = voltdm->sys_clk.rate / 1000; + WARN_ON(!sys_clk_rate); /* Generic voltage parameters */ vdd->volt_scale = omap_vp_forceupdate_scale; @@ -84,13 +60,13 @@ static int __init _config_common_vdd_data(struct voltagedomain *voltdm) (voltdm->pmic->vp_erroroffset << __ffs(voltdm->vp->common->vpconfig_erroroffset_mask)); - timeout_val = (sys_clk_speed * voltdm->pmic->vp_timeout_us) / 1000; + timeout_val = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000; vdd->vp_rt_data.vlimitto_timeout = timeout_val; vdd->vp_rt_data.vlimitto_vddmin = voltdm->pmic->vp_vddmin; vdd->vp_rt_data.vlimitto_vddmax = voltdm->pmic->vp_vddmax; waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) * - sys_clk_speed) / 1000; + sys_clk_rate) / 1000; vdd->vp_rt_data.vstepmin_smpswaittimemin = waittime; vdd->vp_rt_data.vstepmax_smpswaittimemax = waittime; vdd->vp_rt_data.vstepmin_stepmin = voltdm->pmic->vp_vstepmin; @@ -346,9 +322,20 @@ int __init omap_voltage_late_init(void) } list_for_each_entry(voltdm, &voltdm_list, node) { + struct clk *sys_ck; + if (!voltdm->scalable) continue; + sys_ck = clk_get(NULL, voltdm->sys_clk.name); + if (IS_ERR(sys_ck)) { + pr_warning("%s: Could not get sys clk.\n", __func__); + return -EINVAL; + } + voltdm->sys_clk.rate = clk_get_rate(sys_ck); + WARN_ON(!voltdm->sys_clk.rate); + clk_put(sys_ck); + if (voltdm->vc) { voltdm->vdd->volt_scale = omap_vc_bypass_scale; omap_vc_init_channel(voltdm); diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h index eafcc927e873b1187f1c47b549bc3871b10934c7..3e163297682cf32faabeacca5057905b4344d2af 100644 --- a/arch/arm/mach-omap2/voltage.h +++ b/arch/arm/mach-omap2/voltage.h @@ -59,6 +59,7 @@ struct omap_vfsm_instance { * @read: read a VC/VP register * @write: write a VC/VP register * @read: read-modify-write a VC/VP register + * @sys_clk: system clock name/frequency, used for various timing calculations * @vdd: to be removed */ struct voltagedomain { @@ -76,6 +77,11 @@ struct voltagedomain { void (*write) (u32 val, u8 offset); u32 (*rmw)(u32 mask, u32 bits, u8 offset); + union { + const char *name; + u32 rate; + } sys_clk; + struct omap_vdd_info *vdd; }; diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c index 35117fcd55cf052eeeac8ec18156cebb66992dc2..7bbec74499088a20d1bf6c3b4bb52c3397774343 100644 --- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c +++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c @@ -80,8 +80,13 @@ static struct voltagedomain *voltagedomains_omap3[] __initdata = { NULL, }; +static const char *sys_clk_name __initdata = "sys_ck"; + void __init omap3xxx_voltagedomains_init(void) { + struct voltagedomain *voltdm; + int i; + /* * XXX Will depend on the process, validation, and binning * for the currently-running IC @@ -94,5 +99,8 @@ void __init omap3xxx_voltagedomains_init(void) omap3_vdd2_info.volt_data = omap34xx_vddcore_volt_data; } + for (i = 0; voltdm = voltagedomains_omap3[i], voltdm; i++) + voltdm->sys_clk.name = sys_clk_name; + voltdm_init(voltagedomains_omap3); }; diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c index 3e7cb4e0a63a74031be293bddc356beaaf5ce85a..9c20fbb41f6acf722a089feff1deccfccfb498ac 100644 --- a/arch/arm/mach-omap2/voltagedomains44xx_data.c +++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c @@ -98,8 +98,13 @@ static struct voltagedomain *voltagedomains_omap4[] __initdata = { NULL, }; +static const char *sys_clk_name __initdata = "sys_clkin_ck"; + void __init omap44xx_voltagedomains_init(void) { + struct voltagedomain *voltdm; + int i; + /* * XXX Will depend on the process, validation, and binning * for the currently-running IC @@ -108,5 +113,8 @@ void __init omap44xx_voltagedomains_init(void) omap4_vdd_iva_info.volt_data = omap44xx_vdd_iva_volt_data; omap4_vdd_core_info.volt_data = omap44xx_vdd_core_volt_data; + for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++) + voltdm->sys_clk.name = sys_clk_name; + voltdm_init(voltagedomains_omap4); };