arm: tegra12: support for embedded 0x80 SKU
Bibek Basu [Fri, 28 Nov 2014 09:05:35 +0000 (14:05 +0530)]
Added DVFS support for CD575MI SKU 0x80
CPU DVFS: Max Freq 2116Mhz. Switch to PLLX below 0 DegC
          and fixed voltage
SOC DVFS: Vmax @ 1100mv constant below 0 DegC
          EMC dvfs max freq 924Mhz
GPU DVFS: Max Freq 924Mhz and thermal bump up of voltage
          by 50mv below 0 DegC. Max gpu freq below 0degC
  is 852Mhz

Bug 1563635

Change-Id: Ic55654c36ed39b96a1262b7243a51d8eaad1b894
Signed-off-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-on: http://git-master/r/657110
Reviewed-by: Aleksandr Frid <afrid@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Matthew Pedro <mapedro@nvidia.com>

arch/arm/mach-tegra/edp.c
arch/arm/mach-tegra/tegra12_dvfs.c
arch/arm/mach-tegra/tegra12_edp.c
arch/arm/mach-tegra/tegra12_speedo.c

index df8c8dc..6ac0f3f 100644 (file)
@@ -868,6 +868,8 @@ static int init_gpu_edp_limits_calculated(void)
                        gpu_temperatures[i];
                if (gpu_temperatures[i] == 0 && tegra_gpu_speedo_id() == 5)
                        limit = 708000;
+               else if (gpu_temperatures[i] == 0 && tegra_gpu_speedo_id() == 6)
+                       limit = 852000;
                else
                        limit = gpu_edp_calculate_maxf(params,
                                               gpu_temperatures[i],
index 5a84918..145e990 100644 (file)
@@ -51,8 +51,11 @@ static int vdd_core_therm_floors_table[MAX_THERMAL_LIMITS] = { 950, };
 static int vdd_core_vmax_trips_table[MAX_THERMAL_LIMITS] = { 62,   72,   82, };
 static int vdd_core_therm_caps_table[MAX_THERMAL_LIMITS] = { 1130, 1100, 1060, };
 
-static int vdd_core_vmax_trips_table_sku80[] = { -40, 0, };
-static int vdd_core_therm_caps_table_sku80[] = { 950, 1000, };
+static int vdd_core_vmax_trips_table_sku80_alwayson[MAX_THERMAL_LIMITS] = { -40, 0, };
+static int vdd_core_therm_caps_table_sku80_alwayson[MAX_THERMAL_LIMITS] = { 950, 1000, };
+
+static int vdd_core_vmax_trips_table_sku80[MAX_THERMAL_LIMITS] = { -40, 0, 70};
+static int vdd_core_therm_caps_table_sku80[MAX_THERMAL_LIMITS] = { 1000, 1100, 1050 };
 
 #ifndef CONFIG_TEGRA_CPU_VOLT_CAP
 static int vdd_cpu_vmax_trips_table[MAX_THERMAL_LIMITS] = { 62,   72,   82, };
@@ -155,8 +158,8 @@ void __init tegra12x_vdd_cpu_align(int step_uv, int offset_uv)
 
 /* CPU DVFS tables */
 static unsigned long cpu_max_freq[] = {
-/* speedo_id   0        1        2        3        4        5        6         7       */
-               2014500, 2320500, 2116500, 2524500, 1811000, 2218500, 1938000, 1912500,
+/* speedo_id   0        1        2        3        4        5        6         7        8*/
+               2014500, 2320500, 2116500, 2524500, 1811000, 2218500, 1938000, 1912500, 2140000,
 };
 
 static struct cpu_cvb_dvfs cpu_cvb_dvfs_table[] = {
@@ -192,7 +195,7 @@ static struct cpu_cvb_dvfs cpu_cvb_dvfs_table[] = {
                 */
                .clk_switch_trips = {34,}
        },
-       /* Entry for Embedded SKU CD575MI */
+       /* Entry for Embedded SKU CD575MI Always On*/
        {
                .speedo_id = 7,
                .process_id = -1,
@@ -236,6 +239,52 @@ static struct cpu_cvb_dvfs cpu_cvb_dvfs_table[] = {
                 */
                .clk_switch_trips = {0,}
        },
+       /* Entry for Embedded SKU CD575MI */
+       {
+               .speedo_id = 8,
+               .process_id = -1,
+               .dfll_tune_data  = {
+                       .tune0          = 0x005020FF,
+                       .tune0_high_mv  = 0x005040FF,
+                       .tune1          = 0x00000060,
+                       .droop_rate_min = 1000000,
+                       .tune_high_min_millivolts = 900,
+                       .min_millivolts = 720,
+               },
+               .max_mv = 1210,
+               .freqs_mult = KHZ,
+               .speedo_scale = 100,
+               .voltage_scale = 1000,
+               .cvb_table = {
+                       /*f       dfll: c0,     c1,   c2  pll:  c0,   c1,    c2 */
+                       {204000,        {1112619, -29295, 402}, {800000, 0, 0}},
+                       {306000,        {1150460, -30585, 402}, {800000, 0, 0}},
+                       {408000,        {1190122, -31865, 402}, {800000, 0, 0}},
+                       {510000,        {1231606, -33155, 402}, {800000, 0, 0}},
+                       {612000,        {1274912, -34435, 402}, {800000, 0, 0}},
+                       {714000,        {1320040, -35725, 402}, {800000, 0, 0}},
+                       {816000,        {1366990, -37005, 402}, {820000, 0, 0}},
+                       {918000,        {1415762, -38295, 402}, {840000, 0, 0}},
+                       {1020000,       {1466355, -39575, 402}, {880000, 0, 0}},
+                       {1122000,       {1518771, -40865, 402}, {900000, 0, 0}},
+                       {1224000,       {1573009, -42145, 402}, {930000, 0, 0}},
+                       {1326000,       {1629068, -43435, 402}, {960000, 0, 0}},
+                       {1428000,       {1686950, -44715, 402}, {990000, 0, 0}},
+                       {1530000,       {1746653, -46005, 402}, {1020000, 0, 0}},
+                       {1632000,       {1808179, -47285, 402}, {1070000, 0, 0}},
+                       {1734000,       {1871526, -48575, 402}, {1100000, 0, 0}},
+                       {1836000,       {1936696, -49855, 402}, {1140000, 0, 0}},
+                       {1938000,       {2003687, -51145, 402}, {1180000, 0, 0}},
+                       {2014500,       {2054787, -52095, 402}, {1220000, 0, 0}},
+                       {2116500,       {2124957, -53385, 402}, {1260000, 0, 0}},
+                       {      0 ,      {      0,      0,   0}, {}},
+               },
+               /*
+                * < 0 : Set CPU clock source as PLLX
+                * > 0 : Set CPU clock source as DFLL
+                */
+               .clk_switch_trips = {0,}
+       },
        {
                .speedo_id = -1,
                .process_id = -1,
@@ -434,7 +483,8 @@ static struct dvfs core_dvfs_table[] = {
        OVRRD_DVFS("sdmmc4",         -1, -1, 1, KHZ,      1,      1,  82000,  82000,  136000, 136000, 136000,  136000,  200000),
 };
 
-static struct dvfs core_dvfs_table_embedded[] = {
+/* CD575MI Always On Personality */
+static struct dvfs core_dvfs_table_embedded_alwayson[] = {
        /* Core voltages (mV):                   800,    850,    900,    950,    1000 */
        /* Clock limits for internal blocks, PLLs */
 
@@ -504,6 +554,77 @@ static struct dvfs core_dvfs_table_embedded[] = {
        OVRRD_DVFS("sdmmc4",         3, -1, 1, KHZ,      1,      1,       1,    82000,          136000),
 };
 
+/* CD575MI */
+static struct dvfs core_dvfs_table_embedded[] = {
+       /* Core voltages (mV):                   800,    850,    900,    950,    1000,   1050,    1100  */
+       /* Clock limits for internal blocks, PLLs */
+
+       CORE_DVFS("emc",        4, -1, 1, KHZ, 1,      1,      1,      1,       792000,  792000, 924000),
+
+        CORE_DVFS("cpu_lp",     4, -1, 1, KHZ,  1,      1,      1,      1,     1044000, 1044000, 1044000),
+
+        CORE_DVFS("sbus",       4, -1, 1, KHZ,  1,      1,      1,      1,     348000, 348000, 372000),
+
+       CORE_DVFS("vic03",      4, -1, 1, KHZ,  1,      1,      1,      1,      660000, 660000, 708000),
+
+       CORE_DVFS("tsec",       4, -1, 1, KHZ,  1,      1,      1,      1,      660000, 660000, 708000),
+
+       CORE_DVFS("msenc",      4, -1, 1, KHZ,  1,      1,      1,      1,      432000, 432000, 456000),
+
+       CORE_DVFS("se",         4, -1, 1, KHZ,  1,      1,      1,      1,      432000, 432000, 456000),
+
+       CORE_DVFS("vde",        4, -1, 1, KHZ,  1,      1,      1,      1,      432000, 432000, 456000),
+
+        CORE_DVFS("host1x",     4, -1, 1, KHZ,  1,      1,      1,      1,     372000, 372000, 408000),
+
+       CORE_DVFS("vi",         4, -1, 1, KHZ,  1,      1,      1,      1,      600000, 600000, 600000),
+
+       CORE_DVFS("isp",        4, -1, 1, KHZ,  1,      1,      1,      1,      600000, 600000, 600000),
+
+#ifdef CONFIG_TEGRA_DUAL_CBUS
+        CORE_DVFS("c2bus",      4, -1, 1, KHZ,  1,      1,      1,      1,     432000, 432000, 456000),
+
+        CORE_DVFS("c3bus",      4, -1, 1, KHZ,  1,      1,      1,      1,     660000, 660000, 708000),
+#else
+       CORE_DVFS("cbus",      4, -1, 1, KHZ,  1,      1,      1,      1,       216000, 216000, 372000),
+#endif
+
+       CORE_DVFS("c4bus",      4, -1, 1, KHZ,  1,      1,      1,      1,      600000, 600000, 600000),
+
+       CORE_DVFS("pll_m",  4, -1, 1, KHZ,   1,      1,      1,      1,         1066000, 1066000, 1200000),
+       CORE_DVFS("pll_c",  4, -1, 1, KHZ,   1,      1,      1,      1,         1066000, 1066000, 1066000),
+       CORE_DVFS("pll_c2", 4, -1, 1, KHZ,   1,      1,      1,      1,         1066000, 1066000, 1066000),
+       CORE_DVFS("pll_c3", 4, -1, 1, KHZ,   1,      1,      1,      1,         1066000, 1066000, 1066000),
+
+       /* Core voltages (mV):               800,    850,    900,    950,       1000    1050    1100*/
+       /* Clock limits for I/O peripherals */
+       CORE_DVFS("dsia",   4, -1, 1, KHZ,   1,      1,      1,      1,         750000, 750000, 750000),
+       CORE_DVFS("dsib",   4, -1, 1, KHZ,   1,      1,      1,      1,         750000, 750000, 750000),
+       CORE_DVFS("dsialp", 4, -1, 1, KHZ,   1,      1,      1,      1,         156000, 156000, 156000),
+       CORE_DVFS("dsiblp", 4, -1, 1, KHZ,   1,      1,      1,      1,         156000, 156000, 156000),
+       CORE_DVFS("hdmi",   4, -1, 1, KHZ,   1,      1,      1,      1,         297000, 297000, 297000),
+
+       CORE_DVFS("pciex",  4,  -1, 1, KHZ,   1,      1,      1,     1,         500000, 500000, 500000),
+       CORE_DVFS("mselect", 4, -1, 1, KHZ,  1,      1,      1,      1,         204000, 204000, 408000),
+
+       /* Core voltages (mV):                          800,    850,    900,     950,    1000   1050    1100*/
+       /* xusb clocks */
+       CORE_DVFS("xusb_falcon_src", 4, -1, 1, KHZ,       1,      1,      1,      1,    336000, 336000 ,  336000),
+       CORE_DVFS("xusb_host_src",   4, -1, 1, KHZ,       1,      1,      1,      1,    112000, 112000 ,  112000),
+       CORE_DVFS("xusb_dev_src",    4, -1, 1, KHZ,       1,      1,      1,      1,    112000, 112000 ,  112000),
+       CORE_DVFS("xusb_ss_src",     4, -1, 1, KHZ,       1,      1,      1,      1,    120000, 120000 ,  120000),
+       CORE_DVFS("xusb_fs_src",     4, -1, 1, KHZ,       1,      1,      1,      1,     48000,  48000 ,   48000),
+       CORE_DVFS("xusb_hs_src",     4, -1, 1, KHZ,       1,      1,      1,      1,     60000,  60000 ,   60000),
+
+       CORE_DVFS("hda",             4, -1, 1, KHZ,       1,      1,      1,      1,    108000, 108000 ,  108000),
+       CORE_DVFS("hda2codec_2x",    4, -1, 1, KHZ,       1,      1,      1,      1,     48000,  48000 ,   48000),
+
+       CORE_DVFS("sor0",            4, -1, 1, KHZ,       1,      1,      1,      1,    540000,  540000,  540000),
+       OVRRD_DVFS("sdmmc1",         4, -1, 1, KHZ,      1,      1,     1,      1,      136000, 136000, 136000),
+        OVRRD_DVFS("sdmmc3",         4, -1, 1, KHZ,      1,      1,    1,      1,      136000, 136000, 136000),
+        OVRRD_DVFS("sdmmc4",         4, -1, 1, KHZ,      1,      1,    1,      1,      136000, 136000, 136000),
+};
+
 static struct dvfs core_dvfs_table_automotive[] = {
        /* Core voltages (mV):                      800,    850,    900,    950,    1000,  1050,    1100, 1110,   1150 */
        /* Clock limits for internal blocks, PLLs */
@@ -595,8 +716,8 @@ static int resolve_core_override(int min_override_mv)
 
 /* GPU DVFS tables */
 static unsigned long gpu_max_freq[] = {
-/* speedo_id   0       1       2        3       4       5      */
-               648000, 852000, 1008000, 600000, 804000, 756000
+/* speedo_id   0       1       2        3       4       5       6*/
+               648000, 852000, 1008000, 600000, 804000, 756000, 924000
 };
 static struct gpu_cvb_dvfs gpu_cvb_dvfs_table[] = {
        {
@@ -617,7 +738,7 @@ static struct gpu_cvb_dvfs gpu_cvb_dvfs_table[] = {
                .vts_trips_table = { -40, 35, },
        },
        {
-               /* Embedded SKU CD575MI */
+               /* Embedded SKU CD575MI Always On*/
                .speedo_id =  5,
                .process_id = -1,
                .max_mv = 1090,
@@ -646,6 +767,39 @@ static struct gpu_cvb_dvfs gpu_cvb_dvfs_table[] = {
                .vts_trips_table = { -40, 0,},
        },
        {
+               /* Embedded SKU CD575MI */
+               .speedo_id =  6,
+               .process_id = -1,
+               .max_mv = 1200,
+               .freqs_mult = KHZ,
+               .speedo_scale = 100,
+               .thermal_scale = 10,
+               .voltage_scale = 1000,
+               .cvb_table = {
+                       /*f        dfll  pll:   c0,     c1,   c2,   c3,      c4,   c5 */
+                       {   72000, {  }, { 1209886, -36468,  515,  }, },
+                       {  108000, {  }, { 1130804, -27659,  296,  }, },
+                       {  180000, {  }, { 1162871, -27110,  247,  }, },
+                       {  252000, {  }, { 1220458, -28654,  247,  }, },
+                       {  324000, {  }, { 1280953, -30204,  247,  }, },
+                       {  396000, {  }, { 1344547, -31777,  247,  }, },
+                       {  468000, {  }, { 1420168, -34227,  269,  }, },
+                       {  540000, {  }, { 1490757, -35955,  274,  }, },
+                       {  612000, {  }, { 1599112, -42583,  398,  }, },
+                       {  648000, {  }, { 1366986, -16459, -274,  }, },
+                       {  684000, {  }, { 1391884, -17078, -274,  }, },
+                       {  708000, {  }, { 1415522, -17497, -274,  }, },
+                       {  756000, {  }, { 1464061, -18331, -274,  }, },
+                       {  804000, {  }, { 1524225, -20064, -254,  }, },
+                        {  852000, {  }, { 1608418, -21643, -269,  }, },
+                       {  900000, {  }, { 1706383, -25155, -209,  }, },
+                       {  924000, {  }, { 1739600, -26289, -194,  }, },
+                       {       0, {  }, { }, },
+               },
+               .cvb_vmin =  { 0, { } , { 950000, }, },
+               .vts_trips_table = { -40, 0,},
+       },
+       {
                .speedo_id =  -1,
                .process_id = -1,
                .max_mv = 1200,
@@ -1012,7 +1166,8 @@ static int __init set_cpu_dvfs_data(unsigned long max_freq,
                rail, &d->dfll_tune_data);
 #endif
 
-       if (cpu_dvfs->speedo_id == 4 || cpu_dvfs->speedo_id == 7) {
+       if (cpu_dvfs->speedo_id == 4 || cpu_dvfs->speedo_id == 7 ||
+                       cpu_dvfs->speedo_id == 8) {
                rail->clk_switch_cdev = &cpu_clk_switch_cdev;
                ret = tegra_dvfs_rail_init_clk_switch_thermal_profile(
                                d->clk_switch_trips, rail);
@@ -1120,9 +1275,11 @@ static int __init set_gpu_dvfs_data(unsigned long max_freq,
                        int t = rail->vts_cdev->trip_temperatures[j];
 
                        /* get thermal offset for this trip-point */
-                       if ((d->speedo_id == 5) && (j == 0))
+                       if ((d->speedo_id == 5 || d->speedo_id == 6) && (j == 0)) {
                                mvj += 50 * d->voltage_scale;
-                       else
+                               if (mvj > (d->max_mv * 1000))
+                                       mvj -= 50 * d->voltage_scale;
+                       } else
                                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);
@@ -1304,12 +1461,12 @@ void __init tegra12x_init_dvfs(void)
                tegra_dvfs_cpu_disabled = true;
        }
 #endif
-       if (cpu_speedo_id == 7)
+       if (cpu_speedo_id == 7 || cpu_speedo_id == 8)
                tegra_dvfs_cpu_disabled = true;
-       if (cpu_speedo_id == 7 ||
+       if (cpu_speedo_id == 7 || cpu_speedo_id == 8 ||
                CONFIG_TEGRA_USE_DFLL_RANGE == TEGRA_USE_DFLL_CDEV_CNTRL)
                tegra_override_dfll_range = TEGRA_USE_DFLL_CDEV_CNTRL;
-       if (soc_speedo_id == 3)
+       if (soc_speedo_id == 3 || soc_speedo_id == 4)
                tegra_dvfs_core_disabled = true;
        /*
         * Find nominal voltages for core (1st) and cpu rails before rail
@@ -1374,6 +1531,14 @@ void __init tegra12x_init_dvfs(void)
        tegra_dvfs_rail_init_vmin_thermal_profile(vdd_core_vmin_trips_table,
                vdd_core_therm_floors_table, &tegra12_dvfs_rail_vdd_core, NULL);
        if (soc_speedo_id == 3) {
+               tegra12_dvfs_rail_vdd_core.therm_mv_caps = vdd_core_therm_caps_table_sku80_alwayson;
+               tegra12_dvfs_rail_vdd_core.therm_mv_caps_num = ARRAY_SIZE(vdd_core_therm_caps_table_sku80_alwayson);
+               if (tegra12_dvfs_rail_vdd_core.vmax_cdev) {
+                       tegra12_dvfs_rail_vdd_core.vmax_cdev->trip_temperatures_num =
+                               ARRAY_SIZE(vdd_core_vmax_trips_table_sku80_alwayson);
+                       tegra12_dvfs_rail_vdd_core.vmax_cdev->trip_temperatures = vdd_core_vmax_trips_table_sku80_alwayson;
+               }
+       } else if (soc_speedo_id == 4) {
                tegra12_dvfs_rail_vdd_core.therm_mv_caps = vdd_core_therm_caps_table_sku80;
                tegra12_dvfs_rail_vdd_core.therm_mv_caps_num = ARRAY_SIZE(vdd_core_therm_caps_table_sku80);
                if (tegra12_dvfs_rail_vdd_core.vmax_cdev) {
@@ -1397,6 +1562,10 @@ void __init tegra12x_init_dvfs(void)
                        INIT_CORE_DVFS_TABLE(core_dvfs_table_automotive,
                                     ARRAY_SIZE(core_dvfs_table_automotive));
                } else if (soc_speedo_id == 3) {
+                       /* Use embedded core dvfs table alwayson personality */
+                       INIT_CORE_DVFS_TABLE(core_dvfs_table_embedded_alwayson,
+                                    ARRAY_SIZE(core_dvfs_table_embedded_alwayson));
+               } else if (soc_speedo_id == 4) {
                        /* Use embedded core dvfs table */
                        INIT_CORE_DVFS_TABLE(core_dvfs_table_embedded,
                                     ARRAY_SIZE(core_dvfs_table_embedded));
index aebc7f2..97685e9 100644 (file)
@@ -341,6 +341,10 @@ static struct tegra_edp_cpu_powermodel_params t12x_cpu_powermodel_params[] = {
                .cpu_speedo_id = 7, /* Prod SKU */
                .common = EDP_PARAMS_COMMON_PART,
        },
+       {
+               .cpu_speedo_id = 8, /* Prod SKU */
+               .common = EDP_PARAMS_COMMON_PART,
+       },
 };
 
 struct tegra_edp_cpu_powermodel_params *tegra12x_get_cpu_powermodel_params(
index e779e97..0faeb54 100644 (file)
@@ -143,6 +143,9 @@ static void rev_sku_to_speedo_ids(int rev, int sku)
                threshold_index = 1;
                break;
        case 0x80:
+               cpu_speedo_id = 8;
+               soc_speedo_id = 4;
+               gpu_speedo_id = 6;
                if (chip_personality == always_on) {
                        cpu_speedo_id = 7;
                        soc_speedo_id = 3;
@@ -337,6 +340,8 @@ int tegra_core_speedo_mv(void)
                return 1110;
        case 3:
                return 1000;
+       case 4:
+               return 1100;
        default:
                BUG();
        }