Re: [RFC] OMAP3 : PM : Handle variable length OPP tables

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

 



"Premi, Sanjeev" <premi@xxxxxx> writes:

>> -----Original Message-----
>> From: Kevin Hilman [mailto:khilman@xxxxxxxxxxxxxxxxxxx] 
>> Sent: Friday, September 11, 2009 12:00 AM
>> To: Premi, Sanjeev
>> Cc: linux-omap@xxxxxxxxxxxxxxx
>> Subject: Re: [RFC] OMAP3 : PM : Handle variable length OPP tables
>> 
>> "Premi, Sanjeev" <premi@xxxxxx> writes:
>> 
>> > Hi all,
>> >
>> > There is no generic function to translate an OPP to FREQ 
>> and vice versa.
>> > Came across the problem while trying to submit a follow-up 
>> to earlier
>> > patch for change in mpurate via bootargs. 
>> >
>> > The function get_opp in resource34xx.c, but it is always 
>> called with an
>> > explicit addition of MAX_VDDn_OPP e.g.
>> >
>> >   opp = get_opp(mpu_opps + MAX_VDD1_OPP, clk->rate);
>> >   opp = get_opp(l3_opps + MAX_VDD2_OPP, clk->rate);
>> >
>> > This is 'addition' is required as there is no encapsulation of the
>> > MIN and MAX VDDs associated to the table.
>> >
>> > The patch below fixes this issue; buy creating a 'table' object with
>> > necessary information. It can also help in getting rid of the
>> > empty {0, 0, 0} at index 0 of each OPP table.
>> >
>> > At the moment, it does not break any functionality in 
>> resource34xx.c;
>> > migration to this encapsulation can be taken as next step.
>> >
>> > This code is bare 'git-diff' for early comments. Formal 
>> patch to follow...
>> >
>> > Best regards,
>> > Sanjeev
>> 
>> Is the goal of the min and max fields so you could have some OPPs
>> in the table that aren't valid for some SoCs?  IOW, the 'max' value
>> might be higher on newer SoCs with higher OPPs.
>
> The goal is to have get_*() functions where caller shouldn't be aware
> of the MAX_ for the table. Considering table as an object, it should
> be able to provide its own length.
>
> Reason to use min and max was to maintain current functionality as is.
> Else, simple 'length' should be sufficient.
>
>> 
>> What if you want a list of OPPs, but want to remove one from the
>> middle of the list?  The min/max approach doesn't work here.
>> 
>> What about a also extending the struct omap_opp to have some sort of
>> valid field.
>
> This doesn't help in eliminating the addition of MAX value for each
> function call.

No it doesn't.  I'm just thinking about the next step of having a more flexible list of OPPs.

Kevin

>> 
>> >
>> > diff --git a/arch/arm/plat-omap/include/mach/omap-pm.h 
>> b/arch/arm/plat-omap/include/mach/omap-pm.h
>> > index 583e540..2357784 100644
>> > --- a/arch/arm/plat-omap/include/mach/omap-pm.h
>> > +++ b/arch/arm/plat-omap/include/mach/omap-pm.h
>> > @@ -33,6 +33,20 @@ struct omap_opp {
>> >         u16 vsel;
>> >  };
>> >  
>> > +/* struct omap_opp_table - View OPP table as an object
>> > + * @min: Minimum OPP id
>> > + * @max: Maximim OPP id
>> > + * @opps: Pointer to array defining the OPPs.
>> > + *
>> > + * An OPP table has varied length. Knowing minimum and maximum
>> > + * OPP ids allow easy traversal.
>> > + */
>> > +struct omap_opp_table {
>> > +       u8      min;
>> > +       u8      max;
>> > +       struct omap_opp* opps;
>> > +};
>> > +
>> >  extern struct omap_opp *mpu_opps;
>> >  extern struct omap_opp *dsp_opps;
>> >  extern struct omap_opp *l3_opps;
>> > diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
>> > index fec7d00..c90b1af 100644
>> > --- a/arch/arm/mach-omap2/pm.c
>> > +++ b/arch/arm/mach-omap2/pm.c
>> > @@ -33,6 +33,7 @@
>> >  #include <mach/powerdomain.h>
>> >  #include <mach/resource.h>
>> >  #include <mach/omap34xx.h>
>> > +#include <mach/omap-pm.h>
>> >  
>> >  #include "prm-regbits-34xx.h"
>> >  #include "pm.h"
>> > @@ -281,3 +282,50 @@ static int __init omap_pm_init(void)
>> >         return error;
>> >  }
>> >  late_initcall(omap_pm_init);
>> > +
>> > +/*
>> > + * Get frequency corresponding to an OPP
>> > + */
>> > +int opp_to_freq(unsigned int* freq, struct omap_opp_table* 
>> table, u8 opp)
>> > +{
>> > +        int i, found=0;
>> > +
>> > +        if (table && table->opps) {
>> > +                for (i=table->min;  table->opps[i].opp_id 
>> <= table->max; i++)
>> > +                        if (table->opps[i].opp_id == opp) {
>> > +                                found = 1;
>> > +                                break;
>> > +                        }
>> > +
>> > +                if (found) {
>> > +                        *freq = table->opps[i].rate;
>> > +                        return 1;
>> > +                }
>> > +        }
>> > +
>> > +        return 0;
>> > +}
>> > +
>> > +/*
>> > + * Get OPP corresponding to a frequency
>> > + */
>> > +int freq_to_opp(u8* opp, struct omap_opp_table* table, 
>> unsigned long freq)
>> > +{
>> > +        int i, found=0;
>> > +
>> > +        if (table && table->opps) {
>> > +                for (i=table->min;  table->opps[i].opp_id 
>> <= table->max; i++)
>> > +                        if (table->opps[i].rate == freq) {
>> > +                                found = 1;
>> > +                                break;
>> > +                        }
>> > +
>> > +                if (found) {
>> > +                        *opp = table->opps[i].opp_id;
>> > +                        return 1;
>> > +                }
>> > +        }
>> > +
>> > +        return 0;
>> > +}
>> > +
>> > --
>> > 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