Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: brcm-sata: Add BCM63138 (DSL) PHY init sequence

The BCM63138 SATA PHY requires a special initialization sequence in
order to operate correctly, mostly tuning incorrect default values.
Implement that sequence and match the documented compatible string as an
entry point into that sequence.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

authored by

Florian Fainelli and committed by
Kishon Vijay Abraham I
7b69fa1c 26728df4

+70
+70
drivers/phy/broadcom/phy-brcm-sata.c
··· 47 47 BRCM_SATA_PHY_IPROC_NS2, 48 48 BRCM_SATA_PHY_IPROC_NSP, 49 49 BRCM_SATA_PHY_IPROC_SR, 50 + BRCM_SATA_PHY_DSL_28NM, 50 51 }; 51 52 52 53 enum brcm_sata_phy_rxaeq_mode { ··· 97 96 PLLCONTROL_0_FREQ_DET_RESTART = BIT(13), 98 97 PLLCONTROL_0_FREQ_MONITOR = BIT(12), 99 98 PLLCONTROL_0_SEQ_START = BIT(15), 99 + PLL_CAP_CHARGE_TIME = 0x83, 100 + PLL_VCO_CAL_THRESH = 0x84, 100 101 PLL_CAP_CONTROL = 0x85, 102 + PLL_FREQ_DET_TIME = 0x86, 101 103 PLL_ACTRL2 = 0x8b, 102 104 PLL_ACTRL2_SELDIV_MASK = 0x1f, 103 105 PLL_ACTRL2_SELDIV_SHIFT = 9, ··· 110 106 PLL1_ACTRL2 = 0x82, 111 107 PLL1_ACTRL3 = 0x83, 112 108 PLL1_ACTRL4 = 0x84, 109 + PLL1_ACTRL5 = 0x85, 110 + PLL1_ACTRL6 = 0x86, 111 + PLL1_ACTRL7 = 0x87, 113 112 114 113 TX_REG_BANK = 0x070, 115 114 TX_ACTRL0 = 0x80, ··· 126 119 AEQ_FRC_EQ_FORCE = BIT(0), 127 120 AEQ_FRC_EQ_FORCE_VAL = BIT(1), 128 121 AEQRX_REG_BANK_1 = 0xe0, 122 + AEQRX_SLCAL0_CTRL0 = 0x82, 123 + AEQRX_SLCAL1_CTRL0 = 0x86, 129 124 130 125 OOB_REG_BANK = 0x150, 131 126 OOB1_REG_BANK = 0x160, ··· 177 168 switch (priv->version) { 178 169 case BRCM_SATA_PHY_STB_28NM: 179 170 case BRCM_SATA_PHY_IPROC_NS2: 171 + case BRCM_SATA_PHY_DSL_28NM: 180 172 size = SATA_PCB_REG_28NM_SPACE_SIZE; 181 173 break; 182 174 case BRCM_SATA_PHY_STB_40NM: ··· 492 482 return 0; 493 483 } 494 484 485 + static int brcm_dsl_sata_init(struct brcm_sata_port *port) 486 + { 487 + void __iomem *base = brcm_sata_pcb_base(port); 488 + struct device *dev = port->phy_priv->dev; 489 + unsigned int try; 490 + u32 tmp; 491 + 492 + brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL7, 0, 0x873); 493 + 494 + brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL6, 0, 0xc000); 495 + 496 + brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0, 497 + 0, 0x3089); 498 + usleep_range(1000, 2000); 499 + 500 + brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0, 501 + 0, 0x3088); 502 + usleep_range(1000, 2000); 503 + 504 + brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, AEQRX_SLCAL0_CTRL0, 505 + 0, 0x3000); 506 + 507 + brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, AEQRX_SLCAL1_CTRL0, 508 + 0, 0x3000); 509 + usleep_range(1000, 2000); 510 + 511 + brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_CAP_CHARGE_TIME, 0, 0x32); 512 + 513 + brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_VCO_CAL_THRESH, 0, 0xa); 514 + 515 + brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_FREQ_DET_TIME, 0, 0x64); 516 + usleep_range(1000, 2000); 517 + 518 + /* Acquire PLL lock */ 519 + try = 50; 520 + while (try) { 521 + tmp = brcm_sata_phy_rd(base, BLOCK0_REG_BANK, 522 + BLOCK0_XGXSSTATUS); 523 + if (tmp & BLOCK0_XGXSSTATUS_PLL_LOCK) 524 + break; 525 + msleep(20); 526 + try--; 527 + }; 528 + 529 + if (!try) { 530 + /* PLL did not lock; give up */ 531 + dev_err(dev, "port%d PLL did not lock\n", port->portnum); 532 + return -ETIMEDOUT; 533 + } 534 + 535 + dev_dbg(dev, "port%d initialized\n", port->portnum); 536 + 537 + return 0; 538 + } 539 + 495 540 static int brcm_sata_phy_init(struct phy *phy) 496 541 { 497 542 int rc; ··· 565 500 break; 566 501 case BRCM_SATA_PHY_IPROC_SR: 567 502 rc = brcm_sr_sata_init(port); 503 + break; 504 + case BRCM_SATA_PHY_DSL_28NM: 505 + rc = brcm_dsl_sata_init(port); 568 506 break; 569 507 default: 570 508 rc = -ENODEV; ··· 620 552 .data = (void *)BRCM_SATA_PHY_IPROC_NSP }, 621 553 { .compatible = "brcm,iproc-sr-sata-phy", 622 554 .data = (void *)BRCM_SATA_PHY_IPROC_SR }, 555 + { .compatible = "brcm,bcm63138-sata-phy", 556 + .data = (void *)BRCM_SATA_PHY_DSL_28NM }, 623 557 {}, 624 558 }; 625 559 MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);