common: Drop log.h from common header
[pandora-u-boot.git] / arch / arm / mach-omap2 / omap5 / fdt.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2016 Texas Instruments, Inc.
4  */
5
6 #include <common.h>
7 #include <hang.h>
8 #include <log.h>
9 #include <linux/libfdt.h>
10 #include <fdt_support.h>
11 #include <malloc.h>
12
13 #include <asm/omap_common.h>
14 #include <asm/arch-omap5/sys_proto.h>
15
16 #ifdef CONFIG_TI_SECURE_DEVICE
17
18 /* Give zero values if not already defined */
19 #ifndef TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ
20 #define TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ (0)
21 #endif
22 #ifndef CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ
23 #define CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ (0)
24 #endif
25
26 static u32 hs_irq_skip[] = {
27         8,      /* Secure violation reporting interrupt */
28         15,     /* One interrupt for SDMA by secure world */
29         118     /* One interrupt for Crypto DMA by secure world */
30 };
31
32 static int ft_hs_fixup_crossbar(void *fdt, bd_t *bd)
33 {
34         const char *path;
35         int offs;
36         int ret;
37         int len, i, old_cnt, new_cnt;
38         u32 *temp;
39         const u32 *p_data;
40
41         /*
42          * Increase the size of the fdt
43          * so we have some breathing room
44          */
45         ret = fdt_increase_size(fdt, 512);
46         if (ret < 0) {
47                 printf("Could not increase size of device tree: %s\n",
48                        fdt_strerror(ret));
49                 return ret;
50         }
51
52         /* Reserve IRQs that are used/needed by secure world */
53         path = "/ocp/crossbar";
54         offs = fdt_path_offset(fdt, path);
55         if (offs < 0) {
56                 debug("Node %s not found.\n", path);
57                 return 0;
58         }
59
60         /* Get current entries */
61         p_data = fdt_getprop(fdt, offs, "ti,irqs-skip", &len);
62         if (p_data)
63                 old_cnt = len / sizeof(u32);
64         else
65                 old_cnt = 0;
66
67         new_cnt = sizeof(hs_irq_skip) /
68                                 sizeof(hs_irq_skip[0]);
69
70         /* Create new/updated skip list for HS parts */
71         temp = malloc(sizeof(u32) * (old_cnt + new_cnt));
72         for (i = 0; i < new_cnt; i++)
73                 temp[i] = cpu_to_fdt32(hs_irq_skip[i]);
74         for (i = 0; i < old_cnt; i++)
75                 temp[i + new_cnt] = p_data[i];
76
77         /* Blow away old data and set new data */
78         fdt_delprop(fdt, offs, "ti,irqs-skip");
79         ret = fdt_setprop(fdt, offs, "ti,irqs-skip",
80                           temp,
81                           (old_cnt + new_cnt) * sizeof(u32));
82         free(temp);
83
84         /* Check if the update worked */
85         if (ret < 0) {
86                 printf("Could not add ti,irqs-skip property to node %s: %s\n",
87                        path, fdt_strerror(ret));
88                 return ret;
89         }
90
91         return 0;
92 }
93
94 #if ((TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ != 0) || \
95     (CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ != 0))
96 static int ft_hs_fixup_sram(void *fdt, bd_t *bd)
97 {
98         const char *path;
99         int offs;
100         int ret;
101         u32 temp[2];
102
103         /*
104          * Update SRAM reservations on secure devices. The OCMC RAM
105          * is always reserved for secure use from the start of that
106          * memory region
107          */
108         path = "/ocp/ocmcram@40300000/sram-hs";
109         offs = fdt_path_offset(fdt, path);
110         if (offs < 0) {
111                 debug("Node %s not found.\n", path);
112                 return 0;
113         }
114
115         /* relative start offset */
116         temp[0] = cpu_to_fdt32(0);
117         /* reservation size */
118         temp[1] = cpu_to_fdt32(max(TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ,
119                                    CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ));
120         fdt_delprop(fdt, offs, "reg");
121         ret = fdt_setprop(fdt, offs, "reg", temp, 2 * sizeof(u32));
122         if (ret < 0) {
123                 printf("Could not add reg property to node %s: %s\n",
124                        path, fdt_strerror(ret));
125                 return ret;
126         }
127
128         return 0;
129 }
130 #else
131 static int ft_hs_fixup_sram(void *fdt, bd_t *bd) { return 0; }
132 #endif
133
134 static void ft_hs_fixups(void *fdt, bd_t *bd)
135 {
136         /* Check we are running on an HS/EMU device type */
137         if (GP_DEVICE != get_device_type()) {
138                 if ((ft_hs_fixup_crossbar(fdt, bd) == 0) &&
139                     (ft_hs_disable_rng(fdt, bd) == 0) &&
140                     (ft_hs_fixup_sram(fdt, bd) == 0) &&
141                     (ft_hs_fixup_dram(fdt, bd) == 0) &&
142                     (ft_hs_add_tee(fdt, bd) == 0))
143                         return;
144         } else {
145                 printf("ERROR: Incorrect device type (GP) detected!");
146         }
147         /* Fixup failed or wrong device type */
148         hang();
149 }
150 #else
151 static void ft_hs_fixups(void *fdt, bd_t *bd)
152 {
153 }
154 #endif /* #ifdef CONFIG_TI_SECURE_DEVICE */
155
156 #if defined(CONFIG_TARGET_DRA7XX_EVM) || defined(CONFIG_TARGET_AM57XX_EVM)
157 #define OPP_DSP_CLK_NUM 3
158 #define OPP_IVA_CLK_NUM 2
159 #define OPP_GPU_CLK_NUM 2
160
161 const char *dra7_opp_dsp_clk_names[OPP_DSP_CLK_NUM] = {
162         "dpll_dsp_ck",
163         "dpll_dsp_m2_ck",
164         "dpll_dsp_m3x2_ck",
165 };
166
167 const char *dra7_opp_iva_clk_names[OPP_IVA_CLK_NUM] = {
168         "dpll_iva_ck",
169         "dpll_iva_m2_ck",
170 };
171
172 const char *dra7_opp_gpu_clk_names[OPP_GPU_CLK_NUM] = {
173         "dpll_gpu_ck",
174         "dpll_gpu_m2_ck",
175 };
176
177 /* DSPEVE voltage domain */
178 u32 dra7_opp_dsp_clk_rates[NUM_OPPS][OPP_DSP_CLK_NUM] = {
179         {}, /*OPP_LOW */
180         {600000000, 600000000, 400000000}, /* OPP_NOM */
181         {700000000, 700000000, 466666667}, /* OPP_OD */
182         {750000000, 750000000, 500000000}, /* OPP_HIGH */
183 };
184
185 /* DSP clock rates on DRA76x ACD-package based SoCs */
186 u32 dra76_opp_dsp_clk_rates[NUM_OPPS][OPP_DSP_CLK_NUM] = {
187         {}, /* OPP_LOW */
188         {600000000, 600000000, 400000000}, /* OPP_NOM */
189         {700000000, 700000000, 466666667}, /* OPP_OD */
190         {850000000, 850000000, 566666667}, /* OPP_HIGH */
191 };
192
193 /* IVA voltage domain */
194 u32 dra7_opp_iva_clk_rates[NUM_OPPS][OPP_IVA_CLK_NUM] = {
195         {}, /* OPP_LOW */
196         {1165000000, 388333334}, /* OPP_NOM */
197         {860000000, 430000000}, /* OPP_OD */
198         {1064000000, 532000000}, /* OPP_HIGH */
199 };
200
201 /* GPU voltage domain */
202 u32 dra7_opp_gpu_clk_rates[NUM_OPPS][OPP_GPU_CLK_NUM] = {
203         {}, /* OPP_LOW */
204         {1277000000, 425666667}, /* OPP_NOM */
205         {1000000000, 500000000}, /* OPP_OD */
206         {1064000000, 532000000}, /* OPP_HIGH */
207 };
208
209 static int ft_fixup_clocks(void *fdt, const char **names, u32 *rates, int num)
210 {
211         int offs, node_offs, ret, i;
212         uint32_t phandle;
213
214         offs = fdt_path_offset(fdt, "/ocp/interconnect@4a000000/segment@0/target-module@5000/cm_core_aon@0/clocks");
215         if (offs < 0)
216                 offs = fdt_path_offset(fdt, "/ocp/l4@4a000000/cm_core_aon@5000/clocks");
217         if (offs < 0) {
218                 debug("Could not find cm_core_aon clocks node path offset : %s\n",
219                       fdt_strerror(offs));
220                 return offs;
221         }
222
223         for (i = 0; i < num; i++) {
224                 node_offs = fdt_subnode_offset(fdt, offs, names[i]);
225                 if (node_offs < 0) {
226                         debug("Could not find clock sub-node %s: %s\n",
227                               names[i], fdt_strerror(node_offs));
228                         return offs;
229                 }
230
231                 phandle = fdt_get_phandle(fdt, node_offs);
232                 if (!phandle) {
233                         debug("Could not find phandle for clock %s\n",
234                               names[i]);
235                         return -1;
236                 }
237
238                 ret = fdt_setprop_u32(fdt, node_offs, "assigned-clocks",
239                                       phandle);
240                 if (ret < 0) {
241                         debug("Could not add assigned-clocks property to clock node %s: %s\n",
242                               names[i], fdt_strerror(ret));
243                         return ret;
244                 }
245
246                 ret = fdt_setprop_u32(fdt, node_offs, "assigned-clock-rates",
247                                       rates[i]);
248                 if (ret < 0) {
249                         debug("Could not add assigned-clock-rates property to clock node %s: %s\n",
250                               names[i], fdt_strerror(ret));
251                         return ret;
252                 }
253         }
254
255         return 0;
256 }
257
258 static void ft_opp_clock_fixups(void *fdt, bd_t *bd)
259 {
260         const char **clk_names;
261         u32 *clk_rates;
262         int ret;
263
264         if (!is_dra72x() && !is_dra7xx())
265                 return;
266
267         /* fixup DSP clocks */
268         clk_names = dra7_opp_dsp_clk_names;
269         clk_rates = dra7_opp_dsp_clk_rates[get_voltrail_opp(VOLT_EVE)];
270         /* adjust for higher OPP_HIGH clock rate on DRA76xP/DRA77xP SoCs */
271         if (is_dra76x_acd())
272                 clk_rates = dra76_opp_dsp_clk_rates[get_voltrail_opp(VOLT_EVE)];
273
274         ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_DSP_CLK_NUM);
275         if (ret) {
276                 printf("ft_fixup_clocks failed for DSP voltage domain: %s\n",
277                        fdt_strerror(ret));
278                 return;
279         }
280
281         /* fixup IVA clocks */
282         clk_names = dra7_opp_iva_clk_names;
283         clk_rates = dra7_opp_iva_clk_rates[get_voltrail_opp(VOLT_IVA)];
284         ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_IVA_CLK_NUM);
285         if (ret) {
286                 printf("ft_fixup_clocks failed for IVA voltage domain: %s\n",
287                        fdt_strerror(ret));
288                 return;
289         }
290
291         /* fixup GPU clocks */
292         clk_names = dra7_opp_gpu_clk_names;
293         clk_rates = dra7_opp_gpu_clk_rates[get_voltrail_opp(VOLT_GPU)];
294         ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_GPU_CLK_NUM);
295         if (ret) {
296                 printf("ft_fixup_clocks failed for GPU voltage domain: %s\n",
297                        fdt_strerror(ret));
298                 return;
299         }
300 }
301 #else
302 static void ft_opp_clock_fixups(void *fdt, bd_t *bd) { }
303 #endif /* CONFIG_TARGET_DRA7XX_EVM || CONFIG_TARGET_AM57XX_EVM */
304
305 /*
306  * Place for general cpu/SoC FDT fixups. Board specific
307  * fixups should remain in the board files which is where
308  * this function should be called from.
309  */
310 void ft_cpu_setup(void *fdt, bd_t *bd)
311 {
312         ft_hs_fixups(fdt, bd);
313         ft_opp_clock_fixups(fdt, bd);
314 }