/* Register offset between PHYs in PCB space */ #define SATA_PCB_REG_28NM_SPACE_SIZE 0x1000
/* The older SATA PHY registers duplicated per port registers within the map, * rather than having a separate map per port.
*/ #define SATA_PCB_REG_40NM_SPACE_SIZE 0x10
/* Register offset between PHYs in PHY control space */ #define SATA_PHY_CTRL_REG_28NM_SPACE_SIZE 0x8
/* These defaults were characterized by H/W group */ #define STB_FMIN_VAL_DEFAULT 0x3df #define STB_FMAX_VAL_DEFAULT 0x3df #define STB_FMAX_VAL_SSC 0x83
/* Reduce CP tail current to 1/16th of its default value */
brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL6, 0, 0x141);
/* Turn off CP tail current boost */
brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL8, 0, 0xc006);
/* Set a specific AEQ equalizer value */
tmp = AEQ_FRC_EQ_FORCE_VAL | AEQ_FRC_EQ_FORCE;
brcm_sata_phy_wr(port, AEQRX_REG_BANK_0, AEQ_FRC_EQ,
~(tmp | AEQ_RFZ_FRC_VAL |
AEQ_FRC_EQ_VAL_MASK << AEQ_FRC_EQ_VAL_SHIFT),
tmp | 32 << AEQ_FRC_EQ_VAL_SHIFT);
/* Set RX PPM val center frequency */ if (port->ssc_en)
value = 0x52; else
value = 0;
brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_CDR_CONTROL1,
~RXPMD_RX_PPM_VAL_MASK, value);
/* Set CDR integral loop acquisition bandwidth for Gen1/2/3 */
tmp = RXPMD_G_CDR_ACQ_INT_BW_MASK << RXPMD_G1_CDR_ACQ_INT_BW_SHIFT |
RXPMD_G_CDR_ACQ_INT_BW_MASK << RXPMD_G2_CDR_ACQ_INT_BW_SHIFT |
RXPMD_G_CDR_ACQ_INT_BW_MASK << RXPMD_G3_CDR_ACQ_INT_BW_SHIFT; if (port->ssc_en)
value = 1 << RXPMD_G1_CDR_ACQ_INT_BW_SHIFT |
1 << RXPMD_G2_CDR_ACQ_INT_BW_SHIFT |
1 << RXPMD_G3_CDR_ACQ_INT_BW_SHIFT; else
value = 0;
brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_ACQ_INTEG_BW,
~tmp, value);
/* Set CDR integral loop locking bandwidth to 1 for Gen 1/2/3 */
tmp = RXPMD_G_CDR_LOCK_INT_BW_MASK << RXPMD_G1_CDR_LOCK_INT_BW_SHIFT |
RXPMD_G_CDR_LOCK_INT_BW_MASK << RXPMD_G2_CDR_LOCK_INT_BW_SHIFT |
RXPMD_G_CDR_LOCK_INT_BW_MASK << RXPMD_G3_CDR_LOCK_INT_BW_SHIFT; if (port->ssc_en)
value = 1 << RXPMD_G1_CDR_LOCK_INT_BW_SHIFT |
1 << RXPMD_G2_CDR_LOCK_INT_BW_SHIFT |
1 << RXPMD_G3_CDR_LOCK_INT_BW_SHIFT; else
value = 0;
brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_LOCK_INTEG_BW,
~tmp, value);
/* Set no guard band and clamp CDR */
tmp = RXPMD_MON_CORRECT_EN | RXPMD_MON_MARGIN_VAL_MASK; if (port->ssc_en)
value = 0x51; else
value = 0;
brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1,
~tmp, RXPMD_MON_CORRECT_EN | value);
tmp = GENMASK(15, 12); switch (port->tx_amplitude_val) { case 400:
value = BIT(12) | BIT(13); break; case 500:
value = BIT(13); break; case 600:
value = BIT(12); break; case 800:
value = 0; break; default:
value = tmp; break;
}
if (value != tmp)
brcm_sata_phy_wr(port, BLOCK1_REG_BANK, BLOCK1_TEST_TX, ~tmp,
value);
/* NS2 SATA PLL1 defaults were characterized by H/W group */ #define NS2_PLL1_ACTRL2_MAGIC 0x1df8 #define NS2_PLL1_ACTRL3_MAGIC 0x2b00 #define NS2_PLL1_ACTRL4_MAGIC 0x8824
/* Configure OOB control */
val = 0x0;
val |= (0xc << OOB_CTRL1_BURST_MAX_SHIFT);
val |= (0x4 << OOB_CTRL1_BURST_MIN_SHIFT);
val |= (0x9 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT);
val |= (0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT);
brcm_sata_phy_wr(port, OOB_REG_BANK, OOB_CTRL1, 0x0, val);
val = 0x0;
val |= (0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT);
val |= (0x2 << OOB_CTRL2_BURST_CNT_SHIFT);
val |= (0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT);
brcm_sata_phy_wr(port, OOB_REG_BANK, OOB_CTRL2, 0x0, val);
/* Configure PHY PLL register bank 1 */
val = NS2_PLL1_ACTRL2_MAGIC;
brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
val = NS2_PLL1_ACTRL3_MAGIC;
brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
val = NS2_PLL1_ACTRL4_MAGIC;
brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
/* Configure PHY BLOCK0 register bank */ /* Set oob_clk_sel to refclk/2 */
brcm_sata_phy_wr(port, BLOCK0_REG_BANK, BLOCK0_SPARE,
~BLOCK0_SPARE_OOB_CLK_SEL_MASK,
BLOCK0_SPARE_OOB_CLK_SEL_REFBY2);
/* Strobe PHY reset using PHY control register */
writel(PHY_CTRL_1_RESET, ctrl_base + PHY_CTRL_1);
mdelay(1);
writel(0x0, ctrl_base + PHY_CTRL_1);
mdelay(1);
/* Wait for PHY PLL lock by polling pll_lock bit */ try = 50; while (try) {
val = brcm_sata_phy_rd(port, BLOCK0_REG_BANK,
BLOCK0_XGXSSTATUS); if (val & BLOCK0_XGXSSTATUS_PLL_LOCK) break;
msleep(20);
try--;
} if (!try) { /* PLL did not lock; give up */
dev_err(dev, "port%d PLL did not lock\n", port->portnum); return -ETIMEDOUT;
}
/* Wait for pll_seq_done bit */ try = 50; while (--try) {
val = brcm_sata_phy_rd(port, BLOCK0_REG_BANK,
BLOCK0_XGXSSTATUS); if (val & BLOCK0_XGXSSTATUS_PLL_LOCK) break;
msleep(20);
} if (!try) { /* PLL did not lock; give up */
dev_err(dev, "port%d PLL did not lock\n", port->portnum); return -ETIMEDOUT;
}
/* Configure PHY PLL register bank 1 */
val = SR_PLL1_ACTRL2_MAGIC;
brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
val = SR_PLL1_ACTRL3_MAGIC;
brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
val = SR_PLL1_ACTRL4_MAGIC;
brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
/* Configure PHY PLL register bank 0 */
val = SR_PLL0_ACTRL6_MAGIC;
brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_ACTRL6, 0x0, val);
/* Wait for PHY PLL lock by polling pll_lock bit */ try = 50; do {
val = brcm_sata_phy_rd(port, BLOCK0_REG_BANK,
BLOCK0_XGXSSTATUS); if (val & BLOCK0_XGXSSTATUS_PLL_LOCK) break;
msleep(20);
try--;
} while (try);
if ((val & BLOCK0_XGXSSTATUS_PLL_LOCK) == 0) { /* PLL did not lock; give up */
dev_err(dev, "port%d PLL did not lock\n", port->portnum); return -ETIMEDOUT;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.