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