OMAP3: PM: Scale VDD2 OPP for VDD1 OPP3 and higher
PATCH 1/1 OMAP3: PM: Scale VDD2 OPP for VDD1 OPP3 and higher
This patch implements an implicit/internal constraint of 100Mhz for L3 bus while the VDD1 OPP is OPP3 or higher. The patch also removes the usage of bus_throughput_db from SRF.
Applies on the latest pm branch.
--- arch/arm/mach-omap2/pm.c | 6 +++++- arch/arm/mach-omap2/resource34xx.c | 37 ++++++++++++++++++++++++++++--------- arch/arm/mach-omap2/resource34xx.h | 13 ------------- 3 files changed, 33 insertions(+), 23 deletions(-)
arch/arm/mach-omap2/resource34xx.c +28 -9
@@ -146,7 +146,7 @@ void init_opp(struct shared_resource *re resp->no_of_users =0 ;if (!mpu_opps || !dsp_opps || !l3_opps) -return 0 ; +return ;/* Initialize the current level of the OPP resource * to the opp set by u-boot.
@@ -161,11 +161,12 @@ void init_opp(struct shared_resource *rereturn ; } +static struct device vdd2_dev; +int set_opp (struct shared_resource *resp,u32 target_level) { -unsigned long mpu_freq, mpu_old_freq, l3_freq, tput, t_opp; +unsigned long mpu_freq, mpu_old_freq, l3_freq, req_l3_freq, tput, t_opp;int ind; -struct bus_throughput_db *tput_db;struct cpufreq_freqs freqs_notify;if (resp->curr_level == target_level)
@@ -188,6 +189,14 @@ int set_opp(struct shared_resource *resp#endif t_opp =ID_VDD (PRCM_VDD1 ) |ID_OPP_NO (mpu_opps[target_level].opp_id); + +/* 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 (mpu_opps[target_level].opp_id >=3 ) +resource_request ("vdd2_opp" , &vdd2_dev,400000 ); +if (resp->curr_level > target_level) {/* Scale Frequency and then voltage */ clk_set_rate (vdd1_clk, mpu_freq);
@@ -203,22 +212,32 @@ int set_opp(struct shared_resource *resp#endif clk_set_rate (vdd1_clk, mpu_freq); } + +/* Release the VDD2/interconnect constraint */ +if (mpu_opps[target_level].opp_id <3 ) +resource_release ("vdd2_opp" , &vdd2_dev); + resp->curr_level = curr_vdd1_prcm_set->opp_id;#ifdef CONFIG_CPU_FREQ /* Send a post notification to CPUFreq */ cpufreq_notify_transition (&freqs_notify,CPUFREQ_POSTCHANGE );#endif }else if (strcmp (resp->name,"vdd2_opp" ) ==0 ) { - tput_db = resp->resource_data; tput = target_level; -/* using the throughput db map to the appropriate L3 Freq */ -for (ind =1 ; ind <MAX_VDD2_OPP ; ind++) -if (tput_db->throughput[ind] > tput) + +/* Convert the tput in KiB/s to Bus frequency in Mhz*/ + req_l3_freq = (tput *1000 )/4 ; + +for (ind =2 ; ind <=MAX_VDD2_OPP ; ind++) { +if ((l3_opps + ind)->rate >= req_l3_freq) { target_level = ind; +break ; + } + }/* Set the highest OPP possible */ -if (ind ==MAX_VDD2_OPP ) - target_level = ind-1 ; +if (ind >MAX_VDD2_OPP ) + target_level =MAX_VDD2_OPP ;if (resp->curr_level == target_level)return 0 ;
arch/arm/mach-omap2/pm.c +5 -1
@@ -34,6 +34,7 @@#include <mach/powerdomain.h> #include <mach/omapdev.h> #include <mach/resource.h> +#include <mach/omap-pm.h> #include "prm-regbits-34xx.h" #include "pm.h"
@@ -136,6 +137,7 @@ static ssize_t vdd_opp_store(struct kobj const char *buf, size_t n) { unsigned short value; +unsigned long bus_tput;if (sscanf (buf,"%hu" , &value) !=1 )return -EINVAL ;
@@ -151,7 +153,9 @@ static ssize_t vdd_opp_store(struct kobjprintk (KERN_ERR "vdd_opp_store: Invalid value\n" );return -EINVAL ; } -resource_request ("vdd2_opp" , &dummy_sysfs_dev, value); +/* Convert OPP's requested to appr. bus throughtput in KiB/s */ + bus_tput = ((l3_opps + value)->rate/1000 ) *4 ; +resource_request ("vdd2_opp" , &dummy_sysfs_dev, bus_tput); }else {return -EINVAL ; }
arch/arm/mach-omap2/resource34xx.h +0 -13
@@ -238,11 +238,6 @@ void init_freq(struct shared_resource *rint set_freq (struct shared_resource *resp,u32 target_level);int validate_freq (struct shared_resource *resp,u32 target_level); -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,
@@ -255,17 +250,9 @@ static struct shared_resource vdd1_opp = .ops = &opp_res_ops, }; -/* Throughput in KiB/s */ -static struct bus_throughput_db l3_throughput_db = { - .throughput[0 ] =0 , - .throughput[1 ] =2656000 , - .throughput[2 ] =5312000 , -}; -static struct shared_resource vdd2_opp = { .name ="vdd2_opp" , .omap_chip =OMAP_CHIP_INIT (CHIP_IS_OMAP3430 ), - .resource_data = &l3_throughput_db, .ops = &opp_res_ops, };
Kevin Hilman
AppliedQuoted 7 lines · Rajendra Nayak
This patch implements an implicit/internal constraint of 100Mhz for L3 bus while the VDD1 OPP is OPP3 or higher. The patch also removes the usage of
bus_throughput_dbfrom SRF.
Applies on the latest pm branch.Signed-off-by Rajendra Nayak <[email protected]>
Thanks, applied to PM branch.
Kevin
Quoted 158 lines
--- arch/arm/mach-omap2/pm.c | 6 +++++- arch/arm/mach-omap2/resource34xx.c | 37 ++++++++++++++++++++++++++++--------- arch/arm/mach-omap2/resource34xx.h | 13 ------------- 3 files changed, 33 insertions(+), 23 deletions(-)Index:
linux-omap-2.6/arch/arm/mach-omap2/resource34xx.c
===================================================================arch/arm/mach-omap2/resource34xx.c +28
-9@@ -146,7 +146,7 @@ void init_opp(struct shared_resource *re resp->no_of_users =0 ;if (!mpu_opps || !dsp_opps || !l3_opps) -return 0 ; +return ;/* Initialize the current level of the OPP resource * to the opp set by u-boot. @@ -161,11 +161,12 @@ void init_opp(struct shared_resource *rereturn ; } +static struct device vdd2_dev; +int set_opp (struct shared_resource *resp,u32 target_level) { -unsigned long mpu_freq, mpu_old_freq, l3_freq, tput, t_opp; +unsigned long mpu_freq, mpu_old_freq, l3_freq, req_l3_freq, tput, t_opp;int ind; -struct bus_throughput_db *tput_db;struct cpufreq_freqs freqs_notify;if (resp->curr_level == target_level)@@ -188,6 +189,14 @@ int set_opp(struct shared_resource *resp#endif t_opp =ID_VDD (PRCM_VDD1 ) |ID_OPP_NO (mpu_opps[target_level].opp_id); + +/* 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 (mpu_opps[target_level].opp_id >=3 ) +resource_request ("vdd2_opp" , &vdd2_dev,400000 ); +if (resp->curr_level > target_level) {/* Scale Frequency and then voltage */ clk_set_rate (vdd1_clk, mpu_freq);@@ -203,22 +212,32 @@ int set_opp(struct shared_resource *resp#endif clk_set_rate (vdd1_clk, mpu_freq); } + +/* Release the VDD2/interconnect constraint */ +if (mpu_opps[target_level].opp_id <3 ) +resource_release ("vdd2_opp" , &vdd2_dev); + resp->curr_level = curr_vdd1_prcm_set->opp_id;#ifdef CONFIG_CPU_FREQ /* Send a post notification to CPUFreq */ cpufreq_notify_transition (&freqs_notify,CPUFREQ_POSTCHANGE );#endif }else if (strcmp (resp->name,"vdd2_opp" ) ==0 ) { - tput_db = resp->resource_data; tput = target_level; -/* using the throughput db map to the appropriate L3 Freq */ -for (ind =1 ; ind <MAX_VDD2_OPP ; ind++) -if (tput_db->throughput[ind] > tput) + +/* Convert the tput in KiB/s to Bus frequency in Mhz*/ + req_l3_freq = (tput *1000 )/4 ; + +for (ind =2 ; ind <=MAX_VDD2_OPP ; ind++) { +if ((l3_opps + ind)->rate >= req_l3_freq) { target_level = ind; +break ; + } + }/* Set the highest OPP possible */ -if (ind ==MAX_VDD2_OPP ) - target_level = ind-1 ; +if (ind >MAX_VDD2_OPP ) + target_level =MAX_VDD2_OPP ;if (resp->curr_level == target_level)return 0 ;Index:
linux-omap-2.6/arch/arm/mach-omap2/pm.c
===================================================================arch/arm/mach-omap2/pm.c +5
-1@@ -34,6 +34,7 @@#include <mach/powerdomain.h> #include <mach/omapdev.h> #include <mach/resource.h> +#include <mach/omap-pm.h> #include "prm-regbits-34xx.h" #include "pm.h" @@ -136,6 +137,7 @@ static ssize_t vdd_opp_store(struct kobj const char *buf, size_t n) { unsigned short value; +unsigned long bus_tput;if (sscanf (buf,"%hu" , &value) !=1 )return -EINVAL ;@@ -151,7 +153,9 @@ static ssize_t vdd_opp_store(struct kobjprintk (KERN_ERR "vdd_opp_store: Invalid value\n" );return -EINVAL ; } -resource_request ("vdd2_opp" , &dummy_sysfs_dev, value); +/* Convert OPP's requested to appr. bus throughtput in KiB/s */ + bus_tput = ((l3_opps + value)->rate/1000 ) *4 ; +resource_request ("vdd2_opp" , &dummy_sysfs_dev, bus_tput); }else {return -EINVAL ; }Index:
linux-omap-2.6/arch/arm/mach-omap2/resource34xx.h
===================================================================arch/arm/mach-omap2/resource34xx.h +0
-14@@ -238,11 +238,6 @@ void init_freq(struct shared_resource *rint set_freq (struct shared_resource *resp,u32 target_level);int validate_freq (struct shared_resource *resp,u32 target_level); -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,@@ -255,17 +250,9 @@ static struct shared_resource vdd1_opp = .ops = &opp_res_ops, }; -/* Throughput in KiB/s */ -static struct bus_throughput_db l3_throughput_db = { - .throughput[0 ] =0 , - .throughput[1 ] =2656000 , - .throughput[2 ] =5312000 , -}; -static struct shared_resource vdd2_opp = { .name ="vdd2_opp" , .omap_chip =OMAP_CHIP_INIT (CHIP_IS_OMAP3430 ), - .resource_data = &l3_throughput_db, .ops = &opp_res_ops, }; --To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html