cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

phy-brcm-sata.c (23367B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Broadcom SATA3 AHCI Controller PHY Driver
      4 *
      5 * Copyright (C) 2016 Broadcom
      6 */
      7
      8#include <linux/delay.h>
      9#include <linux/device.h>
     10#include <linux/init.h>
     11#include <linux/interrupt.h>
     12#include <linux/io.h>
     13#include <linux/kernel.h>
     14#include <linux/module.h>
     15#include <linux/of.h>
     16#include <linux/phy/phy.h>
     17#include <linux/platform_device.h>
     18
     19#define SATA_PCB_BANK_OFFSET				0x23c
     20#define SATA_PCB_REG_OFFSET(ofs)			((ofs) * 4)
     21
     22#define MAX_PORTS					2
     23
     24/* Register offset between PHYs in PCB space */
     25#define SATA_PCB_REG_28NM_SPACE_SIZE			0x1000
     26
     27/* The older SATA PHY registers duplicated per port registers within the map,
     28 * rather than having a separate map per port.
     29 */
     30#define SATA_PCB_REG_40NM_SPACE_SIZE			0x10
     31
     32/* Register offset between PHYs in PHY control space */
     33#define SATA_PHY_CTRL_REG_28NM_SPACE_SIZE		0x8
     34
     35enum brcm_sata_phy_version {
     36	BRCM_SATA_PHY_STB_16NM,
     37	BRCM_SATA_PHY_STB_28NM,
     38	BRCM_SATA_PHY_STB_40NM,
     39	BRCM_SATA_PHY_IPROC_NS2,
     40	BRCM_SATA_PHY_IPROC_NSP,
     41	BRCM_SATA_PHY_IPROC_SR,
     42	BRCM_SATA_PHY_DSL_28NM,
     43};
     44
     45enum brcm_sata_phy_rxaeq_mode {
     46	RXAEQ_MODE_OFF = 0,
     47	RXAEQ_MODE_AUTO,
     48	RXAEQ_MODE_MANUAL,
     49};
     50
     51static enum brcm_sata_phy_rxaeq_mode rxaeq_to_val(const char *m)
     52{
     53	if (!strcmp(m, "auto"))
     54		return RXAEQ_MODE_AUTO;
     55	else if (!strcmp(m, "manual"))
     56		return RXAEQ_MODE_MANUAL;
     57	else
     58		return RXAEQ_MODE_OFF;
     59}
     60
     61struct brcm_sata_port {
     62	int portnum;
     63	struct phy *phy;
     64	struct brcm_sata_phy *phy_priv;
     65	bool ssc_en;
     66	enum brcm_sata_phy_rxaeq_mode rxaeq_mode;
     67	u32 rxaeq_val;
     68	u32 tx_amplitude_val;
     69};
     70
     71struct brcm_sata_phy {
     72	struct device *dev;
     73	void __iomem *phy_base;
     74	void __iomem *ctrl_base;
     75	enum brcm_sata_phy_version version;
     76
     77	struct brcm_sata_port phys[MAX_PORTS];
     78};
     79
     80enum sata_phy_regs {
     81	BLOCK0_REG_BANK				= 0x000,
     82	BLOCK0_XGXSSTATUS			= 0x81,
     83	BLOCK0_XGXSSTATUS_PLL_LOCK		= BIT(12),
     84	BLOCK0_SPARE				= 0x8d,
     85	BLOCK0_SPARE_OOB_CLK_SEL_MASK		= 0x3,
     86	BLOCK0_SPARE_OOB_CLK_SEL_REFBY2		= 0x1,
     87
     88	BLOCK1_REG_BANK				= 0x10,
     89	BLOCK1_TEST_TX				= 0x83,
     90	BLOCK1_TEST_TX_AMP_SHIFT		= 12,
     91
     92	PLL_REG_BANK_0				= 0x050,
     93	PLL_REG_BANK_0_PLLCONTROL_0		= 0x81,
     94	PLLCONTROL_0_FREQ_DET_RESTART		= BIT(13),
     95	PLLCONTROL_0_FREQ_MONITOR		= BIT(12),
     96	PLLCONTROL_0_SEQ_START			= BIT(15),
     97	PLL_CAP_CHARGE_TIME			= 0x83,
     98	PLL_VCO_CAL_THRESH			= 0x84,
     99	PLL_CAP_CONTROL				= 0x85,
    100	PLL_FREQ_DET_TIME			= 0x86,
    101	PLL_ACTRL2				= 0x8b,
    102	PLL_ACTRL2_SELDIV_MASK			= 0x1f,
    103	PLL_ACTRL2_SELDIV_SHIFT			= 9,
    104	PLL_ACTRL6				= 0x86,
    105
    106	PLL1_REG_BANK				= 0x060,
    107	PLL1_ACTRL2				= 0x82,
    108	PLL1_ACTRL3				= 0x83,
    109	PLL1_ACTRL4				= 0x84,
    110	PLL1_ACTRL5				= 0x85,
    111	PLL1_ACTRL6				= 0x86,
    112	PLL1_ACTRL7				= 0x87,
    113	PLL1_ACTRL8				= 0x88,
    114
    115	TX_REG_BANK				= 0x070,
    116	TX_ACTRL0				= 0x80,
    117	TX_ACTRL0_TXPOL_FLIP			= BIT(6),
    118	TX_ACTRL5				= 0x85,
    119	TX_ACTRL5_SSC_EN			= BIT(11),
    120
    121	AEQRX_REG_BANK_0			= 0xd0,
    122	AEQ_CONTROL1				= 0x81,
    123	AEQ_CONTROL1_ENABLE			= BIT(2),
    124	AEQ_CONTROL1_FREEZE			= BIT(3),
    125	AEQ_FRC_EQ				= 0x83,
    126	AEQ_FRC_EQ_FORCE			= BIT(0),
    127	AEQ_FRC_EQ_FORCE_VAL			= BIT(1),
    128	AEQ_RFZ_FRC_VAL				= BIT(8),
    129	AEQRX_REG_BANK_1			= 0xe0,
    130	AEQRX_SLCAL0_CTRL0			= 0x82,
    131	AEQRX_SLCAL1_CTRL0			= 0x86,
    132
    133	OOB_REG_BANK				= 0x150,
    134	OOB1_REG_BANK				= 0x160,
    135	OOB_CTRL1				= 0x80,
    136	OOB_CTRL1_BURST_MAX_MASK		= 0xf,
    137	OOB_CTRL1_BURST_MAX_SHIFT		= 12,
    138	OOB_CTRL1_BURST_MIN_MASK		= 0xf,
    139	OOB_CTRL1_BURST_MIN_SHIFT		= 8,
    140	OOB_CTRL1_WAKE_IDLE_MAX_MASK		= 0xf,
    141	OOB_CTRL1_WAKE_IDLE_MAX_SHIFT		= 4,
    142	OOB_CTRL1_WAKE_IDLE_MIN_MASK		= 0xf,
    143	OOB_CTRL1_WAKE_IDLE_MIN_SHIFT		= 0,
    144	OOB_CTRL2				= 0x81,
    145	OOB_CTRL2_SEL_ENA_SHIFT			= 15,
    146	OOB_CTRL2_SEL_ENA_RC_SHIFT		= 14,
    147	OOB_CTRL2_RESET_IDLE_MAX_MASK		= 0x3f,
    148	OOB_CTRL2_RESET_IDLE_MAX_SHIFT		= 8,
    149	OOB_CTRL2_BURST_CNT_MASK		= 0x3,
    150	OOB_CTRL2_BURST_CNT_SHIFT		= 6,
    151	OOB_CTRL2_RESET_IDLE_MIN_MASK		= 0x3f,
    152	OOB_CTRL2_RESET_IDLE_MIN_SHIFT		= 0,
    153
    154	TXPMD_REG_BANK				= 0x1a0,
    155	TXPMD_CONTROL1				= 0x81,
    156	TXPMD_CONTROL1_TX_SSC_EN_FRC		= BIT(0),
    157	TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL	= BIT(1),
    158	TXPMD_TX_FREQ_CTRL_CONTROL1		= 0x82,
    159	TXPMD_TX_FREQ_CTRL_CONTROL2		= 0x83,
    160	TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK	= 0x3ff,
    161	TXPMD_TX_FREQ_CTRL_CONTROL3		= 0x84,
    162	TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK	= 0x3ff,
    163
    164	RXPMD_REG_BANK				= 0x1c0,
    165	RXPMD_RX_CDR_CONTROL1			= 0x81,
    166	RXPMD_RX_PPM_VAL_MASK			= 0x1ff,
    167	RXPMD_RXPMD_EN_FRC			= BIT(12),
    168	RXPMD_RXPMD_EN_FRC_VAL			= BIT(13),
    169	RXPMD_RX_CDR_CDR_PROP_BW		= 0x82,
    170	RXPMD_G_CDR_PROP_BW_MASK		= 0x7,
    171	RXPMD_G1_CDR_PROP_BW_SHIFT		= 0,
    172	RXPMD_G2_CDR_PROP_BW_SHIFT		= 3,
    173	RXPMD_G3_CDR_PROB_BW_SHIFT		= 6,
    174	RXPMD_RX_CDR_CDR_ACQ_INTEG_BW		= 0x83,
    175	RXPMD_G_CDR_ACQ_INT_BW_MASK		= 0x7,
    176	RXPMD_G1_CDR_ACQ_INT_BW_SHIFT		= 0,
    177	RXPMD_G2_CDR_ACQ_INT_BW_SHIFT		= 3,
    178	RXPMD_G3_CDR_ACQ_INT_BW_SHIFT		= 6,
    179	RXPMD_RX_CDR_CDR_LOCK_INTEG_BW		= 0x84,
    180	RXPMD_G_CDR_LOCK_INT_BW_MASK		= 0x7,
    181	RXPMD_G1_CDR_LOCK_INT_BW_SHIFT		= 0,
    182	RXPMD_G2_CDR_LOCK_INT_BW_SHIFT		= 3,
    183	RXPMD_G3_CDR_LOCK_INT_BW_SHIFT		= 6,
    184	RXPMD_RX_FREQ_MON_CONTROL1		= 0x87,
    185	RXPMD_MON_CORRECT_EN			= BIT(8),
    186	RXPMD_MON_MARGIN_VAL_MASK		= 0xff,
    187};
    188
    189enum sata_phy_ctrl_regs {
    190	PHY_CTRL_1				= 0x0,
    191	PHY_CTRL_1_RESET			= BIT(0),
    192};
    193
    194static inline void __iomem *brcm_sata_ctrl_base(struct brcm_sata_port *port)
    195{
    196	struct brcm_sata_phy *priv = port->phy_priv;
    197	u32 size = 0;
    198
    199	switch (priv->version) {
    200	case BRCM_SATA_PHY_IPROC_NS2:
    201		size = SATA_PHY_CTRL_REG_28NM_SPACE_SIZE;
    202		break;
    203	default:
    204		dev_err(priv->dev, "invalid phy version\n");
    205		break;
    206	}
    207
    208	return priv->ctrl_base + (port->portnum * size);
    209}
    210
    211static void brcm_sata_phy_wr(struct brcm_sata_port *port, u32 bank,
    212			     u32 ofs, u32 msk, u32 value)
    213{
    214	struct brcm_sata_phy *priv = port->phy_priv;
    215	void __iomem *pcb_base = priv->phy_base;
    216	u32 tmp;
    217
    218	if (priv->version == BRCM_SATA_PHY_STB_40NM)
    219		bank += (port->portnum * SATA_PCB_REG_40NM_SPACE_SIZE);
    220	else
    221		pcb_base += (port->portnum * SATA_PCB_REG_28NM_SPACE_SIZE);
    222
    223	writel(bank, pcb_base + SATA_PCB_BANK_OFFSET);
    224	tmp = readl(pcb_base + SATA_PCB_REG_OFFSET(ofs));
    225	tmp = (tmp & msk) | value;
    226	writel(tmp, pcb_base + SATA_PCB_REG_OFFSET(ofs));
    227}
    228
    229static u32 brcm_sata_phy_rd(struct brcm_sata_port *port, u32 bank, u32 ofs)
    230{
    231	struct brcm_sata_phy *priv = port->phy_priv;
    232	void __iomem *pcb_base = priv->phy_base;
    233
    234	if (priv->version == BRCM_SATA_PHY_STB_40NM)
    235		bank += (port->portnum * SATA_PCB_REG_40NM_SPACE_SIZE);
    236	else
    237		pcb_base += (port->portnum * SATA_PCB_REG_28NM_SPACE_SIZE);
    238
    239	writel(bank, pcb_base + SATA_PCB_BANK_OFFSET);
    240	return readl(pcb_base + SATA_PCB_REG_OFFSET(ofs));
    241}
    242
    243/* These defaults were characterized by H/W group */
    244#define STB_FMIN_VAL_DEFAULT	0x3df
    245#define STB_FMAX_VAL_DEFAULT	0x3df
    246#define STB_FMAX_VAL_SSC	0x83
    247
    248static void brcm_stb_sata_ssc_init(struct brcm_sata_port *port)
    249{
    250	struct brcm_sata_phy *priv = port->phy_priv;
    251	u32 tmp;
    252
    253	/* override the TX spread spectrum setting */
    254	tmp = TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL | TXPMD_CONTROL1_TX_SSC_EN_FRC;
    255	brcm_sata_phy_wr(port, TXPMD_REG_BANK, TXPMD_CONTROL1, ~tmp, tmp);
    256
    257	/* set fixed min freq */
    258	brcm_sata_phy_wr(port, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL2,
    259			 ~TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK,
    260			 STB_FMIN_VAL_DEFAULT);
    261
    262	/* set fixed max freq depending on SSC config */
    263	if (port->ssc_en) {
    264		dev_info(priv->dev, "enabling SSC on port%d\n", port->portnum);
    265		tmp = STB_FMAX_VAL_SSC;
    266	} else {
    267		tmp = STB_FMAX_VAL_DEFAULT;
    268	}
    269
    270	brcm_sata_phy_wr(port, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL3,
    271			  ~TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK, tmp);
    272}
    273
    274#define AEQ_FRC_EQ_VAL_SHIFT	2
    275#define AEQ_FRC_EQ_VAL_MASK	0x3f
    276
    277static int brcm_stb_sata_rxaeq_init(struct brcm_sata_port *port)
    278{
    279	u32 tmp = 0, reg = 0;
    280
    281	switch (port->rxaeq_mode) {
    282	case RXAEQ_MODE_OFF:
    283		return 0;
    284
    285	case RXAEQ_MODE_AUTO:
    286		reg = AEQ_CONTROL1;
    287		tmp = AEQ_CONTROL1_ENABLE | AEQ_CONTROL1_FREEZE;
    288		break;
    289
    290	case RXAEQ_MODE_MANUAL:
    291		reg = AEQ_FRC_EQ;
    292		tmp = AEQ_FRC_EQ_FORCE | AEQ_FRC_EQ_FORCE_VAL;
    293		if (port->rxaeq_val > AEQ_FRC_EQ_VAL_MASK)
    294			return -EINVAL;
    295		tmp |= port->rxaeq_val << AEQ_FRC_EQ_VAL_SHIFT;
    296		break;
    297	}
    298
    299	brcm_sata_phy_wr(port, AEQRX_REG_BANK_0, reg, ~tmp, tmp);
    300	brcm_sata_phy_wr(port, AEQRX_REG_BANK_1, reg, ~tmp, tmp);
    301
    302	return 0;
    303}
    304
    305static int brcm_stb_sata_init(struct brcm_sata_port *port)
    306{
    307	brcm_stb_sata_ssc_init(port);
    308
    309	return brcm_stb_sata_rxaeq_init(port);
    310}
    311
    312static int brcm_stb_sata_16nm_ssc_init(struct brcm_sata_port *port)
    313{
    314	u32 tmp, value;
    315
    316	/* Reduce CP tail current to 1/16th of its default value */
    317	brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL6, 0, 0x141);
    318
    319	/* Turn off CP tail current boost */
    320	brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL8, 0, 0xc006);
    321
    322	/* Set a specific AEQ equalizer value */
    323	tmp = AEQ_FRC_EQ_FORCE_VAL | AEQ_FRC_EQ_FORCE;
    324	brcm_sata_phy_wr(port, AEQRX_REG_BANK_0, AEQ_FRC_EQ,
    325			 ~(tmp | AEQ_RFZ_FRC_VAL |
    326			   AEQ_FRC_EQ_VAL_MASK << AEQ_FRC_EQ_VAL_SHIFT),
    327			 tmp | 32 << AEQ_FRC_EQ_VAL_SHIFT);
    328
    329	/* Set RX PPM val center frequency */
    330	if (port->ssc_en)
    331		value = 0x52;
    332	else
    333		value = 0;
    334	brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_CDR_CONTROL1,
    335			 ~RXPMD_RX_PPM_VAL_MASK, value);
    336
    337	/* Set proportional loop bandwith Gen1/2/3 */
    338	tmp = RXPMD_G_CDR_PROP_BW_MASK << RXPMD_G1_CDR_PROP_BW_SHIFT |
    339	      RXPMD_G_CDR_PROP_BW_MASK << RXPMD_G2_CDR_PROP_BW_SHIFT |
    340	      RXPMD_G_CDR_PROP_BW_MASK << RXPMD_G3_CDR_PROB_BW_SHIFT;
    341	if (port->ssc_en)
    342		value = 2 << RXPMD_G1_CDR_PROP_BW_SHIFT |
    343			2 << RXPMD_G2_CDR_PROP_BW_SHIFT |
    344			2 << RXPMD_G3_CDR_PROB_BW_SHIFT;
    345	else
    346		value = 1 << RXPMD_G1_CDR_PROP_BW_SHIFT |
    347			1 << RXPMD_G2_CDR_PROP_BW_SHIFT |
    348			1 << RXPMD_G3_CDR_PROB_BW_SHIFT;
    349	brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_PROP_BW, ~tmp,
    350			 value);
    351
    352	/* Set CDR integral loop acquisition bandwidth for Gen1/2/3 */
    353	tmp = RXPMD_G_CDR_ACQ_INT_BW_MASK << RXPMD_G1_CDR_ACQ_INT_BW_SHIFT |
    354	      RXPMD_G_CDR_ACQ_INT_BW_MASK << RXPMD_G2_CDR_ACQ_INT_BW_SHIFT |
    355	      RXPMD_G_CDR_ACQ_INT_BW_MASK << RXPMD_G3_CDR_ACQ_INT_BW_SHIFT;
    356	if (port->ssc_en)
    357		value = 1 << RXPMD_G1_CDR_ACQ_INT_BW_SHIFT |
    358			1 << RXPMD_G2_CDR_ACQ_INT_BW_SHIFT |
    359			1 << RXPMD_G3_CDR_ACQ_INT_BW_SHIFT;
    360	else
    361		value = 0;
    362	brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_ACQ_INTEG_BW,
    363			 ~tmp, value);
    364
    365	/* Set CDR integral loop locking bandwidth to 1 for Gen 1/2/3 */
    366	tmp = RXPMD_G_CDR_LOCK_INT_BW_MASK << RXPMD_G1_CDR_LOCK_INT_BW_SHIFT |
    367	      RXPMD_G_CDR_LOCK_INT_BW_MASK << RXPMD_G2_CDR_LOCK_INT_BW_SHIFT |
    368	      RXPMD_G_CDR_LOCK_INT_BW_MASK << RXPMD_G3_CDR_LOCK_INT_BW_SHIFT;
    369	if (port->ssc_en)
    370		value = 1 << RXPMD_G1_CDR_LOCK_INT_BW_SHIFT |
    371			1 << RXPMD_G2_CDR_LOCK_INT_BW_SHIFT |
    372			1 << RXPMD_G3_CDR_LOCK_INT_BW_SHIFT;
    373	else
    374		value = 0;
    375	brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_LOCK_INTEG_BW,
    376			 ~tmp, value);
    377
    378	/* Set no guard band and clamp CDR */
    379	tmp = RXPMD_MON_CORRECT_EN | RXPMD_MON_MARGIN_VAL_MASK;
    380	if (port->ssc_en)
    381		value = 0x51;
    382	else
    383		value = 0;
    384	brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1,
    385			 ~tmp, RXPMD_MON_CORRECT_EN | value);
    386
    387	tmp = GENMASK(15, 12);
    388	switch (port->tx_amplitude_val) {
    389	case 400:
    390		value = BIT(12) | BIT(13);
    391		break;
    392	case 500:
    393		value = BIT(13);
    394		break;
    395	case 600:
    396		value = BIT(12);
    397		break;
    398	case 800:
    399		value = 0;
    400		break;
    401	default:
    402		value = tmp;
    403		break;
    404	}
    405
    406	if (value != tmp)
    407		brcm_sata_phy_wr(port, BLOCK1_REG_BANK, BLOCK1_TEST_TX, ~tmp,
    408				 value);
    409
    410	/* Turn on/off SSC */
    411	brcm_sata_phy_wr(port, TX_REG_BANK, TX_ACTRL5, ~TX_ACTRL5_SSC_EN,
    412			 port->ssc_en ? TX_ACTRL5_SSC_EN : 0);
    413
    414	return 0;
    415}
    416
    417static int brcm_stb_sata_16nm_init(struct brcm_sata_port *port)
    418{
    419	return brcm_stb_sata_16nm_ssc_init(port);
    420}
    421
    422/* NS2 SATA PLL1 defaults were characterized by H/W group */
    423#define NS2_PLL1_ACTRL2_MAGIC	0x1df8
    424#define NS2_PLL1_ACTRL3_MAGIC	0x2b00
    425#define NS2_PLL1_ACTRL4_MAGIC	0x8824
    426
    427static int brcm_ns2_sata_init(struct brcm_sata_port *port)
    428{
    429	int try;
    430	unsigned int val;
    431	void __iomem *ctrl_base = brcm_sata_ctrl_base(port);
    432	struct device *dev = port->phy_priv->dev;
    433
    434	/* Configure OOB control */
    435	val = 0x0;
    436	val |= (0xc << OOB_CTRL1_BURST_MAX_SHIFT);
    437	val |= (0x4 << OOB_CTRL1_BURST_MIN_SHIFT);
    438	val |= (0x9 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT);
    439	val |= (0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT);
    440	brcm_sata_phy_wr(port, OOB_REG_BANK, OOB_CTRL1, 0x0, val);
    441	val = 0x0;
    442	val |= (0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT);
    443	val |= (0x2 << OOB_CTRL2_BURST_CNT_SHIFT);
    444	val |= (0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT);
    445	brcm_sata_phy_wr(port, OOB_REG_BANK, OOB_CTRL2, 0x0, val);
    446
    447	/* Configure PHY PLL register bank 1 */
    448	val = NS2_PLL1_ACTRL2_MAGIC;
    449	brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
    450	val = NS2_PLL1_ACTRL3_MAGIC;
    451	brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
    452	val = NS2_PLL1_ACTRL4_MAGIC;
    453	brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
    454
    455	/* Configure PHY BLOCK0 register bank */
    456	/* Set oob_clk_sel to refclk/2 */
    457	brcm_sata_phy_wr(port, BLOCK0_REG_BANK, BLOCK0_SPARE,
    458			 ~BLOCK0_SPARE_OOB_CLK_SEL_MASK,
    459			 BLOCK0_SPARE_OOB_CLK_SEL_REFBY2);
    460
    461	/* Strobe PHY reset using PHY control register */
    462	writel(PHY_CTRL_1_RESET, ctrl_base + PHY_CTRL_1);
    463	mdelay(1);
    464	writel(0x0, ctrl_base + PHY_CTRL_1);
    465	mdelay(1);
    466
    467	/* Wait for PHY PLL lock by polling pll_lock bit */
    468	try = 50;
    469	while (try) {
    470		val = brcm_sata_phy_rd(port, BLOCK0_REG_BANK,
    471					BLOCK0_XGXSSTATUS);
    472		if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
    473			break;
    474		msleep(20);
    475		try--;
    476	}
    477	if (!try) {
    478		/* PLL did not lock; give up */
    479		dev_err(dev, "port%d PLL did not lock\n", port->portnum);
    480		return -ETIMEDOUT;
    481	}
    482
    483	dev_dbg(dev, "port%d initialized\n", port->portnum);
    484
    485	return 0;
    486}
    487
    488static int brcm_nsp_sata_init(struct brcm_sata_port *port)
    489{
    490	struct device *dev = port->phy_priv->dev;
    491	unsigned int oob_bank;
    492	unsigned int val, try;
    493
    494	/* Configure OOB control */
    495	if (port->portnum == 0)
    496		oob_bank = OOB_REG_BANK;
    497	else if (port->portnum == 1)
    498		oob_bank = OOB1_REG_BANK;
    499	else
    500		return -EINVAL;
    501
    502	val = 0x0;
    503	val |= (0x0f << OOB_CTRL1_BURST_MAX_SHIFT);
    504	val |= (0x06 << OOB_CTRL1_BURST_MIN_SHIFT);
    505	val |= (0x0f << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT);
    506	val |= (0x06 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT);
    507	brcm_sata_phy_wr(port, oob_bank, OOB_CTRL1, 0x0, val);
    508
    509	val = 0x0;
    510	val |= (0x2e << OOB_CTRL2_RESET_IDLE_MAX_SHIFT);
    511	val |= (0x02 << OOB_CTRL2_BURST_CNT_SHIFT);
    512	val |= (0x16 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT);
    513	brcm_sata_phy_wr(port, oob_bank, OOB_CTRL2, 0x0, val);
    514
    515
    516	brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_ACTRL2,
    517		~(PLL_ACTRL2_SELDIV_MASK << PLL_ACTRL2_SELDIV_SHIFT),
    518		0x0c << PLL_ACTRL2_SELDIV_SHIFT);
    519
    520	brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_CAP_CONTROL,
    521						0xff0, 0x4f0);
    522
    523	val = PLLCONTROL_0_FREQ_DET_RESTART | PLLCONTROL_0_FREQ_MONITOR;
    524	brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
    525								~val, val);
    526	val = PLLCONTROL_0_SEQ_START;
    527	brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
    528								~val, 0);
    529	mdelay(10);
    530	brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
    531								~val, val);
    532
    533	/* Wait for pll_seq_done bit */
    534	try = 50;
    535	while (--try) {
    536		val = brcm_sata_phy_rd(port, BLOCK0_REG_BANK,
    537					BLOCK0_XGXSSTATUS);
    538		if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
    539			break;
    540		msleep(20);
    541	}
    542	if (!try) {
    543		/* PLL did not lock; give up */
    544		dev_err(dev, "port%d PLL did not lock\n", port->portnum);
    545		return -ETIMEDOUT;
    546	}
    547
    548	dev_dbg(dev, "port%d initialized\n", port->portnum);
    549
    550	return 0;
    551}
    552
    553/* SR PHY PLL0 registers */
    554#define SR_PLL0_ACTRL6_MAGIC			0xa
    555
    556/* SR PHY PLL1 registers */
    557#define SR_PLL1_ACTRL2_MAGIC			0x32
    558#define SR_PLL1_ACTRL3_MAGIC			0x2
    559#define SR_PLL1_ACTRL4_MAGIC			0x3e8
    560
    561static int brcm_sr_sata_init(struct brcm_sata_port *port)
    562{
    563	struct device *dev = port->phy_priv->dev;
    564	unsigned int val, try;
    565
    566	/* Configure PHY PLL register bank 1 */
    567	val = SR_PLL1_ACTRL2_MAGIC;
    568	brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
    569	val = SR_PLL1_ACTRL3_MAGIC;
    570	brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
    571	val = SR_PLL1_ACTRL4_MAGIC;
    572	brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
    573
    574	/* Configure PHY PLL register bank 0 */
    575	val = SR_PLL0_ACTRL6_MAGIC;
    576	brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_ACTRL6, 0x0, val);
    577
    578	/* Wait for PHY PLL lock by polling pll_lock bit */
    579	try = 50;
    580	do {
    581		val = brcm_sata_phy_rd(port, BLOCK0_REG_BANK,
    582					BLOCK0_XGXSSTATUS);
    583		if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
    584			break;
    585		msleep(20);
    586		try--;
    587	} while (try);
    588
    589	if ((val & BLOCK0_XGXSSTATUS_PLL_LOCK) == 0) {
    590		/* PLL did not lock; give up */
    591		dev_err(dev, "port%d PLL did not lock\n", port->portnum);
    592		return -ETIMEDOUT;
    593	}
    594
    595	/* Invert Tx polarity */
    596	brcm_sata_phy_wr(port, TX_REG_BANK, TX_ACTRL0,
    597			 ~TX_ACTRL0_TXPOL_FLIP, TX_ACTRL0_TXPOL_FLIP);
    598
    599	/* Configure OOB control to handle 100MHz reference clock */
    600	val = ((0xc << OOB_CTRL1_BURST_MAX_SHIFT) |
    601		(0x4 << OOB_CTRL1_BURST_MIN_SHIFT) |
    602		(0x8 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT) |
    603		(0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT));
    604	brcm_sata_phy_wr(port, OOB_REG_BANK, OOB_CTRL1, 0x0, val);
    605	val = ((0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT) |
    606		(0x2 << OOB_CTRL2_BURST_CNT_SHIFT) |
    607		(0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT));
    608	brcm_sata_phy_wr(port, OOB_REG_BANK, OOB_CTRL2, 0x0, val);
    609
    610	return 0;
    611}
    612
    613static int brcm_dsl_sata_init(struct brcm_sata_port *port)
    614{
    615	struct device *dev = port->phy_priv->dev;
    616	unsigned int try;
    617	u32 tmp;
    618
    619	brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL7, 0, 0x873);
    620
    621	brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL6, 0, 0xc000);
    622
    623	brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
    624			 0, 0x3089);
    625	usleep_range(1000, 2000);
    626
    627	brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
    628			 0, 0x3088);
    629	usleep_range(1000, 2000);
    630
    631	brcm_sata_phy_wr(port, AEQRX_REG_BANK_1, AEQRX_SLCAL0_CTRL0,
    632			 0, 0x3000);
    633
    634	brcm_sata_phy_wr(port, AEQRX_REG_BANK_1, AEQRX_SLCAL1_CTRL0,
    635			 0, 0x3000);
    636	usleep_range(1000, 2000);
    637
    638	brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_CAP_CHARGE_TIME, 0, 0x32);
    639
    640	brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_VCO_CAL_THRESH, 0, 0xa);
    641
    642	brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_FREQ_DET_TIME, 0, 0x64);
    643	usleep_range(1000, 2000);
    644
    645	/* Acquire PLL lock */
    646	try = 50;
    647	while (try) {
    648		tmp = brcm_sata_phy_rd(port, BLOCK0_REG_BANK,
    649				       BLOCK0_XGXSSTATUS);
    650		if (tmp & BLOCK0_XGXSSTATUS_PLL_LOCK)
    651			break;
    652		msleep(20);
    653		try--;
    654	}
    655
    656	if (!try) {
    657		/* PLL did not lock; give up */
    658		dev_err(dev, "port%d PLL did not lock\n", port->portnum);
    659		return -ETIMEDOUT;
    660	}
    661
    662	dev_dbg(dev, "port%d initialized\n", port->portnum);
    663
    664	return 0;
    665}
    666
    667static int brcm_sata_phy_init(struct phy *phy)
    668{
    669	int rc;
    670	struct brcm_sata_port *port = phy_get_drvdata(phy);
    671
    672	switch (port->phy_priv->version) {
    673	case BRCM_SATA_PHY_STB_16NM:
    674		rc = brcm_stb_sata_16nm_init(port);
    675		break;
    676	case BRCM_SATA_PHY_STB_28NM:
    677	case BRCM_SATA_PHY_STB_40NM:
    678		rc = brcm_stb_sata_init(port);
    679		break;
    680	case BRCM_SATA_PHY_IPROC_NS2:
    681		rc = brcm_ns2_sata_init(port);
    682		break;
    683	case BRCM_SATA_PHY_IPROC_NSP:
    684		rc = brcm_nsp_sata_init(port);
    685		break;
    686	case BRCM_SATA_PHY_IPROC_SR:
    687		rc = brcm_sr_sata_init(port);
    688		break;
    689	case BRCM_SATA_PHY_DSL_28NM:
    690		rc = brcm_dsl_sata_init(port);
    691		break;
    692	default:
    693		rc = -ENODEV;
    694	}
    695
    696	return rc;
    697}
    698
    699static void brcm_stb_sata_calibrate(struct brcm_sata_port *port)
    700{
    701	u32 tmp = BIT(8);
    702
    703	brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1,
    704			 ~tmp, tmp);
    705}
    706
    707static int brcm_sata_phy_calibrate(struct phy *phy)
    708{
    709	struct brcm_sata_port *port = phy_get_drvdata(phy);
    710	int rc = -EOPNOTSUPP;
    711
    712	switch (port->phy_priv->version) {
    713	case BRCM_SATA_PHY_STB_28NM:
    714	case BRCM_SATA_PHY_STB_40NM:
    715		brcm_stb_sata_calibrate(port);
    716		rc = 0;
    717		break;
    718	default:
    719		break;
    720	}
    721
    722	return rc;
    723}
    724
    725static const struct phy_ops phy_ops = {
    726	.init		= brcm_sata_phy_init,
    727	.calibrate	= brcm_sata_phy_calibrate,
    728	.owner		= THIS_MODULE,
    729};
    730
    731static const struct of_device_id brcm_sata_phy_of_match[] = {
    732	{ .compatible	= "brcm,bcm7216-sata-phy",
    733	  .data = (void *)BRCM_SATA_PHY_STB_16NM },
    734	{ .compatible	= "brcm,bcm7445-sata-phy",
    735	  .data = (void *)BRCM_SATA_PHY_STB_28NM },
    736	{ .compatible	= "brcm,bcm7425-sata-phy",
    737	  .data = (void *)BRCM_SATA_PHY_STB_40NM },
    738	{ .compatible	= "brcm,iproc-ns2-sata-phy",
    739	  .data = (void *)BRCM_SATA_PHY_IPROC_NS2 },
    740	{ .compatible = "brcm,iproc-nsp-sata-phy",
    741	  .data = (void *)BRCM_SATA_PHY_IPROC_NSP },
    742	{ .compatible	= "brcm,iproc-sr-sata-phy",
    743	  .data = (void *)BRCM_SATA_PHY_IPROC_SR },
    744	{ .compatible	= "brcm,bcm63138-sata-phy",
    745	  .data = (void *)BRCM_SATA_PHY_DSL_28NM },
    746	{},
    747};
    748MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);
    749
    750static int brcm_sata_phy_probe(struct platform_device *pdev)
    751{
    752	const char *rxaeq_mode;
    753	struct device *dev = &pdev->dev;
    754	struct device_node *dn = dev->of_node, *child;
    755	const struct of_device_id *of_id;
    756	struct brcm_sata_phy *priv;
    757	struct phy_provider *provider;
    758	int ret, count = 0;
    759
    760	if (of_get_child_count(dn) == 0)
    761		return -ENODEV;
    762
    763	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
    764	if (!priv)
    765		return -ENOMEM;
    766	dev_set_drvdata(dev, priv);
    767	priv->dev = dev;
    768
    769	priv->phy_base = devm_platform_ioremap_resource_byname(pdev, "phy");
    770	if (IS_ERR(priv->phy_base))
    771		return PTR_ERR(priv->phy_base);
    772
    773	of_id = of_match_node(brcm_sata_phy_of_match, dn);
    774	if (of_id)
    775		priv->version = (enum brcm_sata_phy_version)of_id->data;
    776	else
    777		priv->version = BRCM_SATA_PHY_STB_28NM;
    778
    779	if (priv->version == BRCM_SATA_PHY_IPROC_NS2) {
    780		priv->ctrl_base = devm_platform_ioremap_resource_byname(pdev, "phy-ctrl");
    781		if (IS_ERR(priv->ctrl_base))
    782			return PTR_ERR(priv->ctrl_base);
    783	}
    784
    785	for_each_available_child_of_node(dn, child) {
    786		unsigned int id;
    787		struct brcm_sata_port *port;
    788
    789		if (of_property_read_u32(child, "reg", &id)) {
    790			dev_err(dev, "missing reg property in node %pOFn\n",
    791					child);
    792			ret = -EINVAL;
    793			goto put_child;
    794		}
    795
    796		if (id >= MAX_PORTS) {
    797			dev_err(dev, "invalid reg: %u\n", id);
    798			ret = -EINVAL;
    799			goto put_child;
    800		}
    801		if (priv->phys[id].phy) {
    802			dev_err(dev, "already registered port %u\n", id);
    803			ret = -EINVAL;
    804			goto put_child;
    805		}
    806
    807		port = &priv->phys[id];
    808		port->portnum = id;
    809		port->phy_priv = priv;
    810		port->phy = devm_phy_create(dev, child, &phy_ops);
    811		port->rxaeq_mode = RXAEQ_MODE_OFF;
    812		if (!of_property_read_string(child, "brcm,rxaeq-mode",
    813					     &rxaeq_mode))
    814			port->rxaeq_mode = rxaeq_to_val(rxaeq_mode);
    815		if (port->rxaeq_mode == RXAEQ_MODE_MANUAL)
    816			of_property_read_u32(child, "brcm,rxaeq-value",
    817					     &port->rxaeq_val);
    818
    819		of_property_read_u32(child, "brcm,tx-amplitude-millivolt",
    820				     &port->tx_amplitude_val);
    821
    822		port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc");
    823		if (IS_ERR(port->phy)) {
    824			dev_err(dev, "failed to create PHY\n");
    825			ret = PTR_ERR(port->phy);
    826			goto put_child;
    827		}
    828
    829		phy_set_drvdata(port->phy, port);
    830		count++;
    831	}
    832
    833	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
    834	if (IS_ERR(provider)) {
    835		dev_err(dev, "could not register PHY provider\n");
    836		return PTR_ERR(provider);
    837	}
    838
    839	dev_info(dev, "registered %d port(s)\n", count);
    840
    841	return 0;
    842put_child:
    843	of_node_put(child);
    844	return ret;
    845}
    846
    847static struct platform_driver brcm_sata_phy_driver = {
    848	.probe	= brcm_sata_phy_probe,
    849	.driver	= {
    850		.of_match_table	= brcm_sata_phy_of_match,
    851		.name		= "brcm-sata-phy",
    852	}
    853};
    854module_platform_driver(brcm_sata_phy_driver);
    855
    856MODULE_DESCRIPTION("Broadcom SATA PHY driver");
    857MODULE_LICENSE("GPL");
    858MODULE_AUTHOR("Marc Carino");
    859MODULE_AUTHOR("Brian Norris");
    860MODULE_ALIAS("platform:phy-brcm-sata");