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		USB_XHCI_GBL_UNSET(xhci_gbl, GUSB2PHYCFG, U2_FREECLK_EXISTS);
157	}
158}
159
160static void usb_init_ipp(struct brcm_usb_init_params *params)
161{
162	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
163	u32 reg;
164	u32 orig_reg;
165
166	pr_debug("%s\n", __func__);
167
168	orig_reg = reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
169	if (params->ipp != 2)
170		/* override ipp strap pin (if it exits) */
171		reg &= ~(USB_CTRL_MASK(SETUP, STRAP_IPP_SEL));
172
173	/* Override the default OC and PP polarity */
174	reg &= ~(USB_CTRL_MASK(SETUP, IPP) | USB_CTRL_MASK(SETUP, IOC));
175	if (params->ioc)
176		reg |= USB_CTRL_MASK(SETUP, IOC);
177	if (params->ipp == 1)
178		reg |= USB_CTRL_MASK(SETUP, IPP);
179	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
180
181	/*
182	 * If we're changing IPP, make sure power is off long enough
183	 * to turn off any connected devices.
184	 */
185	if ((reg ^ orig_reg) & USB_CTRL_MASK(SETUP, IPP))
186		msleep(50);
187}
188
189static void syscon_piarbctl_init(struct regmap *rmap)
190{
191	/* Switch from legacy USB OTG controller to new STB USB controller */
192	regmap_update_bits(rmap, PIARBCTL_MISC, PIARBCTL_MISC_USB_ONLY_MASK,
193			   PIARBCTL_MISC_USB_SELECT_MASK |
194			   PIARBCTL_MISC_USB_4G_SDRAM_MASK);
195}
196
197static void usb_init_common(struct brcm_usb_init_params *params)
198{
199	u32 reg;
200	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
201
202	pr_debug("%s\n", __func__);
203
204	if (USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE)) {
205		reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
206		reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
207		reg |= params->port_mode;
208		brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
209	}
210	switch (params->supported_port_modes) {
211	case USB_CTLR_MODE_HOST:
212		USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB);
213		break;
214	default:
215		USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB);
216		USB_CTRL_SET(ctrl, USB_PM, BDC_SOFT_RESETB);
217		break;
218	}
219}
220
221static void usb_wake_enable_7211b0(struct brcm_usb_init_params *params,
222				   bool enable)
223{
224	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
225
226	if (enable)
227		USB_CTRL_SET(ctrl, CTLR_CSHCR, ctl_pme_en);
228	else
229		USB_CTRL_UNSET(ctrl, CTLR_CSHCR, ctl_pme_en);
230}
231
232static void usb_wake_enable_7216(struct brcm_usb_init_params *params,
233				 bool enable)
234{
235	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
236
237	if (enable)
238		USB_CTRL_SET(ctrl, USB_PM, XHC_PME_EN);
239	else
240		USB_CTRL_UNSET(ctrl, USB_PM, XHC_PME_EN);
241}
242
243static void usb_init_common_7211b0(struct brcm_usb_init_params *params)
244{
245	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
246	void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
247	void __iomem *bdc_ec = params->regs[BRCM_REGS_BDC_EC];
248	int timeout_ms = PHY_LOCK_TIMEOUT_MS;
249	u32 reg;
250
251	if (params->syscon_piarbctl)
252		syscon_piarbctl_init(params->syscon_piarbctl);
253
254	USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
255
256	usb_wake_enable_7211b0(params, false);
257	if (!params->wake_enabled) {
258
259		/* undo possible suspend settings */
260		brcm_usb_writel(0, usb_phy + USB_PHY_IDDQ);
261		reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
262		reg |= USB_PHY_PLL_CTL_PLL_RESETB_MASK;
263		brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
264
265		/* temporarily enable FSM so PHY comes up properly */
266		reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
267		reg |= USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
268		brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
269	}
270
271	/* Disable PLL auto suspend */
272	reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
273	reg |= USB_PHY_PLL_CTL_PLL_SUSPEND_MASK;
274	brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
275
276	/* Init the PHY */
277	reg = USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK |
278		USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK |
279		USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK;
280	brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_LDO_CTL);
281
282	/* wait for lock */
283	while (timeout_ms-- > 0) {
284		reg = brcm_usb_readl(usb_phy + USB_PHY_STATUS);
285		if (reg & USB_PHY_STATUS_pll_lock_MASK)
286			break;
287		usleep_range(1000, 2000);
288	}
289
290	/* Set the PHY_MODE */
291	reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
292	reg &= ~USB_PHY_UTMI_CTL_1_PHY_MODE_MASK;
293	reg |= params->supported_port_modes << USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT;
294	brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
295
296	usb_init_common(params);
297
298	/*
299	 * The BDC controller will get occasional failures with
300	 * the default "Read Transaction Size" of 6 (1024 bytes).
301	 * Set it to 4 (256 bytes).
302	 */
303	if ((params->supported_port_modes != USB_CTLR_MODE_HOST) && bdc_ec) {
304		reg = brcm_usb_readl(bdc_ec + BDC_EC_AXIRDA);
305		reg &= ~BDC_EC_AXIRDA_RTS_MASK;
306		reg |= (0x4 << BDC_EC_AXIRDA_RTS_SHIFT);
307		brcm_usb_writel(reg, bdc_ec + BDC_EC_AXIRDA);
308	}
309
310	/*
311	 * Disable FSM, otherwise the PHY will auto suspend when no
312	 * device is connected and will be reset on resume.
313	 */
314	reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
315	reg &= ~USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
316	brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
317
318	usb2_eye_fix_7211b0(params);
319}
320
321static void usb_init_common_7216(struct brcm_usb_init_params *params)
322{
323	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
324
325	USB_CTRL_UNSET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
326	USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
327
328	/* 1 millisecond - for USB clocks to settle down */
329	usleep_range(1000, 2000);
330
331	/* Disable PHY when port is suspended */
332	USB_CTRL_SET(ctrl, P0_U2PHY_CFG1, COMMONONN);
333
334	usb_wake_enable_7216(params, false);
335	usb_init_common(params);
336}
337
338static void usb_init_xhci(struct brcm_usb_init_params *params)
339{
340	pr_debug("%s\n", __func__);
341
342	xhci_soft_reset(params, 0);
343}
344
345static void usb_uninit_common_7216(struct brcm_usb_init_params *params)
346{
347	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
348
349	pr_debug("%s\n", __func__);
350
351	if (params->wake_enabled) {
352		/* Switch to using slower clock during suspend to save power */
353		USB_CTRL_SET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
354		usb_wake_enable_7216(params, true);
355	} else {
356		USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
357	}
358}
359
360static void usb_uninit_common_7211b0(struct brcm_usb_init_params *params)
361{
362	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
363	void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
364	u32 reg;
365
366	pr_debug("%s\n", __func__);
367
368	if (params->wake_enabled) {
369		USB_CTRL_SET(ctrl, TEST_PORT_CTL, TPOUT_SEL_PME_GEN);
370		usb_wake_enable_7211b0(params, true);
371	} else {
372		USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
373		brcm_usb_writel(0, usb_phy + USB_PHY_PLL_LDO_CTL);
374		reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
375		reg &= ~USB_PHY_PLL_CTL_PLL_RESETB_MASK;
376		brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
377		brcm_usb_writel(USB_PHY_IDDQ_phy_iddq_MASK,
378				usb_phy + USB_PHY_IDDQ);
379	}
380
381}
382
383static void usb_uninit_xhci(struct brcm_usb_init_params *params)
384{
385
386	pr_debug("%s\n", __func__);
387
388	if (!params->wake_enabled)
389		xhci_soft_reset(params, 1);
390}
391
392static int usb_get_dual_select(struct brcm_usb_init_params *params)
393{
394	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
395	u32 reg = 0;
396
397	pr_debug("%s\n", __func__);
398
399	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
400	reg &= USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
401	return reg;
402}
403
404static void usb_set_dual_select(struct brcm_usb_init_params *params)
405{
406	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
407	u32 reg;
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	reg |= params->port_mode;
414	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
415}
416
417static const struct brcm_usb_init_ops bcm7216_ops = {
418	.init_ipp = usb_init_ipp,
419	.init_common = usb_init_common_7216,
420	.init_xhci = usb_init_xhci,
421	.uninit_common = usb_uninit_common_7216,
422	.uninit_xhci = usb_uninit_xhci,
423	.get_dual_select = usb_get_dual_select,
424	.set_dual_select = usb_set_dual_select,
425};
426
427static const struct brcm_usb_init_ops bcm7211b0_ops = {
428	.init_ipp = usb_init_ipp,
429	.init_common = usb_init_common_7211b0,
430	.init_xhci = usb_init_xhci,
431	.uninit_common = usb_uninit_common_7211b0,
432	.uninit_xhci = usb_uninit_xhci,
433	.get_dual_select = usb_get_dual_select,
434	.set_dual_select = usb_set_dual_select,
435};
436
437void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params)
438{
439
440	pr_debug("%s\n", __func__);
441
442	params->family_name = "7216";
443	params->ops = &bcm7216_ops;
444}
445
446void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params)
447{
448
449	pr_debug("%s\n", __func__);
450
451	params->family_name = "7211";
452	params->ops = &bcm7211b0_ops;
453}