@@ -37,6 +37,8 @@
#warning MPU latency constraints require CONFIG_CPU_IDLE to function!
#endif
+static struct device vdd1_volt_dev, vdd2_volt_dev;
+
/**
* init_latency - Initializes the mpu/core latency resource.
* @resp: Latency resource to be initalized
@@ -146,115 +148,6 @@ int set_pd_latency(struct shared_resource *resp, u32 latency)
return 0;
}
-static struct shared_resource *vdd1_resp;
-static struct shared_resource *vdd2_resp;
-static struct device dummy_mpu_dev;
-static struct device dummy_dsp_dev;
-static struct device vdd2_dev;
-static int vdd1_lock;
-static int vdd2_lock;
-static struct clk *dpll1_clk, *dpll2_clk, *dpll3_clk;
-static int curr_vdd1_opp;
-static int curr_vdd2_opp;
-static DEFINE_MUTEX(dvfs_mutex);
-
-/**
- * opp_to_freq - convert OPPID to frequency (DEPRECATED)
- * @freq: return frequency back to caller
- * @opps: opp list
- * @opp_id: OPP ID we are searching for
- *
- * return 0 and freq is populated if we find the opp_id, else,
- * we return error
- *
- * NOTE: this function is a standin for the timebeing as opp_id is deprecated
- */
-static int __deprecated opp_to_freq(unsigned long *freq,
- const struct omap_opp *opps, u8 opp_id)
-{
- struct omap_opp *opp;
-
- BUG_ON(!freq || !opps);
-
- opp = opp_find_by_opp_id(opps, opp_id);
- if (!opp)
- return -EINVAL;
-
- *freq = opp_get_freq(opp);
-
- return 0;
-}
-
-/**
- * freq_to_opp - convert a frequency back to OPP ID (DEPRECATED)
- * @opp_id: opp ID returned back to caller
- * @opps: opp list
- * @freq: frequency we are searching for
- *
- * return 0 and opp_id is populated if we find the freq, else, we return error
- *
- * NOTE: this function is a standin for the timebeing as opp_id is deprecated
- */
-static int __deprecated freq_to_opp(u8 *opp_id, struct omap_opp *opps,
- unsigned long freq)
-{
- struct omap_opp *opp;
-
- BUG_ON(!opp_id || !opps);
- opp = opp_find_freq_ceil(opps, &freq);
- if (IS_ERR(opp))
- return -EINVAL;
- *opp_id = opp_get_opp_id(opp);
- return 0;
-}
-
-/**
- * init_opp - Initialize the OPP resource
- */
-void init_opp(struct shared_resource *resp)
-{
- struct clk *l3_clk;
- int ret;
- u8 opp_id;
- resp->no_of_users = 0;
-
- if (!mpu_opps || !dsp_opps || !l3_opps)
- return;
-
- /* Initialize the current level of the OPP resource
- * to the opp set by u-boot.
- */
- if (strcmp(resp->name, "vdd1_opp") == 0) {
- vdd1_resp = resp;
- dpll1_clk = clk_get(NULL, "dpll1_ck");
- dpll2_clk = clk_get(NULL, "dpll2_ck");
- ret = freq_to_opp(&opp_id, mpu_opps, dpll1_clk->rate);
- BUG_ON(ret); /* TBD Cleanup handling */
- curr_vdd1_opp = opp_id;
- } else if (strcmp(resp->name, "vdd2_opp") == 0) {
- vdd2_resp = resp;
- dpll3_clk = clk_get(NULL, "dpll3_m2_ck");
- l3_clk = clk_get(NULL, "l3_ick");
- ret = freq_to_opp(&opp_id, l3_opps, l3_clk->rate);
- BUG_ON(ret); /* TBD Cleanup handling */
- curr_vdd2_opp = opp_id;
- }
- resp->curr_level = opp_id;
- return;
-}
-
-int resource_access_opp_lock(int res, int delta)
-{
- if (res == VDD1_OPP) {
- vdd1_lock += delta;
- return vdd1_lock;
- } else if (res == VDD2_OPP) {
- vdd2_lock += delta;
- return vdd2_lock;
- }
- return -EINVAL;
-}
-
#ifndef CONFIG_CPU_FREQ
static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult)
{
@@ -277,235 +170,60 @@ static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult)
}
#endif
-static int program_opp_freq(int res, int target_level, int current_level)
-{
- int ret = 0, l3_div;
- int *curr_opp;
- unsigned long mpu_freq, dsp_freq, l3_freq;
-#ifndef CONFIG_CPU_FREQ
- unsigned long mpu_cur_freq;
-#endif
-
- /* Check if I can actually switch or not */
- if (res == VDD1_OPP) {
- ret = opp_to_freq(&mpu_freq, mpu_opps, target_level);
- ret |= opp_to_freq(&dsp_freq, dsp_opps, target_level);
-#ifndef CONFIG_CPU_FREQ
- ret |= opp_to_freq(&mpu_cur_freq, mpu_opps, current_level);
-#endif
- } else {
- ret = opp_to_freq(&l3_freq, l3_opps, target_level);
- }
- /* we would have caught all bad levels earlier.. */
- if (unlikely(ret))
- return ret;
+struct _vdd_priv {
+ struct omap_opp *curr;
+ struct omap_opp *target;
+};
- lock_scratchpad_sem();
- if (res == VDD1_OPP) {
- curr_opp = &curr_vdd1_opp;
- clk_set_rate(dpll1_clk, mpu_freq);
- clk_set_rate(dpll2_clk, dsp_freq);
-#ifndef CONFIG_CPU_FREQ
- /*Update loops_per_jiffy if processor speed is being changed*/
- loops_per_jiffy = compute_lpj(loops_per_jiffy,
- mpu_cur_freq / 1000, mpu_freq / 1000);
-#endif
- } else {
- curr_opp = &curr_vdd2_opp;
+void init_volt(struct shared_resource *resp)
+{
+ struct omap_opp *opp = NULL;
+
+ if (!strcmp(resp->name, "vdd1_volt")) {
+ opp = find_opp_by_freq(OPP_MPU,
+ clk_get(NULL, "dpll1_ck")->rate,
+ OPP_ENABLED | OPP_EQ);
+ } else if (!strcmp(resp->name, "vdd2_volt")) {
+ int l3_div = 0;
l3_div = cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
- OMAP3430_CLKSEL_L3_MASK;
- ret = clk_set_rate(dpll3_clk, l3_freq * l3_div);
- }
- if (ret) {
- unlock_scratchpad_sem();
- return current_level;
+ OMAP3430_CLKSEL_L3_MASK;
+ opp = find_opp_by_freq(OPP_L3, clk_get(NULL,
+ "dpll3_m2_ck")->rate / l3_div,
+ OPP_ENABLED | OPP_EQ);
}
-#ifdef CONFIG_PM
- omap3_save_scratchpad_contents();
-#endif
- unlock_scratchpad_sem();
-
- *curr_opp = target_level;
- return target_level;
+ BUG_ON(!opp);
+ resp->curr_level = opp_to_volt(opp); /* in uV */
+ return;
}
-static int program_opp(int res, struct omap_opp *opp, int target_level,
- int current_level)
+int set_volt(struct shared_resource *resp, u32 target_volt)
{
- int i, ret = 0, raise;
- unsigned long freq;
-#ifdef CONFIG_OMAP_SMARTREFLEX
- unsigned long t_opp, c_opp;
-
- t_opp = ID_VDD(res) | ID_OPP_NO(target_level);
- c_opp = ID_VDD(res) | ID_OPP_NO(current_level);
-#endif
-
- /* See if have a freq associated, if not, invalid opp */
- ret = opp_to_freq(&freq, opp, target_level);
- if (unlikely(ret))
- return ret;
-
- if (target_level > current_level)
- raise = 1;
- else
- raise = 0;
-
- for (i = 0; i < 2; i++) {
- if (i == raise)
- ret = program_opp_freq(res, target_level,
- current_level);
-#ifdef CONFIG_OMAP_SMARTREFLEX
- else {
- u8 vc, vt;
- struct omap_opp *oppx;
- unsigned long uvdc;
-
- /*
- * transitioning from good to good OPP
- * none of the following should fail..
- */
- oppx = opp_find_freq_exact(opp, freq, true);
- BUG_ON(IS_ERR(oppx));
- uvdc = opp_get_voltage(oppx);
- vt = omap_twl_uv_to_vsel(uvdc);
-
- BUG_ON(opp_to_freq(&freq, opp, current_level));
- oppx = opp_find_freq_exact(opp, freq, true);
- BUG_ON(IS_ERR(oppx));
- uvdc = opp_get_voltage(oppx);
- vc = omap_twl_uv_to_vsel(uvdc);
-
- /* ok to scale.. */
- sr_voltagescale_vcbypass(t_opp, c_opp, vt, vc);
- }
-#endif
+ int ret = 0;
+ struct omap_opp *current_opp, *target_opp;
+
+ if (!strcmp(resp->name, "vdd1_volt") && voltage_scale) {
+ current_opp =
+ ((struct _vdd_priv *)(vdd1_volt.resource_data))->curr;
+ target_opp =
+ ((struct _vdd_priv *)
+ (vdd1_volt.resource_data))->target;
+ ret = voltage_scale(RAIL_VDD1, current_opp, target_opp);
+ } else if (!strcmp(resp->name, "vdd2_volt") && voltage_scale) {
+ current_opp =
+ ((struct _vdd_priv *)(vdd2_volt.resource_data))->curr;
+ target_opp =
+ ((struct _vdd_priv *)
+ (vdd2_volt.resource_data))->target;
+ ret = voltage_scale(RAIL_VDD2, current_opp, target_opp);
}
-
return ret;
}
-int resource_set_opp_level(int res, u32 target_level, int flags)
-{
- unsigned long mpu_freq, mpu_old_freq, l3_freq;
- int ret;
-#ifdef CONFIG_CPU_FREQ
- struct cpufreq_freqs freqs_notify;
-#endif
- struct shared_resource *resp;
-
- if (res == VDD1_OPP)
- resp = vdd1_resp;
- else if (res == VDD2_OPP)
- resp = vdd2_resp;
- else
- return 0;
-
- if (resp->curr_level == target_level)
- return 0;
-
- if (!mpu_opps || !dsp_opps || !l3_opps)
- return 0;
-
- /* Check if I can actually switch or not */
- if (res == VDD1_OPP) {
- ret = opp_to_freq(&mpu_freq, mpu_opps, target_level);
- ret |= opp_to_freq(&mpu_old_freq, mpu_opps, resp->curr_level);
- } else {
- ret = opp_to_freq(&l3_freq, l3_opps, target_level);
- }
- if (ret)
- return ret;
-
- mutex_lock(&dvfs_mutex);
-
- if (res == VDD1_OPP) {
- if (flags != OPP_IGNORE_LOCK && vdd1_lock) {
- mutex_unlock(&dvfs_mutex);
- return 0;
- }
-#ifdef CONFIG_CPU_FREQ
- freqs_notify.old = mpu_old_freq/1000;
- freqs_notify.new = mpu_freq/1000;
- freqs_notify.cpu = 0;
- /* Send pre notification to CPUFreq */
- cpufreq_notify_transition(&freqs_notify, CPUFREQ_PRECHANGE);
-#endif
- resp->curr_level = program_opp(res, mpu_opps, target_level,
- resp->curr_level);
-#ifdef CONFIG_CPU_FREQ
- /* Send a post notification to CPUFreq */
- cpufreq_notify_transition(&freqs_notify, CPUFREQ_POSTCHANGE);
-#endif
- } else {
- if (!(flags & OPP_IGNORE_LOCK) && vdd2_lock) {
- mutex_unlock(&dvfs_mutex);
- return 0;
- }
- resp->curr_level = program_opp(res, l3_opps, target_level,
- resp->curr_level);
- }
- mutex_unlock(&dvfs_mutex);
- return 0;
-}
-
-int set_opp(struct shared_resource *resp, u32 target_level)
-{
- int ret = -EINVAL;
-
- if (resp == vdd1_resp) {
- if (target_level < 3)
- resource_release("vdd2_opp", &vdd2_dev);
-
- ret = resource_set_opp_level(VDD1_OPP, target_level, 0);
- /*
- * For VDD1 OPP3 and above, make sure the interconnect
- * is at 100Mhz or above.
- * throughput in KiB/s for 100 Mhz = 100 * 1000 * 4.
- */
- if (target_level >= 3)
- resource_request("vdd2_opp", &vdd2_dev, 400000);
-
- } else if (resp == vdd2_resp) {
- unsigned long req_l3_freq;
- struct omap_opp *oppx = NULL;
-
- /* Convert the tput in KiB/s to Bus frequency in MHz */
- req_l3_freq = (target_level * 1000)/4;
-
- /* Do I have a best match? */
- oppx = opp_find_freq_ceil(l3_opps, &req_l3_freq);
- if (IS_ERR(oppx)) {
- /* Give me the best we got */
- req_l3_freq = ULONG_MAX;
- oppx = opp_find_freq_floor(l3_opps, &req_l3_freq);
- }
-
- /* uh uh.. no OPPs?? */
- BUG_ON(IS_ERR(oppx));
-
- ret = freq_to_opp((u8 *)&target_level, l3_opps, req_l3_freq);
- /* we dont expect this to fail */
- BUG_ON(ret);
-
- ret = resource_set_opp_level(VDD2_OPP, target_level, 0);
- }
- return 0;
-}
-
-/**
- * validate_opp - Validates if valid VDD1 OPP's are passed as the
- * target_level.
- * VDD2 OPP levels are passed as L3 throughput, which are then mapped
- * to an appropriate OPP.
+/*
+ * XXX: TODO
*/
-int validate_opp(struct shared_resource *resp, u32 target_level)
+int validate_volt(struct shared_resource *resp, u32 target_volt)
{
- unsigned long x;
- if (strcmp(resp->name, "mpu_freq") == 0)
- return opp_to_freq(&x, mpu_opps, target_level);
- else if (strcmp(resp->name, "dsp_freq") == 0)
- return opp_to_freq(&x, dsp_opps, target_level);
return 0;
}
@@ -514,60 +232,154 @@ int validate_opp(struct shared_resource *resp, u32 target_level)
*/
void init_freq(struct shared_resource *resp)
{
- char *linked_res_name;
- int ret = -EINVAL;
- unsigned long freq;
+ struct omap_opp *opp = NULL;
resp->no_of_users = 0;
- if (!mpu_opps || !dsp_opps)
- return;
-
- linked_res_name = (char *)resp->resource_data;
/* Initialize the current level of the Freq resource
- * to the frequency set by u-boot.
- */
- if (strcmp(resp->name, "mpu_freq") == 0)
- /* MPU freq in Mhz */
- ret = opp_to_freq(&freq, mpu_opps, curr_vdd1_opp);
- else if (strcmp(resp->name, "dsp_freq") == 0)
- /* DSP freq in Mhz */
- ret = opp_to_freq(&freq, dsp_opps, curr_vdd1_opp);
- BUG_ON(ret);
-
- resp->curr_level = freq;
+ * to the clk_rate set by bootloader.
+ */
+ if (!strcmp(resp->name, "mpu_freq"))
+ opp = find_opp_by_freq(OPP_MPU,
+ clk_get(NULL, "dpll1_ck")->rate,
+ OPP_ENABLED | OPP_EQ);
+ else if (!strcmp(resp->name, "dsp_freq"))
+ opp = find_opp_by_freq(OPP_DSP,
+ clk_get(NULL, "dpll2_ck")->rate,
+ OPP_ENABLED | OPP_EQ);
+ else if (!strcmp(resp->name, "l3_freq")) {
+ int l3_div = 0;
+ l3_div = cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
+ OMAP3430_CLKSEL_L3_MASK;
+ opp = find_opp_by_freq(OPP_L3, clk_get(NULL,
+ "dpll3_m2_ck")->rate / l3_div,
+ OPP_ENABLED | OPP_EQ);
+ }
+
+ BUG_ON(!opp);
+
+ resp->curr_level = opp_to_freq(opp);
return;
}
-int set_freq(struct shared_resource *resp, u32 target_level)
+static char vres[][255] = {"vdd1_volt", "vdd2_volt"};
+
+int set_freq(struct shared_resource *resp, u32 target_freq)
{
- u8 vdd1_opp;
- int ret = -EINVAL;
+ struct omap_opp *current_opp = NULL, *target_opp = NULL;
+ int ret = 0, l3_div = 0, scale_up = 0;
+ struct device *dev = NULL;
+ struct clk *clk = NULL;
+ struct _vdd_priv vdd_priv;
+ char *volt_res = NULL;
+#ifdef CONFIG_CPU_FREQ
+ struct cpufreq_freqs freqs_notify;
+#endif
- if (!mpu_opps || !dsp_opps)
- return 0;
+ if (!strcmp(resp->name, "mpu_freq")) {
+ dev = &vdd1_volt_dev;
+ volt_res = vres[0];
+ clk = clk_get(NULL, "dpll1_ck");
+ current_opp = find_opp_by_freq(OPP_MPU, clk->rate,
+ OPP_EQ | OPP_ENABLED);
+ target_opp = find_opp_by_freq(OPP_MPU, target_freq,
+ OPP_EQ | OPP_ENABLED);
+ BUG_ON(!current_opp || !target_opp);
+ vdd_priv.curr = current_opp;
+ vdd_priv.target = target_opp;
+ vdd1_volt.resource_data = &vdd_priv;
+#ifdef CONFIG_CPU_FREQ
+ freqs_notify.old = opp_to_freq(current_opp) / 1000;
+ freqs_notify.new = opp_to_freq(target_opp) / 1000;
+ freqs_notify.cpu = smp_processor_id();
+ cpufreq_notify_transition(&freqs_notify, CPUFREQ_PRECHANGE);
+#endif
+ } else if (!strcmp(resp->name, "dsp_freq")) {
+ dev = &vdd1_volt_dev;
+ volt_res = vres[0];
+ clk = clk_get(NULL, "dpll2_ck");
+ current_opp = find_opp_by_freq(OPP_DSP, clk->rate,
+ OPP_EQ | OPP_ENABLED);
+ target_opp = find_opp_by_freq(OPP_DSP, target_freq,
+ OPP_EQ | OPP_ENABLED);
+ BUG_ON(!current_opp || !target_opp);
+ vdd_priv.curr = current_opp;
+ vdd_priv.target = target_opp;
+ vdd1_volt.resource_data = &vdd_priv;
+
+ } else if (!strcmp(resp->name, "l3_freq")) {
+ dev = &vdd2_volt_dev;
+ volt_res = vres[1];
+ clk = clk_get(NULL, "dpll3_m2_ck");
+ l3_div = cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
+ OMAP3430_CLKSEL_L3_MASK;
+ current_opp = find_opp_by_freq(OPP_L3, clk->rate / l3_div,
+ OPP_EQ | OPP_ENABLED);
+ target_opp = find_opp_by_freq(OPP_L3, target_freq,
+ OPP_EQ | OPP_ENABLED);
+
+ target_freq *= l3_div;
+ vdd_priv.curr = current_opp;
+ vdd_priv.target = target_opp;
+ vdd2_volt.resource_data = &vdd_priv;
+ }
+
+ if (opp_to_freq(current_opp) == opp_to_freq(target_opp))
+ return 0; /* This should not happen. Check with resource fmwk */
+ else if (opp_to_freq(current_opp) < opp_to_freq(target_opp))
+ scale_up = 1;
- if (strcmp(resp->name, "mpu_freq") == 0) {
- ret = freq_to_opp(&vdd1_opp, mpu_opps, target_level);
+ lock_scratchpad_sem();
+ if (scale_up) {
+ ret = resource_request(volt_res, dev,
+ opp_to_volt(target_opp));
if (!ret)
- ret = resource_request("vdd1_opp", &dummy_mpu_dev,
- vdd1_opp);
- } else if (strcmp(resp->name, "dsp_freq") == 0) {
- ret = freq_to_opp(&vdd1_opp, dsp_opps, target_level);
+ ret = clk_set_rate(clk, target_freq);
+ } else {
+ ret = clk_set_rate(clk, target_freq);
if (!ret)
- ret = resource_request("vdd1_opp", &dummy_dsp_dev,
- vdd1_opp);
+ ret = resource_request(volt_res, dev,
+ opp_to_volt(target_opp));
}
+ unlock_scratchpad_sem();
+
+ /*
+ * L3 clock adjustment.
+ */
+ if (!strcmp(resp->name, "l3_freq"))
+ target_freq /= l3_div;
+
+ if (!strcmp(resp->name, "mpu_freq") && !ret)
+#ifdef CONFIG_CPU_FREQ
+ cpufreq_notify_transition(&freqs_notify, CPUFREQ_POSTCHANGE);
+#else
+ /* Update loops per jiffy */
+ loops_per_jiffy = compute_lpj(loops_per_jiffy,
+ opp_to_freq(current_opp) / 1000,
+ opp_to_freq(target_opp) / 1000);
+#endif
if (!ret)
- resp->curr_level = target_level;
+ resp->curr_level = target_freq;
+
return ret;
}
-int validate_freq(struct shared_resource *resp, u32 target_level)
+int validate_freq(struct shared_resource *resp, u32 target_freq)
{
- u8 x;
- if (strcmp(resp->name, "mpu_freq") == 0)
- return freq_to_opp(&x, mpu_opps, target_level);
- else if (strcmp(resp->name, "dsp_freq") == 0)
- return freq_to_opp(&x, dsp_opps, target_level);
- return 0;
+ struct omap_opp *opp;
+
+ if (!strcmp(resp->name, "mpu_freq")) {
+ opp = find_opp_by_freq(OPP_MPU, target_freq,
+ OPP_EQ | OPP_ENABLED);
+ return !opp_is_valid(opp);
+ } else if (!strcmp(resp->name, "dsp_freq")) {
+ opp = find_opp_by_freq(OPP_DSP, target_freq,
+ OPP_EQ | OPP_ENABLED);
+ return !opp_is_valid(opp);
+ } else if (!strcmp(resp->name, "l3_freq")) {
+ opp = find_opp_by_freq(OPP_L3, target_freq,
+ OPP_EQ | OPP_ENABLED);
+ return !opp_is_valid(opp);
+ }
+
+ return 1;
}
@@ -30,7 +30,6 @@
#include <plat/opp.h>
#include <plat/omap34xx.h>
-extern int sr_voltagescale_vcbypass(u32 t_opp, u32 c_opp, u8 t_vsel, u8 c_vsel);
extern void lock_scratchpad_sem(void);
extern void unlock_scratchpad_sem(void);
@@ -244,29 +243,33 @@ static struct shared_resource emu_pwrdm_latency = {
.ops = &pd_lat_res_ops,
};
-void init_opp(struct shared_resource *resp);
-int set_opp(struct shared_resource *resp, u32 target_level);
-int validate_opp(struct shared_resource *resp, u32 target_level);
-void init_freq(struct shared_resource *resp);
-int set_freq(struct shared_resource *resp, u32 target_level);
-int validate_freq(struct shared_resource *resp, u32 target_level);
+extern void init_volt(struct shared_resource *);
+extern int set_volt(struct shared_resource *, u32);
+extern int validate_volt(struct shared_resource *, u32);
struct bus_throughput_db {
/* Throughput for each OPP/Freq of the bus */
unsigned long throughput[3];
};
-static struct shared_resource_ops opp_res_ops = {
- .init = init_opp,
- .change_level = set_opp,
- .validate_level = validate_opp,
+static struct shared_resource_ops volt_res_ops = {
+ .init = init_volt,
+ .change_level = set_volt,
+ .validate_level = validate_volt,
};
-static struct shared_resource vdd1_opp = {
- .name = "vdd1_opp",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
- .flags = RES_TYPE_PERFORMANCE,
- .ops = &opp_res_ops,
+static struct shared_resource vdd1_volt = {
+ .name = "vdd1_volt",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = RES_TYPE_PERFORMANCE,
+ .ops = &volt_res_ops,
+};
+
+static struct shared_resource vdd2_volt = {
+ .name = "vdd2_volt",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = RES_TYPE_PERFORMANCE,
+ .ops = &volt_res_ops,
};
/* Throughput in KiB/s */
@@ -276,15 +279,11 @@ static struct bus_throughput_db l3_throughput_db = {
.throughput[2] = 5312000,
};
-static struct shared_resource vdd2_opp = {
- .name = "vdd2_opp",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
- .flags = RES_TYPE_PERFORMANCE,
- .resource_data = &l3_throughput_db,
- .ops = &opp_res_ops,
-};
+static char linked_res[] = "vdd1_volt";
-static char linked_res[] = "vdd1_opp";
+extern void init_freq(struct shared_resource *);
+extern int set_freq(struct shared_resource *, u32);
+extern int validate_freq(struct shared_resource *, u32);
static struct shared_resource_ops freq_res_ops = {
.init = init_freq,
@@ -308,6 +307,13 @@ static struct shared_resource dsp_freq = {
.ops = &freq_res_ops,
};
+static struct shared_resource l3_freq = {
+ .name = "l3_freq",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = RES_TYPE_PERFORMANCE,
+ .ops = &freq_res_ops,
+};
+
struct shared_resource *resources_omap[] __initdata = {
&mpu_latency,
&core_latency,
@@ -322,10 +328,12 @@ struct shared_resource *resources_omap[] __initdata = {
&neon_pwrdm_latency,
&usbhost_pwrdm_latency,
&emu_pwrdm_latency,
- /* OPP/frequency resources */
- &vdd1_opp,
- &vdd2_opp,
+ /* Voltage rail resources */
+ &vdd1_volt,
+ &vdd2_volt,
+ /* frequency resources */
&mpu_freq,
+ &l3_freq,
&dsp_freq,
NULL
};