Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2018, Broadcom */
  3
  4/*
  5 * This module contains USB PHY initialization for power up and S3 resume
  6 * for newer Synopsys based USB hardware first used on the bcm7216.
  7 */
  8
  9#include <linux/delay.h>
 10#include <linux/io.h>
 11
 12#include <linux/soc/brcmstb/brcmstb.h>
 13#include "phy-brcm-usb-init.h"
 14
 15#define PHY_LOCK_TIMEOUT_MS 200
 16
 17/* Register definitions for syscon piarbctl registers */
 18#define PIARBCTL_CAM			0x00
 19#define PIARBCTL_SPLITTER		0x04
 20#define PIARBCTL_MISC			0x08
 21#define   PIARBCTL_MISC_SATA_PRIORITY_MASK		GENMASK(3, 0)
 22#define   PIARBCTL_MISC_CAM0_MEM_PAGE_MASK		GENMASK(7, 4)
 23#define   PIARBCTL_MISC_CAM1_MEM_PAGE_MASK		GENMASK(11, 8)
 24#define   PIARBCTL_MISC_USB_MEM_PAGE_MASK		GENMASK(15, 12)
 25#define   PIARBCTL_MISC_USB_PRIORITY_MASK		GENMASK(19, 16)
 26#define   PIARBCTL_MISC_USB_4G_SDRAM_MASK		BIT(29)
 27#define   PIARBCTL_MISC_USB_SELECT_MASK			BIT(30)
 28#define   PIARBCTL_MISC_SECURE_MASK			BIT(31)
 29
 30#define PIARBCTL_MISC_USB_ONLY_MASK		\
 31	(PIARBCTL_MISC_USB_SELECT_MASK |	\
 32	 PIARBCTL_MISC_USB_4G_SDRAM_MASK |	\
 33	 PIARBCTL_MISC_USB_PRIORITY_MASK |	\
 34	 PIARBCTL_MISC_USB_MEM_PAGE_MASK)
 35
 36/* Register definitions for the USB CTRL block */
 37#define USB_CTRL_SETUP			0x00
 38#define   USB_CTRL_SETUP_IOC_MASK			BIT(4)
 39#define   USB_CTRL_SETUP_IPP_MASK			BIT(5)
 40#define   USB_CTRL_SETUP_SOFT_SHUTDOWN_MASK		BIT(9)
 41#define   USB_CTRL_SETUP_SCB1_EN_MASK			BIT(14)
 42#define   USB_CTRL_SETUP_SCB2_EN_MASK			BIT(15)
 43#define   USB_CTRL_SETUP_tca_drv_sel_MASK		BIT(24)
 44#define   USB_CTRL_SETUP_STRAP_IPP_SEL_MASK		BIT(25)
 45#define USB_CTRL_USB_PM			0x04
 46#define   USB_CTRL_USB_PM_XHC_S2_CLK_SWITCH_EN_MASK	BIT(3)
 47#define   USB_CTRL_USB_PM_XHC_PME_EN_MASK		BIT(4)
 48#define   USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK		BIT(22)
 49#define   USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK		BIT(23)
 50#define   USB_CTRL_USB_PM_SOFT_RESET_MASK		BIT(30)
 51#define   USB_CTRL_USB_PM_USB_PWRDN_MASK		BIT(31)
 52#define USB_CTRL_USB_PM_STATUS		0x08
 53#define USB_CTRL_USB_DEVICE_CTL1	0x10
 54#define   USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK	GENMASK(1, 0)
 55#define USB_CTRL_TEST_PORT_CTL		0x30
 56#define   USB_CTRL_TEST_PORT_CTL_TPOUT_SEL_MASK		GENMASK(7, 0)
 57#define   USB_CTRL_TEST_PORT_CTL_TPOUT_SEL_PME_GEN_MASK	0x0000002e
 58#define USB_CTRL_TP_DIAG1		0x34
 59#define   USB_CTLR_TP_DIAG1_wake_MASK			BIT(1)
 60#define USB_CTRL_CTLR_CSHCR		0x50
 61#define   USB_CTRL_CTLR_CSHCR_ctl_pme_en_MASK		BIT(18)
 62#define USB_CTRL_P0_U2PHY_CFG1		0x68
 63#define   USB_CTRL_P0_U2PHY_CFG1_COMMONONN_MASK		BIT(10)
 64
 65/* Register definitions for the USB_PHY block in 7211b0 */
 66#define USB_PHY_PLL_CTL			0x00
 67#define   USB_PHY_PLL_CTL_PLL_SUSPEND_MASK		BIT(27)
 68#define   USB_PHY_PLL_CTL_PLL_RESETB_MASK		BIT(30)
 69#define USB_PHY_PLL_LDO_CTL		0x08
 70#define   USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK	BIT(0)
 71#define   USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK	BIT(1)
 72#define   USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK		BIT(2)
 73#define USB_PHY_UTMI_CTL_1		0x04
 74#define   USB_PHY_UTMI_CTL_1_PHY_MODE_MASK		GENMASK(3, 2)
 75#define   USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT		2
 76#define   USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK	BIT(11)
 77#define USB_PHY_IDDQ			0x1c
 78#define   USB_PHY_IDDQ_phy_iddq_MASK			BIT(0)
 79#define USB_PHY_STATUS			0x20
 80#define   USB_PHY_STATUS_pll_lock_MASK			BIT(0)
 81
 82/* Register definitions for the MDIO registers in the DWC2 block of
 83 * the 7211b0.
 84 * NOTE: The PHY's MDIO registers are only accessible through the
 85 * legacy DesignWare USB controller even though it's not being used.
 86 */
 87#define USB_GMDIOCSR	0
 88#define USB_GMDIOGEN	4
 89
 90/* Register definitions for the BDC EC block in 7211b0 */
 91#define BDC_EC_AXIRDA			0x0c
 92#define   BDC_EC_AXIRDA_RTS_MASK			GENMASK(31, 28)
 93#define   BDC_EC_AXIRDA_RTS_SHIFT			28
 94
 95#define USB_XHCI_GBL_GUSB2PHYCFG	0x100
 96#define   USB_XHCI_GBL_GUSB2PHYCFG_U2_FREECLK_EXISTS_MASK	BIT(30)
 97
 98static void usb_mdio_write_7211b0(struct brcm_usb_init_params *params,
 99				  uint8_t addr, uint16_t data)
100{
101	void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO];
102
103	addr &= 0x1f; /* 5-bit address */
104	brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN);
105	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
106		;
107	brcm_usb_writel(0x59020000 | (addr << 18) | data,
108			usb_mdio + USB_GMDIOGEN);
109	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
110		;
111	brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN);
112	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
113		;
114}
115
116static uint16_t __maybe_unused usb_mdio_read_7211b0(
117	struct brcm_usb_init_params *params, uint8_t addr)
118{
119	void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO];
120
121	addr &= 0x1f; /* 5-bit address */
122	brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN);
123	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
124		;
125	brcm_usb_writel(0x69020000 | (addr << 18), usb_mdio + USB_GMDIOGEN);
126	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
127		;
128	brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN);
129	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
130		;
131	return brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & 0xffff;
132}
133
134static void usb2_eye_fix_7211b0(struct brcm_usb_init_params *params)
135{
136	/* select bank */
137	usb_mdio_write_7211b0(params, 0x1f, 0x80a0);
138
139	/* Set the eye */
140	usb_mdio_write_7211b0(params, 0x0a, 0xc6a0);
141}
142
143static void xhci_soft_reset(struct brcm_usb_init_params *params,
144			int on_off)
145{
146	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
147	void __iomem *xhci_gbl = params->regs[BRCM_REGS_XHCI_GBL];
148
149	/* Assert reset */
150	if (on_off) {
151		USB_CTRL_UNSET(ctrl, USB_PM, XHC_SOFT_RESETB);
152	/* De-assert reset */
153	} else {
154		USB_CTRL_SET(ctrl, USB_PM, XHC_SOFT_RESETB);
155		/* Required for COMMONONN to be set */
156		if (params->supported_port_modes != USB_CTLR_MODE_DRD)
157			USB_XHCI_GBL_UNSET(xhci_gbl, GUSB2PHYCFG,
158					   U2_FREECLK_EXISTS);
159	}
160}
161
162static void usb_init_ipp(struct brcm_usb_init_params *params)
163{
164	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
165	u32 reg;
166	u32 orig_reg;
167
168	pr_debug("%s\n", __func__);
169
170	orig_reg = reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
171	if (params->ipp != 2)
172		/* override ipp strap pin (if it exits) */
173		reg &= ~(USB_CTRL_MASK(SETUP, STRAP_IPP_SEL));
174
175	/* Override the default OC and PP polarity */
176	reg &= ~(USB_CTRL_MASK(SETUP, IPP) | USB_CTRL_MASK(SETUP, IOC));
177	if (params->ioc)
178		reg |= USB_CTRL_MASK(SETUP, IOC);
179	if (params->ipp == 1)
180		reg |= USB_CTRL_MASK(SETUP, IPP);
181	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
182
183	/*
184	 * If we're changing IPP, make sure power is off long enough
185	 * to turn off any connected devices.
186	 */
187	if ((reg ^ orig_reg) & USB_CTRL_MASK(SETUP, IPP))
188		msleep(50);
189}
190
191static void syscon_piarbctl_init(struct regmap *rmap)
192{
193	/* Switch from legacy USB OTG controller to new STB USB controller */
194	regmap_update_bits(rmap, PIARBCTL_MISC, PIARBCTL_MISC_USB_ONLY_MASK,
195			   PIARBCTL_MISC_USB_SELECT_MASK |
196			   PIARBCTL_MISC_USB_4G_SDRAM_MASK);
197}
198
199static void usb_init_common(struct brcm_usb_init_params *params)
200{
201	u32 reg;
202	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
203
204	pr_debug("%s\n", __func__);
205
206	if (USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE)) {
207		reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
208		reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
209		reg |= params->port_mode;
210		brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
211	}
212	switch (params->supported_port_modes) {
213	case USB_CTLR_MODE_HOST:
214		USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB);
215		break;
216	default:
217		USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB);
218		USB_CTRL_SET(ctrl, USB_PM, BDC_SOFT_RESETB);
219		break;
220	}
221}
222
223static void usb_wake_enable_7211b0(struct brcm_usb_init_params *params,
224				   bool enable)
225{
226	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
227
228	if (enable)
229		USB_CTRL_SET(ctrl, CTLR_CSHCR, ctl_pme_en);
230	else
231		USB_CTRL_UNSET(ctrl, CTLR_CSHCR, ctl_pme_en);
232}
233
234static void usb_wake_enable_7216(struct brcm_usb_init_params *params,
235				 bool enable)
236{
237	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
238
239	if (enable)
240		USB_CTRL_SET(ctrl, USB_PM, XHC_PME_EN);
241	else
242		USB_CTRL_UNSET(ctrl, USB_PM, XHC_PME_EN);
243}
244
245static void usb_init_common_7211b0(struct brcm_usb_init_params *params)
246{
247	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
248	void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
249	void __iomem *bdc_ec = params->regs[BRCM_REGS_BDC_EC];
250	int timeout_ms = PHY_LOCK_TIMEOUT_MS;
251	u32 reg;
252
253	if (params->syscon_piarbctl)
254		syscon_piarbctl_init(params->syscon_piarbctl);
255
256	USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
257
258	usb_wake_enable_7211b0(params, false);
259	if (!params->wake_enabled) {
260
261		/* undo possible suspend settings */
262		brcm_usb_writel(0, usb_phy + USB_PHY_IDDQ);
263		reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
264		reg |= USB_PHY_PLL_CTL_PLL_RESETB_MASK;
265		brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
266
267		/* temporarily enable FSM so PHY comes up properly */
268		reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
269		reg |= USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
270		brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
271	}
272
273	/* Disable PLL auto suspend */
274	reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
275	reg |= USB_PHY_PLL_CTL_PLL_SUSPEND_MASK;
276	brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
277
278	/* Init the PHY */
279	reg = USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK |
280		USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK |
281		USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK;
282	brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_LDO_CTL);
283
284	/* wait for lock */
285	while (timeout_ms-- > 0) {
286		reg = brcm_usb_readl(usb_phy + USB_PHY_STATUS);
287		if (reg & USB_PHY_STATUS_pll_lock_MASK)
288			break;
289		usleep_range(1000, 2000);
290	}
291
292	/* Set the PHY_MODE */
293	reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
294	reg &= ~USB_PHY_UTMI_CTL_1_PHY_MODE_MASK;
295	reg |= params->supported_port_modes << USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT;
296	brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
297
298	usb_init_common(params);
299
300	/*
301	 * The BDC controller will get occasional failures with
302	 * the default "Read Transaction Size" of 6 (1024 bytes).
303	 * Set it to 4 (256 bytes).
304	 */
305	if ((params->supported_port_modes != USB_CTLR_MODE_HOST) && bdc_ec) {
306		reg = brcm_usb_readl(bdc_ec + BDC_EC_AXIRDA);
307		reg &= ~BDC_EC_AXIRDA_RTS_MASK;
308		reg |= (0x4 << BDC_EC_AXIRDA_RTS_SHIFT);
309		brcm_usb_writel(reg, bdc_ec + BDC_EC_AXIRDA);
310	}
311
312	/*
313	 * Disable FSM, otherwise the PHY will auto suspend when no
314	 * device is connected and will be reset on resume.
315	 */
316	reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
317	reg &= ~USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
318	brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
319
320	usb2_eye_fix_7211b0(params);
321}
322
323static void usb_init_common_7216(struct brcm_usb_init_params *params)
324{
325	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
326
327	USB_CTRL_UNSET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
328
329	/*
330	 * The PHY might be in a bad state if it is already powered
331	 * up. Toggle the power just in case.
332	 */
333	USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
334	USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
335
336	/* 1 millisecond - for USB clocks to settle down */
337	usleep_range(1000, 2000);
338
339	/*
340	 * Disable PHY when port is suspended
341	 * Does not work in DRD mode
342	 */
343	if (params->supported_port_modes != USB_CTLR_MODE_DRD)
344		USB_CTRL_SET(ctrl, P0_U2PHY_CFG1, COMMONONN);
345
346	usb_wake_enable_7216(params, false);
347	usb_init_common(params);
348}
349
350static void usb_init_xhci(struct brcm_usb_init_params *params)
351{
352	pr_debug("%s\n", __func__);
353
354	xhci_soft_reset(params, 0);
355}
356
357static void usb_uninit_common_7216(struct brcm_usb_init_params *params)
358{
359	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
360
361	pr_debug("%s\n", __func__);
362
363	if (params->wake_enabled) {
364		/* Switch to using slower clock during suspend to save power */
365		USB_CTRL_SET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
366		usb_wake_enable_7216(params, true);
367	} else {
368		USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
369	}
370}
371
372static void usb_uninit_common_7211b0(struct brcm_usb_init_params *params)
373{
374	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
375	void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
376	u32 reg;
377
378	pr_debug("%s\n", __func__);
379
380	if (params->wake_enabled) {
381		USB_CTRL_SET(ctrl, TEST_PORT_CTL, TPOUT_SEL_PME_GEN);
382		usb_wake_enable_7211b0(params, true);
383	} else {
384		USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
385		brcm_usb_writel(0, usb_phy + USB_PHY_PLL_LDO_CTL);
386		reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
387		reg &= ~USB_PHY_PLL_CTL_PLL_RESETB_MASK;
388		brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
389		brcm_usb_writel(USB_PHY_IDDQ_phy_iddq_MASK,
390				usb_phy + USB_PHY_IDDQ);
391	}
392
393}
394
395static void usb_uninit_xhci(struct brcm_usb_init_params *params)
396{
397
398	pr_debug("%s\n", __func__);
399
400	if (!params->wake_enabled)
401		xhci_soft_reset(params, 1);
402}
403
404static int usb_get_dual_select(struct brcm_usb_init_params *params)
405{
406	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
407	u32 reg = 0;
408
409	pr_debug("%s\n", __func__);
410
411	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
412	reg &= USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
413	return reg;
414}
415
416static void usb_set_dual_select(struct brcm_usb_init_params *params)
417{
418	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
419	u32 reg;
420
421	pr_debug("%s\n", __func__);
422
423	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
424	reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
425	reg |= params->port_mode;
426	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
427}
428
429static const struct brcm_usb_init_ops bcm7216_ops = {
430	.init_ipp = usb_init_ipp,
431	.init_common = usb_init_common_7216,
432	.init_xhci = usb_init_xhci,
433	.uninit_common = usb_uninit_common_7216,
434	.uninit_xhci = usb_uninit_xhci,
435	.get_dual_select = usb_get_dual_select,
436	.set_dual_select = usb_set_dual_select,
437};
438
439static const struct brcm_usb_init_ops bcm7211b0_ops = {
440	.init_ipp = usb_init_ipp,
441	.init_common = usb_init_common_7211b0,
442	.init_xhci = usb_init_xhci,
443	.uninit_common = usb_uninit_common_7211b0,
444	.uninit_xhci = usb_uninit_xhci,
445	.get_dual_select = usb_get_dual_select,
446	.set_dual_select = usb_set_dual_select,
447};
448
449void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params)
450{
451
452	pr_debug("%s\n", __func__);
453
454	params->family_name = "7216";
455	params->ops = &bcm7216_ops;
456}
457
458void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params)
459{
460
461	pr_debug("%s\n", __func__);
462
463	params->family_name = "7211";
464	params->ops = &bcm7211b0_ops;
465}