xref: /OK3568_Linux_fs/u-boot/arch/arm/mach-rockchip/spl_pcie_ep_boot.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2023 Rockchip Electronics Co., Ltd
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <common.h>
7*4882a593Smuzhiyun #include <spl.h>
8*4882a593Smuzhiyun #include <asm/io.h>
9*4882a593Smuzhiyun #include <asm/arch/cpu.h>
10*4882a593Smuzhiyun #include <asm/arch/hardware.h>
11*4882a593Smuzhiyun #include <asm/arch/ioc_rk3588.h>
12*4882a593Smuzhiyun #include <dt-bindings/clock/rk3588-cru.h>
13*4882a593Smuzhiyun #include <pci.h>
14*4882a593Smuzhiyun #include <asm/arch/rk_atags.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #ifndef CONFIG_SPL_LOAD_FIT_ADDRESS
17*4882a593Smuzhiyun #error "SPL_LOAD_FIT_ADDRESS not defined!"
18*4882a593Smuzhiyun #endif
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #define printep(fmt, ...) \
21*4882a593Smuzhiyun 		do { \
22*4882a593Smuzhiyun 			printf("RKEP: %d - ", readl(CONFIG_ROCKCHIP_STIMER_BASE + 0x2c) / 24); \
23*4882a593Smuzhiyun 			printf(fmt, ##__VA_ARGS__); \
24*4882a593Smuzhiyun 		} while (0)
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #ifdef CONFIG_ROCKCHIP_RK3588
27*4882a593Smuzhiyun #define PCIE_SNPS_DBI_BASE	0xf5000000
28*4882a593Smuzhiyun #define PCIE_SNPS_APB_BASE	0xfe150000
29*4882a593Smuzhiyun #define PCIE_SNPS_IATU_BASE	0xa40300000
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #define PCI_RESBAR		0x2e8
32*4882a593Smuzhiyun #elif CONFIG_ROCKCHIP_RK3568
33*4882a593Smuzhiyun #define PCIE_SNPS_DBI_BASE	0xf6000000
34*4882a593Smuzhiyun #define PCIE_SNPS_APB_BASE	0xfe280000
35*4882a593Smuzhiyun #define PCIE_SNPS_IATU_BASE	0x3c0b00000
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun #define PCI_RESBAR		0x2b8
38*4882a593Smuzhiyun #else
39*4882a593Smuzhiyun #error "this soc is not support pcie ep!"
40*4882a593Smuzhiyun #endif
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun #define RKEP_BAR0_ADDR		0x3c000000
43*4882a593Smuzhiyun #define RKEP_BAR2_ADDR		CONFIG_SPL_LOAD_FIT_ADDRESS
44*4882a593Smuzhiyun #define RKEP_BAR0_CMD_ADDR	(RKEP_BAR0_ADDR + 0x400)
45*4882a593Smuzhiyun #define RKEP_BOOT_MAGIC		0x524b4550 /* RKEP */
46*4882a593Smuzhiyun #define RKEP_CMD_LOADER_RUN	0x524b4501
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun #define PCI_EXP_LNKCAP		12	/* Link Capabilities */
49*4882a593Smuzhiyun #define PCI_EXP_LNKCTL2		48	/* Link Control 2 */
50*4882a593Smuzhiyun #define PCI_EXP_LNKCTL2_TLS		0x000f
51*4882a593Smuzhiyun #define PCI_EXP_LNKCAP_SLS		0x0000000f
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #define PCI_EXP_LNKCTL2_TLS_2_5GT	0x0001 /* Supported Speed 2.5GT/s */
54*4882a593Smuzhiyun #define PCI_EXP_LNKCTL2_TLS_5_0GT	0x0002 /* Supported Speed 5GT/s */
55*4882a593Smuzhiyun #define PCI_EXP_LNKCTL2_TLS_8_0GT	0x0003 /* Supported Speed 8GT/s */
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /* Synopsys-specific PCIe configuration registers */
58*4882a593Smuzhiyun #define PCIE_PORT_LINK_CONTROL		0x710
59*4882a593Smuzhiyun #define PORT_LINK_MODE_MASK		(0x3f << 16)
60*4882a593Smuzhiyun #define PORT_LINK_MODE_1_LANES		(0x1 << 16)
61*4882a593Smuzhiyun #define PORT_LINK_MODE_2_LANES		(0x3 << 16)
62*4882a593Smuzhiyun #define PORT_LINK_MODE_4_LANES		(0x7 << 16)
63*4882a593Smuzhiyun #define PORT_LINK_MODE_8_LANES		(0xf << 16)
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun #define PCIE_LINK_WIDTH_SPEED_CONTROL	0x80C
66*4882a593Smuzhiyun #define PORT_LOGIC_SPEED_CHANGE		(0x1 << 17)
67*4882a593Smuzhiyun #define PORT_LOGIC_LINK_WIDTH_MASK	(0x1f << 8)
68*4882a593Smuzhiyun #define PORT_LOGIC_LINK_WIDTH_1_LANES	(0x1 << 8)
69*4882a593Smuzhiyun #define PORT_LOGIC_LINK_WIDTH_2_LANES	(0x2 << 8)
70*4882a593Smuzhiyun #define PORT_LOGIC_LINK_WIDTH_4_LANES	(0x4 << 8)
71*4882a593Smuzhiyun #define PORT_LOGIC_LINK_WIDTH_8_LANES	(0x8 << 8)
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun #define PCIE_DIRECT_SPEED_CHANGE	(0x1 << 17)
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun #define LINK_WAIT_IATU			10000
76*4882a593Smuzhiyun #define PCIE_ATU_ENABLE			(0x1 << 31)
77*4882a593Smuzhiyun #define PCIE_ATU_BAR_MODE_ENABLE	(0x1 << 30 | 1 << 19)
78*4882a593Smuzhiyun #define PCIE_ATU_UNR_REGION_CTRL1	0x00
79*4882a593Smuzhiyun #define PCIE_ATU_UNR_REGION_CTRL2	0x04
80*4882a593Smuzhiyun #define PCIE_ATU_CPU_ADDR_LOW		0x14
81*4882a593Smuzhiyun #define PCIE_ATU_CPU_ADDR_HIGH		0x18
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun /* SRNS: Use Separate refclk(internal clock) instead of from RC */
84*4882a593Smuzhiyun // #define PCIE_ENABLE_SRNS_PLL_REFCLK
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun struct rkpcie_cmd {
87*4882a593Smuzhiyun 	u32 cmd;
88*4882a593Smuzhiyun 	u32 size;
89*4882a593Smuzhiyun 	u32 data[6];
90*4882a593Smuzhiyun };
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun /* rkep device mode status definition */
93*4882a593Smuzhiyun #define RKEP_MODE_BOOTROM	1
94*4882a593Smuzhiyun #define RKEP_MODE_LOADER	2
95*4882a593Smuzhiyun #define RKEP_MODE_KERNEL	3
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /* Common status */
98*4882a593Smuzhiyun #define RKEP_SMODE_INIT		0
99*4882a593Smuzhiyun #define RKEP_SMODE_LNKRDY	1
100*4882a593Smuzhiyun #define RKEP_SMODE_LNKUP	2
101*4882a593Smuzhiyun #define RKEP_SMODE_ERR		0xff
102*4882a593Smuzhiyun /* Firmware download status */
103*4882a593Smuzhiyun #define RKEP_SMODE_FWDLRDY	0x10
104*4882a593Smuzhiyun #define RKEP_SMODE_FWDLDONE	0x11
105*4882a593Smuzhiyun /* Application status*/
106*4882a593Smuzhiyun #define RKEP_SMODE_APPRDY	0x20
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun struct rkpcie_boot {
109*4882a593Smuzhiyun 	/* magic: "RKEP" */
110*4882a593Smuzhiyun 	u32 magic;
111*4882a593Smuzhiyun 	u32 version;
112*4882a593Smuzhiyun 	struct {
113*4882a593Smuzhiyun 		u16 mode;
114*4882a593Smuzhiyun 		u16 submode;
115*4882a593Smuzhiyun 	} devmode;
116*4882a593Smuzhiyun 	/* Size of ATAGS for cap */
117*4882a593Smuzhiyun 	u32 cap_size;
118*4882a593Smuzhiyun 	struct {
119*4882a593Smuzhiyun 		u8 cmd;
120*4882a593Smuzhiyun 		u8 status;
121*4882a593Smuzhiyun 		/* Error code for current CMD */
122*4882a593Smuzhiyun 		u16 opcode;
123*4882a593Smuzhiyun 	} cmd_status;
124*4882a593Smuzhiyun 	u32 reserved[2];
125*4882a593Smuzhiyun 	/* RK ATAGS, for mem and other info */
126*4882a593Smuzhiyun 	struct tag cap;
127*4882a593Smuzhiyun 	/* offset 0x400 */
128*4882a593Smuzhiyun 	struct rkpcie_cmd cmd;
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun 
pcie_inbound_config(void)131*4882a593Smuzhiyun static void pcie_inbound_config(void)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun 	u64 base = PCIE_SNPS_IATU_BASE + 0x100;
134*4882a593Smuzhiyun 	u32 val;
135*4882a593Smuzhiyun 	char i;
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	/* BAR0: RKEP_BAR0_ADDR */
138*4882a593Smuzhiyun 	writel(RKEP_BAR0_ADDR, base + PCIE_ATU_CPU_ADDR_LOW);
139*4882a593Smuzhiyun 	writel(0, base + PCIE_ATU_CPU_ADDR_HIGH);
140*4882a593Smuzhiyun 	writel(0, base + PCIE_ATU_UNR_REGION_CTRL1);
141*4882a593Smuzhiyun 	/* PCIE_ATU_UNR_REGION_CTRL2 */
142*4882a593Smuzhiyun 	writel(PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE | (0 << 8),
143*4882a593Smuzhiyun 	       base + PCIE_ATU_UNR_REGION_CTRL2);
144*4882a593Smuzhiyun 	for (i = 0; i < 5; i++) {
145*4882a593Smuzhiyun 		val = readl(base + PCIE_ATU_UNR_REGION_CTRL2);
146*4882a593Smuzhiyun 		if (val & PCIE_ATU_ENABLE)
147*4882a593Smuzhiyun 			break;
148*4882a593Smuzhiyun 		udelay(LINK_WAIT_IATU);
149*4882a593Smuzhiyun 	}
150*4882a593Smuzhiyun 	printep("BAR0: 0x%x\n", RKEP_BAR0_ADDR);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	/* BAR2: RKEP_BAR2_ADDR */
153*4882a593Smuzhiyun 	writel(RKEP_BAR2_ADDR, base + PCIE_ATU_CPU_ADDR_LOW + 0x200);
154*4882a593Smuzhiyun 	writel(0, base + PCIE_ATU_CPU_ADDR_HIGH + 0x200);
155*4882a593Smuzhiyun 	writel(0, base + PCIE_ATU_UNR_REGION_CTRL1 + 0x200);
156*4882a593Smuzhiyun 	writel(PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE | (2 << 8),
157*4882a593Smuzhiyun 	       base + PCIE_ATU_UNR_REGION_CTRL2 + 0x200);
158*4882a593Smuzhiyun 	for (i = 0; i < 5; i++) {
159*4882a593Smuzhiyun 		val = readl(base + PCIE_ATU_UNR_REGION_CTRL2 + 0x200);
160*4882a593Smuzhiyun 		if (val & PCIE_ATU_ENABLE)
161*4882a593Smuzhiyun 			break;
162*4882a593Smuzhiyun 		udelay(LINK_WAIT_IATU);
163*4882a593Smuzhiyun 	}
164*4882a593Smuzhiyun 	printep("BAR2: 0x%x%x\n", 0, RKEP_BAR2_ADDR);
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	/* BAR4 is wired reg, no need iATU */
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun 
rockchip_pcie_ep_set_bar_flag(void * dbi_base,u32 barno,int flags)169*4882a593Smuzhiyun static int rockchip_pcie_ep_set_bar_flag(void *dbi_base, u32 barno, int flags)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun 	u32 reg;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	reg = PCI_BASE_ADDRESS_0 + (4 * barno);
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	/* Disabled the upper 32bits BAR to make a 64bits bar pair */
176*4882a593Smuzhiyun 	if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
177*4882a593Smuzhiyun 		writel(0, dbi_base + reg + 0x100000 + 4);
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	writel(flags, dbi_base + reg);
180*4882a593Smuzhiyun 	if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
181*4882a593Smuzhiyun 		writel(0, dbi_base + reg + 4);
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	return 0;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun 
pcie_bar_init(void * dbi_base)186*4882a593Smuzhiyun static void pcie_bar_init(void *dbi_base)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun 	void *resbar_base;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	writel(0, dbi_base + 0x10);
191*4882a593Smuzhiyun 	writel(0, dbi_base + 0x14);
192*4882a593Smuzhiyun 	writel(0, dbi_base + 0x18);
193*4882a593Smuzhiyun 	writel(0, dbi_base + 0x1c);
194*4882a593Smuzhiyun 	writel(0, dbi_base + 0x20);
195*4882a593Smuzhiyun 	writel(0, dbi_base + 0x24);
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	/* Resize BAR0 to support 4M 32bits */
198*4882a593Smuzhiyun 	resbar_base = dbi_base + PCI_RESBAR;
199*4882a593Smuzhiyun 	writel(0xfffff0, resbar_base + 0x4);
200*4882a593Smuzhiyun 	writel(0x2c0, resbar_base + 0x8);
201*4882a593Smuzhiyun 	/* BAR2: 64M 64bits */
202*4882a593Smuzhiyun 	writel(0xfffff0, resbar_base + 0x14);
203*4882a593Smuzhiyun 	writel(0x6c0, resbar_base + 0x18);
204*4882a593Smuzhiyun 	/* BAR4: Fixed for EP wired register, 1M 32bits */
205*4882a593Smuzhiyun 	writel(0xfffff0, resbar_base + 0x24);
206*4882a593Smuzhiyun 	writel(0xc0, resbar_base + 0x28);
207*4882a593Smuzhiyun 	/* Set flags */
208*4882a593Smuzhiyun 	rockchip_pcie_ep_set_bar_flag(dbi_base, 0, PCI_BASE_ADDRESS_MEM_TYPE_32);
209*4882a593Smuzhiyun 	rockchip_pcie_ep_set_bar_flag(dbi_base, 2,
210*4882a593Smuzhiyun 				      PCI_BASE_ADDRESS_MEM_PREFETCH | PCI_BASE_ADDRESS_MEM_TYPE_64);
211*4882a593Smuzhiyun 	rockchip_pcie_ep_set_bar_flag(dbi_base, 4, PCI_BASE_ADDRESS_MEM_TYPE_32);
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	/* Close bar1 bar3 bar5 */
214*4882a593Smuzhiyun 	writel(0x0, dbi_base + 0x100000 + 0x14);
215*4882a593Smuzhiyun 	//writel(0x0, dbi_base + 0x100000 + 0x18);
216*4882a593Smuzhiyun 	writel(0x0, dbi_base + 0x100000 + 0x1c);
217*4882a593Smuzhiyun 	//writel(0x0, dbi_base + 0x100000 + 0x20);
218*4882a593Smuzhiyun 	writel(0x0, dbi_base + 0x100000 + 0x24);
219*4882a593Smuzhiyun 	/* Close ROM BAR */
220*4882a593Smuzhiyun 	writel(0x0, dbi_base + 0x100000 + 0x30);
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun 
pcie_bar0_header_init(void)223*4882a593Smuzhiyun static void pcie_bar0_header_init(void)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun 	struct rkpcie_boot *bh = (struct rkpcie_boot *)RKEP_BAR0_ADDR;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	bh->magic = RKEP_BOOT_MAGIC;
228*4882a593Smuzhiyun 	bh->version = 0x100;
229*4882a593Smuzhiyun 	bh->devmode.mode = RKEP_MODE_LOADER;
230*4882a593Smuzhiyun 	bh->devmode.submode = RKEP_SMODE_INIT;
231*4882a593Smuzhiyun 	bh->cap_size = 0;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	memset((char *)RKEP_BAR0_CMD_ADDR, 0, sizeof(struct rkpcie_cmd));
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun 
pcie_link_set_max_speed(void * dbi_base,u32 link_gen)236*4882a593Smuzhiyun static void pcie_link_set_max_speed(void *dbi_base, u32 link_gen)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun 	u32 cap, ctrl2, link_speed;
239*4882a593Smuzhiyun 	u8 offset = 0x70;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	cap = readl(dbi_base + offset + PCI_EXP_LNKCAP);
242*4882a593Smuzhiyun 	ctrl2 = readl(dbi_base + offset + PCI_EXP_LNKCTL2);
243*4882a593Smuzhiyun 	ctrl2 &= ~PCI_EXP_LNKCTL2_TLS;
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	link_speed = link_gen;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	cap &= ~((u32)PCI_EXP_LNKCAP_SLS);
248*4882a593Smuzhiyun 	writel(ctrl2 | link_speed, dbi_base + offset + PCI_EXP_LNKCTL2);
249*4882a593Smuzhiyun 	writel(cap | link_speed, dbi_base + offset + PCI_EXP_LNKCAP);
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun 
pcie_link_set_lanes(void * dbi_base,u32 lanes)252*4882a593Smuzhiyun static void pcie_link_set_lanes(void *dbi_base, u32 lanes)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun 	u32 val;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	/* Set the number of lanes */
257*4882a593Smuzhiyun 	val = readl(dbi_base + PCIE_PORT_LINK_CONTROL);
258*4882a593Smuzhiyun 	val &= ~PORT_LINK_MODE_MASK;
259*4882a593Smuzhiyun 	switch (lanes) {
260*4882a593Smuzhiyun 	case 1:
261*4882a593Smuzhiyun 		val |= PORT_LINK_MODE_1_LANES;
262*4882a593Smuzhiyun 		break;
263*4882a593Smuzhiyun 	case 2:
264*4882a593Smuzhiyun 		val |= PORT_LINK_MODE_2_LANES;
265*4882a593Smuzhiyun 		break;
266*4882a593Smuzhiyun 	case 4:
267*4882a593Smuzhiyun 		val |= PORT_LINK_MODE_4_LANES;
268*4882a593Smuzhiyun 		break;
269*4882a593Smuzhiyun 	default:
270*4882a593Smuzhiyun 		printf("RKEP: num-lanes %u: invalid value\n", lanes);
271*4882a593Smuzhiyun 		return;
272*4882a593Smuzhiyun 	}
273*4882a593Smuzhiyun 	writel(val, dbi_base + PCIE_PORT_LINK_CONTROL);
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	/* Set link width speed control register */
276*4882a593Smuzhiyun 	val = readl(dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
277*4882a593Smuzhiyun 	val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
278*4882a593Smuzhiyun 	switch (lanes) {
279*4882a593Smuzhiyun 	case 1:
280*4882a593Smuzhiyun 		val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
281*4882a593Smuzhiyun 		break;
282*4882a593Smuzhiyun 	case 2:
283*4882a593Smuzhiyun 		val |= PORT_LOGIC_LINK_WIDTH_2_LANES;
284*4882a593Smuzhiyun 		break;
285*4882a593Smuzhiyun 	case 4:
286*4882a593Smuzhiyun 		val |= PORT_LOGIC_LINK_WIDTH_4_LANES;
287*4882a593Smuzhiyun 		break;
288*4882a593Smuzhiyun 	}
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	val |= PCIE_DIRECT_SPEED_CHANGE;
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	writel(val, dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun 
pcie_devmode_update(int mode,int submode)295*4882a593Smuzhiyun static void pcie_devmode_update(int mode, int submode)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	struct rkpcie_boot *bh = (struct rkpcie_boot *)RKEP_BAR0_ADDR;
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	bh->devmode.mode = mode;
300*4882a593Smuzhiyun 	bh->devmode.submode = submode;
301*4882a593Smuzhiyun 	flush_dcache_range(RKEP_BAR0_ADDR, RKEP_BAR0_ADDR + 64);
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun #ifdef CONFIG_SPL_RAM_DEVICE
pcie_wait_for_fw(void)305*4882a593Smuzhiyun static void pcie_wait_for_fw(void)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun 	struct rkpcie_cmd *cmd = (struct rkpcie_cmd *)(RKEP_BAR0_CMD_ADDR);
308*4882a593Smuzhiyun 	int val;
309*4882a593Smuzhiyun 	int i = 0;
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	printep("Link ready! Waiting RC to download Firmware:\n");
312*4882a593Smuzhiyun 	printep("Download uboot.img  to BAR2+0\n");
313*4882a593Smuzhiyun 	printep("Download boot.img   to BAR2+0x400000\n");
314*4882a593Smuzhiyun 	printep("Send CMD_LOADER_RUN to BAR0+0x400\n");
315*4882a593Smuzhiyun 	while (1) {
316*4882a593Smuzhiyun 		invalidate_dcache_range(RKEP_BAR0_CMD_ADDR,
317*4882a593Smuzhiyun 					RKEP_BAR0_CMD_ADDR + 32);
318*4882a593Smuzhiyun 		val = readl(&cmd->cmd);
319*4882a593Smuzhiyun 		if (val == RKEP_CMD_LOADER_RUN)
320*4882a593Smuzhiyun 			break;
321*4882a593Smuzhiyun 		i++;
322*4882a593Smuzhiyun 		if (!(i % 10))
323*4882a593Smuzhiyun 			printep("Waiting for FW, CMD: %x\n", val);
324*4882a593Smuzhiyun 		mdelay(100);
325*4882a593Smuzhiyun 	}
326*4882a593Smuzhiyun 	/* Invalidate Cache for firmware area: BAR2, 64MB */
327*4882a593Smuzhiyun 	invalidate_dcache_range(RKEP_BAR2_ADDR, RKEP_BAR2_ADDR + 0x4000000);
328*4882a593Smuzhiyun 	printep("Firmware Download complete!\n");
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun 
pcie_update_atags(void)331*4882a593Smuzhiyun static void pcie_update_atags(void)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun 	struct tag_ram_partition t_ram_part;
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	if (!atags_is_available()) {
336*4882a593Smuzhiyun 		printf("RKEP: No ATAGS data found, create new!\n");
337*4882a593Smuzhiyun 		atags_destroy();
338*4882a593Smuzhiyun 	}
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	/* ram partition */
341*4882a593Smuzhiyun 	memset(&t_ram_part, 0, sizeof(t_ram_part));
342*4882a593Smuzhiyun 	t_ram_part.version = 0;
343*4882a593Smuzhiyun 	t_ram_part.count = 1;
344*4882a593Smuzhiyun 	strcpy(t_ram_part.part[0].name, "boot");
345*4882a593Smuzhiyun 	t_ram_part.part[0].start = RKEP_BAR2_ADDR + 0x400000;	/* 4M offset */
346*4882a593Smuzhiyun 	t_ram_part.part[0].size  = 0x3c00000;	/* 60M size */
347*4882a593Smuzhiyun 	atags_set_tag(ATAG_RAM_PARTITION, &t_ram_part);
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun 
rockchip_pcie_ep_get_firmware(void)350*4882a593Smuzhiyun void rockchip_pcie_ep_get_firmware(void)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun 	pcie_devmode_update(RKEP_MODE_LOADER, RKEP_SMODE_FWDLRDY);
353*4882a593Smuzhiyun 	pcie_wait_for_fw();
354*4882a593Smuzhiyun 	pcie_update_atags();
355*4882a593Smuzhiyun 	pcie_devmode_update(RKEP_MODE_LOADER, RKEP_SMODE_FWDLDONE);
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun #endif
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun #ifdef CONFIG_ROCKCHIP_RK3588
360*4882a593Smuzhiyun #define BUS_IOC_GPIO3D_IOMUX_SEL_H	0xfd5f807c
361*4882a593Smuzhiyun #define GPIO3_BASE			0xfec40000
362*4882a593Smuzhiyun #define GPIO3_SWPORT_DR_H		(GPIO3_BASE + 0x4)
363*4882a593Smuzhiyun #define GPIO3_SWPORT_DDR_H		(GPIO3_BASE + 0xc)
364*4882a593Smuzhiyun 
pcie_board_init(void)365*4882a593Smuzhiyun static void pcie_board_init(void)
366*4882a593Smuzhiyun {
367*4882a593Smuzhiyun 	/* Enable AU5426 buffer chip on EVB4v10 */
368*4882a593Smuzhiyun 	/* Set GPIO3D4 to gpio output HIGH mode PCIE20_CLK_PWREN */
369*4882a593Smuzhiyun 	writel(0xf << 16, BUS_IOC_GPIO3D_IOMUX_SEL_H);
370*4882a593Smuzhiyun 	writel(0x10001000, GPIO3_SWPORT_DDR_H);
371*4882a593Smuzhiyun 	writel(0x10001000, GPIO3_SWPORT_DR_H);
372*4882a593Smuzhiyun 	udelay(100);
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun #define PHY_MODE_PCIE_AGGREGATION 4	/* PCIe3x4 */
376*4882a593Smuzhiyun #define PHY_MODE_PCIE_NANBNB	0	/* P1:PCIe3x2  +  P0:PCIe3x2 */
377*4882a593Smuzhiyun #define PHY_MODE_PCIE_NANBBI	1	/* P1:PCIe3x2  +  P0:PCIe3x1*2 */
378*4882a593Smuzhiyun #define PHY_MODE_PCIE_NABINB	2	/* P1:PCIe3x1*2 + P0:PCIe3x2 */
379*4882a593Smuzhiyun #define PHY_MODE_PCIE_NABIBI	3	/* P1:PCIe3x1*2 + P0:PCIe3x1*2 */
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun #define CRU_BASE_ADDR			0xfd7c0000
382*4882a593Smuzhiyun #define CRU_SOFTRST_CON32		(CRU_BASE_ADDR + 0x0a80)
383*4882a593Smuzhiyun #define CRU_SOFTRST_CON33		(CRU_BASE_ADDR + 0x0a84)
384*4882a593Smuzhiyun #define CRU_SOFTRST_CON34		(CRU_BASE_ADDR + 0x0a88)
385*4882a593Smuzhiyun #define CRU_GATE_CON32			(CRU_BASE_ADDR + 0x0880)
386*4882a593Smuzhiyun #define CRU_GATE_CON33			(CRU_BASE_ADDR + 0x0884)
387*4882a593Smuzhiyun #define CRU_GATE_CON34			(CRU_BASE_ADDR + 0x0888)
388*4882a593Smuzhiyun #define CRU_GATE_CON38			(CRU_BASE_ADDR + 0x0898)
389*4882a593Smuzhiyun #define CRU_GATE_CON39			(CRU_BASE_ADDR + 0x089c)
390*4882a593Smuzhiyun #define PHPTOPCRU_BASE_ADDR		0xfd7c8000
391*4882a593Smuzhiyun #define PHPTOPCRU_SOFTRST_CON00		(PHPTOPCRU_BASE_ADDR + 0x0a00)
392*4882a593Smuzhiyun #define PHPTOPCRU_GATE_CON00		(PHPTOPCRU_BASE_ADDR + 0x0800)
393*4882a593Smuzhiyun #define PCIE3PHY_GRF_BASE		0xfd5b8000
394*4882a593Smuzhiyun #define RK3588_PCIE3PHY_GRF_CMN_CON0	(PCIE3PHY_GRF_BASE + 0x0000)
395*4882a593Smuzhiyun #define PCIE3PHY_GRF_PHY0_CON6		(PCIE3PHY_GRF_BASE + 0x0118)
396*4882a593Smuzhiyun #define PCIE3PHY_GRF_PHY1_CON6		(PCIE3PHY_GRF_BASE + 0x0218)
397*4882a593Smuzhiyun #define PCIE3PHY_GRF_PHY0_LN0_CON1	(PCIE3PHY_GRF_BASE + 0x1004)
398*4882a593Smuzhiyun #define PCIE3PHY_GRF_PHY0_LN1_CON1	(PCIE3PHY_GRF_BASE + 0x1104)
399*4882a593Smuzhiyun #define PCIE3PHY_GRF_PHY1_LN0_CON1	(PCIE3PHY_GRF_BASE + 0x2004)
400*4882a593Smuzhiyun #define PCIE3PHY_GRF_PHY1_LN1_CON1	(PCIE3PHY_GRF_BASE + 0x2104)
401*4882a593Smuzhiyun #define FIREWALL_PCIE_MASTER_SEC	0xfe0300f0
402*4882a593Smuzhiyun #define FIREWALL_PCIE_ACCESS		0xfe586040
403*4882a593Smuzhiyun #define CRU_PHYREF_ALT_GATE_CON		(CRU_BASE_ADDR + 0x0c38)
404*4882a593Smuzhiyun #define PMU_PWR_GATE_SFTCON1		0xfd8d8150
pcie_cru_init(void)405*4882a593Smuzhiyun static void pcie_cru_init(void)
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun 	u32 phy0_mplla, phy1_mplla, t0 = 0, t1 = 0;
408*4882a593Smuzhiyun 	u32 i, timeout = 500;
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	/* Enable power domain: PD_PCIE & PD_PHP */
411*4882a593Smuzhiyun 	writel(0x1 << 23 | 0x1 << 21, PMU_PWR_GATE_SFTCON1);
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	/* FixMe init 3.0 PHY */
414*4882a593Smuzhiyun 	/* Phy mode: Aggregation NBNB */
415*4882a593Smuzhiyun 	writel((0x7 << 16) | PHY_MODE_PCIE_AGGREGATION, RK3588_PCIE3PHY_GRF_CMN_CON0);
416*4882a593Smuzhiyun 	printep("PHY Mode 0x%x\n", readl(RK3588_PCIE3PHY_GRF_CMN_CON0) & 7);
417*4882a593Smuzhiyun 	/* Enable clock and sfreset for Controller and PHY */
418*4882a593Smuzhiyun 	writel(0xffff0000, CRU_SOFTRST_CON32);
419*4882a593Smuzhiyun 	writel(0xffff0000, CRU_SOFTRST_CON33);
420*4882a593Smuzhiyun 	writel(0xffff0000, CRU_SOFTRST_CON34);
421*4882a593Smuzhiyun 	writel(0xffff0000, CRU_GATE_CON32);
422*4882a593Smuzhiyun 	writel(0xffff0000, CRU_GATE_CON33);
423*4882a593Smuzhiyun 	writel(0xffff0000, CRU_GATE_CON34);
424*4882a593Smuzhiyun 	writel(0xffff0000, CRU_GATE_CON38);
425*4882a593Smuzhiyun 	writel(0xffff0000, CRU_GATE_CON39);
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 	writel((0x1 << 24), PHPTOPCRU_SOFTRST_CON00);
428*4882a593Smuzhiyun 	writel(0xffff0000, PHPTOPCRU_GATE_CON00);
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 	/* PHY Reset */
431*4882a593Smuzhiyun 	writel((0x1 << 10) | (0x1 << 26), PHPTOPCRU_SOFTRST_CON00);
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	udelay(1);
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun #ifdef PCIE_ENABLE_SRNS_PLL_REFCLK
436*4882a593Smuzhiyun 	writel(0x000f0000, CRU_PHYREF_ALT_GATE_CON);
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	/* PHY0 & PHY1  use internal clock */
439*4882a593Smuzhiyun 	writel(0x0 | (0x1 << 18), PCIE3PHY_GRF_PHY0_CON6);
440*4882a593Smuzhiyun 	writel(0x0 | (0x1 << 18), PCIE3PHY_GRF_PHY1_CON6);
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 	/* phy0_rx0_cmn_refclk_mod */
443*4882a593Smuzhiyun 	writel((0x0) | (0x1 << 23), PCIE3PHY_GRF_PHY0_LN0_CON1);
444*4882a593Smuzhiyun 	/* phy1_rx0_cmn_refclk_mod */
445*4882a593Smuzhiyun 	writel((0x0) | (0x1 << 23), PCIE3PHY_GRF_PHY0_LN1_CON1);
446*4882a593Smuzhiyun 	/* phy0_rx0_cmn_refclk_mod */
447*4882a593Smuzhiyun 	writel((0x0) | (0x1 << 23), PCIE3PHY_GRF_PHY1_LN0_CON1);
448*4882a593Smuzhiyun 	/* phy1_rx0_cmn_refclk_mod */
449*4882a593Smuzhiyun 	writel((0x0) | (0x1 << 23), PCIE3PHY_GRF_PHY1_LN1_CON1);
450*4882a593Smuzhiyun #endif
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun 	udelay(1000);
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	/* Deassert PCIe PMA output clamp mode */
455*4882a593Smuzhiyun 	writel((0x1 << 8) | (0x1 << 24), RK3588_PCIE3PHY_GRF_CMN_CON0);
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	/* Deassert PHY Reset */
458*4882a593Smuzhiyun 	writel((0x1 << 26), PHPTOPCRU_SOFTRST_CON00);
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	/* S-Phy: waiting for phy locked */
461*4882a593Smuzhiyun 	for (i = 0; i < timeout; i++) {
462*4882a593Smuzhiyun 		phy0_mplla = readl(PCIE3PHY_GRF_BASE + 0x904);
463*4882a593Smuzhiyun 		phy1_mplla = readl(PCIE3PHY_GRF_BASE + 0xA04);
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 		if (phy0_mplla != t0 || phy1_mplla != t1) {
466*4882a593Smuzhiyun 			printf("RKEP: GRF:904=%x, a04=%x...\n", phy0_mplla, phy1_mplla);
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 			t0 = phy0_mplla;
469*4882a593Smuzhiyun 			t1 = phy1_mplla;
470*4882a593Smuzhiyun 			if (phy0_mplla == 0xF && phy1_mplla == 0xF)
471*4882a593Smuzhiyun 				break;
472*4882a593Smuzhiyun 		}
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 		udelay(10);
475*4882a593Smuzhiyun 	}
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	/* PHY config: no config need for snps3.0phy */
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun 	/* Enable PCIe Access in firewall and master secure mode */
480*4882a593Smuzhiyun 	writel(0xffff0000, FIREWALL_PCIE_MASTER_SEC);
481*4882a593Smuzhiyun 	writel(0x01800000, FIREWALL_PCIE_ACCESS);
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun #elif CONFIG_ROCKCHIP_RK3568
484*4882a593Smuzhiyun 
pcie_board_init(void)485*4882a593Smuzhiyun static void pcie_board_init(void)
486*4882a593Smuzhiyun {
487*4882a593Smuzhiyun 	/* to-do */
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun static const u16 phy_fw[] = {
491*4882a593Smuzhiyun 	#include "./../../../drivers/phy/phy-rockchip-snps-pcie3.fw"
492*4882a593Smuzhiyun };
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun #define GRF_PCIE30PHY_RK3568_CON1 0x4
495*4882a593Smuzhiyun #define GRF_PCIE30PHY_RK3568_CON3 0xC
496*4882a593Smuzhiyun #define GRF_PCIE30PHY_RK3568_CON4 0x10
497*4882a593Smuzhiyun #define GRF_PCIE30PHY_RK3568_CON5 0x14
498*4882a593Smuzhiyun #define GRF_PCIE30PHY_RK3568_CON6 0x18
499*4882a593Smuzhiyun #define GRF_PCIE30PHY_RK3568_CON9 0x24
500*4882a593Smuzhiyun #define GRF_PCIE30PHY_RK3568_STATUS0 0x80
501*4882a593Smuzhiyun #define RK3568_SRAM_INIT_DONE(reg) ((reg) & BIT(14))
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun #define PMUCRU_BASE			0xFDD00000
504*4882a593Smuzhiyun #define PMUCRU_PMUGATE_CON02		(PMUCRU_BASE + 0x188)
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun #define CRU_BASE			0xFDD20000
507*4882a593Smuzhiyun #define CRU_GATE_CON12			(CRU_BASE + 0x330)
508*4882a593Smuzhiyun #define CRU_GATE_CON13			(CRU_BASE + 0x334)
509*4882a593Smuzhiyun #define CRU_GATE_CON33			(CRU_BASE + 0x384)
510*4882a593Smuzhiyun #define CRU_SOFTRST_CON12		(CRU_BASE + 0x430)
511*4882a593Smuzhiyun #define CRU_SOFTRST_CON27		(CRU_BASE + 0x46c)
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun #define PCIE30_PHY_GRF			0xFDCB8000
514*4882a593Smuzhiyun 
pcie_cru_init(void)515*4882a593Smuzhiyun void pcie_cru_init(void)
516*4882a593Smuzhiyun {
517*4882a593Smuzhiyun 	u32 i, reg;
518*4882a593Smuzhiyun 	void __iomem *mmio = (void __iomem *)0xFE8C0000;
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	/* Enable phy and controoler clk */
521*4882a593Smuzhiyun 	writel(0xffff0000, PMUCRU_PMUGATE_CON02);
522*4882a593Smuzhiyun 	writel(0xffff0000, CRU_GATE_CON12);
523*4882a593Smuzhiyun 	writel(0xffff0000, CRU_GATE_CON13);
524*4882a593Smuzhiyun 	writel(0xffff0000, CRU_GATE_CON33);
525*4882a593Smuzhiyun 	writel(0xffff0000, CRU_SOFTRST_CON27);
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun 	writel(0x40004000, CRU_SOFTRST_CON27);
528*4882a593Smuzhiyun 	writel(0x80008000, PCIE30_PHY_GRF + GRF_PCIE30PHY_RK3568_CON9);
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	writel((0x1 << 15) | (0x1 << 31),
531*4882a593Smuzhiyun 	       PCIE30_PHY_GRF + GRF_PCIE30PHY_RK3568_CON9); //map to access sram
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun #ifdef PCIE_ENABLE_SRNS_PLL_REFCLK
534*4882a593Smuzhiyun 	/* use internal clock */
535*4882a593Smuzhiyun 	writel(0x0 | (0x1 << 31), PCIE30_PHY_GRF + GRF_PCIE30PHY_RK3568_CON3);
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	/* rx0_cmn_refclk_mode disabled */
538*4882a593Smuzhiyun 	writel((0x0) | (0x1 << 25), PCIE30_PHY_GRF + GRF_PCIE30PHY_RK3568_CON5);
539*4882a593Smuzhiyun 	/* rx1_cmn_refclk_mode disabled */
540*4882a593Smuzhiyun 	writel((0x0) | (0x1 << 25), PCIE30_PHY_GRF + GRF_PCIE30PHY_RK3568_CON6);
541*4882a593Smuzhiyun #endif
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 	writel((0x0 << 14) | (0x1 << (14 + 16)),
544*4882a593Smuzhiyun 	       PCIE30_PHY_GRF + GRF_PCIE30PHY_RK3568_CON4); //sdram_ld_done
545*4882a593Smuzhiyun 	writel((0x0 << 13) | (0x1 << (13 + 16)),
546*4882a593Smuzhiyun 	       PCIE30_PHY_GRF + GRF_PCIE30PHY_RK3568_CON4); //sdram_bypass
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 	writel(0x40000000, CRU_SOFTRST_CON27);
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun 	udelay(5);
551*4882a593Smuzhiyun 	printf("RKEP: sram initial\n");
552*4882a593Smuzhiyun 	while (1) {
553*4882a593Smuzhiyun 		reg = readl(PCIE30_PHY_GRF + GRF_PCIE30PHY_RK3568_STATUS0);
554*4882a593Smuzhiyun 		if (RK3568_SRAM_INIT_DONE(reg))
555*4882a593Smuzhiyun 			break;
556*4882a593Smuzhiyun 	}
557*4882a593Smuzhiyun 	printf("RKEP: sram init done\n");
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun 	writel((0x3 << 8) | (0x3 << (8 + 16)),
560*4882a593Smuzhiyun 	       PCIE30_PHY_GRF + GRF_PCIE30PHY_RK3568_CON9); //map to access sram
561*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(phy_fw); i++)
562*4882a593Smuzhiyun 		writel(phy_fw[i], mmio + (i << 2));
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	printf("RKEP: snps pcie3phy FW update! size %ld\n", ARRAY_SIZE(phy_fw));
565*4882a593Smuzhiyun 	writel((0x0 << 8) | (0x3 << (8 + 16)),
566*4882a593Smuzhiyun 	       PCIE30_PHY_GRF + GRF_PCIE30PHY_RK3568_CON9);
567*4882a593Smuzhiyun 	writel((0x1 << 14) | (0x1 << (14 + 16)),
568*4882a593Smuzhiyun 	       PCIE30_PHY_GRF + GRF_PCIE30PHY_RK3568_CON4); //sdram_ld_done
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 	writel(0xffff0000, CRU_SOFTRST_CON12);
571*4882a593Smuzhiyun 	writel(0x100010, PCIE_SNPS_APB_BASE + 0x180);
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun 	udelay(1);
574*4882a593Smuzhiyun }
575*4882a593Smuzhiyun #endif
576*4882a593Smuzhiyun 
pcie_ep_init(void)577*4882a593Smuzhiyun static void pcie_ep_init(void)
578*4882a593Smuzhiyun {
579*4882a593Smuzhiyun 	u32 val;
580*4882a593Smuzhiyun 	void *dbi_base = (void *)PCIE_SNPS_DBI_BASE;
581*4882a593Smuzhiyun 	u64 apb_base = PCIE_SNPS_APB_BASE;
582*4882a593Smuzhiyun 	int i, retries = 0;
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun #ifdef PCIE_ENABLE_SRNS_PLL_REFCLK
585*4882a593Smuzhiyun 	printep("RefClock in SRNS clock mode\n");
586*4882a593Smuzhiyun #else
587*4882a593Smuzhiyun 	printep("RefClock in common clock_mode\n");
588*4882a593Smuzhiyun #endif
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 	/*
591*4882a593Smuzhiyun 	 * ltssm_enable enhance mode and enable delaying the link training
592*4882a593Smuzhiyun 	 * after Hot Reset
593*4882a593Smuzhiyun 	 */
594*4882a593Smuzhiyun 	writel(0x120012, apb_base + 0x180);
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 	/* Unmask pm_turnoff_int */
597*4882a593Smuzhiyun 	writel(0x04000000, apb_base + 0x18);
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	/* PortLorgic DBI_RO_WR_EN */
600*4882a593Smuzhiyun 	val = readl((dbi_base + 0x8bc));
601*4882a593Smuzhiyun 	val |= 0x1;
602*4882a593Smuzhiyun 	writel(val, dbi_base + 0x8bc);
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun reinit:
605*4882a593Smuzhiyun 	pcie_bar_init(dbi_base);
606*4882a593Smuzhiyun 	pcie_inbound_config();
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun 	/* Device PID, DID */
609*4882a593Smuzhiyun 	writel(0x1d87, dbi_base + 0x00);
610*4882a593Smuzhiyun 	writel(0x356a, dbi_base + 0x02);
611*4882a593Smuzhiyun 	/* Device Class: Processing accelerators */
612*4882a593Smuzhiyun 	writel(0x1200, dbi_base + 0x0a);
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 	pcie_link_set_max_speed(dbi_base, PCI_EXP_LNKCTL2_TLS_8_0GT);
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun #ifdef	CONFIG_ROCKCHIP_RK3588
617*4882a593Smuzhiyun 	pcie_link_set_lanes(dbi_base, 4);
618*4882a593Smuzhiyun #elif	CONFIG_ROCKCHIP_RK3568
619*4882a593Smuzhiyun 	pcie_link_set_lanes(dbi_base, 2);
620*4882a593Smuzhiyun #endif
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 	/* EP mode */
623*4882a593Smuzhiyun 	writel(0xf00000, apb_base);
624*4882a593Smuzhiyun 	udelay(100);
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 	/* Enable EP mem/io access */
627*4882a593Smuzhiyun 	val = readl(dbi_base + 0x4);
628*4882a593Smuzhiyun 	writel(val | 0x6, dbi_base + 0x4);
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 	if (retries)	/* Set app_dly2_done to enable app_ltssm_enable */
631*4882a593Smuzhiyun 		writel(0x80008, apb_base + 0x180);
632*4882a593Smuzhiyun 	else		/* Enable LTSSM */
633*4882a593Smuzhiyun 		writel(0xc000c, apb_base);
634*4882a593Smuzhiyun 	printep("init PCIe fast Link up\n");
635*4882a593Smuzhiyun 	pcie_devmode_update(RKEP_MODE_LOADER, RKEP_SMODE_LNKRDY);
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun 	/* Waiting for Link up */
638*4882a593Smuzhiyun 	while (1) {
639*4882a593Smuzhiyun 		val = readl(apb_base + 0x300);
640*4882a593Smuzhiyun 		if (((val & 0x3ffff) & ((0x3 << 16) | 0x11)) == 0x30011)
641*4882a593Smuzhiyun 			break;
642*4882a593Smuzhiyun 		mdelay(1);
643*4882a593Smuzhiyun 	}
644*4882a593Smuzhiyun 	printep("Link up %x\n", val);
645*4882a593Smuzhiyun 	mdelay(3);
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun 	/* Wait for link stable */
648*4882a593Smuzhiyun 	for (i = 0; i < 10000; i++) {
649*4882a593Smuzhiyun 		val = readl(apb_base + 0x10);
650*4882a593Smuzhiyun 		if (val & 0x4) {
651*4882a593Smuzhiyun 			writel(0x4, apb_base + 0x10);
652*4882a593Smuzhiyun 			printep("Link is reset, int status misc=%x\n", val);
653*4882a593Smuzhiyun 			if (retries < 3) {
654*4882a593Smuzhiyun 				retries++;
655*4882a593Smuzhiyun 				goto reinit;
656*4882a593Smuzhiyun 			} else {
657*4882a593Smuzhiyun 				break;
658*4882a593Smuzhiyun 			}
659*4882a593Smuzhiyun 		}
660*4882a593Smuzhiyun 		udelay(1);
661*4882a593Smuzhiyun 	}
662*4882a593Smuzhiyun 	printep("Done\n");
663*4882a593Smuzhiyun 	pcie_devmode_update(RKEP_MODE_LOADER, RKEP_SMODE_LNKUP);
664*4882a593Smuzhiyun }
665*4882a593Smuzhiyun 
rockchip_pcie_ep_init(void)666*4882a593Smuzhiyun void rockchip_pcie_ep_init(void)
667*4882a593Smuzhiyun {
668*4882a593Smuzhiyun 	u32 val;
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	printf("\nRKEP: Init PCIe EP\n");
671*4882a593Smuzhiyun 	pcie_bar0_header_init();
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun #ifdef CONFIG_ROCKCHIP_RK3588
674*4882a593Smuzhiyun 	writel(0x1 << 23 | 0x1 << 21, PMU_PWR_GATE_SFTCON1);
675*4882a593Smuzhiyun 	udelay(10);
676*4882a593Smuzhiyun #endif
677*4882a593Smuzhiyun 	/* Re-in pcie initial */
678*4882a593Smuzhiyun 	val = readl(PCIE_SNPS_APB_BASE + 0x300);
679*4882a593Smuzhiyun 	if (((val & 0x3ffff) & ((0x3 << 16))) == 0x30000) {
680*4882a593Smuzhiyun 		printf("RKEP: already link up\n");
681*4882a593Smuzhiyun 		return;
682*4882a593Smuzhiyun 	}
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	pcie_board_init();
685*4882a593Smuzhiyun 	/* CRU and PHY Init */
686*4882a593Smuzhiyun 	pcie_cru_init();
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 	pcie_ep_init();
689*4882a593Smuzhiyun }
690