phy: omap-usb2-phy: disable PHY charger detect
AM654x PG1.0 has a silicon bug that D+ is pulled high after POR, which could cause enumeration failure with some USB hubs. Disabling the USB2_PHY Charger Detect function will put D+ into the normal state. This addresses Silicon Errata: i2075 - "USB2PHY: USB2PHY Charger Detect is Enabled by Default Without VBUS Presence" Signed-off-by: Roger Quadros <rogerq@ti.com> Tested-by: Jan Kiszka <jan.kiszka@siemens.com> Link: https://lore.kernel.org/r/20200824075127.14902-2-rogerq@ti.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
afd55e6d1b
commit
ad7a7acaed
@ -22,10 +22,15 @@
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/sys_soc.h>
|
||||
|
||||
#define USB2PHY_ANA_CONFIG1 0x4c
|
||||
#define USB2PHY_DISCON_BYP_LATCH BIT(31)
|
||||
|
||||
#define USB2PHY_CHRG_DET 0x14
|
||||
#define USB2PHY_CHRG_DET_USE_CHG_DET_REG BIT(29)
|
||||
#define USB2PHY_CHRG_DET_DIS_CHG_DET BIT(28)
|
||||
|
||||
/* SoC Specific USB2_OTG register definitions */
|
||||
#define AM654_USB2_OTG_PD BIT(8)
|
||||
#define AM654_USB2_VBUS_DET_EN BIT(5)
|
||||
@ -43,6 +48,7 @@
|
||||
#define OMAP_USB2_HAS_START_SRP BIT(0)
|
||||
#define OMAP_USB2_HAS_SET_VBUS BIT(1)
|
||||
#define OMAP_USB2_CALIBRATE_FALSE_DISCONNECT BIT(2)
|
||||
#define OMAP_USB2_DISABLE_CHRG_DET BIT(3)
|
||||
|
||||
struct omap_usb {
|
||||
struct usb_phy phy;
|
||||
@ -236,6 +242,13 @@ static int omap_usb_init(struct phy *x)
|
||||
omap_usb_writel(phy->phy_base, USB2PHY_ANA_CONFIG1, val);
|
||||
}
|
||||
|
||||
if (phy->flags & OMAP_USB2_DISABLE_CHRG_DET) {
|
||||
val = omap_usb_readl(phy->phy_base, USB2PHY_CHRG_DET);
|
||||
val |= USB2PHY_CHRG_DET_USE_CHG_DET_REG |
|
||||
USB2PHY_CHRG_DET_DIS_CHG_DET;
|
||||
omap_usb_writel(phy->phy_base, USB2PHY_CHRG_DET, val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -329,6 +342,26 @@ static const struct of_device_id omap_usb2_id_table[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, omap_usb2_id_table);
|
||||
|
||||
static void omap_usb2_init_errata(struct omap_usb *phy)
|
||||
{
|
||||
static const struct soc_device_attribute am65x_sr10_soc_devices[] = {
|
||||
{ .family = "AM65X", .revision = "SR1.0" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
/*
|
||||
* Errata i2075: USB2PHY: USB2PHY Charger Detect is Enabled by
|
||||
* Default Without VBUS Presence.
|
||||
*
|
||||
* AM654x SR1.0 has a silicon bug due to which D+ is pulled high after
|
||||
* POR, which could cause enumeration failure with some USB hubs.
|
||||
* Disabling the USB2_PHY Charger Detect function will put D+
|
||||
* into the normal state.
|
||||
*/
|
||||
if (soc_device_match(am65x_sr10_soc_devices))
|
||||
phy->flags |= OMAP_USB2_DISABLE_CHRG_DET;
|
||||
}
|
||||
|
||||
static int omap_usb2_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_usb *phy;
|
||||
@ -366,14 +399,14 @@ static int omap_usb2_probe(struct platform_device *pdev)
|
||||
phy->mask = phy_data->mask;
|
||||
phy->power_on = phy_data->power_on;
|
||||
phy->power_off = phy_data->power_off;
|
||||
phy->flags = phy_data->flags;
|
||||
|
||||
if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
phy->phy_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(phy->phy_base))
|
||||
return PTR_ERR(phy->phy_base);
|
||||
phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT;
|
||||
}
|
||||
omap_usb2_init_errata(phy);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
phy->phy_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(phy->phy_base))
|
||||
return PTR_ERR(phy->phy_base);
|
||||
|
||||
phy->syscon_phy_power = syscon_regmap_lookup_by_phandle(node,
|
||||
"syscon-phy-power");
|
||||
|
Loading…
Reference in New Issue
Block a user