RE: [PATCH 8/10] OPP layer and additional cleanups

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Romit,
With VDD1 OPP resource being removed, how are you maitaning link between MPU and DSP frequencies? I could not find such a link in the below code. May be I am missing something??

> -----Original Message-----
> From: linux-omap-owner@xxxxxxxxxxxxxxx [mailto:linux-omap-
> owner@xxxxxxxxxxxxxxx] On Behalf Of Dasgupta, Romit
> Sent: Thursday, December 31, 2009 7:00 PM
> To: paul@xxxxxxxxx; Menon, Nishanth; khilman@xxxxxxxxxxxxxxxxxxx
> Cc: linux-omap@xxxxxxxxxxxxxxx
> Subject: [PATCH 8/10] OPP layer and additional cleanups
>
> 1. Removed the OPP resources and instead introduced voltage resources.
>    This leads to a leaner implementation of DVFS. It still has scope for
>    cleanup and this will be done soon.
>
> 2. Introduced a L3 frequency resource a.k.a. l3_freq.
>
> 3. L3 frequency changes are now handled through CPUFREQ notifiers.
>
> 4. The frequency resources use the new OPP layer APIs.
>
> 5. Removed hardcoded call to vcbypass function of the smartreflex driver.
>    Now we invoke the generic voltage scaling function.
>
> diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-
> omap2/resource34xx.c
> index 157b38e..59b8faa 100644
> --- a/arch/arm/mach-omap2/resource34xx.c
> +++ b/arch/arm/mach-omap2/resource34xx.c
> @@ -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;
>  }
> diff --git a/arch/arm/mach-omap2/resource34xx.h b/arch/arm/mach-
> omap2/resource34xx.h
> index 0b4e76e..7dd7032 100644
> --- a/arch/arm/mach-omap2/resource34xx.h
> +++ b/arch/arm/mach-omap2/resource34xx.h
> @@ -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
>  };
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux