Commit | Line | Data |
---|---|---|
73a7f0a9 MP |
1 | /* |
2 | * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. | |
3 | * | |
4 | * Author: | |
5 | * Mikko Perttunen <mperttunen@nvidia.com> | |
6 | * | |
7 | * This software is licensed under the terms of the GNU General Public | |
8 | * License version 2, as published by the Free Software Foundation, and | |
9 | * may be copied, distributed, and modified under those terms. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | */ | |
17 | ||
18 | #include <linux/clk-provider.h> | |
19 | #include <linux/clk.h> | |
20 | #include <linux/clkdev.h> | |
9c77a81f | 21 | #include <linux/debugfs.h> |
73a7f0a9 MP |
22 | #include <linux/delay.h> |
23 | #include <linux/of_address.h> | |
24 | #include <linux/of_platform.h> | |
25 | #include <linux/platform_device.h> | |
26 | #include <linux/sort.h> | |
27 | #include <linux/string.h> | |
28 | ||
29 | #include <soc/tegra/emc.h> | |
30 | #include <soc/tegra/fuse.h> | |
31 | #include <soc/tegra/mc.h> | |
32 | ||
33 | #define EMC_FBIO_CFG5 0x104 | |
34 | #define EMC_FBIO_CFG5_DRAM_TYPE_MASK 0x3 | |
35 | #define EMC_FBIO_CFG5_DRAM_TYPE_SHIFT 0 | |
36 | ||
37 | #define EMC_INTSTATUS 0x0 | |
38 | #define EMC_INTSTATUS_CLKCHANGE_COMPLETE BIT(4) | |
39 | ||
40 | #define EMC_CFG 0xc | |
41 | #define EMC_CFG_DRAM_CLKSTOP_PD BIT(31) | |
42 | #define EMC_CFG_DRAM_CLKSTOP_SR BIT(30) | |
43 | #define EMC_CFG_DRAM_ACPD BIT(29) | |
44 | #define EMC_CFG_DYN_SREF BIT(28) | |
45 | #define EMC_CFG_PWR_MASK ((0xF << 28) | BIT(18)) | |
46 | #define EMC_CFG_DSR_VTTGEN_DRV_EN BIT(18) | |
47 | ||
48 | #define EMC_REFCTRL 0x20 | |
49 | #define EMC_REFCTRL_DEV_SEL_SHIFT 0 | |
50 | #define EMC_REFCTRL_ENABLE BIT(31) | |
51 | ||
52 | #define EMC_TIMING_CONTROL 0x28 | |
53 | #define EMC_RC 0x2c | |
54 | #define EMC_RFC 0x30 | |
55 | #define EMC_RAS 0x34 | |
56 | #define EMC_RP 0x38 | |
57 | #define EMC_R2W 0x3c | |
58 | #define EMC_W2R 0x40 | |
59 | #define EMC_R2P 0x44 | |
60 | #define EMC_W2P 0x48 | |
61 | #define EMC_RD_RCD 0x4c | |
62 | #define EMC_WR_RCD 0x50 | |
63 | #define EMC_RRD 0x54 | |
64 | #define EMC_REXT 0x58 | |
65 | #define EMC_WDV 0x5c | |
66 | #define EMC_QUSE 0x60 | |
67 | #define EMC_QRST 0x64 | |
68 | #define EMC_QSAFE 0x68 | |
69 | #define EMC_RDV 0x6c | |
70 | #define EMC_REFRESH 0x70 | |
71 | #define EMC_BURST_REFRESH_NUM 0x74 | |
72 | #define EMC_PDEX2WR 0x78 | |
73 | #define EMC_PDEX2RD 0x7c | |
74 | #define EMC_PCHG2PDEN 0x80 | |
75 | #define EMC_ACT2PDEN 0x84 | |
76 | #define EMC_AR2PDEN 0x88 | |
77 | #define EMC_RW2PDEN 0x8c | |
78 | #define EMC_TXSR 0x90 | |
79 | #define EMC_TCKE 0x94 | |
80 | #define EMC_TFAW 0x98 | |
81 | #define EMC_TRPAB 0x9c | |
82 | #define EMC_TCLKSTABLE 0xa0 | |
83 | #define EMC_TCLKSTOP 0xa4 | |
84 | #define EMC_TREFBW 0xa8 | |
85 | #define EMC_ODT_WRITE 0xb0 | |
86 | #define EMC_ODT_READ 0xb4 | |
87 | #define EMC_WEXT 0xb8 | |
88 | #define EMC_CTT 0xbc | |
89 | #define EMC_RFC_SLR 0xc0 | |
90 | #define EMC_MRS_WAIT_CNT2 0xc4 | |
91 | ||
92 | #define EMC_MRS_WAIT_CNT 0xc8 | |
93 | #define EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT 0 | |
94 | #define EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK \ | |
95 | (0x3FF << EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT) | |
96 | #define EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT 16 | |
97 | #define EMC_MRS_WAIT_CNT_LONG_WAIT_MASK \ | |
98 | (0x3FF << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT) | |
99 | ||
100 | #define EMC_MRS 0xcc | |
101 | #define EMC_MODE_SET_DLL_RESET BIT(8) | |
102 | #define EMC_MODE_SET_LONG_CNT BIT(26) | |
103 | #define EMC_EMRS 0xd0 | |
104 | #define EMC_REF 0xd4 | |
105 | #define EMC_PRE 0xd8 | |
106 | ||
107 | #define EMC_SELF_REF 0xe0 | |
108 | #define EMC_SELF_REF_CMD_ENABLED BIT(0) | |
109 | #define EMC_SELF_REF_DEV_SEL_SHIFT 30 | |
110 | ||
111 | #define EMC_MRW 0xe8 | |
112 | ||
113 | #define EMC_MRR 0xec | |
114 | #define EMC_MRR_MA_SHIFT 16 | |
115 | #define LPDDR2_MR4_TEMP_SHIFT 0 | |
116 | ||
117 | #define EMC_XM2DQSPADCTRL3 0xf8 | |
118 | #define EMC_FBIO_SPARE 0x100 | |
119 | ||
120 | #define EMC_FBIO_CFG6 0x114 | |
121 | #define EMC_EMRS2 0x12c | |
122 | #define EMC_MRW2 0x134 | |
123 | #define EMC_MRW4 0x13c | |
124 | #define EMC_EINPUT 0x14c | |
125 | #define EMC_EINPUT_DURATION 0x150 | |
126 | #define EMC_PUTERM_EXTRA 0x154 | |
127 | #define EMC_TCKESR 0x158 | |
128 | #define EMC_TPD 0x15c | |
129 | ||
130 | #define EMC_AUTO_CAL_CONFIG 0x2a4 | |
131 | #define EMC_AUTO_CAL_CONFIG_AUTO_CAL_START BIT(31) | |
132 | #define EMC_AUTO_CAL_INTERVAL 0x2a8 | |
133 | #define EMC_AUTO_CAL_STATUS 0x2ac | |
134 | #define EMC_AUTO_CAL_STATUS_ACTIVE BIT(31) | |
135 | #define EMC_STATUS 0x2b4 | |
136 | #define EMC_STATUS_TIMING_UPDATE_STALLED BIT(23) | |
137 | ||
138 | #define EMC_CFG_2 0x2b8 | |
139 | #define EMC_CFG_2_MODE_SHIFT 0 | |
140 | #define EMC_CFG_2_DIS_STP_OB_CLK_DURING_NON_WR BIT(6) | |
141 | ||
142 | #define EMC_CFG_DIG_DLL 0x2bc | |
143 | #define EMC_CFG_DIG_DLL_PERIOD 0x2c0 | |
144 | #define EMC_RDV_MASK 0x2cc | |
145 | #define EMC_WDV_MASK 0x2d0 | |
146 | #define EMC_CTT_DURATION 0x2d8 | |
147 | #define EMC_CTT_TERM_CTRL 0x2dc | |
148 | #define EMC_ZCAL_INTERVAL 0x2e0 | |
149 | #define EMC_ZCAL_WAIT_CNT 0x2e4 | |
150 | ||
151 | #define EMC_ZQ_CAL 0x2ec | |
152 | #define EMC_ZQ_CAL_CMD BIT(0) | |
153 | #define EMC_ZQ_CAL_LONG BIT(4) | |
154 | #define EMC_ZQ_CAL_LONG_CMD_DEV0 \ | |
155 | (DRAM_DEV_SEL_0 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD) | |
156 | #define EMC_ZQ_CAL_LONG_CMD_DEV1 \ | |
157 | (DRAM_DEV_SEL_1 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD) | |
158 | ||
159 | #define EMC_XM2CMDPADCTRL 0x2f0 | |
160 | #define EMC_XM2DQSPADCTRL 0x2f8 | |
161 | #define EMC_XM2DQSPADCTRL2 0x2fc | |
162 | #define EMC_XM2DQSPADCTRL2_RX_FT_REC_ENABLE BIT(0) | |
163 | #define EMC_XM2DQSPADCTRL2_VREF_ENABLE BIT(5) | |
164 | #define EMC_XM2DQPADCTRL 0x300 | |
165 | #define EMC_XM2DQPADCTRL2 0x304 | |
166 | #define EMC_XM2CLKPADCTRL 0x308 | |
167 | #define EMC_XM2COMPPADCTRL 0x30c | |
168 | #define EMC_XM2VTTGENPADCTRL 0x310 | |
169 | #define EMC_XM2VTTGENPADCTRL2 0x314 | |
170 | #define EMC_XM2VTTGENPADCTRL3 0x318 | |
171 | #define EMC_XM2DQSPADCTRL4 0x320 | |
172 | #define EMC_DLL_XFORM_DQS0 0x328 | |
173 | #define EMC_DLL_XFORM_DQS1 0x32c | |
174 | #define EMC_DLL_XFORM_DQS2 0x330 | |
175 | #define EMC_DLL_XFORM_DQS3 0x334 | |
176 | #define EMC_DLL_XFORM_DQS4 0x338 | |
177 | #define EMC_DLL_XFORM_DQS5 0x33c | |
178 | #define EMC_DLL_XFORM_DQS6 0x340 | |
179 | #define EMC_DLL_XFORM_DQS7 0x344 | |
180 | #define EMC_DLL_XFORM_QUSE0 0x348 | |
181 | #define EMC_DLL_XFORM_QUSE1 0x34c | |
182 | #define EMC_DLL_XFORM_QUSE2 0x350 | |
183 | #define EMC_DLL_XFORM_QUSE3 0x354 | |
184 | #define EMC_DLL_XFORM_QUSE4 0x358 | |
185 | #define EMC_DLL_XFORM_QUSE5 0x35c | |
186 | #define EMC_DLL_XFORM_QUSE6 0x360 | |
187 | #define EMC_DLL_XFORM_QUSE7 0x364 | |
188 | #define EMC_DLL_XFORM_DQ0 0x368 | |
189 | #define EMC_DLL_XFORM_DQ1 0x36c | |
190 | #define EMC_DLL_XFORM_DQ2 0x370 | |
191 | #define EMC_DLL_XFORM_DQ3 0x374 | |
192 | #define EMC_DLI_TRIM_TXDQS0 0x3a8 | |
193 | #define EMC_DLI_TRIM_TXDQS1 0x3ac | |
194 | #define EMC_DLI_TRIM_TXDQS2 0x3b0 | |
195 | #define EMC_DLI_TRIM_TXDQS3 0x3b4 | |
196 | #define EMC_DLI_TRIM_TXDQS4 0x3b8 | |
197 | #define EMC_DLI_TRIM_TXDQS5 0x3bc | |
198 | #define EMC_DLI_TRIM_TXDQS6 0x3c0 | |
199 | #define EMC_DLI_TRIM_TXDQS7 0x3c4 | |
200 | #define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 0x3cc | |
201 | #define EMC_SEL_DPD_CTRL 0x3d8 | |
202 | #define EMC_SEL_DPD_CTRL_DATA_SEL_DPD BIT(8) | |
203 | #define EMC_SEL_DPD_CTRL_ODT_SEL_DPD BIT(5) | |
204 | #define EMC_SEL_DPD_CTRL_RESET_SEL_DPD BIT(4) | |
205 | #define EMC_SEL_DPD_CTRL_CA_SEL_DPD BIT(3) | |
206 | #define EMC_SEL_DPD_CTRL_CLK_SEL_DPD BIT(2) | |
207 | #define EMC_SEL_DPD_CTRL_DDR3_MASK \ | |
208 | ((0xf << 2) | BIT(8)) | |
209 | #define EMC_SEL_DPD_CTRL_MASK \ | |
210 | ((0x3 << 2) | BIT(5) | BIT(8)) | |
211 | #define EMC_PRE_REFRESH_REQ_CNT 0x3dc | |
212 | #define EMC_DYN_SELF_REF_CONTROL 0x3e0 | |
213 | #define EMC_TXSRDLL 0x3e4 | |
214 | #define EMC_CCFIFO_ADDR 0x3e8 | |
215 | #define EMC_CCFIFO_DATA 0x3ec | |
216 | #define EMC_CCFIFO_STATUS 0x3f0 | |
217 | #define EMC_CDB_CNTL_1 0x3f4 | |
218 | #define EMC_CDB_CNTL_2 0x3f8 | |
219 | #define EMC_XM2CLKPADCTRL2 0x3fc | |
220 | #define EMC_AUTO_CAL_CONFIG2 0x458 | |
221 | #define EMC_AUTO_CAL_CONFIG3 0x45c | |
222 | #define EMC_IBDLY 0x468 | |
223 | #define EMC_DLL_XFORM_ADDR0 0x46c | |
224 | #define EMC_DLL_XFORM_ADDR1 0x470 | |
225 | #define EMC_DLL_XFORM_ADDR2 0x474 | |
226 | #define EMC_DSR_VTTGEN_DRV 0x47c | |
227 | #define EMC_TXDSRVTTGEN 0x480 | |
228 | #define EMC_XM2CMDPADCTRL4 0x484 | |
229 | #define EMC_XM2CMDPADCTRL5 0x488 | |
230 | #define EMC_DLL_XFORM_DQS8 0x4a0 | |
231 | #define EMC_DLL_XFORM_DQS9 0x4a4 | |
232 | #define EMC_DLL_XFORM_DQS10 0x4a8 | |
233 | #define EMC_DLL_XFORM_DQS11 0x4ac | |
234 | #define EMC_DLL_XFORM_DQS12 0x4b0 | |
235 | #define EMC_DLL_XFORM_DQS13 0x4b4 | |
236 | #define EMC_DLL_XFORM_DQS14 0x4b8 | |
237 | #define EMC_DLL_XFORM_DQS15 0x4bc | |
238 | #define EMC_DLL_XFORM_QUSE8 0x4c0 | |
239 | #define EMC_DLL_XFORM_QUSE9 0x4c4 | |
240 | #define EMC_DLL_XFORM_QUSE10 0x4c8 | |
241 | #define EMC_DLL_XFORM_QUSE11 0x4cc | |
242 | #define EMC_DLL_XFORM_QUSE12 0x4d0 | |
243 | #define EMC_DLL_XFORM_QUSE13 0x4d4 | |
244 | #define EMC_DLL_XFORM_QUSE14 0x4d8 | |
245 | #define EMC_DLL_XFORM_QUSE15 0x4dc | |
246 | #define EMC_DLL_XFORM_DQ4 0x4e0 | |
247 | #define EMC_DLL_XFORM_DQ5 0x4e4 | |
248 | #define EMC_DLL_XFORM_DQ6 0x4e8 | |
249 | #define EMC_DLL_XFORM_DQ7 0x4ec | |
250 | #define EMC_DLI_TRIM_TXDQS8 0x520 | |
251 | #define EMC_DLI_TRIM_TXDQS9 0x524 | |
252 | #define EMC_DLI_TRIM_TXDQS10 0x528 | |
253 | #define EMC_DLI_TRIM_TXDQS11 0x52c | |
254 | #define EMC_DLI_TRIM_TXDQS12 0x530 | |
255 | #define EMC_DLI_TRIM_TXDQS13 0x534 | |
256 | #define EMC_DLI_TRIM_TXDQS14 0x538 | |
257 | #define EMC_DLI_TRIM_TXDQS15 0x53c | |
258 | #define EMC_CDB_CNTL_3 0x540 | |
259 | #define EMC_XM2DQSPADCTRL5 0x544 | |
260 | #define EMC_XM2DQSPADCTRL6 0x548 | |
261 | #define EMC_XM2DQPADCTRL3 0x54c | |
262 | #define EMC_DLL_XFORM_ADDR3 0x550 | |
263 | #define EMC_DLL_XFORM_ADDR4 0x554 | |
264 | #define EMC_DLL_XFORM_ADDR5 0x558 | |
265 | #define EMC_CFG_PIPE 0x560 | |
266 | #define EMC_QPOP 0x564 | |
267 | #define EMC_QUSE_WIDTH 0x568 | |
268 | #define EMC_PUTERM_WIDTH 0x56c | |
269 | #define EMC_BGBIAS_CTL0 0x570 | |
270 | #define EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_RX BIT(3) | |
271 | #define EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_VTTGEN BIT(2) | |
272 | #define EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD BIT(1) | |
273 | #define EMC_PUTERM_ADJ 0x574 | |
274 | ||
275 | #define DRAM_DEV_SEL_ALL 0 | |
276 | #define DRAM_DEV_SEL_0 (2 << 30) | |
277 | #define DRAM_DEV_SEL_1 (1 << 30) | |
278 | ||
279 | #define EMC_CFG_POWER_FEATURES_MASK \ | |
280 | (EMC_CFG_DYN_SREF | EMC_CFG_DRAM_ACPD | EMC_CFG_DRAM_CLKSTOP_SR | \ | |
281 | EMC_CFG_DRAM_CLKSTOP_PD | EMC_CFG_DSR_VTTGEN_DRV_EN) | |
282 | #define EMC_REFCTRL_DEV_SEL(n) (((n > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT) | |
283 | #define EMC_DRAM_DEV_SEL(n) ((n > 1) ? DRAM_DEV_SEL_ALL : DRAM_DEV_SEL_0) | |
284 | ||
285 | /* Maximum amount of time in us. to wait for changes to become effective */ | |
286 | #define EMC_STATUS_UPDATE_TIMEOUT 1000 | |
287 | ||
288 | enum emc_dram_type { | |
289 | DRAM_TYPE_DDR3 = 0, | |
290 | DRAM_TYPE_DDR1 = 1, | |
291 | DRAM_TYPE_LPDDR3 = 2, | |
292 | DRAM_TYPE_DDR2 = 3 | |
293 | }; | |
294 | ||
295 | enum emc_dll_change { | |
296 | DLL_CHANGE_NONE, | |
297 | DLL_CHANGE_ON, | |
298 | DLL_CHANGE_OFF | |
299 | }; | |
300 | ||
301 | static const unsigned long emc_burst_regs[] = { | |
302 | EMC_RC, | |
303 | EMC_RFC, | |
304 | EMC_RFC_SLR, | |
305 | EMC_RAS, | |
306 | EMC_RP, | |
307 | EMC_R2W, | |
308 | EMC_W2R, | |
309 | EMC_R2P, | |
310 | EMC_W2P, | |
311 | EMC_RD_RCD, | |
312 | EMC_WR_RCD, | |
313 | EMC_RRD, | |
314 | EMC_REXT, | |
315 | EMC_WEXT, | |
316 | EMC_WDV, | |
317 | EMC_WDV_MASK, | |
318 | EMC_QUSE, | |
319 | EMC_QUSE_WIDTH, | |
320 | EMC_IBDLY, | |
321 | EMC_EINPUT, | |
322 | EMC_EINPUT_DURATION, | |
323 | EMC_PUTERM_EXTRA, | |
324 | EMC_PUTERM_WIDTH, | |
325 | EMC_PUTERM_ADJ, | |
326 | EMC_CDB_CNTL_1, | |
327 | EMC_CDB_CNTL_2, | |
328 | EMC_CDB_CNTL_3, | |
329 | EMC_QRST, | |
330 | EMC_QSAFE, | |
331 | EMC_RDV, | |
332 | EMC_RDV_MASK, | |
333 | EMC_REFRESH, | |
334 | EMC_BURST_REFRESH_NUM, | |
335 | EMC_PRE_REFRESH_REQ_CNT, | |
336 | EMC_PDEX2WR, | |
337 | EMC_PDEX2RD, | |
338 | EMC_PCHG2PDEN, | |
339 | EMC_ACT2PDEN, | |
340 | EMC_AR2PDEN, | |
341 | EMC_RW2PDEN, | |
342 | EMC_TXSR, | |
343 | EMC_TXSRDLL, | |
344 | EMC_TCKE, | |
345 | EMC_TCKESR, | |
346 | EMC_TPD, | |
347 | EMC_TFAW, | |
348 | EMC_TRPAB, | |
349 | EMC_TCLKSTABLE, | |
350 | EMC_TCLKSTOP, | |
351 | EMC_TREFBW, | |
352 | EMC_FBIO_CFG6, | |
353 | EMC_ODT_WRITE, | |
354 | EMC_ODT_READ, | |
355 | EMC_FBIO_CFG5, | |
356 | EMC_CFG_DIG_DLL, | |
357 | EMC_CFG_DIG_DLL_PERIOD, | |
358 | EMC_DLL_XFORM_DQS0, | |
359 | EMC_DLL_XFORM_DQS1, | |
360 | EMC_DLL_XFORM_DQS2, | |
361 | EMC_DLL_XFORM_DQS3, | |
362 | EMC_DLL_XFORM_DQS4, | |
363 | EMC_DLL_XFORM_DQS5, | |
364 | EMC_DLL_XFORM_DQS6, | |
365 | EMC_DLL_XFORM_DQS7, | |
366 | EMC_DLL_XFORM_DQS8, | |
367 | EMC_DLL_XFORM_DQS9, | |
368 | EMC_DLL_XFORM_DQS10, | |
369 | EMC_DLL_XFORM_DQS11, | |
370 | EMC_DLL_XFORM_DQS12, | |
371 | EMC_DLL_XFORM_DQS13, | |
372 | EMC_DLL_XFORM_DQS14, | |
373 | EMC_DLL_XFORM_DQS15, | |
374 | EMC_DLL_XFORM_QUSE0, | |
375 | EMC_DLL_XFORM_QUSE1, | |
376 | EMC_DLL_XFORM_QUSE2, | |
377 | EMC_DLL_XFORM_QUSE3, | |
378 | EMC_DLL_XFORM_QUSE4, | |
379 | EMC_DLL_XFORM_QUSE5, | |
380 | EMC_DLL_XFORM_QUSE6, | |
381 | EMC_DLL_XFORM_QUSE7, | |
382 | EMC_DLL_XFORM_ADDR0, | |
383 | EMC_DLL_XFORM_ADDR1, | |
384 | EMC_DLL_XFORM_ADDR2, | |
385 | EMC_DLL_XFORM_ADDR3, | |
386 | EMC_DLL_XFORM_ADDR4, | |
387 | EMC_DLL_XFORM_ADDR5, | |
388 | EMC_DLL_XFORM_QUSE8, | |
389 | EMC_DLL_XFORM_QUSE9, | |
390 | EMC_DLL_XFORM_QUSE10, | |
391 | EMC_DLL_XFORM_QUSE11, | |
392 | EMC_DLL_XFORM_QUSE12, | |
393 | EMC_DLL_XFORM_QUSE13, | |
394 | EMC_DLL_XFORM_QUSE14, | |
395 | EMC_DLL_XFORM_QUSE15, | |
396 | EMC_DLI_TRIM_TXDQS0, | |
397 | EMC_DLI_TRIM_TXDQS1, | |
398 | EMC_DLI_TRIM_TXDQS2, | |
399 | EMC_DLI_TRIM_TXDQS3, | |
400 | EMC_DLI_TRIM_TXDQS4, | |
401 | EMC_DLI_TRIM_TXDQS5, | |
402 | EMC_DLI_TRIM_TXDQS6, | |
403 | EMC_DLI_TRIM_TXDQS7, | |
404 | EMC_DLI_TRIM_TXDQS8, | |
405 | EMC_DLI_TRIM_TXDQS9, | |
406 | EMC_DLI_TRIM_TXDQS10, | |
407 | EMC_DLI_TRIM_TXDQS11, | |
408 | EMC_DLI_TRIM_TXDQS12, | |
409 | EMC_DLI_TRIM_TXDQS13, | |
410 | EMC_DLI_TRIM_TXDQS14, | |
411 | EMC_DLI_TRIM_TXDQS15, | |
412 | EMC_DLL_XFORM_DQ0, | |
413 | EMC_DLL_XFORM_DQ1, | |
414 | EMC_DLL_XFORM_DQ2, | |
415 | EMC_DLL_XFORM_DQ3, | |
416 | EMC_DLL_XFORM_DQ4, | |
417 | EMC_DLL_XFORM_DQ5, | |
418 | EMC_DLL_XFORM_DQ6, | |
419 | EMC_DLL_XFORM_DQ7, | |
420 | EMC_XM2CMDPADCTRL, | |
421 | EMC_XM2CMDPADCTRL4, | |
422 | EMC_XM2CMDPADCTRL5, | |
423 | EMC_XM2DQPADCTRL2, | |
424 | EMC_XM2DQPADCTRL3, | |
425 | EMC_XM2CLKPADCTRL, | |
426 | EMC_XM2CLKPADCTRL2, | |
427 | EMC_XM2COMPPADCTRL, | |
428 | EMC_XM2VTTGENPADCTRL, | |
429 | EMC_XM2VTTGENPADCTRL2, | |
430 | EMC_XM2VTTGENPADCTRL3, | |
431 | EMC_XM2DQSPADCTRL3, | |
432 | EMC_XM2DQSPADCTRL4, | |
433 | EMC_XM2DQSPADCTRL5, | |
434 | EMC_XM2DQSPADCTRL6, | |
435 | EMC_DSR_VTTGEN_DRV, | |
436 | EMC_TXDSRVTTGEN, | |
437 | EMC_FBIO_SPARE, | |
438 | EMC_ZCAL_WAIT_CNT, | |
439 | EMC_MRS_WAIT_CNT2, | |
440 | EMC_CTT, | |
441 | EMC_CTT_DURATION, | |
442 | EMC_CFG_PIPE, | |
443 | EMC_DYN_SELF_REF_CONTROL, | |
444 | EMC_QPOP | |
445 | }; | |
446 | ||
447 | struct emc_timing { | |
448 | unsigned long rate; | |
449 | ||
450 | u32 emc_burst_data[ARRAY_SIZE(emc_burst_regs)]; | |
451 | ||
452 | u32 emc_auto_cal_config; | |
453 | u32 emc_auto_cal_config2; | |
454 | u32 emc_auto_cal_config3; | |
455 | u32 emc_auto_cal_interval; | |
456 | u32 emc_bgbias_ctl0; | |
457 | u32 emc_cfg; | |
458 | u32 emc_cfg_2; | |
459 | u32 emc_ctt_term_ctrl; | |
460 | u32 emc_mode_1; | |
461 | u32 emc_mode_2; | |
462 | u32 emc_mode_4; | |
463 | u32 emc_mode_reset; | |
464 | u32 emc_mrs_wait_cnt; | |
465 | u32 emc_sel_dpd_ctrl; | |
466 | u32 emc_xm2dqspadctrl2; | |
467 | u32 emc_zcal_cnt_long; | |
468 | u32 emc_zcal_interval; | |
469 | }; | |
470 | ||
471 | struct tegra_emc { | |
472 | struct device *dev; | |
473 | ||
474 | struct tegra_mc *mc; | |
475 | ||
476 | void __iomem *regs; | |
477 | ||
478 | enum emc_dram_type dram_type; | |
479 | unsigned int dram_num; | |
480 | ||
481 | struct emc_timing last_timing; | |
482 | struct emc_timing *timings; | |
483 | unsigned int num_timings; | |
484 | }; | |
485 | ||
486 | /* Timing change sequence functions */ | |
487 | ||
488 | static void emc_ccfifo_writel(struct tegra_emc *emc, u32 value, | |
489 | unsigned long offset) | |
490 | { | |
491 | writel(value, emc->regs + EMC_CCFIFO_DATA); | |
492 | writel(offset, emc->regs + EMC_CCFIFO_ADDR); | |
493 | } | |
494 | ||
495 | static void emc_seq_update_timing(struct tegra_emc *emc) | |
496 | { | |
497 | unsigned int i; | |
498 | u32 value; | |
499 | ||
500 | writel(1, emc->regs + EMC_TIMING_CONTROL); | |
501 | ||
502 | for (i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; ++i) { | |
503 | value = readl(emc->regs + EMC_STATUS); | |
504 | if ((value & EMC_STATUS_TIMING_UPDATE_STALLED) == 0) | |
505 | return; | |
506 | udelay(1); | |
507 | } | |
508 | ||
509 | dev_err(emc->dev, "timing update timed out\n"); | |
510 | } | |
511 | ||
512 | static void emc_seq_disable_auto_cal(struct tegra_emc *emc) | |
513 | { | |
514 | unsigned int i; | |
515 | u32 value; | |
516 | ||
517 | writel(0, emc->regs + EMC_AUTO_CAL_INTERVAL); | |
518 | ||
519 | for (i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; ++i) { | |
520 | value = readl(emc->regs + EMC_AUTO_CAL_STATUS); | |
521 | if ((value & EMC_AUTO_CAL_STATUS_ACTIVE) == 0) | |
522 | return; | |
523 | udelay(1); | |
524 | } | |
525 | ||
526 | dev_err(emc->dev, "auto cal disable timed out\n"); | |
527 | } | |
528 | ||
529 | static void emc_seq_wait_clkchange(struct tegra_emc *emc) | |
530 | { | |
531 | unsigned int i; | |
532 | u32 value; | |
533 | ||
534 | for (i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; ++i) { | |
535 | value = readl(emc->regs + EMC_INTSTATUS); | |
536 | if (value & EMC_INTSTATUS_CLKCHANGE_COMPLETE) | |
537 | return; | |
538 | udelay(1); | |
539 | } | |
540 | ||
541 | dev_err(emc->dev, "clock change timed out\n"); | |
542 | } | |
543 | ||
544 | static struct emc_timing *tegra_emc_find_timing(struct tegra_emc *emc, | |
545 | unsigned long rate) | |
546 | { | |
547 | struct emc_timing *timing = NULL; | |
548 | unsigned int i; | |
549 | ||
550 | for (i = 0; i < emc->num_timings; i++) { | |
551 | if (emc->timings[i].rate == rate) { | |
552 | timing = &emc->timings[i]; | |
553 | break; | |
554 | } | |
555 | } | |
556 | ||
557 | if (!timing) { | |
558 | dev_err(emc->dev, "no timing for rate %lu\n", rate); | |
559 | return NULL; | |
560 | } | |
561 | ||
562 | return timing; | |
563 | } | |
564 | ||
565 | int tegra_emc_prepare_timing_change(struct tegra_emc *emc, | |
566 | unsigned long rate) | |
567 | { | |
568 | struct emc_timing *timing = tegra_emc_find_timing(emc, rate); | |
569 | struct emc_timing *last = &emc->last_timing; | |
570 | enum emc_dll_change dll_change; | |
571 | unsigned int pre_wait = 0; | |
572 | u32 val, val2, mask; | |
573 | bool update = false; | |
574 | unsigned int i; | |
575 | ||
576 | if (!timing) | |
577 | return -ENOENT; | |
578 | ||
579 | if ((last->emc_mode_1 & 0x1) == (timing->emc_mode_1 & 0x1)) | |
580 | dll_change = DLL_CHANGE_NONE; | |
581 | else if (timing->emc_mode_1 & 0x1) | |
582 | dll_change = DLL_CHANGE_ON; | |
583 | else | |
584 | dll_change = DLL_CHANGE_OFF; | |
585 | ||
586 | /* Clear CLKCHANGE_COMPLETE interrupts */ | |
587 | writel(EMC_INTSTATUS_CLKCHANGE_COMPLETE, emc->regs + EMC_INTSTATUS); | |
588 | ||
589 | /* Disable dynamic self-refresh */ | |
590 | val = readl(emc->regs + EMC_CFG); | |
591 | if (val & EMC_CFG_PWR_MASK) { | |
592 | val &= ~EMC_CFG_POWER_FEATURES_MASK; | |
593 | writel(val, emc->regs + EMC_CFG); | |
594 | ||
595 | pre_wait = 5; | |
596 | } | |
597 | ||
598 | /* Disable SEL_DPD_CTRL for clock change */ | |
599 | if (emc->dram_type == DRAM_TYPE_DDR3) | |
600 | mask = EMC_SEL_DPD_CTRL_DDR3_MASK; | |
601 | else | |
602 | mask = EMC_SEL_DPD_CTRL_MASK; | |
603 | ||
604 | val = readl(emc->regs + EMC_SEL_DPD_CTRL); | |
605 | if (val & mask) { | |
606 | val &= ~mask; | |
607 | writel(val, emc->regs + EMC_SEL_DPD_CTRL); | |
608 | } | |
609 | ||
610 | /* Prepare DQ/DQS for clock change */ | |
611 | val = readl(emc->regs + EMC_BGBIAS_CTL0); | |
612 | val2 = last->emc_bgbias_ctl0; | |
613 | if (!(timing->emc_bgbias_ctl0 & | |
614 | EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_RX) && | |
615 | (val & EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_RX)) { | |
616 | val2 &= ~EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_RX; | |
617 | update = true; | |
618 | } | |
619 | ||
620 | if ((val & EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD) || | |
621 | (val & EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_VTTGEN)) { | |
622 | update = true; | |
623 | } | |
624 | ||
625 | if (update) { | |
626 | writel(val2, emc->regs + EMC_BGBIAS_CTL0); | |
627 | if (pre_wait < 5) | |
628 | pre_wait = 5; | |
629 | } | |
630 | ||
631 | update = false; | |
632 | val = readl(emc->regs + EMC_XM2DQSPADCTRL2); | |
633 | if (timing->emc_xm2dqspadctrl2 & EMC_XM2DQSPADCTRL2_VREF_ENABLE && | |
634 | !(val & EMC_XM2DQSPADCTRL2_VREF_ENABLE)) { | |
635 | val |= EMC_XM2DQSPADCTRL2_VREF_ENABLE; | |
636 | update = true; | |
637 | } | |
638 | ||
639 | if (timing->emc_xm2dqspadctrl2 & EMC_XM2DQSPADCTRL2_RX_FT_REC_ENABLE && | |
640 | !(val & EMC_XM2DQSPADCTRL2_RX_FT_REC_ENABLE)) { | |
641 | val |= EMC_XM2DQSPADCTRL2_RX_FT_REC_ENABLE; | |
642 | update = true; | |
643 | } | |
644 | ||
645 | if (update) { | |
646 | writel(val, emc->regs + EMC_XM2DQSPADCTRL2); | |
647 | if (pre_wait < 30) | |
648 | pre_wait = 30; | |
649 | } | |
650 | ||
651 | /* Wait to settle */ | |
652 | if (pre_wait) { | |
653 | emc_seq_update_timing(emc); | |
654 | udelay(pre_wait); | |
655 | } | |
656 | ||
657 | /* Program CTT_TERM control */ | |
658 | if (last->emc_ctt_term_ctrl != timing->emc_ctt_term_ctrl) { | |
659 | emc_seq_disable_auto_cal(emc); | |
660 | writel(timing->emc_ctt_term_ctrl, | |
661 | emc->regs + EMC_CTT_TERM_CTRL); | |
662 | emc_seq_update_timing(emc); | |
663 | } | |
664 | ||
665 | /* Program burst shadow registers */ | |
666 | for (i = 0; i < ARRAY_SIZE(timing->emc_burst_data); ++i) | |
667 | writel(timing->emc_burst_data[i], | |
668 | emc->regs + emc_burst_regs[i]); | |
669 | ||
670 | writel(timing->emc_xm2dqspadctrl2, emc->regs + EMC_XM2DQSPADCTRL2); | |
671 | writel(timing->emc_zcal_interval, emc->regs + EMC_ZCAL_INTERVAL); | |
672 | ||
673 | tegra_mc_write_emem_configuration(emc->mc, timing->rate); | |
674 | ||
675 | val = timing->emc_cfg & ~EMC_CFG_POWER_FEATURES_MASK; | |
676 | emc_ccfifo_writel(emc, val, EMC_CFG); | |
677 | ||
678 | /* Program AUTO_CAL_CONFIG */ | |
679 | if (timing->emc_auto_cal_config2 != last->emc_auto_cal_config2) | |
680 | emc_ccfifo_writel(emc, timing->emc_auto_cal_config2, | |
681 | EMC_AUTO_CAL_CONFIG2); | |
682 | ||
683 | if (timing->emc_auto_cal_config3 != last->emc_auto_cal_config3) | |
684 | emc_ccfifo_writel(emc, timing->emc_auto_cal_config3, | |
685 | EMC_AUTO_CAL_CONFIG3); | |
686 | ||
687 | if (timing->emc_auto_cal_config != last->emc_auto_cal_config) { | |
688 | val = timing->emc_auto_cal_config; | |
689 | val &= EMC_AUTO_CAL_CONFIG_AUTO_CAL_START; | |
690 | emc_ccfifo_writel(emc, val, EMC_AUTO_CAL_CONFIG); | |
691 | } | |
692 | ||
693 | /* DDR3: predict MRS long wait count */ | |
694 | if (emc->dram_type == DRAM_TYPE_DDR3 && | |
695 | dll_change == DLL_CHANGE_ON) { | |
696 | u32 cnt = 512; | |
697 | ||
698 | if (timing->emc_zcal_interval != 0 && | |
699 | last->emc_zcal_interval == 0) | |
700 | cnt -= emc->dram_num * 256; | |
701 | ||
702 | val = (timing->emc_mrs_wait_cnt | |
703 | & EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK) | |
704 | >> EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT; | |
705 | if (cnt < val) | |
706 | cnt = val; | |
707 | ||
708 | val = timing->emc_mrs_wait_cnt | |
709 | & ~EMC_MRS_WAIT_CNT_LONG_WAIT_MASK; | |
710 | val |= (cnt << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT) | |
711 | & EMC_MRS_WAIT_CNT_LONG_WAIT_MASK; | |
712 | ||
713 | writel(val, emc->regs + EMC_MRS_WAIT_CNT); | |
714 | } | |
715 | ||
716 | val = timing->emc_cfg_2; | |
717 | val &= ~EMC_CFG_2_DIS_STP_OB_CLK_DURING_NON_WR; | |
718 | emc_ccfifo_writel(emc, val, EMC_CFG_2); | |
719 | ||
720 | /* DDR3: Turn off DLL and enter self-refresh */ | |
721 | if (emc->dram_type == DRAM_TYPE_DDR3 && dll_change == DLL_CHANGE_OFF) | |
722 | emc_ccfifo_writel(emc, timing->emc_mode_1, EMC_EMRS); | |
723 | ||
724 | /* Disable refresh controller */ | |
725 | emc_ccfifo_writel(emc, EMC_REFCTRL_DEV_SEL(emc->dram_num), | |
726 | EMC_REFCTRL); | |
727 | if (emc->dram_type == DRAM_TYPE_DDR3) | |
728 | emc_ccfifo_writel(emc, EMC_DRAM_DEV_SEL(emc->dram_num) | | |
729 | EMC_SELF_REF_CMD_ENABLED, | |
730 | EMC_SELF_REF); | |
731 | ||
732 | /* Flow control marker */ | |
733 | emc_ccfifo_writel(emc, 1, EMC_STALL_THEN_EXE_AFTER_CLKCHANGE); | |
734 | ||
735 | /* DDR3: Exit self-refresh */ | |
736 | if (emc->dram_type == DRAM_TYPE_DDR3) | |
737 | emc_ccfifo_writel(emc, EMC_DRAM_DEV_SEL(emc->dram_num), | |
738 | EMC_SELF_REF); | |
739 | emc_ccfifo_writel(emc, EMC_REFCTRL_DEV_SEL(emc->dram_num) | | |
740 | EMC_REFCTRL_ENABLE, | |
741 | EMC_REFCTRL); | |
742 | ||
743 | /* Set DRAM mode registers */ | |
744 | if (emc->dram_type == DRAM_TYPE_DDR3) { | |
745 | if (timing->emc_mode_1 != last->emc_mode_1) | |
746 | emc_ccfifo_writel(emc, timing->emc_mode_1, EMC_EMRS); | |
747 | if (timing->emc_mode_2 != last->emc_mode_2) | |
748 | emc_ccfifo_writel(emc, timing->emc_mode_2, EMC_EMRS2); | |
749 | ||
750 | if ((timing->emc_mode_reset != last->emc_mode_reset) || | |
751 | dll_change == DLL_CHANGE_ON) { | |
752 | val = timing->emc_mode_reset; | |
753 | if (dll_change == DLL_CHANGE_ON) { | |
754 | val |= EMC_MODE_SET_DLL_RESET; | |
755 | val |= EMC_MODE_SET_LONG_CNT; | |
756 | } else { | |
757 | val &= ~EMC_MODE_SET_DLL_RESET; | |
758 | } | |
759 | emc_ccfifo_writel(emc, val, EMC_MRS); | |
760 | } | |
761 | } else { | |
762 | if (timing->emc_mode_2 != last->emc_mode_2) | |
763 | emc_ccfifo_writel(emc, timing->emc_mode_2, EMC_MRW2); | |
764 | if (timing->emc_mode_1 != last->emc_mode_1) | |
765 | emc_ccfifo_writel(emc, timing->emc_mode_1, EMC_MRW); | |
766 | if (timing->emc_mode_4 != last->emc_mode_4) | |
767 | emc_ccfifo_writel(emc, timing->emc_mode_4, EMC_MRW4); | |
768 | } | |
769 | ||
770 | /* Issue ZCAL command if turning ZCAL on */ | |
771 | if (timing->emc_zcal_interval != 0 && last->emc_zcal_interval == 0) { | |
772 | emc_ccfifo_writel(emc, EMC_ZQ_CAL_LONG_CMD_DEV0, EMC_ZQ_CAL); | |
773 | if (emc->dram_num > 1) | |
774 | emc_ccfifo_writel(emc, EMC_ZQ_CAL_LONG_CMD_DEV1, | |
775 | EMC_ZQ_CAL); | |
776 | } | |
777 | ||
778 | /* Write to RO register to remove stall after change */ | |
779 | emc_ccfifo_writel(emc, 0, EMC_CCFIFO_STATUS); | |
780 | ||
781 | if (timing->emc_cfg_2 & EMC_CFG_2_DIS_STP_OB_CLK_DURING_NON_WR) | |
782 | emc_ccfifo_writel(emc, timing->emc_cfg_2, EMC_CFG_2); | |
783 | ||
784 | /* Disable AUTO_CAL for clock change */ | |
785 | emc_seq_disable_auto_cal(emc); | |
786 | ||
787 | /* Read register to wait until programming has settled */ | |
788 | readl(emc->regs + EMC_INTSTATUS); | |
789 | ||
790 | return 0; | |
791 | } | |
792 | ||
793 | void tegra_emc_complete_timing_change(struct tegra_emc *emc, | |
794 | unsigned long rate) | |
795 | { | |
796 | struct emc_timing *timing = tegra_emc_find_timing(emc, rate); | |
797 | struct emc_timing *last = &emc->last_timing; | |
798 | u32 val; | |
799 | ||
800 | if (!timing) | |
801 | return; | |
802 | ||
803 | /* Wait until the state machine has settled */ | |
804 | emc_seq_wait_clkchange(emc); | |
805 | ||
806 | /* Restore AUTO_CAL */ | |
807 | if (timing->emc_ctt_term_ctrl != last->emc_ctt_term_ctrl) | |
808 | writel(timing->emc_auto_cal_interval, | |
809 | emc->regs + EMC_AUTO_CAL_INTERVAL); | |
810 | ||
811 | /* Restore dynamic self-refresh */ | |
812 | if (timing->emc_cfg & EMC_CFG_PWR_MASK) | |
813 | writel(timing->emc_cfg, emc->regs + EMC_CFG); | |
814 | ||
815 | /* Set ZCAL wait count */ | |
816 | writel(timing->emc_zcal_cnt_long, emc->regs + EMC_ZCAL_WAIT_CNT); | |
817 | ||
818 | /* LPDDR3: Turn off BGBIAS if low frequency */ | |
819 | if (emc->dram_type == DRAM_TYPE_LPDDR3 && | |
820 | timing->emc_bgbias_ctl0 & | |
821 | EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_RX) { | |
822 | val = timing->emc_bgbias_ctl0; | |
823 | val |= EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_VTTGEN; | |
824 | val |= EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD; | |
825 | writel(val, emc->regs + EMC_BGBIAS_CTL0); | |
826 | } else { | |
827 | if (emc->dram_type == DRAM_TYPE_DDR3 && | |
828 | readl(emc->regs + EMC_BGBIAS_CTL0) != | |
829 | timing->emc_bgbias_ctl0) { | |
830 | writel(timing->emc_bgbias_ctl0, | |
831 | emc->regs + EMC_BGBIAS_CTL0); | |
832 | } | |
833 | ||
834 | writel(timing->emc_auto_cal_interval, | |
835 | emc->regs + EMC_AUTO_CAL_INTERVAL); | |
836 | } | |
837 | ||
838 | /* Wait for timing to settle */ | |
839 | udelay(2); | |
840 | ||
841 | /* Reprogram SEL_DPD_CTRL */ | |
842 | writel(timing->emc_sel_dpd_ctrl, emc->regs + EMC_SEL_DPD_CTRL); | |
843 | emc_seq_update_timing(emc); | |
844 | ||
845 | emc->last_timing = *timing; | |
846 | } | |
847 | ||
848 | /* Initialization and deinitialization */ | |
849 | ||
850 | static void emc_read_current_timing(struct tegra_emc *emc, | |
851 | struct emc_timing *timing) | |
852 | { | |
853 | unsigned int i; | |
854 | ||
855 | for (i = 0; i < ARRAY_SIZE(emc_burst_regs); ++i) | |
856 | timing->emc_burst_data[i] = | |
857 | readl(emc->regs + emc_burst_regs[i]); | |
858 | ||
859 | timing->emc_cfg = readl(emc->regs + EMC_CFG); | |
860 | ||
861 | timing->emc_auto_cal_interval = 0; | |
862 | timing->emc_zcal_cnt_long = 0; | |
863 | timing->emc_mode_1 = 0; | |
864 | timing->emc_mode_2 = 0; | |
865 | timing->emc_mode_4 = 0; | |
866 | timing->emc_mode_reset = 0; | |
867 | } | |
868 | ||
869 | static int emc_init(struct tegra_emc *emc) | |
870 | { | |
871 | emc->dram_type = readl(emc->regs + EMC_FBIO_CFG5); | |
872 | emc->dram_type &= EMC_FBIO_CFG5_DRAM_TYPE_MASK; | |
873 | emc->dram_type >>= EMC_FBIO_CFG5_DRAM_TYPE_SHIFT; | |
874 | ||
875 | emc->dram_num = tegra_mc_get_emem_device_count(emc->mc); | |
876 | ||
877 | emc_read_current_timing(emc, &emc->last_timing); | |
878 | ||
879 | return 0; | |
880 | } | |
881 | ||
882 | static int load_one_timing_from_dt(struct tegra_emc *emc, | |
883 | struct emc_timing *timing, | |
884 | struct device_node *node) | |
885 | { | |
886 | u32 value; | |
887 | int err; | |
888 | ||
889 | err = of_property_read_u32(node, "clock-frequency", &value); | |
890 | if (err) { | |
891 | dev_err(emc->dev, "timing %s: failed to read rate: %d\n", | |
892 | node->name, err); | |
893 | return err; | |
894 | } | |
895 | ||
896 | timing->rate = value; | |
897 | ||
898 | err = of_property_read_u32_array(node, "nvidia,emc-configuration", | |
899 | timing->emc_burst_data, | |
900 | ARRAY_SIZE(timing->emc_burst_data)); | |
901 | if (err) { | |
902 | dev_err(emc->dev, | |
903 | "timing %s: failed to read emc burst data: %d\n", | |
904 | node->name, err); | |
905 | return err; | |
906 | } | |
907 | ||
908 | #define EMC_READ_PROP(prop, dtprop) { \ | |
909 | err = of_property_read_u32(node, dtprop, &timing->prop); \ | |
910 | if (err) { \ | |
911 | dev_err(emc->dev, "timing %s: failed to read " #prop ": %d\n", \ | |
912 | node->name, err); \ | |
913 | return err; \ | |
914 | } \ | |
915 | } | |
916 | ||
917 | EMC_READ_PROP(emc_auto_cal_config, "nvidia,emc-auto-cal-config") | |
918 | EMC_READ_PROP(emc_auto_cal_config2, "nvidia,emc-auto-cal-config2") | |
919 | EMC_READ_PROP(emc_auto_cal_config3, "nvidia,emc-auto-cal-config3") | |
920 | EMC_READ_PROP(emc_auto_cal_interval, "nvidia,emc-auto-cal-interval") | |
921 | EMC_READ_PROP(emc_bgbias_ctl0, "nvidia,emc-bgbias-ctl0") | |
922 | EMC_READ_PROP(emc_cfg, "nvidia,emc-cfg") | |
923 | EMC_READ_PROP(emc_cfg_2, "nvidia,emc-cfg-2") | |
924 | EMC_READ_PROP(emc_ctt_term_ctrl, "nvidia,emc-ctt-term-ctrl") | |
925 | EMC_READ_PROP(emc_mode_1, "nvidia,emc-mode-1") | |
926 | EMC_READ_PROP(emc_mode_2, "nvidia,emc-mode-2") | |
927 | EMC_READ_PROP(emc_mode_4, "nvidia,emc-mode-4") | |
928 | EMC_READ_PROP(emc_mode_reset, "nvidia,emc-mode-reset") | |
929 | EMC_READ_PROP(emc_mrs_wait_cnt, "nvidia,emc-mrs-wait-cnt") | |
930 | EMC_READ_PROP(emc_sel_dpd_ctrl, "nvidia,emc-sel-dpd-ctrl") | |
931 | EMC_READ_PROP(emc_xm2dqspadctrl2, "nvidia,emc-xm2dqspadctrl2") | |
932 | EMC_READ_PROP(emc_zcal_cnt_long, "nvidia,emc-zcal-cnt-long") | |
933 | EMC_READ_PROP(emc_zcal_interval, "nvidia,emc-zcal-interval") | |
934 | ||
935 | #undef EMC_READ_PROP | |
936 | ||
937 | return 0; | |
938 | } | |
939 | ||
940 | static int cmp_timings(const void *_a, const void *_b) | |
941 | { | |
942 | const struct emc_timing *a = _a; | |
943 | const struct emc_timing *b = _b; | |
944 | ||
945 | if (a->rate < b->rate) | |
946 | return -1; | |
947 | else if (a->rate == b->rate) | |
948 | return 0; | |
949 | else | |
950 | return 1; | |
951 | } | |
952 | ||
953 | static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, | |
954 | struct device_node *node) | |
955 | { | |
956 | int child_count = of_get_child_count(node); | |
957 | struct device_node *child; | |
958 | struct emc_timing *timing; | |
959 | unsigned int i = 0; | |
960 | int err; | |
961 | ||
962 | emc->timings = devm_kcalloc(emc->dev, child_count, sizeof(*timing), | |
963 | GFP_KERNEL); | |
964 | if (!emc->timings) | |
965 | return -ENOMEM; | |
966 | ||
967 | emc->num_timings = child_count; | |
968 | ||
969 | for_each_child_of_node(node, child) { | |
970 | timing = &emc->timings[i++]; | |
971 | ||
972 | err = load_one_timing_from_dt(emc, timing, child); | |
aafb197f AKC |
973 | if (err) { |
974 | of_node_put(child); | |
73a7f0a9 | 975 | return err; |
aafb197f | 976 | } |
73a7f0a9 MP |
977 | } |
978 | ||
979 | sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings, | |
980 | NULL); | |
981 | ||
982 | return 0; | |
983 | } | |
984 | ||
985 | static const struct of_device_id tegra_emc_of_match[] = { | |
986 | { .compatible = "nvidia,tegra124-emc" }, | |
987 | {} | |
988 | }; | |
989 | ||
990 | static struct device_node * | |
991 | tegra_emc_find_node_by_ram_code(struct device_node *node, u32 ram_code) | |
992 | { | |
993 | struct device_node *np; | |
994 | int err; | |
995 | ||
996 | for_each_child_of_node(node, np) { | |
997 | u32 value; | |
998 | ||
999 | err = of_property_read_u32(np, "nvidia,ram-code", &value); | |
d1122e4b | 1000 | if (err || (value != ram_code)) |
73a7f0a9 | 1001 | continue; |
73a7f0a9 MP |
1002 | |
1003 | return np; | |
1004 | } | |
1005 | ||
1006 | return NULL; | |
1007 | } | |
1008 | ||
9c77a81f MP |
1009 | /* Debugfs entry */ |
1010 | ||
1011 | static int emc_debug_rate_get(void *data, u64 *rate) | |
1012 | { | |
1013 | struct clk *c = data; | |
1014 | ||
1015 | *rate = clk_get_rate(c); | |
1016 | ||
1017 | return 0; | |
1018 | } | |
1019 | ||
1020 | static int emc_debug_rate_set(void *data, u64 rate) | |
1021 | { | |
1022 | struct clk *c = data; | |
1023 | ||
1024 | return clk_set_rate(c, rate); | |
1025 | } | |
1026 | ||
1027 | DEFINE_SIMPLE_ATTRIBUTE(emc_debug_rate_fops, emc_debug_rate_get, | |
1028 | emc_debug_rate_set, "%lld\n"); | |
1029 | ||
30a636f9 TR |
1030 | static int emc_debug_supported_rates_show(struct seq_file *s, void *data) |
1031 | { | |
1032 | struct tegra_emc *emc = s->private; | |
1033 | const char *prefix = ""; | |
1034 | unsigned int i; | |
1035 | ||
1036 | for (i = 0; i < emc->num_timings; i++) { | |
1037 | struct emc_timing *timing = &emc->timings[i]; | |
1038 | ||
1039 | seq_printf(s, "%s%lu", prefix, timing->rate); | |
1040 | ||
1041 | prefix = " "; | |
1042 | } | |
1043 | ||
1044 | seq_puts(s, "\n"); | |
1045 | ||
1046 | return 0; | |
1047 | } | |
1048 | ||
1049 | static int emc_debug_supported_rates_open(struct inode *inode, | |
1050 | struct file *file) | |
1051 | { | |
1052 | return single_open(file, emc_debug_supported_rates_show, | |
1053 | inode->i_private); | |
1054 | } | |
1055 | ||
1056 | static const struct file_operations emc_debug_supported_rates_fops = { | |
1057 | .open = emc_debug_supported_rates_open, | |
1058 | .read = seq_read, | |
1059 | .llseek = seq_lseek, | |
1060 | .release = single_release, | |
1061 | }; | |
1062 | ||
1063 | static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc) | |
9c77a81f MP |
1064 | { |
1065 | struct dentry *root, *file; | |
1066 | struct clk *clk; | |
1067 | ||
1068 | root = debugfs_create_dir("emc", NULL); | |
1069 | if (!root) { | |
1070 | dev_err(dev, "failed to create debugfs directory\n"); | |
1071 | return; | |
1072 | } | |
1073 | ||
1074 | clk = clk_get_sys("tegra-clk-debug", "emc"); | |
1075 | if (IS_ERR(clk)) { | |
1076 | dev_err(dev, "failed to get debug clock: %ld\n", PTR_ERR(clk)); | |
1077 | return; | |
1078 | } | |
1079 | ||
1080 | file = debugfs_create_file("rate", S_IRUGO | S_IWUSR, root, clk, | |
1081 | &emc_debug_rate_fops); | |
1082 | if (!file) | |
1083 | dev_err(dev, "failed to create debugfs entry\n"); | |
30a636f9 TR |
1084 | |
1085 | file = debugfs_create_file("supported_rates", S_IRUGO, root, emc, | |
1086 | &emc_debug_supported_rates_fops); | |
1087 | if (!file) | |
1088 | dev_err(dev, "failed to create debugfs entry\n"); | |
9c77a81f MP |
1089 | } |
1090 | ||
73a7f0a9 MP |
1091 | static int tegra_emc_probe(struct platform_device *pdev) |
1092 | { | |
1093 | struct platform_device *mc; | |
1094 | struct device_node *np; | |
1095 | struct tegra_emc *emc; | |
1096 | struct resource *res; | |
1097 | u32 ram_code; | |
1098 | int err; | |
1099 | ||
1100 | emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL); | |
1101 | if (!emc) | |
1102 | return -ENOMEM; | |
1103 | ||
1104 | emc->dev = &pdev->dev; | |
1105 | ||
1106 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
1107 | emc->regs = devm_ioremap_resource(&pdev->dev, res); | |
1108 | if (IS_ERR(emc->regs)) | |
1109 | return PTR_ERR(emc->regs); | |
1110 | ||
1111 | np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0); | |
1112 | if (!np) { | |
1113 | dev_err(&pdev->dev, "could not get memory controller\n"); | |
1114 | return -ENOENT; | |
1115 | } | |
1116 | ||
1117 | mc = of_find_device_by_node(np); | |
1118 | if (!mc) | |
1119 | return -ENOENT; | |
1120 | ||
1121 | of_node_put(np); | |
1122 | ||
1123 | emc->mc = platform_get_drvdata(mc); | |
1124 | if (!emc->mc) | |
1125 | return -EPROBE_DEFER; | |
1126 | ||
1127 | ram_code = tegra_read_ram_code(); | |
1128 | ||
1129 | np = tegra_emc_find_node_by_ram_code(pdev->dev.of_node, ram_code); | |
1130 | if (!np) { | |
1131 | dev_err(&pdev->dev, | |
1132 | "no memory timings for RAM code %u found in DT\n", | |
1133 | ram_code); | |
1134 | return -ENOENT; | |
1135 | } | |
1136 | ||
1137 | err = tegra_emc_load_timings_from_dt(emc, np); | |
1138 | ||
1139 | of_node_put(np); | |
1140 | ||
1141 | if (err) | |
1142 | return err; | |
1143 | ||
1144 | if (emc->num_timings == 0) { | |
1145 | dev_err(&pdev->dev, | |
1146 | "no memory timings for RAM code %u registered\n", | |
1147 | ram_code); | |
1148 | return -ENOENT; | |
1149 | } | |
1150 | ||
1151 | err = emc_init(emc); | |
1152 | if (err) { | |
1153 | dev_err(&pdev->dev, "EMC initialization failed: %d\n", err); | |
1154 | return err; | |
1155 | } | |
1156 | ||
1157 | platform_set_drvdata(pdev, emc); | |
1158 | ||
9c77a81f | 1159 | if (IS_ENABLED(CONFIG_DEBUG_FS)) |
30a636f9 | 1160 | emc_debugfs_init(&pdev->dev, emc); |
9c77a81f | 1161 | |
73a7f0a9 MP |
1162 | return 0; |
1163 | }; | |
1164 | ||
1165 | static struct platform_driver tegra_emc_driver = { | |
1166 | .probe = tegra_emc_probe, | |
1167 | .driver = { | |
1168 | .name = "tegra-emc", | |
1169 | .of_match_table = tegra_emc_of_match, | |
1170 | .suppress_bind_attrs = true, | |
1171 | }, | |
1172 | }; | |
1173 | ||
1174 | static int tegra_emc_init(void) | |
1175 | { | |
1176 | return platform_driver_register(&tegra_emc_driver); | |
1177 | } | |
1178 | subsys_initcall(tegra_emc_init); |