summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBibek Basu <bbasu@nvidia.com>2014-11-06 16:34:09 +0530
committerWinnie Hsu <whsu@nvidia.com>2014-11-21 13:46:32 -0800
commite9b32d4342a9ee9308729ae0c725d421869a0538 (patch)
treeb75923e1184e8620e4a7e8650b306fb96d606d9c
parent2c1ad0be0a4ef9a83f8fbdbb19dbc72cb83f7420 (diff)
arm: tegra12: add support for CD575M 24x7 Chip
Added DVFS support for CD575M Always on behaviour. With this personality configuration for the chip,the lifetime of the chip increases to 5 Yrs Operating Temp : -25 to 105 degC CPU DVFS: Max Freq 1938Mhz. Max Voltage 1.12V SOC DVFS: Max Voltage0 1.01V EMC dvfs max freq 792Mhz GPU DVFS: Max Freq 804Mhz and Ma Voltage 1.09V Bug 1563635 Change-Id: If7fec38b83ae4de8c5435006207fa3cf717384c0 Signed-off-by: Bibek Basu <bbasu@nvidia.com> Reviewed-on: http://git-master/r/594855 GVS: Gerrit_Virtual_Submit Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/board.h6
-rw-r--r--arch/arm/mach-tegra/clock.c1
-rw-r--r--arch/arm/mach-tegra/common.c16
-rw-r--r--arch/arm/mach-tegra/dvfs.c3
-rw-r--r--arch/arm/mach-tegra/tegra12_dvfs.c36
-rw-r--r--arch/arm/mach-tegra/tegra12_edp.c5
-rw-r--r--arch/arm/mach-tegra/tegra12_speedo.c12
-rw-r--r--drivers/mmc/host/sdhci-tegra.c3
-rw-r--r--include/linux/clk/tegra.h1
-rw-r--r--include/linux/tegra-fuse.h1
10 files changed, 65 insertions, 19 deletions
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index 07f9c2b37d9e..3ae1d51876b3 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -244,6 +244,12 @@ enum image_type {
rck_image,
};
+/* Usage Model */
+enum chip_personality {
+ normal = 0,
+ always_on,
+};
+
void tegra_get_board_info(struct board_info *);
void tegra_get_pmu_board_info(struct board_info *bi);
void tegra_get_display_board_info(struct board_info *bi);
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index ab1cf8dab68a..eb79acb14187 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -150,6 +150,7 @@ unsigned long clk_get_max_rate(struct clk *c)
{
return c->max_rate;
}
+EXPORT_SYMBOL(clk_get_max_rate);
unsigned long clk_get_min_rate(struct clk *c)
{
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 271e8228a865..de7173b67cb0 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -333,6 +333,7 @@ static int emc_max_dvfs;
static unsigned int memory_type;
static int usb_port_owner_info;
static int lane_owner_info;
+static int chip_personality;
#ifdef CONFIG_ARCH_TEGRA_11x_SOC
static __initdata struct tegra_clk_init_table tegra11x_clk_init_table[] = {
@@ -1157,6 +1158,21 @@ int tegra_get_sku_override(void)
return sku_override;
}
+static int __init tegra_chip_personality(char *id)
+{
+ char *p = id;
+
+ chip_personality = memparse(p, &p);
+
+ return 0;
+}
+early_param("chip_personality", tegra_chip_personality);
+
+int tegra_get_chip_personality(void)
+{
+ return chip_personality;
+}
+
#ifndef CONFIG_NVMAP_USE_CMA_FOR_CARVEOUT
static int __init tegra_vpr_arg(char *options)
{
diff --git a/arch/arm/mach-tegra/dvfs.c b/arch/arm/mach-tegra/dvfs.c
index 06596c51ee1a..429385118b64 100644
--- a/arch/arm/mach-tegra/dvfs.c
+++ b/arch/arm/mach-tegra/dvfs.c
@@ -1146,7 +1146,8 @@ int __init tegra_enable_dvfs_on_clk(struct clk *c, struct dvfs *d)
}
for (i = 0; i < MAX_DVFS_FREQS; i++) {
- if (d->millivolts[i] == 0)
+ if (d->millivolts[i] == 0 ||
+ d->millivolts[i] > d->max_millivolts)
break;
d->freqs[i] *= d->freqs_mult;
diff --git a/arch/arm/mach-tegra/tegra12_dvfs.c b/arch/arm/mach-tegra/tegra12_dvfs.c
index a5d37ddb73d9..ac59d2c0a4a2 100644
--- a/arch/arm/mach-tegra/tegra12_dvfs.c
+++ b/arch/arm/mach-tegra/tegra12_dvfs.c
@@ -152,8 +152,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 */
- 2014500, 2320500, 2116500, 2524500, 1811000, 2218500,
+/* speedo_id 0 1 2 3 4 5 6 */
+ 2014500, 2320500, 2116500, 2524500, 1811000, 2218500, 1938000,
};
static struct cpu_cvb_dvfs cpu_cvb_dvfs_table[] = {
@@ -277,11 +277,24 @@ static const int core_millivolts[MAX_DVFS_FREQS] = {
.dvfs_rail = &tegra12_dvfs_rail_vdd_core, \
}
+#define DEFER_DVFS(_clk_name, _speedo_id, _process_id, _auto, _mult, _freqs...) \
+ { \
+ .clk_name = _clk_name, \
+ .speedo_id = _speedo_id, \
+ .process_id = _process_id, \
+ .freqs = {_freqs}, \
+ .freqs_mult = _mult, \
+ .millivolts = core_millivolts, \
+ .auto_dvfs = _auto, \
+ .defer_override = true, \
+ .dvfs_rail = &tegra12_dvfs_rail_vdd_core, \
+ }
+
static struct dvfs core_dvfs_table[] = {
/* Core voltages (mV): 800, 850, 900, 950, 1000, 1050, 1100, 1110, 1150 */
/* Clock limits for internal blocks, PLLs */
- CORE_DVFS("emc", -1, -1, 1, KHZ, 264000, 348000, 384000, 384000, 528000, 528000, 1200000, 1200000, 1200000),
+ CORE_DVFS("emc", -1, -1, 1, KHZ, 264000, 348000, 384000, 384000, 792000, 792000, 1200000, 1200000, 1200000),
CORE_DVFS("cpu_lp", 0, 0, 1, KHZ, 312000, 528000, 660000, 804000, 912000, 1044000, 1044000, 1044000, 1044000),
CORE_DVFS("cpu_lp", 0, 1, 1, KHZ, 312000, 564000, 696000, 828000, 960000, 1044000, 1044000, 1044000, 1044000),
@@ -440,19 +453,6 @@ static struct dvfs core_dvfs_table_automotive[] = {
* clock capabilities specified in DVFS table.
*
*/
-#define DEFER_DVFS(_clk_name, _speedo_id, _process_id, _auto, _mult, _freqs...) \
- { \
- .clk_name = _clk_name, \
- .speedo_id = _speedo_id, \
- .process_id = _process_id, \
- .freqs = {_freqs}, \
- .freqs_mult = _mult, \
- .millivolts = core_millivolts, \
- .auto_dvfs = _auto, \
- .defer_override = true, \
- .dvfs_rail = &tegra12_dvfs_rail_vdd_core, \
- }
-
static struct dvfs disp_dvfs_table[] = {
/*
* The clock rate for the display controllers that determines the
@@ -478,8 +478,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 */
- 648000, 852000, 1008000, 600000
+/* speedo_id 0 1 2 3 4 */
+ 648000, 852000, 1008000, 600000, 804000
};
static struct gpu_cvb_dvfs gpu_cvb_dvfs_table[] = {
{
diff --git a/arch/arm/mach-tegra/tegra12_edp.c b/arch/arm/mach-tegra/tegra12_edp.c
index 2fcae97829d7..4e95abce381d 100644
--- a/arch/arm/mach-tegra/tegra12_edp.c
+++ b/arch/arm/mach-tegra/tegra12_edp.c
@@ -189,6 +189,7 @@ struct tegra_sysedp_corecap *tegra_get_sysedp_corecap(unsigned int *sz)
gpu_speedo_id = tegra_gpu_speedo_id();
switch (cpu_speedo_id) {
+ case 0x6:
case 0x5:
case 0x2:
if (gpu_speedo_id == 1) {
@@ -332,6 +333,10 @@ static struct tegra_edp_cpu_powermodel_params t12x_cpu_powermodel_params[] = {
.cpu_speedo_id = 5, /* Prod SKU */
.common = EDP_PARAMS_COMMON_PART,
},
+ {
+ .cpu_speedo_id = 6, /* Prod SKU */
+ .common = EDP_PARAMS_COMMON_PART,
+ },
};
struct tegra_edp_cpu_powermodel_params *tegra12x_get_cpu_powermodel_params(
diff --git a/arch/arm/mach-tegra/tegra12_speedo.c b/arch/arm/mach-tegra/tegra12_speedo.c
index 8341128c66ba..28dfac8c0baa 100644
--- a/arch/arm/mach-tegra/tegra12_speedo.c
+++ b/arch/arm/mach-tegra/tegra12_speedo.c
@@ -30,6 +30,7 @@
#include "iomap.h"
#include "common.h"
+#include "board.h"
#define TEGRA124_CPU_SPEEDO 2271 /* FIXME: Get Correct Value */
@@ -92,6 +93,7 @@ static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
static void rev_sku_to_speedo_ids(int rev, int sku)
{
int can_boost = tegra_get_sku_override();
+ int chip_personality = tegra_get_chip_personality();
switch (sku) {
case 0x00: /* Engg sku */
@@ -111,6 +113,10 @@ static void rev_sku_to_speedo_ids(int rev, int sku)
soc_speedo_id = 0;
gpu_speedo_id = 1;
threshold_index = 0;
+ if (sku == 0x87 && chip_personality == always_on) {
+ cpu_speedo_id = 6;
+ gpu_speedo_id = 4;
+ }
break;
case 0x07:
if (can_boost) {
@@ -310,13 +316,19 @@ int tegra_cpu_speedo_mv(void)
int tegra_core_speedo_mv(void)
{
+ int chip_personality = tegra_get_chip_personality();
+
switch (soc_speedo_id) {
case 0:
+ if (chip_personality == always_on)
+ return 1010;
return 1150;
case 1:
return 1150;
case 2:
return 1110;
+ case 3:
+ return 1010;
default:
BUG();
}
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 485570c75a2d..52aeac80ca31 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -1398,6 +1398,9 @@ static void tegra_sdhci_set_clk_rate(struct sdhci_host *sdhci,
(clk_rate > tegra_host->max_clk_limit))
clk_rate = tegra_host->max_clk_limit;
+ if (clk_rate > clk_get_max_rate(pltfm_host->clk))
+ clk_rate = clk_get_max_rate(pltfm_host->clk);
+
tegra_sdhci_clock_set_parent(sdhci, clk_rate);
clk_set_rate(pltfm_host->clk, clk_rate);
sdhci->max_clk = clk_get_rate(pltfm_host->clk);
diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
index 2a374c56297d..8394de40787c 100644
--- a/include/linux/clk/tegra.h
+++ b/include/linux/clk/tegra.h
@@ -168,6 +168,7 @@ void tegra_unregister_clk_rate_notifier(
struct clk *c, struct notifier_block *nb);
int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting);
int tegra_dvfs_use_alt_freqs_on_clk(struct clk *c, bool use_alt_freq);
+unsigned long clk_get_max_rate(struct clk *c);
/**
* tegra_is_clk_enabled - get info if the clk is enabled or not
diff --git a/include/linux/tegra-fuse.h b/include/linux/tegra-fuse.h
index c12770eafcf5..0d2b9c967bce 100644
--- a/include/linux/tegra-fuse.h
+++ b/include/linux/tegra-fuse.h
@@ -60,6 +60,7 @@ int tegra_core_speedo_mv(void);
int tegra_gpu_speedo_id(void);
int tegra_get_sku_override(void);
int tegra_get_cpu_iddq_value(void);
+int tegra_get_chip_personality(void);
#ifdef CONFIG_ARCH_TEGRA_12x_SOC
int tegra_cpu_speedo_0_value(void);