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