brintos

brintos / linux-shallow public Read only

0
0
Text · 35.5 KiB · 5ebb3a6 Raw
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