1092 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * phy-brcm-usb-init.c - Broadcom USB Phy chip specific init functions4 *5 * Copyright (C) 2014-2017 Broadcom6 */7 8/*9 * This module contains USB PHY initialization for power up and S3 resume10 */11 12#include <linux/delay.h>13#include <linux/io.h>14 15#include <linux/soc/brcmstb/brcmstb.h>16#include "phy-brcm-usb-init.h"17 18#define PHY_PORTS 219#define PHY_PORT_SELECT_0 020#define PHY_PORT_SELECT_1 0x100021 22/* Register definitions for the USB CTRL block */23#define USB_CTRL_SETUP 0x0024#define USB_CTRL_SETUP_BABO_MASK BIT(0)25#define USB_CTRL_SETUP_FNHW_MASK BIT(1)26#define USB_CTRL_SETUP_FNBO_MASK BIT(2)27#define USB_CTRL_SETUP_WABO_MASK BIT(3)28#define USB_CTRL_SETUP_IOC_MASK BIT(4)29#define USB_CTRL_SETUP_IPP_MASK BIT(5)30#define USB_CTRL_SETUP_SCB_CLIENT_SWAP_MASK BIT(13) /* option */31#define USB_CTRL_SETUP_SCB1_EN_MASK BIT(14) /* option */32#define USB_CTRL_SETUP_SCB2_EN_MASK BIT(15) /* option */33#define USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK BIT(17) /* option */34#define USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK BIT(16) /* option */35#define USB_CTRL_SETUP_STRAP_IPP_SEL_MASK BIT(25) /* option */36#define USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK BIT(26) /* option */37#define USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK BIT(27) /* opt */38#define USB_CTRL_SETUP_OC_DISABLE_PORT0_MASK BIT(28)39#define USB_CTRL_SETUP_OC_DISABLE_PORT1_MASK BIT(29)40#define USB_CTRL_SETUP_OC_DISABLE_MASK GENMASK(29, 28) /* option */41#define USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK BIT(30)42#define USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK BIT(31)43#define USB_CTRL_SETUP_OC3_DISABLE_MASK GENMASK(31, 30) /* option */44#define USB_CTRL_PLL_CTL 0x0445#define USB_CTRL_PLL_CTL_PLL_SUSPEND_EN_MASK BIT(27)46#define USB_CTRL_PLL_CTL_PLL_RESETB_MASK BIT(30)47#define USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK BIT(31) /* option */48#define USB_CTRL_EBRIDGE 0x0c49#define USB_CTRL_EBRIDGE_EBR_SCB_SIZE_MASK GENMASK(11, 7) /* option */50#define USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK BIT(17) /* option */51#define USB_CTRL_OBRIDGE 0x1052#define USB_CTRL_OBRIDGE_LS_KEEP_ALIVE_MASK BIT(27)53#define USB_CTRL_MDIO 0x1454#define USB_CTRL_MDIO2 0x1855#define USB_CTRL_UTMI_CTL_1 0x2c56#define USB_CTRL_UTMI_CTL_1_POWER_UP_FSM_EN_MASK BIT(11)57#define USB_CTRL_UTMI_CTL_1_POWER_UP_FSM_EN_P1_MASK BIT(27)58#define USB_CTRL_USB_PM 0x3459#define USB_CTRL_USB_PM_RMTWKUP_EN_MASK BIT(0)60#define USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK GENMASK(21, 20) /* option */61#define USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK BIT(22) /* option */62#define USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK BIT(23) /* option */63#define USB_CTRL_USB_PM_USB20_HC_RESETB_MASK GENMASK(29, 28) /* option */64#define USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK BIT(30) /* option */65#define USB_CTRL_USB_PM_SOFT_RESET_MASK BIT(30) /* option */66#define USB_CTRL_USB_PM_USB_PWRDN_MASK BIT(31) /* option */67#define USB_CTRL_USB_PM_STATUS 0x3868#define USB_CTRL_USB30_CTL1 0x6069#define USB_CTRL_USB30_CTL1_PHY3_PLL_SEQ_START_MASK BIT(4)70#define USB_CTRL_USB30_CTL1_PHY3_RESETB_MASK BIT(16)71#define USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK BIT(17) /* option */72#define USB_CTRL_USB30_CTL1_USB3_IOC_MASK BIT(28) /* option */73#define USB_CTRL_USB30_CTL1_USB3_IPP_MASK BIT(29) /* option */74#define USB_CTRL_USB30_PCTL 0x7075#define USB_CTRL_USB30_PCTL_PHY3_SOFT_RESETB_MASK BIT(1)76#define USB_CTRL_USB30_PCTL_PHY3_IDDQ_OVERRIDE_MASK BIT(15)77#define USB_CTRL_USB30_PCTL_PHY3_SOFT_RESETB_P1_MASK BIT(17)78#define USB_CTRL_USB_DEVICE_CTL1 0x9079#define USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK GENMASK(1, 0) /* option */80 81/* Register definitions for the XHCI EC block */82#define USB_XHCI_EC_IRAADR 0x65883#define USB_XHCI_EC_IRADAT 0x65c84 85enum brcm_family_type {86 BRCM_FAMILY_3390A0,87 BRCM_FAMILY_4908,88 BRCM_FAMILY_7250B0,89 BRCM_FAMILY_7271A0,90 BRCM_FAMILY_7364A0,91 BRCM_FAMILY_7366C0,92 BRCM_FAMILY_74371A0,93 BRCM_FAMILY_7439B0,94 BRCM_FAMILY_7445D0,95 BRCM_FAMILY_7260A0,96 BRCM_FAMILY_7278A0,97 BRCM_FAMILY_COUNT,98};99 100#define USB_BRCM_FAMILY(chip) \101 [BRCM_FAMILY_##chip] = __stringify(chip)102 103static const char *family_names[BRCM_FAMILY_COUNT] = {104 USB_BRCM_FAMILY(3390A0),105 USB_BRCM_FAMILY(4908),106 USB_BRCM_FAMILY(7250B0),107 USB_BRCM_FAMILY(7271A0),108 USB_BRCM_FAMILY(7364A0),109 USB_BRCM_FAMILY(7366C0),110 USB_BRCM_FAMILY(74371A0),111 USB_BRCM_FAMILY(7439B0),112 USB_BRCM_FAMILY(7445D0),113 USB_BRCM_FAMILY(7260A0),114 USB_BRCM_FAMILY(7278A0),115};116 117enum {118 USB_CTRL_SETUP_SCB1_EN_SELECTOR,119 USB_CTRL_SETUP_SCB2_EN_SELECTOR,120 USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR,121 USB_CTRL_SETUP_STRAP_IPP_SEL_SELECTOR,122 USB_CTRL_SETUP_OC3_DISABLE_PORT0_SELECTOR,123 USB_CTRL_SETUP_OC3_DISABLE_PORT1_SELECTOR,124 USB_CTRL_SETUP_OC3_DISABLE_SELECTOR,125 USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR,126 USB_CTRL_USB_PM_BDC_SOFT_RESETB_SELECTOR,127 USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR,128 USB_CTRL_USB_PM_USB_PWRDN_SELECTOR,129 USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_SELECTOR,130 USB_CTRL_USB30_CTL1_USB3_IOC_SELECTOR,131 USB_CTRL_USB30_CTL1_USB3_IPP_SELECTOR,132 USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_SELECTOR,133 USB_CTRL_USB_PM_SOFT_RESET_SELECTOR,134 USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_SELECTOR,135 USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_SELECTOR,136 USB_CTRL_USB_PM_USB20_HC_RESETB_SELECTOR,137 USB_CTRL_SETUP_ENDIAN_SELECTOR,138 USB_CTRL_SELECTOR_COUNT,139};140 141#define USB_CTRL_MASK_FAMILY(params, reg, field) \142 (params->usb_reg_bits_map[USB_CTRL_##reg##_##field##_SELECTOR])143 144#define USB_CTRL_SET_FAMILY(params, reg, field) \145 usb_ctrl_set_family(params, USB_CTRL_##reg, \146 USB_CTRL_##reg##_##field##_SELECTOR)147#define USB_CTRL_UNSET_FAMILY(params, reg, field) \148 usb_ctrl_unset_family(params, USB_CTRL_##reg, \149 USB_CTRL_##reg##_##field##_SELECTOR)150 151#define MDIO_USB2 0152#define MDIO_USB3 BIT(31)153 154#define USB_CTRL_SETUP_ENDIAN_BITS ( \155 USB_CTRL_MASK(SETUP, BABO) | \156 USB_CTRL_MASK(SETUP, FNHW) | \157 USB_CTRL_MASK(SETUP, FNBO) | \158 USB_CTRL_MASK(SETUP, WABO))159 160#ifdef __LITTLE_ENDIAN161#define ENDIAN_SETTINGS ( \162 USB_CTRL_MASK(SETUP, BABO) | \163 USB_CTRL_MASK(SETUP, FNHW))164#else165#define ENDIAN_SETTINGS ( \166 USB_CTRL_MASK(SETUP, FNHW) | \167 USB_CTRL_MASK(SETUP, FNBO) | \168 USB_CTRL_MASK(SETUP, WABO))169#endif170 171struct id_to_type {172 u32 id;173 int type;174};175 176static const struct id_to_type id_to_type_table[] = {177 { 0x33900000, BRCM_FAMILY_3390A0 },178 { 0x72500010, BRCM_FAMILY_7250B0 },179 { 0x72600000, BRCM_FAMILY_7260A0 },180 { 0x72550000, BRCM_FAMILY_7260A0 },181 { 0x72680000, BRCM_FAMILY_7271A0 },182 { 0x72710000, BRCM_FAMILY_7271A0 },183 { 0x73640000, BRCM_FAMILY_7364A0 },184 { 0x73660020, BRCM_FAMILY_7366C0 },185 { 0x07437100, BRCM_FAMILY_74371A0 },186 { 0x74390010, BRCM_FAMILY_7439B0 },187 { 0x74450030, BRCM_FAMILY_7445D0 },188 { 0x72780000, BRCM_FAMILY_7278A0 },189 { 0, BRCM_FAMILY_7271A0 }, /* default */190};191 192static const u32193usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {194 /* 3390B0 */195 [BRCM_FAMILY_3390A0] = {196 USB_CTRL_SETUP_SCB1_EN_MASK,197 USB_CTRL_SETUP_SCB2_EN_MASK,198 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,199 USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,200 USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,201 USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,202 USB_CTRL_SETUP_OC3_DISABLE_MASK,203 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */204 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */205 USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,206 USB_CTRL_USB_PM_USB_PWRDN_MASK,207 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */208 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */209 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */210 USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,211 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */212 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */213 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */214 USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,215 ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */216 },217 /* 4908 */218 [BRCM_FAMILY_4908] = {219 0, /* USB_CTRL_SETUP_SCB1_EN_MASK */220 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */221 0, /* USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK */222 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */223 0, /* USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK */224 0, /* USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK */225 0, /* USB_CTRL_SETUP_OC3_DISABLE_MASK */226 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */227 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */228 USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,229 USB_CTRL_USB_PM_USB_PWRDN_MASK,230 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */231 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */232 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */233 0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */234 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */235 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */236 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */237 0, /* USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK */238 0, /* USB_CTRL_SETUP ENDIAN bits */239 },240 /* 7250b0 */241 [BRCM_FAMILY_7250B0] = {242 USB_CTRL_SETUP_SCB1_EN_MASK,243 USB_CTRL_SETUP_SCB2_EN_MASK,244 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,245 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */246 USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,247 USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,248 USB_CTRL_SETUP_OC3_DISABLE_MASK,249 USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,250 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */251 USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,252 0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */253 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */254 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */255 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */256 0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */257 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */258 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */259 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */260 USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,261 ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */262 },263 /* 7271a0 */264 [BRCM_FAMILY_7271A0] = {265 0, /* USB_CTRL_SETUP_SCB1_EN_MASK */266 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */267 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,268 USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,269 USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,270 USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,271 USB_CTRL_SETUP_OC3_DISABLE_MASK,272 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */273 USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,274 USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,275 USB_CTRL_USB_PM_USB_PWRDN_MASK,276 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */277 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */278 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */279 USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,280 USB_CTRL_USB_PM_SOFT_RESET_MASK,281 USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK,282 USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK,283 USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,284 ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */285 },286 /* 7364a0 */287 [BRCM_FAMILY_7364A0] = {288 USB_CTRL_SETUP_SCB1_EN_MASK,289 USB_CTRL_SETUP_SCB2_EN_MASK,290 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,291 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */292 USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,293 USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,294 USB_CTRL_SETUP_OC3_DISABLE_MASK,295 USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,296 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */297 USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,298 0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */299 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */300 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */301 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */302 0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */303 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */304 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */305 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */306 USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,307 ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */308 },309 /* 7366c0 */310 [BRCM_FAMILY_7366C0] = {311 USB_CTRL_SETUP_SCB1_EN_MASK,312 USB_CTRL_SETUP_SCB2_EN_MASK,313 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,314 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */315 USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,316 USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,317 USB_CTRL_SETUP_OC3_DISABLE_MASK,318 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */319 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */320 USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,321 USB_CTRL_USB_PM_USB_PWRDN_MASK,322 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */323 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */324 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */325 0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */326 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */327 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */328 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */329 USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,330 ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */331 },332 /* 74371A0 */333 [BRCM_FAMILY_74371A0] = {334 USB_CTRL_SETUP_SCB1_EN_MASK,335 USB_CTRL_SETUP_SCB2_EN_MASK,336 USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK,337 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */338 0, /* USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK */339 0, /* USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK */340 0, /* USB_CTRL_SETUP_OC3_DISABLE_MASK */341 USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,342 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */343 0, /* USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK */344 0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */345 USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK,346 USB_CTRL_USB30_CTL1_USB3_IOC_MASK,347 USB_CTRL_USB30_CTL1_USB3_IPP_MASK,348 0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */349 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */350 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */351 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */352 0, /* USB_CTRL_USB_PM_USB20_HC_RESETB_MASK */353 ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */354 },355 /* 7439B0 */356 [BRCM_FAMILY_7439B0] = {357 USB_CTRL_SETUP_SCB1_EN_MASK,358 USB_CTRL_SETUP_SCB2_EN_MASK,359 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,360 USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,361 USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,362 USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,363 USB_CTRL_SETUP_OC3_DISABLE_MASK,364 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */365 USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,366 USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,367 USB_CTRL_USB_PM_USB_PWRDN_MASK,368 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */369 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */370 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */371 USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,372 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */373 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */374 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */375 USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,376 ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */377 },378 /* 7445d0 */379 [BRCM_FAMILY_7445D0] = {380 USB_CTRL_SETUP_SCB1_EN_MASK,381 USB_CTRL_SETUP_SCB2_EN_MASK,382 USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK,383 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */384 USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,385 USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,386 USB_CTRL_SETUP_OC3_DISABLE_MASK,387 USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,388 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */389 0, /* USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK */390 0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */391 USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK,392 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */393 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */394 0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */395 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */396 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */397 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */398 USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,399 ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */400 },401 /* 7260a0 */402 [BRCM_FAMILY_7260A0] = {403 0, /* USB_CTRL_SETUP_SCB1_EN_MASK */404 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */405 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,406 USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,407 USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,408 USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,409 USB_CTRL_SETUP_OC3_DISABLE_MASK,410 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */411 USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,412 USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,413 USB_CTRL_USB_PM_USB_PWRDN_MASK,414 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */415 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */416 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */417 USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,418 USB_CTRL_USB_PM_SOFT_RESET_MASK,419 USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK,420 USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK,421 USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,422 ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */423 },424 /* 7278a0 */425 [BRCM_FAMILY_7278A0] = {426 0, /* USB_CTRL_SETUP_SCB1_EN_MASK */427 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */428 0, /*USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK */429 USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,430 USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,431 USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,432 USB_CTRL_SETUP_OC3_DISABLE_MASK,433 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */434 USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,435 USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,436 USB_CTRL_USB_PM_USB_PWRDN_MASK,437 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */438 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */439 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */440 USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,441 USB_CTRL_USB_PM_SOFT_RESET_MASK,442 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */443 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */444 0, /* USB_CTRL_USB_PM_USB20_HC_RESETB_MASK */445 0, /* USB_CTRL_SETUP ENDIAN bits */446 },447};448 449static inline450void usb_ctrl_unset_family(struct brcm_usb_init_params *params,451 u32 reg_offset, u32 field)452{453 u32 mask;454 455 mask = params->usb_reg_bits_map[field];456 brcm_usb_ctrl_unset(params->regs[BRCM_REGS_CTRL] + reg_offset, mask);457};458 459static inline460void usb_ctrl_set_family(struct brcm_usb_init_params *params,461 u32 reg_offset, u32 field)462{463 u32 mask;464 465 mask = params->usb_reg_bits_map[field];466 brcm_usb_ctrl_set(params->regs[BRCM_REGS_CTRL] + reg_offset, mask);467};468 469static u32 brcmusb_usb_mdio_read(void __iomem *ctrl_base, u32 reg, int mode)470{471 u32 data;472 473 data = (reg << 16) | mode;474 brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));475 data |= (1 << 24);476 brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));477 data &= ~(1 << 24);478 /* wait for the 60MHz parallel to serial shifter */479 usleep_range(10, 20);480 brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));481 /* wait for the 60MHz parallel to serial shifter */482 usleep_range(10, 20);483 484 return brcm_usb_readl(USB_CTRL_REG(ctrl_base, MDIO2)) & 0xffff;485}486 487static void brcmusb_usb_mdio_write(void __iomem *ctrl_base, u32 reg,488 u32 val, int mode)489{490 u32 data;491 492 data = (reg << 16) | val | mode;493 brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));494 data |= (1 << 25);495 brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));496 data &= ~(1 << 25);497 498 /* wait for the 60MHz parallel to serial shifter */499 usleep_range(10, 20);500 brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));501 /* wait for the 60MHz parallel to serial shifter */502 usleep_range(10, 20);503}504 505static void brcmusb_usb_phy_ldo_fix(void __iomem *ctrl_base)506{507 /* first disable FSM but also leave it that way */508 /* to allow normal suspend/resume */509 USB_CTRL_UNSET(ctrl_base, UTMI_CTL_1, POWER_UP_FSM_EN);510 USB_CTRL_UNSET(ctrl_base, UTMI_CTL_1, POWER_UP_FSM_EN_P1);511 512 /* reset USB 2.0 PLL */513 USB_CTRL_UNSET(ctrl_base, PLL_CTL, PLL_RESETB);514 /* PLL reset period */515 udelay(1);516 USB_CTRL_SET(ctrl_base, PLL_CTL, PLL_RESETB);517 /* Give PLL enough time to lock */518 usleep_range(1000, 2000);519}520 521static void brcmusb_usb2_eye_fix(void __iomem *ctrl_base)522{523 /* Increase USB 2.0 TX level to meet spec requirement */524 brcmusb_usb_mdio_write(ctrl_base, 0x1f, 0x80a0, MDIO_USB2);525 brcmusb_usb_mdio_write(ctrl_base, 0x0a, 0xc6a0, MDIO_USB2);526}527 528static void brcmusb_usb3_pll_fix(void __iomem *ctrl_base)529{530 /* Set correct window for PLL lock detect */531 brcmusb_usb_mdio_write(ctrl_base, 0x1f, 0x8000, MDIO_USB3);532 brcmusb_usb_mdio_write(ctrl_base, 0x07, 0x1503, MDIO_USB3);533}534 535static void brcmusb_usb3_enable_pipe_reset(void __iomem *ctrl_base)536{537 u32 val;538 539 /* Re-enable USB 3.0 pipe reset */540 brcmusb_usb_mdio_write(ctrl_base, 0x1f, 0x8000, MDIO_USB3);541 val = brcmusb_usb_mdio_read(ctrl_base, 0x0f, MDIO_USB3) | 0x200;542 brcmusb_usb_mdio_write(ctrl_base, 0x0f, val, MDIO_USB3);543}544 545static void brcmusb_usb3_enable_sigdet(void __iomem *ctrl_base)546{547 u32 val, ofs;548 int ii;549 550 ofs = 0;551 for (ii = 0; ii < PHY_PORTS; ++ii) {552 /* Set correct default for sigdet */553 brcmusb_usb_mdio_write(ctrl_base, 0x1f, (0x8080 + ofs),554 MDIO_USB3);555 val = brcmusb_usb_mdio_read(ctrl_base, 0x05, MDIO_USB3);556 val = (val & ~0x800f) | 0x800d;557 brcmusb_usb_mdio_write(ctrl_base, 0x05, val, MDIO_USB3);558 ofs = PHY_PORT_SELECT_1;559 }560}561 562static void brcmusb_usb3_enable_skip_align(void __iomem *ctrl_base)563{564 u32 val, ofs;565 int ii;566 567 ofs = 0;568 for (ii = 0; ii < PHY_PORTS; ++ii) {569 /* Set correct default for SKIP align */570 brcmusb_usb_mdio_write(ctrl_base, 0x1f, (0x8060 + ofs),571 MDIO_USB3);572 val = brcmusb_usb_mdio_read(ctrl_base, 0x01, MDIO_USB3) | 0x200;573 brcmusb_usb_mdio_write(ctrl_base, 0x01, val, MDIO_USB3);574 ofs = PHY_PORT_SELECT_1;575 }576}577 578static void brcmusb_usb3_unfreeze_aeq(void __iomem *ctrl_base)579{580 u32 val, ofs;581 int ii;582 583 ofs = 0;584 for (ii = 0; ii < PHY_PORTS; ++ii) {585 /* Let EQ freeze after TSEQ */586 brcmusb_usb_mdio_write(ctrl_base, 0x1f, (0x80e0 + ofs),587 MDIO_USB3);588 val = brcmusb_usb_mdio_read(ctrl_base, 0x01, MDIO_USB3);589 val &= ~0x0008;590 brcmusb_usb_mdio_write(ctrl_base, 0x01, val, MDIO_USB3);591 ofs = PHY_PORT_SELECT_1;592 }593}594 595static void brcmusb_usb3_pll_54mhz(struct brcm_usb_init_params *params)596{597 u32 ofs;598 int ii;599 void __iomem *ctrl_base = params->regs[BRCM_REGS_CTRL];600 601 /*602 * On newer B53 based SoC's, the reference clock for the603 * 3.0 PLL has been changed from 50MHz to 54MHz so the604 * PLL needs to be reprogrammed.605 * See SWLINUX-4006.606 *607 * On the 7364C0, the reference clock for the608 * 3.0 PLL has been changed from 50MHz to 54MHz to609 * work around a MOCA issue.610 * See SWLINUX-4169.611 */612 switch (params->selected_family) {613 case BRCM_FAMILY_3390A0:614 case BRCM_FAMILY_4908:615 case BRCM_FAMILY_7250B0:616 case BRCM_FAMILY_7366C0:617 case BRCM_FAMILY_74371A0:618 case BRCM_FAMILY_7439B0:619 case BRCM_FAMILY_7445D0:620 case BRCM_FAMILY_7260A0:621 return;622 case BRCM_FAMILY_7364A0:623 if (BRCM_REV(params->family_id) < 0x20)624 return;625 break;626 }627 628 /* set USB 3.0 PLL to accept 54Mhz reference clock */629 USB_CTRL_UNSET(ctrl_base, USB30_CTL1, PHY3_PLL_SEQ_START);630 631 brcmusb_usb_mdio_write(ctrl_base, 0x1f, 0x8000, MDIO_USB3);632 brcmusb_usb_mdio_write(ctrl_base, 0x10, 0x5784, MDIO_USB3);633 brcmusb_usb_mdio_write(ctrl_base, 0x11, 0x01d0, MDIO_USB3);634 brcmusb_usb_mdio_write(ctrl_base, 0x12, 0x1DE8, MDIO_USB3);635 brcmusb_usb_mdio_write(ctrl_base, 0x13, 0xAA80, MDIO_USB3);636 brcmusb_usb_mdio_write(ctrl_base, 0x14, 0x8826, MDIO_USB3);637 brcmusb_usb_mdio_write(ctrl_base, 0x15, 0x0044, MDIO_USB3);638 brcmusb_usb_mdio_write(ctrl_base, 0x16, 0x8000, MDIO_USB3);639 brcmusb_usb_mdio_write(ctrl_base, 0x17, 0x0851, MDIO_USB3);640 brcmusb_usb_mdio_write(ctrl_base, 0x18, 0x0000, MDIO_USB3);641 642 /* both ports */643 ofs = 0;644 for (ii = 0; ii < PHY_PORTS; ++ii) {645 brcmusb_usb_mdio_write(ctrl_base, 0x1f, (0x8040 + ofs),646 MDIO_USB3);647 brcmusb_usb_mdio_write(ctrl_base, 0x03, 0x0090, MDIO_USB3);648 brcmusb_usb_mdio_write(ctrl_base, 0x04, 0x0134, MDIO_USB3);649 brcmusb_usb_mdio_write(ctrl_base, 0x1f, (0x8020 + ofs),650 MDIO_USB3);651 brcmusb_usb_mdio_write(ctrl_base, 0x01, 0x00e2, MDIO_USB3);652 ofs = PHY_PORT_SELECT_1;653 }654 655 /* restart PLL sequence */656 USB_CTRL_SET(ctrl_base, USB30_CTL1, PHY3_PLL_SEQ_START);657 /* Give PLL enough time to lock */658 usleep_range(1000, 2000);659}660 661static void brcmusb_usb3_ssc_enable(void __iomem *ctrl_base)662{663 u32 val;664 665 /* Enable USB 3.0 TX spread spectrum */666 brcmusb_usb_mdio_write(ctrl_base, 0x1f, 0x8040, MDIO_USB3);667 val = brcmusb_usb_mdio_read(ctrl_base, 0x01, MDIO_USB3) | 0xf;668 brcmusb_usb_mdio_write(ctrl_base, 0x01, val, MDIO_USB3);669 670 /* Currently, USB 3.0 SSC is enabled via port 0 MDIO registers,671 * which should have been adequate. However, due to a bug in the672 * USB 3.0 PHY, it must be enabled via both ports (HWUSB3DVT-26).673 */674 brcmusb_usb_mdio_write(ctrl_base, 0x1f, 0x9040, MDIO_USB3);675 val = brcmusb_usb_mdio_read(ctrl_base, 0x01, MDIO_USB3) | 0xf;676 brcmusb_usb_mdio_write(ctrl_base, 0x01, val, MDIO_USB3);677}678 679static void brcmusb_usb3_phy_workarounds(struct brcm_usb_init_params *params)680{681 void __iomem *ctrl_base = params->regs[BRCM_REGS_CTRL];682 683 brcmusb_usb3_pll_fix(ctrl_base);684 brcmusb_usb3_pll_54mhz(params);685 brcmusb_usb3_ssc_enable(ctrl_base);686 brcmusb_usb3_enable_pipe_reset(ctrl_base);687 brcmusb_usb3_enable_sigdet(ctrl_base);688 brcmusb_usb3_enable_skip_align(ctrl_base);689 brcmusb_usb3_unfreeze_aeq(ctrl_base);690}691 692static void brcmusb_memc_fix(struct brcm_usb_init_params *params)693{694 u32 prid;695 696 if (params->selected_family != BRCM_FAMILY_7445D0)697 return;698 /*699 * This is a workaround for HW7445-1869 where a DMA write ends up700 * doing a read pre-fetch after the end of the DMA buffer. This701 * causes a problem when the DMA buffer is at the end of physical702 * memory, causing the pre-fetch read to access non-existent memory,703 * and the chip bondout has MEMC2 disabled. When the pre-fetch read704 * tries to use the disabled MEMC2, it hangs the bus. The workaround705 * is to disable MEMC2 access in the usb controller which avoids706 * the hang.707 */708 709 prid = params->product_id & 0xfffff000;710 switch (prid) {711 case 0x72520000:712 case 0x74480000:713 case 0x74490000:714 case 0x07252000:715 case 0x07448000:716 case 0x07449000:717 USB_CTRL_UNSET_FAMILY(params, SETUP, SCB2_EN);718 }719}720 721static void brcmusb_usb3_otp_fix(struct brcm_usb_init_params *params)722{723 void __iomem *xhci_ec_base = params->regs[BRCM_REGS_XHCI_EC];724 u32 val;725 726 if (params->family_id != 0x74371000 || !xhci_ec_base)727 return;728 brcm_usb_writel(0xa20c, USB_XHCI_EC_REG(xhci_ec_base, IRAADR));729 val = brcm_usb_readl(USB_XHCI_EC_REG(xhci_ec_base, IRADAT));730 731 /* set cfg_pick_ss_lock */732 val |= (1 << 27);733 brcm_usb_writel(val, USB_XHCI_EC_REG(xhci_ec_base, IRADAT));734 735 /* Reset USB 3.0 PHY for workaround to take effect */736 USB_CTRL_UNSET(params->regs[BRCM_REGS_CTRL], USB30_CTL1, PHY3_RESETB);737 USB_CTRL_SET(params->regs[BRCM_REGS_CTRL], USB30_CTL1, PHY3_RESETB);738}739 740static void brcmusb_xhci_soft_reset(struct brcm_usb_init_params *params,741 int on_off)742{743 /* Assert reset */744 if (on_off) {745 if (USB_CTRL_MASK_FAMILY(params, USB_PM, XHC_SOFT_RESETB))746 USB_CTRL_UNSET_FAMILY(params, USB_PM, XHC_SOFT_RESETB);747 else748 USB_CTRL_UNSET_FAMILY(params,749 USB30_CTL1, XHC_SOFT_RESETB);750 } else { /* De-assert reset */751 if (USB_CTRL_MASK_FAMILY(params, USB_PM, XHC_SOFT_RESETB))752 USB_CTRL_SET_FAMILY(params, USB_PM, XHC_SOFT_RESETB);753 else754 USB_CTRL_SET_FAMILY(params, USB30_CTL1,755 XHC_SOFT_RESETB);756 }757}758 759/*760 * Return the best map table family. The order is:761 * - exact match of chip and major rev762 * - exact match of chip and closest older major rev763 * - default chip/rev.764 * NOTE: The minor rev is always ignored.765 */766static enum brcm_family_type get_family_type(767 struct brcm_usb_init_params *params)768{769 int last_type = -1;770 u32 last_family = 0;771 u32 family_no_major;772 unsigned int x;773 u32 family;774 775 family = params->family_id & 0xfffffff0;776 family_no_major = params->family_id & 0xffffff00;777 for (x = 0; id_to_type_table[x].id; x++) {778 if (family == id_to_type_table[x].id)779 return id_to_type_table[x].type;780 if (family_no_major == (id_to_type_table[x].id & 0xffffff00))781 if (family > id_to_type_table[x].id &&782 last_family < id_to_type_table[x].id) {783 last_family = id_to_type_table[x].id;784 last_type = id_to_type_table[x].type;785 }786 }787 788 /* If no match, return the default family */789 if (last_type == -1)790 return id_to_type_table[x].type;791 return last_type;792}793 794static void usb_init_ipp(struct brcm_usb_init_params *params)795{796 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];797 u32 reg;798 u32 orig_reg;799 800 /* Starting with the 7445d0, there are no longer separate 3.0801 * versions of IOC and IPP.802 */803 if (USB_CTRL_MASK_FAMILY(params, USB30_CTL1, USB3_IOC)) {804 if (params->ioc)805 USB_CTRL_SET_FAMILY(params, USB30_CTL1, USB3_IOC);806 if (params->ipp == 1)807 USB_CTRL_SET_FAMILY(params, USB30_CTL1, USB3_IPP);808 }809 810 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));811 orig_reg = reg;812 if (USB_CTRL_MASK_FAMILY(params, SETUP, STRAP_CC_DRD_MODE_ENABLE_SEL))813 /* Never use the strap, it's going away. */814 reg &= ~(USB_CTRL_MASK_FAMILY(params,815 SETUP,816 STRAP_CC_DRD_MODE_ENABLE_SEL));817 if (USB_CTRL_MASK_FAMILY(params, SETUP, STRAP_IPP_SEL))818 /* override ipp strap pin (if it exits) */819 if (params->ipp != 2)820 reg &= ~(USB_CTRL_MASK_FAMILY(params, SETUP,821 STRAP_IPP_SEL));822 823 /* Override the default OC and PP polarity */824 reg &= ~(USB_CTRL_MASK(SETUP, IPP) | USB_CTRL_MASK(SETUP, IOC));825 if (params->ioc)826 reg |= USB_CTRL_MASK(SETUP, IOC);827 if (params->ipp == 1)828 reg |= USB_CTRL_MASK(SETUP, IPP);829 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));830 831 /*832 * If we're changing IPP, make sure power is off long enough833 * to turn off any connected devices.834 */835 if ((reg ^ orig_reg) & USB_CTRL_MASK(SETUP, IPP))836 msleep(50);837}838 839static void usb_wake_enable(struct brcm_usb_init_params *params,840 bool enable)841{842 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];843 844 if (enable)845 USB_CTRL_SET(ctrl, USB_PM, RMTWKUP_EN);846 else847 USB_CTRL_UNSET(ctrl, USB_PM, RMTWKUP_EN);848}849 850static void usb_init_common(struct brcm_usb_init_params *params)851{852 u32 reg;853 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];854 855 /* Clear any pending wake conditions */856 usb_wake_enable(params, false);857 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM_STATUS));858 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_PM_STATUS));859 860 /* Take USB out of power down */861 if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN)) {862 USB_CTRL_UNSET_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN);863 /* 1 millisecond - for USB clocks to settle down */864 usleep_range(1000, 2000);865 }866 867 if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB_PWRDN)) {868 USB_CTRL_UNSET_FAMILY(params, USB_PM, USB_PWRDN);869 /* 1 millisecond - for USB clocks to settle down */870 usleep_range(1000, 2000);871 }872 873 if (params->selected_family != BRCM_FAMILY_74371A0 &&874 (BRCM_ID(params->family_id) != 0x7364))875 /*876 * HW7439-637: 7439a0 and its derivatives do not have large877 * enough descriptor storage for this.878 */879 USB_CTRL_SET_FAMILY(params, SETUP, SS_EHCI64BIT_EN);880 881 /* Block auto PLL suspend by USB2 PHY (Sasi) */882 USB_CTRL_SET(ctrl, PLL_CTL, PLL_SUSPEND_EN);883 884 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));885 if (params->selected_family == BRCM_FAMILY_7364A0)886 /* Suppress overcurrent indication from USB30 ports for A0 */887 reg |= USB_CTRL_MASK_FAMILY(params, SETUP, OC3_DISABLE);888 889 brcmusb_usb_phy_ldo_fix(ctrl);890 brcmusb_usb2_eye_fix(ctrl);891 892 /*893 * Make sure the second and third memory controller894 * interfaces are enabled if they exist.895 */896 if (USB_CTRL_MASK_FAMILY(params, SETUP, SCB1_EN))897 reg |= USB_CTRL_MASK_FAMILY(params, SETUP, SCB1_EN);898 if (USB_CTRL_MASK_FAMILY(params, SETUP, SCB2_EN))899 reg |= USB_CTRL_MASK_FAMILY(params, SETUP, SCB2_EN);900 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));901 902 brcmusb_memc_fix(params);903 904 /* Workaround for false positive OC for 7439b2 in DRD/Device mode */905 if ((params->family_id == 0x74390012) &&906 (params->supported_port_modes != USB_CTLR_MODE_HOST)) {907 USB_CTRL_SET(ctrl, SETUP, OC_DISABLE_PORT1);908 USB_CTRL_SET_FAMILY(params, SETUP, OC3_DISABLE_PORT1);909 }910 911 if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {912 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));913 reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,914 PORT_MODE);915 reg |= params->port_mode;916 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));917 }918 if (USB_CTRL_MASK_FAMILY(params, USB_PM, BDC_SOFT_RESETB)) {919 switch (params->supported_port_modes) {920 case USB_CTLR_MODE_HOST:921 USB_CTRL_UNSET_FAMILY(params, USB_PM, BDC_SOFT_RESETB);922 break;923 default:924 USB_CTRL_UNSET_FAMILY(params, USB_PM, BDC_SOFT_RESETB);925 USB_CTRL_SET_FAMILY(params, USB_PM, BDC_SOFT_RESETB);926 break;927 }928 }929 if (USB_CTRL_MASK_FAMILY(params, SETUP, CC_DRD_MODE_ENABLE)) {930 if (params->supported_port_modes == USB_CTLR_MODE_TYPEC_PD)931 USB_CTRL_SET_FAMILY(params, SETUP, CC_DRD_MODE_ENABLE);932 else933 USB_CTRL_UNSET_FAMILY(params, SETUP,934 CC_DRD_MODE_ENABLE);935 }936}937 938static void usb_init_eohci(struct brcm_usb_init_params *params)939{940 u32 reg;941 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];942 943 if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB20_HC_RESETB))944 USB_CTRL_SET_FAMILY(params, USB_PM, USB20_HC_RESETB);945 946 if (params->selected_family == BRCM_FAMILY_7366C0)947 /*948 * Don't enable this so the memory controller doesn't read949 * into memory holes. NOTE: This bit is low true on 7366C0.950 */951 USB_CTRL_SET(ctrl, EBRIDGE, ESTOP_SCB_REQ);952 953 /* Setup the endian bits */954 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));955 reg &= ~USB_CTRL_SETUP_ENDIAN_BITS;956 reg |= USB_CTRL_MASK_FAMILY(params, SETUP, ENDIAN);957 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));958 959 if (params->selected_family == BRCM_FAMILY_7271A0)960 /* Enable LS keep alive fix for certain keyboards */961 USB_CTRL_SET(ctrl, OBRIDGE, LS_KEEP_ALIVE);962 963 if (params->family_id == 0x72550000) {964 /*965 * Make the burst size 512 bytes to fix a hardware bug966 * on the 7255a0. See HW7255-24.967 */968 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, EBRIDGE));969 reg &= ~USB_CTRL_MASK(EBRIDGE, EBR_SCB_SIZE);970 reg |= 0x800;971 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, EBRIDGE));972 }973}974 975static void usb_init_xhci(struct brcm_usb_init_params *params)976{977 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];978 979 USB_CTRL_UNSET(ctrl, USB30_PCTL, PHY3_IDDQ_OVERRIDE);980 /* 1 millisecond - for USB clocks to settle down */981 usleep_range(1000, 2000);982 983 if (BRCM_ID(params->family_id) == 0x7366) {984 /*985 * The PHY3_SOFT_RESETB bits default to the wrong state.986 */987 USB_CTRL_SET(ctrl, USB30_PCTL, PHY3_SOFT_RESETB);988 USB_CTRL_SET(ctrl, USB30_PCTL, PHY3_SOFT_RESETB_P1);989 }990 991 /*992 * Kick start USB3 PHY993 * Make sure it's low to insure a rising edge.994 */995 USB_CTRL_UNSET(ctrl, USB30_CTL1, PHY3_PLL_SEQ_START);996 USB_CTRL_SET(ctrl, USB30_CTL1, PHY3_PLL_SEQ_START);997 998 brcmusb_usb3_phy_workarounds(params);999 brcmusb_xhci_soft_reset(params, 0);1000 brcmusb_usb3_otp_fix(params);1001}1002 1003static void usb_uninit_common(struct brcm_usb_init_params *params)1004{1005 if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB_PWRDN))1006 USB_CTRL_SET_FAMILY(params, USB_PM, USB_PWRDN);1007 1008 if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN))1009 USB_CTRL_SET_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN);1010 if (params->wake_enabled)1011 usb_wake_enable(params, true);1012}1013 1014static void usb_uninit_eohci(struct brcm_usb_init_params *params)1015{1016}1017 1018static void usb_uninit_xhci(struct brcm_usb_init_params *params)1019{1020 brcmusb_xhci_soft_reset(params, 1);1021 USB_CTRL_SET(params->regs[BRCM_REGS_CTRL], USB30_PCTL,1022 PHY3_IDDQ_OVERRIDE);1023}1024 1025static int usb_get_dual_select(struct brcm_usb_init_params *params)1026{1027 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];1028 u32 reg = 0;1029 1030 pr_debug("%s\n", __func__);1031 if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {1032 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));1033 reg &= USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,1034 PORT_MODE);1035 }1036 return reg;1037}1038 1039static void usb_set_dual_select(struct brcm_usb_init_params *params)1040{1041 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];1042 u32 reg;1043 1044 pr_debug("%s\n", __func__);1045 1046 if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {1047 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));1048 reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,1049 PORT_MODE);1050 reg |= params->port_mode;1051 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));1052 }1053}1054 1055static const struct brcm_usb_init_ops bcm7445_ops = {1056 .init_ipp = usb_init_ipp,1057 .init_common = usb_init_common,1058 .init_eohci = usb_init_eohci,1059 .init_xhci = usb_init_xhci,1060 .uninit_common = usb_uninit_common,1061 .uninit_eohci = usb_uninit_eohci,1062 .uninit_xhci = usb_uninit_xhci,1063 .get_dual_select = usb_get_dual_select,1064 .set_dual_select = usb_set_dual_select,1065};1066 1067void brcm_usb_dvr_init_4908(struct brcm_usb_init_params *params)1068{1069 int fam;1070 1071 fam = BRCM_FAMILY_4908;1072 params->selected_family = fam;1073 params->usb_reg_bits_map =1074 &usb_reg_bits_map_table[fam][0];1075 params->family_name = family_names[fam];1076 params->ops = &bcm7445_ops;1077}1078 1079void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params)1080{1081 int fam;1082 1083 pr_debug("%s\n", __func__);1084 1085 fam = get_family_type(params);1086 params->selected_family = fam;1087 params->usb_reg_bits_map =1088 &usb_reg_bits_map_table[fam][0];1089 params->family_name = family_names[fam];1090 params->ops = &bcm7445_ops;1091}1092