aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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