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