Linux Audio

Check our new training course

Loading...
v6.8
  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 = (uintptr_t)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");
v5.4
  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_28NM,
 37	BRCM_SATA_PHY_STB_40NM,
 38	BRCM_SATA_PHY_IPROC_NS2,
 39	BRCM_SATA_PHY_IPROC_NSP,
 40	BRCM_SATA_PHY_IPROC_SR,
 41	BRCM_SATA_PHY_DSL_28NM,
 42};
 43
 44enum brcm_sata_phy_rxaeq_mode {
 45	RXAEQ_MODE_OFF = 0,
 46	RXAEQ_MODE_AUTO,
 47	RXAEQ_MODE_MANUAL,
 48};
 49
 50static enum brcm_sata_phy_rxaeq_mode rxaeq_to_val(const char *m)
 51{
 52	if (!strcmp(m, "auto"))
 53		return RXAEQ_MODE_AUTO;
 54	else if (!strcmp(m, "manual"))
 55		return RXAEQ_MODE_MANUAL;
 56	else
 57		return RXAEQ_MODE_OFF;
 58}
 59
 60struct brcm_sata_port {
 61	int portnum;
 62	struct phy *phy;
 63	struct brcm_sata_phy *phy_priv;
 64	bool ssc_en;
 65	enum brcm_sata_phy_rxaeq_mode rxaeq_mode;
 66	u32 rxaeq_val;
 
 67};
 68
 69struct brcm_sata_phy {
 70	struct device *dev;
 71	void __iomem *phy_base;
 72	void __iomem *ctrl_base;
 73	enum brcm_sata_phy_version version;
 74
 75	struct brcm_sata_port phys[MAX_PORTS];
 76};
 77
 78enum sata_phy_regs {
 79	BLOCK0_REG_BANK				= 0x000,
 80	BLOCK0_XGXSSTATUS			= 0x81,
 81	BLOCK0_XGXSSTATUS_PLL_LOCK		= BIT(12),
 82	BLOCK0_SPARE				= 0x8d,
 83	BLOCK0_SPARE_OOB_CLK_SEL_MASK		= 0x3,
 84	BLOCK0_SPARE_OOB_CLK_SEL_REFBY2		= 0x1,
 85
 
 
 
 
 86	PLL_REG_BANK_0				= 0x050,
 87	PLL_REG_BANK_0_PLLCONTROL_0		= 0x81,
 88	PLLCONTROL_0_FREQ_DET_RESTART		= BIT(13),
 89	PLLCONTROL_0_FREQ_MONITOR		= BIT(12),
 90	PLLCONTROL_0_SEQ_START			= BIT(15),
 91	PLL_CAP_CHARGE_TIME			= 0x83,
 92	PLL_VCO_CAL_THRESH			= 0x84,
 93	PLL_CAP_CONTROL				= 0x85,
 94	PLL_FREQ_DET_TIME			= 0x86,
 95	PLL_ACTRL2				= 0x8b,
 96	PLL_ACTRL2_SELDIV_MASK			= 0x1f,
 97	PLL_ACTRL2_SELDIV_SHIFT			= 9,
 98	PLL_ACTRL6				= 0x86,
 99
100	PLL1_REG_BANK				= 0x060,
101	PLL1_ACTRL2				= 0x82,
102	PLL1_ACTRL3				= 0x83,
103	PLL1_ACTRL4				= 0x84,
104	PLL1_ACTRL5				= 0x85,
105	PLL1_ACTRL6				= 0x86,
106	PLL1_ACTRL7				= 0x87,
 
107
108	TX_REG_BANK				= 0x070,
109	TX_ACTRL0				= 0x80,
110	TX_ACTRL0_TXPOL_FLIP			= BIT(6),
 
 
111
112	AEQRX_REG_BANK_0			= 0xd0,
113	AEQ_CONTROL1				= 0x81,
114	AEQ_CONTROL1_ENABLE			= BIT(2),
115	AEQ_CONTROL1_FREEZE			= BIT(3),
116	AEQ_FRC_EQ				= 0x83,
117	AEQ_FRC_EQ_FORCE			= BIT(0),
118	AEQ_FRC_EQ_FORCE_VAL			= BIT(1),
 
119	AEQRX_REG_BANK_1			= 0xe0,
120	AEQRX_SLCAL0_CTRL0			= 0x82,
121	AEQRX_SLCAL1_CTRL0			= 0x86,
122
123	OOB_REG_BANK				= 0x150,
124	OOB1_REG_BANK				= 0x160,
125	OOB_CTRL1				= 0x80,
126	OOB_CTRL1_BURST_MAX_MASK		= 0xf,
127	OOB_CTRL1_BURST_MAX_SHIFT		= 12,
128	OOB_CTRL1_BURST_MIN_MASK		= 0xf,
129	OOB_CTRL1_BURST_MIN_SHIFT		= 8,
130	OOB_CTRL1_WAKE_IDLE_MAX_MASK		= 0xf,
131	OOB_CTRL1_WAKE_IDLE_MAX_SHIFT		= 4,
132	OOB_CTRL1_WAKE_IDLE_MIN_MASK		= 0xf,
133	OOB_CTRL1_WAKE_IDLE_MIN_SHIFT		= 0,
134	OOB_CTRL2				= 0x81,
135	OOB_CTRL2_SEL_ENA_SHIFT			= 15,
136	OOB_CTRL2_SEL_ENA_RC_SHIFT		= 14,
137	OOB_CTRL2_RESET_IDLE_MAX_MASK		= 0x3f,
138	OOB_CTRL2_RESET_IDLE_MAX_SHIFT		= 8,
139	OOB_CTRL2_BURST_CNT_MASK		= 0x3,
140	OOB_CTRL2_BURST_CNT_SHIFT		= 6,
141	OOB_CTRL2_RESET_IDLE_MIN_MASK		= 0x3f,
142	OOB_CTRL2_RESET_IDLE_MIN_SHIFT		= 0,
143
144	TXPMD_REG_BANK				= 0x1a0,
145	TXPMD_CONTROL1				= 0x81,
146	TXPMD_CONTROL1_TX_SSC_EN_FRC		= BIT(0),
147	TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL	= BIT(1),
148	TXPMD_TX_FREQ_CTRL_CONTROL1		= 0x82,
149	TXPMD_TX_FREQ_CTRL_CONTROL2		= 0x83,
150	TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK	= 0x3ff,
151	TXPMD_TX_FREQ_CTRL_CONTROL3		= 0x84,
152	TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK	= 0x3ff,
153
154	RXPMD_REG_BANK				= 0x1c0,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155	RXPMD_RX_FREQ_MON_CONTROL1		= 0x87,
 
 
156};
157
158enum sata_phy_ctrl_regs {
159	PHY_CTRL_1				= 0x0,
160	PHY_CTRL_1_RESET			= BIT(0),
161};
162
163static inline void __iomem *brcm_sata_pcb_base(struct brcm_sata_port *port)
164{
165	struct brcm_sata_phy *priv = port->phy_priv;
166	u32 size = 0;
167
168	switch (priv->version) {
169	case BRCM_SATA_PHY_STB_28NM:
170	case BRCM_SATA_PHY_IPROC_NS2:
171	case BRCM_SATA_PHY_DSL_28NM:
172		size = SATA_PCB_REG_28NM_SPACE_SIZE;
173		break;
174	case BRCM_SATA_PHY_STB_40NM:
175		size = SATA_PCB_REG_40NM_SPACE_SIZE;
176		break;
177	default:
178		dev_err(priv->dev, "invalid phy version\n");
179		break;
180	}
181
182	return priv->phy_base + (port->portnum * size);
183}
184
185static inline void __iomem *brcm_sata_ctrl_base(struct brcm_sata_port *port)
186{
187	struct brcm_sata_phy *priv = port->phy_priv;
188	u32 size = 0;
189
190	switch (priv->version) {
191	case BRCM_SATA_PHY_IPROC_NS2:
192		size = SATA_PHY_CTRL_REG_28NM_SPACE_SIZE;
193		break;
194	default:
195		dev_err(priv->dev, "invalid phy version\n");
196		break;
197	}
198
199	return priv->ctrl_base + (port->portnum * size);
200}
201
202static void brcm_sata_phy_wr(void __iomem *pcb_base, u32 bank,
203			     u32 ofs, u32 msk, u32 value)
204{
 
 
205	u32 tmp;
206
 
 
 
 
 
207	writel(bank, pcb_base + SATA_PCB_BANK_OFFSET);
208	tmp = readl(pcb_base + SATA_PCB_REG_OFFSET(ofs));
209	tmp = (tmp & msk) | value;
210	writel(tmp, pcb_base + SATA_PCB_REG_OFFSET(ofs));
211}
212
213static u32 brcm_sata_phy_rd(void __iomem *pcb_base, u32 bank, u32 ofs)
214{
 
 
 
 
 
 
 
 
215	writel(bank, pcb_base + SATA_PCB_BANK_OFFSET);
216	return readl(pcb_base + SATA_PCB_REG_OFFSET(ofs));
217}
218
219/* These defaults were characterized by H/W group */
220#define STB_FMIN_VAL_DEFAULT	0x3df
221#define STB_FMAX_VAL_DEFAULT	0x3df
222#define STB_FMAX_VAL_SSC	0x83
223
224static void brcm_stb_sata_ssc_init(struct brcm_sata_port *port)
225{
226	void __iomem *base = brcm_sata_pcb_base(port);
227	struct brcm_sata_phy *priv = port->phy_priv;
228	u32 tmp;
229
230	/* override the TX spread spectrum setting */
231	tmp = TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL | TXPMD_CONTROL1_TX_SSC_EN_FRC;
232	brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_CONTROL1, ~tmp, tmp);
233
234	/* set fixed min freq */
235	brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL2,
236			 ~TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK,
237			 STB_FMIN_VAL_DEFAULT);
238
239	/* set fixed max freq depending on SSC config */
240	if (port->ssc_en) {
241		dev_info(priv->dev, "enabling SSC on port%d\n", port->portnum);
242		tmp = STB_FMAX_VAL_SSC;
243	} else {
244		tmp = STB_FMAX_VAL_DEFAULT;
245	}
246
247	brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL3,
248			  ~TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK, tmp);
249}
250
251#define AEQ_FRC_EQ_VAL_SHIFT	2
252#define AEQ_FRC_EQ_VAL_MASK	0x3f
253
254static int brcm_stb_sata_rxaeq_init(struct brcm_sata_port *port)
255{
256	void __iomem *base = brcm_sata_pcb_base(port);
257	u32 tmp = 0, reg = 0;
258
259	switch (port->rxaeq_mode) {
260	case RXAEQ_MODE_OFF:
261		return 0;
262
263	case RXAEQ_MODE_AUTO:
264		reg = AEQ_CONTROL1;
265		tmp = AEQ_CONTROL1_ENABLE | AEQ_CONTROL1_FREEZE;
266		break;
267
268	case RXAEQ_MODE_MANUAL:
269		reg = AEQ_FRC_EQ;
270		tmp = AEQ_FRC_EQ_FORCE | AEQ_FRC_EQ_FORCE_VAL;
271		if (port->rxaeq_val > AEQ_FRC_EQ_VAL_MASK)
272			return -EINVAL;
273		tmp |= port->rxaeq_val << AEQ_FRC_EQ_VAL_SHIFT;
274		break;
275	}
276
277	brcm_sata_phy_wr(base, AEQRX_REG_BANK_0, reg, ~tmp, tmp);
278	brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, reg, ~tmp, tmp);
279
280	return 0;
281}
282
283static int brcm_stb_sata_init(struct brcm_sata_port *port)
284{
285	brcm_stb_sata_ssc_init(port);
286
287	return brcm_stb_sata_rxaeq_init(port);
288}
289
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290/* NS2 SATA PLL1 defaults were characterized by H/W group */
291#define NS2_PLL1_ACTRL2_MAGIC	0x1df8
292#define NS2_PLL1_ACTRL3_MAGIC	0x2b00
293#define NS2_PLL1_ACTRL4_MAGIC	0x8824
294
295static int brcm_ns2_sata_init(struct brcm_sata_port *port)
296{
297	int try;
298	unsigned int val;
299	void __iomem *base = brcm_sata_pcb_base(port);
300	void __iomem *ctrl_base = brcm_sata_ctrl_base(port);
301	struct device *dev = port->phy_priv->dev;
302
303	/* Configure OOB control */
304	val = 0x0;
305	val |= (0xc << OOB_CTRL1_BURST_MAX_SHIFT);
306	val |= (0x4 << OOB_CTRL1_BURST_MIN_SHIFT);
307	val |= (0x9 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT);
308	val |= (0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT);
309	brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL1, 0x0, val);
310	val = 0x0;
311	val |= (0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT);
312	val |= (0x2 << OOB_CTRL2_BURST_CNT_SHIFT);
313	val |= (0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT);
314	brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL2, 0x0, val);
315
316	/* Configure PHY PLL register bank 1 */
317	val = NS2_PLL1_ACTRL2_MAGIC;
318	brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
319	val = NS2_PLL1_ACTRL3_MAGIC;
320	brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
321	val = NS2_PLL1_ACTRL4_MAGIC;
322	brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
323
324	/* Configure PHY BLOCK0 register bank */
325	/* Set oob_clk_sel to refclk/2 */
326	brcm_sata_phy_wr(base, BLOCK0_REG_BANK, BLOCK0_SPARE,
327			 ~BLOCK0_SPARE_OOB_CLK_SEL_MASK,
328			 BLOCK0_SPARE_OOB_CLK_SEL_REFBY2);
329
330	/* Strobe PHY reset using PHY control register */
331	writel(PHY_CTRL_1_RESET, ctrl_base + PHY_CTRL_1);
332	mdelay(1);
333	writel(0x0, ctrl_base + PHY_CTRL_1);
334	mdelay(1);
335
336	/* Wait for PHY PLL lock by polling pll_lock bit */
337	try = 50;
338	while (try) {
339		val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
340					BLOCK0_XGXSSTATUS);
341		if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
342			break;
343		msleep(20);
344		try--;
345	}
346	if (!try) {
347		/* PLL did not lock; give up */
348		dev_err(dev, "port%d PLL did not lock\n", port->portnum);
349		return -ETIMEDOUT;
350	}
351
352	dev_dbg(dev, "port%d initialized\n", port->portnum);
353
354	return 0;
355}
356
357static int brcm_nsp_sata_init(struct brcm_sata_port *port)
358{
359	struct brcm_sata_phy *priv = port->phy_priv;
360	struct device *dev = port->phy_priv->dev;
361	void __iomem *base = priv->phy_base;
362	unsigned int oob_bank;
363	unsigned int val, try;
364
365	/* Configure OOB control */
366	if (port->portnum == 0)
367		oob_bank = OOB_REG_BANK;
368	else if (port->portnum == 1)
369		oob_bank = OOB1_REG_BANK;
370	else
371		return -EINVAL;
372
373	val = 0x0;
374	val |= (0x0f << OOB_CTRL1_BURST_MAX_SHIFT);
375	val |= (0x06 << OOB_CTRL1_BURST_MIN_SHIFT);
376	val |= (0x0f << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT);
377	val |= (0x06 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT);
378	brcm_sata_phy_wr(base, oob_bank, OOB_CTRL1, 0x0, val);
379
380	val = 0x0;
381	val |= (0x2e << OOB_CTRL2_RESET_IDLE_MAX_SHIFT);
382	val |= (0x02 << OOB_CTRL2_BURST_CNT_SHIFT);
383	val |= (0x16 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT);
384	brcm_sata_phy_wr(base, oob_bank, OOB_CTRL2, 0x0, val);
385
386
387	brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_ACTRL2,
388		~(PLL_ACTRL2_SELDIV_MASK << PLL_ACTRL2_SELDIV_SHIFT),
389		0x0c << PLL_ACTRL2_SELDIV_SHIFT);
390
391	brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_CAP_CONTROL,
392						0xff0, 0x4f0);
393
394	val = PLLCONTROL_0_FREQ_DET_RESTART | PLLCONTROL_0_FREQ_MONITOR;
395	brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
396								~val, val);
397	val = PLLCONTROL_0_SEQ_START;
398	brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
399								~val, 0);
400	mdelay(10);
401	brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
402								~val, val);
403
404	/* Wait for pll_seq_done bit */
405	try = 50;
406	while (--try) {
407		val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
408					BLOCK0_XGXSSTATUS);
409		if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
410			break;
411		msleep(20);
412	}
413	if (!try) {
414		/* PLL did not lock; give up */
415		dev_err(dev, "port%d PLL did not lock\n", port->portnum);
416		return -ETIMEDOUT;
417	}
418
419	dev_dbg(dev, "port%d initialized\n", port->portnum);
420
421	return 0;
422}
423
424/* SR PHY PLL0 registers */
425#define SR_PLL0_ACTRL6_MAGIC			0xa
426
427/* SR PHY PLL1 registers */
428#define SR_PLL1_ACTRL2_MAGIC			0x32
429#define SR_PLL1_ACTRL3_MAGIC			0x2
430#define SR_PLL1_ACTRL4_MAGIC			0x3e8
431
432static int brcm_sr_sata_init(struct brcm_sata_port *port)
433{
434	struct brcm_sata_phy *priv = port->phy_priv;
435	struct device *dev = port->phy_priv->dev;
436	void __iomem *base = priv->phy_base;
437	unsigned int val, try;
438
439	/* Configure PHY PLL register bank 1 */
440	val = SR_PLL1_ACTRL2_MAGIC;
441	brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
442	val = SR_PLL1_ACTRL3_MAGIC;
443	brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
444	val = SR_PLL1_ACTRL4_MAGIC;
445	brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
446
447	/* Configure PHY PLL register bank 0 */
448	val = SR_PLL0_ACTRL6_MAGIC;
449	brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_ACTRL6, 0x0, val);
450
451	/* Wait for PHY PLL lock by polling pll_lock bit */
452	try = 50;
453	do {
454		val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
455					BLOCK0_XGXSSTATUS);
456		if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
457			break;
458		msleep(20);
459		try--;
460	} while (try);
461
462	if ((val & BLOCK0_XGXSSTATUS_PLL_LOCK) == 0) {
463		/* PLL did not lock; give up */
464		dev_err(dev, "port%d PLL did not lock\n", port->portnum);
465		return -ETIMEDOUT;
466	}
467
468	/* Invert Tx polarity */
469	brcm_sata_phy_wr(base, TX_REG_BANK, TX_ACTRL0,
470			 ~TX_ACTRL0_TXPOL_FLIP, TX_ACTRL0_TXPOL_FLIP);
471
472	/* Configure OOB control to handle 100MHz reference clock */
473	val = ((0xc << OOB_CTRL1_BURST_MAX_SHIFT) |
474		(0x4 << OOB_CTRL1_BURST_MIN_SHIFT) |
475		(0x8 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT) |
476		(0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT));
477	brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL1, 0x0, val);
478	val = ((0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT) |
479		(0x2 << OOB_CTRL2_BURST_CNT_SHIFT) |
480		(0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT));
481	brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL2, 0x0, val);
482
483	return 0;
484}
485
486static int brcm_dsl_sata_init(struct brcm_sata_port *port)
487{
488	void __iomem *base = brcm_sata_pcb_base(port);
489	struct device *dev = port->phy_priv->dev;
490	unsigned int try;
491	u32 tmp;
492
493	brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL7, 0, 0x873);
494
495	brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL6, 0, 0xc000);
496
497	brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
498			 0, 0x3089);
499	usleep_range(1000, 2000);
500
501	brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
502			 0, 0x3088);
503	usleep_range(1000, 2000);
504
505	brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, AEQRX_SLCAL0_CTRL0,
506			 0, 0x3000);
507
508	brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, AEQRX_SLCAL1_CTRL0,
509			 0, 0x3000);
510	usleep_range(1000, 2000);
511
512	brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_CAP_CHARGE_TIME, 0, 0x32);
513
514	brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_VCO_CAL_THRESH, 0, 0xa);
515
516	brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_FREQ_DET_TIME, 0, 0x64);
517	usleep_range(1000, 2000);
518
519	/* Acquire PLL lock */
520	try = 50;
521	while (try) {
522		tmp = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
523				       BLOCK0_XGXSSTATUS);
524		if (tmp & BLOCK0_XGXSSTATUS_PLL_LOCK)
525			break;
526		msleep(20);
527		try--;
528	};
529
530	if (!try) {
531		/* PLL did not lock; give up */
532		dev_err(dev, "port%d PLL did not lock\n", port->portnum);
533		return -ETIMEDOUT;
534	}
535
536	dev_dbg(dev, "port%d initialized\n", port->portnum);
537
538	return 0;
539}
540
541static int brcm_sata_phy_init(struct phy *phy)
542{
543	int rc;
544	struct brcm_sata_port *port = phy_get_drvdata(phy);
545
546	switch (port->phy_priv->version) {
 
 
 
547	case BRCM_SATA_PHY_STB_28NM:
548	case BRCM_SATA_PHY_STB_40NM:
549		rc = brcm_stb_sata_init(port);
550		break;
551	case BRCM_SATA_PHY_IPROC_NS2:
552		rc = brcm_ns2_sata_init(port);
553		break;
554	case BRCM_SATA_PHY_IPROC_NSP:
555		rc = brcm_nsp_sata_init(port);
556		break;
557	case BRCM_SATA_PHY_IPROC_SR:
558		rc = brcm_sr_sata_init(port);
559		break;
560	case BRCM_SATA_PHY_DSL_28NM:
561		rc = brcm_dsl_sata_init(port);
562		break;
563	default:
564		rc = -ENODEV;
565	}
566
567	return rc;
568}
569
570static void brcm_stb_sata_calibrate(struct brcm_sata_port *port)
571{
572	void __iomem *base = brcm_sata_pcb_base(port);
573	u32 tmp = BIT(8);
574
575	brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1,
576			 ~tmp, tmp);
577}
578
579static int brcm_sata_phy_calibrate(struct phy *phy)
580{
581	struct brcm_sata_port *port = phy_get_drvdata(phy);
582	int rc = -EOPNOTSUPP;
583
584	switch (port->phy_priv->version) {
585	case BRCM_SATA_PHY_STB_28NM:
586	case BRCM_SATA_PHY_STB_40NM:
587		brcm_stb_sata_calibrate(port);
588		rc = 0;
589		break;
590	default:
591		break;
592	}
593
594	return rc;
595}
596
597static const struct phy_ops phy_ops = {
598	.init		= brcm_sata_phy_init,
599	.calibrate	= brcm_sata_phy_calibrate,
600	.owner		= THIS_MODULE,
601};
602
603static const struct of_device_id brcm_sata_phy_of_match[] = {
 
 
604	{ .compatible	= "brcm,bcm7445-sata-phy",
605	  .data = (void *)BRCM_SATA_PHY_STB_28NM },
606	{ .compatible	= "brcm,bcm7425-sata-phy",
607	  .data = (void *)BRCM_SATA_PHY_STB_40NM },
608	{ .compatible	= "brcm,iproc-ns2-sata-phy",
609	  .data = (void *)BRCM_SATA_PHY_IPROC_NS2 },
610	{ .compatible = "brcm,iproc-nsp-sata-phy",
611	  .data = (void *)BRCM_SATA_PHY_IPROC_NSP },
612	{ .compatible	= "brcm,iproc-sr-sata-phy",
613	  .data = (void *)BRCM_SATA_PHY_IPROC_SR },
614	{ .compatible	= "brcm,bcm63138-sata-phy",
615	  .data = (void *)BRCM_SATA_PHY_DSL_28NM },
616	{},
617};
618MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);
619
620static int brcm_sata_phy_probe(struct platform_device *pdev)
621{
622	const char *rxaeq_mode;
623	struct device *dev = &pdev->dev;
624	struct device_node *dn = dev->of_node, *child;
625	const struct of_device_id *of_id;
626	struct brcm_sata_phy *priv;
627	struct resource *res;
628	struct phy_provider *provider;
629	int ret, count = 0;
630
631	if (of_get_child_count(dn) == 0)
632		return -ENODEV;
633
634	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
635	if (!priv)
636		return -ENOMEM;
637	dev_set_drvdata(dev, priv);
638	priv->dev = dev;
639
640	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
641	priv->phy_base = devm_ioremap_resource(dev, res);
642	if (IS_ERR(priv->phy_base))
643		return PTR_ERR(priv->phy_base);
644
645	of_id = of_match_node(brcm_sata_phy_of_match, dn);
646	if (of_id)
647		priv->version = (enum brcm_sata_phy_version)of_id->data;
648	else
649		priv->version = BRCM_SATA_PHY_STB_28NM;
650
651	if (priv->version == BRCM_SATA_PHY_IPROC_NS2) {
652		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
653						   "phy-ctrl");
654		priv->ctrl_base = devm_ioremap_resource(dev, res);
655		if (IS_ERR(priv->ctrl_base))
656			return PTR_ERR(priv->ctrl_base);
657	}
658
659	for_each_available_child_of_node(dn, child) {
660		unsigned int id;
661		struct brcm_sata_port *port;
662
663		if (of_property_read_u32(child, "reg", &id)) {
664			dev_err(dev, "missing reg property in node %pOFn\n",
665					child);
666			ret = -EINVAL;
667			goto put_child;
668		}
669
670		if (id >= MAX_PORTS) {
671			dev_err(dev, "invalid reg: %u\n", id);
672			ret = -EINVAL;
673			goto put_child;
674		}
675		if (priv->phys[id].phy) {
676			dev_err(dev, "already registered port %u\n", id);
677			ret = -EINVAL;
678			goto put_child;
679		}
680
681		port = &priv->phys[id];
682		port->portnum = id;
683		port->phy_priv = priv;
684		port->phy = devm_phy_create(dev, child, &phy_ops);
685		port->rxaeq_mode = RXAEQ_MODE_OFF;
686		if (!of_property_read_string(child, "brcm,rxaeq-mode",
687					     &rxaeq_mode))
688			port->rxaeq_mode = rxaeq_to_val(rxaeq_mode);
689		if (port->rxaeq_mode == RXAEQ_MODE_MANUAL)
690			of_property_read_u32(child, "brcm,rxaeq-value",
691					     &port->rxaeq_val);
 
 
 
 
692		port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc");
693		if (IS_ERR(port->phy)) {
694			dev_err(dev, "failed to create PHY\n");
695			ret = PTR_ERR(port->phy);
696			goto put_child;
697		}
698
699		phy_set_drvdata(port->phy, port);
700		count++;
701	}
702
703	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
704	if (IS_ERR(provider)) {
705		dev_err(dev, "could not register PHY provider\n");
706		return PTR_ERR(provider);
707	}
708
709	dev_info(dev, "registered %d port(s)\n", count);
710
711	return 0;
712put_child:
713	of_node_put(child);
714	return ret;
715}
716
717static struct platform_driver brcm_sata_phy_driver = {
718	.probe	= brcm_sata_phy_probe,
719	.driver	= {
720		.of_match_table	= brcm_sata_phy_of_match,
721		.name		= "brcm-sata-phy",
722	}
723};
724module_platform_driver(brcm_sata_phy_driver);
725
726MODULE_DESCRIPTION("Broadcom SATA PHY driver");
727MODULE_LICENSE("GPL");
728MODULE_AUTHOR("Marc Carino");
729MODULE_AUTHOR("Brian Norris");
730MODULE_ALIAS("platform:phy-brcm-sata");