xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/spl_pcie_ep_boot.c (revision 17d5ed3ee9dbbcbae06ad3a291a8f61c3cde3d5b)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2023 Rockchip Electronics Co., Ltd
4  */
5 
6 #include <common.h>
7 #include <spl.h>
8 #include <asm/io.h>
9 #include <asm/arch/cpu.h>
10 #include <asm/arch/hardware.h>
11 #include <asm/arch/ioc_rk3588.h>
12 #include <dt-bindings/clock/rk3588-cru.h>
13 #include <pci.h>
14 #include <asm/arch/rk_atags.h>
15 
16 #ifndef CONFIG_SPL_LOAD_FIT_ADDRESS
17 #error "SPL_LOAD_FIT_ADDRESS not defined!"
18 #endif
19 
20 #define printep(fmt, ...) \
21 		do { \
22 		printf("RKEP: %d - ", readl(CONFIG_ROCKCHIP_STIMER_BASE + 0x2c)/24); \
23 		printk(fmt, ##__VA_ARGS__); \
24 		} while (0)
25 
26 #define RKEP_BAR0_ADDR		0x3c000000
27 #define RKEP_BAR2_ADDR		CONFIG_SPL_LOAD_FIT_ADDRESS
28 #define RKEP_BAR0_CMD_ADDR	(RKEP_BAR0_ADDR + 0x400)
29 #define RKEP_BOOT_MAGIC		0x524b4550 /* RKEP */
30 #define RKEP_CMD_LOADER_RUN	0x524b4501
31 
32 #define PCIE_SNPS_DBI_BASE	0xf5000000
33 #define PCIE_SNPS_APB_BASE	0xfe150000
34 #define PCIE_SNPS_IATU_BASE	0xa40300000
35 
36 #define LINK_WAIT_IATU			10000
37 #define PCIE_ATU_ENABLE			(0x1 << 31)
38 #define PCIE_ATU_BAR_MODE_ENABLE	(0x1 << 30 | 1 << 19)
39 #define PCIE_ATU_UNR_REGION_CTRL1	0x00
40 #define PCIE_ATU_UNR_REGION_CTRL2	0x04
41 #define PCIE_ATU_CPU_ADDR_LOW		0x14
42 #define PCIE_ATU_CPU_ADDR_HIGH		0x18
43 
44 /* SRNS: Use Seperate refclk(internal clock) instead of from RC */
45 // #define PCIE_ENABLE_SRNS_PLL_REFCLK
46 
47 struct rkpcie_cmd {
48 	u32 cmd;
49 	u32 size;
50 	u32 data[6];
51 };
52 
53 #define RKEP_MODE_BOOTROM 	1
54 #define RKEP_MODE_LOADER	2
55 #define RKEP_MODE_FUN0  	3
56 #define RKEP_SMODE_INIT		0
57 #define RKEP_SMODE_RDY		1
58 #define RKEP_SMODE_ERR		2
59 #define RKEP_SMODE_BUSY		3
60 
61 struct rkpcie_boot{
62 	/* magic: "RKEP" */
63 	u32 magic;
64 	u32 version;
65 	struct {
66 		u16 mode;
67 		u16 submode;
68 	} devmode;
69 	/* Size of ATAGS for cap */
70 	u32 cap_size;
71 	struct {
72 		u8 cmd;
73 		u8 status;
74 		/* Error code for current CMD */
75 		u16 opcode;
76 	} cmd_status;
77 	u32 reserved[2];
78 	/* RK ATAGS, for mem and other info */
79 	struct tag cap;
80 	/* offset 0x400 */
81 	struct rkpcie_cmd cmd;
82 };
83 
84 static void pcie_inbound_config(void)
85 {
86 	u64 base = PCIE_SNPS_IATU_BASE + 0x100;
87 	u32 val;
88 	char i;
89 
90 	/* BAR0: RKEP_BAR0_ADDR */
91 	writel(RKEP_BAR0_ADDR, base + PCIE_ATU_CPU_ADDR_LOW);
92 	writel(0, base + PCIE_ATU_CPU_ADDR_HIGH);
93 	writel(0, base + PCIE_ATU_UNR_REGION_CTRL1);
94 	/* PCIE_ATU_UNR_REGION_CTRL2 */
95 	writel(PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE | (0 << 8),
96 	       base + PCIE_ATU_UNR_REGION_CTRL2);
97 	for (i = 0; i < 5; i++) {
98 		val = readl(base + PCIE_ATU_UNR_REGION_CTRL2);
99 		if (val & PCIE_ATU_ENABLE)
100 			break;
101 		udelay(LINK_WAIT_IATU);
102 	}
103 	printep("BAR0: 0x%x\n", RKEP_BAR0_ADDR);
104 
105 	/* BAR2: RKEP_BAR2_ADDR */
106 	writel(RKEP_BAR2_ADDR, base + PCIE_ATU_CPU_ADDR_LOW + 0x200);
107 	writel(0, base + PCIE_ATU_CPU_ADDR_HIGH + 0x200);
108 	writel(0, base + PCIE_ATU_UNR_REGION_CTRL1 + 0x200);
109 	writel(PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE | (2 << 8),
110 	       base + PCIE_ATU_UNR_REGION_CTRL2 + 0x200);
111 	for (i = 0; i < 5; i++) {
112 		val = readl(base + PCIE_ATU_UNR_REGION_CTRL2 + 0x200);
113 		if (val & PCIE_ATU_ENABLE)
114 			break;
115 		udelay(LINK_WAIT_IATU);
116 	}
117 	printep("BAR2: 0x%x%x\n", 0, RKEP_BAR2_ADDR);
118 
119 	/* BAR4 is wired reg, no need iATU */
120 }
121 
122 #define PHY_MODE_PCIE_AGGREGATION 4	/* PCIe3x4 */
123 #define PHY_MODE_PCIE_NANBNB	0	/* P1:PCIe3x2  +  P0:PCIe3x2 */
124 #define PHY_MODE_PCIE_NANBBI	1	/* P1:PCIe3x2  +  P0:PCIe3x1*2 */
125 #define PHY_MODE_PCIE_NABINB	2	/* P1:PCIe3x1*2 + P0:PCIe3x2 */
126 #define PHY_MODE_PCIE_NABIBI	3	/* P1:PCIe3x1*2 + P0:PCIe3x1*2 */
127 
128 #define CRU_BASE_ADDR			0xfd7c0000
129 #define CRU_SOFTRST_CON32		(CRU_BASE_ADDR + 0x0a80)
130 #define CRU_SOFTRST_CON33		(CRU_BASE_ADDR + 0x0a84)
131 #define CRU_SOFTRST_CON34		(CRU_BASE_ADDR + 0x0a88)
132 #define CRU_GATE_CON32			(CRU_BASE_ADDR + 0x0880)
133 #define CRU_GATE_CON33			(CRU_BASE_ADDR + 0x0884)
134 #define CRU_GATE_CON34			(CRU_BASE_ADDR + 0x0888)
135 #define CRU_GATE_CON38			(CRU_BASE_ADDR + 0x0898)
136 #define CRU_GATE_CON39			(CRU_BASE_ADDR + 0x089c)
137 #define PHPTOPCRU_BASE_ADDR		0xfd7c8000
138 #define PHPTOPCRU_SOFTRST_CON00		(PHPTOPCRU_BASE_ADDR + 0x0a00)
139 #define PHPTOPCRU_GATE_CON00		(PHPTOPCRU_BASE_ADDR + 0x0800)
140 #define PCIE3PHY_GRF_BASE		0xfd5b8000
141 #define RK3588_PCIE3PHY_GRF_CMN_CON0	(PCIE3PHY_GRF_BASE + 0x0000)
142 #define PCIe3PHY_GRF_PHY0_CON6		(PCIE3PHY_GRF_BASE + 0x0118)
143 #define PCIe3PHY_GRF_PHY1_CON6		(PCIE3PHY_GRF_BASE + 0x0218)
144 #define PCIe3PHY_GRF_PHY0_LN0_CON1	(PCIE3PHY_GRF_BASE + 0x1004)
145 #define PCIe3PHY_GRF_PHY0_LN1_CON1	(PCIE3PHY_GRF_BASE + 0x1104)
146 #define PCIe3PHY_GRF_PHY1_LN0_CON1	(PCIE3PHY_GRF_BASE + 0x2004)
147 #define PCIe3PHY_GRF_PHY1_LN1_CON1	(PCIE3PHY_GRF_BASE + 0x2104)
148 #define FIREWALL_PCIE_MASTER_SEC	0xfe0300f0
149 #define FIREWALL_PCIE_ACCESS		0xfe586040
150 #define CRU_PHYREF_ALT_GATE_CON		(CRU_BASE_ADDR + 0x0c38)
151 #define PMU_PWR_GATE_SFTCON1		0xfd8d8150
152 static void pcie_cru_init(void)
153 {
154 	/* Enable power domain: PD_PCIE & PD_PHP */
155 	writel(0x1 << 23 | 0x1 << 21, PMU_PWR_GATE_SFTCON1);
156 
157 	/* FixMe init 3.0 PHY */
158 	/* Phy mode: Aggregation NBNB */
159 	writel((0x7 << 16) | PHY_MODE_PCIE_AGGREGATION, RK3588_PCIE3PHY_GRF_CMN_CON0);
160 	printep("PHY Mode 0x%x\n", readl(RK3588_PCIE3PHY_GRF_CMN_CON0) & 7);
161 	/* Enable clock and sfreset for Controller and PHY */
162 	writel(0xffff0000, CRU_SOFTRST_CON32);
163 	writel(0xffff0000, CRU_SOFTRST_CON33);
164 	writel(0xffff0000, CRU_SOFTRST_CON34);
165 	writel(0xffff0000, CRU_GATE_CON32);
166 	writel(0xffff0000, CRU_GATE_CON33);
167 	writel(0xffff0000, CRU_GATE_CON34);
168 	writel(0xffff0000, CRU_GATE_CON38);
169 	writel(0xffff0000, CRU_GATE_CON39);
170 
171 	writel((0x1 << 24), PHPTOPCRU_SOFTRST_CON00);
172 	writel(0xffff0000, PHPTOPCRU_GATE_CON00);
173 
174 	/* PHY Reset */
175 	writel((0x1 << 10) | (0x1 << 26), PHPTOPCRU_SOFTRST_CON00);
176 
177 	udelay(1);
178 
179 #ifdef PCIE_ENABLE_SRNS_PLL_REFCLK
180 	writel(0x000f0000, CRU_PHYREF_ALT_GATE_CON);
181 
182 	/* PHY0 & PHY1  use internal clock */
183 	writel(0x0 | (0x1 << 18), PCIe3PHY_GRF_PHY0_CON6);
184 	writel(0x0 | (0x1 << 18), PCIe3PHY_GRF_PHY1_CON6);
185 
186 	/* phy0_rx0_cmn_refclk_mod */
187 	writel((0x0) | (0x1 << 23), PCIe3PHY_GRF_PHY0_LN0_CON1);
188 	/* phy1_rx0_cmn_refclk_mod */
189 	writel((0x0) | (0x1 << 23), PCIe3PHY_GRF_PHY0_LN1_CON1);
190 	/* phy0_rx0_cmn_refclk_mod */
191 	writel((0x0) | (0x1 << 23), PCIe3PHY_GRF_PHY1_LN0_CON1);
192 	/* phy1_rx0_cmn_refclk_mod */
193 	writel((0x0) | (0x1 << 23), PCIe3PHY_GRF_PHY1_LN1_CON1);
194 #endif
195 
196 	udelay(1000);
197 
198 	/* Deassert PCIe PMA output clamp mode */
199 	writel((0x1 << 8) | (0x1 << 24), RK3588_PCIE3PHY_GRF_CMN_CON0);
200 
201 	/* Deassert PHY Reset */
202 	writel((0x1 << 26), PHPTOPCRU_SOFTRST_CON00);
203 
204 	/* PHY config: no config need for snps3.0phy */
205 
206 	/* Enable PCIe Access in firewall and master secure mode */
207 	writel(0xffff0000, FIREWALL_PCIE_MASTER_SEC);
208 	writel(0x01800000, FIREWALL_PCIE_ACCESS);
209 }
210 
211 #define BUS_IOC_GPIO3D_IOMUX_SEL_H 	0xfd5f807c
212 #define GPIO3_BASE			0xfec40000
213 #define GPIO3_SWPORT_DR_H		(GPIO3_BASE + 0x4)
214 #define GPIO3_SWPORT_DDR_H		(GPIO3_BASE + 0xc)
215 
216 static void pcie_board_init(void)
217 {
218 	/* Enable AU5426 buffer chip on EVB4v10 */
219 	/* Set GPIO3D4 to gpio output HIGH mode PCIE20_CLK_PWREN */
220 	writel(0xf << 16, BUS_IOC_GPIO3D_IOMUX_SEL_H);
221 	writel(0x10001000, GPIO3_SWPORT_DDR_H);
222 	writel(0x10001000, GPIO3_SWPORT_DR_H);
223 	udelay(100);
224 }
225 
226 static int rockchip_pcie_ep_set_bar_flag(void *dbi_base, u32 barno, int flags)
227 {
228 	u32 reg;
229 
230 	reg = PCI_BASE_ADDRESS_0 + (4 * barno);
231 
232 	/* Disabled the upper 32bits BAR to make a 64bits bar pair */
233 	if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
234 		writel(0, dbi_base + reg + 0x100000 + 4);
235 
236 	writel(flags, dbi_base + reg);
237 	if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
238 		writel(0, dbi_base + reg + 4);
239 
240 	return 0;
241 }
242 
243 static void pcie_bar_init(void *dbi_base)
244 {
245 	void *resbar_base;
246 
247 	writel(0, dbi_base + 0x10);
248 	writel(0, dbi_base + 0x14);
249 	writel(0, dbi_base + 0x18);
250 	writel(0, dbi_base + 0x1c);
251 	writel(0, dbi_base + 0x20);
252 	writel(0, dbi_base + 0x24);
253 
254 	/* Resize BAR0 to support 4M 32bits */
255 	resbar_base = dbi_base + 0x2e8;
256 	writel(0xfffff0, resbar_base + 0x4);
257 	writel(0x2c0, resbar_base + 0x8);
258 	/* BAR2: 64M 64bits */
259 	writel(0xfffff0, resbar_base + 0x14);
260 	writel(0x6c0, resbar_base + 0x18);
261 	/* BAR4: Fixed for EP wired register, 1M 32bits */
262 	writel(0xfffff0, resbar_base + 0x24);
263 	writel(0xc0, resbar_base + 0x28);
264 	/* Set flags */
265 	rockchip_pcie_ep_set_bar_flag(dbi_base, 0, PCI_BASE_ADDRESS_MEM_TYPE_32);
266 	rockchip_pcie_ep_set_bar_flag(dbi_base, 2, PCI_BASE_ADDRESS_MEM_PREFETCH | PCI_BASE_ADDRESS_MEM_TYPE_64);
267 	rockchip_pcie_ep_set_bar_flag(dbi_base, 4, PCI_BASE_ADDRESS_MEM_TYPE_32);
268 
269 	/* Close bar1 bar3 bar5 */
270 	writel(0x0, dbi_base + 0x100000 + 0x14);
271 	//writel(0x0, dbi_base + 0x100000 + 0x18);
272 	writel(0x0, dbi_base + 0x100000 + 0x1c);
273 	//writel(0x0, dbi_base + 0x100000 + 0x20);
274 	writel(0x0, dbi_base + 0x100000 + 0x24);
275 	/* Close ROM BAR */
276 	writel(0x0, dbi_base + 0x100000 + 0x30);
277 }
278 
279 static void pcie_bar0_header_init(void)
280 {
281 	struct rkpcie_boot *bh = (struct rkpcie_boot *)RKEP_BAR0_ADDR;
282 
283 	bh->magic = RKEP_BOOT_MAGIC;
284 	bh->version = 0x100;
285 	bh->devmode.mode = RKEP_MODE_LOADER;
286 	bh->devmode.submode = RKEP_SMODE_INIT;
287 	bh->cap_size = 0;
288 
289 	memset((char *)RKEP_BAR0_CMD_ADDR, 0, sizeof(struct rkpcie_cmd));
290 }
291 
292 #ifdef CONFIG_SPL_RAM_DEVICE
293 static void pcie_wait_for_fw(void)
294 {
295 	struct rkpcie_cmd *cmd = (struct rkpcie_cmd *)(RKEP_BAR0_CMD_ADDR);
296 	int val;
297 	int i = 0;
298 
299 	printep("Link ready! Waiting RC to download Firmware:\n");
300 	printep("Download uboot.img  to BAR2+0\n");
301 	printep("Download boot.img   to BAR2+0x400000\n");
302 	printep("Send CMD_LOADER_RUN to BAR0+0x400\n");
303 	while (1) {
304 		invalidate_dcache_range(RKEP_BAR0_CMD_ADDR,
305 					RKEP_BAR0_CMD_ADDR + 32);
306 		val = readl(&cmd->cmd);
307 		if (val == RKEP_CMD_LOADER_RUN)
308 			break;
309 		i++;
310 		if (!(i % 10))
311 			printep("Waiting for FW, CMD: %x\n", val);
312 		udelay(100000);
313 	}
314 	/* Invalidate Cache for firmware area: BAR2, 64MB */
315 	invalidate_dcache_range(RKEP_BAR2_ADDR, RKEP_BAR2_ADDR + 0x4000000);
316 	printep("Firmware Download complete!\n");
317 }
318 
319 static void pcie_update_atags(void)
320 {
321 	struct tag_ram_partition t_ram_part;
322 
323 	if (!atags_is_available()) {
324 		printf("No ATAGS data found, create new!\n");
325 		atags_destroy();
326 	}
327 
328 	/* ram partition */
329 	memset(&t_ram_part, 0, sizeof(t_ram_part));
330 	t_ram_part.version = 0;
331 	t_ram_part.count = 1;
332 	strcpy(t_ram_part.part[0].name, "boot");
333 	t_ram_part.part[0].start = RKEP_BAR2_ADDR + 0x400000;	/* 4M offset */
334 	t_ram_part.part[0].size  = 0x3c00000;	/* 60M size */
335 	atags_set_tag(ATAG_RAM_PARTITION, &t_ram_part);
336 }
337 
338 void rockchip_pcie_ep_get_firmware(void)
339 {
340 	pcie_wait_for_fw();
341 	pcie_update_atags();
342 }
343 #endif
344 
345 static void pcie_ep_init(void)
346 {
347 	u32 val;
348 	void *dbi_base = (void *)PCIE_SNPS_DBI_BASE;
349 	u64 apb_base = PCIE_SNPS_APB_BASE;
350 	int i, retries = 0;
351 
352 #ifdef PCIE_ENABLE_SRNS_PLL_REFCLK
353 	printep("RefClock in SRNS clock mode\n");
354 #else
355 	printep("RefClock in common clock_mode\n");
356 #endif
357 
358 	/*
359 	 * ltssm_enbale enhance mode and enable delaying the link training
360 	 * after Hot Reset
361 	 */
362 	writel(0x120012, apb_base + 0x180);
363 
364 	/* PortLorgic DBI_RO_WR_EN */
365 	val = readl((dbi_base + 0x8bc));
366 	val |= 0x1;
367 	writel(val, dbi_base + 0x8bc);
368 
369 reinit:
370 	pcie_bar_init(dbi_base);
371 	pcie_inbound_config();
372 
373 	/* Device PID, DID */
374 	writel(0x1d87, dbi_base + 0x00);
375 	writel(0x356a, dbi_base + 0x02);
376 	/* Device Class: Processing accelerators */
377 	writel(0x1200, dbi_base + 0x0a);
378 
379 	/* EP mode */
380 	writel(0xf00000, apb_base);
381 	udelay(100);
382 
383 	/* Enable EP mem/io access */
384 	val = readl(dbi_base + 0x4);
385 	writel(val | 0x6, dbi_base + 0x4);
386 
387 	if (retries)	/* Set app_dly2_done to enable app_ltssm_enable */
388 		writel(0x80008, apb_base + 0x180);
389 	else		/* Enable LTSSM */
390 		writel(0xc000c, apb_base);
391 	printep("init PCIe fast Link up\n");
392 
393 	/* Waiting for Link up */
394 	while (1) {
395 		val = readl(apb_base + 0x300);
396 		if (((val & 0x3ffff) & ((0x3 << 16) | 0x11)) == 0x30011)
397 			break;
398 		udelay(1000);
399 	}
400 	printep("Link up %x\n", val);
401 	udelay(3000);
402 
403 	/* Wait for link stable */
404 	for (i = 0; i < 10000; i++) {
405 		val = readl(apb_base + 0x10);
406 		if (val & 0x4) {
407 			writel(0x4, apb_base + 0x10);
408 			printep("Link is reset, int status misc=%x\n", val);
409 			if (retries < 3) {
410 				retries++;
411 				goto reinit;
412 			} else {
413 				break;
414 			}
415 		}
416 		udelay(1);
417 	}
418 	printep("Done\n");
419 
420 	return;
421 }
422 
423 void rockchip_pcie_ep_init(void)
424 {
425 	printf("\nRKEP: Init PCIe EP\n");
426 	pcie_bar0_header_init();
427 
428 	/*
429 	 * TODO: Move board_init/cru_init to soc level if more SoCs available
430 	 */
431 	pcie_board_init();
432 	/* CRU and PHY Init */
433 	pcie_cru_init();
434 
435 	pcie_ep_init();
436 }
437