shbde_iproc.c (15582B)
1 /* 2 * Copyright 2017 Broadcom 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License, version 2, as 6 * published by the Free Software Foundation (the "GPL"). 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License version 2 (GPLv2) for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * version 2 (GPLv2) along with this source code. 15 */ 16 /* 17 * $Id: $ 18 * $Copyright: (c) 2014 Broadcom Corp. 19 * All Rights Reserved.$ 20 * 21 */ 22 23 #include <shbde_iproc.h> 24 #include <shbde_mdio.h> 25 #include <shbde_pci.h> 26 27 /* PAXB register offsets within PCI BAR0 window */ 28 #define BAR0_PAXB_ENDIANESS 0x2030 29 #define BAR0_PAXB_PCIE_EP_AXI_CONFIG 0x2104 30 #define BAR0_PAXB_CONFIG_IND_ADDR 0x2120 31 #define BAR0_PAXB_CONFIG_IND_DATA 0x2124 32 33 #define PAXB_0_CMICD_TO_PCIE_INTR_EN 0x2380 34 35 #define BAR0_PAXB_IMAP0_0 (0x2c00) 36 #define BAR0_PAXB_IMAP0_1 (0x2c04) 37 #define BAR0_PAXB_IMAP0_2 (0x2c08) 38 #define BAR0_PAXB_IMAP0_7 (0x2c1c) 39 40 #define BAR0_PAXB_OARR_FUNC0_MSI_PAGE 0x2d34 41 #define BAR0_PAXB_OARR_2 0x2d60 42 #define BAR0_PAXB_OARR_2_UPPER 0x2d64 43 #define BAR0_DMU_PCU_PCIE_SLAVE_RESET_MODE 0x7024 44 45 #define PAXB_0_FUNC0_IMAP1_3 0x2d88 46 47 /* Force byte pointer for offset adjustments */ 48 #define ROFFS(_ptr, _offset) ((unsigned char*)(_ptr) + (_offset)) 49 50 #define PAXB_CONFIG_IND_ADDRr_PROTOCOL_LAYERf_SHFT 11 51 #define PAXB_CONFIG_IND_ADDRr_PROTOCOL_LAYERf_MASK 0x3 52 #define PAXB_CONFIG_IND_ADDRr_ADDRESSf_SHFT 0 53 #define PAXB_CONFIG_IND_ADDRr_ADDRESSf_MASK 0x7ff 54 #define PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT 20 55 56 /* Register value set/get by field */ 57 #define REG_FIELD_SET(_r, _f, _r_val, _f_val) \ 58 _r_val = ((_r_val) & ~(_r##_##_f##_MASK << _r##_##_f##_SHFT)) | \ 59 (((_f_val) & _r##_##_f##_MASK) << _r##_##_f##_SHFT) 60 #define REG_FIELD_GET(_r, _f, _r_val) \ 61 (((_r_val) >> _r##_##_f##_SHFT) & _r##_##_f##_MASK) 62 63 /* PCIe capabilities definition */ 64 #ifndef PCI_EXP_LNKSTA 65 #define PCI_EXP_LNKSTA 0x12 66 #endif 67 /* Current Link Speed 5.0GT/s */ 68 #ifndef PCI_EXP_LNKSTA_CLS_5_0GB 69 #define PCI_EXP_LNKSTA_CLS_5_0GB 2 70 #endif 71 #ifndef PCI_EXP_LNKSTA2 72 #define PCI_EXP_LNKSTA2 0x32 73 #endif 74 /* Current Deemphasis Level -3.5 dB */ 75 #ifndef PCI_EXP_LNKSTA2_CDL_3_5DB 76 #define PCI_EXP_LNKSTA2_CDL_3_5DB 0x1 77 #endif 78 79 static unsigned int 80 iproc32_read(shbde_hal_t *shbde, void *addr) 81 { 82 if (!shbde || !shbde->io32_read) { 83 return 0; 84 } 85 return shbde->io32_read(addr); 86 } 87 88 static void 89 iproc32_write(shbde_hal_t *shbde, void *addr, unsigned int data) 90 { 91 if (!shbde || !shbde->io32_write) { 92 return; 93 } 94 shbde->io32_write(addr, data); 95 } 96 97 static void 98 wait_usec(shbde_hal_t *shbde, int usec) 99 { 100 if (shbde && shbde->usleep) { 101 shbde->usleep(usec); 102 } else { 103 int idx; 104 volatile int count; 105 for (idx = 0; idx < usec; idx++) { 106 for (count = 0; count < 100; count++); 107 } 108 } 109 } 110 111 /* 112 * Function: 113 * shbde_iproc_config_init 114 * Purpose: 115 * Initialize iProc configuration parameters 116 * Parameters: 117 * icfg - pointer to empty iProc configuration structure 118 * Returns: 119 * -1 if error, otherwise 0 120 */ 121 int 122 shbde_iproc_config_init(shbde_iproc_config_t *icfg, 123 unsigned int dev_id, unsigned int dev_rev) 124 { 125 if (!icfg) { 126 return -1; 127 } 128 129 /* Save device ID and revision */ 130 icfg->dev_id = dev_id; 131 icfg->dev_rev = dev_rev; 132 133 /* Check device families first */ 134 switch (icfg->dev_id & 0xfff0) { 135 case 0x8400: /* Greyhound Lite */ 136 case 0x8410: /* Greyhound */ 137 case 0x8420: /* Bloodhound */ 138 case 0x8450: /* Elkhound */ 139 case 0xb060: /* Ranger2(Greyhound) */ 140 case 0x8360: /* Greyhound 53365 & 53369 */ 141 case 0xb260: /* saber2 */ 142 case 0xb460: /* saber2+ */ 143 case 0xb170: /* Hurricane3-MG */ 144 case 0x8570: /* Greyhound2 */ 145 case 0xb070: /* Greyhound2(emulation) */ 146 case 0x8580: /* Greyhound2(emulation) */ 147 case 0xb230: /* Dagger2 */ 148 icfg->iproc_ver = 7; 149 icfg->dma_hi_bits = 0x2; 150 break; 151 case 0xb560: /* Apache */ 152 case 0xb670: /* MO */ 153 case 0xb760: /* Maverick */ 154 icfg->iproc_ver = 0xB; 155 break; 156 case 0xb160: /* Hurricane3 */ 157 case 0x8440: /* Buckhound2 */ 158 case 0x8430: /* Foxhound2 */ 159 case 0x8540: /* Wolfhound2 */ 160 icfg->iproc_ver = 10; 161 icfg->dma_hi_bits = 0x2; 162 break; 163 default: 164 break; 165 } 166 167 /* Check for exceptions */ 168 switch (icfg->dev_id) { 169 case 0xb069: 170 case 0xb068: 171 icfg->iproc_ver = 0xB; /*Ranger2+ Apache Family */ 172 icfg->dma_hi_bits = 0; 173 break; 174 case 0xb168: /* Ranger3+ */ 175 case 0xb169: 176 icfg->iproc_ver = 0; 177 icfg->dma_hi_bits = 0; 178 break; 179 default: 180 break; 181 } 182 /* Check for PCIe PHY address that needs PCIe preemphasis and 183 * assign the MDIO base address 184 */ 185 switch (icfg->dev_id & 0xfff0) { 186 case 0xb150: /* Hurricane2 */ 187 case 0x8340: /* Wolfhound */ 188 case 0x8330: /* Foxhound */ 189 case 0x8390: /* Dearhound */ 190 icfg->mdio_base_addr = 0x18032000; 191 icfg->pcie_phy_addr = 0x2; 192 break; 193 case 0xb340: /* Helilx4 */ 194 case 0xb540: /* FireScout */ 195 case 0xb040: /* Spiral, Ranger */ 196 icfg->mdio_base_addr = 0x18032000; 197 icfg->pcie_phy_addr = 0x5; 198 icfg->adjust_pcie_preemphasis = 1; 199 break; 200 case 0xa450: /* Katana2 */ 201 case 0xb240: 202 case 0xb450: 203 icfg->mdio_base_addr = 0x18032000; 204 icfg->pcie_phy_addr = 0x5; 205 icfg->adjust_pcie_preemphasis = 1; 206 break; 207 default: 208 break; 209 } 210 211 /* Check for exceptions */ 212 switch (icfg->dev_id) { 213 default: 214 break; 215 } 216 217 return 0; 218 } 219 220 /* 221 * Function: 222 * shbde_iproc_paxb_init 223 * Purpose: 224 * Initialize iProc PCI-AXI bridge for CMIC access 225 * Parameters: 226 * shbde - pointer to initialized hardware abstraction module 227 * iproc_regs - memory mapped iProc registers in PCI BAR 228 * icfg - iProc configuration parameters 229 * Returns: 230 * -1 if error, otherwise 0 231 */ 232 int 233 shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs, 234 shbde_iproc_config_t *icfg) 235 { 236 void *reg; 237 unsigned int data; 238 int pci_num; 239 240 if (!iproc_regs || !icfg) { 241 return -1; 242 } 243 244 /* 245 * The following code attempts to auto-detect the correct 246 * iProc PCI endianess configuration by reading a well-known 247 * register (the endianess configuration register itself). 248 * Note that the PCI endianess may be different for different 249 * big endian host processors. 250 */ 251 reg = ROFFS(iproc_regs, BAR0_PAXB_ENDIANESS); 252 /* Select big endian */ 253 iproc32_write(shbde, reg, 0x01010101); 254 /* Check if endianess register itself is correct endian */ 255 if (iproc32_read(shbde, reg) != 1) { 256 /* If not, then assume little endian */ 257 iproc32_write(shbde, reg, 0x0); 258 } 259 260 /* Select which PCI core to use */ 261 pci_num = 0; 262 reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_2); 263 data = iproc32_read(shbde, reg); 264 if (data & 0x1000) { 265 /* PAXB_1 is mapped to sub-window 2 */ 266 pci_num = 1; 267 } 268 269 /* Default DMA mapping if uninitialized */ 270 if (icfg->dma_hi_bits == 0) { 271 icfg->dma_hi_bits = 0x1; 272 if (pci_num == 1) { 273 icfg->dma_hi_bits = 0x2; 274 } 275 } 276 277 /* Enable iProc DMA to external host memory */ 278 reg = ROFFS(iproc_regs, BAR0_PAXB_PCIE_EP_AXI_CONFIG); 279 iproc32_write(shbde, reg, 0x0); 280 if(icfg->cmic_ver < 4) { /* Non-CMICX */ 281 reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_2); 282 iproc32_write(shbde, reg, 0x1); 283 reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_2_UPPER); 284 iproc32_write(shbde, reg, icfg->dma_hi_bits); 285 /* Configure MSI interrupt page */ 286 if (icfg->use_msi) { 287 reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_FUNC0_MSI_PAGE); 288 data = iproc32_read(shbde, reg); 289 iproc32_write(shbde, reg, data | 0x1); 290 } 291 } 292 293 /* Configure MSIX interrupt page, need for iproc ver 0x10 and 0x12 */ 294 if ((icfg->use_msi == 2) && 295 ((icfg->iproc_ver == 0x10) || (icfg->iproc_ver == 0x12))){ 296 unsigned int mask = (0x1 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT) - 1; 297 reg = ROFFS(iproc_regs, PAXB_0_FUNC0_IMAP1_3); 298 data = iproc32_read(shbde, reg); 299 data &= mask; 300 data |= 0x410 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT; 301 iproc32_write(shbde, reg, data); 302 } 303 304 /* Disable INTx interrupt if MSI/MSIX is selected */ 305 reg = ROFFS(iproc_regs, PAXB_0_CMICD_TO_PCIE_INTR_EN); 306 data = iproc32_read(shbde, reg); 307 if (icfg->use_msi) { 308 data &= ~0x1; 309 } else { 310 data |= 0x1; 311 } 312 iproc32_write(shbde, reg, data); 313 314 return pci_num; 315 } 316 317 /* 318 * Function: 319 * shbde_iproc_pci_read 320 * Purpose: 321 * Read iProc register through PCI BAR 0 322 * Parameters: 323 * shbde - pointer to initialized hardware abstraction module 324 * iproc_regs - memory mapped iProc registers in PCI BAR 325 * addr - iProc register address in AXI memory space 326 * Returns: 327 * Register value 328 */ 329 unsigned int 330 shbde_iproc_pci_read(shbde_hal_t *shbde, void *iproc_regs, 331 unsigned int addr) 332 { 333 unsigned int subwin_base; 334 void *reg; 335 shbde_iproc_config_t *icfg = &shbde->icfg; 336 337 if (!iproc_regs) { 338 return -1; 339 } 340 341 /* Sub-window size is 0x1000 (4K) */ 342 subwin_base = (addr & ~0xfff); 343 344 if((icfg->cmic_ver >= 4) && 345 ((subwin_base == 0x10230000) || (subwin_base == 0x18012000))) { 346 /* Route the PAXB register through IMAP0_2 */ 347 reg = ROFFS(iproc_regs, 0x2000 + (addr & 0xfff)); 348 } else if((icfg->cmic_ver >= 4) && 349 ((subwin_base == 0x10231000) || (subwin_base == 0x18013000))) { 350 /* Route the INTC block access through IMAP0_6 */ 351 reg = ROFFS(iproc_regs, 0x6000 + (addr & 0xfff)); 352 } else { 353 /* Update base address for sub-window 7 */ 354 subwin_base |= 1; /* Valid bit */ 355 reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); 356 iproc32_write(shbde, reg, subwin_base); 357 /* Read it to make sure the write actually goes through */ 358 subwin_base = iproc32_read(shbde, reg); 359 360 /* Read register through sub-window 7 */ 361 reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); 362 } 363 364 return iproc32_read(shbde, reg); 365 } 366 367 /* 368 * Function: 369 * shbde_iproc_pci_write 370 * Purpose: 371 * Write iProc register through PCI BAR 0 372 * Parameters: 373 * shbde - pointer to initialized hardware abstraction module 374 * iproc_regs - memory mapped iProc registers in PCI BAR 375 * addr - iProc register address in AXI memory space 376 * data - data to write to iProc register 377 * Returns: 378 * Register value 379 */ 380 void 381 shbde_iproc_pci_write(shbde_hal_t *shbde, void *iproc_regs, 382 unsigned int addr, unsigned int data) 383 { 384 unsigned int subwin_base; 385 void *reg; 386 shbde_iproc_config_t *icfg = &shbde->icfg; 387 388 if (!iproc_regs) { 389 return; 390 } 391 392 /* Sub-window size is 0x1000 (4K) */ 393 subwin_base = (addr & ~0xfff); 394 395 if((icfg->cmic_ver >= 4) && 396 ((subwin_base == 0x10230000) || (subwin_base == 0x18012000))) { 397 /* Route the PAXB register through IMAP0_2 */ 398 reg = ROFFS(iproc_regs, 0x2000 + (addr & 0xfff)); 399 } else if((icfg->cmic_ver >= 4) && 400 ((subwin_base == 0x10231000) || (subwin_base == 0x18013000))) { 401 /* Route the INTC block access through IMAP0_6 */ 402 reg = ROFFS(iproc_regs, 0x6000 + (addr & 0xfff)); 403 } else { 404 /* Update base address for sub-window 7 */ 405 subwin_base |= 1; /* Valid bit */ 406 reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); 407 iproc32_write(shbde, reg, subwin_base); 408 /* Read it to make sure the write actually goes through */ 409 subwin_base = iproc32_read(shbde, reg); 410 411 /* Read register through sub-window 7 */ 412 reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); 413 } 414 415 iproc32_write(shbde, reg, data); 416 } 417 418 int 419 shbde_iproc_pcie_preemphasis_set(shbde_hal_t *shbde, void *iproc_regs, 420 shbde_iproc_config_t *icfg, void *pci_dev) 421 { 422 shbde_mdio_ctrl_t mdio_ctrl, *smc = &mdio_ctrl; 423 unsigned int phy_addr, data; 424 void *reg; 425 unsigned int pcie_cap_base; 426 unsigned short link_stat, link_stat2; 427 428 if (!icfg) { 429 return -1; 430 } 431 432 /* PHY address for PCIe link */ 433 phy_addr = icfg->pcie_phy_addr; 434 if (phy_addr == 0 || icfg->mdio_base_addr == 0) { 435 return 0; 436 } 437 438 /* Initialize MDIO control */ 439 smc->shbde = shbde; 440 smc->regs = iproc_regs; 441 smc->base_addr = icfg->mdio_base_addr; 442 smc->io32_read = shbde_iproc_pci_read; 443 smc->io32_write = shbde_iproc_pci_write; 444 shbde_iproc_mdio_init(smc); 445 446 /* PCIe SerDes Gen1/Gen2 CDR Track Bandwidth Adjustment 447 * for Better Jitter Tolerance 448 */ 449 shbde_iproc_mdio_write(smc, phy_addr, 0x1f, 0x8630); 450 shbde_iproc_mdio_write(smc, phy_addr, 0x13, 0x190); 451 shbde_iproc_mdio_write(smc, phy_addr, 0x19, 0x191); 452 453 if (!icfg->adjust_pcie_preemphasis) { 454 return 0; 455 } 456 457 /* Check to see if the PCIe SerDes deemphasis needs to be changed 458 * based on the advertisement from the root complex 459 */ 460 /* Find PCIe capability base */ 461 if (!shbde || !shbde->pcic16_read || !pci_dev) { 462 return -1; 463 } 464 pcie_cap_base = shbde_pci_pcie_cap(shbde, pci_dev); 465 if (pcie_cap_base) { 466 link_stat = shbde->pcic16_read(pci_dev, 467 pcie_cap_base + PCI_EXP_LNKSTA); 468 link_stat2 = shbde->pcic16_read(pci_dev, 469 pcie_cap_base + PCI_EXP_LNKSTA2); 470 if (((link_stat & 0xf) == PCI_EXP_LNKSTA_CLS_5_0GB) && 471 (link_stat2 & PCI_EXP_LNKSTA2_CDL_3_5DB)) { 472 /* Device is operating at Gen2 speeds and RC requested -3.5dB */ 473 /* Change the transmitter setting */ 474 shbde_iproc_mdio_write(smc, phy_addr, 0x1f, 0x8610); 475 shbde_iproc_mdio_read(smc, phy_addr, 0x17, &data); 476 data &= ~0xf00; 477 data |= 0x700; 478 shbde_iproc_mdio_write(smc, phy_addr, 0x17, data); 479 480 /* Force the PCIe link to retrain */ 481 data = 0; 482 REG_FIELD_SET(PAXB_CONFIG_IND_ADDRr, PROTOCOL_LAYERf, data, 0x2); 483 REG_FIELD_SET(PAXB_CONFIG_IND_ADDRr, ADDRESSf, data, 0x4); 484 reg = ROFFS(iproc_regs, BAR0_PAXB_CONFIG_IND_ADDR); 485 iproc32_write(shbde, reg, data); 486 487 reg = ROFFS(iproc_regs, BAR0_PAXB_CONFIG_IND_DATA); 488 data = iproc32_read(shbde, reg); 489 data &= ~0x4000; 490 iproc32_write(shbde, reg, data); 491 data |= 0x4000; 492 iproc32_write(shbde, reg, data); 493 data &= ~0x4000; 494 iproc32_write(shbde, reg, data); 495 496 /* Wait a short while for the retraining to complete */ 497 wait_usec(shbde, 1000); 498 } 499 } 500 501 return 0; 502 } 503