Skip to content

Commit 4f5892b

Browse files
Alex FridRohan Somvanshi
Alex Frid
authored and
Rohan Somvanshi
committed
ARM: tegra: dvfs: Add cold zone Tegra3 CPU dvfs limits
Added alternative frequency limits for Tegra3 CPU. These limits are applied only in the lowest CPU EDP temperature zone, and the offset from regular Tegra3 dvfs frequencies is set at -50MHz at all scaling voltage steps. Offset values as well as temperature threshold are to be updated per characterization. Bug 913884 Change-Id: Ia420f54b4c9fdc966e44d0269d45d9164d751b5f Signed-off-by: Alex Frid <[email protected]> Reviewed-on: http://git-master/r/70189 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Diwakar Tundlam <[email protected]> Tested-by: Diwakar Tundlam <[email protected]> Reviewed-by: Krishna Reddy <[email protected]> Reviewed-on: http://git-master/r/75615 Reviewed-by: Varun Wadekar <[email protected]> Tested-by: Varun Wadekar <[email protected]>
1 parent 732dd0e commit 4f5892b

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

arch/arm/mach-tegra/cpu-tegra.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#include "clock.h"
4343
#include "cpu-tegra.h"
44+
#include "dvfs.h"
4445

4546
/* tegra throttling and edp governors require frequencies in the table
4647
to be in ascending order */
@@ -226,11 +227,14 @@ int tegra_edp_update_thermal_zone(int temperature)
226227
mutex_lock(&tegra_cpu_lock);
227228
edp_thermal_index = index;
228229

229-
/* Update cpu rate if cpufreq (at least on cpu0) is already started */
230+
/* Update cpu rate if cpufreq (at least on cpu0) is already started;
231+
alter cpu dvfs table for this thermal zone if necessary */
232+
tegra_cpu_dvfs_alter(edp_thermal_index, true);
230233
if (target_cpu_speed[0]) {
231234
edp_update_limit();
232235
tegra_cpu_set_speed_cap(NULL);
233236
}
237+
tegra_cpu_dvfs_alter(edp_thermal_index, false);
234238
mutex_unlock(&tegra_cpu_lock);
235239

236240
return ret;

arch/arm/mach-tegra/dvfs.h

+4
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ int tegra_dvfs_predict_millivolts(struct clk *c, unsigned long rate);
125125
void tegra_dvfs_core_cap_enable(bool enable);
126126
void tegra_dvfs_core_cap_level_set(int level);
127127
int tegra_dvfs_alt_freqs_set(struct dvfs *d, bool enable);
128+
void tegra_cpu_dvfs_alter(int edp_thermal_index, bool before_clk_update);
128129
#else
129130
static inline void tegra_soc_init_dvfs(void)
130131
{}
@@ -161,6 +162,9 @@ static inline void tegra_dvfs_core_cap_level_set(int level)
161162
{}
162163
static inline int tegra_dvfs_alt_freqs_set(struct dvfs *d, bool enable)
163164
{ return 0; }
165+
static inline void tegra_cpu_dvfs_alter(int edp_thermal_index,
166+
bool before_clk_update)
167+
{}
164168
#endif
165169

166170
#ifndef CONFIG_ARCH_TEGRA_2x_SOC

arch/arm/mach-tegra/tegra3_dvfs.c

+41-1
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@
3030

3131
static bool tegra_dvfs_cpu_disabled;
3232
static bool tegra_dvfs_core_disabled;
33+
static struct dvfs *cpu_dvfs;
3334

3435
static const int cpu_millivolts[MAX_DVFS_FREQS] = {
3536
800, 825, 850, 875, 900, 912, 975, 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1212, 1237};
3637

38+
static const unsigned int cpu_cold_offs_mhz[MAX_DVFS_FREQS] = {
39+
50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50};
40+
3741
static const int core_millivolts[MAX_DVFS_FREQS] =
3842
{1000, 1050, 1100, 1150, 1200, 1250, 1300};
3943

@@ -422,6 +426,31 @@ static void __init init_dvfs_one(struct dvfs *d, int nominal_mv_index)
422426
}
423427
}
424428

429+
static void __init init_dvfs_cold(struct dvfs *d, int nominal_mv_index)
430+
{
431+
int i;
432+
unsigned long offs;
433+
434+
BUG_ON((nominal_mv_index == 0) || (nominal_mv_index > d->num_freqs));
435+
436+
for (i = 0; i < d->num_freqs; i++) {
437+
offs = cpu_cold_offs_mhz[i] * MHZ;
438+
if (i > nominal_mv_index)
439+
d->alt_freqs[i] = d->alt_freqs[i - 1];
440+
else if (d->freqs[i] > offs)
441+
d->alt_freqs[i] = d->freqs[i] - offs;
442+
else {
443+
d->alt_freqs[i] = d->freqs[i];
444+
pr_warn("tegra3_dvfs: cold offset %lu is too high for"
445+
" regular dvfs limit %lu\n", offs, d->freqs[i]);
446+
}
447+
448+
if (i)
449+
BUG_ON(d->alt_freqs[i] < d->alt_freqs[i - 1]);
450+
}
451+
d->alt_freqs_state = ALT_FREQS_DISABLED;
452+
}
453+
425454
static bool __init match_dvfs_one(struct dvfs *d, int speedo_id, int process_id)
426455
{
427456
if ((d->process_id != -1 && d->process_id != process_id) ||
@@ -535,7 +564,6 @@ void __init tegra_soc_init_dvfs(void)
535564
int i;
536565
int core_nominal_mv_index;
537566
int cpu_nominal_mv_index;
538-
struct dvfs *cpu_dvfs = NULL;
539567

540568
#ifndef CONFIG_TEGRA_CORE_DVFS
541569
tegra_dvfs_core_disabled = true;
@@ -581,6 +609,7 @@ void __init tegra_soc_init_dvfs(void)
581609
/* Initialize matching cpu dvfs entry already found when nominal
582610
voltage was determined */
583611
init_dvfs_one(cpu_dvfs, cpu_nominal_mv_index);
612+
init_dvfs_cold(cpu_dvfs, cpu_nominal_mv_index);
584613

585614
/* Finally disable dvfs on rails if necessary */
586615
if (tegra_dvfs_core_disabled)
@@ -596,6 +625,17 @@ void __init tegra_soc_init_dvfs(void)
596625
tegra_dvfs_core_disabled ? "disabled" : "enabled");
597626
}
598627

628+
void tegra_cpu_dvfs_alter(int edp_thermal_index, bool before_clk_update)
629+
{
630+
bool enable = !edp_thermal_index;
631+
632+
if (enable != before_clk_update) {
633+
int ret = tegra_dvfs_alt_freqs_set(cpu_dvfs, enable);
634+
WARN_ONCE(ret, "tegra dvfs: failed to set CPU alternative"
635+
" frequency limits for cold temeperature\n");
636+
}
637+
}
638+
599639
int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail)
600640
{
601641
int ret = 0;

0 commit comments

Comments
 (0)