tegra2: dvfs: enable dvfs for sdmmc
[linux-2.6.git] / arch / arm / mach-tegra / tegra2_dvfs.c
index 6758069..a53033b 100644 (file)
@@ -6,6 +6,8 @@
  * Author:
  *     Colin Cross <ccross@google.com>
  *
+ * Copyright (C) 2010-2011 NVIDIA Corporation
+ *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
  * may be copied, distributed, and modified under those terms.
@@ -38,7 +40,7 @@ static bool tegra_dvfs_cpu_disabled = true;
 #endif
 
 static const int core_millivolts[MAX_DVFS_FREQS] =
-       {950, 1000, 1100, 1200, 1275};
+       {950, 1000, 1100, 1200, 1225, 1275, 1300};
 static const int cpu_millivolts[MAX_DVFS_FREQS] =
        {750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000, 1025, 1050, 1100, 1125};
 
@@ -46,6 +48,10 @@ static const int cpu_speedo_nominal_millivolts[] =
 /* spedo_id  0,    1,    2 */
        { 1100, 1025, 1125 };
 
+static const int core_speedo_nominal_millivolts[] =
+/* spedo_id  0,    1,    2 */
+       { 1225, 1225, 1300 };
+
 #define KHZ 1000
 #define MHZ 1000000
 
@@ -58,32 +64,32 @@ static struct dvfs_rail tegra2_dvfs_rail_vdd_cpu = {
 
 static struct dvfs_rail tegra2_dvfs_rail_vdd_core = {
        .reg_id = "vdd_core",
-       .max_millivolts = 1275,
+       .max_millivolts = 1300,
        .min_millivolts = 950,
-       .nominal_millivolts = 1200,
+       .nominal_millivolts = 1225,
        .step = 150, /* step vdd_core by 150 mV to allow vdd_aon to follow */
 };
 
 static struct dvfs_rail tegra2_dvfs_rail_vdd_aon = {
        .reg_id = "vdd_aon",
-       .max_millivolts = 1275,
+       .max_millivolts = 1300,
        .min_millivolts = 950,
-       .nominal_millivolts = 1200,
+       .nominal_millivolts = 1225,
 #ifndef CONFIG_TEGRA_CORE_DVFS
        .disabled = true,
 #endif
 };
 
-/* vdd_core and vdd_aon must be 50 mV higher than vdd_cpu */
+/* vdd_core and vdd_aon must be 120 mV higher than vdd_cpu */
 static int tegra2_dvfs_rel_vdd_cpu_vdd_core(struct dvfs_rail *vdd_cpu,
        struct dvfs_rail *vdd_core)
 {
        if (vdd_cpu->new_millivolts > vdd_cpu->millivolts &&
-           vdd_core->new_millivolts < vdd_cpu->new_millivolts + 50)
-               return vdd_cpu->new_millivolts + 50;
+           vdd_core->new_millivolts < vdd_cpu->new_millivolts + 120)
+               return vdd_cpu->new_millivolts + 120;
 
-       if (vdd_core->new_millivolts < vdd_cpu->millivolts + 50)
-               return vdd_cpu->millivolts + 50;
+       if (vdd_core->new_millivolts < vdd_cpu->millivolts + 120)
+               return vdd_cpu->millivolts + 120;
 
        return vdd_core->new_millivolts;
 }
@@ -99,13 +105,13 @@ static int tegra2_dvfs_rel_vdd_core_vdd_aon(struct dvfs_rail *vdd_core,
 
 static struct dvfs_relationship tegra2_dvfs_relationships[] = {
        {
-               /* vdd_core must be 50 mV higher than vdd_cpu */
+               /* vdd_core must be 120 mV higher than vdd_cpu */
                .from = &tegra2_dvfs_rail_vdd_cpu,
                .to = &tegra2_dvfs_rail_vdd_core,
                .solve = tegra2_dvfs_rel_vdd_cpu_vdd_core,
        },
        {
-               /* vdd_aon must be 50 mV higher than vdd_cpu */
+               /* vdd_aon must be 120 mV higher than vdd_cpu */
                .from = &tegra2_dvfs_rail_vdd_cpu,
                .to = &tegra2_dvfs_rail_vdd_aon,
                .solve = tegra2_dvfs_rel_vdd_cpu_vdd_core,
@@ -136,11 +142,11 @@ static struct dvfs_rail *tegra2_dvfs_rails[] = {
                .dvfs_rail      = &tegra2_dvfs_rail_vdd_cpu,    \
        }
 
-#define CORE_DVFS(_clk_name, _auto, _mult, _freqs...)          \
+#define CORE_DVFS(_clk_name, _process_id, _auto, _mult, _freqs...)     \
        {                                                       \
                .clk_name       = _clk_name,                    \
                .speedo_id      = -1,                           \
-               .process_id     = -1,                           \
+               .process_id     = _process_id,                          \
                .freqs          = {_freqs},                     \
                .freqs_mult     = _mult,                        \
                .millivolts     = core_millivolts,              \
@@ -165,32 +171,24 @@ static struct dvfs dvfs_init[] = {
        CPU_DVFS("cpu", 2, 2, MHZ,   0,   0,   0,   0, 769, 769,  902,  902,  1026, 1026, 1140, 1140, 1200),
        CPU_DVFS("cpu", 2, 3, MHZ,   0,   0,   0,   0, 940, 1000, 1000, 1000, 1130, 1130, 1200),
 
-       /* Core voltages (mV):       950,    1000,   1100,   1200,   1275 */
-       CORE_DVFS("emc",     1, KHZ, 57000,  333000, 333000, 666000, 666000),
-
-#if 0
-       /*
-        * The sdhci core calls the clock ops with a spinlock held, which
-        * conflicts with the sleeping dvfs api.
-        * For now, boards must ensure that the core voltage does not drop
-        * below 1V, or that the sdmmc busses are set to 44 MHz or less.
-        */
-       CORE_DVFS("sdmmc1",  1, KHZ, 44000,  52000,  52000,  52000,  52000),
-       CORE_DVFS("sdmmc2",  1, KHZ, 44000,  52000,  52000,  52000,  52000),
-       CORE_DVFS("sdmmc3",  1, KHZ, 44000,  52000,  52000,  52000,  52000),
-       CORE_DVFS("sdmmc4",  1, KHZ, 44000,  52000,  52000,  52000,  52000),
-#endif
-
-       CORE_DVFS("ndflash", 1, KHZ, 130000, 150000, 158000, 164000, 164000),
-       CORE_DVFS("nor",     1, KHZ, 0,      92000,  92000,  92000,  92000),
-       CORE_DVFS("ide",     1, KHZ, 0,      0,      100000, 100000, 100000),
-       CORE_DVFS("mipi",    1, KHZ, 0,      40000,  40000,  40000, 60000),
-       CORE_DVFS("usbd",    1, KHZ, 0,      0,      0,      480000, 480000),
-       CORE_DVFS("usb2",    1, KHZ, 0,      0,      0,      480000, 480000),
-       CORE_DVFS("usb3",    1, KHZ, 0,      0,      0,      480000, 480000),
-       CORE_DVFS("pcie",    1, KHZ, 0,      0,      0,      250000, 250000),
-       CORE_DVFS("dsi",     1, KHZ, 100000, 100000, 100000, 500000, 500000),
-       CORE_DVFS("tvo",     1, KHZ, 0,      0,      0,      250000, 250000),
+       /* Core voltages (mV):           950,    1000,   1100,   1200,   1225,   1275,   1300 */
+       CORE_DVFS("emc",     -1, 1, KHZ, 57000,  333000, 380000, 666000, 666000, 666000, 760000),
+
+       CORE_DVFS("sdmmc1",  -1, 1, KHZ, 44000,  52000,  52000,  52000,  52000,  52000,  52000),
+       CORE_DVFS("sdmmc2",  -1, 1, KHZ, 44000,  52000,  52000,  52000,  52000,  52000,  52000),
+       CORE_DVFS("sdmmc3",  -1, 1, KHZ, 44000,  52000,  52000,  52000,  52000,  52000,  52000),
+       CORE_DVFS("sdmmc4",  -1, 1, KHZ, 44000,  52000,  52000,  52000,  52000,  52000,  52000),
+
+       CORE_DVFS("ndflash", -1, 1, KHZ, 130000, 150000, 158000, 164000, 164000, 164000, 164000),
+       CORE_DVFS("nor",     -1, 1, KHZ, 0,      92000,  92000,  92000,  92000,  92000,  92000),
+       CORE_DVFS("ide",     -1, 1, KHZ, 0,      0,      100000, 100000, 100000, 100000, 100000),
+       CORE_DVFS("mipi",    -1, 1, KHZ, 0,      40000,  40000,  40000,  40000,  60000,  60000),
+       CORE_DVFS("usbd",    -1, 1, KHZ, 0,      0,      480000, 480000, 480000, 480000, 480000),
+       CORE_DVFS("usb2",    -1, 1, KHZ, 0,      0,      480000, 480000, 480000, 480000, 480000),
+       CORE_DVFS("usb3",    -1, 1, KHZ, 0,      0,      480000, 480000, 480000, 480000, 480000),
+       CORE_DVFS("pcie",    -1, 1, KHZ, 0,      0,      0,      250000, 250000, 250000, 250000),
+       CORE_DVFS("dsi",     -1, 1, KHZ, 100000, 100000, 100000, 500000, 500000, 500000, 500000),
+       CORE_DVFS("tvo",     -1, 1, KHZ, 0,      0,      0,      250000, 250000, 250000, 250000),
 
        /*
         * The clock rate for the display controllers that determines the
@@ -198,24 +196,43 @@ static struct dvfs dvfs_init[] = {
         * to the display block.  Disable auto-dvfs on the display clocks,
         * and let the display driver call tegra_dvfs_set_rate manually
         */
-       CORE_DVFS("disp1",   0, KHZ, 158000, 158000, 190000, 190000, 190000),
-       CORE_DVFS("disp2",   0, KHZ, 158000, 158000, 190000, 190000, 190000),
-       CORE_DVFS("hdmi",    0, KHZ, 0,      0,      0,      148500, 148500),
+       CORE_DVFS("disp1",   -1, 0, KHZ, 158000, 158000, 190000, 190000, 190000, 190000, 190000),
+       CORE_DVFS("disp2",   -1, 0, KHZ, 158000, 158000, 190000, 190000, 190000, 190000, 190000),
+       CORE_DVFS("hdmi",    -1, 0, KHZ, 0,      0,      0,      148500, 148500, 148500, 148500),
 
        /*
-        * These clocks technically depend on the core process id,
-        * but just use the worst case value for now
+        * Clocks below depend on the core process id. Define per process_id
+        * tables for SCLK/VDE/3D clocks (maximum rate for these clocks is
+        * increased depending on tegra2 sku). Use the worst case value for
+        * other clocks for now.
         */
-       CORE_DVFS("host1x",  1, KHZ, 104500, 133000, 166000, 166000, 166000),
-       CORE_DVFS("epp",     1, KHZ, 133000, 171000, 247000, 300000, 300000),
-       CORE_DVFS("2d",      1, KHZ, 133000, 171000, 247000, 300000, 300000),
-       CORE_DVFS("3d",      1, KHZ, 114000, 161500, 247000, 300000, 300000),
-       CORE_DVFS("mpe",     1, KHZ, 104500, 152000, 228000, 250000, 250000),
-       CORE_DVFS("vi",      1, KHZ, 85000,  100000, 150000, 150000, 150000),
-       CORE_DVFS("sclk",    1, KHZ, 95000,  133000, 190000, 250000, 250000),
-       CORE_DVFS("vde",     1, KHZ, 95000,  123500, 209000, 250000, 250000),
+       CORE_DVFS("host1x",  -1, 1, KHZ, 104500, 133000, 166000, 166000, 166000, 166000, 166000),
+       CORE_DVFS("epp",     -1, 1, KHZ, 133000, 171000, 247000, 300000, 300000, 300000, 300000),
+       CORE_DVFS("2d",      -1, 1, KHZ, 133000, 171000, 247000, 300000, 300000, 300000, 300000),
+
+       CORE_DVFS("3d",       0, 1, KHZ, 114000, 161500, 247000, 304000, 304000, 333500, 333500),
+       CORE_DVFS("3d",       1, 1, KHZ, 161500, 209000, 285000, 333500, 333500, 361000, 361000),
+       CORE_DVFS("3d",       2, 1, KHZ, 218500, 256500, 323000, 380000, 380000, 400000, 400000),
+       CORE_DVFS("3d",       3, 1, KHZ, 247000, 285000, 351500, 400000, 400000, 400000, 400000),
+
+       CORE_DVFS("mpe",      0, 1, KHZ, 104500, 152000, 228000, 300000, 300000, 300000, 300000),
+       CORE_DVFS("mpe",      1, 1, KHZ, 142500, 190000, 275500, 300000, 300000, 300000, 300000),
+       CORE_DVFS("mpe",      2, 1, KHZ, 190000, 237500, 300000, 300000, 300000, 300000, 300000),
+       CORE_DVFS("mpe",      3, 1, KHZ, 228000, 266000, 300000, 300000, 300000, 300000, 300000),
+
+       CORE_DVFS("vi",      -1, 1, KHZ, 85000,  100000, 150000, 150000, 150000, 150000, 150000),
+
+       CORE_DVFS("sclk",     0, 1, KHZ, 95000,  133000, 190000, 222500, 240000, 247000, 262000),
+       CORE_DVFS("sclk",     1, 1, KHZ, 123500, 159500, 207000, 240000, 240000, 264000, 277500),
+       CORE_DVFS("sclk",     2, 1, KHZ, 152000, 180500, 229500, 260000, 260000, 285000, 300000),
+       CORE_DVFS("sclk",     3, 1, KHZ, 171000, 218500, 256500, 292500, 292500, 300000, 300000),
+
+       CORE_DVFS("vde",      0, 1, KHZ, 95000,  123500, 209000, 275500, 275500, 300000, 300000),
+       CORE_DVFS("vde",      1, 1, KHZ, 123500, 152000, 237500, 300000, 300000, 300000, 300000),
+       CORE_DVFS("vde",      2, 1, KHZ, 152000, 209000, 285000, 300000, 300000, 300000, 300000),
+       CORE_DVFS("vde",      3, 1, KHZ, 171000, 218500, 300000, 300000, 300000, 300000, 300000),
        /* What is this? */
-       CORE_DVFS("NVRM_DEVID_CLK_SRC", 1, MHZ, 480, 600, 800, 1067, 1067),
+       CORE_DVFS("NVRM_DEVID_CLK_SRC", -1, 1, MHZ, 480, 600, 800, 1067, 1067, 1067, 1067),
 };
 
 int tegra_dvfs_disable_core_set(const char *arg, const struct kernel_param *kp)
@@ -270,7 +287,7 @@ module_param_cb(disable_core, &tegra_dvfs_disable_core_ops,
 module_param_cb(disable_cpu, &tegra_dvfs_disable_cpu_ops,
        &tegra_dvfs_cpu_disabled, 0644);
 
-void __init tegra2_init_dvfs(void)
+void __init tegra_soc_init_dvfs(void)
 {
        int i;
        struct clk *c;
@@ -284,6 +301,11 @@ void __init tegra2_init_dvfs(void)
        BUG_ON(speedo_id >= ARRAY_SIZE(cpu_speedo_nominal_millivolts));
        tegra2_dvfs_rail_vdd_cpu.nominal_millivolts =
                cpu_speedo_nominal_millivolts[speedo_id];
+       BUG_ON(speedo_id >= ARRAY_SIZE(core_speedo_nominal_millivolts));
+       tegra2_dvfs_rail_vdd_core.nominal_millivolts =
+               core_speedo_nominal_millivolts[speedo_id];
+       tegra2_dvfs_rail_vdd_aon.nominal_millivolts =
+               core_speedo_nominal_millivolts[speedo_id];
 
        tegra_dvfs_init_rails(tegra2_dvfs_rails, ARRAY_SIZE(tegra2_dvfs_rails));
        tegra_dvfs_add_relationships(tegra2_dvfs_relationships,