phy: for 4.16
*) Fix in exynos5-usbdrd to enumerate SuperSpeed devices on Odroid XU3 *) Fix in Broadcom USB PHY to get Dell Low Speed keyboards working *) Fix in Broadcom USB PHY to power down the PHY when XHCI disabled to save power *) Fix in Broadcom USB PHY to prevent abort in DRD mode *) Fix in Broadcom USB PHY to use the correct dt properties *) Fix in Mediatek PHY to detect device connection *) Make getting resource optional for Mediatek V1 TPHY *) Cleanup in Mediatek PHY Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJaSzimAAoJEA5ceFyATYLZrCUP/3f02fVtkF+OAL3e+ZwgCWy/ xoGIHffTcrYFimPeHh7INbeA16o2qNcN8JxJqQFFpZtZIoBR60az6ql7P2CZomXv Z4S8ftKl8cOEI6O6AmLgRFuxaHSG24IxD54rHwCa6bDAoq36VnHM2CG+EEB6Yd3M 4eYoS1hQuwFCKeWSmHo4Uq8zyvTwIaxfKhOBlonXZu3/Tt34ZR0sGr3FC2OIamTN Isrx/BsdHsfg+mTElos9jnc5/Uhwy/r7JFmRotn06cWGw2EGoM6EOXBrp3WXHD/f jQnSSP3ZKmDvq0zY7QywXVo+fVWddZYx3fsbd26A5bUsarcj2VWlbHWyAWtYty3N HOuucYbMHSXTFxP/0j6pwONzQIIucisGgNdUc4Zc7nzwcF8A/BWrEMkGqZLit45q NalvVz/+lk0be3zZngm/vbaztHbHMQDvKe0U5QbHH9h47MybmydocrPgs7JbDcFd P0vHJ1be5CMItcElC0w+fkrRf3tk5IYQb4nZFDaTRSiuLU+S+mgLfYjbGH4lXtnQ USsGRv827wFqQVEzay2WvazvviBautoneh2+YDMg7R1cSOh9kQkunPl9ePOig/DR Cgy1MEZH8GZIIhIOBshnLQ2FiQbtnn0NkDTOajLNyJssFbE+9XXYKJr/cUvCOArP W9GjMMvI06gI7T+sDylY =f9so -----END PGP SIGNATURE----- Merge tag 'phy-for-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy into usb-next Kishon writes: phy: for 4.16 *) Fix in exynos5-usbdrd to enumerate SuperSpeed devices on Odroid XU3 *) Fix in Broadcom USB PHY to get Dell Low Speed keyboards working *) Fix in Broadcom USB PHY to power down the PHY when XHCI disabled to save power *) Fix in Broadcom USB PHY to prevent abort in DRD mode *) Fix in Broadcom USB PHY to use the correct dt properties *) Fix in Mediatek PHY to detect device connection *) Make getting resource optional for Mediatek V1 TPHY *) Cleanup in Mediatek PHY Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
This commit is contained in:
commit
f1faf88c13
5 changed files with 212 additions and 34 deletions
|
@ -50,6 +50,8 @@
|
|||
#define USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK 0x80000000 /* option */
|
||||
#define USB_CTRL_EBRIDGE 0x0c
|
||||
#define USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK 0x00020000 /* option */
|
||||
#define USB_CTRL_OBRIDGE 0x10
|
||||
#define USB_CTRL_OBRIDGE_LS_KEEP_ALIVE_MASK 0x08000000
|
||||
#define USB_CTRL_MDIO 0x14
|
||||
#define USB_CTRL_MDIO2 0x18
|
||||
#define USB_CTRL_UTMI_CTL_1 0x2c
|
||||
|
@ -71,6 +73,7 @@
|
|||
#define USB_CTRL_USB30_CTL1_USB3_IPP_MASK 0x20000000 /* option */
|
||||
#define USB_CTRL_USB30_PCTL 0x70
|
||||
#define USB_CTRL_USB30_PCTL_PHY3_SOFT_RESETB_MASK 0x00000002
|
||||
#define USB_CTRL_USB30_PCTL_PHY3_IDDQ_OVERRIDE_MASK 0x00008000
|
||||
#define USB_CTRL_USB30_PCTL_PHY3_SOFT_RESETB_P1_MASK 0x00020000
|
||||
#define USB_CTRL_USB_DEVICE_CTL1 0x90
|
||||
#define USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK 0x00000003 /* option */
|
||||
|
@ -116,7 +119,6 @@ enum {
|
|||
USB_CTRL_SETUP_STRAP_IPP_SEL_SELECTOR,
|
||||
USB_CTRL_SETUP_OC3_DISABLE_SELECTOR,
|
||||
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR,
|
||||
USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_SELECTOR,
|
||||
USB_CTRL_USB_PM_BDC_SOFT_RESETB_SELECTOR,
|
||||
USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR,
|
||||
USB_CTRL_USB_PM_USB_PWRDN_SELECTOR,
|
||||
|
@ -203,7 +205,6 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
|
|||
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
|
||||
USB_CTRL_SETUP_OC3_DISABLE_MASK,
|
||||
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
|
||||
USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK,
|
||||
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
|
||||
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
|
||||
USB_CTRL_USB_PM_USB_PWRDN_MASK,
|
||||
|
@ -225,7 +226,6 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
|
|||
0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */
|
||||
USB_CTRL_SETUP_OC3_DISABLE_MASK,
|
||||
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
|
||||
USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK,
|
||||
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
|
||||
USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
|
||||
0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */
|
||||
|
@ -247,7 +247,6 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
|
|||
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
|
||||
USB_CTRL_SETUP_OC3_DISABLE_MASK,
|
||||
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
|
||||
USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK,
|
||||
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
|
||||
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
|
||||
USB_CTRL_USB_PM_USB_PWRDN_MASK,
|
||||
|
@ -269,7 +268,6 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
|
|||
0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */
|
||||
USB_CTRL_SETUP_OC3_DISABLE_MASK,
|
||||
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
|
||||
USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK,
|
||||
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
|
||||
USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
|
||||
0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */
|
||||
|
@ -291,7 +289,6 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
|
|||
0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */
|
||||
USB_CTRL_SETUP_OC3_DISABLE_MASK,
|
||||
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
|
||||
USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK,
|
||||
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
|
||||
USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
|
||||
USB_CTRL_USB_PM_USB_PWRDN_MASK,
|
||||
|
@ -313,7 +310,6 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
|
|||
0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */
|
||||
0, /* USB_CTRL_SETUP_OC3_DISABLE_MASK */
|
||||
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
|
||||
0, /* USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK */
|
||||
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
|
||||
0, /* USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK */
|
||||
0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */
|
||||
|
@ -335,7 +331,6 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
|
|||
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
|
||||
USB_CTRL_SETUP_OC3_DISABLE_MASK,
|
||||
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
|
||||
0, /* USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK */
|
||||
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
|
||||
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
|
||||
USB_CTRL_USB_PM_USB_PWRDN_MASK,
|
||||
|
@ -357,7 +352,6 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
|
|||
0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */
|
||||
USB_CTRL_SETUP_OC3_DISABLE_MASK,
|
||||
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
|
||||
0, /* USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK */
|
||||
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
|
||||
0, /* USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK */
|
||||
0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */
|
||||
|
@ -379,7 +373,6 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
|
|||
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
|
||||
USB_CTRL_SETUP_OC3_DISABLE_MASK,
|
||||
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
|
||||
USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK,
|
||||
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
|
||||
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
|
||||
USB_CTRL_USB_PM_USB_PWRDN_MASK,
|
||||
|
@ -401,7 +394,6 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
|
|||
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
|
||||
USB_CTRL_SETUP_OC3_DISABLE_MASK,
|
||||
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
|
||||
USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK,
|
||||
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
|
||||
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
|
||||
USB_CTRL_USB_PM_USB_PWRDN_MASK,
|
||||
|
@ -926,6 +918,7 @@ void brcm_usb_init_common(struct brcm_usb_init_params *params)
|
|||
USB_CTRL_UNSET_FAMILY(params, USB_PM, BDC_SOFT_RESETB);
|
||||
break;
|
||||
default:
|
||||
USB_CTRL_UNSET_FAMILY(params, USB_PM, BDC_SOFT_RESETB);
|
||||
USB_CTRL_SET_FAMILY(params, USB_PM, BDC_SOFT_RESETB);
|
||||
break;
|
||||
}
|
||||
|
@ -952,13 +945,17 @@ void brcm_usb_init_eohci(struct brcm_usb_init_params *params)
|
|||
* Don't enable this so the memory controller doesn't read
|
||||
* into memory holes. NOTE: This bit is low true on 7366C0.
|
||||
*/
|
||||
USB_CTRL_SET_FAMILY(params, EBRIDGE, ESTOP_SCB_REQ);
|
||||
USB_CTRL_SET(ctrl, EBRIDGE, ESTOP_SCB_REQ);
|
||||
|
||||
/* Setup the endian bits */
|
||||
reg = brcmusb_readl(USB_CTRL_REG(ctrl, SETUP));
|
||||
reg &= ~USB_CTRL_SETUP_ENDIAN_BITS;
|
||||
reg |= USB_CTRL_MASK_FAMILY(params, SETUP, ENDIAN);
|
||||
brcmusb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
|
||||
|
||||
if (params->selected_family == BRCM_FAMILY_7271A0)
|
||||
/* Enable LS keep alive fix for certain keyboards */
|
||||
USB_CTRL_SET(ctrl, OBRIDGE, LS_KEEP_ALIVE);
|
||||
}
|
||||
|
||||
void brcm_usb_init_xhci(struct brcm_usb_init_params *params)
|
||||
|
@ -1003,6 +1000,7 @@ void brcm_usb_uninit_eohci(struct brcm_usb_init_params *params)
|
|||
void brcm_usb_uninit_xhci(struct brcm_usb_init_params *params)
|
||||
{
|
||||
brcmusb_xhci_soft_reset(params, 1);
|
||||
USB_CTRL_SET(params->ctrl_regs, USB30_PCTL, PHY3_IDDQ_OVERRIDE);
|
||||
}
|
||||
|
||||
void brcm_usb_set_family_map(struct brcm_usb_init_params *params)
|
||||
|
|
|
@ -338,9 +338,9 @@ static int brcm_usb_phy_probe(struct platform_device *pdev)
|
|||
ARRAY_SIZE(brcm_dr_mode_to_name),
|
||||
mode, &priv->ini.mode);
|
||||
}
|
||||
if (of_property_read_bool(dn, "brcm,has_xhci"))
|
||||
if (of_property_read_bool(dn, "brcm,has-xhci"))
|
||||
priv->has_xhci = true;
|
||||
if (of_property_read_bool(dn, "brcm,has_eohci"))
|
||||
if (of_property_read_bool(dn, "brcm,has-eohci"))
|
||||
priv->has_eohci = true;
|
||||
|
||||
err = brcm_usb_phy_dvr_init(dev, priv, dn);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/iopoll.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
|
@ -440,9 +441,9 @@ static void u2_phy_instance_init(struct mtk_tphy *tphy,
|
|||
u32 index = instance->index;
|
||||
u32 tmp;
|
||||
|
||||
/* switch to USB function. (system register, force ip into usb mode) */
|
||||
/* switch to USB function, and enable usb pll */
|
||||
tmp = readl(com + U3P_U2PHYDTM0);
|
||||
tmp &= ~P2C_FORCE_UART_EN;
|
||||
tmp &= ~(P2C_FORCE_UART_EN | P2C_FORCE_SUSPENDM);
|
||||
tmp |= P2C_RG_XCVRSEL_VAL(1) | P2C_RG_DATAIN_VAL(0);
|
||||
writel(tmp, com + U3P_U2PHYDTM0);
|
||||
|
||||
|
@ -502,10 +503,8 @@ static void u2_phy_instance_power_on(struct mtk_tphy *tphy,
|
|||
u32 index = instance->index;
|
||||
u32 tmp;
|
||||
|
||||
/* (force_suspendm=0) (let suspendm=1, enable usb 480MHz pll) */
|
||||
tmp = readl(com + U3P_U2PHYDTM0);
|
||||
tmp &= ~(P2C_FORCE_SUSPENDM | P2C_RG_XCVRSEL);
|
||||
tmp &= ~(P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
|
||||
tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
|
||||
writel(tmp, com + U3P_U2PHYDTM0);
|
||||
|
||||
/* OTG Enable */
|
||||
|
@ -540,7 +539,6 @@ static void u2_phy_instance_power_off(struct mtk_tphy *tphy,
|
|||
|
||||
tmp = readl(com + U3P_U2PHYDTM0);
|
||||
tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN);
|
||||
tmp |= P2C_FORCE_SUSPENDM;
|
||||
writel(tmp, com + U3P_U2PHYDTM0);
|
||||
|
||||
/* OTG Disable */
|
||||
|
@ -548,18 +546,16 @@ static void u2_phy_instance_power_off(struct mtk_tphy *tphy,
|
|||
tmp &= ~PA6_RG_U2_OTG_VBUSCMP_EN;
|
||||
writel(tmp, com + U3P_USBPHYACR6);
|
||||
|
||||
/* let suspendm=0, set utmi into analog power down */
|
||||
tmp = readl(com + U3P_U2PHYDTM0);
|
||||
tmp &= ~P2C_RG_SUSPENDM;
|
||||
writel(tmp, com + U3P_U2PHYDTM0);
|
||||
udelay(1);
|
||||
|
||||
tmp = readl(com + U3P_U2PHYDTM1);
|
||||
tmp &= ~(P2C_RG_VBUSVALID | P2C_RG_AVALID);
|
||||
tmp |= P2C_RG_SESSEND;
|
||||
writel(tmp, com + U3P_U2PHYDTM1);
|
||||
|
||||
if (tphy->pdata->avoid_rx_sen_degradation && index) {
|
||||
tmp = readl(com + U3P_U2PHYDTM0);
|
||||
tmp &= ~(P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM);
|
||||
writel(tmp, com + U3P_U2PHYDTM0);
|
||||
|
||||
tmp = readl(com + U3D_U2PHYDCR0);
|
||||
tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
|
||||
writel(tmp, com + U3D_U2PHYDCR0);
|
||||
|
@ -1000,7 +996,6 @@ MODULE_DEVICE_TABLE(of, mtk_tphy_id_table);
|
|||
|
||||
static int mtk_tphy_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct device_node *child_np;
|
||||
|
@ -1010,15 +1005,14 @@ static int mtk_tphy_probe(struct platform_device *pdev)
|
|||
struct resource res;
|
||||
int port, retval;
|
||||
|
||||
match = of_match_node(mtk_tphy_id_table, pdev->dev.of_node);
|
||||
if (!match)
|
||||
return -EINVAL;
|
||||
|
||||
tphy = devm_kzalloc(dev, sizeof(*tphy), GFP_KERNEL);
|
||||
if (!tphy)
|
||||
return -ENOMEM;
|
||||
|
||||
tphy->pdata = match->data;
|
||||
tphy->pdata = of_device_get_match_data(dev);
|
||||
if (!tphy->pdata)
|
||||
return -EINVAL;
|
||||
|
||||
tphy->nphys = of_get_child_count(np);
|
||||
tphy->phys = devm_kcalloc(dev, tphy->nphys,
|
||||
sizeof(*tphy->phys), GFP_KERNEL);
|
||||
|
@ -1028,9 +1022,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
|
|||
tphy->dev = dev;
|
||||
platform_set_drvdata(pdev, tphy);
|
||||
|
||||
if (tphy->pdata->version == MTK_PHY_V1) {
|
||||
sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
/* SATA phy of V1 needn't it if not shared with PCIe or USB */
|
||||
if (sif_res && tphy->pdata->version == MTK_PHY_V1) {
|
||||
/* get banks shared by multiple phys */
|
||||
sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
tphy->sif_base = devm_ioremap_resource(dev, sif_res);
|
||||
if (IS_ERR(tphy->sif_base)) {
|
||||
dev_err(dev, "failed to remap sif regs\n");
|
||||
|
|
|
@ -90,7 +90,17 @@
|
|||
#define PHYCLKRST_COMMONONN BIT(0)
|
||||
|
||||
#define EXYNOS5_DRD_PHYREG0 0x14
|
||||
#define PHYREG0_SSC_REF_CLK_SEL BIT(21)
|
||||
#define PHYREG0_SSC_RANGE BIT(20)
|
||||
#define PHYREG0_CR_WRITE BIT(19)
|
||||
#define PHYREG0_CR_READ BIT(18)
|
||||
#define PHYREG0_CR_DATA_IN(_x) ((_x) << 2)
|
||||
#define PHYREG0_CR_CAP_DATA BIT(1)
|
||||
#define PHYREG0_CR_CAP_ADDR BIT(0)
|
||||
|
||||
#define EXYNOS5_DRD_PHYREG1 0x18
|
||||
#define PHYREG1_CR_DATA_OUT(_x) ((_x) << 1)
|
||||
#define PHYREG1_CR_ACK BIT(0)
|
||||
|
||||
#define EXYNOS5_DRD_PHYPARAM0 0x1c
|
||||
|
||||
|
@ -119,6 +129,25 @@
|
|||
#define EXYNOS5_DRD_PHYRESUME 0x34
|
||||
#define EXYNOS5_DRD_LINKPORT 0x44
|
||||
|
||||
/* USB 3.0 DRD PHY SS Function Control Reg; accessed by CR_PORT */
|
||||
#define EXYNOS5_DRD_PHYSS_LOSLEVEL_OVRD_IN (0x15)
|
||||
#define LOSLEVEL_OVRD_IN_LOS_BIAS_5420 (0x5 << 13)
|
||||
#define LOSLEVEL_OVRD_IN_LOS_BIAS_DEFAULT (0x0 << 13)
|
||||
#define LOSLEVEL_OVRD_IN_EN (0x1 << 10)
|
||||
#define LOSLEVEL_OVRD_IN_LOS_LEVEL_DEFAULT (0x9 << 0)
|
||||
|
||||
#define EXYNOS5_DRD_PHYSS_TX_VBOOSTLEVEL_OVRD_IN (0x12)
|
||||
#define TX_VBOOSTLEVEL_OVRD_IN_VBOOST_5420 (0x5 << 13)
|
||||
#define TX_VBOOSTLEVEL_OVRD_IN_VBOOST_DEFAULT (0x4 << 13)
|
||||
|
||||
#define EXYNOS5_DRD_PHYSS_LANE0_TX_DEBUG (0x1010)
|
||||
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_19M2_20M (0x4 << 4)
|
||||
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_24M (0x8 << 4)
|
||||
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_25M_26M (0x8 << 4)
|
||||
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_48M_50M_52M (0x20 << 4)
|
||||
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_62M5 (0x20 << 4)
|
||||
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_96M_100M (0x40 << 4)
|
||||
|
||||
#define KHZ 1000
|
||||
#define MHZ (KHZ * KHZ)
|
||||
|
||||
|
@ -527,6 +556,151 @@ static int exynos5_usbdrd_phy_power_off(struct phy *phy)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int crport_handshake(struct exynos5_usbdrd_phy *phy_drd,
|
||||
u32 val, u32 cmd)
|
||||
{
|
||||
u32 usec = 100;
|
||||
unsigned int result;
|
||||
|
||||
writel(val | cmd, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0);
|
||||
|
||||
do {
|
||||
result = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1);
|
||||
if (result & PHYREG1_CR_ACK)
|
||||
break;
|
||||
|
||||
udelay(1);
|
||||
} while (usec-- > 0);
|
||||
|
||||
if (!usec) {
|
||||
dev_err(phy_drd->dev,
|
||||
"CRPORT handshake timeout1 (0x%08x)\n", val);
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
usec = 100;
|
||||
|
||||
writel(val, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0);
|
||||
|
||||
do {
|
||||
result = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1);
|
||||
if (!(result & PHYREG1_CR_ACK))
|
||||
break;
|
||||
|
||||
udelay(1);
|
||||
} while (usec-- > 0);
|
||||
|
||||
if (!usec) {
|
||||
dev_err(phy_drd->dev,
|
||||
"CRPORT handshake timeout2 (0x%08x)\n", val);
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crport_ctrl_write(struct exynos5_usbdrd_phy *phy_drd,
|
||||
u32 addr, u32 data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Write Address */
|
||||
writel(PHYREG0_CR_DATA_IN(addr),
|
||||
phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0);
|
||||
ret = crport_handshake(phy_drd, PHYREG0_CR_DATA_IN(addr),
|
||||
PHYREG0_CR_CAP_ADDR);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Write Data */
|
||||
writel(PHYREG0_CR_DATA_IN(data),
|
||||
phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0);
|
||||
ret = crport_handshake(phy_drd, PHYREG0_CR_DATA_IN(data),
|
||||
PHYREG0_CR_CAP_DATA);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = crport_handshake(phy_drd, PHYREG0_CR_DATA_IN(data),
|
||||
PHYREG0_CR_WRITE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calibrate few PHY parameters using CR_PORT register to meet
|
||||
* SuperSpeed requirements on Exynos5420 and Exynos5800 systems,
|
||||
* which have 28nm USB 3.0 DRD PHY.
|
||||
*/
|
||||
static int exynos5420_usbdrd_phy_calibrate(struct exynos5_usbdrd_phy *phy_drd)
|
||||
{
|
||||
unsigned int temp;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* Change los_bias to (0x5) for 28nm PHY from a
|
||||
* default value (0x0); los_level is set as default
|
||||
* (0x9) as also reflected in los_level[30:26] bits
|
||||
* of PHYPARAM0 register.
|
||||
*/
|
||||
temp = LOSLEVEL_OVRD_IN_LOS_BIAS_5420 |
|
||||
LOSLEVEL_OVRD_IN_EN |
|
||||
LOSLEVEL_OVRD_IN_LOS_LEVEL_DEFAULT;
|
||||
ret = crport_ctrl_write(phy_drd,
|
||||
EXYNOS5_DRD_PHYSS_LOSLEVEL_OVRD_IN,
|
||||
temp);
|
||||
if (ret) {
|
||||
dev_err(phy_drd->dev,
|
||||
"Failed setting Loss-of-Signal level for SuperSpeed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set tx_vboost_lvl to (0x5) for 28nm PHY Tuning,
|
||||
* to raise Tx signal level from its default value of (0x4)
|
||||
*/
|
||||
temp = TX_VBOOSTLEVEL_OVRD_IN_VBOOST_5420;
|
||||
ret = crport_ctrl_write(phy_drd,
|
||||
EXYNOS5_DRD_PHYSS_TX_VBOOSTLEVEL_OVRD_IN,
|
||||
temp);
|
||||
if (ret) {
|
||||
dev_err(phy_drd->dev,
|
||||
"Failed setting Tx-Vboost-Level for SuperSpeed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set proper time to wait for RxDetect measurement, for
|
||||
* desired reference clock of PHY, by tuning the CR_PORT
|
||||
* register LANE0.TX_DEBUG which is internal to PHY.
|
||||
* This fixes issue with few USB 3.0 devices, which are
|
||||
* not detected (not even generate interrupts on the bus
|
||||
* on insertion) without this change.
|
||||
* e.g. Samsung SUM-TSB16S 3.0 USB drive.
|
||||
*/
|
||||
switch (phy_drd->extrefclk) {
|
||||
case EXYNOS5_FSEL_50MHZ:
|
||||
temp = LANE0_TX_DEBUG_RXDET_MEAS_TIME_48M_50M_52M;
|
||||
break;
|
||||
case EXYNOS5_FSEL_20MHZ:
|
||||
case EXYNOS5_FSEL_19MHZ2:
|
||||
temp = LANE0_TX_DEBUG_RXDET_MEAS_TIME_19M2_20M;
|
||||
break;
|
||||
case EXYNOS5_FSEL_24MHZ:
|
||||
default:
|
||||
temp = LANE0_TX_DEBUG_RXDET_MEAS_TIME_24M;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = crport_ctrl_write(phy_drd,
|
||||
EXYNOS5_DRD_PHYSS_LANE0_TX_DEBUG,
|
||||
temp);
|
||||
if (ret)
|
||||
dev_err(phy_drd->dev,
|
||||
"Fail to set RxDet measurement time for SuperSpeed\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct phy *exynos5_usbdrd_phy_xlate(struct device *dev,
|
||||
struct of_phandle_args *args)
|
||||
{
|
||||
|
@ -538,11 +712,20 @@ static struct phy *exynos5_usbdrd_phy_xlate(struct device *dev,
|
|||
return phy_drd->phys[args->args[0]].phy;
|
||||
}
|
||||
|
||||
static int exynos5_usbdrd_phy_calibrate(struct phy *phy)
|
||||
{
|
||||
struct phy_usb_instance *inst = phy_get_drvdata(phy);
|
||||
struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
|
||||
|
||||
return exynos5420_usbdrd_phy_calibrate(phy_drd);
|
||||
}
|
||||
|
||||
static const struct phy_ops exynos5_usbdrd_phy_ops = {
|
||||
.init = exynos5_usbdrd_phy_init,
|
||||
.exit = exynos5_usbdrd_phy_exit,
|
||||
.power_on = exynos5_usbdrd_phy_power_on,
|
||||
.power_off = exynos5_usbdrd_phy_power_off,
|
||||
.calibrate = exynos5_usbdrd_phy_calibrate,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
|
|
@ -147,6 +147,7 @@ static void __dwc3_set_mode(struct work_struct *work)
|
|||
otg_set_vbus(dwc->usb2_phy->otg, true);
|
||||
phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);
|
||||
phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST);
|
||||
phy_calibrate(dwc->usb2_generic_phy);
|
||||
}
|
||||
break;
|
||||
case DWC3_GCTL_PRTCAP_DEVICE:
|
||||
|
@ -945,6 +946,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
|
|||
dev_err(dev, "failed to initialize host\n");
|
||||
return ret;
|
||||
}
|
||||
phy_calibrate(dwc->usb2_generic_phy);
|
||||
break;
|
||||
case USB_DR_MODE_OTG:
|
||||
INIT_WORK(&dwc->drd_work, __dwc3_set_mode);
|
||||
|
|
Loading…
Reference in a new issue