14e5b9c9aSAl Cooper // SPDX-License-Identifier: GPL-2.0 24e5b9c9aSAl Cooper /* Copyright (c) 2018, Broadcom */ 34e5b9c9aSAl Cooper 44e5b9c9aSAl Cooper /* 54e5b9c9aSAl Cooper * This module contains USB PHY initialization for power up and S3 resume 64e5b9c9aSAl Cooper * for newer Synopsys based USB hardware first used on the bcm7216. 74e5b9c9aSAl Cooper */ 84e5b9c9aSAl Cooper 94e5b9c9aSAl Cooper #include <linux/delay.h> 104e5b9c9aSAl Cooper #include <linux/io.h> 114e5b9c9aSAl Cooper 124e5b9c9aSAl Cooper #include <linux/soc/brcmstb/brcmstb.h> 134e5b9c9aSAl Cooper #include "phy-brcm-usb-init.h" 144e5b9c9aSAl Cooper 159d5f51dcSAl Cooper #define PHY_LOCK_TIMEOUT_MS 200 169d5f51dcSAl Cooper 179d5f51dcSAl Cooper /* Register definitions for syscon piarbctl registers */ 189d5f51dcSAl Cooper #define PIARBCTL_CAM 0x00 199d5f51dcSAl Cooper #define PIARBCTL_SPLITTER 0x04 209d5f51dcSAl Cooper #define PIARBCTL_MISC 0x08 219d5f51dcSAl Cooper #define PIARBCTL_MISC_SECURE_MASK 0x80000000 229d5f51dcSAl Cooper #define PIARBCTL_MISC_USB_SELECT_MASK 0x40000000 239d5f51dcSAl Cooper #define PIARBCTL_MISC_USB_4G_SDRAM_MASK 0x20000000 249d5f51dcSAl Cooper #define PIARBCTL_MISC_USB_PRIORITY_MASK 0x000f0000 259d5f51dcSAl Cooper #define PIARBCTL_MISC_USB_MEM_PAGE_MASK 0x0000f000 269d5f51dcSAl Cooper #define PIARBCTL_MISC_CAM1_MEM_PAGE_MASK 0x00000f00 279d5f51dcSAl Cooper #define PIARBCTL_MISC_CAM0_MEM_PAGE_MASK 0x000000f0 289d5f51dcSAl Cooper #define PIARBCTL_MISC_SATA_PRIORITY_MASK 0x0000000f 299d5f51dcSAl Cooper #define PIARBCTL_USB_M_ASB_CTRL 0x10 309d5f51dcSAl Cooper 319d5f51dcSAl Cooper #define PIARBCTL_MISC_USB_ONLY_MASK \ 329d5f51dcSAl Cooper (PIARBCTL_MISC_USB_SELECT_MASK | \ 339d5f51dcSAl Cooper PIARBCTL_MISC_USB_4G_SDRAM_MASK | \ 349d5f51dcSAl Cooper PIARBCTL_MISC_USB_PRIORITY_MASK | \ 359d5f51dcSAl Cooper PIARBCTL_MISC_USB_MEM_PAGE_MASK) 369d5f51dcSAl Cooper 374e5b9c9aSAl Cooper /* Register definitions for the USB CTRL block */ 384e5b9c9aSAl Cooper #define USB_CTRL_SETUP 0x00 394e5b9c9aSAl Cooper #define USB_CTRL_SETUP_STRAP_IPP_SEL_MASK 0x02000000 404e5b9c9aSAl Cooper #define USB_CTRL_SETUP_SCB2_EN_MASK 0x00008000 419d5f51dcSAl Cooper #define USB_CTRL_SETUP_tca_drv_sel_MASK 0x01000000 424e5b9c9aSAl Cooper #define USB_CTRL_SETUP_SCB1_EN_MASK 0x00004000 434e5b9c9aSAl Cooper #define USB_CTRL_SETUP_SOFT_SHUTDOWN_MASK 0x00000200 444e5b9c9aSAl Cooper #define USB_CTRL_SETUP_IPP_MASK 0x00000020 454e5b9c9aSAl Cooper #define USB_CTRL_SETUP_IOC_MASK 0x00000010 464e5b9c9aSAl Cooper #define USB_CTRL_USB_PM 0x04 474e5b9c9aSAl Cooper #define USB_CTRL_USB_PM_USB_PWRDN_MASK 0x80000000 484e5b9c9aSAl Cooper #define USB_CTRL_USB_PM_SOFT_RESET_MASK 0x40000000 494e5b9c9aSAl Cooper #define USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK 0x00800000 504e5b9c9aSAl Cooper #define USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK 0x00400000 514e5b9c9aSAl Cooper #define USB_CTRL_USB_PM_STATUS 0x08 524e5b9c9aSAl Cooper #define USB_CTRL_USB_DEVICE_CTL1 0x10 534e5b9c9aSAl Cooper #define USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK 0x00000003 544e5b9c9aSAl Cooper 559d5f51dcSAl Cooper /* Register definitions for the USB_PHY block in 7211b0 */ 569d5f51dcSAl Cooper #define USB_PHY_PLL_LDO_CTL 0x08 579d5f51dcSAl Cooper #define USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK 0x00000004 589d5f51dcSAl Cooper #define USB_PHY_UTMI_CTL_1 0x04 59fc430aeaSAl Cooper #define USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK 0x00000800 609d5f51dcSAl Cooper #define USB_PHY_UTMI_CTL_1_PHY_MODE_MASK 0x0000000c 619d5f51dcSAl Cooper #define USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT 2 629d5f51dcSAl Cooper #define USB_PHY_STATUS 0x20 639d5f51dcSAl Cooper #define USB_PHY_STATUS_pll_lock_MASK 0x00000001 649d5f51dcSAl Cooper 659d5f51dcSAl Cooper /* Register definitions for the MDIO registers in the DWC2 block of 669d5f51dcSAl Cooper * the 7211b0. 679d5f51dcSAl Cooper * NOTE: The PHY's MDIO registers are only accessible through the 689d5f51dcSAl Cooper * legacy DesignWare USB controller even though it's not being used. 699d5f51dcSAl Cooper */ 709d5f51dcSAl Cooper #define USB_GMDIOCSR 0 719d5f51dcSAl Cooper #define USB_GMDIOGEN 4 729d5f51dcSAl Cooper 73*bed63b63SAl Cooper /* Register definitions for the BDC EC block in 7211b0 */ 74*bed63b63SAl Cooper #define BDC_EC_AXIRDA 0x0c 75*bed63b63SAl Cooper #define BDC_EC_AXIRDA_RTS_MASK 0xf0000000 76*bed63b63SAl Cooper #define BDC_EC_AXIRDA_RTS_SHIFT 28 77*bed63b63SAl Cooper 789d5f51dcSAl Cooper 799d5f51dcSAl Cooper static void usb_mdio_write_7211b0(struct brcm_usb_init_params *params, 809d5f51dcSAl Cooper uint8_t addr, uint16_t data) 819d5f51dcSAl Cooper { 829d5f51dcSAl Cooper void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO]; 839d5f51dcSAl Cooper 849d5f51dcSAl Cooper addr &= 0x1f; /* 5-bit address */ 859d5f51dcSAl Cooper brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN); 869d5f51dcSAl Cooper while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31)) 879d5f51dcSAl Cooper ; 889d5f51dcSAl Cooper brcm_usb_writel(0x59020000 | (addr << 18) | data, 899d5f51dcSAl Cooper usb_mdio + USB_GMDIOGEN); 909d5f51dcSAl Cooper while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31)) 919d5f51dcSAl Cooper ; 929d5f51dcSAl Cooper brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN); 939d5f51dcSAl Cooper while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31)) 949d5f51dcSAl Cooper ; 959d5f51dcSAl Cooper } 969d5f51dcSAl Cooper 979d5f51dcSAl Cooper static uint16_t __maybe_unused usb_mdio_read_7211b0( 989d5f51dcSAl Cooper struct brcm_usb_init_params *params, uint8_t addr) 999d5f51dcSAl Cooper { 1009d5f51dcSAl Cooper void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO]; 1019d5f51dcSAl Cooper 1029d5f51dcSAl Cooper addr &= 0x1f; /* 5-bit address */ 1039d5f51dcSAl Cooper brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN); 1049d5f51dcSAl Cooper while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31)) 1059d5f51dcSAl Cooper ; 1069d5f51dcSAl Cooper brcm_usb_writel(0x69020000 | (addr << 18), usb_mdio + USB_GMDIOGEN); 1079d5f51dcSAl Cooper while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31)) 1089d5f51dcSAl Cooper ; 1099d5f51dcSAl Cooper brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN); 1109d5f51dcSAl Cooper while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31)) 1119d5f51dcSAl Cooper ; 1129d5f51dcSAl Cooper return brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & 0xffff; 1139d5f51dcSAl Cooper } 1149d5f51dcSAl Cooper 1159d5f51dcSAl Cooper static void usb2_eye_fix_7211b0(struct brcm_usb_init_params *params) 1169d5f51dcSAl Cooper { 1179d5f51dcSAl Cooper /* select bank */ 1189d5f51dcSAl Cooper usb_mdio_write_7211b0(params, 0x1f, 0x80a0); 1199d5f51dcSAl Cooper 1209d5f51dcSAl Cooper /* Set the eye */ 1219d5f51dcSAl Cooper usb_mdio_write_7211b0(params, 0x0a, 0xc6a0); 1229d5f51dcSAl Cooper } 1234e5b9c9aSAl Cooper 1244e5b9c9aSAl Cooper static void xhci_soft_reset(struct brcm_usb_init_params *params, 1254e5b9c9aSAl Cooper int on_off) 1264e5b9c9aSAl Cooper { 1279d5f51dcSAl Cooper void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; 1284e5b9c9aSAl Cooper 1294e5b9c9aSAl Cooper /* Assert reset */ 1304e5b9c9aSAl Cooper if (on_off) 1314e5b9c9aSAl Cooper USB_CTRL_UNSET(ctrl, USB_PM, XHC_SOFT_RESETB); 1324e5b9c9aSAl Cooper /* De-assert reset */ 1334e5b9c9aSAl Cooper else 1344e5b9c9aSAl Cooper USB_CTRL_SET(ctrl, USB_PM, XHC_SOFT_RESETB); 1354e5b9c9aSAl Cooper } 1364e5b9c9aSAl Cooper 1374e5b9c9aSAl Cooper static void usb_init_ipp(struct brcm_usb_init_params *params) 1384e5b9c9aSAl Cooper { 1399d5f51dcSAl Cooper void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; 1404e5b9c9aSAl Cooper u32 reg; 1414e5b9c9aSAl Cooper u32 orig_reg; 1424e5b9c9aSAl Cooper 1434e5b9c9aSAl Cooper pr_debug("%s\n", __func__); 1444e5b9c9aSAl Cooper 1454e5b9c9aSAl Cooper orig_reg = reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP)); 1464e5b9c9aSAl Cooper if (params->ipp != 2) 1474e5b9c9aSAl Cooper /* override ipp strap pin (if it exits) */ 1484e5b9c9aSAl Cooper reg &= ~(USB_CTRL_MASK(SETUP, STRAP_IPP_SEL)); 1494e5b9c9aSAl Cooper 1504e5b9c9aSAl Cooper /* Override the default OC and PP polarity */ 1514e5b9c9aSAl Cooper reg &= ~(USB_CTRL_MASK(SETUP, IPP) | USB_CTRL_MASK(SETUP, IOC)); 1524e5b9c9aSAl Cooper if (params->ioc) 1534e5b9c9aSAl Cooper reg |= USB_CTRL_MASK(SETUP, IOC); 1544e5b9c9aSAl Cooper if (params->ipp == 1) 1554e5b9c9aSAl Cooper reg |= USB_CTRL_MASK(SETUP, IPP); 1564e5b9c9aSAl Cooper brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP)); 1574e5b9c9aSAl Cooper 1584e5b9c9aSAl Cooper /* 1594e5b9c9aSAl Cooper * If we're changing IPP, make sure power is off long enough 1604e5b9c9aSAl Cooper * to turn off any connected devices. 1614e5b9c9aSAl Cooper */ 1624e5b9c9aSAl Cooper if ((reg ^ orig_reg) & USB_CTRL_MASK(SETUP, IPP)) 1634e5b9c9aSAl Cooper msleep(50); 1644e5b9c9aSAl Cooper } 1654e5b9c9aSAl Cooper 1669d5f51dcSAl Cooper static void syscon_piarbctl_init(struct regmap *rmap) 1679d5f51dcSAl Cooper { 1689d5f51dcSAl Cooper /* Switch from legacy USB OTG controller to new STB USB controller */ 1699d5f51dcSAl Cooper regmap_update_bits(rmap, PIARBCTL_MISC, PIARBCTL_MISC_USB_ONLY_MASK, 1709d5f51dcSAl Cooper PIARBCTL_MISC_USB_SELECT_MASK | 1719d5f51dcSAl Cooper PIARBCTL_MISC_USB_4G_SDRAM_MASK); 1729d5f51dcSAl Cooper } 1739d5f51dcSAl Cooper 1744e5b9c9aSAl Cooper static void usb_init_common(struct brcm_usb_init_params *params) 1754e5b9c9aSAl Cooper { 1764e5b9c9aSAl Cooper u32 reg; 1779d5f51dcSAl Cooper void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; 1784e5b9c9aSAl Cooper 1794e5b9c9aSAl Cooper pr_debug("%s\n", __func__); 1804e5b9c9aSAl Cooper 1814e5b9c9aSAl Cooper USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN); 1824e5b9c9aSAl Cooper /* 1 millisecond - for USB clocks to settle down */ 1834e5b9c9aSAl Cooper usleep_range(1000, 2000); 1844e5b9c9aSAl Cooper 1854e5b9c9aSAl Cooper if (USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE)) { 1864e5b9c9aSAl Cooper reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); 1874e5b9c9aSAl Cooper reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE); 1884e5b9c9aSAl Cooper reg |= params->mode; 1894e5b9c9aSAl Cooper brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); 1904e5b9c9aSAl Cooper } 1914e5b9c9aSAl Cooper switch (params->mode) { 1924e5b9c9aSAl Cooper case USB_CTLR_MODE_HOST: 1934e5b9c9aSAl Cooper USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB); 1944e5b9c9aSAl Cooper break; 1954e5b9c9aSAl Cooper default: 1964e5b9c9aSAl Cooper USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB); 1974e5b9c9aSAl Cooper USB_CTRL_SET(ctrl, USB_PM, BDC_SOFT_RESETB); 1984e5b9c9aSAl Cooper break; 1994e5b9c9aSAl Cooper } 2004e5b9c9aSAl Cooper } 2014e5b9c9aSAl Cooper 2029d5f51dcSAl Cooper static void usb_init_common_7211b0(struct brcm_usb_init_params *params) 2039d5f51dcSAl Cooper { 2049d5f51dcSAl Cooper void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; 2059d5f51dcSAl Cooper void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY]; 206*bed63b63SAl Cooper void __iomem *bdc_ec = params->regs[BRCM_REGS_BDC_EC]; 2079d5f51dcSAl Cooper int timeout_ms = PHY_LOCK_TIMEOUT_MS; 2089d5f51dcSAl Cooper u32 reg; 2099d5f51dcSAl Cooper 2109d5f51dcSAl Cooper if (params->syscon_piarbctl) 2119d5f51dcSAl Cooper syscon_piarbctl_init(params->syscon_piarbctl); 2129d5f51dcSAl Cooper 2139d5f51dcSAl Cooper /* Init the PHY */ 2149d5f51dcSAl Cooper reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_LDO_CTL); 2159d5f51dcSAl Cooper reg |= USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK; 2169d5f51dcSAl Cooper brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_LDO_CTL); 2179d5f51dcSAl Cooper 2189d5f51dcSAl Cooper /* wait for lock */ 2199d5f51dcSAl Cooper while (timeout_ms-- > 0) { 2209d5f51dcSAl Cooper reg = brcm_usb_readl(usb_phy + USB_PHY_STATUS); 2219d5f51dcSAl Cooper if (reg & USB_PHY_STATUS_pll_lock_MASK) 2229d5f51dcSAl Cooper break; 2239d5f51dcSAl Cooper usleep_range(1000, 2000); 2249d5f51dcSAl Cooper } 2259d5f51dcSAl Cooper 2269d5f51dcSAl Cooper /* Set the PHY_MODE */ 2279d5f51dcSAl Cooper reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1); 2289d5f51dcSAl Cooper reg &= ~USB_PHY_UTMI_CTL_1_PHY_MODE_MASK; 2299d5f51dcSAl Cooper reg |= params->mode << USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT; 2309d5f51dcSAl Cooper brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1); 2319d5f51dcSAl Cooper 2329d5f51dcSAl Cooper /* Fix the incorrect default */ 2339d5f51dcSAl Cooper reg = brcm_usb_readl(ctrl + USB_CTRL_SETUP); 2349d5f51dcSAl Cooper reg &= ~USB_CTRL_SETUP_tca_drv_sel_MASK; 2359d5f51dcSAl Cooper brcm_usb_writel(reg, ctrl + USB_CTRL_SETUP); 2369d5f51dcSAl Cooper 2379d5f51dcSAl Cooper usb_init_common(params); 2389d5f51dcSAl Cooper 239fc430aeaSAl Cooper /* 240*bed63b63SAl Cooper * The BDC controller will get occasional failures with 241*bed63b63SAl Cooper * the default "Read Transaction Size" of 6 (1024 bytes). 242*bed63b63SAl Cooper * Set it to 4 (256 bytes). 243*bed63b63SAl Cooper */ 244*bed63b63SAl Cooper if ((params->mode != USB_CTLR_MODE_HOST) && bdc_ec) { 245*bed63b63SAl Cooper reg = brcm_usb_readl(bdc_ec + BDC_EC_AXIRDA); 246*bed63b63SAl Cooper reg &= ~BDC_EC_AXIRDA_RTS_MASK; 247*bed63b63SAl Cooper reg |= (0x4 << BDC_EC_AXIRDA_RTS_SHIFT); 248*bed63b63SAl Cooper brcm_usb_writel(reg, bdc_ec + BDC_EC_AXIRDA); 249*bed63b63SAl Cooper } 250*bed63b63SAl Cooper 251*bed63b63SAl Cooper /* 252fc430aeaSAl Cooper * Disable FSM, otherwise the PHY will auto suspend when no 253fc430aeaSAl Cooper * device is connected and will be reset on resume. 254fc430aeaSAl Cooper */ 255fc430aeaSAl Cooper reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1); 256fc430aeaSAl Cooper reg &= ~USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK; 257fc430aeaSAl Cooper brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1); 258fc430aeaSAl Cooper 2599d5f51dcSAl Cooper usb2_eye_fix_7211b0(params); 2609d5f51dcSAl Cooper } 2619d5f51dcSAl Cooper 2624e5b9c9aSAl Cooper static void usb_init_xhci(struct brcm_usb_init_params *params) 2634e5b9c9aSAl Cooper { 2644e5b9c9aSAl Cooper pr_debug("%s\n", __func__); 2654e5b9c9aSAl Cooper 2664e5b9c9aSAl Cooper xhci_soft_reset(params, 0); 2674e5b9c9aSAl Cooper } 2684e5b9c9aSAl Cooper 2694e5b9c9aSAl Cooper static void usb_uninit_common(struct brcm_usb_init_params *params) 2704e5b9c9aSAl Cooper { 2719d5f51dcSAl Cooper void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; 2724e5b9c9aSAl Cooper 2734e5b9c9aSAl Cooper pr_debug("%s\n", __func__); 2744e5b9c9aSAl Cooper 2754e5b9c9aSAl Cooper USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN); 2764e5b9c9aSAl Cooper 2774e5b9c9aSAl Cooper } 2784e5b9c9aSAl Cooper 2794e5b9c9aSAl Cooper static void usb_uninit_xhci(struct brcm_usb_init_params *params) 2804e5b9c9aSAl Cooper { 2814e5b9c9aSAl Cooper 2824e5b9c9aSAl Cooper pr_debug("%s\n", __func__); 2834e5b9c9aSAl Cooper 2844e5b9c9aSAl Cooper xhci_soft_reset(params, 1); 2854e5b9c9aSAl Cooper } 2864e5b9c9aSAl Cooper 2874e5b9c9aSAl Cooper static int usb_get_dual_select(struct brcm_usb_init_params *params) 2884e5b9c9aSAl Cooper { 2899d5f51dcSAl Cooper void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; 2904e5b9c9aSAl Cooper u32 reg = 0; 2914e5b9c9aSAl Cooper 2924e5b9c9aSAl Cooper pr_debug("%s\n", __func__); 2934e5b9c9aSAl Cooper 2944e5b9c9aSAl Cooper reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); 2954e5b9c9aSAl Cooper reg &= USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE); 2964e5b9c9aSAl Cooper return reg; 2974e5b9c9aSAl Cooper } 2984e5b9c9aSAl Cooper 2994e5b9c9aSAl Cooper static void usb_set_dual_select(struct brcm_usb_init_params *params, int mode) 3004e5b9c9aSAl Cooper { 3019d5f51dcSAl Cooper void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; 3024e5b9c9aSAl Cooper u32 reg; 3034e5b9c9aSAl Cooper 3044e5b9c9aSAl Cooper pr_debug("%s\n", __func__); 3054e5b9c9aSAl Cooper 3064e5b9c9aSAl Cooper reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); 3074e5b9c9aSAl Cooper reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE); 3084e5b9c9aSAl Cooper reg |= mode; 3094e5b9c9aSAl Cooper brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); 3104e5b9c9aSAl Cooper } 3114e5b9c9aSAl Cooper 3124e5b9c9aSAl Cooper 3134e5b9c9aSAl Cooper static const struct brcm_usb_init_ops bcm7216_ops = { 3144e5b9c9aSAl Cooper .init_ipp = usb_init_ipp, 3154e5b9c9aSAl Cooper .init_common = usb_init_common, 3164e5b9c9aSAl Cooper .init_xhci = usb_init_xhci, 3174e5b9c9aSAl Cooper .uninit_common = usb_uninit_common, 3184e5b9c9aSAl Cooper .uninit_xhci = usb_uninit_xhci, 3194e5b9c9aSAl Cooper .get_dual_select = usb_get_dual_select, 3204e5b9c9aSAl Cooper .set_dual_select = usb_set_dual_select, 3214e5b9c9aSAl Cooper }; 3224e5b9c9aSAl Cooper 3239d5f51dcSAl Cooper static const struct brcm_usb_init_ops bcm7211b0_ops = { 3249d5f51dcSAl Cooper .init_ipp = usb_init_ipp, 3259d5f51dcSAl Cooper .init_common = usb_init_common_7211b0, 3269d5f51dcSAl Cooper .init_xhci = usb_init_xhci, 3279d5f51dcSAl Cooper .uninit_common = usb_uninit_common, 3289d5f51dcSAl Cooper .uninit_xhci = usb_uninit_xhci, 3299d5f51dcSAl Cooper .get_dual_select = usb_get_dual_select, 3309d5f51dcSAl Cooper .set_dual_select = usb_set_dual_select, 3319d5f51dcSAl Cooper }; 3329d5f51dcSAl Cooper 3334e5b9c9aSAl Cooper void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params) 3344e5b9c9aSAl Cooper { 3354e5b9c9aSAl Cooper 3364e5b9c9aSAl Cooper pr_debug("%s\n", __func__); 3374e5b9c9aSAl Cooper 3384e5b9c9aSAl Cooper params->family_name = "7216"; 3394e5b9c9aSAl Cooper params->ops = &bcm7216_ops; 3404e5b9c9aSAl Cooper } 3419d5f51dcSAl Cooper 3429d5f51dcSAl Cooper void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params) 3439d5f51dcSAl Cooper { 3449d5f51dcSAl Cooper 3459d5f51dcSAl Cooper pr_debug("%s\n", __func__); 3469d5f51dcSAl Cooper 3479d5f51dcSAl Cooper params->family_name = "7211"; 3489d5f51dcSAl Cooper params->ops = &bcm7211b0_ops; 3499d5f51dcSAl Cooper } 350