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_SECURE_MASK			0x80000000
 22#define   PIARBCTL_MISC_USB_SELECT_MASK			0x40000000
 23#define   PIARBCTL_MISC_USB_4G_SDRAM_MASK		0x20000000
 24#define   PIARBCTL_MISC_USB_PRIORITY_MASK		0x000f0000
 25#define   PIARBCTL_MISC_USB_MEM_PAGE_MASK		0x0000f000
 26#define   PIARBCTL_MISC_CAM1_MEM_PAGE_MASK		0x00000f00
 27#define   PIARBCTL_MISC_CAM0_MEM_PAGE_MASK		0x000000f0
 28#define   PIARBCTL_MISC_SATA_PRIORITY_MASK		0x0000000f
 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_STRAP_IPP_SEL_MASK		0x02000000
 39#define   USB_CTRL_SETUP_SCB2_EN_MASK			0x00008000
 40#define   USB_CTRL_SETUP_tca_drv_sel_MASK		0x01000000
 41#define   USB_CTRL_SETUP_SCB1_EN_MASK			0x00004000
 42#define   USB_CTRL_SETUP_SOFT_SHUTDOWN_MASK		0x00000200
 43#define   USB_CTRL_SETUP_IPP_MASK			0x00000020
 44#define   USB_CTRL_SETUP_IOC_MASK			0x00000010
 45#define USB_CTRL_USB_PM			0x04
 46#define   USB_CTRL_USB_PM_USB_PWRDN_MASK		0x80000000
 47#define   USB_CTRL_USB_PM_SOFT_RESET_MASK		0x40000000
 48#define   USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK		0x00800000
 49#define   USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK		0x00400000
 50#define USB_CTRL_USB_PM_STATUS		0x08
 51#define USB_CTRL_USB_DEVICE_CTL1	0x10
 52#define   USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK	0x00000003
 53#define USB_CTRL_TEST_PORT_CTL		0x30
 54#define   USB_CTRL_TEST_PORT_CTL_TPOUT_SEL_MASK	0x000000ff
 55#define   USB_CTRL_TEST_PORT_CTL_TPOUT_SEL_PME_GEN_MASK	0x0000002e
 56#define USB_CTRL_TP_DIAG1		0x34
 57#define   USB_CTLR_TP_DIAG1_wake_MASK	0x00000002
 58#define USB_CTRL_CTLR_CSHCR		0x50
 59#define   USB_CTRL_CTLR_CSHCR_ctl_pme_en_MASK	0x00040000
 60
 61/* Register definitions for the USB_PHY block in 7211b0 */
 62#define USB_PHY_PLL_CTL			0x00
 63#define   USB_PHY_PLL_CTL_PLL_RESETB_MASK		0x40000000
 64#define USB_PHY_PLL_LDO_CTL		0x08
 65#define   USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK		0x00000004
 66#define   USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK	0x00000002
 67#define   USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK	0x00000001
 68#define USB_PHY_UTMI_CTL_1		0x04
 69#define   USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK	0x00000800
 70#define   USB_PHY_UTMI_CTL_1_PHY_MODE_MASK		0x0000000c
 71#define   USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT		2
 72#define USB_PHY_IDDQ			0x1c
 73#define   USB_PHY_IDDQ_phy_iddq_MASK			0x00000001
 74#define USB_PHY_STATUS			0x20
 75#define   USB_PHY_STATUS_pll_lock_MASK			0x00000001
 76
 77/* Register definitions for the MDIO registers in the DWC2 block of
 78 * the 7211b0.
 79 * NOTE: The PHY's MDIO registers are only accessible through the
 80 * legacy DesignWare USB controller even though it's not being used.
 81 */
 82#define USB_GMDIOCSR	0
 83#define USB_GMDIOGEN	4
 84
 85/* Register definitions for the BDC EC block in 7211b0 */
 86#define BDC_EC_AXIRDA			0x0c
 87#define   BDC_EC_AXIRDA_RTS_MASK			0xf0000000
 88#define   BDC_EC_AXIRDA_RTS_SHIFT			28
 89
 90
 91static void usb_mdio_write_7211b0(struct brcm_usb_init_params *params,
 92				  uint8_t addr, uint16_t data)
 93{
 94	void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO];
 95
 96	addr &= 0x1f; /* 5-bit address */
 97	brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN);
 98	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
 99		;
100	brcm_usb_writel(0x59020000 | (addr << 18) | data,
101			usb_mdio + USB_GMDIOGEN);
102	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
103		;
104	brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN);
105	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
106		;
107}
108
109static uint16_t __maybe_unused usb_mdio_read_7211b0(
110	struct brcm_usb_init_params *params, uint8_t addr)
111{
112	void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO];
113
114	addr &= 0x1f; /* 5-bit address */
115	brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN);
116	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
117		;
118	brcm_usb_writel(0x69020000 | (addr << 18), usb_mdio + USB_GMDIOGEN);
119	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
120		;
121	brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN);
122	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
123		;
124	return brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & 0xffff;
125}
126
127static void usb2_eye_fix_7211b0(struct brcm_usb_init_params *params)
128{
129	/* select bank */
130	usb_mdio_write_7211b0(params, 0x1f, 0x80a0);
131
132	/* Set the eye */
133	usb_mdio_write_7211b0(params, 0x0a, 0xc6a0);
134}
135
136static void xhci_soft_reset(struct brcm_usb_init_params *params,
137			int on_off)
138{
139	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
140
141	/* Assert reset */
142	if (on_off)
143		USB_CTRL_UNSET(ctrl, USB_PM, XHC_SOFT_RESETB);
144	/* De-assert reset */
145	else
146		USB_CTRL_SET(ctrl, USB_PM, XHC_SOFT_RESETB);
147}
148
149static void usb_init_ipp(struct brcm_usb_init_params *params)
150{
151	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
152	u32 reg;
153	u32 orig_reg;
154
155	pr_debug("%s\n", __func__);
156
157	orig_reg = reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
158	if (params->ipp != 2)
159		/* override ipp strap pin (if it exits) */
160		reg &= ~(USB_CTRL_MASK(SETUP, STRAP_IPP_SEL));
161
162	/* Override the default OC and PP polarity */
163	reg &= ~(USB_CTRL_MASK(SETUP, IPP) | USB_CTRL_MASK(SETUP, IOC));
164	if (params->ioc)
165		reg |= USB_CTRL_MASK(SETUP, IOC);
166	if (params->ipp == 1)
167		reg |= USB_CTRL_MASK(SETUP, IPP);
168	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
169
170	/*
171	 * If we're changing IPP, make sure power is off long enough
172	 * to turn off any connected devices.
173	 */
174	if ((reg ^ orig_reg) & USB_CTRL_MASK(SETUP, IPP))
175		msleep(50);
176}
177
178static void syscon_piarbctl_init(struct regmap *rmap)
179{
180	/* Switch from legacy USB OTG controller to new STB USB controller */
181	regmap_update_bits(rmap, PIARBCTL_MISC, PIARBCTL_MISC_USB_ONLY_MASK,
182			   PIARBCTL_MISC_USB_SELECT_MASK |
183			   PIARBCTL_MISC_USB_4G_SDRAM_MASK);
184}
185
186static void usb_init_common(struct brcm_usb_init_params *params)
187{
188	u32 reg;
189	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
190
191	pr_debug("%s\n", __func__);
192
193	USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
194	/* 1 millisecond - for USB clocks to settle down */
195	usleep_range(1000, 2000);
196
197	if (USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE)) {
198		reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
199		reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
200		reg |= params->mode;
201		brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
202	}
203	switch (params->mode) {
204	case USB_CTLR_MODE_HOST:
205		USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB);
206		break;
207	default:
208		USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB);
209		USB_CTRL_SET(ctrl, USB_PM, BDC_SOFT_RESETB);
210		break;
211	}
212}
213
214static void usb_wake_enable_7211b0(struct brcm_usb_init_params *params,
215				   bool enable)
216{
217	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
218
219	if (enable)
220		USB_CTRL_SET(ctrl, CTLR_CSHCR, ctl_pme_en);
221	else
222		USB_CTRL_UNSET(ctrl, CTLR_CSHCR, ctl_pme_en);
223}
224
225static void usb_init_common_7211b0(struct brcm_usb_init_params *params)
226{
227	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
228	void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
229	void __iomem *bdc_ec = params->regs[BRCM_REGS_BDC_EC];
230	int timeout_ms = PHY_LOCK_TIMEOUT_MS;
231	u32 reg;
232
233	if (params->syscon_piarbctl)
234		syscon_piarbctl_init(params->syscon_piarbctl);
235
236	USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
237
238	usb_wake_enable_7211b0(params, false);
239	if (!params->wake_enabled) {
240
241		/* undo possible suspend settings */
242		brcm_usb_writel(0, usb_phy + USB_PHY_IDDQ);
243		reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
244		reg |= USB_PHY_PLL_CTL_PLL_RESETB_MASK;
245		brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
246
247		/* temporarily enable FSM so PHY comes up properly */
248		reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
249		reg |= USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
250		brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
251	}
252
253	/* Init the PHY */
254	reg = USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK |
255		USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK |
256		USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK;
257	brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_LDO_CTL);
258
259	/* wait for lock */
260	while (timeout_ms-- > 0) {
261		reg = brcm_usb_readl(usb_phy + USB_PHY_STATUS);
262		if (reg & USB_PHY_STATUS_pll_lock_MASK)
263			break;
264		usleep_range(1000, 2000);
265	}
266
267	/* Set the PHY_MODE */
268	reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
269	reg &= ~USB_PHY_UTMI_CTL_1_PHY_MODE_MASK;
270	reg |= params->mode << USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT;
271	brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
272
273	/* Fix the incorrect default */
274	reg = brcm_usb_readl(ctrl + USB_CTRL_SETUP);
275	reg &= ~USB_CTRL_SETUP_tca_drv_sel_MASK;
276	brcm_usb_writel(reg, ctrl + USB_CTRL_SETUP);
277
278	usb_init_common(params);
279
280	/*
281	 * The BDC controller will get occasional failures with
282	 * the default "Read Transaction Size" of 6 (1024 bytes).
283	 * Set it to 4 (256 bytes).
284	 */
285	if ((params->mode != USB_CTLR_MODE_HOST) && bdc_ec) {
286		reg = brcm_usb_readl(bdc_ec + BDC_EC_AXIRDA);
287		reg &= ~BDC_EC_AXIRDA_RTS_MASK;
288		reg |= (0x4 << BDC_EC_AXIRDA_RTS_SHIFT);
289		brcm_usb_writel(reg, bdc_ec + BDC_EC_AXIRDA);
290	}
291
292	/*
293	 * Disable FSM, otherwise the PHY will auto suspend when no
294	 * device is connected and will be reset on resume.
295	 */
296	reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
297	reg &= ~USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
298	brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
299
300	usb2_eye_fix_7211b0(params);
301}
302
303static void usb_init_xhci(struct brcm_usb_init_params *params)
304{
305	pr_debug("%s\n", __func__);
306
307	xhci_soft_reset(params, 0);
308}
309
310static void usb_uninit_common(struct brcm_usb_init_params *params)
311{
312	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
313
314	pr_debug("%s\n", __func__);
315
316	USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
317
318}
319
320static void usb_uninit_common_7211b0(struct brcm_usb_init_params *params)
321{
322	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
323	void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
324	u32 reg;
325
326	pr_debug("%s\n", __func__);
327
328	if (params->wake_enabled) {
329		USB_CTRL_SET(ctrl, TEST_PORT_CTL, TPOUT_SEL_PME_GEN);
330		usb_wake_enable_7211b0(params, true);
331	} else {
332		USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
333		brcm_usb_writel(0, usb_phy + USB_PHY_PLL_LDO_CTL);
334		reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
335		reg &= ~USB_PHY_PLL_CTL_PLL_RESETB_MASK;
336		brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
337		brcm_usb_writel(USB_PHY_IDDQ_phy_iddq_MASK,
338				usb_phy + USB_PHY_IDDQ);
339	}
340
341}
342
343static void usb_uninit_xhci(struct brcm_usb_init_params *params)
344{
345
346	pr_debug("%s\n", __func__);
347
348	if (!params->wake_enabled)
349		xhci_soft_reset(params, 1);
350}
351
352static int usb_get_dual_select(struct brcm_usb_init_params *params)
353{
354	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
355	u32 reg = 0;
356
357	pr_debug("%s\n", __func__);
358
359	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
360	reg &= USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
361	return reg;
362}
363
364static void usb_set_dual_select(struct brcm_usb_init_params *params, int mode)
365{
366	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
367	u32 reg;
368
369	pr_debug("%s\n", __func__);
370
371	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
372	reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
373	reg |= mode;
374	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
375}
376
377static const struct brcm_usb_init_ops bcm7216_ops = {
378	.init_ipp = usb_init_ipp,
379	.init_common = usb_init_common,
380	.init_xhci = usb_init_xhci,
381	.uninit_common = usb_uninit_common,
382	.uninit_xhci = usb_uninit_xhci,
383	.get_dual_select = usb_get_dual_select,
384	.set_dual_select = usb_set_dual_select,
385};
386
387static const struct brcm_usb_init_ops bcm7211b0_ops = {
388	.init_ipp = usb_init_ipp,
389	.init_common = usb_init_common_7211b0,
390	.init_xhci = usb_init_xhci,
391	.uninit_common = usb_uninit_common_7211b0,
392	.uninit_xhci = usb_uninit_xhci,
393	.get_dual_select = usb_get_dual_select,
394	.set_dual_select = usb_set_dual_select,
395};
396
397void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params)
398{
399
400	pr_debug("%s\n", __func__);
401
402	params->family_name = "7216";
403	params->ops = &bcm7216_ops;
404}
405
406void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params)
407{
408
409	pr_debug("%s\n", __func__);
410
411	params->family_name = "7211";
412	params->ops = &bcm7211b0_ops;
413	params->suspend_with_clocks = true;
414}