1 /*
2 * Copyright (c) 2024 Junho Lee <junho@tsnlab.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(pcie_brcmstb, LOG_LEVEL_ERR);
9
10 #include <zephyr/arch/common/sys_bitops.h>
11 #include <zephyr/arch/cpu.h>
12 #include <zephyr/device.h>
13 #include <zephyr/kernel.h>
14 #include <zephyr/math/ilog2.h>
15 #include <zephyr/sys/device_mmio.h>
16
17 #include <zephyr/drivers/pcie/pcie.h>
18 #include <zephyr/drivers/pcie/controller.h>
19
20 #define DT_DRV_COMPAT brcm_brcmstb_pcie
21
22 #define PCIE_RC_PL_PHY_CTL_15 0x184c
23 #define PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK 0xff
24
25 #define PCIE_MISC_MISC_CTRL 0x4008
26 #define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000
27 #define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000
28 #define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000
29 #define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_LSB 20
30 #define PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK 0xf8000000
31 #define PCIE_MISC_MISC_CTRL_SCB0_SIZE_LSB 27
32
33 #define PCIE_MISC_RC_BAR_CONFIG_LO_SIZE_MASK 0x1f
34
35 #define PCIE_MISC_RC_BAR1_CONFIG_LO 0x402c
36 #define PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK 0x1f
37
38 #define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034
39 #define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK 0x1f
40 #define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_LSB 0
41 #define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038
42
43 #define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c
44 #define PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK 0x1f
45
46 #define PCIE_MISC_RC_BAR4_CONFIG_LO 0x40d4
47 #define PCIE_MISC_RC_BAR4_CONFIG_HI 0x40d8
48
49 #define PCIE_MISC_UBUS_BAR_CONFIG_REMAP_ENABLE 0x1
50 #define PCIE_MISC_UBUS_BAR_CONFIG_REMAP_LO_MASK 0xfffff000
51 #define PCIE_MISC_UBUS_BAR_CONFIG_REMAP_HI_MASK 0xff
52
53 #define PCIE_MISC_UBUS_BAR2_CONFIG_REMAP 0x40b4
54 #define PCIE_MISC_UBUS_BAR2_CONFIG_REMAP_ACCESS_ENABLE_MASK 0x1
55
56 #define PCIE_MISC_UBUS_BAR4_CONFIG_REMAP_LO 0x410c
57 #define PCIE_MISC_UBUS_BAR4_CONFIG_REMAP_HI 0x4110
58
59 #define PCIE_MISC_UBUS_CTRL 0x40a4
60 #define PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_ERR_DIS_MASK 0x2000
61 #define PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_DECERR_DIS_MASK 0x80000
62
63 #define PCIE_MISC_AXI_READ_ERROR_DATA 0x4170
64 #define PCIE_MISC_UBUS_TIMEOUT 0x40a8
65 #define PCIE_MISC_RC_CONFIG_RETRY_TIMEOUT 0x405c
66
67 #define PCIE_MISC_PCIE_CTRL 0x4064
68 #define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK 0x4
69
70 #define PCIE_RC_CFG_PRIV1_ID_VAL3 0x043c
71 #define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff
72
73 #define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1 0x0188
74 #define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK 0xc
75 #define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_LSB 2
76 #define PCIE_RC_CFG_VENDOR_SPECIFIC_REG1_LITTLE_ENDIAN 0x0
77
78 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c
79 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI 0x4010
80 #define PCIE_MEM_WIN0_LO(win) (PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + (win) * 8)
81 #define PCIE_MEM_WIN0_HI(win) (PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + (win) * 8)
82
83 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070
84 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000
85 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_LSB 20
86 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0
87 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_LSB 4
88
89 #define PCIE_MEM_WIN0_BASE_LIMIT(win) (PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + (win) * 4)
90
91 /* Hamming weight of PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK */
92 #define HIGH_ADDR_SHIFT 12
93
94 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI 0x4080
95 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK 0xff
96 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_LSB 0
97
98 #define PCIE_MEM_WIN0_BASE_HI(win) (PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + (win) * 8)
99
100 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084
101 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK 0xff
102 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_LSB 0
103
104 #define PCIE_MEM_WIN0_LIMIT_HI(win) (PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + (win) * 8)
105
106 #define PCIE_EXT_CFG_DATA 0x8000
107 #define PCIE_EXT_CFG_INDEX 0x9000
108
109 #define PCI_BASE_ADDRESS_0 0x10
110
111 #define PCI_COMMAND 0x0004
112 #define PCI_COMMAND_MEMORY 0x2
113 #define PCI_COMMAND_MASTER 0x4
114
115 #define PCI_EXP_LNKCAP 0x0c
116 #define PCI_EXP_LNKCAP_SLS 0xf
117 #define PCI_EXP_LNKCTL2 0x30
118
119 #define BRCM_PCIE_CAP_REGS 0x00ac
120
121 #define BCM2712_RC_BAR2_SIZE 0x400000
122 #define BCM2712_RC_BAR2_OFFSET 0x0
123 #define BCM2712_RC_BAR4_CPU 0x0
124 #define BCM2712_RC_BAR4_SIZE 0x0
125 #define BCM2712_RC_BAR4_PCI 0x0
126 #define BCM2712_SCB0_SIZE 0x400000
127
128 #define BCM2712_BURST_SIZE 0x1
129
130 #define BCM2712_CLOCK_RATE 750000000ULL /* 750Mhz */
131
132 #define BCM2712_UBUS_TIMEOUT_NS 250000000ULL /* 250ms */
133 #define BCM2712_UBUS_TIMEOUT_TICKS (BCM2712_UBUS_TIMEOUT_NS * BCM2712_CLOCK_RATE / 1000000000ULL)
134
135 #define BCM2712_RC_CONFIG_RETRY_TIMEOUT_NS 240000000ULL /* 240ms */
136 #define BCM2712_RC_CONFIG_RETRY_TIMEOUT_TICKS \
137 (BCM2712_RC_CONFIG_RETRY_TIMEOUT_NS * BCM2712_CLOCK_RATE / 1000000000ULL)
138
139 #define BCM2712_PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE 0x060400
140
141 #define MDIO_DATA_DONE_MASK 0x80000000
142 #define MDIO_CMD_WRITE 0x0
143 #define MDIO_PORT0 0x0
144
145 #define PCIE_RC_DL_MDIO_ADDR 0x1100
146 #define PCIE_RC_DL_MDIO_WR_DATA 0x1104
147 #define PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD 0x12 /* 18.52ns as ticks */
148
149 #define SET_ADDR_OFFSET 0x1f
150
151 #define DMA_RANGES_IDX 2
152
153 #define PCIE_ECAM_BDF_SHIFT 12
154
155 #define BAR_MAX 8
156
157 #define SZ_1M 0x100000
158
159 struct pcie_brcmstb_config {
160 const struct pcie_ctrl_config *common;
161 size_t regs_count;
162 struct {
163 uintptr_t addr;
164 size_t size;
165 } regs[BAR_MAX];
166 };
167
168 enum pcie_region_type {
169 PCIE_REGION_IO = 0,
170 PCIE_REGION_MEM,
171 PCIE_REGION_MEM64,
172 PCIE_REGION_MAX,
173 };
174
175 struct pcie_brcmstb_data {
176 uintptr_t cfg_phys_addr;
177 mm_reg_t cfg_addr;
178 size_t cfg_size;
179 struct {
180 uintptr_t phys_start;
181 uintptr_t bus_start;
182 size_t size;
183 size_t allocation_offset;
184 } regions[PCIE_REGION_MAX];
185 size_t bar_cnt;
186 };
187
lower_32_bits(uint64_t val)188 static inline uint32_t lower_32_bits(uint64_t val)
189 {
190 return val & 0xffffffff;
191 }
192
upper_32_bits(uint64_t val)193 static inline uint32_t upper_32_bits(uint64_t val)
194 {
195 return (val >> 32) & 0xffffffff;
196 }
197
encode_ibar_size(uint64_t size)198 static uint32_t encode_ibar_size(uint64_t size)
199 {
200 uint32_t tmp;
201 uint32_t size_upper = (uint32_t)(size >> 32);
202
203 if (size_upper > 0) {
204 tmp = ilog2(size_upper) + 32;
205 } else {
206 tmp = ilog2(size);
207 }
208
209 if (tmp >= 12 && tmp <= 15) {
210 return (tmp - 12) + 0x1c;
211 } else if (tmp >= 16 && tmp <= 36) {
212 return tmp - 15;
213 }
214
215 return 0;
216 }
217
pcie_brcmstb_map_bus(const struct device * dev,pcie_bdf_t bdf,unsigned int reg)218 static mm_reg_t pcie_brcmstb_map_bus(const struct device *dev, pcie_bdf_t bdf, unsigned int reg)
219 {
220 struct pcie_brcmstb_data *data = dev->data;
221
222 sys_write32(bdf << PCIE_ECAM_BDF_SHIFT, data->cfg_addr + PCIE_EXT_CFG_INDEX);
223 return data->cfg_addr + PCIE_EXT_CFG_DATA + reg * sizeof(uint32_t);
224 }
225
pcie_brcmstb_conf_read(const struct device * dev,pcie_bdf_t bdf,unsigned int reg)226 static uint32_t pcie_brcmstb_conf_read(const struct device *dev, pcie_bdf_t bdf, unsigned int reg)
227 {
228 mm_reg_t conf_addr = pcie_brcmstb_map_bus(dev, bdf, reg);
229
230 if (!conf_addr) {
231 return 0xffffffff;
232 }
233
234 return sys_read32(conf_addr);
235 }
236
pcie_brcmstb_conf_write(const struct device * dev,pcie_bdf_t bdf,unsigned int reg,uint32_t data)237 void pcie_brcmstb_conf_write(const struct device *dev, pcie_bdf_t bdf, unsigned int reg,
238 uint32_t data)
239 {
240 mm_reg_t conf_addr = pcie_brcmstb_map_bus(dev, bdf, reg);
241
242 if (!conf_addr) {
243 return;
244 }
245
246 sys_write32(data, conf_addr);
247 }
248
pcie_brcmstb_determine_region_type(const struct device * dev,bool mem,bool mem64)249 static inline enum pcie_region_type pcie_brcmstb_determine_region_type(const struct device *dev,
250 bool mem, bool mem64)
251 {
252 struct pcie_brcmstb_data *data = dev->data;
253
254 if (!mem) {
255 return PCIE_REGION_IO;
256 }
257
258 if ((data->regions[PCIE_REGION_MEM64].size > 0) &&
259 (mem64 || data->regions[PCIE_REGION_MEM].size == 0)) {
260 return PCIE_REGION_MEM64;
261 }
262
263 return PCIE_REGION_MEM;
264 }
265
pcie_brcmstb_region_allocate_type(const struct device * dev,pcie_bdf_t bdf,size_t bar_size,uintptr_t * bar_bus_addr,enum pcie_region_type type)266 static bool pcie_brcmstb_region_allocate_type(const struct device *dev, pcie_bdf_t bdf,
267 size_t bar_size, uintptr_t *bar_bus_addr,
268 enum pcie_region_type type)
269 {
270 const struct pcie_brcmstb_config *config = dev->config;
271 struct pcie_brcmstb_data *data = dev->data;
272 uintptr_t addr;
273
274 addr = (((data->regions[type].bus_start + config->regs[PCIE_BDF_TO_BUS(bdf) + 1].addr +
275 data->regions[type].allocation_offset) -
276 1) |
277 ((bar_size)-1)) +
278 1;
279
280 if (addr + bar_size > data->regions[type].bus_start + data->regions[type].size) {
281 return false;
282 }
283
284 *bar_bus_addr = addr;
285
286 return true;
287 }
288
pcie_brcmstb_region_allocate(const struct device * dev,pcie_bdf_t bdf,bool mem,bool mem64,size_t bar_size,uintptr_t * bar_bus_addr)289 static bool pcie_brcmstb_region_allocate(const struct device *dev, pcie_bdf_t bdf, bool mem,
290 bool mem64, size_t bar_size, uintptr_t *bar_bus_addr)
291 {
292 struct pcie_brcmstb_data *data = dev->data;
293 enum pcie_region_type type;
294
295 if (!mem && mem64) {
296 return false;
297 }
298
299 if (mem && data->regions[PCIE_REGION_MEM64].size == 0 &&
300 data->regions[PCIE_REGION_MEM].size == 0) {
301 return false;
302 }
303
304 if (!mem && data->regions[PCIE_REGION_IO].size == 0) {
305 return false;
306 }
307
308 type = pcie_brcmstb_determine_region_type(dev, mem, mem64);
309
310 return pcie_brcmstb_region_allocate_type(dev, bdf, bar_size, bar_bus_addr, type);
311 }
312
pcie_brcmstb_region_get_allocate_base(const struct device * dev,pcie_bdf_t bdf,bool mem,bool mem64,size_t align,uintptr_t * bar_base_addr)313 static bool pcie_brcmstb_region_get_allocate_base(const struct device *dev, pcie_bdf_t bdf,
314 bool mem, bool mem64, size_t align,
315 uintptr_t *bar_base_addr)
316 {
317 struct pcie_brcmstb_data *data = dev->data;
318 enum pcie_region_type type;
319
320 if (!mem && mem64) {
321 return false;
322 }
323
324 if (mem && data->regions[PCIE_REGION_MEM64].size == 0 &&
325 data->regions[PCIE_REGION_MEM].size == 0) {
326 return false;
327 }
328
329 if (!mem && data->regions[PCIE_REGION_IO].size == 0) {
330 return false;
331 }
332
333 type = pcie_brcmstb_determine_region_type(dev, mem, mem64);
334
335 *bar_base_addr =
336 (((data->regions[type].bus_start + data->regions[type].allocation_offset) - 1) |
337 ((align)-1)) +
338 1;
339
340 return true;
341 }
342
pcie_brcmstb_region_translate(const struct device * dev,pcie_bdf_t bdf,bool mem,bool mem64,uintptr_t bar_bus_addr,uintptr_t * bar_addr)343 static bool pcie_brcmstb_region_translate(const struct device *dev, pcie_bdf_t bdf, bool mem,
344 bool mem64, uintptr_t bar_bus_addr, uintptr_t *bar_addr)
345 {
346 struct pcie_brcmstb_data *data = dev->data;
347 enum pcie_region_type type;
348
349 type = pcie_brcmstb_determine_region_type(dev, mem, mem64);
350
351 *bar_addr = data->regions[type].phys_start + (bar_bus_addr - data->regions[type].bus_start);
352
353 return true;
354 }
355
356 static DEVICE_API(pcie_ctrl, pcie_brcmstb_api) = {
357 .conf_read = pcie_brcmstb_conf_read,
358 .conf_write = pcie_brcmstb_conf_write,
359 .region_allocate = pcie_brcmstb_region_allocate,
360 .region_get_allocate_base = pcie_brcmstb_region_get_allocate_base,
361 .region_translate = pcie_brcmstb_region_translate,
362 };
363
pcie_brcmstb_parse_regions(const struct device * dev)364 static int pcie_brcmstb_parse_regions(const struct device *dev)
365 {
366 const struct pcie_brcmstb_config *config = dev->config;
367 struct pcie_brcmstb_data *data = dev->data;
368 enum pcie_region_type type;
369 int i;
370
371 for (i = 0; i < DMA_RANGES_IDX; i++) {
372 switch ((config->common->ranges[i].flags >> 24) & 0x03) {
373 case 0x01:
374 type = PCIE_REGION_IO;
375 break;
376 case 0x02:
377 type = PCIE_REGION_MEM;
378 break;
379 case 0x03:
380 type = PCIE_REGION_MEM64;
381 break;
382 default:
383 continue;
384 }
385 data->regions[type].bus_start = config->common->ranges[i].pcie_bus_addr;
386 data->regions[type].phys_start = config->common->ranges[i].host_map_addr;
387 data->regions[type].size = config->common->ranges[i].map_length;
388 }
389
390 if (!data->regions[PCIE_REGION_IO].size && !data->regions[PCIE_REGION_MEM].size &&
391 !data->regions[PCIE_REGION_MEM64].size) {
392 return -EINVAL;
393 }
394
395 return 0;
396 }
397
pcie_brcmstb_mdio_from_pkt(int port,int regad,int cmd)398 static mm_reg_t pcie_brcmstb_mdio_from_pkt(int port, int regad, int cmd)
399 {
400 return (mm_reg_t)cmd << 20 | port << 16 | regad;
401 }
402
pcie_brcmstb_mdio_write(mm_reg_t base,uint8_t port,uint8_t regad,uint16_t wrdata)403 static void pcie_brcmstb_mdio_write(mm_reg_t base, uint8_t port, uint8_t regad, uint16_t wrdata)
404 {
405 sys_write32(pcie_brcmstb_mdio_from_pkt(port, regad, MDIO_CMD_WRITE),
406 base + PCIE_RC_DL_MDIO_ADDR);
407 sys_write32(MDIO_DATA_DONE_MASK | wrdata, base + PCIE_RC_DL_MDIO_WR_DATA);
408 }
409
pcie_brcmstb_munge_pll(const struct device * dev)410 static void pcie_brcmstb_munge_pll(const struct device *dev)
411 {
412 struct pcie_brcmstb_data *data = dev->data;
413 int i;
414
415 uint8_t regs[] = {0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1e};
416 uint16_t vals[] = {0x50b9, 0xbda1, 0x0094, 0x97b4, 0x5030, 0x5030, 0x0007};
417
418 pcie_brcmstb_mdio_write(data->cfg_addr, MDIO_PORT0, SET_ADDR_OFFSET, 0x1600);
419 for (i = 0; i < 7; i++) {
420 k_busy_wait(300);
421 pcie_brcmstb_mdio_write(data->cfg_addr, MDIO_PORT0, regs[i], vals[i]);
422 }
423 }
424
pcie_brcmstb_set_outbound_win(const struct device * dev,uint8_t win,uintptr_t cpu_addr,uintptr_t pcie_addr,size_t size)425 static void pcie_brcmstb_set_outbound_win(const struct device *dev, uint8_t win, uintptr_t cpu_addr,
426 uintptr_t pcie_addr, size_t size)
427 {
428 struct pcie_brcmstb_data *data = dev->data;
429 uint32_t cpu_addr_mb_high, limit_addr_mb_high;
430 uintptr_t cpu_addr_mb, limit_addr_mb;
431 uint32_t tmp, tmp2;
432
433 sys_write32(lower_32_bits(pcie_addr), data->cfg_addr + PCIE_MEM_WIN0_LO(win));
434 sys_write32(upper_32_bits(pcie_addr), data->cfg_addr + PCIE_MEM_WIN0_HI(win));
435
436 cpu_addr_mb = cpu_addr / SZ_1M;
437 limit_addr_mb = (cpu_addr + size - 1) / SZ_1M;
438
439 tmp = sys_read32(data->cfg_addr + PCIE_MEM_WIN0_BASE_LIMIT(win));
440 tmp &= ~PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK;
441 tmp &= ~PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK;
442 tmp2 = (cpu_addr_mb << PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_LSB);
443 tmp2 &= PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK;
444 tmp |= tmp2;
445 tmp2 = (limit_addr_mb << PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_LSB);
446 tmp2 &= PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK;
447 tmp |= tmp2;
448 sys_write32(tmp, data->cfg_addr + PCIE_MEM_WIN0_BASE_LIMIT(win));
449
450 cpu_addr_mb_high = cpu_addr_mb >> HIGH_ADDR_SHIFT;
451 tmp = sys_read32(data->cfg_addr + PCIE_MEM_WIN0_BASE_HI(win));
452 tmp &= ~PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK;
453 tmp |= (cpu_addr_mb_high << PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_LSB);
454 sys_write32(tmp, data->cfg_addr + PCIE_MEM_WIN0_BASE_HI(win));
455
456 limit_addr_mb_high = limit_addr_mb >> HIGH_ADDR_SHIFT;
457 tmp = sys_read32(data->cfg_addr + PCIE_MEM_WIN0_LIMIT_HI(win));
458 tmp &= ~PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK;
459 tmp |= (cpu_addr_mb_high << PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_LSB);
460 sys_write32(tmp, data->cfg_addr + PCIE_MEM_WIN0_LIMIT_HI(win));
461 }
462
pcie_brcmstb_setup(const struct device * dev)463 static int pcie_brcmstb_setup(const struct device *dev)
464 {
465 const struct pcie_brcmstb_config *config = dev->config;
466 struct pcie_brcmstb_data *data = dev->data;
467 uint32_t tmp;
468 uint16_t tmp16;
469
470 /* This block is for BCM2712 only */
471 pcie_brcmstb_munge_pll(dev);
472 tmp = sys_read32(data->cfg_addr + PCIE_RC_PL_PHY_CTL_15);
473 tmp &= ~PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK;
474 tmp |= PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD;
475 sys_write32(tmp, data->cfg_addr + PCIE_RC_PL_PHY_CTL_15);
476
477 tmp = sys_read32(data->cfg_addr + PCIE_MISC_MISC_CTRL);
478 tmp |= PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK;
479 tmp |= PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK;
480 tmp &= ~PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK;
481 tmp |= (BCM2712_BURST_SIZE << PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_LSB);
482 sys_write32(tmp, data->cfg_addr + PCIE_MISC_MISC_CTRL);
483
484 uint64_t rc_bar2_offset = config->common->ranges[DMA_RANGES_IDX].host_map_addr -
485 config->common->ranges[DMA_RANGES_IDX].pcie_bus_addr;
486 uint64_t rc_bar2_size = config->common->ranges[DMA_RANGES_IDX].map_length;
487
488 tmp = lower_32_bits(rc_bar2_offset);
489 tmp &= ~PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK;
490 tmp |= encode_ibar_size(rc_bar2_size) << PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_LSB;
491 sys_write32(tmp, data->cfg_addr + PCIE_MISC_RC_BAR2_CONFIG_LO);
492 sys_write32(upper_32_bits(rc_bar2_offset), data->cfg_addr + PCIE_MISC_RC_BAR2_CONFIG_HI);
493
494 tmp = sys_read32(data->cfg_addr + PCIE_MISC_UBUS_BAR2_CONFIG_REMAP);
495 tmp |= PCIE_MISC_UBUS_BAR2_CONFIG_REMAP_ACCESS_ENABLE_MASK;
496 sys_write32(tmp, data->cfg_addr + PCIE_MISC_UBUS_BAR2_CONFIG_REMAP);
497
498 /* Set SCB Size */
499 tmp = sys_read32(data->cfg_addr + PCIE_MISC_MISC_CTRL);
500 tmp &= ~PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK;
501 tmp |= (ilog2(config->common->ranges[DMA_RANGES_IDX].map_length) - 15)
502 << PCIE_MISC_MISC_CTRL_SCB0_SIZE_LSB;
503 sys_write32(tmp, data->cfg_addr + PCIE_MISC_MISC_CTRL);
504
505 tmp = sys_read32(data->cfg_addr + PCIE_MISC_UBUS_CTRL);
506 tmp |= PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_ERR_DIS_MASK;
507 tmp |= PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_DECERR_DIS_MASK;
508 sys_write32(tmp, data->cfg_addr + PCIE_MISC_UBUS_CTRL);
509 sys_write32(0xffffffff, data->cfg_addr + PCIE_MISC_AXI_READ_ERROR_DATA);
510
511 /* Set timeouts */
512 sys_write32(BCM2712_UBUS_TIMEOUT_TICKS, data->cfg_addr + PCIE_MISC_UBUS_TIMEOUT);
513 sys_write32(BCM2712_RC_CONFIG_RETRY_TIMEOUT_TICKS,
514 data->cfg_addr + PCIE_MISC_RC_CONFIG_RETRY_TIMEOUT);
515
516 tmp = sys_read32(data->cfg_addr + PCIE_MISC_RC_BAR1_CONFIG_LO);
517 tmp &= ~PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK;
518 sys_write32(tmp, data->cfg_addr + PCIE_MISC_RC_BAR1_CONFIG_LO);
519
520 tmp = sys_read32(data->cfg_addr + PCIE_MISC_RC_BAR3_CONFIG_LO);
521 tmp &= ~PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK;
522 sys_write32(tmp, data->cfg_addr + PCIE_MISC_RC_BAR3_CONFIG_LO);
523
524 /* Set gen to 2 */
525 tmp16 = sys_read16(data->cfg_addr + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2);
526 tmp = sys_read32(data->cfg_addr + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP);
527 tmp &= ~PCI_EXP_LNKCAP_SLS;
528 tmp |= 0x2;
529 sys_write32(tmp, data->cfg_addr + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP);
530 tmp16 &= ~0xf;
531 tmp16 |= 0x2;
532 sys_write16(tmp16, data->cfg_addr + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2);
533
534 tmp = sys_read32(data->cfg_addr + PCIE_RC_CFG_PRIV1_ID_VAL3);
535 tmp &= ~PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK;
536 tmp |= BCM2712_PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE;
537 sys_write32(tmp, data->cfg_addr + PCIE_RC_CFG_PRIV1_ID_VAL3);
538
539 tmp = sys_read32(data->cfg_addr + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1);
540 tmp &= ~PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK;
541 tmp |= PCIE_RC_CFG_VENDOR_SPECIFIC_REG1_LITTLE_ENDIAN
542 << PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_LSB;
543 sys_write32(tmp, data->cfg_addr + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1);
544
545 return 0;
546 }
547
pcie_brcmstb_init(const struct device * dev)548 static int pcie_brcmstb_init(const struct device *dev)
549 {
550 const struct pcie_brcmstb_config *config = dev->config;
551 struct pcie_brcmstb_data *data = dev->data;
552 uint32_t tmp;
553 int ret;
554
555 if (config->common->ranges_count < DMA_RANGES_IDX) {
556 /* Workaround since macros for `dma-ranges` property is not available */
557 return -EINVAL;
558 }
559
560 ret = pcie_brcmstb_parse_regions(dev);
561 if (ret != 0) {
562 return ret;
563 }
564
565 data->cfg_phys_addr = config->common->cfg_addr;
566 data->cfg_size = config->common->cfg_size;
567
568 device_map(&data->cfg_addr, data->cfg_phys_addr, data->cfg_size, K_MEM_CACHE_NONE);
569
570 /* PCIe Setup */
571 pcie_brcmstb_setup(dev);
572
573 /* Assert PERST# */
574 tmp = sys_read32(data->cfg_addr + PCIE_MISC_PCIE_CTRL);
575 tmp |= PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK;
576 sys_write32(tmp, data->cfg_addr + PCIE_MISC_PCIE_CTRL);
577
578 k_busy_wait(500000);
579
580 /* Enable resources and bus-mastering */
581 tmp = sys_read32(data->cfg_addr + PCI_COMMAND);
582 tmp |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
583 sys_write32(tmp, data->cfg_addr + PCI_COMMAND);
584
585 for (int i = 0; i < DMA_RANGES_IDX; i++) {
586 pcie_brcmstb_set_outbound_win(dev, i, config->common->ranges[i].host_map_addr,
587 config->common->ranges[i].pcie_bus_addr,
588 config->common->ranges[i].map_length);
589 }
590
591 /* Assign BARs */
592 /* TODO: It might be possible to do this without extra <regs> property */
593 for (int i = 1; i < config->regs_count; i++) {
594 sys_write32(config->regs[i].addr, data->cfg_addr + PCIE_EXT_CFG_DATA +
595 PCI_BASE_ADDRESS_0 + 0x4 * (i - 1));
596 }
597
598 /* Enable resources */
599 tmp = sys_read32(data->cfg_addr + PCIE_EXT_CFG_DATA + PCI_COMMAND);
600 tmp |= PCI_COMMAND_MEMORY;
601 sys_write32(tmp, data->cfg_addr + PCIE_EXT_CFG_DATA + PCI_COMMAND);
602 k_busy_wait(500000);
603
604 return 0;
605 }
606
607 #define PCIE_BRCMSTB_INIT(n) \
608 static struct pcie_brcmstb_data pcie_brcmstb_data_##n = {}; \
609 \
610 static const struct pcie_ctrl_config pcie_ctrl_cfg_##n = { \
611 .cfg_addr = DT_INST_REG_ADDR(n), \
612 .cfg_size = DT_INST_REG_SIZE(n), \
613 .ranges_count = DT_NUM_RANGES(DT_DRV_INST(n)), \
614 .ranges = {DT_FOREACH_RANGE(DT_DRV_INST(n), PCIE_RANGE_FORMAT)}, \
615 }; \
616 \
617 static const struct pcie_brcmstb_config pcie_brcmstb_cfg_##n = { \
618 .common = &pcie_ctrl_cfg_##n, \
619 .regs_count = DT_NUM_REGS(DT_DRV_INST(n)), \
620 .regs = \
621 { \
622 {DT_REG_ADDR_BY_IDX(DT_DRV_INST(n), 0), \
623 DT_REG_SIZE_BY_IDX(DT_DRV_INST(n), 0)}, \
624 {DT_REG_ADDR_BY_IDX(DT_DRV_INST(n), 1), \
625 DT_REG_SIZE_BY_IDX(DT_DRV_INST(n), 1)}, \
626 {DT_REG_ADDR_BY_IDX(DT_DRV_INST(n), 2), \
627 DT_REG_SIZE_BY_IDX(DT_DRV_INST(n), 2)}, \
628 }, \
629 }; \
630 \
631 DEVICE_DT_INST_DEFINE(n, pcie_brcmstb_init, NULL, &pcie_brcmstb_data_##n, \
632 &pcie_brcmstb_cfg_##n, PRE_KERNEL_1, CONFIG_PCIE_INIT_PRIORITY, \
633 &pcie_brcmstb_api);
634
635 DT_INST_FOREACH_STATUS_OKAY(PCIE_BRCMSTB_INIT)
636