Commit fb07c0a16dce007208d58c673aacc649703f18fd

Authored by Shaveta Leekha
Committed by York Sun
1 parent 5e5097c110

board/b4860qds: Add support to make PCIe SATA work on B4860QDS

1) SerDes2 Refclks have been set properly to make
     PCIe SATA to work as it work on SerDes refclk of 100MHz
  2) Mask the SerDes's device reset request before changing
     the Refclks for SerDes1 and SerDes2 for PLL locks to
     happen properly, device reset request bit unmasked
     after SerDes refclks configuration

Signed-off-by: Shaveta Leekha <shaveta@freescale.com>
Reviewed-by: York Sun <yorksun@freescale.com>

Showing 2 changed files with 113 additions and 9 deletions Side-by-side Diff

arch/powerpc/include/asm/immap_85xx.h
... ... @@ -1722,6 +1722,9 @@
1722 1722 u32 rstrqpblsr; /* Reset request preboot loader status */
1723 1723 u8 res11[8];
1724 1724 u32 rstrqmr1; /* Reset request mask */
  1725 +#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
  1726 +#define FSL_CORENET_RSTRQMR1_SRDS_RST_MSK 0x00000800
  1727 +#endif
1725 1728 u8 res12[4];
1726 1729 u32 rstrqsr1; /* Reset request status */
1727 1730 u8 res13[4];
board/freescale/b4860qds/b4860qds.c
... ... @@ -11,6 +11,7 @@
11 11 #include <linux/compiler.h>
12 12 #include <asm/mmu.h>
13 13 #include <asm/processor.h>
  14 +#include <asm/errno.h>
14 15 #include <asm/cache.h>
15 16 #include <asm/immap_85xx.h>
16 17 #include <asm/fsl_law.h>
... ... @@ -293,7 +294,8 @@
293 294 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
294 295 u32 serdes1_prtcl, lane;
295 296 unsigned int flag_sgmii_aurora_prtcl = 0;
296   - int ret, i;
  297 + int i;
  298 + int ret = 0;
297 299  
298 300 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
299 301 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
300 302  
... ... @@ -304,10 +306,12 @@
304 306 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
305 307 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
306 308  
307   - /* Clear SRDS_RSTCTL_RST bit for both PLLs before changing refclks
  309 + /* To prevent generation of reset request from SerDes
  310 + * while changing the refclks, By setting SRDS_RST_MSK bit,
  311 + * SerDes reset event cannot cause a reset request
308 312 */
309   - for (i = 0; i < PLL_NUM; i++)
310   - clrbits_be32(&srds_regs->bank[i].rstctl, SRDS_RSTCTL_RST);
  313 + setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
  314 +
311 315 /* Reconfigure IDT idt8t49n222a device for CPRI to work
312 316 * For this SerDes1's Refclk1 and refclk2 need to be set
313 317 * to 122.88MHz
314 318  
315 319  
... ... @@ -345,11 +349,11 @@
345 349 SERDES_REFCLK_122_88, 0);
346 350 if (ret) {
347 351 printf("IDT8T49N222A configuration failed.\n");
348   - return ret;
  352 + goto out;
349 353 } else
350   - printf("IDT8T49N222A configured.\n");
  354 + debug("IDT8T49N222A configured.\n");
351 355 } else {
352   - return ret;
  356 + goto out;
353 357 }
354 358 select_i2c_ch_pca(I2C_CH_DEFAULT);
355 359  
356 360  
357 361  
358 362  
... ... @@ -400,16 +404,99 @@
400 404 printf("WARNING:IDT8T49N222A configuration not"
401 405 " supported for:%x SerDes1 Protocol.\n",
402 406 serdes1_prtcl);
403   - return -1;
404 407 }
405 408  
406   - return 0;
  409 +out:
  410 + /* Clearing SRDS_RST_MSK bit as now
  411 + * SerDes reset event can cause a reset request
  412 + */
  413 + clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
  414 + return ret;
407 415 }
408 416  
  417 +int config_serdes2_refclks(void)
  418 +{
  419 + ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  420 + serdes_corenet_t *srds2_regs =
  421 + (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
  422 + u32 serdes2_prtcl;
  423 + int ret = 0;
  424 + int i;
  425 +
  426 + serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
  427 + FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
  428 + if (!serdes2_prtcl) {
  429 + debug("SERDES2 is not enabled\n");
  430 + return -ENODEV;
  431 + }
  432 + serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
  433 + debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
  434 +
  435 + /* To prevent generation of reset request from SerDes
  436 + * while changing the refclks, By setting SRDS_RST_MSK bit,
  437 + * SerDes reset event cannot cause a reset request
  438 + */
  439 + setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
  440 +
  441 + /* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
  442 + * For this SerDes2's Refclk1 need to be set to 100MHz
  443 + */
  444 + switch (serdes2_prtcl) {
  445 + case 0x9E:
  446 + case 0x9A:
  447 + case 0xb2:
  448 + debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
  449 + serdes2_prtcl);
  450 + ret = select_i2c_ch_pca(I2C_CH_IDT);
  451 + if (!ret) {
  452 + ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
  453 + SERDES_REFCLK_100,
  454 + SERDES_REFCLK_100, 0);
  455 + if (ret) {
  456 + printf("IDT8T49N222A configuration failed.\n");
  457 + goto out;
  458 + } else
  459 + debug("IDT8T49N222A configured.\n");
  460 + } else {
  461 + goto out;
  462 + }
  463 + select_i2c_ch_pca(I2C_CH_DEFAULT);
  464 +
  465 + /* Steps For SerDes PLLs reset and reconfiguration after
  466 + * changing SerDes's refclks
  467 + */
  468 + for (i = 0; i < PLL_NUM; i++) {
  469 + clrbits_be32(&srds2_regs->bank[i].rstctl,
  470 + SRDS_RSTCTL_SDRST_B);
  471 + udelay(10);
  472 + clrbits_be32(&srds2_regs->bank[i].rstctl,
  473 + (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
  474 + udelay(10);
  475 + setbits_be32(&srds2_regs->bank[i].rstctl,
  476 + SRDS_RSTCTL_RST);
  477 + setbits_be32(&srds2_regs->bank[i].rstctl,
  478 + (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
  479 + | SRDS_RSTCTL_SDRST_B));
  480 + }
  481 + break;
  482 + default:
  483 + printf("IDT configuration not supported for:%x S2 Protocol.\n",
  484 + serdes2_prtcl);
  485 + }
  486 +
  487 +out:
  488 + /* Clearing SRDS_RST_MSK bit as now
  489 + * SerDes reset event can cause a reset request
  490 + */
  491 + clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
  492 + return ret;
  493 +}
  494 +
409 495 int board_early_init_r(void)
410 496 {
411 497 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
412 498 const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);
  499 + int ret;
413 500  
414 501 /*
415 502 * Remap Boot flash + PROMJET region to caching-inhibited
... ... @@ -441,6 +528,20 @@
441 528 printf("SerDes1 Refclks couldn't set properly.\n");
442 529 else
443 530 printf("SerDes1 Refclks have been set.\n");
  531 +
  532 + /* SerDes2 refclks need to be set again, as default clks
  533 + * are not suitable for PCIe SATA to work
  534 + * This function will set SerDes2's Refclk1 and refclk2
  535 + * for SerDes2 protocols having PCIe in them
  536 + * for PCIe SATA to work
  537 + */
  538 + ret = config_serdes2_refclks();
  539 + if (!ret)
  540 + printf("SerDes2 Refclks have been set.\n");
  541 + else if (ret == -ENODEV)
  542 + printf("SerDes disable, Refclks couldn't change.\n");
  543 + else
  544 + printf("SerDes2 Refclk reconfiguring failed.\n");
444 545  
445 546 /* Configure VSC3316 and VSC3308 crossbar switches */
446 547 if (configure_vsc3316_3308())