Skip to contentSkip to conversation

Work around sunxi otg usb phy bug which causes lo-speed devices to not work

PATCH New Hans de Goede 3 participants 12 messages Mar 29, 2015 – May 27, 2015

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover Work around sunxi otg usb phy bug which causes lo-speed devices to not work

Hi All,

Here is a patch-set to work around sunxi otg usb phy bug which causes some lo-speed devices to not work (they get disconnected at there first reset).

This patch set uses a private sunxi phy function, I know that this is not ideal, but given the rather perculiar nature of this bug / the needed workaround I believe that a private sunxi phy function is the best solution here.

This patch-set applies on top of my existing sun4i-usb-phy / musb-sunxi-glue patches.

Regards,

Hans

#1 lore raw

PATCH 1/3 phy-sun4i-usb: Add a sunxi specific function for setting squelch-detect

The sunxi otg phy has a bug where it wrongly detects a high speed squelch when reset on the root port gets de-asserted with a lo-speed device.

The workaround for this is to disable squelch detect before de-asserting reset, and re-enabling it after the reset de-assert is done. Add a sunxi specific phy function to allow the sunxi-musb glue to do this.

---
 drivers/phy/phy-sun4i-usb.c       |  9 +++++++++
 include/linux/phy/phy-sun4i-usb.h | 26 ++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 include/linux/phy/phy-sun4i-usb.h
drivers/phy/phy-sun4i-usb.c +9 -0
index 221e8ab..01eb08d 100644
@@ -33,6 +33,7 @@
 #include <linux/of_address.h>
 #include <linux/of_gpio.h>
 #include <linux/phy/phy.h>
+#include <linux/phy/phy-sun4i-usb.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/reset.h>
@@ -75,6 +76,7 @@
 #define PHY_OTG_FUNC_EN			0x28
 #define PHY_VBUS_DET_EN			0x29
 #define PHY_DISCON_TH_SEL		0x2a
+#define PHY_SQUELCH_DETECT		0x3c  
 
 #define MAX_PHYS			3
 
@@ -322,6 +324,13 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
 	return 0;
 }
 
+void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
+{
+	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+
+	sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2);
+}
+
 static struct phy_ops sun4i_usb_phy_ops = {
 	.init		= sun4i_usb_phy_init,
 	.exit		= sun4i_usb_phy_exit,
include/linux/phy/phy-sun4i-usb.h new file +26 -0
new file mode 100644
index 0000000..50aed92
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 Hans de Goede <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef PHY_SUN4I_USB_H_
+#define PHY_SUN4I_USB_H_
+
+#include "phy.h"
+
+/**
+ * sun4i_usb_phy_set_squelch_detect() - Enable/disable squelch detect
+ * @phy: reference to a sun4i usb phy
+ * @enabled: wether to enable or disable squelch detect
+ */
+void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled);
+
+#endif
Signature · 1 line
2.3.4
#2 lore raw

PATCH 1/3 phy-sun4i-usb: Add a sunxi specific function for setting squelch-detect

Hi,

Quoted 68 lines · Hans de Goede

The sunxi otg phy has a bug where it wrongly detects a high speed squelch when reset on the root port gets de-asserted with a lo-speed device.

The workaround for this is to disable squelch detect before de-asserting reset, and re-enabling it after the reset de-assert is done. Add a sunxi specific phy function to allow the sunxi-musb glue to do this.

---
 drivers/phy/phy-sun4i-usb.c       |  9 +++++++++
 include/linux/phy/phy-sun4i-usb.h | 26 ++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 include/linux/phy/phy-sun4i-usb.h
drivers/phy/phy-sun4i-usb.c +9 -0
index 221e8ab..01eb08d 100644
@@ -33,6 +33,7 @@
 #include <linux/of_address.h>
 #include <linux/of_gpio.h>
 #include <linux/phy/phy.h>
+#include <linux/phy/phy-sun4i-usb.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/reset.h>
@@ -75,6 +76,7 @@
 #define PHY_OTG_FUNC_EN			0x28
 #define PHY_VBUS_DET_EN			0x29
 #define PHY_DISCON_TH_SEL		0x2a
+#define PHY_SQUELCH_DETECT		0x3c  
 
 #define MAX_PHYS			3
 
@@ -322,6 +324,13 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
 	return 0;
 }
 
+void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
+{
+	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+
+	sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2);
+}
+
 static struct phy_ops sun4i_usb_phy_ops = {
 	.init		= sun4i_usb_phy_init,
 	.exit		= sun4i_usb_phy_exit,
include/linux/phy/phy-sun4i-usb.h new file +14 -0
new file mode 100644
index 0000000..50aed92
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 Hans de Goede <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef PHY_SUN4I_USB_H_

include/linux/phy/phy-sun4i-usb.h line 24

Quoted 10 lines
include/linux/phy/phy-sun4i-usb.h new file +10 -0
+#define PHY_SUN4I_USB_H_
+
+#include "phy.h"
+
+/**
+ * sun4i_usb_phy_set_squelch_detect() - Enable/disable squelch detect
+ * @phy: reference to a sun4i usb phy
+ * @enabled: wether to enable or disable squelch detect
+ */
+void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled);

breaks build if MUSB=y and SUN41_PHY=m

Signature · 8 lines
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150508/60352e85/attachment.sig>
#3 lore raw

PATCH 1/3 phy-sun4i-usb: Add a sunxi specific function for setting squelch-detect

Hi,

Quoted 75 lines · Felipe Balbi

Hi,

Quoted 72 lines · Hans de Goede

The sunxi otg phy has a bug where it wrongly detects a high speed squelch when reset on the root port gets de-asserted with a lo-speed device.

The workaround for this is to disable squelch detect before de-asserting reset, and re-enabling it after the reset de-assert is done. Add a sunxi specific phy function to allow the sunxi-musb glue to do this.

---
  drivers/phy/phy-sun4i-usb.c       |  9 +++++++++
  include/linux/phy/phy-sun4i-usb.h | 26 ++++++++++++++++++++++++++
  2 files changed, 35 insertions(+)

create mode 100644 include/linux/phy/phy-sun4i-usb.h

drivers/phy/phy-sun4i-usb.c +9 -0
index 221e8ab..01eb08d 100644
@@ -33,6 +33,7 @@
  #include <linux/of_address.h>
  #include <linux/of_gpio.h>
  #include <linux/phy/phy.h>
+#include <linux/phy/phy-sun4i-usb.h>
  #include <linux/platform_device.h>
  #include <linux/regulator/consumer.h>
  #include <linux/reset.h>
@@ -75,6 +76,7 @@
  #define PHY_OTG_FUNC_EN			0x28
  #define PHY_VBUS_DET_EN			0x29
  #define PHY_DISCON_TH_SEL		0x2a
+#define PHY_SQUELCH_DETECT		0x3c
 
  #define MAX_PHYS			3
 
@@ -322,6 +324,13 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
  	return 0;
  }
 
+void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
+{
+	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+
+	sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2);
+}
+
  static struct phy_ops sun4i_usb_phy_ops = {
  	.init		= sun4i_usb_phy_init,
  	.exit		= sun4i_usb_phy_exit,
include/linux/phy/phy-sun4i-usb.h new file +18 -0
new file mode 100644
index 0000000..50aed92
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 Hans de Goede <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef PHY_SUN4I_USB_H_
+#define PHY_SUN4I_USB_H_
+
+#include "phy.h"
+
Quoted 8 lines

include/linux/phy/phy-sun4i-usb.h line 24

Quoted 6 lines
include/linux/phy/phy-sun4i-usb.h new file +6 -0
+/**
+ * sun4i_usb_phy_set_squelch_detect() - Enable/disable squelch detect
+ * @phy: reference to a sun4i usb phy
+ * @enabled: wether to enable or disable squelch detect
+ */
+void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled);

breaks build if MUSB=y and SUN41_PHY=m

Ah, good one. So I assume that it is ok to fix this by doing:

drivers/usb/musb/Kconfig +1 -0
@@ -66,6 +66,7 @@ config USB_MUSB_SUNXI
         tristate "Allwinner (sunxi)"
         depends on ARCH_SUNXI
         depends on NOP_USB_XCEIV
+ depends on PHY_SUN4I_USB
         select EXTCON
         select GENERIC_PHY
         select SUNXI_SRAM

?

Also I've not heard anything back from you wrt my other musb sunxi preparation patches and the actual musb-sunxi patch? are those all ready for merging?

Regards,

Hans

#4 lore raw

PATCH 1/3 phy-sun4i-usb: Add a sunxi specific function for setting squelch-detect

Hi,

Quoted 92 lines · Hans de Goede

Hi,

Quoted 75 lines · Felipe Balbi

Hi,

Quoted 72 lines · Hans de Goede

The sunxi otg phy has a bug where it wrongly detects a high speed squelch when reset on the root port gets de-asserted with a lo-speed device.

The workaround for this is to disable squelch detect before de-asserting reset, and re-enabling it after the reset de-assert is done. Add a sunxi specific phy function to allow the sunxi-musb glue to do this.

---
 drivers/phy/phy-sun4i-usb.c       |  9 +++++++++
 include/linux/phy/phy-sun4i-usb.h | 26 ++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 include/linux/phy/phy-sun4i-usb.h
drivers/phy/phy-sun4i-usb.c +9 -0
index 221e8ab..01eb08d 100644
@@ -33,6 +33,7 @@
 #include <linux/of_address.h>
 #include <linux/of_gpio.h>
 #include <linux/phy/phy.h>
+#include <linux/phy/phy-sun4i-usb.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/reset.h>
@@ -75,6 +76,7 @@
 #define PHY_OTG_FUNC_EN			0x28
 #define PHY_VBUS_DET_EN			0x29
 #define PHY_DISCON_TH_SEL		0x2a
+#define PHY_SQUELCH_DETECT		0x3c
 
 #define MAX_PHYS			3
 
@@ -322,6 +324,13 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
 	return 0;
 }
 
+void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
+{
+	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+
+	sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2);
+}
+
 static struct phy_ops sun4i_usb_phy_ops = {
 	.init		= sun4i_usb_phy_init,
 	.exit		= sun4i_usb_phy_exit,
include/linux/phy/phy-sun4i-usb.h new file +18 -0
new file mode 100644
index 0000000..50aed92
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 Hans de Goede <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef PHY_SUN4I_USB_H_
+#define PHY_SUN4I_USB_H_
+
+#include "phy.h"
+
Quoted 8 lines

include/linux/phy/phy-sun4i-usb.h line 24

Quoted 6 lines
include/linux/phy/phy-sun4i-usb.h new file +6 -0
+/**
+ * sun4i_usb_phy_set_squelch_detect() - Enable/disable squelch detect
+ * @phy: reference to a sun4i usb phy
+ * @enabled: wether to enable or disable squelch detect
+ */
+void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled);

breaks build if MUSB=y and SUN41_PHY=m

Ah, good one. So I assume that it is ok to fix this by doing:

drivers/usb/musb/Kconfig config USB_MUSB_SUNXI · line 69

Quoted 4 lines
drivers/usb/musb/Kconfig +1 -0
@@ -66,6 +66,7 @@ config USB_MUSB_SUNXI
        tristate "Allwinner (sunxi)"
        depends on ARCH_SUNXI
        depends on NOP_USB_XCEIV
+ depends on PHY_SUN4I_USB

I would prefer not exporting any function from phy to musb. Perhaps figure out with Kishon how "set_squelch" can be added to PHY fwk ?

Quoted 3 lines

Also I've not heard anything back from you wrt my other musb sunxi preparation patches and the actual musb-sunxi patch? are those all ready for merging?

I'm a little iffy with all the function rewriting again because of a new set of limitations with a new platform. I'll review them more carefully maybe today or tomorrow.

cheers

Signature · 8 lines
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150511/4d3fd959/attachment.sig>
#5 lore raw

[linux-sunxi] Re: [PATCH 1/3] phy-sun4i-usb: Add a sunxi specific function for setting squelch-detect

Hi,

Quoted 92 lines · Felipe Balbi

Hi,

Quoted 89 lines · Hans de Goede

Hi,

Quoted 75 lines · Felipe Balbi

Hi,

Quoted 72 lines · Hans de Goede

The sunxi otg phy has a bug where it wrongly detects a high speed squelch when reset on the root port gets de-asserted with a lo-speed device.

The workaround for this is to disable squelch detect before de-asserting reset, and re-enabling it after the reset de-assert is done. Add a sunxi specific phy function to allow the sunxi-musb glue to do this.

---
  drivers/phy/phy-sun4i-usb.c       |  9 +++++++++
  include/linux/phy/phy-sun4i-usb.h | 26 ++++++++++++++++++++++++++
  2 files changed, 35 insertions(+)

create mode 100644 include/linux/phy/phy-sun4i-usb.h

drivers/phy/phy-sun4i-usb.c +9 -0
index 221e8ab..01eb08d 100644
@@ -33,6 +33,7 @@
  #include <linux/of_address.h>
  #include <linux/of_gpio.h>
  #include <linux/phy/phy.h>
+#include <linux/phy/phy-sun4i-usb.h>
  #include <linux/platform_device.h>
  #include <linux/regulator/consumer.h>
  #include <linux/reset.h>
@@ -75,6 +76,7 @@
  #define PHY_OTG_FUNC_EN			0x28
  #define PHY_VBUS_DET_EN			0x29
  #define PHY_DISCON_TH_SEL		0x2a
+#define PHY_SQUELCH_DETECT		0x3c
 
  #define MAX_PHYS			3
 
@@ -322,6 +324,13 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
  	return 0;
  }
 
+void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
+{
+	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+
+	sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2);
+}
+
  static struct phy_ops sun4i_usb_phy_ops = {
  	.init		= sun4i_usb_phy_init,
  	.exit		= sun4i_usb_phy_exit,
include/linux/phy/phy-sun4i-usb.h new file +18 -0
new file mode 100644
index 0000000..50aed92
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 Hans de Goede <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef PHY_SUN4I_USB_H_
+#define PHY_SUN4I_USB_H_
+
+#include "phy.h"
+
Quoted 8 lines

include/linux/phy/phy-sun4i-usb.h line 24

Quoted 6 lines
include/linux/phy/phy-sun4i-usb.h new file +6 -0
+/**
+ * sun4i_usb_phy_set_squelch_detect() - Enable/disable squelch detect
+ * @phy: reference to a sun4i usb phy
+ * @enabled: wether to enable or disable squelch detect
+ */
+void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled);

breaks build if MUSB=y and SUN41_PHY=m

Ah, good one. So I assume that it is ok to fix this by doing:

Quoted 10 lines

drivers/usb/musb/Kconfig config USB_MUSB_SUNXI · line 69

Quoted 7 lines
drivers/usb/musb/Kconfig +1 -0
@@ -66,6 +66,7 @@ config USB_MUSB_SUNXI
         tristate "Allwinner (sunxi)"
         depends on ARCH_SUNXI
         depends on NOP_USB_XCEIV
+ depends on PHY_SUN4I_USB

I would prefer not exporting any function from phy to musb. Perhaps figure out with Kishon how "set_squelch" can be added to PHY fwk ?

Normally one would never want to mess with these phy settings, this is just needed on sunxi because the otg phy there is quirky, so I really do believe that having platform specific phy functions is the most sensible solution here. As for adding the depends on, that is needed at a functional level anyways because the musb code cannot work with the phy code. All the platform specific phy functions do is add a link time dependency to the already present functional dependency.

Quoted 7 lines
Quoted 4 lines

Also I've not heard anything back from you wrt my other musb sunxi preparation patches and the actual musb-sunxi patch? are those all ready for merging?

I'm a little iffy with all the function rewriting again because of a new set of limitations with a new platform.

I actually have done my best to avoid to touching the core code were possible, e.g. I'm done the translating for the sunxi registers being at different addresses at the musb_read* / musb_write* level so as to avoid invasive surgery in the musb-core for this.

Also note that some of the bits of core code which I do change were using a very non orthogonal API before my changes, and my changes are actually a nice cleanup.

Regards,

Hans

#6 lore raw

[linux-sunxi] Re: [PATCH 1/3] phy-sun4i-usb: Add a sunxi specific function for setting squelch-detect

Hi Felipe,

Quoted 105 lines · Hans de Goede

Hi,

Quoted 102 lines · Felipe Balbi

Hi,

Quoted 92 lines · Hans de Goede

Hi,

Quoted 75 lines · Felipe Balbi

Hi,

Quoted 72 lines · Hans de Goede

The sunxi otg phy has a bug where it wrongly detects a high speed squelch when reset on the root port gets de-asserted with a lo-speed device.

The workaround for this is to disable squelch detect before de-asserting reset, and re-enabling it after the reset de-assert is done. Add a sunxi specific phy function to allow the sunxi-musb glue to do this.

---
   drivers/phy/phy-sun4i-usb.c       |  9 +++++++++
   include/linux/phy/phy-sun4i-usb.h | 26 ++++++++++++++++++++++++++
   2 files changed, 35 insertions(+)

create mode 100644 include/linux/phy/phy-sun4i-usb.h

drivers/phy/phy-sun4i-usb.c +9 -0
index 221e8ab..01eb08d 100644
@@ -33,6 +33,7 @@
   #include <linux/of_address.h>
   #include <linux/of_gpio.h>
   #include <linux/phy/phy.h>
+#include <linux/phy/phy-sun4i-usb.h>
   #include <linux/platform_device.h>
   #include <linux/regulator/consumer.h>
   #include <linux/reset.h>
@@ -75,6 +76,7 @@
   #define PHY_OTG_FUNC_EN			0x28
   #define PHY_VBUS_DET_EN			0x29
   #define PHY_DISCON_TH_SEL		0x2a
+#define PHY_SQUELCH_DETECT		0x3c
 
   #define MAX_PHYS			3
 
@@ -322,6 +324,13 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
   	return 0;
   }
 
+void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
+{
+	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+
+	sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2);
+}
+
   static struct phy_ops sun4i_usb_phy_ops = {
   	.init		= sun4i_usb_phy_init,
   	.exit		= sun4i_usb_phy_exit,
include/linux/phy/phy-sun4i-usb.h new file +18 -0
new file mode 100644
index 0000000..50aed92
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 Hans de Goede <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef PHY_SUN4I_USB_H_
+#define PHY_SUN4I_USB_H_
+
+#include "phy.h"
+
Quoted 8 lines

include/linux/phy/phy-sun4i-usb.h line 24

Quoted 6 lines
include/linux/phy/phy-sun4i-usb.h new file +6 -0
+/**
+ * sun4i_usb_phy_set_squelch_detect() - Enable/disable squelch detect
+ * @phy: reference to a sun4i usb phy
+ * @enabled: wether to enable or disable squelch detect
+ */
+void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled);

breaks build if MUSB=y and SUN41_PHY=m

Ah, good one. So I assume that it is ok to fix this by doing:

drivers/usb/musb/Kconfig config USB_MUSB_SUNXI · line 69

Quoted 4 lines
drivers/usb/musb/Kconfig +1 -0
@@ -66,6 +66,7 @@ config USB_MUSB_SUNXI
          tristate "Allwinner (sunxi)"
          depends on ARCH_SUNXI
          depends on NOP_USB_XCEIV
+ depends on PHY_SUN4I_USB

I would prefer not exporting any function from phy to musb. Perhaps figure out with Kishon how "set_squelch" can be added to PHY fwk ?

We don't want to be adding platform specific hooks in PHY framework. While exporting a function from PHY to MUSB is not the best thing, it's still okay since it is from musb sunxi glue only no?

Thanks
Kishon

#7 lore raw

[linux-sunxi] Re: [PATCH 1/3] phy-sun4i-usb: Add a sunxi specific function for setting squelch-detect

Hi,

Quoted 109 lines · Kishon Vijay Abraham I

Hi Felipe,

Quoted 105 lines · Hans de Goede

Hi,

Quoted 102 lines · Felipe Balbi

Hi,

Quoted 92 lines · Hans de Goede

Hi,

Quoted 75 lines · Felipe Balbi

Hi,

Quoted 72 lines · Hans de Goede

The sunxi otg phy has a bug where it wrongly detects a high speed squelch when reset on the root port gets de-asserted with a lo-speed device.

The workaround for this is to disable squelch detect before de-asserting reset, and re-enabling it after the reset de-assert is done. Add a sunxi specific phy function to allow the sunxi-musb glue to do this.

---
   drivers/phy/phy-sun4i-usb.c       |  9 +++++++++
   include/linux/phy/phy-sun4i-usb.h | 26 ++++++++++++++++++++++++++
   2 files changed, 35 insertions(+)

create mode 100644 include/linux/phy/phy-sun4i-usb.h

drivers/phy/phy-sun4i-usb.c +9 -0
index 221e8ab..01eb08d 100644
@@ -33,6 +33,7 @@
   #include <linux/of_address.h>
   #include <linux/of_gpio.h>
   #include <linux/phy/phy.h>
+#include <linux/phy/phy-sun4i-usb.h>
   #include <linux/platform_device.h>
   #include <linux/regulator/consumer.h>
   #include <linux/reset.h>
@@ -75,6 +76,7 @@
   #define PHY_OTG_FUNC_EN            0x28
   #define PHY_VBUS_DET_EN            0x29
   #define PHY_DISCON_TH_SEL        0x2a
+#define PHY_SQUELCH_DETECT        0x3c
 
   #define MAX_PHYS            3
 
@@ -322,6 +324,13 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
       return 0;
   }
 
+void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
+{
+    struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+
+    sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2);
+}
+
   static struct phy_ops sun4i_usb_phy_ops = {
       .init        = sun4i_usb_phy_init,
       .exit        = sun4i_usb_phy_exit,
include/linux/phy/phy-sun4i-usb.h new file +18 -0
new file mode 100644
index 0000000..50aed92
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 Hans de Goede <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef PHY_SUN4I_USB_H_
+#define PHY_SUN4I_USB_H_
+
+#include "phy.h"
+
Quoted 8 lines

include/linux/phy/phy-sun4i-usb.h line 24

Quoted 6 lines
include/linux/phy/phy-sun4i-usb.h new file +6 -0
+/**
+ * sun4i_usb_phy_set_squelch_detect() - Enable/disable squelch detect
+ * @phy: reference to a sun4i usb phy
+ * @enabled: wether to enable or disable squelch detect
+ */
+void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled);

breaks build if MUSB=y and SUN41_PHY=m

Ah, good one. So I assume that it is ok to fix this by doing:

drivers/usb/musb/Kconfig config USB_MUSB_SUNXI · line 69

Quoted 4 lines
drivers/usb/musb/Kconfig +1 -0
@@ -66,6 +66,7 @@ config USB_MUSB_SUNXI
          tristate "Allwinner (sunxi)"
          depends on ARCH_SUNXI
          depends on NOP_USB_XCEIV
+ depends on PHY_SUN4I_USB

I would prefer not exporting any function from phy to musb. Perhaps figure out with Kishon how "set_squelch" can be added to PHY fwk ?

Quoted 1 line

We don't want to be adding platform specific hooks in PHY framework. While exporting a function from PHY to MUSB is not the best thing, it's still okay since it is from musb sunxi glue only no?

Correct this only gets used by drivers/usb/musb/sunxi.c calling directly into drivers/phy/phy-sun4i-usb.c

Regards,

Hans

#8 lore raw

PATCH 1/3 phy-sun4i-usb: Add a sunxi specific function for setting squelch-detect

In reply to Hans de Goede
Quoted 8 lines · Hans de Goede

The sunxi otg phy has a bug where it wrongly detects a high speed squelch when reset on the root port gets de-asserted with a lo-speed device.

The workaround for this is to disable squelch detect before de-asserting reset, and re-enabling it after the reset de-assert is done. Add a sunxi specific phy function to allow the sunxi-musb glue to do this.

Kishon, do you want to take this patch?

Signature · 8 lines
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150526/757cfc83/attachment.sig>
#9 lore raw

PATCH 1/3 phy-sun4i-usb: Add a sunxi specific function for setting squelch-detect

Felipe,

Quoted 11 lines · Felipe Balbi
Quoted 8 lines · Hans de Goede

The sunxi otg phy has a bug where it wrongly detects a high speed squelch when reset on the root port gets de-asserted with a lo-speed device.

The workaround for this is to disable squelch detect before de-asserting reset, and re-enabling it after the reset de-assert is done. Add a sunxi specific phy function to allow the sunxi-musb glue to do this.

Kishon, do you want to take this patch?

This patch should go along with the other patch in the series. So I think it's better you take this series along with the musb sunxi patch series.

Thanks
Kishon

#10 lore raw

PATCH 2/3 musb: Add pre and post root port reset end callbacks

In reply to Hans de Goede

The sunxi otg phy has a bug where it wrongly detects a high speed squelch when reset on the root port gets de-asserted with a lo-speed device.

The workaround for this is to disable squelch detect before de-asserting reset, and re-enabling it after the reset de-assert is done.

---
 drivers/usb/musb/musb_core.h    | 16 ++++++++++++++++
 drivers/usb/musb/musb_virthub.c |  2 ++
 2 files changed, 18 insertions(+)
drivers/usb/musb/musb_core.h +16 -0
index 444b936..19d7b8c 100644
@@ -163,6 +163,8 @@ struct musb_io;
  * @vbus_status: returns vbus status if possible
  * @set_vbus:	forces vbus status
  * @adjust_channel_params: pre check for standard dma channel_program func
+ * @pre_root_reset_end: called before the root usb port reset flag gets cleared
+ * @post_root_reset_end: called after the root usb port reset flag gets cleared
  */
 struct musb_platform_ops {
 
@@ -205,6 +207,8 @@ struct musb_platform_ops {
 	int	(*adjust_channel_params)(struct dma_channel *channel,
 				u16 packet_sz, u8 *mode,
 				dma_addr_t *dma_addr, u32 *len);
+	void	(*pre_root_reset_end)(struct musb *musb);
+	void	(*post_root_reset_end)(struct musb *musb);
 };
 
 /*
@@ -592,4 +596,16 @@ static inline int musb_platform_exit(struct musb *musb)
 	return musb->ops->exit(musb);
 }
 
+static inline void musb_platform_pre_root_reset_end(struct musb *musb)
+{
+	if (musb->ops->pre_root_reset_end)
+		musb->ops->pre_root_reset_end(musb);
+}
+
+static inline void musb_platform_post_root_reset_end(struct musb *musb)
+{
+	if (musb->ops->post_root_reset_end)
+		musb->ops->post_root_reset_end(musb);
+}
+
 #endif	/* __MUSB_CORE_H__ */
drivers/usb/musb/musb_virthub.c +2 -0
index 3c87fd7..e613f8c 100644
@@ -195,8 +195,10 @@ void musb_port_reset(struct musb *musb, bool do_reset)
 				      msecs_to_jiffies(50));
 	} else {
 		dev_dbg(musb->controller, "root port reset stopped\n");
+		musb_platform_pre_root_reset_end(musb);
 		musb_writeb(mbase, MUSB_POWER,
 				power & ~MUSB_POWER_RESET);
+		musb_platform_post_root_reset_end(musb);
 
 		power = musb_readb(mbase, MUSB_POWER);
 		if (power & MUSB_POWER_HSMODE) {
Signature · 1 line
2.3.4
#11 lore raw

PATCH 3/3 msub: sunxi: Add pre/post root reset end platform functions

In reply to Hans de Goede

Add pre/post root reset end platform functions and make them call sun4i_usb_phy_set_squelch_detect() to work around the sunxi usb otg phy workaround.

---
 drivers/usb/musb/sunxi.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
drivers/usb/musb/sunxi.c +17 -0
index ef91548..774312f 100644
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/phy/phy-sun4i-usb.h>
 #include <linux/platform_device.h>
 #include <linux/soc/sunxi/sunxi_sram.h>
 #include <linux/usb/musb.h>
@@ -147,6 +148,20 @@ static void sunxi_musb_set_vbus(struct musb *musb, int is_on)
 	schedule_work(&glue->work);
 }
 
+void sunxi_musb_pre_root_reset_end(struct musb *musb)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+	sun4i_usb_phy_set_squelch_detect(glue->phy, false);
+}
+
+void sunxi_musb_post_root_reset_end(struct musb *musb)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+	sun4i_usb_phy_set_squelch_detect(glue->phy, true);
+}
+
 static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
 {
 	struct musb *musb = __hci;
@@ -515,6 +530,8 @@ static const struct musb_platform_ops sunxi_musb_ops = {
 	.readw		= sunxi_musb_readw,
 	.writew		= sunxi_musb_writew,
 	.set_vbus	= sunxi_musb_set_vbus,
+	.pre_root_reset_end = sunxi_musb_pre_root_reset_end,
+	.post_root_reset_end = sunxi_musb_post_root_reset_end,
 };
 
 /* Allwinner OTG supports up to 5 endpoints */
Signature · 1 line
2.3.4