]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
dvfs: tegra21: Add core Vmax capping cooling device
authorAlex Frid <afrid@nvidia.com>
Wed, 4 Mar 2015 05:32:27 +0000 (21:32 -0800)
committerAleksandr Frid <afrid@nvidia.com>
Fri, 20 Mar 2015 01:48:10 +0000 (18:48 -0700)
Added core Vmax capping cooling device in DT, and parsed device data.
during Tegra DVFS initialization in kernel.

Utilized already existed core cap interface to apply pre-populated
rate limits for each voltage cap to scalable shared bus clocks. I/O
devices clocks are not scaled with temperature, and characterized at
maximum rate for the most aggressive core Vmax cap.

Bug 1588362
Bug 1580606

Change-Id: I396a9a4108f8f51640d9fbf5e6822d7712502995
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/718653
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
arch/arm64/boot/dts/tegra210-platforms/tegra210-ers-power-dvfs-e2174-1101-a00.dtsi
drivers/platform/tegra/tegra21_dvfs.c

index a6b2c0c5c62112945aa6415ceb5dfd8c1a7790fb..24129e06e9c7e0d69a4d4fc481732731204f5da2 100644 (file)
                        compatible = "nvidia,tegra210-dvfs-rail";
                        vdd_core-supply = <&max77620_sd0>;
                        vmin-cdev = <&core_vmin_cdev>;
+                       vmax-cdev = <&core_vmax_cdev>;
                };
 
                cpu_vmin_cdev: vdd-cpu-vmin-cdev@5 {
                        nvidia,constraint;
                        nvidia,trips = <&gpu_vmax1 1130>;
                };
+
+               core_vmax_cdev: vdd-core-vmax-cdev@10 {
+                       reg = <10>;
+                       cooling-min-state = <0>;
+                       cooling-max-state = <1>;
+                       #cooling-cells = <2>;
+                       compatible = "nvidia,tegra210-rail-vmax-cdev";
+                       cdev-type = "core_hot";
+                       nvidia,constraint;
+                       nvidia,trips = <&core_vmax1 1130>;
+               };
        };
 
        thermal-zones {
                };
                Tdiode_tegra {
                        SET_MAP_TRIP(core, core, vmin, 1, 20000);
+                       SET_MAP_TRIP(core, core, vmax, 1, 86000);
                };
                CPU-therm {
                        SET_MAP_TRIP(cpu, cpu, vmax, 1, 86000);
index b8fb380761c09e992645fed9adabdba258ff00c4..0e92a42ac5325afdab3f20422431bedb9b19b4b8 100644 (file)
@@ -47,6 +47,11 @@ static int vdd_core_therm_floors_table[MAX_THERMAL_LIMITS];
 static struct tegra_cooling_device core_vmin_cdev = {
        .compatible = "nvidia,tegra210-rail-vmin-cdev",
 };
+static int vdd_core_vmax_trips_table[MAX_THERMAL_LIMITS];
+static int vdd_core_therm_caps_table[MAX_THERMAL_LIMITS];
+static struct tegra_cooling_device core_vmax_cdev = {
+       .compatible = "nvidia,tegra210-rail-vmax-cdev",
+};
 
 static int vdd_cpu_vmin_trips_table[MAX_THERMAL_LIMITS];
 static int vdd_cpu_therm_floors_table[MAX_THERMAL_LIMITS];
@@ -96,6 +101,7 @@ static struct dvfs_rail tegra21_dvfs_rail_vdd_core = {
        .step = VDD_SAFE_STEP,
        .step_up = 1300,
        .vmin_cdev = &core_vmin_cdev,
+       .vmax_cdev = &core_vmax_cdev,
        .alignment = {
                .step_uv = 12500, /* 12.5mV */
        },
@@ -1006,7 +1012,7 @@ static int __init init_cpu_rail_thermal_profile(struct dvfs *cpu_dvfs)
 /*
  * CPU Vmax cooling device registration for pll mode:
  * - Use CPU capping method provided by CPUFREQ platform driver
- * - Skip registration if most aggressive cap is above maximum voltage
+ * - Skip registration if most aggressive cap is at/above maximum voltage
  */
 static int __init tegra21_dvfs_register_cpu_vmax_cdev(void)
 {
@@ -1322,7 +1328,7 @@ static void __init init_gpu_dvfs_table(int *gpu_max_freq_index)
  *   adjusted for each voltage cap trip-point (in case when GPU thermal
  *   scaling initialization failed, fall back on using WC rate limit across all
  *   thermal ranges).
- * - Skip registration if most aggressive cap is above maximum voltage
+ * - Skip registration if most aggressive cap is at/above maximum voltage
  */
 static int tegra21_gpu_volt_cap_apply(int *cap_idx, int new_idx, int level)
 {
@@ -1538,6 +1544,13 @@ static int __init init_core_rail_thermal_profile(void)
                        rail->vmin_cdev = NULL;
        }
 
+       if (rail->vmax_cdev) {
+               if (tegra_dvfs_rail_of_init_vmax_thermal_profile(
+                       vdd_core_vmax_trips_table, vdd_core_therm_caps_table,
+                       rail, NULL))
+                       rail->vmax_cdev = NULL;
+       }
+
        return 0;
 }
 
@@ -1722,9 +1735,22 @@ static struct core_bus_rates_table tegra21_gpu_rates_sysfs = {
                .attr = {.name = "gpu_time_at_user_rate", .mode = 0444} },
 };
 
+/*
+ * Core Vmax cooling device registration:
+ * - Use VDD_CORE capping method provided by DVFS
+ * - Skip registration if most aggressive cap is at/above maximum voltage
+ */
 static void __init tegra21_dvfs_register_core_vmax_cdev(void)
 {
-       /* FIXME: implement */
+       struct dvfs_rail *rail;
+
+       rail = &tegra21_dvfs_rail_vdd_core;
+       rail->apply_vmax_cap = tegra_dvfs_therm_vmax_core_cap_apply;
+       if (rail->vmax_cdev) {
+               int i = rail->vmax_cdev->trip_temperatures_num;
+               if (i && rail->therm_mv_caps[i-1] < rail->nominal_millivolts)
+                       tegra_dvfs_rail_register_vmax_cdev(rail);
+       }
 }
 
 /*