static int brcm_stb_sata_16nm_ssc_init()

in broadcom/phy-brcm-sata.c [312:415]


static int brcm_stb_sata_16nm_ssc_init(struct brcm_sata_port *port)
{
	u32 tmp, value;

	/* 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 proportional loop bandwith Gen1/2/3 */
	tmp = RXPMD_G_CDR_PROP_BW_MASK << RXPMD_G1_CDR_PROP_BW_SHIFT |
	      RXPMD_G_CDR_PROP_BW_MASK << RXPMD_G2_CDR_PROP_BW_SHIFT |
	      RXPMD_G_CDR_PROP_BW_MASK << RXPMD_G3_CDR_PROB_BW_SHIFT;
	if (port->ssc_en)
		value = 2 << RXPMD_G1_CDR_PROP_BW_SHIFT |
			2 << RXPMD_G2_CDR_PROP_BW_SHIFT |
			2 << RXPMD_G3_CDR_PROB_BW_SHIFT;
	else
		value = 1 << RXPMD_G1_CDR_PROP_BW_SHIFT |
			1 << RXPMD_G2_CDR_PROP_BW_SHIFT |
			1 << RXPMD_G3_CDR_PROB_BW_SHIFT;
	brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_PROP_BW, ~tmp,
			 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);

	/* Turn on/off SSC */
	brcm_sata_phy_wr(port, TX_REG_BANK, TX_ACTRL5, ~TX_ACTRL5_SSC_EN,
			 port->ssc_en ? TX_ACTRL5_SSC_EN : 0);

	return 0;
}