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