0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/delay.h>
0013 #include <linux/io.h>
0014
0015 #include <linux/soc/brcmstb/brcmstb.h>
0016 #include "phy-brcm-usb-init.h"
0017
0018 #define PHY_PORTS 2
0019 #define PHY_PORT_SELECT_0 0
0020 #define PHY_PORT_SELECT_1 0x1000
0021
0022
0023 #define USB_CTRL_SETUP 0x00
0024 #define USB_CTRL_SETUP_IOC_MASK 0x00000010
0025 #define USB_CTRL_SETUP_IPP_MASK 0x00000020
0026 #define USB_CTRL_SETUP_BABO_MASK 0x00000001
0027 #define USB_CTRL_SETUP_FNHW_MASK 0x00000002
0028 #define USB_CTRL_SETUP_FNBO_MASK 0x00000004
0029 #define USB_CTRL_SETUP_WABO_MASK 0x00000008
0030 #define USB_CTRL_SETUP_SCB_CLIENT_SWAP_MASK 0x00002000
0031 #define USB_CTRL_SETUP_SCB1_EN_MASK 0x00004000
0032 #define USB_CTRL_SETUP_SCB2_EN_MASK 0x00008000
0033 #define USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK 0X00020000
0034 #define USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK 0x00010000
0035 #define USB_CTRL_SETUP_STRAP_IPP_SEL_MASK 0x02000000
0036 #define USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK 0x04000000
0037 #define USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK 0x08000000
0038 #define USB_CTRL_SETUP_OC3_DISABLE_MASK 0xc0000000
0039 #define USB_CTRL_PLL_CTL 0x04
0040 #define USB_CTRL_PLL_CTL_PLL_SUSPEND_EN_MASK 0x08000000
0041 #define USB_CTRL_PLL_CTL_PLL_RESETB_MASK 0x40000000
0042 #define USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK 0x80000000
0043 #define USB_CTRL_EBRIDGE 0x0c
0044 #define USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK 0x00020000
0045 #define USB_CTRL_EBRIDGE_EBR_SCB_SIZE_MASK 0x00000f80
0046 #define USB_CTRL_OBRIDGE 0x10
0047 #define USB_CTRL_OBRIDGE_LS_KEEP_ALIVE_MASK 0x08000000
0048 #define USB_CTRL_MDIO 0x14
0049 #define USB_CTRL_MDIO2 0x18
0050 #define USB_CTRL_UTMI_CTL_1 0x2c
0051 #define USB_CTRL_UTMI_CTL_1_POWER_UP_FSM_EN_MASK 0x00000800
0052 #define USB_CTRL_UTMI_CTL_1_POWER_UP_FSM_EN_P1_MASK 0x08000000
0053 #define USB_CTRL_USB_PM 0x34
0054 #define USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK 0x00800000
0055 #define USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK 0x00400000
0056 #define USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK 0x40000000
0057 #define USB_CTRL_USB_PM_USB_PWRDN_MASK 0x80000000
0058 #define USB_CTRL_USB_PM_SOFT_RESET_MASK 0x40000000
0059 #define USB_CTRL_USB_PM_USB20_HC_RESETB_MASK 0x30000000
0060 #define USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK 0x00300000
0061 #define USB_CTRL_USB_PM_RMTWKUP_EN_MASK 0x00000001
0062 #define USB_CTRL_USB_PM_STATUS 0x38
0063 #define USB_CTRL_USB30_CTL1 0x60
0064 #define USB_CTRL_USB30_CTL1_PHY3_PLL_SEQ_START_MASK 0x00000010
0065 #define USB_CTRL_USB30_CTL1_PHY3_RESETB_MASK 0x00010000
0066 #define USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK 0x00020000
0067 #define USB_CTRL_USB30_CTL1_USB3_IOC_MASK 0x10000000
0068 #define USB_CTRL_USB30_CTL1_USB3_IPP_MASK 0x20000000
0069 #define USB_CTRL_USB30_PCTL 0x70
0070 #define USB_CTRL_USB30_PCTL_PHY3_SOFT_RESETB_MASK 0x00000002
0071 #define USB_CTRL_USB30_PCTL_PHY3_IDDQ_OVERRIDE_MASK 0x00008000
0072 #define USB_CTRL_USB30_PCTL_PHY3_SOFT_RESETB_P1_MASK 0x00020000
0073 #define USB_CTRL_USB_DEVICE_CTL1 0x90
0074 #define USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK 0x00000003
0075
0076
0077 #define USB_XHCI_EC_IRAADR 0x658
0078 #define USB_XHCI_EC_IRADAT 0x65c
0079
0080 enum brcm_family_type {
0081 BRCM_FAMILY_3390A0,
0082 BRCM_FAMILY_4908,
0083 BRCM_FAMILY_7250B0,
0084 BRCM_FAMILY_7271A0,
0085 BRCM_FAMILY_7364A0,
0086 BRCM_FAMILY_7366C0,
0087 BRCM_FAMILY_74371A0,
0088 BRCM_FAMILY_7439B0,
0089 BRCM_FAMILY_7445D0,
0090 BRCM_FAMILY_7260A0,
0091 BRCM_FAMILY_7278A0,
0092 BRCM_FAMILY_COUNT,
0093 };
0094
0095 #define USB_BRCM_FAMILY(chip) \
0096 [BRCM_FAMILY_##chip] = __stringify(chip)
0097
0098 static const char *family_names[BRCM_FAMILY_COUNT] = {
0099 USB_BRCM_FAMILY(3390A0),
0100 USB_BRCM_FAMILY(4908),
0101 USB_BRCM_FAMILY(7250B0),
0102 USB_BRCM_FAMILY(7271A0),
0103 USB_BRCM_FAMILY(7364A0),
0104 USB_BRCM_FAMILY(7366C0),
0105 USB_BRCM_FAMILY(74371A0),
0106 USB_BRCM_FAMILY(7439B0),
0107 USB_BRCM_FAMILY(7445D0),
0108 USB_BRCM_FAMILY(7260A0),
0109 USB_BRCM_FAMILY(7278A0),
0110 };
0111
0112 enum {
0113 USB_CTRL_SETUP_SCB1_EN_SELECTOR,
0114 USB_CTRL_SETUP_SCB2_EN_SELECTOR,
0115 USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR,
0116 USB_CTRL_SETUP_STRAP_IPP_SEL_SELECTOR,
0117 USB_CTRL_SETUP_OC3_DISABLE_SELECTOR,
0118 USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR,
0119 USB_CTRL_USB_PM_BDC_SOFT_RESETB_SELECTOR,
0120 USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR,
0121 USB_CTRL_USB_PM_USB_PWRDN_SELECTOR,
0122 USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_SELECTOR,
0123 USB_CTRL_USB30_CTL1_USB3_IOC_SELECTOR,
0124 USB_CTRL_USB30_CTL1_USB3_IPP_SELECTOR,
0125 USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_SELECTOR,
0126 USB_CTRL_USB_PM_SOFT_RESET_SELECTOR,
0127 USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_SELECTOR,
0128 USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_SELECTOR,
0129 USB_CTRL_USB_PM_USB20_HC_RESETB_SELECTOR,
0130 USB_CTRL_SETUP_ENDIAN_SELECTOR,
0131 USB_CTRL_SELECTOR_COUNT,
0132 };
0133
0134 #define USB_CTRL_MASK_FAMILY(params, reg, field) \
0135 (params->usb_reg_bits_map[USB_CTRL_##reg##_##field##_SELECTOR])
0136
0137 #define USB_CTRL_SET_FAMILY(params, reg, field) \
0138 usb_ctrl_set_family(params, USB_CTRL_##reg, \
0139 USB_CTRL_##reg##_##field##_SELECTOR)
0140 #define USB_CTRL_UNSET_FAMILY(params, reg, field) \
0141 usb_ctrl_unset_family(params, USB_CTRL_##reg, \
0142 USB_CTRL_##reg##_##field##_SELECTOR)
0143
0144 #define MDIO_USB2 0
0145 #define MDIO_USB3 BIT(31)
0146
0147 #define USB_CTRL_SETUP_ENDIAN_BITS ( \
0148 USB_CTRL_MASK(SETUP, BABO) | \
0149 USB_CTRL_MASK(SETUP, FNHW) | \
0150 USB_CTRL_MASK(SETUP, FNBO) | \
0151 USB_CTRL_MASK(SETUP, WABO))
0152
0153 #ifdef __LITTLE_ENDIAN
0154 #define ENDIAN_SETTINGS ( \
0155 USB_CTRL_MASK(SETUP, BABO) | \
0156 USB_CTRL_MASK(SETUP, FNHW))
0157 #else
0158 #define ENDIAN_SETTINGS ( \
0159 USB_CTRL_MASK(SETUP, FNHW) | \
0160 USB_CTRL_MASK(SETUP, FNBO) | \
0161 USB_CTRL_MASK(SETUP, WABO))
0162 #endif
0163
0164 struct id_to_type {
0165 u32 id;
0166 int type;
0167 };
0168
0169 static const struct id_to_type id_to_type_table[] = {
0170 { 0x33900000, BRCM_FAMILY_3390A0 },
0171 { 0x72500010, BRCM_FAMILY_7250B0 },
0172 { 0x72600000, BRCM_FAMILY_7260A0 },
0173 { 0x72550000, BRCM_FAMILY_7260A0 },
0174 { 0x72680000, BRCM_FAMILY_7271A0 },
0175 { 0x72710000, BRCM_FAMILY_7271A0 },
0176 { 0x73640000, BRCM_FAMILY_7364A0 },
0177 { 0x73660020, BRCM_FAMILY_7366C0 },
0178 { 0x07437100, BRCM_FAMILY_74371A0 },
0179 { 0x74390010, BRCM_FAMILY_7439B0 },
0180 { 0x74450030, BRCM_FAMILY_7445D0 },
0181 { 0x72780000, BRCM_FAMILY_7278A0 },
0182 { 0, BRCM_FAMILY_7271A0 },
0183 };
0184
0185 static const u32
0186 usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
0187
0188 [BRCM_FAMILY_3390A0] = {
0189 USB_CTRL_SETUP_SCB1_EN_MASK,
0190 USB_CTRL_SETUP_SCB2_EN_MASK,
0191 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
0192 USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
0193 USB_CTRL_SETUP_OC3_DISABLE_MASK,
0194 0,
0195 0,
0196 USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
0197 USB_CTRL_USB_PM_USB_PWRDN_MASK,
0198 0,
0199 0,
0200 0,
0201 USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
0202 0,
0203 0,
0204 0,
0205 USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
0206 ENDIAN_SETTINGS,
0207 },
0208
0209 [BRCM_FAMILY_4908] = {
0210 0,
0211 0,
0212 0,
0213 0,
0214 0,
0215 0,
0216 0,
0217 USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
0218 USB_CTRL_USB_PM_USB_PWRDN_MASK,
0219 0,
0220 0,
0221 0,
0222 0,
0223 0,
0224 0,
0225 0,
0226 0,
0227 0,
0228 },
0229
0230 [BRCM_FAMILY_7250B0] = {
0231 USB_CTRL_SETUP_SCB1_EN_MASK,
0232 USB_CTRL_SETUP_SCB2_EN_MASK,
0233 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
0234 0,
0235 USB_CTRL_SETUP_OC3_DISABLE_MASK,
0236 USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
0237 0,
0238 USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
0239 0,
0240 0,
0241 0,
0242 0,
0243 0,
0244 0,
0245 0,
0246 0,
0247 USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,
0248 ENDIAN_SETTINGS,
0249 },
0250
0251 [BRCM_FAMILY_7271A0] = {
0252 0,
0253 0,
0254 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
0255 USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
0256 USB_CTRL_SETUP_OC3_DISABLE_MASK,
0257 0,
0258 USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
0259 USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
0260 USB_CTRL_USB_PM_USB_PWRDN_MASK,
0261 0,
0262 0,
0263 0,
0264 USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
0265 USB_CTRL_USB_PM_SOFT_RESET_MASK,
0266 USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK,
0267 USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK,
0268 USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
0269 ENDIAN_SETTINGS,
0270 },
0271
0272 [BRCM_FAMILY_7364A0] = {
0273 USB_CTRL_SETUP_SCB1_EN_MASK,
0274 USB_CTRL_SETUP_SCB2_EN_MASK,
0275 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
0276 0,
0277 USB_CTRL_SETUP_OC3_DISABLE_MASK,
0278 USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
0279 0,
0280 USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
0281 0,
0282 0,
0283 0,
0284 0,
0285 0,
0286 0,
0287 0,
0288 0,
0289 USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,
0290 ENDIAN_SETTINGS,
0291 },
0292
0293 [BRCM_FAMILY_7366C0] = {
0294 USB_CTRL_SETUP_SCB1_EN_MASK,
0295 USB_CTRL_SETUP_SCB2_EN_MASK,
0296 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
0297 0,
0298 USB_CTRL_SETUP_OC3_DISABLE_MASK,
0299 0,
0300 0,
0301 USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
0302 USB_CTRL_USB_PM_USB_PWRDN_MASK,
0303 0,
0304 0,
0305 0,
0306 0,
0307 0,
0308 0,
0309 0,
0310 USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,
0311 ENDIAN_SETTINGS,
0312 },
0313
0314 [BRCM_FAMILY_74371A0] = {
0315 USB_CTRL_SETUP_SCB1_EN_MASK,
0316 USB_CTRL_SETUP_SCB2_EN_MASK,
0317 USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK,
0318 0,
0319 0,
0320 USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
0321 0,
0322 0,
0323 0,
0324 USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK,
0325 USB_CTRL_USB30_CTL1_USB3_IOC_MASK,
0326 USB_CTRL_USB30_CTL1_USB3_IPP_MASK,
0327 0,
0328 0,
0329 0,
0330 0,
0331 0,
0332 ENDIAN_SETTINGS,
0333 },
0334
0335 [BRCM_FAMILY_7439B0] = {
0336 USB_CTRL_SETUP_SCB1_EN_MASK,
0337 USB_CTRL_SETUP_SCB2_EN_MASK,
0338 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
0339 USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
0340 USB_CTRL_SETUP_OC3_DISABLE_MASK,
0341 0,
0342 USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
0343 USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
0344 USB_CTRL_USB_PM_USB_PWRDN_MASK,
0345 0,
0346 0,
0347 0,
0348 USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
0349 0,
0350 0,
0351 0,
0352 USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
0353 ENDIAN_SETTINGS,
0354 },
0355
0356 [BRCM_FAMILY_7445D0] = {
0357 USB_CTRL_SETUP_SCB1_EN_MASK,
0358 USB_CTRL_SETUP_SCB2_EN_MASK,
0359 USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK,
0360 0,
0361 USB_CTRL_SETUP_OC3_DISABLE_MASK,
0362 USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
0363 0,
0364 0,
0365 0,
0366 USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK,
0367 0,
0368 0,
0369 0,
0370 0,
0371 0,
0372 0,
0373 USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
0374 ENDIAN_SETTINGS,
0375 },
0376
0377 [BRCM_FAMILY_7260A0] = {
0378 0,
0379 0,
0380 USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
0381 USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
0382 USB_CTRL_SETUP_OC3_DISABLE_MASK,
0383 0,
0384 USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
0385 USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
0386 USB_CTRL_USB_PM_USB_PWRDN_MASK,
0387 0,
0388 0,
0389 0,
0390 USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
0391 USB_CTRL_USB_PM_SOFT_RESET_MASK,
0392 USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK,
0393 USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK,
0394 USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
0395 ENDIAN_SETTINGS,
0396 },
0397
0398 [BRCM_FAMILY_7278A0] = {
0399 0,
0400 0,
0401 0,
0402 USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
0403 USB_CTRL_SETUP_OC3_DISABLE_MASK,
0404 0,
0405 USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
0406 USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
0407 USB_CTRL_USB_PM_USB_PWRDN_MASK,
0408 0,
0409 0,
0410 0,
0411 USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
0412 USB_CTRL_USB_PM_SOFT_RESET_MASK,
0413 0,
0414 0,
0415 0,
0416 0,
0417 },
0418 };
0419
0420 static inline
0421 void usb_ctrl_unset_family(struct brcm_usb_init_params *params,
0422 u32 reg_offset, u32 field)
0423 {
0424 u32 mask;
0425
0426 mask = params->usb_reg_bits_map[field];
0427 brcm_usb_ctrl_unset(params->regs[BRCM_REGS_CTRL] + reg_offset, mask);
0428 };
0429
0430 static inline
0431 void usb_ctrl_set_family(struct brcm_usb_init_params *params,
0432 u32 reg_offset, u32 field)
0433 {
0434 u32 mask;
0435
0436 mask = params->usb_reg_bits_map[field];
0437 brcm_usb_ctrl_set(params->regs[BRCM_REGS_CTRL] + reg_offset, mask);
0438 };
0439
0440 static u32 brcmusb_usb_mdio_read(void __iomem *ctrl_base, u32 reg, int mode)
0441 {
0442 u32 data;
0443
0444 data = (reg << 16) | mode;
0445 brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
0446 data |= (1 << 24);
0447 brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
0448 data &= ~(1 << 24);
0449
0450 usleep_range(10, 20);
0451 brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
0452
0453 usleep_range(10, 20);
0454
0455 return brcm_usb_readl(USB_CTRL_REG(ctrl_base, MDIO2)) & 0xffff;
0456 }
0457
0458 static void brcmusb_usb_mdio_write(void __iomem *ctrl_base, u32 reg,
0459 u32 val, int mode)
0460 {
0461 u32 data;
0462
0463 data = (reg << 16) | val | mode;
0464 brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
0465 data |= (1 << 25);
0466 brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
0467 data &= ~(1 << 25);
0468
0469
0470 usleep_range(10, 20);
0471 brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
0472
0473 usleep_range(10, 20);
0474 }
0475
0476 static void brcmusb_usb_phy_ldo_fix(void __iomem *ctrl_base)
0477 {
0478
0479
0480 USB_CTRL_UNSET(ctrl_base, UTMI_CTL_1, POWER_UP_FSM_EN);
0481 USB_CTRL_UNSET(ctrl_base, UTMI_CTL_1, POWER_UP_FSM_EN_P1);
0482
0483
0484 USB_CTRL_UNSET(ctrl_base, PLL_CTL, PLL_RESETB);
0485
0486 udelay(1);
0487 USB_CTRL_SET(ctrl_base, PLL_CTL, PLL_RESETB);
0488
0489 usleep_range(1000, 2000);
0490 }
0491
0492 static void brcmusb_usb2_eye_fix(void __iomem *ctrl_base)
0493 {
0494
0495 brcmusb_usb_mdio_write(ctrl_base, 0x1f, 0x80a0, MDIO_USB2);
0496 brcmusb_usb_mdio_write(ctrl_base, 0x0a, 0xc6a0, MDIO_USB2);
0497 }
0498
0499 static void brcmusb_usb3_pll_fix(void __iomem *ctrl_base)
0500 {
0501
0502 brcmusb_usb_mdio_write(ctrl_base, 0x1f, 0x8000, MDIO_USB3);
0503 brcmusb_usb_mdio_write(ctrl_base, 0x07, 0x1503, MDIO_USB3);
0504 }
0505
0506 static void brcmusb_usb3_enable_pipe_reset(void __iomem *ctrl_base)
0507 {
0508 u32 val;
0509
0510
0511 brcmusb_usb_mdio_write(ctrl_base, 0x1f, 0x8000, MDIO_USB3);
0512 val = brcmusb_usb_mdio_read(ctrl_base, 0x0f, MDIO_USB3) | 0x200;
0513 brcmusb_usb_mdio_write(ctrl_base, 0x0f, val, MDIO_USB3);
0514 }
0515
0516 static void brcmusb_usb3_enable_sigdet(void __iomem *ctrl_base)
0517 {
0518 u32 val, ofs;
0519 int ii;
0520
0521 ofs = 0;
0522 for (ii = 0; ii < PHY_PORTS; ++ii) {
0523
0524 brcmusb_usb_mdio_write(ctrl_base, 0x1f, (0x8080 + ofs),
0525 MDIO_USB3);
0526 val = brcmusb_usb_mdio_read(ctrl_base, 0x05, MDIO_USB3);
0527 val = (val & ~0x800f) | 0x800d;
0528 brcmusb_usb_mdio_write(ctrl_base, 0x05, val, MDIO_USB3);
0529 ofs = PHY_PORT_SELECT_1;
0530 }
0531 }
0532
0533 static void brcmusb_usb3_enable_skip_align(void __iomem *ctrl_base)
0534 {
0535 u32 val, ofs;
0536 int ii;
0537
0538 ofs = 0;
0539 for (ii = 0; ii < PHY_PORTS; ++ii) {
0540
0541 brcmusb_usb_mdio_write(ctrl_base, 0x1f, (0x8060 + ofs),
0542 MDIO_USB3);
0543 val = brcmusb_usb_mdio_read(ctrl_base, 0x01, MDIO_USB3) | 0x200;
0544 brcmusb_usb_mdio_write(ctrl_base, 0x01, val, MDIO_USB3);
0545 ofs = PHY_PORT_SELECT_1;
0546 }
0547 }
0548
0549 static void brcmusb_usb3_unfreeze_aeq(void __iomem *ctrl_base)
0550 {
0551 u32 val, ofs;
0552 int ii;
0553
0554 ofs = 0;
0555 for (ii = 0; ii < PHY_PORTS; ++ii) {
0556
0557 brcmusb_usb_mdio_write(ctrl_base, 0x1f, (0x80e0 + ofs),
0558 MDIO_USB3);
0559 val = brcmusb_usb_mdio_read(ctrl_base, 0x01, MDIO_USB3);
0560 val &= ~0x0008;
0561 brcmusb_usb_mdio_write(ctrl_base, 0x01, val, MDIO_USB3);
0562 ofs = PHY_PORT_SELECT_1;
0563 }
0564 }
0565
0566 static void brcmusb_usb3_pll_54mhz(struct brcm_usb_init_params *params)
0567 {
0568 u32 ofs;
0569 int ii;
0570 void __iomem *ctrl_base = params->regs[BRCM_REGS_CTRL];
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583 switch (params->selected_family) {
0584 case BRCM_FAMILY_3390A0:
0585 case BRCM_FAMILY_4908:
0586 case BRCM_FAMILY_7250B0:
0587 case BRCM_FAMILY_7366C0:
0588 case BRCM_FAMILY_74371A0:
0589 case BRCM_FAMILY_7439B0:
0590 case BRCM_FAMILY_7445D0:
0591 case BRCM_FAMILY_7260A0:
0592 return;
0593 case BRCM_FAMILY_7364A0:
0594 if (BRCM_REV(params->family_id) < 0x20)
0595 return;
0596 break;
0597 }
0598
0599
0600 USB_CTRL_UNSET(ctrl_base, USB30_CTL1, PHY3_PLL_SEQ_START);
0601
0602 brcmusb_usb_mdio_write(ctrl_base, 0x1f, 0x8000, MDIO_USB3);
0603 brcmusb_usb_mdio_write(ctrl_base, 0x10, 0x5784, MDIO_USB3);
0604 brcmusb_usb_mdio_write(ctrl_base, 0x11, 0x01d0, MDIO_USB3);
0605 brcmusb_usb_mdio_write(ctrl_base, 0x12, 0x1DE8, MDIO_USB3);
0606 brcmusb_usb_mdio_write(ctrl_base, 0x13, 0xAA80, MDIO_USB3);
0607 brcmusb_usb_mdio_write(ctrl_base, 0x14, 0x8826, MDIO_USB3);
0608 brcmusb_usb_mdio_write(ctrl_base, 0x15, 0x0044, MDIO_USB3);
0609 brcmusb_usb_mdio_write(ctrl_base, 0x16, 0x8000, MDIO_USB3);
0610 brcmusb_usb_mdio_write(ctrl_base, 0x17, 0x0851, MDIO_USB3);
0611 brcmusb_usb_mdio_write(ctrl_base, 0x18, 0x0000, MDIO_USB3);
0612
0613
0614 ofs = 0;
0615 for (ii = 0; ii < PHY_PORTS; ++ii) {
0616 brcmusb_usb_mdio_write(ctrl_base, 0x1f, (0x8040 + ofs),
0617 MDIO_USB3);
0618 brcmusb_usb_mdio_write(ctrl_base, 0x03, 0x0090, MDIO_USB3);
0619 brcmusb_usb_mdio_write(ctrl_base, 0x04, 0x0134, MDIO_USB3);
0620 brcmusb_usb_mdio_write(ctrl_base, 0x1f, (0x8020 + ofs),
0621 MDIO_USB3);
0622 brcmusb_usb_mdio_write(ctrl_base, 0x01, 0x00e2, MDIO_USB3);
0623 ofs = PHY_PORT_SELECT_1;
0624 }
0625
0626
0627 USB_CTRL_SET(ctrl_base, USB30_CTL1, PHY3_PLL_SEQ_START);
0628
0629 usleep_range(1000, 2000);
0630 }
0631
0632 static void brcmusb_usb3_ssc_enable(void __iomem *ctrl_base)
0633 {
0634 u32 val;
0635
0636
0637 brcmusb_usb_mdio_write(ctrl_base, 0x1f, 0x8040, MDIO_USB3);
0638 val = brcmusb_usb_mdio_read(ctrl_base, 0x01, MDIO_USB3) | 0xf;
0639 brcmusb_usb_mdio_write(ctrl_base, 0x01, val, MDIO_USB3);
0640
0641
0642
0643
0644
0645 brcmusb_usb_mdio_write(ctrl_base, 0x1f, 0x9040, MDIO_USB3);
0646 val = brcmusb_usb_mdio_read(ctrl_base, 0x01, MDIO_USB3) | 0xf;
0647 brcmusb_usb_mdio_write(ctrl_base, 0x01, val, MDIO_USB3);
0648 }
0649
0650 static void brcmusb_usb3_phy_workarounds(struct brcm_usb_init_params *params)
0651 {
0652 void __iomem *ctrl_base = params->regs[BRCM_REGS_CTRL];
0653
0654 brcmusb_usb3_pll_fix(ctrl_base);
0655 brcmusb_usb3_pll_54mhz(params);
0656 brcmusb_usb3_ssc_enable(ctrl_base);
0657 brcmusb_usb3_enable_pipe_reset(ctrl_base);
0658 brcmusb_usb3_enable_sigdet(ctrl_base);
0659 brcmusb_usb3_enable_skip_align(ctrl_base);
0660 brcmusb_usb3_unfreeze_aeq(ctrl_base);
0661 }
0662
0663 static void brcmusb_memc_fix(struct brcm_usb_init_params *params)
0664 {
0665 u32 prid;
0666
0667 if (params->selected_family != BRCM_FAMILY_7445D0)
0668 return;
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680 prid = params->product_id & 0xfffff000;
0681 switch (prid) {
0682 case 0x72520000:
0683 case 0x74480000:
0684 case 0x74490000:
0685 case 0x07252000:
0686 case 0x07448000:
0687 case 0x07449000:
0688 USB_CTRL_UNSET_FAMILY(params, SETUP, SCB2_EN);
0689 }
0690 }
0691
0692 static void brcmusb_usb3_otp_fix(struct brcm_usb_init_params *params)
0693 {
0694 void __iomem *xhci_ec_base = params->regs[BRCM_REGS_XHCI_EC];
0695 u32 val;
0696
0697 if (params->family_id != 0x74371000 || !xhci_ec_base)
0698 return;
0699 brcm_usb_writel(0xa20c, USB_XHCI_EC_REG(xhci_ec_base, IRAADR));
0700 val = brcm_usb_readl(USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
0701
0702
0703 val |= (1 << 27);
0704 brcm_usb_writel(val, USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
0705
0706
0707 USB_CTRL_UNSET(params->regs[BRCM_REGS_CTRL], USB30_CTL1, PHY3_RESETB);
0708 USB_CTRL_SET(params->regs[BRCM_REGS_CTRL], USB30_CTL1, PHY3_RESETB);
0709 }
0710
0711 static void brcmusb_xhci_soft_reset(struct brcm_usb_init_params *params,
0712 int on_off)
0713 {
0714
0715 if (on_off) {
0716 if (USB_CTRL_MASK_FAMILY(params, USB_PM, XHC_SOFT_RESETB))
0717 USB_CTRL_UNSET_FAMILY(params, USB_PM, XHC_SOFT_RESETB);
0718 else
0719 USB_CTRL_UNSET_FAMILY(params,
0720 USB30_CTL1, XHC_SOFT_RESETB);
0721 } else {
0722 if (USB_CTRL_MASK_FAMILY(params, USB_PM, XHC_SOFT_RESETB))
0723 USB_CTRL_SET_FAMILY(params, USB_PM, XHC_SOFT_RESETB);
0724 else
0725 USB_CTRL_SET_FAMILY(params, USB30_CTL1,
0726 XHC_SOFT_RESETB);
0727 }
0728 }
0729
0730
0731
0732
0733
0734
0735
0736
0737 static enum brcm_family_type get_family_type(
0738 struct brcm_usb_init_params *params)
0739 {
0740 int last_type = -1;
0741 u32 last_family = 0;
0742 u32 family_no_major;
0743 unsigned int x;
0744 u32 family;
0745
0746 family = params->family_id & 0xfffffff0;
0747 family_no_major = params->family_id & 0xffffff00;
0748 for (x = 0; id_to_type_table[x].id; x++) {
0749 if (family == id_to_type_table[x].id)
0750 return id_to_type_table[x].type;
0751 if (family_no_major == (id_to_type_table[x].id & 0xffffff00))
0752 if (family > id_to_type_table[x].id &&
0753 last_family < id_to_type_table[x].id) {
0754 last_family = id_to_type_table[x].id;
0755 last_type = id_to_type_table[x].type;
0756 }
0757 }
0758
0759
0760 if (last_type == -1)
0761 return id_to_type_table[x].type;
0762 return last_type;
0763 }
0764
0765 static void usb_init_ipp(struct brcm_usb_init_params *params)
0766 {
0767 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
0768 u32 reg;
0769 u32 orig_reg;
0770
0771
0772
0773
0774 if (USB_CTRL_MASK_FAMILY(params, USB30_CTL1, USB3_IOC)) {
0775 if (params->ioc)
0776 USB_CTRL_SET_FAMILY(params, USB30_CTL1, USB3_IOC);
0777 if (params->ipp == 1)
0778 USB_CTRL_SET_FAMILY(params, USB30_CTL1, USB3_IPP);
0779 }
0780
0781 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
0782 orig_reg = reg;
0783 if (USB_CTRL_MASK_FAMILY(params, SETUP, STRAP_CC_DRD_MODE_ENABLE_SEL))
0784
0785 reg &= ~(USB_CTRL_MASK_FAMILY(params,
0786 SETUP,
0787 STRAP_CC_DRD_MODE_ENABLE_SEL));
0788 if (USB_CTRL_MASK_FAMILY(params, SETUP, STRAP_IPP_SEL))
0789
0790 if (params->ipp != 2)
0791 reg &= ~(USB_CTRL_MASK_FAMILY(params, SETUP,
0792 STRAP_IPP_SEL));
0793
0794
0795 reg &= ~(USB_CTRL_MASK(SETUP, IPP) | USB_CTRL_MASK(SETUP, IOC));
0796 if (params->ioc)
0797 reg |= USB_CTRL_MASK(SETUP, IOC);
0798 if (params->ipp == 1)
0799 reg |= USB_CTRL_MASK(SETUP, IPP);
0800 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
0801
0802
0803
0804
0805
0806 if ((reg ^ orig_reg) & USB_CTRL_MASK(SETUP, IPP))
0807 msleep(50);
0808 }
0809
0810 static void usb_wake_enable(struct brcm_usb_init_params *params,
0811 bool enable)
0812 {
0813 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
0814
0815 if (enable)
0816 USB_CTRL_SET(ctrl, USB_PM, RMTWKUP_EN);
0817 else
0818 USB_CTRL_UNSET(ctrl, USB_PM, RMTWKUP_EN);
0819 }
0820
0821 static void usb_init_common(struct brcm_usb_init_params *params)
0822 {
0823 u32 reg;
0824 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
0825
0826
0827 usb_wake_enable(params, false);
0828 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM_STATUS));
0829 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_PM_STATUS));
0830
0831
0832 if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN)) {
0833 USB_CTRL_UNSET_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN);
0834
0835 usleep_range(1000, 2000);
0836 }
0837
0838 if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB_PWRDN)) {
0839 USB_CTRL_UNSET_FAMILY(params, USB_PM, USB_PWRDN);
0840
0841 usleep_range(1000, 2000);
0842 }
0843
0844 if (params->selected_family != BRCM_FAMILY_74371A0 &&
0845 (BRCM_ID(params->family_id) != 0x7364))
0846
0847
0848
0849
0850 USB_CTRL_SET_FAMILY(params, SETUP, SS_EHCI64BIT_EN);
0851
0852
0853 USB_CTRL_SET(ctrl, PLL_CTL, PLL_SUSPEND_EN);
0854
0855 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
0856 if (params->selected_family == BRCM_FAMILY_7364A0)
0857
0858 reg |= USB_CTRL_MASK_FAMILY(params, SETUP, OC3_DISABLE);
0859
0860 brcmusb_usb_phy_ldo_fix(ctrl);
0861 brcmusb_usb2_eye_fix(ctrl);
0862
0863
0864
0865
0866
0867 if (USB_CTRL_MASK_FAMILY(params, SETUP, SCB1_EN))
0868 reg |= USB_CTRL_MASK_FAMILY(params, SETUP, SCB1_EN);
0869 if (USB_CTRL_MASK_FAMILY(params, SETUP, SCB2_EN))
0870 reg |= USB_CTRL_MASK_FAMILY(params, SETUP, SCB2_EN);
0871 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
0872
0873 brcmusb_memc_fix(params);
0874
0875 if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
0876 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
0877 reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
0878 PORT_MODE);
0879 reg |= params->mode;
0880 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
0881 }
0882 if (USB_CTRL_MASK_FAMILY(params, USB_PM, BDC_SOFT_RESETB)) {
0883 switch (params->mode) {
0884 case USB_CTLR_MODE_HOST:
0885 USB_CTRL_UNSET_FAMILY(params, USB_PM, BDC_SOFT_RESETB);
0886 break;
0887 default:
0888 USB_CTRL_UNSET_FAMILY(params, USB_PM, BDC_SOFT_RESETB);
0889 USB_CTRL_SET_FAMILY(params, USB_PM, BDC_SOFT_RESETB);
0890 break;
0891 }
0892 }
0893 if (USB_CTRL_MASK_FAMILY(params, SETUP, CC_DRD_MODE_ENABLE)) {
0894 if (params->mode == USB_CTLR_MODE_TYPEC_PD)
0895 USB_CTRL_SET_FAMILY(params, SETUP, CC_DRD_MODE_ENABLE);
0896 else
0897 USB_CTRL_UNSET_FAMILY(params, SETUP,
0898 CC_DRD_MODE_ENABLE);
0899 }
0900 }
0901
0902 static void usb_init_eohci(struct brcm_usb_init_params *params)
0903 {
0904 u32 reg;
0905 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
0906
0907 if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB20_HC_RESETB))
0908 USB_CTRL_SET_FAMILY(params, USB_PM, USB20_HC_RESETB);
0909
0910 if (params->selected_family == BRCM_FAMILY_7366C0)
0911
0912
0913
0914
0915 USB_CTRL_SET(ctrl, EBRIDGE, ESTOP_SCB_REQ);
0916
0917
0918 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
0919 reg &= ~USB_CTRL_SETUP_ENDIAN_BITS;
0920 reg |= USB_CTRL_MASK_FAMILY(params, SETUP, ENDIAN);
0921 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
0922
0923 if (params->selected_family == BRCM_FAMILY_7271A0)
0924
0925 USB_CTRL_SET(ctrl, OBRIDGE, LS_KEEP_ALIVE);
0926
0927 if (params->family_id == 0x72550000) {
0928
0929
0930
0931
0932 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, EBRIDGE));
0933 reg &= ~USB_CTRL_MASK(EBRIDGE, EBR_SCB_SIZE);
0934 reg |= 0x800;
0935 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, EBRIDGE));
0936 }
0937 }
0938
0939 static void usb_init_xhci(struct brcm_usb_init_params *params)
0940 {
0941 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
0942
0943 USB_CTRL_UNSET(ctrl, USB30_PCTL, PHY3_IDDQ_OVERRIDE);
0944
0945 usleep_range(1000, 2000);
0946
0947 if (BRCM_ID(params->family_id) == 0x7366) {
0948
0949
0950
0951 USB_CTRL_SET(ctrl, USB30_PCTL, PHY3_SOFT_RESETB);
0952 USB_CTRL_SET(ctrl, USB30_PCTL, PHY3_SOFT_RESETB_P1);
0953 }
0954
0955
0956
0957
0958
0959 USB_CTRL_UNSET(ctrl, USB30_CTL1, PHY3_PLL_SEQ_START);
0960 USB_CTRL_SET(ctrl, USB30_CTL1, PHY3_PLL_SEQ_START);
0961
0962 brcmusb_usb3_phy_workarounds(params);
0963 brcmusb_xhci_soft_reset(params, 0);
0964 brcmusb_usb3_otp_fix(params);
0965 }
0966
0967 static void usb_uninit_common(struct brcm_usb_init_params *params)
0968 {
0969 if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB_PWRDN))
0970 USB_CTRL_SET_FAMILY(params, USB_PM, USB_PWRDN);
0971
0972 if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN))
0973 USB_CTRL_SET_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN);
0974 if (params->wake_enabled)
0975 usb_wake_enable(params, true);
0976 }
0977
0978 static void usb_uninit_eohci(struct brcm_usb_init_params *params)
0979 {
0980 }
0981
0982 static void usb_uninit_xhci(struct brcm_usb_init_params *params)
0983 {
0984 brcmusb_xhci_soft_reset(params, 1);
0985 USB_CTRL_SET(params->regs[BRCM_REGS_CTRL], USB30_PCTL,
0986 PHY3_IDDQ_OVERRIDE);
0987 }
0988
0989 static int usb_get_dual_select(struct brcm_usb_init_params *params)
0990 {
0991 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
0992 u32 reg = 0;
0993
0994 pr_debug("%s\n", __func__);
0995 if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
0996 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
0997 reg &= USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
0998 PORT_MODE);
0999 }
1000 return reg;
1001 }
1002
1003 static void usb_set_dual_select(struct brcm_usb_init_params *params, int mode)
1004 {
1005 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
1006 u32 reg;
1007
1008 pr_debug("%s\n", __func__);
1009
1010 if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
1011 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
1012 reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
1013 PORT_MODE);
1014 reg |= mode;
1015 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
1016 }
1017 }
1018
1019 static const struct brcm_usb_init_ops bcm7445_ops = {
1020 .init_ipp = usb_init_ipp,
1021 .init_common = usb_init_common,
1022 .init_eohci = usb_init_eohci,
1023 .init_xhci = usb_init_xhci,
1024 .uninit_common = usb_uninit_common,
1025 .uninit_eohci = usb_uninit_eohci,
1026 .uninit_xhci = usb_uninit_xhci,
1027 .get_dual_select = usb_get_dual_select,
1028 .set_dual_select = usb_set_dual_select,
1029 };
1030
1031 void brcm_usb_dvr_init_4908(struct brcm_usb_init_params *params)
1032 {
1033 int fam;
1034
1035 fam = BRCM_FAMILY_4908;
1036 params->selected_family = fam;
1037 params->usb_reg_bits_map =
1038 &usb_reg_bits_map_table[fam][0];
1039 params->family_name = family_names[fam];
1040 params->ops = &bcm7445_ops;
1041 }
1042
1043 void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params)
1044 {
1045 int fam;
1046
1047 pr_debug("%s\n", __func__);
1048
1049 fam = get_family_type(params);
1050 params->selected_family = fam;
1051 params->usb_reg_bits_map =
1052 &usb_reg_bits_map_table[fam][0];
1053 params->family_name = family_names[fam];
1054 params->ops = &bcm7445_ops;
1055 }