Message ID | 1444220561-26139-2-git-send-email-dawei.chien@mediatek.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Oct 07, 2015 at 08:22:40PM +0800, Dawei Chien wrote: > From: "Dawei.Chien" <dawei.chien@mediatek.com> > > This power model is base on Intelligent Power Allocation (IPA) technical, > requires that the operating-points of the CPUs are registered using the > kernel's opp library and the `cpufreq_frequency_table` is assigned to the > `struct device` of the cpu MT8173. > > Signed-off-by: Dawei.Chien <dawei.chien@mediatek.com> > --- > This patch is base on > https://patchwork.kernel.org/patch/7034601/ > --- > drivers/cpufreq/mt8173-cpufreq.c | 97 +++++++++++++++++++++++++++++++++----- > 1 file changed, 86 insertions(+), 11 deletions(-) > > diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c > index 49caed2..9233ec5 100644 > --- a/drivers/cpufreq/mt8173-cpufreq.c > +++ b/drivers/cpufreq/mt8173-cpufreq.c > @@ -28,7 +28,8 @@ > #define MAX_VOLT_SHIFT (200000) > #define MAX_VOLT_LIMIT (1150000) > #define VOLT_TOL (10000) > - > +#define CAPACITANCE_CA53 (263) > +#define CAPACITANCE_CA57 (530) > /* > * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS > * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in > @@ -51,6 +52,72 @@ struct mtk_cpu_dvfs_info { > bool need_voltage_tracking; > }; > > +struct mtk_cpu_static_power { > + unsigned long voltage; > + unsigned int power; > +}; > + > +/* measured by WA program. */ > +static const struct mtk_cpu_static_power mtk_ca53_static_power[] = { > + {859000, 43}, > + {908000, 52}, > + {983000, 86}, > + {1009000, 123}, > + {1028000, 138}, > + {1083000, 172}, > + {1109000, 180}, > + {1125000, 192}, > +}; > + > +/* measured by WA program. */ > +static const struct mtk_cpu_static_power mtk_ca57_static_power[] = { > + {828000, 72}, > + {867000, 90}, > + {927000, 156}, > + {968000, 181}, > + {1007000, 298}, > + {1049000, 435}, > + {1089000, 533}, > + {1125000, 533}, > +}; This should be described in the DT, rather than necessitating tonnes of these tables in the kernel. Mark.
Mark Rutland <mark.rutland@arm.com> writes: > On Wed, Oct 07, 2015 at 08:22:40PM +0800, Dawei Chien wrote: >> From: "Dawei.Chien" <dawei.chien@mediatek.com> >> >> This power model is base on Intelligent Power Allocation (IPA) technical, >> requires that the operating-points of the CPUs are registered using the >> kernel's opp library and the `cpufreq_frequency_table` is assigned to the >> `struct device` of the cpu MT8173. >> >> Signed-off-by: Dawei.Chien <dawei.chien@mediatek.com> >> --- >> This patch is base on >> https://patchwork.kernel.org/patch/7034601/ >> --- >> drivers/cpufreq/mt8173-cpufreq.c | 97 +++++++++++++++++++++++++++++++++----- >> 1 file changed, 86 insertions(+), 11 deletions(-) >> >> diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c >> index 49caed2..9233ec5 100644 >> --- a/drivers/cpufreq/mt8173-cpufreq.c >> +++ b/drivers/cpufreq/mt8173-cpufreq.c >> @@ -28,7 +28,8 @@ >> #define MAX_VOLT_SHIFT (200000) >> #define MAX_VOLT_LIMIT (1150000) >> #define VOLT_TOL (10000) >> - >> +#define CAPACITANCE_CA53 (263) >> +#define CAPACITANCE_CA57 (530) >> /* >> * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS >> * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in >> @@ -51,6 +52,72 @@ struct mtk_cpu_dvfs_info { >> bool need_voltage_tracking; >> }; >> >> +struct mtk_cpu_static_power { >> + unsigned long voltage; >> + unsigned int power; >> +}; >> + >> +/* measured by WA program. */ >> +static const struct mtk_cpu_static_power mtk_ca53_static_power[] = { >> + {859000, 43}, >> + {908000, 52}, >> + {983000, 86}, >> + {1009000, 123}, >> + {1028000, 138}, >> + {1083000, 172}, >> + {1109000, 180}, >> + {1125000, 192}, >> +}; >> + >> +/* measured by WA program. */ >> +static const struct mtk_cpu_static_power mtk_ca57_static_power[] = { >> + {828000, 72}, >> + {867000, 90}, >> + {927000, 156}, >> + {968000, 181}, >> + {1007000, 298}, >> + {1049000, 435}, >> + {1089000, 533}, >> + {1125000, 533}, >> +}; > > This should be described in the DT, rather than necessitating tonnes of > these tables in the kernel. The above table is a simplification that is tying the static power of a device to a voltage (indirectly via frequency for ease of indexing perhaps). We should definitely look at describing the static power model in the device tree - but it is not entirely clear what is the best model to use as basis for the device tree bindings. Static power consumption depends on a few different parameters (silicon process, voltage, temperature, etc.). The relationship between them maybe non-linear and not all of these maybe significant for a given platform. e.g., for Juno, we are using a regression based on voltage and temperature which was deemed close enough (very subjective tbh). On the other hand, dynamic power consumption is somewhat simpler and I have patches[0][1][2] enabling it's description in device tree. Your comments there would be very much appreciated. As for this patch, I hope it can be moved to using the device tree when the bindings for static power are agreed upon. Although sub-optimal, I can't see any other way forward for now. [0] http://thread.gmane.org/gmane.linux.kernel/2011466/focus=130373 [1] http://thread.gmane.org/gmane.linux.kernel/2011466/focus=2011465 [2] http://article.gmane.org/gmane.linux.drivers.sensors/37859 > > Mark. > -- > To unsubscribe from this list: send the line "unsubscribe linux-pm" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 2015-10-12 at 18:26 +0100, Punit Agrawal wrote: > Mark Rutland <mark.rutland@arm.com> writes: > > > On Wed, Oct 07, 2015 at 08:22:40PM +0800, Dawei Chien wrote: > >> From: "Dawei.Chien" <dawei.chien@mediatek.com> > >> > >> This power model is base on Intelligent Power Allocation (IPA) technical, > >> requires that the operating-points of the CPUs are registered using the > >> kernel's opp library and the `cpufreq_frequency_table` is assigned to the > >> `struct device` of the cpu MT8173. > >> > >> Signed-off-by: Dawei.Chien <dawei.chien@mediatek.com> > >> --- > >> This patch is base on > >> https://patchwork.kernel.org/patch/7034601/ > >> --- > >> drivers/cpufreq/mt8173-cpufreq.c | 97 +++++++++++++++++++++++++++++++++----- > >> 1 file changed, 86 insertions(+), 11 deletions(-) > >> > >> diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c > >> index 49caed2..9233ec5 100644 > >> --- a/drivers/cpufreq/mt8173-cpufreq.c > >> +++ b/drivers/cpufreq/mt8173-cpufreq.c > >> @@ -28,7 +28,8 @@ > >> #define MAX_VOLT_SHIFT (200000) > >> #define MAX_VOLT_LIMIT (1150000) > >> #define VOLT_TOL (10000) > >> - > >> +#define CAPACITANCE_CA53 (263) > >> +#define CAPACITANCE_CA57 (530) > >> /* > >> * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS > >> * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in > >> @@ -51,6 +52,72 @@ struct mtk_cpu_dvfs_info { > >> bool need_voltage_tracking; > >> }; > >> > >> +struct mtk_cpu_static_power { > >> + unsigned long voltage; > >> + unsigned int power; > >> +}; > >> + > >> +/* measured by WA program. */ > >> +static const struct mtk_cpu_static_power mtk_ca53_static_power[] = { > >> + {859000, 43}, > >> + {908000, 52}, > >> + {983000, 86}, > >> + {1009000, 123}, > >> + {1028000, 138}, > >> + {1083000, 172}, > >> + {1109000, 180}, > >> + {1125000, 192}, > >> +}; > >> + > >> +/* measured by WA program. */ > >> +static const struct mtk_cpu_static_power mtk_ca57_static_power[] = { > >> + {828000, 72}, > >> + {867000, 90}, > >> + {927000, 156}, > >> + {968000, 181}, > >> + {1007000, 298}, > >> + {1049000, 435}, > >> + {1089000, 533}, > >> + {1125000, 533}, > >> +}; > > > > This should be described in the DT, rather than necessitating tonnes of > > these tables in the kernel. > > The above table is a simplification that is tying the static power of a > device to a voltage (indirectly via frequency for ease of indexing > perhaps). > > We should definitely look at describing the static power model in the > device tree - but it is not entirely clear what is the best model to > use as basis for the device tree bindings. > > Static power consumption depends on a few different parameters (silicon > process, voltage, temperature, etc.). The relationship between them > maybe non-linear and not all of these maybe significant for a given > platform. e.g., for Juno, we are using a regression based on voltage and > temperature which was deemed close enough (very subjective tbh). > > On the other hand, dynamic power consumption is somewhat simpler and I > have patches[0][1][2] enabling it's description in device tree. Your comments > there would be very much appreciated. > > As for this patch, I hope it can be moved to using the device tree when > the bindings for static power are agreed upon. Although sub-optimal, I > can't see any other way forward for now. > > [0] http://thread.gmane.org/gmane.linux.kernel/2011466/focus=130373 > [1] http://thread.gmane.org/gmane.linux.kernel/2011466/focus=2011465 > [2] http://article.gmane.org/gmane.linux.drivers.sensors/37859 Hi Mark/Punit, Thank you for your nice comments. I will resend this patch with device tree for dynamic/static power model, and refer to Punit's patches, thank you. > > > > Mark. > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-pm" in > > the body of a message to majordomo@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c index 49caed2..9233ec5 100644 --- a/drivers/cpufreq/mt8173-cpufreq.c +++ b/drivers/cpufreq/mt8173-cpufreq.c @@ -28,7 +28,8 @@ #define MAX_VOLT_SHIFT (200000) #define MAX_VOLT_LIMIT (1150000) #define VOLT_TOL (10000) - +#define CAPACITANCE_CA53 (263) +#define CAPACITANCE_CA57 (530) /* * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in @@ -51,6 +52,72 @@ struct mtk_cpu_dvfs_info { bool need_voltage_tracking; }; +struct mtk_cpu_static_power { + unsigned long voltage; + unsigned int power; +}; + +/* measured by WA program. */ +static const struct mtk_cpu_static_power mtk_ca53_static_power[] = { + {859000, 43}, + {908000, 52}, + {983000, 86}, + {1009000, 123}, + {1028000, 138}, + {1083000, 172}, + {1109000, 180}, + {1125000, 192}, +}; + +/* measured by WA program. */ +static const struct mtk_cpu_static_power mtk_ca57_static_power[] = { + {828000, 72}, + {867000, 90}, + {927000, 156}, + {968000, 181}, + {1007000, 298}, + {1049000, 435}, + {1089000, 533}, + {1125000, 533}, +}; + +unsigned int mtk_cpufreq_lookup_power(const struct mtk_cpu_static_power *table, + unsigned int count, unsigned long voltage) +{ + int i; + + for (i = 0; i < count; i++) { + if (voltage <= table[i].voltage) + return table[i].power; + } + + return table[count - 1].power; +} + +int mtk_cpufreq_get_static(cpumask_t *cpumask, int interval, + unsigned long voltage, u32 *power) +{ + int nr_cpus = cpumask_weight(cpumask); + + *power = 0; + + if (nr_cpus) { + + if (cpumask_test_cpu(0, cpumask)) + *power += mtk_cpufreq_lookup_power( + mtk_ca53_static_power, + ARRAY_SIZE(mtk_ca53_static_power), + voltage); + + if (cpumask_test_cpu(2, cpumask)) + *power += mtk_cpufreq_lookup_power( + mtk_ca57_static_power, + ARRAY_SIZE(mtk_ca57_static_power), + voltage); + } + return 0; +} + static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info, int new_vproc) { @@ -272,15 +339,21 @@ static void mtk_cpufreq_ready(struct cpufreq_policy *policy) return; if (of_find_property(np, "#cooling-cells", NULL)) { - info->cdev = of_cpufreq_cooling_register(np, - policy->related_cpus); - - if (IS_ERR(info->cdev)) { - dev_err(info->cpu_dev, - "running cpufreq without cooling device: %ld\n", - PTR_ERR(info->cdev)); - - info->cdev = NULL; + u32 capacitance = cpumask_test_cpu(0, policy->related_cpus) ? + CAPACITANCE_CA53 : CAPACITANCE_CA57; + + if (!info->cdev) { + info->cdev = of_cpufreq_power_cooling_register(np, + policy->related_cpus, + capacitance, + mtk_cpufreq_get_static); + + if (IS_ERR(info->cdev)) { + dev_err(info->cpu_dev, + "running cpufreq without cooling device: %ld\n", + PTR_ERR(info->cdev)); + info->cdev = NULL; + } } } @@ -460,7 +533,9 @@ static int mtk_cpufreq_exit(struct cpufreq_policy *policy) { struct mtk_cpu_dvfs_info *info = policy->driver_data; - cpufreq_cooling_unregister(info->cdev); + if (info->cdev) + cpufreq_cooling_unregister(info->cdev); + dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table); mtk_cpu_dvfs_info_release(info); kfree(info);