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

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

 



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

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

[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