ARM: tegra12: introduce revised system-EDP for TN8
Timo Alho [Fri, 18 Oct 2013 09:52:24 +0000 (12:52 +0300)]
This patch introduces a revised system-EDP framework implementation
for TN8 platform.

Change-Id: Id717a46f6112241cfbfb5e29738729c31b055062
Signed-off-by: Timo Alho <talho@nvidia.com>
Reviewed-on: http://git-master/r/301694
Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>
Tested-by: Juha Tukkinen <jtukkinen@nvidia.com>

arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/board-ardbeg.c
arch/arm/mach-tegra/board-ardbeg.h
arch/arm/mach-tegra/board-tn8-sysedp.c [new file with mode: 0644]

index f4f8d98..8b2b6e0 100644 (file)
@@ -279,6 +279,9 @@ obj-${CONFIG_MACH_ARDBEG}               += panel-s-wqxga-10-1.o
 obj-${CONFIG_MACH_ARDBEG}               += panel-lgd-wxga-7-0.o
 obj-${CONFIG_MACH_ARDBEG}               += panel-a-edp-1080p-14-0.o
 obj-${CONFIG_MACH_ARDBEG}               += panel-c-lvds-1366-14.o
+ifeq ($(CONFIG_MACH_ARDBEG),y)
+obj-${CONFIG_SYSEDP_FRAMEWORK}          += board-tn8-sysedp.o
+endif
 
 obj-${CONFIG_MACH_LOKI}                += board-loki.o
 obj-${CONFIG_MACH_LOKI}                += board-loki-kbc.o
index 3b2b5d3..0c1280a 100644 (file)
@@ -1024,7 +1024,7 @@ static int __init ardbeg_touch_init(void)
        return 0;
 }
 
-static void __init sysedp_init(void)
+static void __init ardbeg_sysedp_init(void)
 {
        struct board_info bi;
 
@@ -1032,8 +1032,11 @@ static void __init sysedp_init(void)
 
        switch (bi.board_id) {
        case BOARD_E1780:
-               if (bi.sku == 1100)
+               if (bi.sku == 1100) {
                        tn8_sysedp_init();
+                       if (!IS_ENABLED(CONFIG_SYSEDP_FRAMEWORK))
+                               tn8_new_sysedp_init();
+               }
                break;
        case BOARD_PM358:
        case BOARD_PM359:
@@ -1060,6 +1063,24 @@ static void __init sysedp_core_init(void)
        }
 }
 
+static void __init ardbeg_sysedp_dynamic_capping_init(void)
+{
+       struct board_info bi;
+
+       tegra_get_board_info(&bi);
+
+       switch (bi.board_id) {
+       case BOARD_E1780:
+               if (bi.sku == 1100)
+                       tn8_sysedp_dynamic_capping_init();
+               break;
+       case BOARD_PM358:
+       case BOARD_PM359:
+       default:
+               break;
+       }
+}
+
 
 static void __init sysedp_psydepl_init(void)
 {
@@ -1079,6 +1100,29 @@ static void __init sysedp_psydepl_init(void)
        }
 }
 
+static void __init ardbeg_sysedp_batmon_init(void)
+{
+       struct board_info bi;
+
+       if (!IS_ENABLED(CONFIG_SYSEDP_FRAMEWORK))
+               return;
+
+       tegra_get_board_info(&bi);
+
+       switch (bi.board_id) {
+       case BOARD_E1780:
+               if (bi.sku == 1100)
+                       tn8_sysedp_batmon_init();
+               break;
+       case BOARD_PM358:
+       case BOARD_PM359:
+       default:
+               break;
+       }
+}
+
+
+
 static void __init edp_init(void)
 {
        struct board_info bi;
@@ -1104,7 +1148,7 @@ static void __init edp_init(void)
 
 static void __init tegra_ardbeg_early_init(void)
 {
-       sysedp_init();
+       ardbeg_sysedp_init();
        tegra_clk_init_from_table(ardbeg_clk_init_table);
        tegra_clk_verify_parents();
        if (of_machine_is_compatible("nvidia,laguna"))
@@ -1215,6 +1259,9 @@ static void __init tegra_ardbeg_late_init(void)
 
        sysedp_core_init();
        sysedp_psydepl_init();
+
+       ardbeg_sysedp_dynamic_capping_init();
+       ardbeg_sysedp_batmon_init();
 }
 
 static void __init ardbeg_ramconsole_reserve(unsigned long size)
index 3e958f6..200c1f0 100644 (file)
@@ -37,9 +37,6 @@ int ardbeg_pmon_init(void);
 int ardbeg_rail_alignment_init(void);
 int ardbeg_soctherm_init(void);
 int ardbeg_edp_init(void);
-void ardbeg_sysedp_init(void);
-void ardbeg_sysedp_psydepl_init(void);
-void ardbeg_sysedp_core_init(void);
 
 /* Invensense MPU Definitions */
 #define MPU_GYRO_NAME          "mpu9250"
@@ -170,4 +167,8 @@ void tn8_sysedp_init(void);
 void tn8_sysedp_psydepl_init(void);
 void tn8_sysedp_core_init(void);
 
+void tn8_new_sysedp_init(void);
+void tn8_sysedp_dynamic_capping_init(void);
+void tn8_sysedp_batmon_init(void);
+
 #endif
diff --git a/arch/arm/mach-tegra/board-tn8-sysedp.c b/arch/arm/mach-tegra/board-tn8-sysedp.c
new file mode 100644 (file)
index 0000000..8a64efa
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/sysedp.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/tegra_edp.h>
+#include <linux/power_supply.h>
+#include <mach/edp.h>
+#include "board.h"
+#include "board-panel.h"
+
+/* --- EDP consumers data --- */
+static unsigned int sdhci_states[] = { 0, 966 };
+static unsigned int speaker_states[] = { 0, 1080 };
+static unsigned int wifi_states[] = { 0, 1020 };
+/* 10" panel */
+static unsigned int pwm_backlight_states[] = {
+       0, 425, 851, 1276, 1702, 2127, 2553, 2978, 3404, 3829, 4255
+};
+
+static struct sysedp_consumer_data tn8_sysedp_consumer_data[] = {
+       SYSEDP_CONSUMER_DATA("speaker", speaker_states),
+       SYSEDP_CONSUMER_DATA("wifi", wifi_states),
+       SYSEDP_CONSUMER_DATA("pwm-backlight", pwm_backlight_states),
+       SYSEDP_CONSUMER_DATA("sdhci-tegra.2", sdhci_states),
+       SYSEDP_CONSUMER_DATA("sdhci-tegra.3", sdhci_states),
+};
+
+static struct sysedp_platform_data tn8_sysedp_platform_data = {
+       .consumer_data = tn8_sysedp_consumer_data,
+       .consumer_data_size = ARRAY_SIZE(tn8_sysedp_consumer_data),
+       .margin = 0,
+};
+
+static struct platform_device tn8_sysedp_device = {
+       .name = "sysedp",
+       .id = -1,
+       .dev = { .platform_data = &tn8_sysedp_platform_data }
+};
+
+void __init tn8_new_sysedp_init(void)
+{
+       int r;
+
+       r = platform_device_register(&tn8_sysedp_device);
+       WARN_ON(r);
+}
+
+/* --- Battery monitor data --- */
+static struct sysedp_batmon_ibat_lut tn8_ibat_lut[] = {
+       {  60, 6150 }, /* TODO until battery temp is fixed*/
+       {  40, 6150 },
+       {   0, 6150 },
+       { -30,    0 }
+};
+
+static struct sysedp_batmon_rbat_lut tn8_rbat_lut[] = {
+       { 100,  76000  },
+       {  88,  85000  },
+       {  75,  102000 },
+       {  63,  93000  },
+       {  50,  85000  },
+       {  38,  93000  },
+       {  25,  102000 },
+       {  13,  119000 },
+       {   0,  119000 }
+};
+
+static struct sysedp_batmon_calc_platform_data tn8_batmon_pdata = {
+       .power_supply = "battery",
+       .r_const = 38000,
+       .vsys_min = 2900000,
+       .ibat_lut = tn8_ibat_lut,
+       .rbat_lut = tn8_rbat_lut,
+};
+
+static struct platform_device tn8_batmon_device = {
+       .name = "sysedp_batmon_calc",
+       .id = -1,
+       .dev = { .platform_data = &tn8_batmon_pdata }
+};
+
+void __init tn8_sysedp_batmon_init(void)
+{
+       int r;
+
+       if (get_power_supply_type() != POWER_SUPPLY_TYPE_BATTERY) {
+               /* modify platform data on-the-fly to enable virtual battery */
+               tn8_batmon_pdata.power_supply = "test_battery";
+               tn8_batmon_pdata.update_interval = 2000;
+       }
+
+       r = platform_device_register(&tn8_batmon_device);
+       WARN_ON(r);
+}
+
+/* --- sysedp capping device data --- */
+static struct tegra_sysedp_corecap tn8_sysedp_corecap[] = {
+       {  4000, {  1000, 180000, 924000 }, { 1000, 180000, 924000 } },
+       {  5000, {  2000, 180000, 924000 }, { 2000, 180000, 924000 } },
+       {  6000, {  3000, 180000, 924000 }, { 2000, 252000, 924000 } },
+       {  7000, {  4000, 180000, 924000 }, { 2000, 324000, 924000 } },
+       {  8000, {  5000, 180000, 924000 }, { 2000, 396000, 924000 } },
+       {  9000, {  6000, 180000, 924000 }, { 2000, 468000, 924000 } },
+       { 10000, {  6600, 180000, 924000 }, { 2000, 540000, 924000 } },
+       { 11000, {  7300, 180000, 924000 }, { 2000, 540000, 924000 } },
+       { 12000, {  8000, 180000, 924000 }, { 2000, 612000, 924000 } },
+       { 13000, {  8000, 252000, 924000 }, { 2000, 648000, 924000 } },
+       { 14000, {  8000, 324000, 924000 }, { 2000, 684000, 924000 } },
+       { 15000, {  9000, 324000, 924000 }, { 2000, 708000, 924000 } },
+       { 16000, {  9000, 396000, 924000 }, { 2000, 756000, 924000 } },
+       { 17000, { 10000, 468000, 924000 }, { 3000, 756000, 924000 } },
+       { 18000, { 11000, 540000, 924000 }, { 4000, 756000, 924000 } },
+       { 19000, { 12000, 540000, 924000 }, { 5000, 756000, 924000 } },
+       { 20000, { 13000, 612000, 924000 }, { 5000, 756000, 924000 } },
+       { 21000, { 14000, 648000, 924000 }, { 6000, 804000, 924000 } },
+       { 22000, { 15000, 708000, 924000 }, { 6500, 804000, 924000 } },
+       { 23000, { 16000, 708000, 924000 }, { 7000, 804000, 924000 } },
+};
+
+static struct tegra_sysedp_platform_data tn8_sysedp_dynamic_capping_platdata = {
+       .corecap = tn8_sysedp_corecap,
+       .corecap_size = ARRAY_SIZE(tn8_sysedp_corecap),
+       .core_gain = 130,
+       .init_req_watts = 20000,
+};
+
+static struct platform_device tn8_sysedp_dynamic_capping = {
+       .name = "sysedp_dynamic_capping",
+       .id = -1,
+       .dev = { .platform_data = &tn8_sysedp_dynamic_capping_platdata }
+};
+
+void __init tn8_sysedp_dynamic_capping_init(void)
+{
+       int r;
+
+       tn8_sysedp_dynamic_capping_platdata.cpufreq_lim = tegra_get_system_edp_entries(
+               &tn8_sysedp_dynamic_capping_platdata.cpufreq_lim_size);
+       if (!tn8_sysedp_dynamic_capping_platdata.cpufreq_lim) {
+               WARN_ON(1);
+               return;
+       }
+
+       r = platform_device_register(&tn8_sysedp_dynamic_capping);
+       WARN_ON(r);
+}