ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[linux-3.10.git] / arch / arm / mach-tegra / mc.c
1 /*
2  * arch/arm/mach-tegra/mc.c
3  *
4  * Copyright (C) 2010 Google, Inc.
5  * Copyright (C) 2011-2014, NVIDIA Corporation.  All rights reserved.
6  *
7  * Author:
8  *      Erik Gilling <konkers@google.com>
9  *
10  * This software is licensed under the terms of the GNU General Public
11  * License version 2, as published by the Free Software Foundation, and
12  * may be copied, distributed, and modified under those terms.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/export.h>
24 #include <linux/spinlock.h>
25 #include <linux/delay.h>
26 #include <linux/debugfs.h>
27 #include <linux/tegra-soc.h>
28
29 #include <mach/mc.h>
30 #include <mach/mcerr.h>
31
32 #include "iomap.h"
33
34 #define MC_CLIENT_HOTRESET_CTRL         0x200
35 #define MC_CLIENT_HOTRESET_STAT         0x204
36 #define MC_CLIENT_HOTRESET_CTRL_1       0x970
37 #define MC_CLIENT_HOTRESET_STAT_1       0x974
38
39 #define MC_TIMING_REG_NUM1                                      \
40         ((MC_EMEM_ARB_TIMING_W2R - MC_EMEM_ARB_CFG) / 4 + 1)
41 #define MC_TIMING_REG_NUM2                                      \
42         ((MC_EMEM_ARB_MISC1 - MC_EMEM_ARB_DA_TURNS) / 4 + 1)
43 #if defined(CONFIG_ARCH_TEGRA_12x_SOC)
44 #define MC_TIMING_REG_NUM3      T12X_MC_LATENCY_ALLOWANCE_NUM_REGS
45 #else
46 #define MC_TIMING_REG_NUM3                                              \
47         ((MC_LATENCY_ALLOWANCE_VI_2 - MC_LATENCY_ALLOWANCE_BASE) / 4 + 1)
48 #endif
49
50 static DEFINE_SPINLOCK(tegra_mc_lock);
51 void __iomem *mc = (void __iomem *)IO_ADDRESS(TEGRA_MC_BASE);
52 #ifdef MC_DUAL_CHANNEL
53 void __iomem *mc1 = (void __iomem *)IO_ADDRESS(TEGRA_MC1_BASE);
54 #endif
55
56 #ifdef CONFIG_PM_SLEEP
57 static u32 mc_boot_timing[MC_TIMING_REG_NUM1 + MC_TIMING_REG_NUM2
58                           + MC_TIMING_REG_NUM3 + 4];
59
60 static void tegra_mc_timing_save(void)
61 {
62         u32 off;
63         u32 *ctx = mc_boot_timing;
64
65         for (off = MC_EMEM_ARB_CFG; off <= MC_EMEM_ARB_TIMING_W2R; off += 4)
66                 *ctx++ = mc_readl(off);
67
68         for (off = MC_EMEM_ARB_DA_TURNS; off <= MC_EMEM_ARB_MISC1; off += 4)
69                 *ctx++ = mc_readl(off);
70
71         *ctx++ = mc_readl(MC_EMEM_ARB_RING3_THROTTLE);
72         *ctx++ = mc_readl(MC_EMEM_ARB_OVERRIDE);
73         *ctx++ = mc_readl(MC_RESERVED_RSV);
74
75 #if defined(CONFIG_ARCH_TEGRA_12x_SOC)
76         tegra12_mc_latency_allowance_save(&ctx);
77 #else
78         for (off = MC_LATENCY_ALLOWANCE_BASE; off <= MC_LATENCY_ALLOWANCE_VI_2;
79                 off += 4)
80                 *ctx++ = mc_readl(off);
81 #endif
82
83         *ctx++ = mc_readl(MC_INT_MASK);
84 }
85
86 void tegra_mc_timing_restore(void)
87 {
88         u32 off;
89         u32 *ctx = mc_boot_timing;
90
91         for (off = MC_EMEM_ARB_CFG; off <= MC_EMEM_ARB_TIMING_W2R; off += 4)
92                 __mc_raw_writel(0, *ctx++, off);
93
94         for (off = MC_EMEM_ARB_DA_TURNS; off <= MC_EMEM_ARB_MISC1; off += 4)
95                 __mc_raw_writel(0, *ctx++, off);
96
97         __mc_raw_writel(0, *ctx++, MC_EMEM_ARB_RING3_THROTTLE);
98         __mc_raw_writel(0, *ctx++, MC_EMEM_ARB_OVERRIDE);
99         __mc_raw_writel(0, *ctx++, MC_RESERVED_RSV);
100
101 #if defined(CONFIG_ARCH_TEGRA_12x_SOC)
102         tegra12_mc_latency_allowance_restore(&ctx);
103 #else
104         for (off = MC_LATENCY_ALLOWANCE_BASE; off <= MC_LATENCY_ALLOWANCE_VI_2;
105                 off += 4)
106                 __mc_raw_writel(0, *ctx++, off);
107 #endif
108
109         mc_writel(*ctx++, MC_INT_MASK);
110         off = mc_readl(MC_INT_MASK);
111
112         mc_writel(0x1, MC_TIMING_CONTROL);
113         off = mc_readl(MC_TIMING_CONTROL);
114 #if defined(CONFIG_ARCH_TEGRA_3x_SOC)
115         /* Bug 1059264
116          * Set extra snap level to avoid VI starving and dropping data.
117          */
118         mc_writel(1, MC_VE_EXTRA_SNAP_LEVELS);
119 #endif
120 }
121 #else
122 #define tegra_mc_timing_save()
123 #endif
124
125 /*
126  * If using T30/DDR3, the 2nd 16 bytes part of DDR3 atom is 2nd line and is
127  * discarded in tiling mode.
128  */
129 int tegra_mc_get_tiled_memory_bandwidth_multiplier(void)
130 {
131         int type;
132
133         type = tegra_emc_get_dram_type();
134
135         if (type == DRAM_TYPE_DDR3)
136                 return 2;
137         else
138                 return 1;
139 }
140
141 /* API to get EMC freq to be requested, for Bandwidth.
142  * bw_kbps: BandWidth passed is in KBps.
143  * returns freq in KHz
144  */
145 unsigned int tegra_emc_bw_to_freq_req(unsigned int bw_kbps)
146 {
147         unsigned int freq;
148         unsigned int bytes_per_emc_clk;
149
150         bytes_per_emc_clk = tegra_mc_get_effective_bytes_width() * 2;
151         freq = (bw_kbps + bytes_per_emc_clk - 1) / bytes_per_emc_clk *
152                 CONFIG_TEGRA_EMC_TO_DDR_CLOCK;
153         return freq;
154 }
155 EXPORT_SYMBOL_GPL(tegra_emc_bw_to_freq_req);
156
157 /* API to get EMC bandwidth, for freq that can be requested.
158  * freq_khz: Frequency passed is in KHz.
159  * returns bandwidth in KBps
160  */
161 unsigned int tegra_emc_freq_req_to_bw(unsigned int freq_khz)
162 {
163         unsigned int bw;
164         unsigned int bytes_per_emc_clk;
165
166         bytes_per_emc_clk = tegra_mc_get_effective_bytes_width() * 2;
167         bw = freq_khz * bytes_per_emc_clk / CONFIG_TEGRA_EMC_TO_DDR_CLOCK;
168         return bw;
169 }
170 EXPORT_SYMBOL_GPL(tegra_emc_freq_req_to_bw);
171
172 #define HOTRESET_READ_COUNT     5
173 static bool tegra_stable_hotreset_check(u32 stat_reg, u32 *stat)
174 {
175         int i;
176         u32 cur_stat;
177         u32 prv_stat;
178         unsigned long flags;
179
180         spin_lock_irqsave(&tegra_mc_lock, flags);
181         prv_stat = mc_readl(stat_reg);
182         for (i = 0; i < HOTRESET_READ_COUNT; i++) {
183                 cur_stat = mc_readl(stat_reg);
184                 if (cur_stat != prv_stat) {
185                         spin_unlock_irqrestore(&tegra_mc_lock, flags);
186                         return false;
187                 }
188         }
189         *stat = cur_stat;
190         spin_unlock_irqrestore(&tegra_mc_lock, flags);
191         return true;
192 }
193
194 int tegra_mc_flush(int id)
195 {
196         u32 rst_ctrl, rst_stat;
197         u32 rst_ctrl_reg, rst_stat_reg;
198         unsigned long flags;
199         bool ret;
200
201         if (id < 32) {
202                 rst_ctrl_reg = MC_CLIENT_HOTRESET_CTRL;
203                 rst_stat_reg = MC_CLIENT_HOTRESET_STAT;
204         } else {
205                 id %= 32;
206                 rst_ctrl_reg = MC_CLIENT_HOTRESET_CTRL_1;
207                 rst_stat_reg = MC_CLIENT_HOTRESET_STAT_1;
208         }
209
210         spin_lock_irqsave(&tegra_mc_lock, flags);
211
212         rst_ctrl = mc_readl(rst_ctrl_reg);
213         rst_ctrl |= (1 << id);
214         mc_writel(rst_ctrl, rst_ctrl_reg);
215
216         spin_unlock_irqrestore(&tegra_mc_lock, flags);
217
218         do {
219                 udelay(10);
220                 rst_stat = 0;
221                 ret = tegra_stable_hotreset_check(rst_stat_reg, &rst_stat);
222                 if (!ret)
223                         continue;
224         } while (!(rst_stat & (1 << id)));
225
226         return 0;
227 }
228 EXPORT_SYMBOL(tegra_mc_flush);
229
230 int tegra_mc_flush_done(int id)
231 {
232         u32 rst_ctrl;
233         u32 rst_ctrl_reg, rst_stat_reg;
234         unsigned long flags;
235
236         if (id < 32) {
237                 rst_ctrl_reg = MC_CLIENT_HOTRESET_CTRL;
238                 rst_stat_reg = MC_CLIENT_HOTRESET_STAT;
239         } else {
240                 id %= 32;
241                 rst_ctrl_reg = MC_CLIENT_HOTRESET_CTRL_1;
242                 rst_stat_reg = MC_CLIENT_HOTRESET_STAT_1;
243         }
244
245         spin_lock_irqsave(&tegra_mc_lock, flags);
246
247         rst_ctrl = mc_readl(rst_ctrl_reg);
248         rst_ctrl &= ~(1 << id);
249         mc_writel(rst_ctrl, rst_ctrl_reg);
250
251         spin_unlock_irqrestore(&tegra_mc_lock, flags);
252
253         return 0;
254 }
255 EXPORT_SYMBOL(tegra_mc_flush_done);
256
257 /*
258  * MC driver init.
259  */
260 static int __init tegra_mc_init(void)
261 {
262
263 #if defined(CONFIG_ARCH_TEGRA_3x_SOC) || \
264                                 defined(CONFIG_TEGRA_MC_EARLY_ACK)
265         u32 reg;
266 #endif
267         struct dentry *mc_debugfs_dir;
268
269         tegra_mc_timing_save();
270
271 #if defined(CONFIG_ARCH_TEGRA_3x_SOC)
272         reg = 0x0f7f1010;
273         mc_writel(reg, MC_RESERVED_RSV);
274 #endif
275
276 #if defined(CONFIG_TEGRA_MC_EARLY_ACK)
277         reg = mc_readl(MC_EMEM_ARB_OVERRIDE);
278         reg |= 3;
279 #if defined(CONFIG_TEGRA_ERRATA_1157520)
280         if (tegra_revision == TEGRA_REVISION_A01)
281                 reg &= ~2;
282 #endif
283         mc_writel(reg, MC_EMEM_ARB_OVERRIDE);
284 #endif
285
286         mc_debugfs_dir = debugfs_create_dir("mc", NULL);
287         if (mc_debugfs_dir == NULL) {
288                 pr_err("Failed to make debugfs node: %ld\n",
289                        PTR_ERR(mc_debugfs_dir));
290                 return PTR_ERR(mc_debugfs_dir);
291         }
292
293         tegra_mcerr_init(mc_debugfs_dir);
294
295         return 0;
296 }
297 arch_initcall(tegra_mc_init);