1 /* 2 * Copyright 2011 Freescale Semiconductor, Inc. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License as published by the Free 6 * Software Foundation; either version 2 of the License, or (at your option) 7 * any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 17 * MA 02111-1307 USA 18 */ 19 20 #include <common.h> 21 #include <config.h> 22 #include <asm/fsl_law.h> 23 #include <asm/fsl_serdes.h> 24 #include <asm/fsl_srio.h> 25 #include <asm/errno.h> 26 27 #define SRIO_PORT_ACCEPT_ALL 0x10000001 28 #define SRIO_IB_ATMU_AR 0x80f55000 29 #define SRIO_OB_ATMU_AR_MAINT 0x80077000 30 #define SRIO_OB_ATMU_AR_RW 0x80045000 31 #define SRIO_LCSBA1CSR_OFFSET 0x5c 32 #define SRIO_MAINT_WIN_SIZE 0x1000000 /* 16M */ 33 #define SRIO_RW_WIN_SIZE 0x100000 /* 1M */ 34 #define SRIO_LCSBA1CSR 0x60000000 35 36 #if defined(CONFIG_FSL_CORENET) 37 #define _DEVDISR_SRIO1 FSL_CORENET_DEVDISR_SRIO1 38 #define _DEVDISR_SRIO2 FSL_CORENET_DEVDISR_SRIO2 39 #define _DEVDISR_RMU FSL_CORENET_DEVDISR_RMU 40 #define CONFIG_SYS_MPC8xxx_GUTS_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR 41 #elif defined(CONFIG_MPC85xx) 42 #define _DEVDISR_SRIO1 MPC85xx_DEVDISR_SRIO 43 #define _DEVDISR_SRIO2 MPC85xx_DEVDISR_SRIO 44 #define _DEVDISR_RMU MPC85xx_DEVDISR_RMSG 45 #define CONFIG_SYS_MPC8xxx_GUTS_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR 46 #elif defined(CONFIG_MPC86xx) 47 #define _DEVDISR_SRIO1 MPC86xx_DEVDISR_SRIO 48 #define _DEVDISR_SRIO2 MPC86xx_DEVDISR_SRIO 49 #define _DEVDISR_RMU MPC86xx_DEVDISR_RMSG 50 #define CONFIG_SYS_MPC8xxx_GUTS_ADDR \ 51 (&((immap_t *)CONFIG_SYS_IMMR)->im_gur) 52 #else 53 #error "No defines for DEVDISR_SRIO" 54 #endif 55 56 #ifdef CONFIG_SYS_FSL_ERRATUM_SRIO_A004034 57 /* 58 * Erratum A-004034 59 * Affects: SRIO 60 * Description: During port initialization, the SRIO port performs 61 * lane synchronization (detecting valid symbols on a lane) and 62 * lane alignment (coordinating multiple lanes to receive valid data 63 * across lanes). Internal errors in lane synchronization and lane 64 * alignment may cause failure to achieve link initialization at 65 * the configured port width. 66 * An SRIO port configured as a 4x port may see one of these scenarios: 67 * 1. One or more lanes fails to achieve lane synchronization. Depending 68 * on which lanes fail, this may result in downtraining from 4x to 1x 69 * on lane 0, 4x to 1x on lane R (redundant lane). 70 * 2. The link may fail to achieve lane alignment as a 4x, even though 71 * all 4 lanes achieve lane synchronization, and downtrain to a 1x. 72 * An SRIO port configured as a 1x port may fail to complete port 73 * initialization (PnESCSR[PU] never deasserts) because of scenario 1. 74 * Impact: SRIO port may downtrain to 1x, or may fail to complete 75 * link initialization. Once a port completes link initialization 76 * successfully, it will operate normally. 77 */ 78 static int srio_erratum_a004034(u8 port) 79 { 80 serdes_corenet_t *srds_regs; 81 u32 conf_lane; 82 u32 init_lane; 83 int idx, first, last; 84 u32 i; 85 unsigned long long end_tick; 86 struct ccsr_rio *srio_regs = (void *)CONFIG_SYS_FSL_SRIO_ADDR; 87 88 srds_regs = (void *)(CONFIG_SYS_FSL_CORENET_SERDES_ADDR); 89 conf_lane = (in_be32((void *)&srds_regs->srdspccr0) 90 >> (12 - port * 4)) & 0x3; 91 init_lane = (in_be32((void *)&srio_regs->lp_serial 92 .port[port].pccsr) >> 27) & 0x7; 93 94 /* 95 * Start a counter set to ~2 ms after the SERDES reset is 96 * complete (SERDES SRDSBnRSTCTL[RST_DONE]=1 for n 97 * corresponding to the SERDES bank/PLL for the SRIO port). 98 */ 99 if (in_be32((void *)&srds_regs->bank[0].rstctl) 100 & SRDS_RSTCTL_RSTDONE) { 101 /* 102 * Poll the port uninitialized status (SRIO PnESCSR[PO]) until 103 * PO=1 or the counter expires. If the counter expires, the 104 * port has failed initialization: go to recover steps. If PO=1 105 * and the desired port width is 1x, go to normal steps. If 106 * PO = 1 and the desired port width is 4x, go to recover steps. 107 */ 108 end_tick = usec2ticks(2000) + get_ticks(); 109 do { 110 if (in_be32((void *)&srio_regs->lp_serial 111 .port[port].pescsr) & 0x2) { 112 if (conf_lane == 0x1) 113 goto host_ok; 114 else { 115 if (init_lane == 0x2) 116 goto host_ok; 117 else 118 break; 119 } 120 } 121 } while (end_tick > get_ticks()); 122 123 /* recover at most 3 times */ 124 for (i = 0; i < 3; i++) { 125 /* Set SRIO PnCCSR[PD]=1 */ 126 setbits_be32((void *)&srio_regs->lp_serial 127 .port[port].pccsr, 128 0x800000); 129 /* 130 * Set SRIO PnPCR[OBDEN] on the host to 131 * enable the discarding of any pending packets. 132 */ 133 setbits_be32((void *)&srio_regs->impl.port[port].pcr, 134 0x04); 135 /* Wait 50 us */ 136 udelay(50); 137 /* Run sync command */ 138 isync(); 139 140 if (port) 141 first = serdes_get_first_lane(SRIO2); 142 else 143 first = serdes_get_first_lane(SRIO1); 144 if (unlikely(first < 0)) 145 return -ENODEV; 146 if (conf_lane == 0x1) 147 last = first; 148 else 149 last = first + 3; 150 /* 151 * Set SERDES BnGCRm0[RRST]=0 for each SRIO 152 * bank n and lane m. 153 */ 154 for (idx = first; idx <= last; idx++) 155 clrbits_be32(&srds_regs->lane[idx].gcr0, 156 SRDS_GCR0_RRST); 157 /* 158 * Read SERDES BnGCRm0 for each SRIO 159 * bank n and lane m 160 */ 161 for (idx = first; idx <= last; idx++) 162 in_be32(&srds_regs->lane[idx].gcr0); 163 /* Run sync command */ 164 isync(); 165 /* Wait >= 100 ns */ 166 udelay(1); 167 /* 168 * Set SERDES BnGCRm0[RRST]=1 for each SRIO 169 * bank n and lane m. 170 */ 171 for (idx = first; idx <= last; idx++) 172 setbits_be32(&srds_regs->lane[idx].gcr0, 173 SRDS_GCR0_RRST); 174 /* 175 * Read SERDES BnGCRm0 for each SRIO 176 * bank n and lane m 177 */ 178 for (idx = first; idx <= last; idx++) 179 in_be32(&srds_regs->lane[idx].gcr0); 180 /* Run sync command */ 181 isync(); 182 /* Wait >= 300 ns */ 183 udelay(1); 184 185 /* Write 1 to clear all bits in SRIO PnSLCSR */ 186 out_be32((void *)&srio_regs->impl.port[port].slcsr, 187 0xffffffff); 188 /* Clear SRIO PnPCR[OBDEN] on the host */ 189 clrbits_be32((void *)&srio_regs->impl.port[port].pcr, 190 0x04); 191 /* Set SRIO PnCCSR[PD]=0 */ 192 clrbits_be32((void *)&srio_regs->lp_serial 193 .port[port].pccsr, 194 0x800000); 195 /* Wait >= 24 ms */ 196 udelay(24000); 197 /* Poll the state of the port again */ 198 init_lane = 199 (in_be32((void *)&srio_regs->lp_serial 200 .port[port].pccsr) >> 27) & 0x7; 201 if (in_be32((void *)&srio_regs->lp_serial 202 .port[port].pescsr) & 0x2) { 203 if (conf_lane == 0x1) 204 goto host_ok; 205 else { 206 if (init_lane == 0x2) 207 goto host_ok; 208 } 209 } 210 if (i == 2) 211 return -ENODEV; 212 } 213 } else 214 return -ENODEV; 215 216 host_ok: 217 /* Poll PnESCSR[OES] on the host until it is clear */ 218 end_tick = usec2ticks(1000000) + get_ticks(); 219 do { 220 if (!(in_be32((void *)&srio_regs->lp_serial.port[port].pescsr) 221 & 0x10000)) { 222 out_be32(((void *)&srio_regs->lp_serial 223 .port[port].pescsr), 0xffffffff); 224 out_be32(((void *)&srio_regs->phys_err 225 .port[port].edcsr), 0); 226 out_be32(((void *)&srio_regs->logical_err.ltledcsr), 0); 227 return 0; 228 } 229 } while (end_tick > get_ticks()); 230 231 return -ENODEV; 232 } 233 #endif 234 235 void srio_init(void) 236 { 237 ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC8xxx_GUTS_ADDR; 238 int srio1_used = 0, srio2_used = 0; 239 240 if (is_serdes_configured(SRIO1)) { 241 set_next_law(CONFIG_SYS_SRIO1_MEM_PHYS, 242 law_size_bits(CONFIG_SYS_SRIO1_MEM_SIZE), 243 LAW_TRGT_IF_RIO_1); 244 srio1_used = 1; 245 #ifdef CONFIG_SYS_FSL_ERRATUM_SRIO_A004034 246 if (srio_erratum_a004034(0) < 0) 247 printf("SRIO1: enabled but port error\n"); 248 else 249 #endif 250 printf("SRIO1: enabled\n"); 251 } else { 252 printf("SRIO1: disabled\n"); 253 } 254 255 #ifdef CONFIG_SRIO2 256 if (is_serdes_configured(SRIO2)) { 257 set_next_law(CONFIG_SYS_SRIO2_MEM_PHYS, 258 law_size_bits(CONFIG_SYS_SRIO2_MEM_SIZE), 259 LAW_TRGT_IF_RIO_2); 260 srio2_used = 1; 261 #ifdef CONFIG_SYS_FSL_ERRATUM_SRIO_A004034 262 if (srio_erratum_a004034(1) < 0) 263 printf("SRIO2: enabled but port error\n"); 264 else 265 #endif 266 printf("SRIO2: enabled\n"); 267 268 } else { 269 printf("SRIO2: disabled\n"); 270 } 271 #endif 272 273 #ifdef CONFIG_FSL_CORENET 274 /* On FSL_CORENET devices we can disable individual ports */ 275 if (!srio1_used) 276 setbits_be32(&gur->devdisr, FSL_CORENET_DEVDISR_SRIO1); 277 if (!srio2_used) 278 setbits_be32(&gur->devdisr, FSL_CORENET_DEVDISR_SRIO2); 279 #endif 280 281 /* neither port is used - disable everything */ 282 if (!srio1_used && !srio2_used) { 283 setbits_be32(&gur->devdisr, _DEVDISR_SRIO1); 284 setbits_be32(&gur->devdisr, _DEVDISR_SRIO2); 285 setbits_be32(&gur->devdisr, _DEVDISR_RMU); 286 } 287 } 288 289 #ifdef CONFIG_FSL_CORENET 290 void srio_boot_master(int port) 291 { 292 struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR; 293 294 /* set port accept-all */ 295 out_be32((void *)&srio->impl.port[port - 1].ptaacr, 296 SRIO_PORT_ACCEPT_ALL); 297 298 debug("SRIOBOOT - MASTER: Master port [ %d ] for srio boot.\n", port); 299 /* configure inbound window for slave's u-boot image */ 300 debug("SRIOBOOT - MASTER: Inbound window for slave's image; " 301 "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", 302 (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, 303 (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1, 304 CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); 305 out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwtar, 306 CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12); 307 out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwbar, 308 CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 >> 12); 309 out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwar, 310 SRIO_IB_ATMU_AR 311 | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE)); 312 313 /* configure inbound window for slave's u-boot image */ 314 debug("SRIOBOOT - MASTER: Inbound window for slave's image; " 315 "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", 316 (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, 317 (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2, 318 CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); 319 out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwtar, 320 CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12); 321 out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwbar, 322 CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 >> 12); 323 out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwar, 324 SRIO_IB_ATMU_AR 325 | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE)); 326 327 /* configure inbound window for slave's ucode and ENV */ 328 debug("SRIOBOOT - MASTER: Inbound window for slave's ucode and ENV; " 329 "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", 330 (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS, 331 (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS, 332 CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE); 333 out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwtar, 334 CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS >> 12); 335 out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwbar, 336 CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS >> 12); 337 out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwar, 338 SRIO_IB_ATMU_AR 339 | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE)); 340 } 341 342 void srio_boot_master_release_slave(int port) 343 { 344 struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR; 345 u32 escsr; 346 debug("SRIOBOOT - MASTER: " 347 "Check the port status and release slave core ...\n"); 348 349 escsr = in_be32((void *)&srio->lp_serial.port[port - 1].pescsr); 350 if (escsr & 0x2) { 351 if (escsr & 0x10100) { 352 debug("SRIOBOOT - MASTER: Port [ %d ] is error.\n", 353 port); 354 } else { 355 debug("SRIOBOOT - MASTER: " 356 "Port [ %d ] is ready, now release slave's core ...\n", 357 port); 358 /* 359 * configure outbound window 360 * with maintenance attribute to set slave's LCSBA1CSR 361 */ 362 out_be32((void *)&srio->atmu.port[port - 1] 363 .outbw[1].rowtar, 0); 364 out_be32((void *)&srio->atmu.port[port - 1] 365 .outbw[1].rowtear, 0); 366 if (port - 1) 367 out_be32((void *)&srio->atmu.port[port - 1] 368 .outbw[1].rowbar, 369 CONFIG_SYS_SRIO2_MEM_PHYS >> 12); 370 else 371 out_be32((void *)&srio->atmu.port[port - 1] 372 .outbw[1].rowbar, 373 CONFIG_SYS_SRIO1_MEM_PHYS >> 12); 374 out_be32((void *)&srio->atmu.port[port - 1] 375 .outbw[1].rowar, 376 SRIO_OB_ATMU_AR_MAINT 377 | atmu_size_mask(SRIO_MAINT_WIN_SIZE)); 378 379 /* 380 * configure outbound window 381 * with R/W attribute to set slave's BRR 382 */ 383 out_be32((void *)&srio->atmu.port[port - 1] 384 .outbw[2].rowtar, 385 SRIO_LCSBA1CSR >> 9); 386 out_be32((void *)&srio->atmu.port[port - 1] 387 .outbw[2].rowtear, 0); 388 if (port - 1) 389 out_be32((void *)&srio->atmu.port[port - 1] 390 .outbw[2].rowbar, 391 (CONFIG_SYS_SRIO2_MEM_PHYS 392 + SRIO_MAINT_WIN_SIZE) >> 12); 393 else 394 out_be32((void *)&srio->atmu.port[port - 1] 395 .outbw[2].rowbar, 396 (CONFIG_SYS_SRIO1_MEM_PHYS 397 + SRIO_MAINT_WIN_SIZE) >> 12); 398 out_be32((void *)&srio->atmu.port[port - 1] 399 .outbw[2].rowar, 400 SRIO_OB_ATMU_AR_RW 401 | atmu_size_mask(SRIO_RW_WIN_SIZE)); 402 403 /* 404 * Set the LCSBA1CSR register in slave 405 * by the maint-outbound window 406 */ 407 if (port - 1) { 408 out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT 409 + SRIO_LCSBA1CSR_OFFSET, 410 SRIO_LCSBA1CSR); 411 while (in_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT 412 + SRIO_LCSBA1CSR_OFFSET) 413 != SRIO_LCSBA1CSR) 414 ; 415 /* 416 * And then set the BRR register 417 * to release slave core 418 */ 419 out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT 420 + SRIO_MAINT_WIN_SIZE 421 + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET, 422 CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK); 423 } else { 424 out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT 425 + SRIO_LCSBA1CSR_OFFSET, 426 SRIO_LCSBA1CSR); 427 while (in_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT 428 + SRIO_LCSBA1CSR_OFFSET) 429 != SRIO_LCSBA1CSR) 430 ; 431 /* 432 * And then set the BRR register 433 * to release slave core 434 */ 435 out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT 436 + SRIO_MAINT_WIN_SIZE 437 + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET, 438 CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK); 439 } 440 debug("SRIOBOOT - MASTER: " 441 "Release slave successfully! Now the slave should start up!\n"); 442 } 443 } else 444 debug("SRIOBOOT - MASTER: Port [ %d ] is not ready.\n", port); 445 } 446 #endif 447