File Index
Files and directories
Sign in
FILE

phy-brcm-usb-init-synopsys.c

File preview with syntax highlighting.

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