arm: tegra: tn8-ers: dt: enable support for emc tables
[linux-3.10.git] / arch / arm / mach-tegra / tegra_emc_dt_parse.c
1 /*
2  * arch/arm/mach-tegra/tegra_emc_dt_parse.c
3  *
4  * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  *
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/err.h>
23 #include <linux/of.h>
24 #include <linux/module.h>
25 #include <linux/platform_device.h>
26
27 #include <linux/platform_data/tegra_emc.h>
28
29 #include "fuse.h"
30
31 #ifdef CONFIG_OF
32 static struct device_node *tegra_emc_ramcode_devnode(
33         struct device_node *np)
34 {
35         struct device_node *iter;
36         u32 reg;
37
38         for_each_child_of_node(np, iter) {
39                 if (of_property_read_u32(np, "nvidia,ram-code", &reg))
40                         continue;
41                 if (reg == tegra_get_bct_strapping())
42                         return of_node_get(iter);
43         }
44
45         return NULL;
46 }
47
48 void *tegra_emc_dt_parse_pdata(struct platform_device *pdev)
49 {
50         struct device_node *np = pdev->dev.of_node;
51         struct device_node *tnp, *iter;
52         int ret, i, num_tables;
53         u32 tegra_bct_strapping;
54 #if defined(CONFIG_ARCH_TEGRA_12x_SOC)
55         struct tegra12_emc_pdata *pdata = NULL;
56         const char *comp = "nvidia,tegra12-emc-table";
57 #elif defined(CONFIG_ARCH_TEGRA_11x_SOC)
58         struct tegra11_emc_pdata *pdata = NULL;
59         const char *comp = "nvidia,tegra11-emc-table";
60 #endif
61
62         tegra_bct_strapping = tegra_get_bct_strapping();
63
64         if (!np) {
65                 dev_err(&pdev->dev,
66                         "Unable to find memory-controller node\n");
67                 return NULL;
68         }
69
70         if (of_find_property(np, "nvidia,use-ram-code", NULL)) {
71                 tnp = tegra_emc_ramcode_devnode(np);
72
73                 if (!tnp) {
74                         dev_warn(&pdev->dev,
75                                 "can't find emc table for ram-code 0x%02x\n",
76                                 tegra_bct_strapping);
77                         return NULL;
78                 }
79         } else
80                 tnp = of_node_get(np);
81
82         num_tables = 0;
83         for_each_child_of_node(tnp, iter) {
84                 if (of_device_is_compatible(iter, comp))
85                         num_tables++;
86         }
87
88         if (!num_tables) {
89                 pdata = NULL;
90                 goto out;
91         }
92
93         pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
94         pdata->tables = devm_kzalloc(&pdev->dev,
95                                 sizeof(*pdata->tables) * num_tables,
96                                         GFP_KERNEL);
97
98         if (!pdata->tables)
99                 goto out;
100
101         i = 0;
102         for_each_child_of_node(tnp, iter) {
103                 u32 u;
104                 const char *source_name;
105                 const char *dvfs_ver;
106
107                 ret = of_property_read_u32(iter, "nvidia,revision", &u);
108                 if (ret) {
109                         dev_err(&pdev->dev, "no revision in %s\n",
110                                 iter->full_name);
111                         continue;
112                 }
113                 pdata->tables[i].rev = u;
114
115                 ret = of_property_read_u32(iter, "clock-frequency", &u);
116                 if (ret) {
117                         dev_err(&pdev->dev, "no clock-frequency in %s\n",
118                                 iter->full_name);
119                         continue;
120                 }
121                 pdata->tables[i].rate = u;
122
123                 ret = of_property_read_u32(iter, "nvidia,emc-min-mv", &u);
124                 if (ret) {
125                         dev_err(&pdev->dev, "no emc-min-mv in %s\n",
126                                 iter->full_name);
127                         continue;
128                 }
129                 pdata->tables[i].emc_min_mv = u;
130
131                 ret = of_property_read_string(iter,
132                                         "nvidia,source", &source_name);
133                 if (ret) {
134                         dev_err(&pdev->dev, "no source name in %s\n",
135                                 iter->full_name);
136                         continue;
137                 }
138 #if defined(CONFIG_ARCH_TEGRA_12x_SOC)
139                 strncpy(pdata->tables[i].src_name, source_name, 16);
140 #else
141                 pdata->tables[i].src_name = source_name;
142 #endif
143                 ret = of_property_read_u32(iter, "nvidia,src-sel-reg", &u);
144                 if (ret) {
145                         dev_err(&pdev->dev, "no src-sel-reg in %s\n",
146                                 iter->full_name);
147                         continue;
148                 }
149                 pdata->tables[i].src_sel_reg = u;
150
151                 ret = of_property_read_u32(iter, "nvidia,burst-regs-num", &u);
152                 if (ret) {
153                         dev_err(&pdev->dev, "no burst-regs-num in %s\n",
154                                 iter->full_name);
155                         continue;
156                 }
157                 pdata->tables[i].burst_regs_num = u;
158
159                 ret = of_property_read_u32(iter,
160                                         "nvidia,burst-up-down-regs-num", &u);
161                 if (ret) {
162                         dev_err(&pdev->dev, "no burst-up-down-regs-num in %s\n",
163                                 iter->full_name);
164                         continue;
165                 }
166                 pdata->tables[i].burst_up_down_regs_num = u;
167
168                 ret = of_property_read_u32_array(iter, "nvidia,emc-registers",
169                                         pdata->tables[i].burst_regs,
170                                         pdata->tables[i].burst_regs_num);
171                 if (ret) {
172                         dev_err(&pdev->dev,
173                                 "malformed emc-registers property in %s\n",
174                                 iter->full_name);
175                         continue;
176                 }
177
178                 ret = of_property_read_u32_array(iter,
179                                 "nvidia,emc-burst-up-down-regs",
180                                 pdata->tables[i].burst_up_down_regs,
181                                 pdata->tables[i].burst_up_down_regs_num);
182                 if (ret) {
183                         dev_err(&pdev->dev,
184                                 "malformed emc-burst-up-down-regs "
185                                 "property in %s\n",
186                                 iter->full_name);
187                         continue;
188                 }
189
190                 ret = of_property_read_u32(iter,
191                                 "nvidia,emc-zcal-cnt-long", &u);
192                 if (ret) {
193                         dev_err(&pdev->dev,
194                                 "malformed emc-zcal-cnt-long property in %s\n",
195                                 iter->full_name);
196                         continue;
197                 }
198                 pdata->tables[i].emc_zcal_cnt_long = u;
199
200                 ret = of_property_read_u32(iter,
201                                 "nvidia,emc-acal-interval", &u);
202                 if (ret) {
203                         dev_err(&pdev->dev,
204                                 "malformed emc-acal-interval property in %s\n",
205                                 iter->full_name);
206                         continue;
207                 }
208                 pdata->tables[i].emc_acal_interval = u;
209
210                 ret = of_property_read_u32(iter, "nvidia,emc-cfg", &u);
211                 if (ret) {
212                         dev_err(&pdev->dev,
213                                 "malformed emc-cfg property in %s\n",
214                                 iter->full_name);
215                         continue;
216                 }
217                 pdata->tables[i].emc_cfg = u;
218
219                 ret = of_property_read_u32(iter, "nvidia,emc-mode-reset", &u);
220                 if (ret) {
221                         dev_err(&pdev->dev,
222                                 "malformed emc-mode-reset property in %s\n",
223                                 iter->full_name);
224                         continue;
225                 }
226                 pdata->tables[i].emc_mode_reset = u;
227
228                 ret = of_property_read_u32(iter, "nvidia,emc-mode-1", &u);
229                 if (ret) {
230                         dev_err(&pdev->dev,
231                                 "malformed emc-mode-1 property in %s\n",
232                                 iter->full_name);
233                         continue;
234                 }
235                 pdata->tables[i].emc_mode_1 = u;
236
237                 ret = of_property_read_u32(iter, "nvidia,emc-mode-2", &u);
238                 if (ret) {
239                         dev_err(&pdev->dev,
240                                 "malformed emc-mode-2 property in %s\n",
241                                 iter->full_name);
242                         continue;
243                 }
244                 pdata->tables[i].emc_mode_2 = u;
245
246                 ret = of_property_read_u32(iter, "nvidia,emc-mode-4", &u);
247                 if (ret) {
248                         dev_err(&pdev->dev,
249                                 "malformed emc-mode-4 property in %s\n",
250                                 iter->full_name);
251                         continue;
252                 }
253                 pdata->tables[i].emc_mode_4 = u;
254 #if defined(CONFIG_ARCH_TEGRA_12x_SOC)
255
256                 ret = of_property_read_string(iter,
257                         "nvidia,dvfs-version", &dvfs_ver);
258                 if (ret) {
259                         dev_err(&pdev->dev, "no dvfs version in %s\n",
260                                 iter->full_name);
261                         continue;
262                 }
263                 strncpy(pdata->tables[i].table_id, dvfs_ver,
264                         TEGRA12_MAX_TABLE_ID_LEN);
265
266                 ret = of_property_read_u32(iter, "nvidia,gk20a-min-mv", &u);
267                 if (ret) {
268                         dev_err(&pdev->dev,
269                                 "malformed gk20a-min-mv property in %s\n",
270                                 iter->full_name);
271                         continue;
272                 }
273                 pdata->tables[i].gk20a_min_mv = u;
274
275                 ret = of_property_read_u32(iter,
276                                 "nvidia,emc-ctt-term_ctrl", &u);
277                 if (ret) {
278                         dev_err(&pdev->dev,
279                                 "malformed emc-ctt-term_ctrl property in %s\n",
280                                 iter->full_name);
281                         continue;
282                 }
283                 pdata->tables[i].emc_ctt_term_ctrl = u;
284
285                 ret = of_property_read_u32(iter, "nvidia,emc-cfg-2", &u);
286                 if (ret) {
287                         dev_err(&pdev->dev,
288                                 "malformed emc-cfg-2 property in %s\n",
289                                 iter->full_name);
290                         continue;
291                 }
292                 pdata->tables[i].emc_cfg_2 = u;
293
294                 ret = of_property_read_u32(iter, "nvidia,emc-sel-dpd-ctrl", &u);
295                 if (ret) {
296                         dev_err(&pdev->dev,
297                                 "malformed emc-sel-dpd-ctrl property in %s\n",
298                                 iter->full_name);
299                         continue;
300                 }
301                 pdata->tables[i].emc_sel_dpd_ctrl = u;
302
303                 ret = of_property_read_u32(iter, "nvidia,emc-cfg-dig-dll", &u);
304                 if (ret) {
305                         dev_err(&pdev->dev,
306                                 "malformed emc-cfg-dig-dll property in %s\n",
307                                 iter->full_name);
308                         continue;
309                 }
310                 pdata->tables[i].emc_cfg_dig_dll = u;
311 #endif
312
313 #if defined(CONFIG_ARCH_TEGRA_11x_SOC)
314
315                 ret = of_property_read_u32(iter, "nvidia,emc-trimmers-num", &u);
316                 if (ret) {
317                         dev_err(&pdev->dev, "no emc-trimmers-num in %s\n",
318                                 iter->full_name);
319                         continue;
320                 }
321                 pdata->tables[i].emc_trimmers_num = u;
322
323                 ret = of_property_read_u32_array(iter, "nvidia,emc-trimmers-0",
324                                         pdata->tables[i].emc_trimmers_0,
325                                         pdata->tables[i].emc_trimmers_num);
326                 if (ret) {
327                         dev_err(&pdev->dev,
328                                 "malformed emc-trimmers-0 property in %s\n",
329                                 iter->full_name);
330                         continue;
331                 }
332                 ret = of_property_read_u32_array(iter, "nvidia,emc-trimmers-1",
333                                         pdata->tables[i].emc_trimmers_1,
334                                         pdata->tables[i].emc_trimmers_num);
335                 if (ret) {
336                         dev_err(&pdev->dev,
337                                 "malformed emc-trimmers-1 property in %s\n",
338                                 iter->full_name);
339                         continue;
340                 }
341
342                 ret = of_property_read_u32(iter,
343                                 "nvidia,emc-clock-latency-change", &u);
344                 if (ret) {
345                         dev_err(&pdev->dev,
346                                 "malformed emc-clock-latency-change in %s\n",
347                                 iter->full_name);
348                         continue;
349                 }
350                 pdata->tables[i].clock_change_latency = u;
351 #endif
352                 i++;
353         }
354         pdata->num_tables = i;
355
356 out:
357         of_node_put(tnp);
358         return pdata;
359 }
360 #else
361 void *tegra_emc_dt_parse_pdata(struct platform_device *pdev)
362 {
363         return NULL;
364 }
365 #endif