diff mbox series

[v4,3/3] phy: omap-usb2-phy: disable PHY charger detect

Message ID 20200716082252.21266-4-rogerq@ti.com
State New
Headers show
Series phy: omap-usb2: add quirk to disable charger detection | expand

Commit Message

Roger Quadros July 16, 2020, 8:22 a.m. UTC
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.

Using property "ti,disable-charger-det" in the DT usb2-phy node to
enable this workaround for AM654x PG1.0.

This addresses Silicon Errata:
i2075 - "USB2PHY: USB2PHY Charger Detect is Enabled by Default Without VBUS
Presence"

Signed-off-by: Bin Liu <b-liu@ti.com>

Signed-off-by: Sekhar Nori <nsekhar@ti.com>

Signed-off-by: Roger Quadros <rogerq@ti.com>

---
 drivers/phy/ti/phy-omap-usb2.c | 35 +++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

Comments

Jan Kiszka Aug. 19, 2020, 9:02 a.m. UTC | #1
On 16.07.20 10:22, Roger Quadros wrote:
> 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.

> 

> Using property "ti,disable-charger-det" in the DT usb2-phy node to

> enable this workaround for AM654x PG1.0.

> 

> This addresses Silicon Errata:

> i2075 - "USB2PHY: USB2PHY Charger Detect is Enabled by Default Without VBUS

> Presence"

> 

> Signed-off-by: Bin Liu <b-liu@ti.com>

> Signed-off-by: Sekhar Nori <nsekhar@ti.com>

> Signed-off-by: Roger Quadros <rogerq@ti.com>

> ---

>  drivers/phy/ti/phy-omap-usb2.c | 35 +++++++++++++++++++++++++++-------

>  1 file changed, 28 insertions(+), 7 deletions(-)

> 

> diff --git a/drivers/phy/ti/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c

> index cb2dd3230fa7..21c3904d4efc 100644

> --- a/drivers/phy/ti/phy-omap-usb2.c

> +++ b/drivers/phy/ti/phy-omap-usb2.c

> @@ -26,6 +26,10 @@

>  #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 +47,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 +241,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;

>  }

>  

> @@ -366,14 +378,12 @@ 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;

> -	}

> +	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");

> @@ -405,6 +415,17 @@ static int omap_usb2_probe(struct platform_device *pdev)

>  		}

>  	}

>  

> +	/*

> +	 * 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 (of_property_read_bool(node, "ti,disable-charger-det"))

> +		phy->flags |= OMAP_USB2_DISABLE_CHRG_DET;

>  

>  	phy->wkupclk = devm_clk_get(phy->dev, "wkupclk");

>  	if (IS_ERR(phy->wkupclk)) {

> 


Why a property, rather than SoC detection like in [1] and your previous
downstream version?

Jan

[1] https://patchwork.kernel.org/patch/11710643/

-- 
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux
Roger Quadros Aug. 19, 2020, 2:28 p.m. UTC | #2
On 19/08/2020 12:02, Jan Kiszka wrote:
> On 16.07.20 10:22, Roger Quadros wrote:

>> 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.

>>

>> Using property "ti,disable-charger-det" in the DT usb2-phy node to

>> enable this workaround for AM654x PG1.0.

>>

>> This addresses Silicon Errata:

>> i2075 - "USB2PHY: USB2PHY Charger Detect is Enabled by Default Without VBUS

>> Presence"

>>

>> Signed-off-by: Bin Liu <b-liu@ti.com>

>> Signed-off-by: Sekhar Nori <nsekhar@ti.com>

>> Signed-off-by: Roger Quadros <rogerq@ti.com>

>> ---

>>   drivers/phy/ti/phy-omap-usb2.c | 35 +++++++++++++++++++++++++++-------

>>   1 file changed, 28 insertions(+), 7 deletions(-)

>>

>> diff --git a/drivers/phy/ti/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c

>> index cb2dd3230fa7..21c3904d4efc 100644

>> --- a/drivers/phy/ti/phy-omap-usb2.c

>> +++ b/drivers/phy/ti/phy-omap-usb2.c

>> @@ -26,6 +26,10 @@

>>   #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 +47,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 +241,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;

>>   }

>>   

>> @@ -366,14 +378,12 @@ 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;

>> -	}

>> +	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");

>> @@ -405,6 +415,17 @@ static int omap_usb2_probe(struct platform_device *pdev)

>>   		}

>>   	}

>>   

>> +	/*

>> +	 * 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 (of_property_read_bool(node, "ti,disable-charger-det"))

>> +		phy->flags |= OMAP_USB2_DISABLE_CHRG_DET;

>>   

>>   	phy->wkupclk = devm_clk_get(phy->dev, "wkupclk");

>>   	if (IS_ERR(phy->wkupclk)) {

>>

> 

> Why a property, rather than SoC detection like in [1] and your previous

> downstream version?


I agree, that SoC detection is better way. Will spin a v5.

> 

> Jan

> 

> [1] https://patchwork.kernel.org/patch/11710643/

> 


cheers,
-roger
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
diff mbox series

Patch

diff --git a/drivers/phy/ti/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c
index cb2dd3230fa7..21c3904d4efc 100644
--- a/drivers/phy/ti/phy-omap-usb2.c
+++ b/drivers/phy/ti/phy-omap-usb2.c
@@ -26,6 +26,10 @@ 
 #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 +47,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 +241,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;
 }
 
@@ -366,14 +378,12 @@  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;
-	}
+	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");
@@ -405,6 +415,17 @@  static int omap_usb2_probe(struct platform_device *pdev)
 		}
 	}
 
+	/*
+	 * 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 (of_property_read_bool(node, "ti,disable-charger-det"))
+		phy->flags |= OMAP_USB2_DISABLE_CHRG_DET;
 
 	phy->wkupclk = devm_clk_get(phy->dev, "wkupclk");
 	if (IS_ERR(phy->wkupclk)) {