blob: 5c71fed9b93dd22c5bd36b962f548f694853aeeb [file] [log] [blame]
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +02001/*
2 * Copyright (C) 2018 Marvell International Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
6 */
7
8/* AP806 Marvell SoC driver */
9
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010#include <common/debug.h>
11#include <drivers/marvell/ccu.h>
12#include <drivers/marvell/cache_llc.h>
13#include <drivers/marvell/io_win.h>
14#include <drivers/marvell/mci.h>
15#include <drivers/marvell/mochi/ap_setup.h>
16#include <lib/mmio.h>
17
Konstantin Porotchkin97fb7582020-10-19 11:28:54 +030018#include <a8k_plat_def.h>
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +020019
20#define SMMU_sACR (MVEBU_SMMU_BASE + 0x10)
21#define SMMU_sACR_PG_64K (1 << 16)
22
23#define CCU_GSPMU_CR (MVEBU_CCU_BASE(MVEBU_AP0) + \
24 0x3F0)
25#define GSPMU_CPU_CONTROL (0x1 << 0)
26
27#define CCU_HTC_CR (MVEBU_CCU_BASE(MVEBU_AP0) + \
28 0x200)
29#define CCU_SET_POC_OFFSET 5
30
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +020031#define DSS_CR0 (MVEBU_RFU_BASE + 0x100)
32#define DVM_48BIT_VA_ENABLE (1 << 21)
33
34/* Secure MoChi incoming access */
35#define SEC_MOCHI_IN_ACC_REG (MVEBU_RFU_BASE + 0x4738)
36#define SEC_MOCHI_IN_ACC_IHB0_EN (1)
37#define SEC_MOCHI_IN_ACC_IHB1_EN (1 << 3)
38#define SEC_MOCHI_IN_ACC_IHB2_EN (1 << 6)
39#define SEC_MOCHI_IN_ACC_PIDI_EN (1 << 9)
40#define SEC_IN_ACCESS_ENA_ALL_MASTERS (SEC_MOCHI_IN_ACC_IHB0_EN | \
41 SEC_MOCHI_IN_ACC_IHB1_EN | \
42 SEC_MOCHI_IN_ACC_IHB2_EN | \
43 SEC_MOCHI_IN_ACC_PIDI_EN)
Konstantin Porotchkin7a96a502019-08-22 14:23:34 +030044#define MOCHI_IN_ACC_LEVEL_FORCE_NONSEC (0)
45#define MOCHI_IN_ACC_LEVEL_FORCE_SEC (1)
46#define MOCHI_IN_ACC_LEVEL_LEAVE_ORIG (2)
47#define MOCHI_IN_ACC_LEVEL_MASK_ALL (3)
48#define SEC_MOCHI_IN_ACC_IHB0_LEVEL(l) ((l) << 1)
49#define SEC_MOCHI_IN_ACC_IHB1_LEVEL(l) ((l) << 4)
50#define SEC_MOCHI_IN_ACC_PIDI_LEVEL(l) ((l) << 10)
51
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +020052
53/* SYSRST_OUTn Config definitions */
54#define MVEBU_SYSRST_OUT_CONFIG_REG (MVEBU_MISC_SOC_BASE + 0x4)
55#define WD_MASK_SYS_RST_OUT (1 << 2)
56
57/* Generic Timer System Controller */
58#define MVEBU_MSS_GTCR_REG (MVEBU_REGS_BASE + 0x581000)
59#define MVEBU_MSS_GTCR_ENABLE_BIT 0x1
60
61/*
62 * AXI Configuration.
63 */
64
65/* Used for Units of AP-806 (e.g. SDIO and etc) */
66#define MVEBU_AXI_ATTR_BASE (MVEBU_REGS_BASE + 0x6F4580)
67#define MVEBU_AXI_ATTR_REG(index) (MVEBU_AXI_ATTR_BASE + \
68 0x4 * index)
69
Konstantin Porotchkin97fb7582020-10-19 11:28:54 +030070#define XOR_STREAM_ID_REG(ch) (MVEBU_REGS_BASE + 0x410010 + (ch) * 0x20000)
71#define XOR_STREAM_ID_MASK 0xFFFF
72#define SDIO_STREAM_ID_REG (MVEBU_RFU_BASE + 0x4600)
73#define SDIO_STREAM_ID_MASK 0xFF
74
75/* Do not use the default Stream ID 0 */
76#define A806_STREAM_ID_BASE (0x1)
77
78static uintptr_t stream_id_reg[] = {
79 XOR_STREAM_ID_REG(0),
80 XOR_STREAM_ID_REG(1),
81 XOR_STREAM_ID_REG(2),
82 XOR_STREAM_ID_REG(3),
83 SDIO_STREAM_ID_REG,
84 0
85};
86
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +020087enum axi_attr {
88 AXI_SDIO_ATTR = 0,
89 AXI_DFX_ATTR,
90 AXI_MAX_ATTR,
91};
92
93static void apn_sec_masters_access_en(uint32_t enable)
94{
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +020095 /* Open/Close incoming access for all masters.
96 * The access is disabled in trusted boot mode
97 * Could only be done in EL3
98 */
Konstantin Porotchkin7a96a502019-08-22 14:23:34 +030099 if (enable != 0) {
100 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 0x0U, /* no clear */
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +0200101 SEC_IN_ACCESS_ENA_ALL_MASTERS);
Konstantin Porotchkin7a96a502019-08-22 14:23:34 +0300102#if LLC_SRAM
103 /* Do not change access security level
104 * for PIDI masters
105 */
106 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG,
107 SEC_MOCHI_IN_ACC_PIDI_LEVEL(
108 MOCHI_IN_ACC_LEVEL_MASK_ALL),
109 SEC_MOCHI_IN_ACC_PIDI_LEVEL(
110 MOCHI_IN_ACC_LEVEL_LEAVE_ORIG));
111#endif
112 } else {
113 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG,
114 SEC_IN_ACCESS_ENA_ALL_MASTERS,
115 0x0U /* no set */);
116#if LLC_SRAM
117 /* Return PIDI access level to the default */
118 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG,
119 SEC_MOCHI_IN_ACC_PIDI_LEVEL(
120 MOCHI_IN_ACC_LEVEL_MASK_ALL),
121 SEC_MOCHI_IN_ACC_PIDI_LEVEL(
122 MOCHI_IN_ACC_LEVEL_FORCE_NONSEC));
123#endif
124 }
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +0200125}
126
127static void setup_smmu(void)
128{
129 uint32_t reg;
130
131 /* Set the SMMU page size to 64 KB */
132 reg = mmio_read_32(SMMU_sACR);
133 reg |= SMMU_sACR_PG_64K;
134 mmio_write_32(SMMU_sACR, reg);
135}
136
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +0200137static void init_aurora2(void)
138{
139 uint32_t reg;
140
141 /* Enable GSPMU control by CPU */
142 reg = mmio_read_32(CCU_GSPMU_CR);
143 reg |= GSPMU_CPU_CONTROL;
144 mmio_write_32(CCU_GSPMU_CR, reg);
145
146#if LLC_ENABLE
147 /* Enable LLC for AP806 in exclusive mode */
148 llc_enable(0, 1);
149
150 /* Set point of coherency to DDR.
151 * This is required by units which have
152 * SW cache coherency
153 */
154 reg = mmio_read_32(CCU_HTC_CR);
155 reg |= (0x1 << CCU_SET_POC_OFFSET);
156 mmio_write_32(CCU_HTC_CR, reg);
157#endif /* LLC_ENABLE */
158
Stefan Chulski5dea9472019-06-25 15:41:47 +0300159 errata_wa_init();
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +0200160}
161
162
163/* MCIx indirect access register are based by default at 0xf4000000/0xf6000000
164 * to avoid conflict of internal registers of units connected via MCIx, which
165 * can be based on the same address (i.e CP1 base is also 0xf4000000),
166 * the following routines remaps the MCIx indirect bases to another domain
167 */
168static void mci_remap_indirect_access_base(void)
169{
170 uint32_t mci;
171
172 for (mci = 0; mci < MCI_MAX_UNIT_ID; mci++)
173 mmio_write_32(MCIX4_REG_START_ADDRESS_REG(mci),
174 MVEBU_MCI_REG_BASE_REMAP(mci) >>
175 MCI_REMAP_OFF_SHIFT);
176}
177
Konstantin Porotchkin97fb7582020-10-19 11:28:54 +0300178/* Set a unique stream id for all DMA capable devices */
179static void ap806_stream_id_init(void)
180{
181 int i;
182
183 for (i = 0; stream_id_reg[i] != 0; i++) {
184 uint32_t mask = stream_id_reg[i] == SDIO_STREAM_ID_REG ?
185 SDIO_STREAM_ID_MASK : XOR_STREAM_ID_MASK;
186
187 mmio_clrsetbits_32(stream_id_reg[i], mask,
188 i + A806_STREAM_ID_BASE);
189 }
190}
191
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +0200192static void apn806_axi_attr_init(void)
193{
194 uint32_t index, data;
195
196 /* Initialize AXI attributes for APN806 */
197
198 /* Go over the AXI attributes and set Ax-Cache and Ax-Domain */
199 for (index = 0; index < AXI_MAX_ATTR; index++) {
200 switch (index) {
201 /* DFX works with no coherent only -
202 * there's no option to configure the Ax-Cache and Ax-Domain
203 */
204 case AXI_DFX_ATTR:
205 continue;
206 default:
207 /* Set Ax-Cache as cacheable, no allocate, modifiable,
208 * bufferable
209 * The values are different because Read & Write
210 * definition is different in Ax-Cache
211 */
212 data = mmio_read_32(MVEBU_AXI_ATTR_REG(index));
213 data &= ~MVEBU_AXI_ATTR_ARCACHE_MASK;
214 data |= (CACHE_ATTR_WRITE_ALLOC |
215 CACHE_ATTR_CACHEABLE |
216 CACHE_ATTR_BUFFERABLE) <<
217 MVEBU_AXI_ATTR_ARCACHE_OFFSET;
218 data &= ~MVEBU_AXI_ATTR_AWCACHE_MASK;
219 data |= (CACHE_ATTR_READ_ALLOC |
220 CACHE_ATTR_CACHEABLE |
221 CACHE_ATTR_BUFFERABLE) <<
222 MVEBU_AXI_ATTR_AWCACHE_OFFSET;
223 /* Set Ax-Domain as Outer domain */
224 data &= ~MVEBU_AXI_ATTR_ARDOMAIN_MASK;
225 data |= DOMAIN_OUTER_SHAREABLE <<
226 MVEBU_AXI_ATTR_ARDOMAIN_OFFSET;
227 data &= ~MVEBU_AXI_ATTR_AWDOMAIN_MASK;
228 data |= DOMAIN_OUTER_SHAREABLE <<
229 MVEBU_AXI_ATTR_AWDOMAIN_OFFSET;
230 mmio_write_32(MVEBU_AXI_ATTR_REG(index), data);
231 }
232 }
233}
234
235static void dss_setup(void)
236{
237 /* Enable 48-bit VA */
238 mmio_setbits_32(DSS_CR0, DVM_48BIT_VA_ENABLE);
239}
240
241void misc_soc_configurations(void)
242{
243 uint32_t reg;
244
245 /* Un-mask Watchdog reset from influencing the SYSRST_OUTn.
246 * Otherwise, upon WD timeout, the WD reset signal won't trigger reset
247 */
248 reg = mmio_read_32(MVEBU_SYSRST_OUT_CONFIG_REG);
249 reg &= ~(WD_MASK_SYS_RST_OUT);
250 mmio_write_32(MVEBU_SYSRST_OUT_CONFIG_REG, reg);
251}
252
253void ap_init(void)
254{
255 /* Setup Aurora2. */
256 init_aurora2();
257
258 /* configure MCI mapping */
259 mci_remap_indirect_access_base();
260
261 /* configure IO_WIN windows */
262 init_io_win(MVEBU_AP0);
263
264 /* configure CCU windows */
265 init_ccu(MVEBU_AP0);
266
267 /* configure DSS */
268 dss_setup();
269
Konstantin Porotchkin97fb7582020-10-19 11:28:54 +0300270 /* Set the stream IDs for DMA masters */
271 ap806_stream_id_init();
272
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +0200273 /* configure the SMMU */
274 setup_smmu();
275
276 /* Open APN incoming access for all masters */
277 apn_sec_masters_access_en(1);
278
279 /* configure axi for APN*/
280 apn806_axi_attr_init();
281
282 /* misc configuration of the SoC */
283 misc_soc_configurations();
284}
285
286void ap_ble_init(void)
287{
288}
289
290int ap_get_count(void)
291{
292 return 1;
293}
294
Grzegorz Jaszczyk02721c72019-01-13 17:33:45 +0200295void update_cp110_default_win(int cp_id)
296{
297}