aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Walmsley <pwalmsley@nvidia.com>2013-06-07 08:18:58 -0400
committerMike Turquette <mturquette@linaro.org>2013-06-18 14:28:36 -0400
commit25c9ded6ed31184379c9b153ff37621fc323b084 (patch)
tree8336643c5e6ac1d9ad01ed1ecf93b5ad37a5b22b
parent045779942c04646a222289989e6a5b617dfdedf7 (diff)
clk: tegra: T114: add FCPU clock shaper programming, needed by the DFLL
Add clock functions to initialize, enable, and disable the FCPU clock shapers, based on the FCPU voltage rail state. These will be used by the DFLL clocksource driver code. This version of the patch contains a fix for a problem noticed by Andrew Chew <achew@nvidia.com>, where some of the FINETRIM_R bitfields were incorrectly defined. Based on code originally written by Aleksandr Frid <afrid@nvidia.com>. Signed-off-by: Paul Walmsley <pwalmsley@nvidia.com> Cc: Andrew Chew <achew@nvidia.com> Reviewed-by: Andrew Chew <achew@nvidia.com> Cc: Matthew Longnecker <mlongnecker@nvidia.com> Cc: Aleksandr Frid <afrid@nvidia.com> Signed-off-by: Mike Turquette <mturquette@linaro.org>
-rw-r--r--drivers/clk/tegra/clk-tegra114.c118
-rw-r--r--drivers/clk/tegra/clk.h4
2 files changed, 122 insertions, 0 deletions
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index 7fe36eaa993b..23244e476615 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -21,6 +21,7 @@
21#include <linux/of.h> 21#include <linux/of.h>
22#include <linux/of_address.h> 22#include <linux/of_address.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/export.h>
24#include <linux/clk/tegra.h> 25#include <linux/clk/tegra.h>
25 26
26#include "clk.h" 27#include "clk.h"
@@ -41,8 +42,33 @@
41#define RST_DEVICES_CLR_V 0x434 42#define RST_DEVICES_CLR_V 0x434
42#define RST_DEVICES_SET_W 0x438 43#define RST_DEVICES_SET_W 0x438
43#define RST_DEVICES_CLR_W 0x43c 44#define RST_DEVICES_CLR_W 0x43c
45#define CPU_FINETRIM_SELECT 0x4d4 /* override default prop dlys */
46#define CPU_FINETRIM_DR 0x4d8 /* rise->rise prop dly A */
47#define CPU_FINETRIM_R 0x4e4 /* rise->rise prop dly inc A */
44#define RST_DEVICES_NUM 5 48#define RST_DEVICES_NUM 5
45 49
50/* CPU_FINETRIM_SELECT and CPU_FINETRIM_DR bitfields */
51#define CPU_FINETRIM_1_FCPU_1 BIT(0) /* fcpu0 */
52#define CPU_FINETRIM_1_FCPU_2 BIT(1) /* fcpu1 */
53#define CPU_FINETRIM_1_FCPU_3 BIT(2) /* fcpu2 */
54#define CPU_FINETRIM_1_FCPU_4 BIT(3) /* fcpu3 */
55#define CPU_FINETRIM_1_FCPU_5 BIT(4) /* fl2 */
56#define CPU_FINETRIM_1_FCPU_6 BIT(5) /* ftop */
57
58/* CPU_FINETRIM_R bitfields */
59#define CPU_FINETRIM_R_FCPU_1_SHIFT 0 /* fcpu0 */
60#define CPU_FINETRIM_R_FCPU_1_MASK (0x3 << CPU_FINETRIM_R_FCPU_1_SHIFT)
61#define CPU_FINETRIM_R_FCPU_2_SHIFT 2 /* fcpu1 */
62#define CPU_FINETRIM_R_FCPU_2_MASK (0x3 << CPU_FINETRIM_R_FCPU_2_SHIFT)
63#define CPU_FINETRIM_R_FCPU_3_SHIFT 4 /* fcpu2 */
64#define CPU_FINETRIM_R_FCPU_3_MASK (0x3 << CPU_FINETRIM_R_FCPU_3_SHIFT)
65#define CPU_FINETRIM_R_FCPU_4_SHIFT 6 /* fcpu3 */
66#define CPU_FINETRIM_R_FCPU_4_MASK (0x3 << CPU_FINETRIM_R_FCPU_4_SHIFT)
67#define CPU_FINETRIM_R_FCPU_5_SHIFT 8 /* fl2 */
68#define CPU_FINETRIM_R_FCPU_5_MASK (0x3 << CPU_FINETRIM_R_FCPU_5_SHIFT)
69#define CPU_FINETRIM_R_FCPU_6_SHIFT 10 /* ftop */
70#define CPU_FINETRIM_R_FCPU_6_MASK (0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT)
71
46#define CLK_OUT_ENB_L 0x010 72#define CLK_OUT_ENB_L 0x010
47#define CLK_OUT_ENB_H 0x014 73#define CLK_OUT_ENB_H 0x014
48#define CLK_OUT_ENB_U 0x018 74#define CLK_OUT_ENB_U 0x018
@@ -2119,6 +2145,98 @@ static void __init tegra114_clock_apply_init_table(void)
2119 tegra_init_from_table(init_table, clks, clk_max); 2145 tegra_init_from_table(init_table, clks, clk_max);
2120} 2146}
2121 2147
2148
2149/**
2150 * tegra114_car_barrier - wait for pending writes to the CAR to complete
2151 *
2152 * Wait for any outstanding writes to the CAR MMIO space from this CPU
2153 * to complete before continuing execution. No return value.
2154 */
2155static void tegra114_car_barrier(void)
2156{
2157 wmb(); /* probably unnecessary */
2158 readl_relaxed(clk_base + CPU_FINETRIM_SELECT);
2159}
2160
2161/**
2162 * tegra114_clock_tune_cpu_trimmers_high - use high-voltage propagation delays
2163 *
2164 * When the CPU rail voltage is in the high-voltage range, use the
2165 * built-in hardwired clock propagation delays in the CPU clock
2166 * shaper. No return value.
2167 */
2168void tegra114_clock_tune_cpu_trimmers_high(void)
2169{
2170 u32 select = 0;
2171
2172 /* Use hardwired rise->rise & fall->fall clock propagation delays */
2173 select |= ~(CPU_FINETRIM_1_FCPU_1 | CPU_FINETRIM_1_FCPU_2 |
2174 CPU_FINETRIM_1_FCPU_3 | CPU_FINETRIM_1_FCPU_4 |
2175 CPU_FINETRIM_1_FCPU_5 | CPU_FINETRIM_1_FCPU_6);
2176 writel_relaxed(select, clk_base + CPU_FINETRIM_SELECT);
2177
2178 tegra114_car_barrier();
2179}
2180EXPORT_SYMBOL(tegra114_clock_tune_cpu_trimmers_high);
2181
2182/**
2183 * tegra114_clock_tune_cpu_trimmers_low - use low-voltage propagation delays
2184 *
2185 * When the CPU rail voltage is in the low-voltage range, use the
2186 * extended clock propagation delays set by
2187 * tegra114_clock_tune_cpu_trimmers_init(). The intention is to
2188 * maintain the input clock duty cycle that the FCPU subsystem
2189 * expects. No return value.
2190 */
2191void tegra114_clock_tune_cpu_trimmers_low(void)
2192{
2193 u32 select = 0;
2194
2195 /*
2196 * Use software-specified rise->rise & fall->fall clock
2197 * propagation delays (from
2198 * tegra114_clock_tune_cpu_trimmers_init()
2199 */
2200 select |= (CPU_FINETRIM_1_FCPU_1 | CPU_FINETRIM_1_FCPU_2 |
2201 CPU_FINETRIM_1_FCPU_3 | CPU_FINETRIM_1_FCPU_4 |
2202 CPU_FINETRIM_1_FCPU_5 | CPU_FINETRIM_1_FCPU_6);
2203 writel_relaxed(select, clk_base + CPU_FINETRIM_SELECT);
2204
2205 tegra114_car_barrier();
2206}
2207EXPORT_SYMBOL(tegra114_clock_tune_cpu_trimmers_low);
2208
2209/**
2210 * tegra114_clock_tune_cpu_trimmers_init - set up and enable clk prop delays
2211 *
2212 * Program extended clock propagation delays into the FCPU clock
2213 * shaper and enable them. XXX Define the purpose - peak current
2214 * reduction? No return value.
2215 */
2216/* XXX Initial voltage rail state assumption issues? */
2217void tegra114_clock_tune_cpu_trimmers_init(void)
2218{
2219 u32 dr = 0, r = 0;
2220
2221 /* Increment the rise->rise clock delay by four steps */
2222 r |= (CPU_FINETRIM_R_FCPU_1_MASK | CPU_FINETRIM_R_FCPU_2_MASK |
2223 CPU_FINETRIM_R_FCPU_3_MASK | CPU_FINETRIM_R_FCPU_4_MASK |
2224 CPU_FINETRIM_R_FCPU_5_MASK | CPU_FINETRIM_R_FCPU_6_MASK);
2225 writel_relaxed(r, clk_base + CPU_FINETRIM_R);
2226
2227 /*
2228 * Use the rise->rise clock propagation delay specified in the
2229 * r field
2230 */
2231 dr |= (CPU_FINETRIM_1_FCPU_1 | CPU_FINETRIM_1_FCPU_2 |
2232 CPU_FINETRIM_1_FCPU_3 | CPU_FINETRIM_1_FCPU_4 |
2233 CPU_FINETRIM_1_FCPU_5 | CPU_FINETRIM_1_FCPU_6);
2234 writel_relaxed(dr, clk_base + CPU_FINETRIM_DR);
2235
2236 tegra114_clock_tune_cpu_trimmers_low();
2237}
2238EXPORT_SYMBOL(tegra114_clock_tune_cpu_trimmers_init);
2239
2122static void __init tegra114_clock_init(struct device_node *np) 2240static void __init tegra114_clock_init(struct device_node *np)
2123{ 2241{
2124 struct device_node *node; 2242 struct device_node *node;
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index e01ac4608fb0..554814c67825 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -587,6 +587,10 @@ void tegra_init_from_table(struct tegra_clk_init_table *tbl,
587void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, 587void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
588 struct clk *clks[], int clk_max); 588 struct clk *clks[], int clk_max);
589 589
590void tegra114_clock_tune_cpu_trimmers_high(void);
591void tegra114_clock_tune_cpu_trimmers_low(void);
592void tegra114_clock_tune_cpu_trimmers_init(void);
593
590typedef void (*tegra_clk_apply_init_table_func)(void); 594typedef void (*tegra_clk_apply_init_table_func)(void);
591extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table; 595extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
592 596