ARM: tegra: dvfs: Remove obsolete gpu_dvfs debugfs node
[linux-3.10.git] / arch / arm / mach-tegra / tegra12_dvfs.c
index 1d7af28..20967a4 100644 (file)
@@ -55,6 +55,10 @@ static struct tegra_cooling_device gpu_vmin_cdev = {
        .cdev_type = "gpu_cold",
 };
 
+static struct tegra_cooling_device gpu_vts_cdev = {
+       .cdev_type = "gpu_scaling",
+};
+
 static struct dvfs_rail tegra12_dvfs_rail_vdd_cpu = {
        .reg_id = "vdd_cpu",
        .max_millivolts = 1400,
@@ -85,6 +89,7 @@ static struct dvfs_rail tegra12_dvfs_rail_vdd_gpu = {
        .min_millivolts = 700,
        .step = VDD_SAFE_STEP,
        .in_band_pm = true,
+       .vts_cdev = &gpu_vts_cdev,
        .vmin_cdev = &gpu_vmin_cdev,
        .alignment = {
                .step_uv = 10000, /* 10mV */
@@ -239,13 +244,13 @@ static struct dvfs core_dvfs_table[] = {
 
         CORE_DVFS("emc",        -1, -1, 1, KHZ, 264000, 348000, 384000, 384000, 528000, 528000, 924000, 924000),
 
-        CORE_DVFS("cpu_lp",     0, 0, 1, KHZ,   396000, 528000, 660000, 804000, 912000, 1044000, 1140000, 1188000),
-        CORE_DVFS("cpu_lp",     0, 1, 1, KHZ,   420000, 564000, 696000, 828000, 960000, 1092000, 1188000, 1188000),
-        CORE_DVFS("cpu_lp",     1, -1, 1, KHZ,  420000, 564000, 696000, 828000, 960000, 1092000, 1188000, 1284000),
+        CORE_DVFS("cpu_lp",     0, 0, 1, KHZ,   396000, 528000, 660000, 804000, 912000, 1044000, 1140000, 1140000),
+        CORE_DVFS("cpu_lp",     0, 1, 1, KHZ,   420000, 564000, 696000, 828000, 960000, 1092000, 1140000, 1140000),
+        CORE_DVFS("cpu_lp",     1, -1, 1, KHZ,  420000, 564000, 696000, 828000, 960000, 1092000, 1188000, 1188000),
 
-        CORE_DVFS("sbus",       0, 0, 1, KHZ,   156000, 192000, 228000, 264000, 312000, 348000, 372000, 384000),
-        CORE_DVFS("sbus",       0, 1, 1, KHZ,   156000, 204000, 252000, 288000, 324000, 360000, 384000, 384000),
-        CORE_DVFS("sbus",       1, -1, 1, KHZ,  156000, 204000, 252000, 288000, 324000, 360000, 384000, 420000),
+        CORE_DVFS("sbus",       0, 0, 1, KHZ,   156000, 192000, 228000, 264000, 312000, 348000, 372000, 372000),
+        CORE_DVFS("sbus",       0, 1, 1, KHZ,   156000, 204000, 252000, 288000, 324000, 360000, 372000, 372000),
+        CORE_DVFS("sbus",       1, -1, 1, KHZ,  156000, 204000, 252000, 288000, 324000, 360000, 384000, 384000),
 
         CORE_DVFS("vic03",      0, 0, 1, KHZ,   228000, 324000, 408000, 492000, 588000, 660000, 708000, 756000),
         CORE_DVFS("vic03",      0, 1, 1, KHZ,   228000, 336000, 420000, 504000, 600000, 684000, 756000, 756000),
@@ -267,9 +272,9 @@ static struct dvfs core_dvfs_table[] = {
         CORE_DVFS("vde",        0, 1, 1, KHZ,   168000, 228000, 276000, 348000, 396000, 444000, 480000, 480000),
         CORE_DVFS("vde",        1, -1, 1, KHZ,  168000, 228000, 276000, 348000, 396000, 444000, 480000, 528000),
 
-        CORE_DVFS("host1x",     0, 0, 1, KHZ,   108000, 156000, 204000, 240000, 348000, 372000, 408000, 432000),
-        CORE_DVFS("host1x",     0, 1, 1, KHZ,   108000, 156000, 204000, 252000, 348000, 384000, 432000, 432000),
-        CORE_DVFS("host1x",     1, -1, 1, KHZ,  108000, 156000, 204000, 252000, 348000, 384000, 444000, 456000),
+        CORE_DVFS("host1x",     0, 0, 1, KHZ,   108000, 156000, 204000, 240000, 348000, 372000, 408000, 408000),
+        CORE_DVFS("host1x",     0, 1, 1, KHZ,   108000, 156000, 204000, 252000, 348000, 384000, 408000, 408000),
+        CORE_DVFS("host1x",     1, -1, 1, KHZ,  108000, 156000, 204000, 252000, 348000, 384000, 444000, 444000),
 
         CORE_DVFS("vi",         0, 0, 1, KHZ,   300000, 408000, 480000, 600000, 600000, 600000, 600000, 600000),
         CORE_DVFS("vi",         0, 1, 1, KHZ,   300000, 420000, 480000, 600000, 600000, 600000, 600000, 600000),
@@ -313,7 +318,7 @@ static struct dvfs core_dvfs_table[] = {
        OVRRD_DVFS("sdmmc3", -1, -1, 1, KHZ,  100000, 100000, 100000, 100000,  136000, 136000, 136000, 204000),
        OVRRD_DVFS("sdmmc4", -1, -1, 1, KHZ,  102000, 102000, 102000, 102000,  136000, 136000, 136000, 200000),
 
-       CORE_DVFS("hdmi",   -1, -1, 1, KHZ,   148500, 148500, 148500, 297000,  297000, 297000, 297000, 297000),
+       CORE_DVFS("hdmi",   -1, -1, 1, KHZ,        1, 148500, 148500, 297000,  297000, 297000, 297000, 297000),
        /* FIXME: Finalize these values for NOR after qual */
        CORE_DVFS("nor",    -1, -1, 1, KHZ,   102000, 102000, 102000, 102000,  102000, 102000, 102000, 102000),
 
@@ -327,23 +332,14 @@ static struct dvfs core_dvfs_table[] = {
         */
         CORE_DVFS("disp1",       0, 0, 0, KHZ,   148500, 241000, 297000, 297000, 297000, 474000, 474000, 474000),
         CORE_DVFS("disp1",       0, 1, 0, KHZ,   148500, 241000, 297000, 297000, 474000, 474000, 474000, 474000),
-        CORE_DVFS("disp1",       1, -1, 0, KHZ,  148500, 241000, 297000, 297000, 474000, 474000, 474000, 474000),
+        CORE_DVFS("disp1",       1, -1, 0, KHZ,  148500, 241000, 297000, 297000, 474000, 474000, 474000, 533000),
 
         CORE_DVFS("disp2",       0, 0, 0, KHZ,   148500, 241000, 297000, 297000, 297000, 474000, 474000, 474000),
         CORE_DVFS("disp2",       0, 1, 0, KHZ,   148500, 241000, 297000, 297000, 474000, 474000, 474000, 474000),
-        CORE_DVFS("disp2",       1, -1, 0, KHZ,  148500, 241000, 297000, 297000, 474000, 474000, 474000, 474000),
-
-       /* Core voltages (mV):                          800,    850,    900,     950,    1000,  1050,    1100,   1150 */
-       /* xusb clocks */
-       CORE_DVFS("xusb_falcon_src", -1, -1, 1, KHZ,  336000, 336000, 336000, 336000, 336000, 336000,  336000,  336000),
-       CORE_DVFS("xusb_host_src",   -1, -1, 1, KHZ,  112000, 112000, 112000, 112000, 112000, 112000,  112000,  112000),
-       CORE_DVFS("xusb_dev_src",    -1, -1, 1, KHZ,   58300,  58300,  58300,  58300, 112000, 112000,  112000,  112000),
-       CORE_DVFS("xusb_ss_src",     -1, -1, 1, KHZ,  120000, 120000, 120000, 120000, 120000, 120000,  120000,  120000),
-       CORE_DVFS("xusb_fs_src",     -1, -1, 1, KHZ,   48000,  48000,  48000,  48000,  48000,  48000,   48000,   48000),
-       CORE_DVFS("xusb_hs_src",     -1, -1, 1, KHZ,   60000,  60000,  60000,  60000,  60000,  60000,   60000,   60000),
+        CORE_DVFS("disp2",       1, -1, 0, KHZ,  148500, 241000, 297000, 297000, 474000, 474000, 474000, 533000),
+
 };
 
-/* TBD: fill in actual hw numbers */
 static struct gpu_cvb_dvfs gpu_cvb_dvfs_table[] = {
        {
                .speedo_id =   0,
@@ -352,23 +348,25 @@ static struct gpu_cvb_dvfs gpu_cvb_dvfs_table[] = {
                .min_mv = 800,
                .freqs_mult = KHZ,
                .speedo_scale = 100,
+               .thermal_scale = 10,
                .voltage_scale = 1000,
                .cvb_table = {
-                       /*f        dfll  pll:   c0,     c1,   c2 */
-                       {   72000, {  }, {  975248, -10755,  -56}, },
-                       {  108000, {  }, {  995948, -11645,  -56}, },
-                       {  180000, {  }, { 1041350, -13415,  -56}, },
-                       {  252000, {  }, { 1092088, -15195,  -56}, },
-                       {  324000, {  }, { 1148163, -16975,  -56}, },
-                       {  396000, {  }, { 1209574, -18745,  -56}, },
-                       {  468000, {  }, { 1276322, -20525,  -56}, },
-                       {  540000, {  }, { 1348406, -22295,  -56}, },
-                       {  612000, {  }, { 1425827, -24075,  -56}, },
-                       {  648000, {  }, { 1466538, -24965,  -56}, },
-                       {       0, {  }, {       0,      0,   0}, },
+                       /*f        dfll  pll:   c0,     c1,   c2,   c3,      c4,   c5 */
+                       {   72000, {  }, { 1013806, -14060, -127,   954, -27008,  781}, },
+                       {  108000, {  }, {  983062,  -9373, -263,   954, -26703,  650}, },
+                       {  180000, {  }, { 1040909, -12008, -224,   775, -23193,  376}, },
+                       {  252000, {  }, { 1150002, -20683,  -17,   298, -13428,  232}, },
+                       {  324000, {  }, { 1081549, -10827, -274,   179, -10681,  238}, },
+                       {  396000, {  }, { 1136931, -12086, -274,   119, -10071,  238}, },
+                       {  468000, {  }, { 1195664, -13329, -274,    60,  -8850,  221}, },
+                       {  540000, {  }, { 1257766, -14587, -274,     0,  -7019,  179}, },
+                       {  612000, {  }, { 1323069, -15830, -274,     0,  -4578,  113}, },
+                       {  648000, {  }, { 1356986, -16459, -274,     0,  -3204,   72}, },
+                       {       0, {  }, { }, },
                },
                .vmin_trips_table = { 20, },
                .therm_floors_table = { 900, },
+               .vts_trips_table = { -10, 10, 30, 50, 70, },
        },
        {
                .speedo_id =   1,
@@ -377,47 +375,40 @@ static struct gpu_cvb_dvfs gpu_cvb_dvfs_table[] = {
                .min_mv = 800,
                .freqs_mult = KHZ,
                .speedo_scale = 100,
+               .thermal_scale = 10,
                .voltage_scale = 1000,
                .cvb_table = {
-                       /*f        dfll  pll:   c0,     c1,   c2 */
-                       {   72000, {  }, {  975248, -10755,  -56}, },
-                       {  108000, {  }, {  995948, -11645,  -56}, },
-                       {  180000, {  }, { 1041350, -13415,  -56}, },
-                       {  252000, {  }, { 1092088, -15195,  -56}, },
-                       {  324000, {  }, { 1148163, -16975,  -56}, },
-                       {  396000, {  }, { 1209574, -18745,  -56}, },
-                       {  468000, {  }, { 1276322, -20525,  -56}, },
-                       {  540000, {  }, { 1348406, -22295,  -56}, },
-                       {  612000, {  }, { 1425827, -24075,  -56}, },
-                       {  648000, {  }, { 1466538, -24965,  -56}, },
-                       {  684000, {  }, { 1508583, -25855,  -56}, },
-                       {  708000, {  }, { 1537355, -26445,  -56}, },
-                       {  756000, {  }, { 1596677, -27625,  -56}, },
-                       {  804000, {  }, { 1658370, -28815,  -56}, },
-                       {       0, {  }, {       0,      0,   0}, },
+                       /*f        dfll  pll:   c0,     c1,   c2,   c3,      c4,   c5 */
+                       {   72000, {  }, { 1013806, -14060, -127,   954, -27008,  781}, },
+                       {  108000, {  }, {  983062,  -9373, -263,   954, -26703,  650}, },
+                       {  180000, {  }, { 1040909, -12008, -224,   775, -23193,  376}, },
+                       {  252000, {  }, { 1150002, -20683,  -17,   298, -13428,  232}, },
+                       {  324000, {  }, { 1081549, -10827, -274,   179, -10681,  238}, },
+                       {  396000, {  }, { 1136931, -12086, -274,   119, -10071,  238}, },
+                       {  468000, {  }, { 1195664, -13329, -274,    60,  -8850,  221}, },
+                       {  540000, {  }, { 1257766, -14587, -274,     0,  -7019,  179}, },
+                       {  612000, {  }, { 1323069, -15830, -274,     0,  -4578,  113}, },
+                       {  648000, {  }, { 1356986, -16459, -274,     0,  -3204,   72}, },
+                       {  684000, {  }, { 1391884, -17078, -274,   -60,  -1526,   30}, },
+                       {  708000, {  }, { 1415522, -17497, -274,   -60,   -458,    0}, },
+                       {  756000, {  }, { 1464061, -18331, -274,  -119,   1831,  -72}, },
+                       {  804000, {  }, { 1524225, -20064, -254,  -119,   4272, -155}, },
+                       {  852000, {  }, { 1608418, -21643, -269,     0,    763,  -48}, },
+                       {       0, {  }, { }, },
                },
                .vmin_trips_table = { 20, },
                .therm_floors_table = { 900, },
+               .vts_trips_table = { -10, 10, 30, 50, 70, },
        }
 };
 
-static int gpu_millivolts[MAX_DVFS_FREQS];
+static int gpu_millivolts[MAX_THERMAL_RANGES][MAX_DVFS_FREQS];
 static struct dvfs gpu_dvfs = {
        .clk_name       = "gbus",
-       .millivolts     = gpu_millivolts,
        .auto_dvfs      = true,
        .dvfs_rail      = &tegra12_dvfs_rail_vdd_gpu,
 };
 
-int read_gpu_dvfs_table(int **millivolts, unsigned long **freqs)
-{
-       *millivolts = gpu_dvfs.millivolts;
-       *freqs = gpu_dvfs.freqs;
-
-       return 0;
-}
-EXPORT_SYMBOL(read_gpu_dvfs_table);
-
 int tegra_dvfs_disable_core_set(const char *arg, const struct kernel_param *kp)
 {
        int ret;
@@ -582,6 +573,19 @@ static inline int get_cvb_voltage(int speedo, int s_scale,
        return mv;
 }
 
+/* cvb_t_mv =
+   ((c3 * speedo / s_scale + c4 + c5 * T / t_scale) * T / t_scale) / v_scale */
+static inline int get_cvb_t_voltage(int speedo, int s_scale, int t, int t_scale,
+                                   struct cvb_dvfs_parameters *cvb)
+{
+       /* apply speedo & temperature scales: output mv = cvb_t_mv * v_scale */
+       int mv;
+       mv = DIV_ROUND_CLOSEST(cvb->c3 * speedo, s_scale) + cvb->c4 +
+               DIV_ROUND_CLOSEST(cvb->c5 * t, t_scale);
+       mv = DIV_ROUND_CLOSEST(mv * t, t_scale);
+       return mv;
+}
+
 static int round_cvb_voltage(int mv, int v_scale, struct rail_alignment *align)
 {
        /* combined: apply voltage scale and round to cvb alignment step */
@@ -725,16 +729,32 @@ static int __init set_cpu_dvfs_data(
 static int __init set_gpu_dvfs_data(
        struct gpu_cvb_dvfs *d, struct dvfs *gpu_dvfs, int *max_freq_index)
 {
-       int i, mv;
+       int i, j, thermal_ranges, mv;
        struct cvb_dvfs_table *table = NULL;
        int speedo = tegra_gpu_speedo_value();
-       struct rail_alignment *align = &tegra12_dvfs_rail_vdd_gpu.alignment;
+       struct dvfs_rail *rail = &tegra12_dvfs_rail_vdd_gpu;
+       struct rail_alignment *align = &rail->alignment;
 
        d->max_mv = round_voltage(d->max_mv, align, false);
        d->min_mv = round_voltage(d->min_mv, align, true);
        BUG_ON(d->min_mv < tegra12_dvfs_rail_vdd_gpu.min_millivolts);
 
        /*
+        * Init thermal trips, find number of thermal ranges; note that the
+        * first trip-point is used for voltage calculations within the lowest
+        * range, but should not be actually set. Hence, at least 2 trip-points
+        * must be specified.
+        */
+       if (tegra_dvfs_rail_init_thermal_dvfs_trips(d->vts_trips_table, rail))
+               return -ENOENT;
+       thermal_ranges = rail->vts_cdev->trip_temperatures_num;
+       rail->vts_cdev->trip_temperatures_num--;
+
+       if (thermal_ranges < 2)
+               WARN(1, "tegra12_dvfs: %d gpu trip: thermal dvfs is broken\n",
+                    thermal_ranges);
+
+       /*
         * Use CVB table to fill in gpu dvfs frequencies and voltages. Each
         * CVB entry specifies gpu frequency and CVB coefficients to calculate
         * the respective voltage.
@@ -746,29 +766,56 @@ static int __init set_gpu_dvfs_data(
 
                mv = get_cvb_voltage(
                        speedo, d->speedo_scale, &table->cvb_pll_param);
-               mv = round_cvb_voltage(mv, d->voltage_scale, align);
 
-               if (mv > d->max_mv)
+               for (j = 0; j < thermal_ranges; j++) {
+                       int mvj = mv;
+                       int t = rail->vts_cdev->trip_temperatures[j];
+
+                       /* get thermal offset for this trip-point */
+                       mvj += get_cvb_t_voltage(speedo, d->speedo_scale,
+                               t, d->thermal_scale, &table->cvb_pll_param);
+                       mvj = round_cvb_voltage(mvj, d->voltage_scale, align);
+
+                       /* clip to minimum, abort if above maximum */
+                       mvj = max(mvj, d->min_mv);
+                       if (mvj > d->max_mv)
+                               break;
+
+                       /* update voltage for adjacent ranges bounded by this
+                          trip-point (cvb & dvfs are transpose matrices) */
+                       gpu_millivolts[j][i] = mvj;
+                       if (j && (gpu_millivolts[j-1][i] < mvj))
+                               gpu_millivolts[j-1][i] = mvj;
+               }
+               /* Make sure all voltages for this frequency are below max */
+               if (j < thermal_ranges)
                        break;
 
                /* fill in gpu dvfs tables */
-               mv = max(mv, d->min_mv);
-               gpu_millivolts[i] = mv;
                gpu_dvfs->freqs[i] = table->freq;
        }
-       /* Table must not be empty, must have at least one entry in range */
-       if (!i || (gpu_millivolts[i - 1] <
-                  tegra12_dvfs_rail_vdd_gpu.min_millivolts)) {
-               pr_err("tegra14_dvfs: invalid gpu dvfs table\n");
+
+       /*
+        * Table must not be empty, must have at least one entry in range, and
+        * must specify monotonically increasing voltage on frequency dependency
+        * in each temperature range.
+        */
+       if (!i || tegra_dvfs_init_thermal_dvfs_voltages(
+               &gpu_millivolts[0][0], i, thermal_ranges, gpu_dvfs)) {
+               pr_err("tegra12_dvfs: invalid gpu dvfs table\n");
                return -ENOENT;
        }
 
+       /* Shift out the 1st trip-point */
+       for (j = 1; j < thermal_ranges; j++)
+               rail->vts_cdev->trip_temperatures[j - 1] =
+               rail->vts_cdev->trip_temperatures[j];
+
        /* dvfs tables are successfully populated - fill in the gpu dvfs */
        gpu_dvfs->speedo_id = d->speedo_id;
        gpu_dvfs->process_id = d->process_id;
        gpu_dvfs->freqs_mult = d->freqs_mult;
-       gpu_dvfs->dvfs_rail->nominal_millivolts =
-               min(d->max_mv, gpu_millivolts[i - 1]);
+       gpu_dvfs->dvfs_rail->nominal_millivolts = d->max_mv;
 
        *max_freq_index = i - 1;
 
@@ -975,14 +1022,14 @@ static struct core_dvfs_cap_table tegra12_core_cap_table[] = {
 static struct core_bus_limit_table tegra12_gpu_cap_syfs = {
        .limit_clk_name = "cap.profile.gbus",
        .refcnt_attr = {.attr = {.name = "gpu_cap_state", .mode = 0644} },
-       .level_attr  = {.attr = {.name = "gpu_cap_level", .mode = 0644} },
+       .level_attr  = {.attr = {.name = "gpu_cap_rate", .mode = 0644} },
        .pm_qos_class = PM_QOS_GPU_FREQ_MAX,
 };
 
 static struct core_bus_limit_table tegra12_gpu_floor_sysfs = {
        .limit_clk_name = "floor.profile.gbus",
        .refcnt_attr = {.attr = {.name = "gpu_floor_state", .mode = 0644} },
-       .level_attr  = {.attr = {.name = "gpu_floor_level", .mode = 0644} },
+       .level_attr  = {.attr = {.name = "gpu_floor_rate", .mode = 0644} },
        .pm_qos_class = PM_QOS_GPU_FREQ_MIN,
 };