blob: 610ec6c37aa1e68eb8c4005a9d9de564841481a9 [file] [log] [blame]
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -07001/*
2 * Copyright (C) 2015 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18#include <arch/io.h>
19#include <delay.h>
20#include <console/console.h>
Corneliu Doban189bec52015-04-10 15:51:55 -070021#include <soc/tz.h>
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -070022#include <soc/hw_init.h>
23
24/*****************************************************************************
25 * TrustZone
26 *****************************************************************************/
Corneliu Doban189bec52015-04-10 15:51:55 -070027#define IHOST_SCU_SECURE_ACCESS 0x19020054
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -070028
Corneliu Doban189bec52015-04-10 15:51:55 -070029#define SMAU_NIC_IDM_TZ_BASE 0x180150a0
30#define SMAU_DDR_TZ_BASE 0x18015200
31#define SMAU_FLASH0_TZ_BASE 0x18015300
32#define SMAU_FLASH1_TZ_BASE 0x18015308
33#define SMAU_FLASH2_TZ_BASE 0x18015310
34#define SMAU_FLASH3_TZ_BASE 0x18015318
35#define SMAU_TZ_BASE_ENABLE 0x00000001
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -070036
Corneliu Doban189bec52015-04-10 15:51:55 -070037#define CRMU_IPROC_ADDR_RANGE0_LOW 0x03024c30
38#define CRMU_IPROC_ADDR_RANGE0_HIGH 0x03024c34
39#define CRMU_ADDR_MASK 0xffffff00
40#define CRMU_ADDR_VALID 0x00000001
41#define CRMU_ADDR_START 0x03010000
42#define CRMU_ADDR_END 0x03100000
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -070043
Corneliu Doban189bec52015-04-10 15:51:55 -070044static void scu_ns_config(void)
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -070045{
Corneliu Doban189bec52015-04-10 15:51:55 -070046 /*
47 * Enable NS SCU access to ARM global timer, private timer, and
48 * components
49 */
50 write32((void *)IHOST_SCU_SECURE_ACCESS, 0xFFF);
51}
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -070052
Corneliu Doban189bec52015-04-10 15:51:55 -070053static void smau_ns_config(void)
54{
55 unsigned int val;
56
57 /* Disable SMAU NIC IDM TZ */
58 val = read32((void *)SMAU_NIC_IDM_TZ_BASE);
59 val &= ~SMAU_TZ_BASE_ENABLE;
60 write32((void *)SMAU_NIC_IDM_TZ_BASE, val);
61
62 /*
63 * Disable DDR TZ base
64 *
65 * This means the entire DDR is marked as NONSECURE (NS)
66 *
67 * NOTE: In the future, multiple regions of DDR may need to be marked
68 * as SECURE for secure OS and other TZ usages
69 */
70 val = read32((void *)SMAU_DDR_TZ_BASE);
71 val &= ~SMAU_TZ_BASE_ENABLE;
72 write32((void *)SMAU_DDR_TZ_BASE, val);
73
74
75 /*
76 * Disable flash TZ support
77 *
78 * The entire flash is currently marked as NS
79 *
80 * NOTE: In the future, multiple regions of flash may need to be marked
81 * as SECURE for secure OS and other TZ firmware/data storage
82 */
83
84 /* Flash 0: ROM */
85 val = read32((void *)SMAU_FLASH0_TZ_BASE);
86 val &= ~SMAU_TZ_BASE_ENABLE;
87 write32((void *)SMAU_FLASH0_TZ_BASE, val);
88
89 /* Flash 1: QSPI */
90 val = read32((void *)SMAU_FLASH1_TZ_BASE);
91 val &= ~SMAU_TZ_BASE_ENABLE;
92 write32((void *)SMAU_FLASH1_TZ_BASE, val);
93
94 /* Flash 2: NAND */
95 val = read32((void *)SMAU_FLASH2_TZ_BASE);
96 val &= ~SMAU_TZ_BASE_ENABLE;
97 write32((void *)SMAU_FLASH2_TZ_BASE, val);
98
99 /* Flash 3: PNOR */
100 val = read32((void *)SMAU_FLASH3_TZ_BASE);
101 val &= ~SMAU_TZ_BASE_ENABLE;
102 write32((void *)SMAU_FLASH3_TZ_BASE, val);
103}
104
105static void crmu_ns_config(void)
106{
107
108 /*
109 * Currently opens up the entire CRMU to allow iPROC NS access
110 *
111 * NOTE: In the future, we might want to protect particular CRMU
112 * sub-blocks to allow SECURE access only. That can be done by
113 * programing the CRMU IPROC address range registers. Up to 4 access
114 * windows can be created
115 */
116 write32((void *)CRMU_IPROC_ADDR_RANGE0_LOW,
117 (CRMU_ADDR_START & CRMU_ADDR_MASK) | CRMU_ADDR_VALID);
118 write32((void *)CRMU_IPROC_ADDR_RANGE0_HIGH,
119 (CRMU_ADDR_END & CRMU_ADDR_MASK) | CRMU_ADDR_VALID);
120}
121
122static void tz_init(void)
123{
124 /* Configure the Cygnus for non-secure access */
125 /* ARM Cortex A9 SCU NS access configuration */
126 scu_ns_config();
127
128 /* SMAU NS related configurations */
129 smau_ns_config();
130
131 /* CRMU NS related configurations */
132 crmu_ns_config();
133
134 /*
135 * Configure multiple masters and slaves to run in NS
136 */
137 tz_set_non_virtual_slaves_security(0xFFFFFFFF, TZ_STATE_NON_SECURE);
138 tz_set_periph_security(0xFFFFFFFF, TZ_STATE_NON_SECURE);
139 tz_set_masters_security(0xFFFFFFFF, TZ_STATE_NON_SECURE);
140 tz_set_wrapper_security(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
141 TZ_STATE_NON_SECURE);
142 tz_set_cfg_slaves_security(0xFFFFFFFF, TZ_STATE_NON_SECURE);
143
144 tz_set_ext_slaves_security(0xFFFFFFFF, TZ_STATE_NON_SECURE);
145
146 /* configure sec peripherals to be accessed from non-secure world */
147 tz_set_sec_periphs_security(0xFFFFFFFF &
148 ~(CYGNUS_sec_periph_APBz_sotp |
149 CYGNUS_sec_periph_APBz_tzpc),
150 TZ_STATE_NON_SECURE);
151
152 /* default sram to non-secure */
153 tz_set_sram_sec_region(0);
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -0700154}
155
156/*****************************************************************************
157 * DMAC
158 *****************************************************************************/
159#define DMAC_M0_IDM_RESET_CONTROL 0x1810f800
160#define DMAC_RESET_MASK 0x00000001
161#define DMAC_RESET_TIMEOUT 1000
162
163static void dmac_init(void)
164{
165 unsigned int val, timeout;
166
167 /* bring the DMAC block out of reset */
168 val = read32((void *)DMAC_M0_IDM_RESET_CONTROL);
169 val |= DMAC_RESET_MASK;
170 write32((void *)DMAC_M0_IDM_RESET_CONTROL, val);
171 udelay(10);
172 val &= ~DMAC_RESET_MASK;
173 write32((void *)DMAC_M0_IDM_RESET_CONTROL, val);
174
175 timeout = 0;
176 while (read32((void *)DMAC_M0_IDM_RESET_CONTROL) & DMAC_RESET_MASK) {
177 udelay(1);
178 if (timeout++ > DMAC_RESET_TIMEOUT)
179 die("Failed to bring PL330 DMAC out of reset\n");
180 }
181}
182
183/*****************************************************************************
184 * Neon
185 *****************************************************************************/
186#define CRU_CONTROL 0x1800e000
187#define CRU_CONTROL_NEON_RESET_N 0x00000040
188
189#define CRU_IHOST_PWRDWN_EN 0x1800e004
190#define CRU_IHOST_PWRDWN_EN_CLAMPON_NEON 0x00100000
191#define CRU_IHOST_PWRDWN_EN_PWRON_NEON 0x00200000
192#define CRU_IHOST_PWRDWN_EN_PWROK_NEON 0x00400000
193
194#define CRU_IHOST_PWRDWN_STATUS 0x1800e008
195#define CRU_IHOST_PWRDWN_STATUS_PWRON_NEON 0x00200000
196#define CRU_IHOST_PWRDWN_STATUS_PWROK_NEON 0x00400000
197
198#define CRU_STATUS_DELAY_US 1
199#define CRU_MAX_RETRY_COUNT 10
200#define CRU_RETRY_INTVL_US 1
201
202static void neon_init(void)
203{
204 unsigned int i, val;
205
206 /* put Neon into reset */
207 val = read32((void *)CRU_CONTROL);
208 val &= ~CRU_CONTROL_NEON_RESET_N;
209 write32((void *)CRU_CONTROL, val);
210
211 /* assert the power on register bit */
212 val = read32((void *)CRU_IHOST_PWRDWN_EN);
213 val |= CRU_IHOST_PWRDWN_EN_PWRON_NEON;
214 write32((void *)CRU_IHOST_PWRDWN_EN, val);
215
216 /* wait for power on */
217 i = 0;
218 while (!(read32((void *)CRU_IHOST_PWRDWN_STATUS) &
219 CRU_IHOST_PWRDWN_STATUS_PWRON_NEON)) {
220 udelay(CRU_RETRY_INTVL_US);
221 if (i++ >= CRU_MAX_RETRY_COUNT)
222 die("Failed to ack NEON power on\n");
223 }
224
225 udelay(CRU_STATUS_DELAY_US);
226
227 /* assert the power ok register bit */
228 val = read32((void *)CRU_IHOST_PWRDWN_EN);
229 val |= CRU_IHOST_PWRDWN_EN_PWROK_NEON;
230 write32((void *)CRU_IHOST_PWRDWN_EN, val);
231
232 /* wait for power ok */
233 i = 0;
234 while (!(read32((void *)CRU_IHOST_PWRDWN_STATUS) &
235 CRU_IHOST_PWRDWN_STATUS_PWROK_NEON)) {
236 udelay(CRU_RETRY_INTVL_US);
237 if (i++ >= CRU_MAX_RETRY_COUNT)
238 die("Failed to ack NEON power ok\n");
239 }
240
241 udelay(CRU_STATUS_DELAY_US);
242
243 /* clamp off for the NEON block */
244 val = read32((void *)CRU_IHOST_PWRDWN_EN);
245 val &= ~CRU_IHOST_PWRDWN_EN_CLAMPON_NEON;
246 write32((void *)CRU_IHOST_PWRDWN_EN, val);
247
248 udelay(CRU_STATUS_DELAY_US);
249
250 /* bring NEON out of reset */
251 val = read32((void *)CRU_CONTROL);
252 val |= CRU_CONTROL_NEON_RESET_N;
253 write32((void *)CRU_CONTROL, val);
254}
255
256/*****************************************************************************
257 * PCIe
258 *****************************************************************************/
259#define CRMU_PCIE_CFG 0x0301d0a0
260#define PCIE0_LNK_PHY_IDDQ 0x00000004
261#define PCIE1_LNK_PHY_IDDQ 0x00000400
262
263static void pcie_init(void)
264{
265 unsigned int val;
266
267 /*
268 * Force all AFEs of both PCIe0 and PCIe1 to be powered down, including
269 * pad biasing
270 *
271 * This brings down the PCIe interfaces to the lowest possible power
272 * mode
273 */
274 val = read32((void *)CRMU_PCIE_CFG);
275 val |= PCIE1_LNK_PHY_IDDQ | PCIE0_LNK_PHY_IDDQ;
276 write32((void *)CRMU_PCIE_CFG, val);
277}
278
279/*****************************************************************************
280 * M0
281 *****************************************************************************/
282#define CRMU_MCU_ACCESS_CONTROL 0x03024c00
283#define CRMU_MCU_ACCESS_MODE_SECURE 0x2
284
285static void M0_init(void)
286{
287 /* Set M0 as a secure master */
288 write32((void *)CRMU_MCU_ACCESS_CONTROL, CRMU_MCU_ACCESS_MODE_SECURE);
289}
290
291/*****************************************************************************
292 * CCU
293 *****************************************************************************/
294#define IHOST_PROC_CLK_WR_ACCESS 0x19000000
295#define IHOST_PROC_CLK_POLICY_FREQ 0x19000008
296#define IHOST_PROC_CLK_POLICY_CTL 0x1900000c
297#define IHOST_PROC_CLK_POLICY0_MASK 0x19000010
298#define IHOST_PROC_CLK_POLICY1_MASK 0x19000014
299#define IHOST_PROC_CLK_POLICY2_MASK 0x19000018
300#define IHOST_PROC_CLK_POLICY3_MASK 0x1900001c
301#define IHOST_PROC_CLK_INTEN 0x19000020
302#define IHOST_PROC_CLK_INTSTAT 0x19000024
303#define IHOST_PROC_CLK_LVM_EN 0x19000034
304#define IHOST_PROC_CLK_LVM0_3 0x19000038
305#define IHOST_PROC_CLK_LVM4_7 0x1900003c
306#define IHOST_PROC_CLK_VLT0_3 0x19000040
307#define IHOST_PROC_CLK_VLT4_7 0x19000044
308#define IHOST_PROC_CLK_BUS_QUIESC 0x19000100
309#define IHOST_PROC_CLK_CORE0_CLKGATE 0x19000200
310#define IHOST_PROC_CLK_CORE1_CLKGATE 0x19000204
311#define IHOST_PROC_CLK_ARM_SWITCH_CLKGATE 0x19000210
312#define IHOST_PROC_CLK_ARM_PERIPH_CLKGATE 0x19000300
313#define IHOST_PROC_CLK_APB0_CLKGATE 0x19000400
314#define IHOST_PROC_CLK_PL310_DIV 0x19000a00
315#define IHOST_PROC_CLK_PL310_TRIGGER 0x19000a04
316#define IHOST_PROC_CLK_ARM_SWITCH_DIV 0x19000a08
317#define IHOST_PROC_CLK_ARM_SWITCH_TRIGGER 0x19000a0c
318#define IHOST_PROC_CLK_APB_DIV 0x19000a10
319#define IHOST_PROC_CLK_APB_DIV_TRIGGER 0x19000a14
320#define IHOST_PROC_CLK_PLLARMA 0x19000c00
321#define IHOST_PROC_CLK_PLLARMB 0x19000c04
322#define IHOST_PROC_CLK_PLLARMC 0x19000c08
323#define IHOST_PROC_CLK_PLLARMCTRL0 0x19000c0c
324#define IHOST_PROC_CLK_PLLARMCTRL1 0x19000c10
325#define IHOST_PROC_CLK_PLLARMCTRL2 0x19000c14
326#define IHOST_PROC_CLK_PLLARMCTRL3 0x19000c18
327#define IHOST_PROC_CLK_PLLARMCTRL4 0x19000c1c
328#define IHOST_PROC_CLK_PLLARMCTRL5 0x19000c20
329#define IHOST_PROC_CLK_PLLARM_OFFSET 0x19000c24
330#define IHOST_PROC_CLK_ARM_DIV 0x19000e00
331#define IHOST_PROC_CLK_ARM_SEG_TRG 0x19000e04
332#define IHOST_PROC_CLK_ARM_SEG_TRG_OVERRIDE 0x19000e08
333#define IHOST_PROC_CLK_PLL_DEBUG 0x19000e10
334#define IHOST_PROC_CLK_ACTIVITY_MON1 0x19000e20
335#define IHOST_PROC_CLK_ACTIVITY_MON2 0x19000e24
336#define IHOST_PROC_CLK_CLKGATE_DBG 0x19000e40
337#define IHOST_PROC_CLK_APB_CLKGATE_DBG1 0x19000e48
338#define IHOST_PROC_CLK_CLKMON 0x19000e64
339#define IHOST_PROC_CLK_POLICY_DBG 0x19000ec0
340#define IHOST_PROC_CLK_TGTMASK_DBG1 0x19000ec4
341#define IHOST_PROC_RST_WR_ACCESS 0x19000f00
342#define IHOST_PROC_RST_SOFT_RSTN 0x19000f04
343#define IHOST_PROC_RST_A9_CORE_SOFT_RSTN 0x19000f08
344
345#define WR_ACCESS_PRIVATE_ACCESS_MODE 0x80000000
346
347static uint32_t ccu_reg[] = {
348 IHOST_PROC_CLK_WR_ACCESS,
349 IHOST_PROC_CLK_POLICY_FREQ,
350 IHOST_PROC_CLK_POLICY_CTL,
351 IHOST_PROC_CLK_POLICY0_MASK,
352 IHOST_PROC_CLK_POLICY1_MASK,
353 IHOST_PROC_CLK_POLICY2_MASK,
354 IHOST_PROC_CLK_POLICY3_MASK,
355 IHOST_PROC_CLK_INTEN,
356 IHOST_PROC_CLK_INTSTAT,
357 IHOST_PROC_CLK_LVM_EN,
358 IHOST_PROC_CLK_LVM0_3,
359 IHOST_PROC_CLK_LVM4_7,
360 IHOST_PROC_CLK_VLT0_3,
361 IHOST_PROC_CLK_VLT4_7,
362 IHOST_PROC_CLK_BUS_QUIESC,
363 IHOST_PROC_CLK_CORE0_CLKGATE,
364 IHOST_PROC_CLK_CORE1_CLKGATE,
365 IHOST_PROC_CLK_ARM_SWITCH_CLKGATE,
366 IHOST_PROC_CLK_ARM_PERIPH_CLKGATE,
367 IHOST_PROC_CLK_APB0_CLKGATE,
368 IHOST_PROC_CLK_PL310_DIV,
369 IHOST_PROC_CLK_PL310_TRIGGER,
370 IHOST_PROC_CLK_ARM_SWITCH_DIV,
371 IHOST_PROC_CLK_ARM_SWITCH_TRIGGER,
372 IHOST_PROC_CLK_APB_DIV,
373 IHOST_PROC_CLK_APB_DIV_TRIGGER,
374 IHOST_PROC_CLK_PLLARMA,
375 IHOST_PROC_CLK_PLLARMB,
376 IHOST_PROC_CLK_PLLARMC,
377 IHOST_PROC_CLK_PLLARMCTRL0,
378 IHOST_PROC_CLK_PLLARMCTRL1,
379 IHOST_PROC_CLK_PLLARMCTRL2,
380 IHOST_PROC_CLK_PLLARMCTRL3,
381 IHOST_PROC_CLK_PLLARMCTRL4,
382 IHOST_PROC_CLK_PLLARMCTRL5,
383 IHOST_PROC_CLK_PLLARM_OFFSET,
384 IHOST_PROC_CLK_ARM_DIV,
385 IHOST_PROC_CLK_ARM_SEG_TRG,
386 IHOST_PROC_CLK_ARM_SEG_TRG_OVERRIDE,
387 IHOST_PROC_CLK_PLL_DEBUG,
388 IHOST_PROC_CLK_ACTIVITY_MON1,
389 IHOST_PROC_CLK_ACTIVITY_MON2,
390 IHOST_PROC_CLK_CLKGATE_DBG,
391 IHOST_PROC_CLK_APB_CLKGATE_DBG1,
392 IHOST_PROC_CLK_CLKMON,
393 IHOST_PROC_CLK_POLICY_DBG,
394 IHOST_PROC_CLK_TGTMASK_DBG1,
395 IHOST_PROC_RST_WR_ACCESS,
396 IHOST_PROC_RST_SOFT_RSTN,
397 IHOST_PROC_RST_A9_CORE_SOFT_RSTN
398};
399
400#define CCU_REG_TABLE_SIZE (sizeof(ccu_reg)/sizeof(ccu_reg[0]))
401
402/* Set priv_access_mode field to unrestricted (0) */
403static void ccu_init(void)
404{
405 uint32_t val;
406 uint32_t i;
407 for (i = 0; i < CCU_REG_TABLE_SIZE; i++) {
408 val = read32((void *)(ccu_reg[i]));
409 val &= ~WR_ACCESS_PRIVATE_ACCESS_MODE;
410 write32((void *)(ccu_reg[i]), val);
411 }
412}
413
414/*****************************************************************************
415 * LCD
416 *****************************************************************************/
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -0700417#define ASIU_TOP_CLK_GATING_CTRL 0x180aa024
418#define ASIU_TOP_CLK_GATING_CTRL_LCD_CLK_GATE_EN 0x00000010
419#define ASIU_TOP_CLK_GATING_CTRL_MIPI_DSI_CLK_GATE_EN 0x00000008
420#define ASIU_TOP_CLK_GATING_CTRL_GFX_CLK_GATE_EN 0x00000001
421#define ASIU_TOP_CLK_GATING_CTRL_AUD_CLK_GATE_EN 0x00000002
422
423static void lcd_init(void)
424{
425 unsigned int val;
426
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -0700427 /* make sure the LCD clock is ungated */
428 val = read32((void *)ASIU_TOP_CLK_GATING_CTRL);
429 val |= ASIU_TOP_CLK_GATING_CTRL_LCD_CLK_GATE_EN;
430 write32((void *)ASIU_TOP_CLK_GATING_CTRL, val);
431}
432
433/*******************************************************************
434 * Default priority settings in Cygnus
435 *
436 * Master Name Default Priority
437 * ==================== =================
438 * ihost_m0 12
439 * mhost0_m0 12
440 * mhost1_m0 ` 12
441 * pcie0_m0 9
442 * pcie0_m1 9
443 * cmicd_m0 7
444 * amac_m0 7
445 * amac_m1 7
446 * ext_m0 (LCD) 5
447 * ext_m1 (V3D) 5
448 * sdio_m0 3
449 * sdio_m1 3
450 * usb2h_m0 3
451 * usb2d_m0 3
452 * dmu_m0 3
453 * a9jtag_m0 0
454 *
455 *****************************************************************************/
456
457#define AXIIC_EXT_M0_READ_QOS 0x1a057100
458#define AXIIC_EXT_M0_READ_MASK 0x0000000f
459#define AXIIC_EXT_M0_WRITE_QOS 0x1a057104
460#define AXIIC_EXT_M0_WRITE_MASK 0x0000000f
461
462static void lcd_qos_init(unsigned int qos)
463{
464 unsigned int val;
465
466 val = read32((void *)AXIIC_EXT_M0_READ_QOS);
467 val &= ~AXIIC_EXT_M0_READ_MASK;
468 val |= (qos & AXIIC_EXT_M0_READ_MASK);
469 write32((void *)AXIIC_EXT_M0_READ_QOS, val);
470
471 val = read32((void *)AXIIC_EXT_M0_WRITE_QOS);
472 val &= ~AXIIC_EXT_M0_WRITE_MASK;
473 val |= (qos & AXIIC_EXT_M0_WRITE_MASK);
474 write32((void *)AXIIC_EXT_M0_WRITE_QOS, val);
475}
476
477/*****************************************************************************
478 * V3D
479 *****************************************************************************/
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -0700480static void v3d_init(void)
481{
482 unsigned int val;
483
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -0700484 /* make sure the V3D clock is ungated */
485 val = read32((void *)ASIU_TOP_CLK_GATING_CTRL);
486 val |= ASIU_TOP_CLK_GATING_CTRL_MIPI_DSI_CLK_GATE_EN |
487 ASIU_TOP_CLK_GATING_CTRL_GFX_CLK_GATE_EN;
488 write32((void *)ASIU_TOP_CLK_GATING_CTRL, val);
489}
490
491/*****************************************************************************
492 * Audio
493 *****************************************************************************/
494#define CRMU_PLL_AON_CTRL 0x0301c020
495#define CRMU_PLL_AON_CTRL_ASIU_AUDIO_GENPLL_PWRON_PLL 0x00000800
496#define CRMU_PLL_AON_CTRL_ASIU_AUDIO_GENPLL_PWRON_BG 0x00000400
497#define CRMU_PLL_AON_CTRL_ASIU_AUDIO_GENPLL_PWRON_LDO 0x00000200
498#define CRMU_PLL_AON_CTRL_ASIU_AUDIO_GENPLL_ISO_IN 0x00000100
499
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -0700500static void audio_init(void)
501{
502 unsigned int val;
503
504 /* Ungate (enable) audio clock. */
505 val = read32((void *)ASIU_TOP_CLK_GATING_CTRL);
506 val |= ASIU_TOP_CLK_GATING_CTRL_AUD_CLK_GATE_EN;
507 write32((void *)ASIU_TOP_CLK_GATING_CTRL, val);
508
509 /* Power on audio GEN PLL, LDO, and BG. Input isolation = normal. */
510 val = read32((void *)CRMU_PLL_AON_CTRL);
511 val |= CRMU_PLL_AON_CTRL_ASIU_AUDIO_GENPLL_PWRON_BG;
512 val |= CRMU_PLL_AON_CTRL_ASIU_AUDIO_GENPLL_PWRON_LDO;
513 val |= CRMU_PLL_AON_CTRL_ASIU_AUDIO_GENPLL_PWRON_PLL;
514 val &= ~CRMU_PLL_AON_CTRL_ASIU_AUDIO_GENPLL_ISO_IN;
515 write32((void *)CRMU_PLL_AON_CTRL, val);
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -0700516}
517
518/*****************************************************************************
519 * SDIO
520 *****************************************************************************/
521#define CRMU_SDIO_1P8_FAIL_CONTROL 0x0301c0a0
522#define UHS1_18V_VREG_FAIL 0x00000001
523
524#define SDIO_IDM0_IO_CONTROL_DIRECT 0x18116408
525#define SDIO_IDM1_IO_CONTROL_DIRECT 0x18117408
526#define SDIO_CMD_COMFLICT_DISABLE 0x00400000
527#define SDIO_FEEDBACK_CLK_EN 0x00200000
528#define SDIO_CLK_ENABLE 0x00000001
529
530#define CDRU_SDIO0_IO_CONTROL 0x0301d144
531#define CDRU_SDIO1_IO_CONTROL 0x0301d140
532#define INPUT_DISABLE 0x00000080
533#define SLEW_RATE_ENABLE 0x00000040
534#define PULL_UP_ENABLE 0x00000020
535#define PULL_DOWN_ENABLE 0x00000010
536#define HYSTERESIS_ENABLE 0x00000008
537#define SDIO_DEFAULT_DRIVE_STRENGTH 0x4 /* 8 mA */
538
539#define SDIO_IDM0_IDM_RESET_CONTROL 0x18116800
540#define SDIO_IDM1_IDM_RESET_CONTROL 0x18117800
541#define SDIO_RESET_MASK 0x00000001
542#define SDIO_RESET_TIMEOUT 1000
543
544#define CRMU_SDIO_CONTROL0 0x0301d088
545#define CRMU_SDIO_CONTROL1 0x0301d08c
546#define CRMU_SDIO_CONTROL2 0x0301d090
547#define CRMU_SDIO_CONTROL3 0x0301d094
548#define CRMU_SDIO_CONTROL4 0x0301d098
549#define CRMU_SDIO_CONTROL5 0x0301d09c
550
551/*
552 * SDIO_CAPS_L
553 *
554 * Field Bit(s)
555 * ===========================
556 * DDR50 31
557 * SDR104 30
558 * SDR50 29
559 * SLOTTYPE 28:27
560 * ASYNCHIRQ 26
561 * SYSBUS64 25
562 * V18 24
563 * V3 23
564 * V33 22
565 * SUPRSM 21
566 * SDMA 20
567 * HSPEED 19
568 * ADMA2 18
569 * EXTBUSMED 17
570 * MAXBLK 16:15
571 * BCLK 14:7
572 * TOUT 6
573 * TOUTFREQ 5:0
574 */
575#define SDIO_CAPS_L 0xA17C0000
576
577/*
578 * SDIO_CAPS_H
579 *
580 * Field Bit(s)
581 * ===========================
582 * reserved 31:20
583 * SPIBLOCKMODE 19
584 * SPIMODE_CAP 18
585 * CLOCKMULT 17:10
586 * RETUNE_MODE 9:8
587 * USETUNE_SDR50 7
588 * TMRCNT_RETUNE 6:3
589 * DRVR_TYPED 2
590 * DRVR_TYPEC 1
591 * DRVR_TYPEA 0
592 */
593#define SDIO_CAPS_H 0x000C0087
594
595/*
596 * Preset value
597 *
598 * Field Bit(s)
599 * ===========================
600 * Driver Strength 12:11
601 * Clock Generator 10
602 * SDCLK Frequeency 9:0
603 */
604
605/*
606 * SDIO_PRESETVAL1
607 *
608 * Field Bit(s) Description
609 * ============================================================
610 * DDR50_PRESET 25:13 Preset Value for DDR50
611 * DEFAULT_PRESET 12:0 Preset Value for Default Speed
612 */
613#define SDIO_PRESETVAL1 0x01004004
614
615/*
616 * SDIO_PRESETVAL2
617 *
618 * Field Bit(s) Description
619 * ============================================================
620 * HIGH_SPEED_PRESET 25:13 Preset Value for High Speed
621 * INIT_PRESET 12:0 Preset Value for Initialization
622 */
623#define SDIO_PRESETVAL2 0x01004100
624
625/*
626 * SDIO_PRESETVAL3
627 *
628 * Field Bit(s) Description
629 * ============================================================
630 * SDR104_PRESET 25:13 Preset Value for SDR104
631 * SDR12_PRESET 12:0 Preset Value for SDR12
632 */
633#define SDIO_PRESETVAL3 0x00000004
634
635/*
636 * SDIO_PRESETVAL4
637 *
638 * Field Bit(s) Description
639 * ============================================================
640 * SDR25_PRESET 25:13 Preset Value for SDR25
641 * SDR50_PRESET 12:0 Preset Value for SDR50
642 */
643#define SDIO_PRESETVAL4 0x01005001
644
645static void sdio_ctrl_init(unsigned int idx)
646{
647 unsigned int sdio_idm_io_control_direct_reg;
648 unsigned int cdru_sdio_io_control_reg;
649 unsigned int sdio_idm_reset_control_reg;
650 unsigned int val, timeout;
651
652 switch (idx) {
653 case 0:
654 sdio_idm_io_control_direct_reg = SDIO_IDM0_IO_CONTROL_DIRECT;
655 cdru_sdio_io_control_reg = CDRU_SDIO0_IO_CONTROL;
656 sdio_idm_reset_control_reg = SDIO_IDM0_IDM_RESET_CONTROL;
657 break;
658 case 1:
659 sdio_idm_io_control_direct_reg = SDIO_IDM1_IO_CONTROL_DIRECT;
660 cdru_sdio_io_control_reg = CDRU_SDIO1_IO_CONTROL;
661 sdio_idm_reset_control_reg = SDIO_IDM1_IDM_RESET_CONTROL;
662 break;
663 default:
664 return;
665 }
666
667 /*
668 * Disable the cmd conflict error interrupt and enable feedback clock
669 */
670 val = read32((void *)sdio_idm_io_control_direct_reg);
671 val |= SDIO_CMD_COMFLICT_DISABLE | SDIO_FEEDBACK_CLK_EN |
672 SDIO_CLK_ENABLE;
673 write32((void *)sdio_idm_io_control_direct_reg, val);
674
675 /*
676 * Set drive strength, enable hysteresis and slew rate control
677 */
678 val = SDIO_DEFAULT_DRIVE_STRENGTH |
679 HYSTERESIS_ENABLE | SLEW_RATE_ENABLE;
680 write32((void *)cdru_sdio_io_control_reg, val);
681
682 /* Reset SDIO controller */
683 val = read32((void *)sdio_idm_reset_control_reg);
684 val |= SDIO_RESET_MASK;
685 write32((void *)sdio_idm_reset_control_reg, SDIO_RESET_MASK);
686 udelay(10);
687 val &= ~SDIO_RESET_MASK;
688 write32((void *)sdio_idm_reset_control_reg, val);
689
690 timeout = 0;
691 while (read32((void *)sdio_idm_reset_control_reg) & SDIO_RESET_MASK) {
692 udelay(1);
693 if (timeout++ > SDIO_RESET_TIMEOUT)
694 die("Failed to bring SDIO out of reset\n");
695 }
696}
697
698static void sdio_init(void)
699{
700 unsigned int val;
701
702 /*
703 * Configure SDIO host controller capabilities
704 * (common setting for all SDIO controllers)
705 */
706 write32((void *)CRMU_SDIO_CONTROL0, SDIO_CAPS_H);
707 write32((void *)CRMU_SDIO_CONTROL1, SDIO_CAPS_L);
708 /*
709 * Configure SDIO host controller preset values
710 * (common setting for all SDIO controllers)
711 */
712 write32((void *)CRMU_SDIO_CONTROL2, SDIO_PRESETVAL1);
713 write32((void *)CRMU_SDIO_CONTROL3, SDIO_PRESETVAL2);
714 write32((void *)CRMU_SDIO_CONTROL4, SDIO_PRESETVAL3);
715 write32((void *)CRMU_SDIO_CONTROL5, SDIO_PRESETVAL4);
716
717 /*
718 * The sdhci driver attempts to change the SDIO IO voltage for UHS-I
719 * cards by setting the EN1P8V in control2 register then checks the
720 * outcome by reading it back.
721 * Cygnus does not have an internal regulator for the SDIO IO voltage
722 * but can be configured to indicate success (leave EN1P8V set)
723 * or failure (clear EN1P8V).
724 *
725 * Clear CRMU_SDIO_UHS1_18V_VREG_FAIL in CRMU_SDIO_1P8_FAIL_CONTROL
726 * register to indicate success.
727 * (common setting for all SDIO controllers)
728 */
729 val = read32((void *)CRMU_SDIO_1P8_FAIL_CONTROL);
730 val &= ~UHS1_18V_VREG_FAIL;
731 write32((void *)CRMU_SDIO_1P8_FAIL_CONTROL, val);
732
733 /*
734 * Initialize each SDIO controller
735 */
736 sdio_ctrl_init(0);
737 sdio_ctrl_init(1);
738}
739
740void hw_init(void)
741{
Corneliu Doban189bec52015-04-10 15:51:55 -0700742 tz_init();
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -0700743 printk(BIOS_INFO, "trustzone initialized\n");
744 dmac_init();
Corneliu Doban189bec52015-04-10 15:51:55 -0700745 printk(BIOS_INFO, "PL330 DMAC initialized\n");
Corneliu Dobanbcdbdc62015-04-02 16:19:18 -0700746 lcd_init();
747 lcd_qos_init(15);
748 printk(BIOS_INFO, "LCD initialized\n");
749 v3d_init();
750 printk(BIOS_INFO, "V3D initialized\n");
751 audio_init();
752 printk(BIOS_INFO, "audio initialized\n");
753 neon_init();
754 printk(BIOS_INFO, "neon initialized\n");
755 pcie_init();
756 printk(BIOS_INFO, "PCIe initialized\n");
757 M0_init();
758 printk(BIOS_INFO, "M0 initialized\n");
759 ccu_init();
760 printk(BIOS_INFO, "CCU initialized\n");
761 sdio_init();
762 printk(BIOS_INFO, "SDIO initialized\n");
763}