Skip to contentSkip to conversation

musb: Add support for the Allwinner sunxi musb controller

PATCH New Hans de Goede 6 participants 44 messages Mar 9, 2015 – Mar 11, 2015

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

cover musb: Add support for the Allwinner sunxi musb controller

Hi All,

This patch set has been a while in the making, so I'm very happy to present the end result here, and I hope everyone likes it.

Before talking about merging this there are 2 things which I would like to point out:

a) The musb controller in the sunxi SoCs uses some SRAM which needs to be mapped to the musb controller by poking some bits in the SRAM controller, just like the EMAC patches which were send a while back I've chosen to use syscon for this, actually 2 of the patches in this set come directly from the SRAM mapping patchset for the EMAC.

I know that Maxime is not 100% in favor of using syscon:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html

But I disagree with his arguments for writing a special driver for the SRAM controller:
1) syscon was specifically designed for global system control registers like this and is fine to use as long as there are no conflicts where 1 bit is of interest to multiple drivers, and there is no such conflict here
2) Maxime's other arguments seem to boil down to it would be nice / prettier to have a specific driver for this, without really proving a hard need for such a driver. But writing such a driver is going to be a lot of work, and we've a ton of other work to do, and as said there is no real need for a separate driver, syscon works fine for this.
3) I actually believe that having a specific driver for this is a bad idea, because that means inventing a whole new cross driver API for this, and getting those right is, hard, a lot of work, and even then one is still likely to get it wrong. We can avoid all this by going with the proven syscon solution.

Maxime, can we please have your ack for moving forward with this using syscon? (see above for my arguments why)

b) If you look closely at the new drivers/usb/musb/sunxi.c file you will see that there is some register address translation happening in the sunxi_musb_readb() function and related functions. This is necessary because the registermap of the sunxi musb implementation is different from the other musb implementation and sunxi uses multi-platform kernels.

I've considered adding full dynamic register map support to musb but I've chosen not to. The problem is that the way the musb code currently works is that there are 4 different address spaces used within the musb code:

1) musb->regs, the base address of the controller used for general control register access like the DEVCTL and POWER regs

2) The address space at the offset returned by musb_io.ep_offset, which contains ep control registers, this may be a different offset per endpoint, or indexed by the INDEX register

3) The address space at the offset returned by musb_io.fifo_offset, which contains the endpoint fifo data register, this is a different offset per ep.

4) The address space at the offset returned by MUSB_BUSCTL_OFFSET macro (which gets repaced by musb_io.busctl_offset in this patchset), this may be a different offset per endpoint, or indexed by the INDEX register

Turning this into something using dynamic register mapping is quite hard, esp. since some parts of the address range are per endpoint and the number of endpoints varies from one implementation to the next.

Besides this there also is the issue that I lack hardware to test invasive changes like this for all different musb variants. So I've chosen to do the necessary address translation (which really is only necessary for the general control registers) in a sunxi specific readb & friends implementation, avoiding the need to make invasive chances elsewhere and thus hopefully avoiding any regressions.

Note that some small core changes are still necessary, mostly to rationalize the busctl register handling, and make it more generic as sunxi has indexed busctl registers.

So with that all said lets talk about getting this merged upstream, assuming that the code passes review :)

The first patch in the set adds a header with defines for the sun4i syscon registers. Since this has already been acked by one of the MFD maintainers, I suggest we simply merge this through the musb maintainer together with all the other musb patches, as this introduces a new file without changing any other files collisions are impossible.

The second patch makes some minimal changes to the phy-sun4i-usb driver, I believe it is best to merge this through the musb maintainer too, so that all buildtime deps go in through one tree. Kishon can you review this patch please and let us know if it is ok to merge this through the musb tree?

Then we get 5 musb patches, 4 preparation patches and 1 adding the actual sunxi musb support, which should go through the musb tree obviously.

So assuming everyone agrees this means that patches 1 - 7 should be merged through Felipe's tree. Felipe, is that ok with you and can you review these patches please?

That leaves us with patches 8 - 15 which are all sunxi dts patches and as such should go upstream through Maxime's tree once patches 1 - 7 are queued up for merging. Maxime can you give these a review so that I can address any comments, so that they will be ready to go once patches 1 - 7 are in place ?

Thanks & Regards,

Hans

#1 lore raw

PATCH 1/15 ARM: sunxi: Add register bit definitions for SRAM mapping syscon

From: Chen-Yu Tsai <[email protected]>

---
 include/linux/mfd/syscon/sun4i-sc.h | 42 +++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 include/linux/mfd/syscon/sun4i-sc.h
include/linux/mfd/syscon/sun4i-sc.h new file +42 -0
new file mode 100644
index 0000000..fb970d9
@@ -0,0 +1,42 @@
+/**
+ * sun4i-sc.h - Allwinner sun4i system control register bit definitions
+ *
+ * Copyright (C) 2014 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai  <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 __LINUX_SUN4I_SC_H
+#define __LINUX_SUN4I_SC_H
+
+#include <linux/bitops.h>
+
+/* Registers */
+#define SUN4I_SC0	0x00
+#define SUN4I_SC1	0x04
+
+/* SRAM control register 0 bits */
+#define SUN4I_SC0_SRAM_C1_MAP_VE	0x7fffffff
+
+/* SRAM control register 1 bits */
+#define SUN4I_SC1_BIST_NDMA_CTRL_SEL	BIT(31)
+#define SUN4I_SC1_SRAM_C3_MAP_ISP	BIT(12)
+#define SUN4I_SC1_SRAM_C2_MAP_MASK	0x0300
+#define SUN4I_SC1_SRAM_C2_MAP_AE	0x0100
+#define SUN4I_SC1_SRAM_C2_MAP_CE	0x0200
+#define SUN4I_SC1_SRAM_C2_MAP_ACE	0x0300
+#define SUN4I_SC1_SRAM_A3_A4_MAP_MASK	0x0030
+#define SUN4I_SC1_SRAM_A3_A4_MAP_EMAC	0x0010
+#define SUN4I_SC1_SRAM_D_MAP_USB0	BIT(0)
+
+#endif /* __LINUX_SUN4I_SC_H */
Signature · 1 line
2.3.1
#2 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

In reply to Hans de Goede

Add sun4i_usb_phy_update_iscr() helper function to allow the otg driver to update the sun4i usb phy0 Interface Status and Control Register.

---
 drivers/phy/phy-sun4i-usb.c       | 13 +++++++++++++
 include/linux/phy/phy-sun4i-usb.h | 26 ++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)
 create mode 100644 include/linux/phy/phy-sun4i-usb.h
drivers/phy/phy-sun4i-usb.c +13 -0
index a2b08f3c..4742d5a 100644
@@ -79,6 +79,19 @@ struct sun4i_usb_phy_data {
 #define to_sun4i_usb_phy_data(phy) \
 	container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index])
 
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+	u32 iscr;
+
+	iscr = readl(data->base + REG_ISCR);
+	iscr &= ~clr;
+	iscr |= set;
+	writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+
 static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
 				int len)
 {
include/linux/phy/phy-sun4i-usb.h new file +26 -0
new file mode 100644
index 0000000..f69e784
@@ -0,0 +1,26 @@
+/*
+ * Allwinner sun4i USB phy header
+ *
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __PHY_SUN4I_USB_H
+#define __PHY_SUN4I_USB_H
+
+#include <linux/phy/phy.h>
+
+/**
+ * sun4i_usb_phy_update_iscr() - Update sun4i usb phy0 Interface Status and
+ * Control bits
+ * @phy: Reference to sun4i usb phy0
+ * @clr: bits to clear in the ISCR register
+ * @set: bits to set in the ISCR register
+ */
+void sun4i_usb_phy_update_iscr(struct phy *phy, u32 clr, u32 set);
+
+#endif
Signature · 1 line
2.3.1
#3 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

Quoted 4 lines · On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
drivers/phy/phy-sun4i-usb.c +3 -0
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);

drivers/phy/phy-sun4i-usb.c struct sun4i_usb_phy_data { · line 94

Quoted 10 lines
drivers/phy/phy-sun4i-usb.c +10 -0
+       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+       u32 iscr;
+
+       iscr = readl(data->base + REG_ISCR);
+       iscr &= ~clr;
+       iscr |= set;
+       writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+

I would generally consider this a bad design. What is the purpose of calling sun4i_usb_phy_update_iscr() and why can't there be a high-level PHY API for this?

The only other phy driver with exports like this is the OMAP driver, and that has caused problems in the past.

Arnd

#4 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

Hi,

Quoted 10 lines · Arnd Bergmann
Quoted 9 lines · On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
drivers/phy/phy-sun4i-usb.c +9 -0
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+       u32 iscr;
+
+       iscr = readl(data->base + REG_ISCR);
+       iscr &= ~clr;
+       iscr |= set;
Quoted 8 lines

drivers/phy/phy-sun4i-usb.c struct sun4i_usb_phy_data { · line 94

Quoted 5 lines
drivers/phy/phy-sun4i-usb.c +4 -0
+       writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+

I would generally consider this a bad design. What is the purpose of calling sun4i_usb_phy_update_iscr()

There are 2 different use cases for this one is to enable the dataline pull-ups at driver init and disable them at driver exit, this could / should probably be moved to the phy_init / phy_exit code for the usb0 phy removing the need to do this from within the sunxi musb glue.

The second use-case is more tricky, for some reasons Allwinner has decided to not use the dedicated id-detect and vusb-sense pins of the phy they are using (these pins are not routed to the outside).

Instead id-detect and vusb-sense are done through any $random gpio pins (including non irq capable pins on some designs requiring polling).

But the musb-core still needs to know the status of the id and vbus pins, and gets this from the usb0-phy iscr register, which reflects the status of the not connected dedicated pins of the phy. The reason this can still work at all is because the iscr register allows the user to override whatever the not connected phy pins are seeing and forcing a value to report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val)

{
         struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

         if (val)
                 val = SUNXI_ISCR_FORCE_ID_HIGH;
         else
                 val = SUNXI_ISCR_FORCE_ID_LOW;

         sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val)

{
         struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

         if (val)
                 val = SUNXI_ISCR_FORCE_VBUS_HIGH;
         else
                 val = SUNXI_ISCR_FORCE_VBUS_LOW;

         sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK, val);
}

I will happily admit that these 2 functions are a better API between the sunxi musb glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr approach as I wanted to keep the API as small as possible, but having 2 functions like the one above, which actually reflect what is happening would indeed be better.

Note that the polling of the pins cannot (easily) be moved into the phy driver for various reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on your second point.

Quoted 2 lines

and why can't there be a high-level
PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that in the long run people want to get rid of struct usb_phy, so maybe we should consider adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val); int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Functions in the generic phy API is a good idea, or if this is too sunxi specific, I'm fine with doing this either way. If we want to go the generic phy route I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and 1 doing the sunxi implementation.

If people believe this is too sunxi specific (I believe it is, but as said I'm fine with doing this either way). I'll respin this patch to remove the too generic sun4i_usb_phy_update_iscr function, and instead add these 2:

void sun4i_usb_phy_set_id_detect(struct phy *phy, bool val); void sun4i_usb_phy_set_vbus_detect(struct phy *phy, bool val);

Regards,

Hans

#5 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

Quoted 67 lines · On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:

Hi,

Quoted 10 lines · Arnd Bergmann
Quoted 9 lines · On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
drivers/phy/phy-sun4i-usb.c +9 -0
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+       u32 iscr;
+
+       iscr = readl(data->base + REG_ISCR);
+       iscr &= ~clr;
+       iscr |= set;
Quoted 8 lines

drivers/phy/phy-sun4i-usb.c struct sun4i_usb_phy_data { · line 94

Quoted 5 lines
drivers/phy/phy-sun4i-usb.c +4 -0
+       writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+

I would generally consider this a bad design. What is the purpose of calling sun4i_usb_phy_update_iscr()

There are 2 different use cases for this one is to enable the dataline pull-ups at driver init and disable them at driver exit, this could / should probably be moved to the phy_init / phy_exit code for the usb0 phy removing the need to do this from within the sunxi musb glue.

The second use-case is more tricky, for some reasons Allwinner has decided to not use the dedicated id-detect and vusb-sense pins of the phy they are using (these pins are not routed to the outside).

Instead id-detect and vusb-sense are done through any $random gpio pins (including non irq capable pins on some designs requiring polling).

But the musb-core still needs to know the status of the id and vbus pins, and gets this from the usb0-phy iscr register, which reflects the status of the not connected dedicated pins of the phy. The reason this can still work at all is because the iscr register allows the user to override whatever the not connected phy pins are seeing and forcing a value to report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val)

{
         struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

         if (val)
                 val = SUNXI_ISCR_FORCE_ID_HIGH;
         else
                 val = SUNXI_ISCR_FORCE_ID_LOW;

         sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val)

{
         struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

         if (val)
                 val = SUNXI_ISCR_FORCE_VBUS_HIGH;
         else
                 val = SUNXI_ISCR_FORCE_VBUS_LOW;

         sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK, val);
}
Quoted 4 lines

I will happily admit that these 2 functions are a better API between the sunxi musb glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr approach as I wanted to keep the API as small as possible, but having 2 functions like the one above, which actually reflect what is happening would indeed be better.

Ok, that would definitely improve things.

Quoted 28 lines

Note that the polling of the pins cannot (easily) be moved into the phy driver for various reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on your second point.

Quoted 2 lines

and why can't there be a high-level
PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that in the long run people want to get rid of struct usb_phy, so maybe we should consider adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val); int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Functions in the generic phy API is a good idea, or if this is too sunxi specific, I'm fine with doing this either way. If we want to go the generic phy route I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and 1 doing the sunxi implementation.

Quoted 6 lines

If people believe this is too sunxi specific (I believe it is, but as said I'm fine with doing this either way). I'll respin this patch to remove the too generic sun4i_usb_phy_update_iscr function, and instead add these 2:

void sun4i_usb_phy_set_id_detect(struct phy *phy, bool val); void sun4i_usb_phy_set_vbus_detect(struct phy *phy, bool val);

Thanks for your detailed explanations. I think this is something for Kishon to decide, based on where he wants to take the phy API in the long run. I'm fine with it either way, and it seems easy enough to change between those two interfaces if we make up our minds about it later.

Arnd

#6 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

Hi,

Quoted 107 lines · Arnd Bergmann
Quoted 67 lines · On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:

Hi,

Quoted 10 lines · Arnd Bergmann
Quoted 9 lines · On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
drivers/phy/phy-sun4i-usb.c +9 -0
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+       u32 iscr;
+
+       iscr = readl(data->base + REG_ISCR);
+       iscr &= ~clr;
+       iscr |= set;
Quoted 8 lines

drivers/phy/phy-sun4i-usb.c struct sun4i_usb_phy_data { · line 94

Quoted 5 lines
drivers/phy/phy-sun4i-usb.c +4 -0
+       writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+

I would generally consider this a bad design. What is the purpose of calling sun4i_usb_phy_update_iscr()

There are 2 different use cases for this one is to enable the dataline pull-ups at driver init and disable them at driver exit, this could / should probably be moved to the phy_init / phy_exit code for the usb0 phy removing the need to do this from within the sunxi musb glue.

The second use-case is more tricky, for some reasons Allwinner has decided to not use the dedicated id-detect and vusb-sense pins of the phy they are using (these pins are not routed to the outside).

Instead id-detect and vusb-sense are done through any $random gpio pins (including non irq capable pins on some designs requiring polling).

But the musb-core still needs to know the status of the id and vbus pins, and gets this from the usb0-phy iscr register, which reflects the status of the not connected dedicated pins of the phy. The reason this can still work at all is because the iscr register allows the user to override whatever the not connected phy pins are seeing and forcing a value to report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val)

{
          struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_ID_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_ID_LOW;

          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val)

{
          struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_VBUS_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_VBUS_LOW;

          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK, val);
}
Quoted 4 lines

I will happily admit that these 2 functions are a better API between the sunxi musb glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr approach as I wanted to keep the API as small as possible, but having 2 functions like the one above, which actually reflect what is happening would indeed be better.

Ok, that would definitely improve things.

Quoted 32 lines

Note that the polling of the pins cannot (easily) be moved into the phy driver for various reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on your second point.

Quoted 2 lines

and why can't there be a high-level
PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that in the long run people want to get rid of struct usb_phy, so maybe we should consider adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val); int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Functions in the generic phy API is a good idea, or if this is too sunxi specific, I'm fine with doing this either way. If we want to go the generic phy route I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and 1 doing the sunxi implementation.

If people believe this is too sunxi specific (I believe it is, but as said I'm fine with doing this either way). I'll respin this patch to remove the too generic sun4i_usb_phy_update_iscr function, and instead add these 2:

Quoted 8 lines
Quoted 2 lines

void sun4i_usb_phy_set_id_detect(struct phy *phy, bool val); void sun4i_usb_phy_set_vbus_detect(struct phy *phy, bool val);

Thanks for your detailed explanations. I think this is something for Kishon to decide, based on where he wants to take the phy API in the long run. I'm fine with it either way, and it seems easy enough to change between those two interfaces if we make up our minds about it later.

Ok, so I've fixed things in my personal tree to use 2 sun4i private functions for now:

void sun4i_usb_phy_set_id_detect(struct phy *phy, bool val); void sun4i_usb_phy_set_vbus_detect(struct phy *phy, bool val);

You can find this change here:
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-wip

I'll wait a bit to see if there are more review comments and then I'll send a v2 of the set.

Regards,

Hans

#7 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

Hi,

Quoted 25 lines · Hans de Goede

Hi,

Quoted 22 lines · Arnd Bergmann
Quoted 21 lines · On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:

Hi,

Quoted 18 lines · Arnd Bergmann
Quoted 4 lines · On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
drivers/phy/phy-sun4i-usb.c +3 -0
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);

drivers/phy/phy-sun4i-usb.c struct sun4i_usb_phy_data { · line 94

Quoted 10 lines
drivers/phy/phy-sun4i-usb.c +10 -0
+       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+       u32 iscr;
+
+       iscr = readl(data->base + REG_ISCR);
+       iscr &= ~clr;
+       iscr |= set;
+       writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+

I would generally consider this a bad design. What is the purpose of calling sun4i_usb_phy_update_iscr()

right. That would bind the PHY driver and the controller driver and would start creating problems when a different PHY is connected with the controller.

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

There are 2 different use cases for this one is to enable the dataline pull-ups at driver init and disable them at driver exit, this could / should probably be moved to the phy_init / phy_exit code for the usb0 phy removing the need to do this from within the sunxi musb glue.

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

The second use-case is more tricky, for some reasons Allwinner has decided to not use the dedicated id-detect and vusb-sense pins of the phy they are using (these pins are not routed to the outside).

Instead id-detect and vusb-sense are done through any $random gpio pins (including non irq capable pins on some designs requiring polling).

The polling can still be done in PHY driver and can use the extcon framework to report the status to controller driver no?

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

But the musb-core still needs to know the status of the id and vbus pins,

musb-core or the musb-glue (musb/sunxi.c in this case)?

Quoted 12 lines
Quoted 12 lines
Quoted 12 lines

and gets this from the usb0-phy iscr register, which reflects the status of the not connected dedicated pins of the phy. The reason this can still work at all is because the iscr register allows the user to override whatever the not connected phy pins are seeing and forcing a value to report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val)

{
          struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
          if (val)
                  val = SUNXI_ISCR_FORCE_ID_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_ID_LOW;

          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);

What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq interrupt handler?

Quoted 52 lines
Quoted 52 lines
Quoted 15 lines

}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val)

{
          struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_VBUS_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_VBUS_LOW;

          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,

val);
}

Quoted 7 lines

I will happily admit that these 2 functions are a better API between the sunxi musb
glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
approach as I wanted to keep the API as small as possible, but having 2 functions like
the one above, which actually reflect what is happening would indeed be better.

Ok, that would definitely improve things.

Quoted 27 lines

Note that the polling of the pins cannot (easily) be moved into the phy driver for various
reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on your second point.

Quoted 2 lines

and why can't there be a high-level
PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that
in the long run people want to get rid of struct usb_phy, so maybe we should consider
adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val); int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

Functions in the generic phy API is a good idea, or if this is too sunxi specific,
I'm fine with doing this either way. If we want to go the generic phy route I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
1 doing the sunxi implementation.

Please don't do that. We don't want to be bloating phy framework with platform specific hooks.

Cheers
Kishon

#8 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

Hi,

Quoted 42 lines · Kishon Vijay Abraham I

Hi,

Quoted 25 lines · Hans de Goede

Hi,

Quoted 22 lines · Arnd Bergmann
Quoted 21 lines · On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:

Hi,

Quoted 18 lines · Arnd Bergmann
Quoted 4 lines · On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
drivers/phy/phy-sun4i-usb.c +3 -0
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);

drivers/phy/phy-sun4i-usb.c struct sun4i_usb_phy_data { · line 94

Quoted 10 lines
drivers/phy/phy-sun4i-usb.c +10 -0
+       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+       u32 iscr;
+
+       iscr = readl(data->base + REG_ISCR);
+       iscr &= ~clr;
+       iscr |= set;
+       writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+

I would generally consider this a bad design. What is the purpose of calling sun4i_usb_phy_update_iscr()

right. That would bind the PHY driver and the controller driver and would start creating problems when a different PHY is connected with the controller.

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines

There are 2 different use cases for this one is to enable the dataline pull-ups at driver init and disable them at driver exit, this could / should probably be moved to the phy_init / phy_exit code for the usb0 phy removing the need to do this from within the sunxi musb glue.

The second use-case is more tricky, for some reasons Allwinner has decided to not use the dedicated id-detect and vusb-sense pins of the phy they are using (these pins are not routed to the outside).

Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

Instead id-detect and vusb-sense are done through any $random gpio pins (including non irq capable pins on some designs requiring polling).

The polling can still be done in PHY driver and can use the extcon framework to report the status to controller driver no?

Technically the polling can be moved to the phy driver yes, but it is not easy, e.g. we only need to poll when we're in otg mode rather then host-only or peripheral-only mode, and the mode gets set by the musb driver not phy the phy driver. The sunxi musb implementation uses an integrated phy, so it is just much easier and more logical to have all control / polling happening from a single module rather then from 2 different modules.

Quoted 21 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

But the musb-core still needs to know the status of the id and vbus pins,

musb-core or the musb-glue (musb/sunxi.c in this case)?

Quoted 17 lines
Quoted 17 lines
Quoted 17 lines

and gets this from the usb0-phy iscr register, which reflects the status of the not connected dedicated pins of the phy. The reason this can still work at all is because the iscr register allows the user to override whatever the not connected phy pins are seeing and forcing a value to report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val)

{
          struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_ID_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_ID_LOW;
Quoted 4 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);

What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq interrupt handler?

No this changes the vbus and id status as seen by the musb core, and the musb responds to this, by e.g. starting a session, or when vbus does not get high after a session request by reporting a vbus-error interrupt.

The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio pins which are used to monitor the id and vbus status.

Quoted 59 lines
Quoted 52 lines
Quoted 52 lines
Quoted 15 lines

}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val)

{
          struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_VBUS_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_VBUS_LOW;

          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,

val);
}

Quoted 7 lines

I will happily admit that these 2 functions are a better API between the sunxi musb
glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
approach as I wanted to keep the API as small as possible, but having 2 functions like
the one above, which actually reflect what is happening would indeed be better.

Ok, that would definitely improve things.

Quoted 27 lines

Note that the polling of the pins cannot (easily) be moved into the phy driver for various
reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on your second point.

Quoted 2 lines

and why can't there be a high-level
PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that
in the long run people want to get rid of struct usb_phy, so maybe we should consider
adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val); int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

Functions in the generic phy API is a good idea, or if this is too sunxi specific,
I'm fine with doing this either way. If we want to go the generic phy route I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
1 doing the sunxi implementation.

Quoted 2 lines

Please don't do that. We don't want to be bloating phy framework with platform specific hooks.

Right, that was my feeling too. I believe that using sunxi specific phy functions here is best given that we're dealing with an otg controller + phy both if which are integrated in the same SoC, so we will never seen one used without the other or vice versa.

Regards,

Hans

#9 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

Hi,

Quoted 155 lines · Hans de Goede

Hi,

Quoted 42 lines · Kishon Vijay Abraham I

Hi,

Quoted 25 lines · Hans de Goede

Hi,

Quoted 22 lines · Arnd Bergmann
Quoted 21 lines · On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:

Hi,

Quoted 18 lines · Arnd Bergmann
Quoted 4 lines · On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
(quoted diff) +3 -0
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);

Review

Quoted 10 lines
(quoted diff) +10 -0
+       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+       u32 iscr;
+
+       iscr = readl(data->base + REG_ISCR);
+       iscr &= ~clr;
+       iscr |= set;
+       writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+

I would generally consider this a bad design. What is the purpose of calling sun4i_usb_phy_update_iscr()

right. That would bind the PHY driver and the controller driver and would start creating problems when a different PHY is connected with the controller.

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines

There are 2 different use cases for this one is to enable the dataline pull-ups at driver init and disable them at driver exit, this could / should probably be moved to the phy_init / phy_exit code for the usb0 phy removing the need to do this from within the sunxi musb glue.

The second use-case is more tricky, for some reasons Allwinner has decided to not use the dedicated id-detect and vusb-sense pins of the phy they are using (these pins are not routed to the outside).

Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

Instead id-detect and vusb-sense are done through any $random gpio pins (including non irq capable pins on some designs requiring polling).

The polling can still be done in PHY driver and can use the extcon framework to report the status to controller driver no?

Technically the polling can be moved to the phy driver yes, but it is not easy, e.g. we only need to poll when we're in otg mode rather then host-only or peripheral-only mode, and the mode gets set by the musb driver not phy the phy driver. The sunxi musb implementation uses an integrated phy, so it is just much easier and more logical to have all control / polling happening from a single module rather then from 2 different modules.

Quoted 22 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

But the musb-core still needs to know the status of the id and vbus pins,

musb-core or the musb-glue (musb/sunxi.c in this case)?

Quoted 18 lines
Quoted 18 lines
Quoted 18 lines

and gets this from the usb0-phy iscr register, which reflects the status of the not connected dedicated pins of the phy. The reason this can still work at all is because the iscr register allows the user to override whatever the not connected phy pins are seeing and forcing a value to report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val) {
struct sunxi_glue *glue =
dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_ID_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_ID_LOW;
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,

val);

What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq interrupt handler?

No this changes the vbus and id status as seen by the musb core, and the musb responds to this, by e.g. starting a session, or when vbus does not get high after a session request by reporting a vbus-error interrupt.

The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio pins which are used to monitor the id and vbus status.

Quoted 61 lines
Quoted 60 lines
Quoted 60 lines
Quoted 16 lines

}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val) {
struct sunxi_glue *glue =
dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_VBUS_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_VBUS_LOW;

          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,

val);
}

Quoted 8 lines

I will happily admit that these 2 functions are a better API between the sunxi musb
glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
approach as I wanted to keep the API as small as possible, but having 2 functions like
the one above, which actually reflect what is happening would indeed be better.

Ok, that would definitely improve things.

Quoted 33 lines

Note that the polling of the pins cannot (easily) be moved into the phy driver for various
reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on your second point.

Quoted 2 lines

and why can't there be a high-level
PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that
in the long run people want to get rid of struct usb_phy, so maybe we should consider
adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val); int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Functions in the generic phy API is a good idea, or if this is too sunxi specific,
I'm fine with doing this either way. If we want to go the generic phy route I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
1 doing the sunxi implementation.

Quoted 5 lines
Quoted 2 lines

Please don't do that. We don't want to be bloating phy framework with platform specific hooks.

Right, that was my feeling too. I believe that using sunxi specific phy functions here is best given that we're dealing with an otg controller + phy both if which

Using platform specific PHY functions dissolves the very purpose of creating the PHY framework. We have to find a better way.

Thanks
Kishon

#10 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

Hi,

Quoted 158 lines · Kishon Vijay Abraham I

Hi,

Quoted 155 lines · Hans de Goede

Hi,

Quoted 42 lines · Kishon Vijay Abraham I

Hi,

Quoted 25 lines · Hans de Goede

Hi,

Quoted 22 lines · Arnd Bergmann
Quoted 21 lines · On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:

Hi,

Quoted 18 lines · Arnd Bergmann
Quoted 4 lines · On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
(quoted diff) +3 -0
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);

Review

Quoted 10 lines
(quoted diff) +10 -0
+       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+       u32 iscr;
+
+       iscr = readl(data->base + REG_ISCR);
+       iscr &= ~clr;
+       iscr |= set;
+       writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+

I would generally consider this a bad design. What is the purpose of calling sun4i_usb_phy_update_iscr()

right. That would bind the PHY driver and the controller driver and would start creating problems when a different PHY is connected with the controller.

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines

There are 2 different use cases for this one is to enable the dataline pull-ups at driver init and disable them at driver exit, this could / should probably be moved to the phy_init / phy_exit code for the usb0 phy removing the need to do this from within the sunxi musb glue.

The second use-case is more tricky, for some reasons Allwinner has decided to not use the dedicated id-detect and vusb-sense pins of the phy they are using (these pins are not routed to the outside).

Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

Instead id-detect and vusb-sense are done through any $random gpio pins (including non irq capable pins on some designs requiring polling).

The polling can still be done in PHY driver and can use the extcon framework to report the status to controller driver no?

Technically the polling can be moved to the phy driver yes, but it is not easy, e.g. we only need to poll when we're in otg mode rather then host-only or peripheral-only mode, and the mode gets set by the musb driver not phy the phy driver. The sunxi musb implementation uses an integrated phy, so it is just much easier and more logical to have all control / polling happening from a single module rather then from 2 different modules.

Quoted 22 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

But the musb-core still needs to know the status of the id and vbus pins,

musb-core or the musb-glue (musb/sunxi.c in this case)?

Quoted 18 lines
Quoted 18 lines
Quoted 18 lines

and gets this from the usb0-phy iscr register, which reflects the status of the not connected dedicated pins of the phy. The reason this can still work at all is because the iscr register allows the user to override whatever the not connected phy pins are seeing and forcing a value to report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val) {
struct sunxi_glue *glue =
dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_ID_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_ID_LOW;
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,

val);

What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq interrupt handler?

No this changes the vbus and id status as seen by the musb core, and the musb responds to this, by e.g. starting a session, or when vbus does not get high after a session request by reporting a vbus-error interrupt.

The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio pins which are used to monitor the id and vbus status.

Quoted 61 lines
Quoted 60 lines
Quoted 60 lines
Quoted 16 lines

}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val) {
struct sunxi_glue *glue =
dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_VBUS_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_VBUS_LOW;

          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,

val);
}

Quoted 8 lines

I will happily admit that these 2 functions are a better API between the sunxi musb
glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
approach as I wanted to keep the API as small as possible, but having 2 functions like
the one above, which actually reflect what is happening would indeed be better.

Ok, that would definitely improve things.

Quoted 33 lines

Note that the polling of the pins cannot (easily) be moved into the phy driver for various
reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on your second point.

Quoted 2 lines

and why can't there be a high-level
PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that
in the long run people want to get rid of struct usb_phy, so maybe we should consider
adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val); int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Functions in the generic phy API is a good idea, or if this is too sunxi specific,
I'm fine with doing this either way. If we want to go the generic phy route I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
1 doing the sunxi implementation.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Please don't do that. We don't want to be bloating phy framework with platform specific hooks.

Right, that was my feeling too. I believe that using sunxi specific phy functions here is best given that we're dealing with an otg controller + phy both if which

Using platform specific PHY functions dissolves the very purpose of creating the PHY framework. We have to find a better way.

"We have to find a better way" is not really a helpful answer to the problem at hand. We're talking about a phy integrated on the same die, as, and closely working together with the otg controller, so we need some sort of coordination between the two.

The 2 logical options for coordinatinon are:

1) Add generic phy framework functions for such coordination -> Which you've nacked

2) Use platform private functions for this
-> Which you are essentially nacking above.

Which leaves us with what as solution exactly ?

I could make the phy-sun4i-usb.c driver register a struct usb_phy, as drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does, and communicate through that, but AFAIK that is deprecated ...

Regards,

Hans

#11 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

Hi,

Quoted 172 lines · Hans de Goede

Hi,

Quoted 169 lines · Kishon Vijay Abraham I

Hi,

Quoted 165 lines · Hans de Goede

Hi,

Quoted 42 lines · Kishon Vijay Abraham I

Hi,

Quoted 25 lines · Hans de Goede

Hi,

Quoted 22 lines · Arnd Bergmann
Quoted 21 lines · On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:

Hi,

Quoted 18 lines · Arnd Bergmann
Quoted 4 lines · On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
(quoted diff) +3 -0
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);

Review

Quoted 10 lines
(quoted diff) +10 -0
+       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+       u32 iscr;
+
+       iscr = readl(data->base + REG_ISCR);
+       iscr &= ~clr;
+       iscr |= set;
+       writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+

I would generally consider this a bad design. What is the purpose of calling sun4i_usb_phy_update_iscr()

right. That would bind the PHY driver and the controller driver and would start creating problems when a different PHY is connected with the controller.

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines

There are 2 different use cases for this one is to enable the dataline pull-ups at driver init and disable them at driver exit, this could / should probably be moved to the phy_init / phy_exit code for the usb0 phy removing the need to do this from within the sunxi musb glue.

The second use-case is more tricky, for some reasons Allwinner has decided to not use the dedicated id-detect and vusb-sense pins of the phy they are using (these pins are not routed to the outside).

Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

Instead id-detect and vusb-sense are done through any $random gpio pins (including non irq capable pins on some designs requiring polling).

The polling can still be done in PHY driver and can use the extcon framework to report the status to controller driver no?

Technically the polling can be moved to the phy driver yes, but it is not easy, e.g. we only need to poll when we're in otg mode rather then host-only or peripheral-only mode, and the mode gets set by the musb driver not phy the phy driver. The sunxi musb implementation uses an integrated phy, so it is just much easier and more logical to have all control / polling happening from a single module rather then from 2 different modules.

Quoted 22 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

But the musb-core still needs to know the status of the id and vbus pins,

musb-core or the musb-glue (musb/sunxi.c in this case)?

Quoted 18 lines
Quoted 18 lines
Quoted 18 lines

and gets this from the usb0-phy iscr register, which reflects the status of the not connected dedicated pins of the phy. The reason this can still work at all is because the iscr register allows the user to override whatever the not connected phy pins are seeing and forcing a value to report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val) {
struct sunxi_glue *glue =
dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_ID_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_ID_LOW;
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,

val);

What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq interrupt handler?

No this changes the vbus and id status as seen by the musb core, and the musb responds to this, by e.g. starting a session, or when vbus does not get high after a session request by reporting a vbus-error interrupt.

The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio pins which are used to monitor the id and vbus status.

Quoted 64 lines
Quoted 57 lines
Quoted 57 lines
Quoted 16 lines

}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val) {
struct sunxi_glue *glue =
dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_VBUS_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_VBUS_LOW;

          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,

val);
}

Quoted 8 lines

I will happily admit that these 2 functions are a better API between the sunxi musb
glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
approach as I wanted to keep the API as small as possible, but having 2 functions like
the one above, which actually reflect what is happening would indeed be better.

Ok, that would definitely improve things.

Quoted 30 lines

Note that the polling of the pins cannot (easily) be moved into the phy driver for various
reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on
your second point.

Quoted 2 lines

and why can't there be a high-level
PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that
in the long run people want to get rid of struct usb_phy, so maybe we should
consider
adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val); int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

Functions in the generic phy API is a good idea, or if this is too sunxi specific,
I'm fine with doing this either way. If we want to go the generic phy route I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
1 doing the sunxi implementation.

Quoted 2 lines

Please don't do that. We don't want to be bloating phy framework with platform specific hooks.

Right, that was my feeling too. I believe that using sunxi specific phy functions
here is best given that we're dealing with an otg controller + phy both if which

Quoted 6 lines
Quoted 2 lines

Using platform specific PHY functions dissolves the very purpose of creating the PHY framework. We have to find a better way.

"We have to find a better way" is not really a helpful answer to the problem at hand. We're talking about a phy integrated on the same die, as, and closely working

It's integrated in the same die but it is not within the controller IP. It's still possible to replace the PHY and have the same controller in the next SoC.

Quoted 5 lines

together with the otg controller, so we need some sort of coordination between the two.

The 2 logical options for coordinatinon are:

Quoted 7 lines

1) Add generic phy framework functions for such coordination -> Which you've nacked

2) Use platform private functions for this
-> Which you are essentially nacking above.

Which leaves us with what as solution exactly ?

We could poll on the GPIO in PHY driver to update the iscr register. I think it's alright to poll on the GPIO in multiple modules for serving it's own purpose IMHO.

Quoted 3 lines

I could make the phy-sun4i-usb.c driver register a struct usb_phy, as drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,

I'm not sure how will that help.

Cheers
Kishon

#12 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

Hi,

Quoted 192 lines · Kishon Vijay Abraham I

Hi,

Quoted 172 lines · Hans de Goede

Hi,

Quoted 169 lines · Kishon Vijay Abraham I

Hi,

Quoted 165 lines · Hans de Goede

Hi,

Quoted 42 lines · Kishon Vijay Abraham I

Hi,

Quoted 25 lines · Hans de Goede

Hi,

Quoted 22 lines · Arnd Bergmann
Quoted 21 lines · On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:

Hi,

Quoted 18 lines · Arnd Bergmann
Quoted 4 lines · On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
(quoted diff) +3 -0
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);

Review

Quoted 10 lines
(quoted diff) +10 -0
+       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+       u32 iscr;
+
+       iscr = readl(data->base + REG_ISCR);
+       iscr &= ~clr;
+       iscr |= set;
+       writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+

I would generally consider this a bad design. What is the purpose of calling sun4i_usb_phy_update_iscr()

right. That would bind the PHY driver and the controller driver and would start creating problems when a different PHY is connected with the controller.

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines

There are 2 different use cases for this one is to enable the dataline pull-ups at driver init and disable them at driver exit, this could / should probably be moved to the phy_init / phy_exit code for the usb0 phy removing the need to do this from within the sunxi musb glue.

The second use-case is more tricky, for some reasons Allwinner has decided to not use the dedicated id-detect and vusb-sense pins of the phy they are using (these pins are not routed to the outside).

Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

Instead id-detect and vusb-sense are done through any $random gpio pins (including non irq capable pins on some designs requiring polling).

The polling can still be done in PHY driver and can use the extcon framework to report the status to controller driver no?

Technically the polling can be moved to the phy driver yes, but it is not easy, e.g. we only need to poll when we're in otg mode rather then host-only or peripheral-only mode, and the mode gets set by the musb driver not phy the phy driver. The sunxi musb implementation uses an integrated phy, so it is just much easier and more logical to have all control / polling happening from a single module rather then from 2 different modules.

Quoted 22 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

But the musb-core still needs to know the status of the id and vbus pins,

musb-core or the musb-glue (musb/sunxi.c in this case)?

Quoted 18 lines
Quoted 18 lines
Quoted 18 lines

and gets this from the usb0-phy iscr register, which reflects the status of the not connected dedicated pins of the phy. The reason this can still work at all is because the iscr register allows the user to override whatever the not connected phy pins are seeing and forcing a value to report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val) {
struct sunxi_glue *glue =
dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_ID_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_ID_LOW;
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,

val);

What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq interrupt handler?

No this changes the vbus and id status as seen by the musb core, and the musb responds to this, by e.g. starting a session, or when vbus does not get high after a session request by reporting a vbus-error interrupt.

The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio pins which are used to monitor the id and vbus status.

Quoted 64 lines
Quoted 57 lines
Quoted 57 lines
Quoted 16 lines

}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val) {
struct sunxi_glue *glue =
dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_VBUS_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_VBUS_LOW;

          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,

val);
}

Quoted 8 lines

I will happily admit that these 2 functions are a better API between the sunxi musb
glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
approach as I wanted to keep the API as small as possible, but having 2 functions like
the one above, which actually reflect what is happening would indeed be better.

Ok, that would definitely improve things.

Quoted 30 lines

Note that the polling of the pins cannot (easily) be moved into the phy driver for various
reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on
your second point.

Quoted 2 lines

and why can't there be a high-level
PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that
in the long run people want to get rid of struct usb_phy, so maybe we should
consider
adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val); int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

Functions in the generic phy API is a good idea, or if this is too sunxi specific,
I'm fine with doing this either way. If we want to go the generic phy route I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
1 doing the sunxi implementation.

Quoted 2 lines

Please don't do that. We don't want to be bloating phy framework with platform specific hooks.

Right, that was my feeling too. I believe that using sunxi specific phy functions
here is best given that we're dealing with an otg controller + phy both if which

Quoted 6 lines
Quoted 2 lines

Using platform specific PHY functions dissolves the very purpose of creating the PHY framework. We have to find a better way.

"We have to find a better way" is not really a helpful answer to the problem at hand. We're talking about a phy integrated on the same die, as, and closely working

It's integrated in the same die but it is not within the controller IP. It's still possible to replace the PHY and have the same controller in the next SoC.

Quoted 8 lines

together with the otg controller, so we need some sort of coordination between the two.

The 2 logical options for coordinatinon are:

1) Add generic phy framework functions for such coordination -> Which you've nacked

Quoted 8 lines
Quoted 4 lines

2) Use platform private functions for this
-> Which you are essentially nacking above.

Which leaves us with what as solution exactly ?

We could poll on the GPIO in PHY driver to update the iscr register. I think it's alright to poll on the GPIO in multiple modules for serving it's own purpose IMHO.

No, polling in multiple places is just plain and simple wrong, also where-ever possible we use edge triggered gpio-interrupts for this and having multiple handlers for the same interrupt is even more wrong.

I'm fine with moving all the polling to the phy driver, but then we need to have a way to notify the sunxi musb glue about id pin changes.

Quoted 4 lines
Quoted 2 lines

I could make the phy-sun4i-usb.c driver register a struct usb_phy, as drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,

I'm not sure how will that help.

It helps when we move the polling to the phy driver as it has a notification mechanism for events which we can then use to tell the musb-sunxi glue about id pin changes.

Regards,

Hans

#13 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

Hi,

Quoted 213 lines · Hans de Goede

Hi,

Quoted 201 lines · Kishon Vijay Abraham I

Hi,

Quoted 180 lines · Hans de Goede

Hi,

Quoted 177 lines · Kishon Vijay Abraham I

Hi,

Quoted 173 lines · Hans de Goede

Hi,

Quoted 44 lines · Kishon Vijay Abraham I

Hi,

Quoted 25 lines · Hans de Goede

Hi,

Quoted 22 lines · Arnd Bergmann
Quoted 21 lines · On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:

Hi,

Quoted 18 lines · Arnd Bergmann
Quoted 4 lines · On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
(quoted diff) +3 -0
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);

Review

Quoted 10 lines
(quoted diff) +10 -0
+       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+       u32 iscr;
+
+       iscr = readl(data->base + REG_ISCR);
+       iscr &= ~clr;
+       iscr |= set;
+       writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+

I would generally consider this a bad design. What is the purpose of calling sun4i_usb_phy_update_iscr()

right. That would bind the PHY driver and the controller driver and would start creating problems when a different PHY is connected with the controller.

Quoted 12 lines
Quoted 12 lines
Quoted 12 lines

There are 2 different use cases for this one is to enable the dataline pull-ups at driver init and disable them at driver exit, this could / should probably be moved to the phy_init / phy_exit code for the usb0 phy removing the need to do this from within the sunxi musb glue.

The second use-case is more tricky, for some reasons Allwinner has decided
to not use the dedicated id-detect and vusb-sense pins of the phy they are
using (these pins are not routed to the outside).

Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

Instead id-detect and vusb-sense are done through any $random gpio pins (including non irq capable pins on some designs requiring polling).

The polling can still be done in PHY driver and can use the extcon framework to report the status to controller driver no?

Technically the polling can be moved to the phy driver yes, but it is not easy,
e.g. we only need to poll when we're in otg mode rather then host-only or peripheral-only mode, and the mode gets set by the musb driver not phy the phy driver. The sunxi musb implementation uses an integrated phy, so it is just much easier and more logical to have all control / polling happening from a single module rather then from 2 different modules.

Quoted 23 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

But the musb-core still needs to know the status of the id and vbus pins,

musb-core or the musb-glue (musb/sunxi.c in this case)?

Quoted 19 lines
Quoted 19 lines
Quoted 19 lines

and gets this from the usb0-phy iscr register, which reflects the status of
the not connected dedicated pins of the phy. The reason this can still work at all is because the iscr register allows the user to override whatever the not connected phy pins are seeing and forcing a value to report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val) {
struct sunxi_glue *glue =
dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_ID_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_ID_LOW;
Quoted 6 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,

val);

What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
interrupt handler?

No this changes the vbus and id status as seen by the musb core, and the musb responds to this, by e.g. starting a session, or when vbus does not get high after a session request by reporting a vbus-error interrupt.

The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio pins which are used to monitor the id and vbus status.

Quoted 66 lines
Quoted 58 lines
Quoted 58 lines
Quoted 17 lines

}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val) {
struct sunxi_glue *glue =
dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_VBUS_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_VBUS_LOW;

          sun4i_usb_phy_update_iscr(glue->phy,

SUNXI_ISCR_FORCE_VBUS_MASK,
val);
}

Quoted 8 lines

I will happily admit that these 2 functions are a better API between the sunxi musb
glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
approach as I wanted to keep the API as small as possible, but having 2 functions like
the one above, which actually reflect what is happening would indeed be better.

Ok, that would definitely improve things.

Quoted 30 lines

Note that the polling of the pins cannot (easily) be moved into the phy driver for various
reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on
your second point.

Quoted 2 lines

and why can't there be a high-level
PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that
in the long run people want to get rid of struct usb_phy, so maybe we should
consider
adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val); int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines

Functions in the generic phy API is a good idea, or if this is too sunxi specific,
I'm fine with doing this either way. If we want to go the generic phy route
I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
1 doing the sunxi implementation.

Quoted 3 lines

Please don't do that. We don't want to be bloating phy framework with platform
specific hooks.

Right, that was my feeling too. I believe that using sunxi specific phy functions
here is best given that we're dealing with an otg controller + phy both if which

Quoted 6 lines
Quoted 2 lines

Using platform specific PHY functions dissolves the very purpose of creating the PHY framework. We have to find a better way.

"We have to find a better way" is not really a helpful answer to the problem at hand. We're talking about a phy integrated on the same die, as, and closely working

It's integrated in the same die but it is not within the controller IP. It's still possible to replace the PHY and have the same controller in the next SoC.

Quoted 9 lines

together with the otg controller, so we need some sort of coordination between the
two.

The 2 logical options for coordinatinon are:

1) Add generic phy framework functions for such coordination -> Which you've nacked

Quoted 8 lines
Quoted 4 lines

2) Use platform private functions for this
-> Which you are essentially nacking above.

Which leaves us with what as solution exactly ?

We could poll on the GPIO in PHY driver to update the iscr register. I think it's alright to poll on the GPIO in multiple modules for serving it's own purpose IMHO.

Quoted 6 lines

No, polling in multiple places is just plain and simple wrong, also where-ever possible we use edge triggered gpio-interrupts for this and having multiple handlers for the same interrupt is even more wrong.

I'm fine with moving all the polling to the phy driver, but then we need to have a way to notify the sunxi musb glue about id pin changes.

As I mentioned before, we can use extcon framework for it.

Quoted 9 lines
Quoted 5 lines
Quoted 3 lines

I could make the phy-sun4i-usb.c driver register a struct usb_phy, as drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,

I'm not sure how will that help.

It helps when we move the polling to the phy driver as it has a notification mechanism for events which we can then use to tell the musb-sunxi glue about id pin changes.

extcon framework might help here.

Cheers
Kishon

#14 lore raw

PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register

Hi,

Quoted 228 lines · Kishon Vijay Abraham I

Hi,

Quoted 213 lines · Hans de Goede

Hi,

Quoted 201 lines · Kishon Vijay Abraham I

Hi,

Quoted 180 lines · Hans de Goede

Hi,

Quoted 177 lines · Kishon Vijay Abraham I

Hi,

Quoted 173 lines · Hans de Goede

Hi,

Quoted 44 lines · Kishon Vijay Abraham I

Hi,

Quoted 25 lines · Hans de Goede

Hi,

Quoted 22 lines · Arnd Bergmann
Quoted 21 lines · On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:

Hi,

Quoted 18 lines · Arnd Bergmann
Quoted 4 lines · On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
(quoted diff) +3 -0
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);

Review

Quoted 10 lines
(quoted diff) +10 -0
+       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+       u32 iscr;
+
+       iscr = readl(data->base + REG_ISCR);
+       iscr &= ~clr;
+       iscr |= set;
+       writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+

I would generally consider this a bad design. What is the purpose of calling sun4i_usb_phy_update_iscr()

right. That would bind the PHY driver and the controller driver and would start creating problems when a different PHY is connected with the controller.

Quoted 12 lines
Quoted 12 lines
Quoted 12 lines

There are 2 different use cases for this one is to enable the dataline pull-ups at driver init and disable them at driver exit, this could / should probably be moved to the phy_init / phy_exit code for the usb0 phy removing the need to do this from within the sunxi musb glue.

The second use-case is more tricky, for some reasons Allwinner has decided
to not use the dedicated id-detect and vusb-sense pins of the phy they are
using (these pins are not routed to the outside).

Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

Instead id-detect and vusb-sense are done through any $random gpio pins (including non irq capable pins on some designs requiring polling).

The polling can still be done in PHY driver and can use the extcon framework to report the status to controller driver no?

Technically the polling can be moved to the phy driver yes, but it is not easy,
e.g. we only need to poll when we're in otg mode rather then host-only or peripheral-only mode, and the mode gets set by the musb driver not phy the phy driver. The sunxi musb implementation uses an integrated phy, so it is just much easier and more logical to have all control / polling happening from a single module rather then from 2 different modules.

Quoted 23 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

But the musb-core still needs to know the status of the id and vbus pins,

musb-core or the musb-glue (musb/sunxi.c in this case)?

Quoted 19 lines
Quoted 19 lines
Quoted 19 lines

and gets this from the usb0-phy iscr register, which reflects the status of
the not connected dedicated pins of the phy. The reason this can still work at all is because the iscr register allows the user to override whatever the not connected phy pins are seeing and forcing a value to report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val) {
struct sunxi_glue *glue =
dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_ID_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_ID_LOW;
Quoted 6 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,

val);

What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
interrupt handler?

No this changes the vbus and id status as seen by the musb core, and the musb responds to this, by e.g. starting a session, or when vbus does not get high after a session request by reporting a vbus-error interrupt.

The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio pins which are used to monitor the id and vbus status.

Quoted 66 lines
Quoted 58 lines
Quoted 58 lines
Quoted 17 lines

}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val) {
struct sunxi_glue *glue =
dev_get_drvdata(musb->controller->parent);

          if (val)
                  val = SUNXI_ISCR_FORCE_VBUS_HIGH;
          else
                  val = SUNXI_ISCR_FORCE_VBUS_LOW;

          sun4i_usb_phy_update_iscr(glue->phy,

SUNXI_ISCR_FORCE_VBUS_MASK,
val);
}

Quoted 8 lines

I will happily admit that these 2 functions are a better API between the sunxi musb
glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
approach as I wanted to keep the API as small as possible, but having 2 functions like
the one above, which actually reflect what is happening would indeed be better.

Ok, that would definitely improve things.

Quoted 30 lines

Note that the polling of the pins cannot (easily) be moved into the phy driver for various
reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on
your second point.

Quoted 2 lines

and why can't there be a high-level
PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that
in the long run people want to get rid of struct usb_phy, so maybe we should
consider
adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val); int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines

Functions in the generic phy API is a good idea, or if this is too sunxi specific,
I'm fine with doing this either way. If we want to go the generic phy route
I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
1 doing the sunxi implementation.

Quoted 3 lines

Please don't do that. We don't want to be bloating phy framework with platform
specific hooks.

Right, that was my feeling too. I believe that using sunxi specific phy functions
here is best given that we're dealing with an otg controller + phy both if which

Quoted 6 lines
Quoted 2 lines

Using platform specific PHY functions dissolves the very purpose of creating the PHY framework. We have to find a better way.

"We have to find a better way" is not really a helpful answer to the problem at hand. We're talking about a phy integrated on the same die, as, and closely working

It's integrated in the same die but it is not within the controller IP. It's still possible to replace the PHY and have the same controller in the next SoC.

Quoted 9 lines

together with the otg controller, so we need some sort of coordination between the
two.

The 2 logical options for coordinatinon are:

1) Add generic phy framework functions for such coordination -> Which you've nacked

Quoted 8 lines
Quoted 4 lines

2) Use platform private functions for this
-> Which you are essentially nacking above.

Which leaves us with what as solution exactly ?

We could poll on the GPIO in PHY driver to update the iscr register. I think it's alright to poll on the GPIO in multiple modules for serving it's own purpose IMHO.

Quoted 6 lines

No, polling in multiple places is just plain and simple wrong, also where-ever possible we use edge triggered gpio-interrupts for this and having multiple handlers for the same interrupt is even more wrong.

I'm fine with moving all the polling to the phy driver, but then we need to have a way to notify the sunxi musb glue about id pin changes.

As I mentioned before, we can use extcon framework for it.

Quoted 4 lines
Quoted 4 lines
Quoted 3 lines

I could make the phy-sun4i-usb.c driver register a struct usb_phy, as drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

I'm not sure how will that help.

It helps when we move the polling to the phy driver as it has a notification mechanism for events which we can then use to tell the musb-sunxi glue about id pin changes.

extcon framework might help here.

Ok, I've taken a look and I see that it is already used for exactly this purpose in drivers/usb/phy/phy-tahvo.c and drivers/usb/phy/phy-omap-otg.c .

Since I take it that this is the preferred solution for dealing with this, I'll go and rework my patchset to move the polling to the phy driver and use extcon to signal the status of the id / vbus det pins to other interested parties.

Regards,

Hans

#15 lore raw

PATCH 3/15 musb: Make musb_write_rxfun* and musb_write_rxhub* work like their tx versions

In reply to Hans de Goede

For some reason the musb_write_rxfun* and musb_write_rxhub* functions had a different function prototype and some extra magic needed on the caller side compared to their tx counterparts, this commit makes them work the same as their tx counterparts.

---
 drivers/usb/musb/musb_core.c | 11 +++--------
 drivers/usb/musb/musb_core.h |  2 --
 drivers/usb/musb/musb_host.c | 12 ++++++------
 drivers/usb/musb/musb_regs.h | 31 ++++++++++++-------------------
 4 files changed, 21 insertions(+), 35 deletions(-)
drivers/usb/musb/musb_core.c +3 -8
index e6f4cbf..2c43b59 100644
@@ -1546,7 +1546,6 @@ static int musb_core_init(u16 musb_type, struct musb *musb)
 #endif
 
 		hw_ep->regs = musb->io.ep_offset(i, 0) + mbase;
-		hw_ep->target_regs = musb_read_target_reg_base(i, mbase);
 		hw_ep->rx_reinit = 1;
 		hw_ep->tx_reinit = 1;
 
@@ -2332,7 +2331,6 @@ static void musb_restore_context(struct musb *musb)
 {
 	int i;
 	void __iomem *musb_base = musb->mregs;
-	void __iomem *ep_target_regs;
 	void __iomem *epio;
 	u8 power;
 
@@ -2400,14 +2398,11 @@ static void musb_restore_context(struct musb *musb)
 		musb_write_txhubport(musb_base, i,
 				musb->context.index_regs[i].txhubport);
 
-		ep_target_regs =
-			musb_read_target_reg_base(i, musb_base);
-
-		musb_write_rxfunaddr(ep_target_regs,
+		musb_write_rxfunaddr(musb_base, i,
 				musb->context.index_regs[i].rxfunaddr);
-		musb_write_rxhubaddr(ep_target_regs,
+		musb_write_rxhubaddr(musb_base, i,
 				musb->context.index_regs[i].rxhubaddr);
-		musb_write_rxhubport(ep_target_regs,
+		musb_write_rxhubport(musb_base, i,
 				musb->context.index_regs[i].rxhubport);
 	}
 	musb_writeb(musb_base, MUSB_INDEX, musb->context.index);
drivers/usb/musb/musb_core.h +0 -2
index 5e65958..a31d709 100644
@@ -240,8 +240,6 @@ struct musb_hw_ep {
 	void __iomem		*fifo_sync_va;
 #endif
 
-	void __iomem		*target_regs;
-
 	/* currently scheduled peripheral endpoint */
 	struct musb_qh		*in_qh;
 	struct musb_qh		*out_qh;
drivers/usb/musb/musb_host.c +6 -6
index 883a9ad..77006ee 100644
@@ -555,8 +555,9 @@ musb_host_packet_rx(struct musb *musb, struct urb *urb, u8 epnum, u8 iso_err)
  * the busy/not-empty tests are basically paranoia.
  */
 static void
-musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
+musb_rx_reinit(struct musb *musb, struct musb_qh *qh, u8 epnum)
 {
+	struct musb_hw_ep *ep = musb->endpoints + epnum;
 	u16	csr;
 
 	/* NOTE:  we know the "rx" fifo reinit never triggers for ep0.
@@ -594,10 +595,9 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
 
 	/* target addr and (for multipoint) hub addr/port */
 	if (musb->is_multipoint) {
-		musb_write_rxfunaddr(ep->target_regs, qh->addr_reg);
-		musb_write_rxhubaddr(ep->target_regs, qh->h_addr_reg);
-		musb_write_rxhubport(ep->target_regs, qh->h_port_reg);
-
+		musb_write_rxfunaddr(musb->mregs, epnum, qh->addr_reg);
+		musb_write_rxhubaddr(musb->mregs, epnum, qh->h_addr_reg);
+		musb_write_rxhubport(musb->mregs, epnum, qh->h_port_reg);
 	} else
 		musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg);
 
@@ -875,7 +875,7 @@ finish:
 		u16	csr;
 
 		if (hw_ep->rx_reinit) {
-			musb_rx_reinit(musb, qh, hw_ep);
+			musb_rx_reinit(musb, qh, epnum);
 
 			/* init new state: toggle and NYET, maybe DMA later */
 			if (usb_gettoggle(urb->dev, qh->epnum, 0))
drivers/usb/musb/musb_regs.h +12 -19
index 11f0be0..edfc730 100644
@@ -364,27 +364,25 @@ static inline u16 musb_read_hwvers(void __iomem *mbase)
 	return musb_readw(mbase, MUSB_HWVERS);
 }
 
-static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
-{
-	return (MUSB_BUSCTL_OFFSET(i, 0) + mbase);
-}
-
-static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs,
+static inline void musb_write_rxfunaddr(void __iomem *mbase, u8 epnum,
 		u8 qh_addr_reg)
 {
-	musb_writeb(ep_target_regs, MUSB_RXFUNCADDR, qh_addr_reg);
+	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR),
+			qh_addr_reg);
 }
 
-static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs,
+static inline void musb_write_rxhubaddr(void __iomem *mbase, u8 epnum,
 		u8 qh_h_addr_reg)
 {
-	musb_writeb(ep_target_regs, MUSB_RXHUBADDR, qh_h_addr_reg);
+	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR),
+			qh_h_addr_reg);
 }
 
-static inline void musb_write_rxhubport(void __iomem *ep_target_regs,
+static inline void musb_write_rxhubport(void __iomem *mbase, u8 epnum,
 		u8 qh_h_port_reg)
 {
-	musb_writeb(ep_target_regs, MUSB_RXHUBPORT, qh_h_port_reg);
+	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT),
+			qh_h_port_reg);
 }
 
 static inline void  musb_write_txfunaddr(void __iomem *mbase, u8 epnum,
@@ -556,22 +554,17 @@ static inline u16 musb_read_hwvers(void __iomem *mbase)
 	return MUSB_HWVERS_1900;
 }
 
-static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
-{
-	return NULL;
-}
-
-static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs,
+static inline void musb_write_rxfunaddr(void __iomem *mbase, u8 epnum,
 		u8 qh_addr_req)
 {
 }
 
-static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs,
+static inline void musb_write_rxhubaddr(void __iomem *mbase, u8 epnum,
 		u8 qh_h_addr_reg)
 {
 }
 
-static inline void musb_write_rxhubport(void __iomem *ep_target_regs,
+static inline void musb_write_rxhubport(void __iomem *mbase, u8 epnum,
 		u8 qh_h_port_reg)
 {
 }
Signature · 1 line
2.3.1
#16 lore raw

PATCH 4/15 musb: Make busctl_offset an io-op rather then a define

In reply to Hans de Goede

The Allwinner (sunxi) implementation of the musb has its busctl registers indexed by the MUSB_INDEX register rather then in a flat address space.

This commit turns MUSB_BUSCTL_OFFSET from a macro into an io-op which can be overridden from the platform ops.

---
 drivers/usb/musb/musb_core.c | 34 +++++++++++++++---------
 drivers/usb/musb/musb_core.h |  5 +++-
 drivers/usb/musb/musb_host.c | 12 ++++-----
 drivers/usb/musb/musb_io.h   |  2 ++
 drivers/usb/musb/musb_regs.h | 63 ++++++++++++++++++++++++--------------------
 5 files changed, 68 insertions(+), 48 deletions(-)
drivers/usb/musb/musb_core.c +22 -12
index 2c43b59..b71d310 100644
@@ -250,6 +250,11 @@ static u32 musb_indexed_ep_offset(u8 epnum, u16 offset)
 	return 0x10 + offset;
 }
 
+static u32 musb_default_busctl_offset(u8 epnum, u16 offset)
+{
+	return 0x80 + (0x08 * epnum) + offset;
+}
+
 static u8 musb_default_readb(const void __iomem *addr, unsigned offset)
 {
 	return __raw_readb(addr + offset);
@@ -2039,6 +2044,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 	else
 		musb->io.fifo_offset = musb_default_fifo_offset;
 
+	if (musb->ops->busctl_offset)
+		musb->io.busctl_offset = musb->ops->busctl_offset;
+	else
+		musb->io.busctl_offset = musb_default_busctl_offset;
+
 	if (musb->ops->readb)
 		musb_readb = musb->ops->readb;
 	if (musb->ops->writeb)
@@ -2312,18 +2322,18 @@ static void musb_save_context(struct musb *musb)
 			musb_readb(epio, MUSB_RXINTERVAL);
 
 		musb->context.index_regs[i].txfunaddr =
-			musb_read_txfunaddr(musb_base, i);
+			musb_read_txfunaddr(musb, i);
 		musb->context.index_regs[i].txhubaddr =
-			musb_read_txhubaddr(musb_base, i);
+			musb_read_txhubaddr(musb, i);
 		musb->context.index_regs[i].txhubport =
-			musb_read_txhubport(musb_base, i);
+			musb_read_txhubport(musb, i);
 
 		musb->context.index_regs[i].rxfunaddr =
-			musb_read_rxfunaddr(musb_base, i);
+			musb_read_rxfunaddr(musb, i);
 		musb->context.index_regs[i].rxhubaddr =
-			musb_read_rxhubaddr(musb_base, i);
+			musb_read_rxhubaddr(musb, i);
 		musb->context.index_regs[i].rxhubport =
-			musb_read_rxhubport(musb_base, i);
+			musb_read_rxhubport(musb, i);
 	}
 }
 
@@ -2391,18 +2401,18 @@ static void musb_restore_context(struct musb *musb)
 		musb_writeb(epio, MUSB_RXINTERVAL,
 
 				musb->context.index_regs[i].rxinterval);
-		musb_write_txfunaddr(musb_base, i,
+		musb_write_txfunaddr(musb, i,
 				musb->context.index_regs[i].txfunaddr);
-		musb_write_txhubaddr(musb_base, i,
+		musb_write_txhubaddr(musb, i,
 				musb->context.index_regs[i].txhubaddr);
-		musb_write_txhubport(musb_base, i,
+		musb_write_txhubport(musb, i,
 				musb->context.index_regs[i].txhubport);
 
-		musb_write_rxfunaddr(musb_base, i,
+		musb_write_rxfunaddr(musb, i,
 				musb->context.index_regs[i].rxfunaddr);
-		musb_write_rxhubaddr(musb_base, i,
+		musb_write_rxhubaddr(musb, i,
 				musb->context.index_regs[i].rxhubaddr);
-		musb_write_rxhubport(musb_base, i,
+		musb_write_rxhubport(musb, i,
 				musb->context.index_regs[i].rxhubport);
 	}
 	musb_writeb(musb_base, MUSB_INDEX, musb->context.index);
drivers/usb/musb/musb_core.h +4 -1
index a31d709..ba8dd78 100644
@@ -67,7 +67,6 @@ struct musb_ep;
 #include "musb_dma.h"
 
 #include "musb_io.h"
-#include "musb_regs.h"
 
 #include "musb_gadget.h"
 #include <linux/usb/hcd.h>
@@ -186,6 +185,7 @@ struct musb_platform_ops {
 	void	(*ep_select)(void __iomem *mbase, u8 epnum);
 	u16	fifo_mode;
 	u32	(*fifo_offset)(u8 epnum);
+	u32	(*busctl_offset)(u8 epnum, u16 offset);
 	u8	(*readb)(const void __iomem *addr, unsigned offset);
 	void	(*writeb)(void __iomem *addr, unsigned offset, u8 data);
 	u16	(*readw)(const void __iomem *addr, unsigned offset);
@@ -435,6 +435,9 @@ struct musb {
 #endif
 };
 
+/* This must be included after struct musb is defined */
+#include "musb_regs.h"
+
 static inline struct musb *gadget_to_musb(struct usb_gadget *g)
 {
 	return container_of(g, struct musb, g);
drivers/usb/musb/musb_host.c +6 -6
index 77006ee..e2fabef 100644
@@ -595,9 +595,9 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, u8 epnum)
 
 	/* target addr and (for multipoint) hub addr/port */
 	if (musb->is_multipoint) {
-		musb_write_rxfunaddr(musb->mregs, epnum, qh->addr_reg);
-		musb_write_rxhubaddr(musb->mregs, epnum, qh->h_addr_reg);
-		musb_write_rxhubport(musb->mregs, epnum, qh->h_port_reg);
+		musb_write_rxfunaddr(musb, epnum, qh->addr_reg);
+		musb_write_rxhubaddr(musb, epnum, qh->h_addr_reg);
+		musb_write_rxhubport(musb, epnum, qh->h_port_reg);
 	} else
 		musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg);
 
@@ -801,9 +801,9 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
 
 		/* target addr and (for multipoint) hub addr/port */
 		if (musb->is_multipoint) {
-			musb_write_txfunaddr(mbase, epnum, qh->addr_reg);
-			musb_write_txhubaddr(mbase, epnum, qh->h_addr_reg);
-			musb_write_txhubport(mbase, epnum, qh->h_port_reg);
+			musb_write_txfunaddr(musb, epnum, qh->addr_reg);
+			musb_write_txhubaddr(musb, epnum, qh->h_addr_reg);
+			musb_write_txhubport(musb, epnum, qh->h_port_reg);
 /* FIXME if !epnum, do the same for RX ... */
 		} else
 			musb_writeb(mbase, MUSB_FADDR, qh->addr_reg);
drivers/usb/musb/musb_io.h +2 -0
index 8a57a6f..17a80ae 100644
@@ -47,6 +47,7 @@
  * @fifo_offset: platform specific function to get fifo offset
  * @read_fifo:	platform specific function to read fifo
  * @write_fifo:	platform specific function to write fifo
+ * @busctl_offset: platform specific function to get busctl offset
  */
 struct musb_io {
 	u32	quirks;
@@ -55,6 +56,7 @@ struct musb_io {
 	u32	(*fifo_offset)(u8 epnum);
 	void	(*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf);
 	void	(*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf);
+	u32	(*busctl_offset)(u8 epnum, u16 offset);
 };
 
 /* Do not add new entries here, add them the struct musb_io instead */
drivers/usb/musb/musb_regs.h +34 -29

119 lines not on this page · raw message

Signature · 1 line
2.3.1
#17 lore raw

PATCH 5/15 musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions

In reply to Hans de Goede

The generic fifo functions already use non wrapped accesses in various cases through the iowrite#_rep functions, and all platforms which override the default musb_read[b|w] / _write[b|w] functions also provide their own fifo access functions, so we can safely drop the unnecessary indirection from the fifo access functions.

---
 drivers/usb/musb/musb_core.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/musb/musb_core.c +4 -4
index b71d310..47c1a0a 100644
@@ -313,7 +313,7 @@ static void musb_default_write_fifo(struct musb_hw_ep *hw_ep, u16 len,
 				index += len & ~0x03;
 			}
 			if (len & 0x02) {
-				musb_writew(fifo, 0, *(u16 *)&src[index]);
+				__raw_writew(*(u16 *)&src[index], fifo);
 				index += 2;
 			}
 		} else {
@@ -323,7 +323,7 @@ static void musb_default_write_fifo(struct musb_hw_ep *hw_ep, u16 len,
 			}
 		}
 		if (len & 0x01)
-			musb_writeb(fifo, 0, src[index]);
+			__raw_writeb(src[index], fifo);
 	} else  {
 		/* byte aligned */
 		iowrite8_rep(fifo, src, len);
@@ -355,7 +355,7 @@ static void musb_default_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
 				index = len & ~0x03;
 			}
 			if (len & 0x02) {
-				*(u16 *)&dst[index] = musb_readw(fifo, 0);
+				*(u16 *)&dst[index] = __raw_readw(fifo);
 				index += 2;
 			}
 		} else {
@@ -365,7 +365,7 @@ static void musb_default_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
 			}
 		}
 		if (len & 0x01)
-			dst[index] = musb_readb(fifo, 0);
+			dst[index] = __raw_readb(fifo);
 	} else  {
 		/* byte aligned */
 		ioread8_rep(fifo, dst, len);
Signature · 1 line
2.3.1
#18 lore raw

PATCH 5/15 musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions

Quoted 8 lines · On Monday 09 March 2015 21:40:18 Hans de Goede wrote:

The generic fifo functions already use non wrapped accesses in various cases through the iowrite#_rep functions, and all platforms which override the default musb_read[b|w] / _write[b|w] functions also provide their own fifo access functions, so we can safely drop the unnecessary indirection from the fifo access functions.

The patch looks reasonably, but the description seem misleading. I believe the real reason why it's ok to use __raw_writew for the FIFO is that a FIFO by definition is using CPU endian access for copying byte streams from memory, which is unlike any other MMIO register that requires fixed-endian accessors.

Arnd

#19 lore raw

PATCH 5/15 musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions

Hi,

Quoted 7 lines · Arnd Bergmann
Quoted 6 lines · On Monday 09 March 2015 21:40:18 Hans de Goede wrote:

The generic fifo functions already use non wrapped accesses in various cases through the iowrite#_rep functions, and all platforms which override the default musb_read[b|w] / _write[b|w] functions also provide their own fifo access functions, so we can safely drop the unnecessary indirection from the fifo access functions.

Quoted 8 lines
Quoted 2 lines

The patch looks reasonably, but the description seem misleading. I believe the real reason why it's ok to use __raw_writew for the FIFO is that a FIFO by definition is using CPU endian access for copying byte streams from memory, which is unlike any other MMIO register that requires fixed-endian accessors.

I'm not sure that that is the case here, this fifo allows reading 4 bytes at a time using 32 bit word access, so endianness may come into play. This patch is safe however since all existing users of the generic fifo_read / write helpers which this patch touches, are also using the generic musb_read[b|w] / _write[b|w] functions which are just __raw_foo wrappers, so there is no functional change, which is what the commit message tries to say.

Note that sunxi needs this function because of the register address translation the sunxi_musb_readb / writeb wrappers are doing which does not know how to deal with fifo data, and besides that it should make the generic read / write fifo helpers somewhat faster by removing an indirect function call.

Regards,

Hans

#20 lore raw

PATCH 5/15 musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions

Quoted 17 lines · On Tuesday 10 March 2015 08:43:22 Hans de Goede wrote:
Quoted 7 lines · Arnd Bergmann
Quoted 6 lines · On Monday 09 March 2015 21:40:18 Hans de Goede wrote:

The generic fifo functions already use non wrapped accesses in various cases through the iowrite#_rep functions, and all platforms which override the default musb_read[b|w] / _write[b|w] functions also provide their own fifo access functions, so we can safely drop the unnecessary indirection from the fifo access functions.

Quoted 8 lines
Quoted 2 lines

The patch looks reasonably, but the description seem misleading. I believe the real reason why it's ok to use __raw_writew for the FIFO is that a FIFO by definition is using CPU endian access for copying byte streams from memory, which is unlike any other MMIO register that requires fixed-endian accessors.

Quoted 7 lines

I'm not sure that that is the case here, this fifo allows reading 4 bytes at a time using 32 bit word access, so endianness may come into play. This patch is safe however since all existing users of the generic fifo_read / write helpers which this patch touches, are also using the generic musb_read[b|w] / _write[b|w] functions which are just __raw_foo wrappers, so there is no functional change, which is what the commit message tries to say.

This probably means that the generic musb helpers are not safe to use on big-endian ARM systems (but may work on MIPS). The only one currently not using the generic helpers is blackfin, which is fixed to little endian.

Quoted 5 lines

Note that sunxi needs this function because of the register address translation the sunxi_musb_readb / writeb wrappers are doing which does not know how to deal with fifo data, and besides that it should make the generic read / write fifo helpers somewhat faster by removing an indirect function call.

Your sunxi_musb_readw/writew functions however also are endian-safe and seem to get this part right, unlike all other platforms that use the generic __raw_*() accessors. With this patch applied, it should actually work fine, and it would work on other platforms as well if we change all __raw_*() calls outside of musb_default_write_fifo() and musb_default_read_fifo() to use *_relaxed() instead.

Arnd

#21 lore raw

PATCH 5/15 musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions

Hi,

Quoted 37 lines · Arnd Bergmann
Quoted 17 lines · On Tuesday 10 March 2015 08:43:22 Hans de Goede wrote:
Quoted 7 lines · Arnd Bergmann
Quoted 6 lines · On Monday 09 March 2015 21:40:18 Hans de Goede wrote:

The generic fifo functions already use non wrapped accesses in various cases through the iowrite#_rep functions, and all platforms which override the default musb_read[b|w] / _write[b|w] functions also provide their own fifo access functions, so we can safely drop the unnecessary indirection from the fifo access functions.

Quoted 8 lines
Quoted 2 lines

The patch looks reasonably, but the description seem misleading. I believe the real reason why it's ok to use __raw_writew for the FIFO is that a FIFO by definition is using CPU endian access for copying byte streams from memory, which is unlike any other MMIO register that requires fixed-endian accessors.

Quoted 7 lines

I'm not sure that that is the case here, this fifo allows reading 4 bytes at a time using 32 bit word access, so endianness may come into play. This patch is safe however since all existing users of the generic fifo_read / write helpers which this patch touches, are also using the generic musb_read[b|w] / _write[b|w] functions which are just __raw_foo wrappers, so there is no functional change, which is what the commit message tries to say.

This probably means that the generic musb helpers are not safe to use on big-endian ARM systems (but may work on MIPS). The only one currently not using the generic helpers is blackfin, which is fixed to little endian.

Quoted 5 lines

Note that sunxi needs this function because of the register address translation the sunxi_musb_readb / writeb wrappers are doing which does not know how to deal with fifo data, and besides that it should make the generic read / write fifo helpers somewhat faster by removing an indirect function call.

Quoted 6 lines

Your sunxi_musb_readw/writew functions however also are endian-safe and seem to get this part right, unlike all other platforms that use the generic __raw_*() accessors. With this patch applied, it should actually work fine, and it would work on other platforms as well if we change all __raw_*() calls outside of musb_default_write_fifo() and musb_default_read_fifo() to use *_relaxed() instead.

I think that that change falls outside of the scope of this patchset.

I agree that it would be probably a good idea to get rid of the __raw_foo usage in musb, which is why I've used the non __raw versions in the sunxi glue, but as said I believe this falls outside of the scope of this patchset. All my preparation patches for adding sunxi support carefully do not make any functional changes, as I do not want to cause regressions on hardware which I cannot test.

Regards,

Hans

#22 lore raw

PATCH 5/15 musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions

Quoted 38 lines · On Tuesday 10 March 2015 09:56:52 Hans de Goede wrote:
Quoted 37 lines · Arnd Bergmann
Quoted 17 lines · On Tuesday 10 March 2015 08:43:22 Hans de Goede wrote:
Quoted 7 lines · Arnd Bergmann
Quoted 6 lines · On Monday 09 March 2015 21:40:18 Hans de Goede wrote:

The generic fifo functions already use non wrapped accesses in various cases through the iowrite#_rep functions, and all platforms which override the default musb_read[b|w] / _write[b|w] functions also provide their own fifo access functions, so we can safely drop the unnecessary indirection from the fifo access functions.

Quoted 8 lines
Quoted 2 lines

The patch looks reasonably, but the description seem misleading. I believe the real reason why it's ok to use __raw_writew for the FIFO is that a FIFO by definition is using CPU endian access for copying byte streams from memory, which is unlike any other MMIO register that requires fixed-endian accessors.

Quoted 7 lines

I'm not sure that that is the case here, this fifo allows reading 4 bytes at a time using 32 bit word access, so endianness may come into play. This patch is safe however since all existing users of the generic fifo_read / write helpers which this patch touches, are also using the generic musb_read[b|w] / _write[b|w] functions which are just __raw_foo wrappers, so there is no functional change, which is what the commit message tries to say.

This probably means that the generic musb helpers are not safe to use on big-endian ARM systems (but may work on MIPS). The only one currently not using the generic helpers is blackfin, which is fixed to little endian.

Quoted 5 lines

Note that sunxi needs this function because of the register address translation the sunxi_musb_readb / writeb wrappers are doing which does not know how to deal with fifo data, and besides that it should make the generic read / write fifo helpers somewhat faster by removing an indirect function call.

Quoted 8 lines
Quoted 6 lines

Your sunxi_musb_readw/writew functions however also are endian-safe and seem to get this part right, unlike all other platforms that use the generic __raw_*() accessors. With this patch applied, it should actually work fine, and it would work on other platforms as well if we change all __raw_*() calls outside of musb_default_write_fifo() and musb_default_read_fifo() to use *_relaxed() instead.

I think that that change falls outside of the scope of this patchset.

Yes, sorry for not being clear about that.

Quoted 6 lines

I agree that it would be probably a good idea to get rid of the __raw_foo usage in musb, which is why I've used the non __raw versions in the sunxi glue, but as said I believe this falls outside of the scope of this patchset. All my preparation patches for adding sunxi support carefully do not make any functional changes, as I do not want to cause regressions on hardware which I cannot test.

Right.

Arnd

#23 lore raw

PATCH 6/15 musb: Fix platform code being unable to override ep access ops

In reply to Hans de Goede

musb-core was setting the ops to the default indexed or flat handlers after checking for platform overrides. Reverse the order of this so that platform overrides actually work.

---
 drivers/usb/musb/musb_core.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/usb/musb/musb_core.c +6 -7
index 47c1a0a..374d181 100644
@@ -2019,13 +2019,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 	if (musb->ops->quirks)
 		musb->io.quirks = musb->ops->quirks;
 
-	/* At least tusb6010 has it's own offsets.. */
-	if (musb->ops->ep_offset)
-		musb->io.ep_offset = musb->ops->ep_offset;
-	if (musb->ops->ep_select)
-		musb->io.ep_select = musb->ops->ep_select;
-
-	/* ..and some devices use indexed offset or flat offset */
+	/* Set default ep access to indexed offset or flat offset ops */
 	if (musb->io.quirks & MUSB_INDEXED_EP) {
 		musb->io.ep_offset = musb_indexed_ep_offset;
 		musb->io.ep_select = musb_indexed_ep_select;
@@ -2033,6 +2027,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 		musb->io.ep_offset = musb_flat_ep_offset;
 		musb->io.ep_select = musb_flat_ep_select;
 	}
+	/* And override them with platform specific ops if specified. */
+	if (musb->ops->ep_offset)
+		musb->io.ep_offset = musb->ops->ep_offset;
+	if (musb->ops->ep_select)
+		musb->io.ep_select = musb->ops->ep_select;
 
 	if (musb->ops->fifo_mode)
 		fifo_mode = musb->ops->fifo_mode;
Signature · 1 line
2.3.1
#24 lore raw

PATCH 7/15 musb: Add support for the Allwinner sunxi musb controller

In reply to Hans de Goede

This is based on initial code to get the Allwinner sunxi musb controller supported by Chen-Yu Tsai and Roman Byshko.

This adds support for the Allwinner sunxi musb controller in both host only and otg mode. Peripheral only mode is not supported, as no boards use that.

This has been tested on a cubietruck (A20 SoC) and an UTOO P66 tablet (A13 SoC) with a variety of devices in host mode and with the g_serial gadget driver in peripheral mode, plugging otg / host cables in/out a lot of times in all possible imaginable plug orders.

---
 .../bindings/usb/allwinner,sun4i-a10-musb.txt      |  27 +
 drivers/usb/musb/Kconfig                           |   9 +-
 drivers/usb/musb/Makefile                          |   1 +
 drivers/usb/musb/musb_core.h                       |   1 +
 drivers/usb/musb/musb_gadget.c                     |   6 +
 drivers/usb/musb/musb_virthub.c                    |   6 +
 drivers/usb/musb/sunxi.c                           | 788 +++++++++++++++++++++
 7 files changed, 837 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
 create mode 100644 drivers/usb/musb/sunxi.c
Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt new file +27 -0
new file mode 100644
index 0000000..22b6887
@@ -0,0 +1,27 @@
+Allwinner sun4i A10 musb DRC/OTG controller
+-------------------------------------------
+
+Required properties:
+ - compatible      : "allwinner,sun4i-a10-musb"
+ - reg             : mmio address range of the musb controller
+ - clocks          : clock specifier for the musb controller ahb gate clock
+ - interrupts      : interrupt to which the musb controller is connected
+ - interrupt-names : must be "mc"
+ - phys            : phy specifier for the otg phy
+ - phy-names       : must be "usb"
+ - syscons         : syscon specifier
+ - dr_mode         : Dual-Role mode must be "host" or "otg"
+
+Example:
+
+	usb_otg: usb at 01c13000 {
+		compatible = "allwinner,sun4i-a10-musb";
+		reg = <0x01c13000 0x0400>;
+		clocks = <&ahb_gates 0>;
+		interrupts = <38>;
+		interrupt-names = "mc";
+		phys = <&usbphy 0>;
+		phy-names = "usb";
+		syscons = <&syscon>;
+		status = "disabled";
+	};
drivers/usb/musb/Kconfig +8 -1
index 14e1628..8180a3a 100644
@@ -5,7 +5,7 @@
 
 # (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
 config USB_MUSB_HDRC
-	tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
+	tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, AW, ...)'
 	depends on (USB || USB_GADGET)
 	help
 	  Say Y here if your system has a dual role high speed USB
@@ -20,6 +20,8 @@ config USB_MUSB_HDRC
 	  Analog Devices parts using this IP include Blackfin BF54x,
 	  BF525 and BF527.
 
+	  Allwinner SoCs using this IP include A10, A13, A20, ...
+
 	  If you do not know what this is, please say N.
 
 	  To compile this driver as a module, choose M here; the
@@ -60,6 +62,11 @@ endchoice
 
 comment "Platform Glue Layer"
 
+config USB_MUSB_SUNXI
+	tristate "Allwinner (sunxi)"
+	depends on ARCH_SUNXI
+	select GENERIC_PHY
+
 config USB_MUSB_DAVINCI
 	tristate "DaVinci"
 	depends on ARCH_DAVINCI_DMx
drivers/usb/musb/Makefile +1 -0
index ba49501..f95befe 100644
@@ -20,6 +20,7 @@ obj-$(CONFIG_USB_MUSB_DA8XX)			+= da8xx.o
 obj-$(CONFIG_USB_MUSB_BLACKFIN)			+= blackfin.o
 obj-$(CONFIG_USB_MUSB_UX500)			+= ux500.o
 obj-$(CONFIG_USB_MUSB_JZ4740)			+= jz4740.o
+obj-$(CONFIG_USB_MUSB_SUNXI)			+= sunxi.o
 
 
 obj-$(CONFIG_USB_MUSB_AM335X_CHILD)		+= musb_am335x.o
drivers/usb/musb/musb_core.h +1 -0
index ba8dd78..444b936 100644
@@ -166,6 +166,7 @@ struct musb_io;
  */
 struct musb_platform_ops {
 
+#define MUSB_SUN4I		BIT(7)
 #define MUSB_DMA_UX500		BIT(6)
 #define MUSB_DMA_CPPI41		BIT(5)
 #define MUSB_DMA_CPPI		BIT(4)
drivers/usb/musb/musb_gadget.c +6 -0
index b2d9040..7d13eb9 100644
@@ -2041,6 +2041,12 @@ void musb_g_disconnect(struct musb *musb)
 		spin_lock(&musb->lock);
 	}
 
+	/* On sunxi ep0 FADDR must be 0 when (re)entering peripheral mode */
+	if (musb->io.quirks & MUSB_SUN4I) {
+		musb_ep_select(musb->mregs, 0);
+		musb_writeb(musb->mregs, MUSB_FADDR, 0);
+	}
+
 	switch (musb->xceiv->otg->state) {
 	default:
 		dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n",
drivers/usb/musb/musb_virthub.c +6 -0
index 294e159..3c87fd7 100644
@@ -224,6 +224,12 @@ void musb_root_disconnect(struct musb *musb)
 	usb_hcd_poll_rh_status(musb->hcd);
 	musb->is_active = 0;
 
+	/* On sunxi ep0 FADDR must be 0 when (re)entering peripheral mode */
+	if (musb->io.quirks & MUSB_SUN4I) {
+		musb_ep_select(musb->mregs, 0);
+		musb_writeb(musb->mregs, MUSB_FADDR, 0);
+	}
+
 	switch (musb->xceiv->otg->state) {
 	case OTG_STATE_A_SUSPEND:
 		if (otg->host->b_hnp_enable) {
drivers/usb/musb/sunxi.c new file +788 -0

788 lines not on this page · raw message

Signature · 1 line
2.3.1
#25 lore raw

PATCH 8/15 ARM: dts: sunxi: Add syscon node for controlling SRAM mapping

In reply to Hans de Goede

From: Chen-Yu Tsai <[email protected]>

Allwinner SoCs have a system controller module that controls whether SRAM blocks are mapped to the CPU memory or specific peripherals.

[jenskuske at gmail.com: duplicate syscon node to sun4i and sun5i]
---
 arch/arm/boot/dts/sun4i-a10.dtsi | 5 +++++
 arch/arm/boot/dts/sun5i.dtsi     | 5 +++++
 arch/arm/boot/dts/sun7i-a20.dtsi | 5 +++++
 3 files changed, 15 insertions(+)
arch/arm/boot/dts/sun4i-a10.dtsi +5 -0
index c66352b..2f792b6 100644
@@ -457,6 +457,11 @@
 		#size-cells = <1>;
 		ranges;
 
+		syscon: syscon at 01c00000 {
+			compatible = "allwinner,sun4i-a10-syscon", "syscon";
+			reg = <0x01c00000 0x8>;
+		};
+
 		dma: dma-controller at 01c02000 {
 			compatible = "allwinner,sun4i-a10-dma";
 			reg = <0x01c02000 0x1000>;
arch/arm/boot/dts/sun5i.dtsi +5 -0
index 244d896..97b4eb1 100644
@@ -298,6 +298,11 @@
 		#size-cells = <1>;
 		ranges;
 
+		syscon: syscon at 01c00000 {
+			compatible = "allwinner,sun4i-a10-syscon", "syscon";
+			reg = <0x01c00000 0x8>;
+		};
+
 		dma: dma-controller at 01c02000 {
 			compatible = "allwinner,sun4i-a10-dma";
 			reg = <0x01c02000 0x1000>;
arch/arm/boot/dts/sun7i-a20.dtsi +5 -0
index 8df77f5..fb56a1d 100644
@@ -528,6 +528,11 @@
 		#size-cells = <1>;
 		ranges;
 
+		syscon: syscon at 01c00000 {
+			compatible = "allwinner,sun4i-a10-syscon", "syscon";
+			reg = <0x01c00000 0x8>;
+		};
+
 		nmi_intc: interrupt-controller at 01c00030 {
 			compatible = "allwinner,sun7i-a20-sc-nmi";
 			interrupt-controller;
Signature · 1 line
2.3.1
#26 lore raw

PATCH 9/15 ARM: dts: sun4i: Add USB Dual Role Controller

In reply to Hans de Goede

Add a node for the otg/drc usb controller to sun4i-a10.dtsi.

---
 arch/arm/boot/dts/sun4i-a10.dtsi | 12 ++++++++++++
 drivers/usb/musb/Kconfig         |  1 +
 2 files changed, 13 insertions(+)
arch/arm/boot/dts/sun4i-a10.dtsi +12 -0
index 2f792b6..e550415 100644
@@ -574,6 +574,18 @@
 			status = "disabled";
 		};
 
+		usb_otg: usb at 01c13000 {
+			compatible = "allwinner,sun4i-a10-musb";
+			reg = <0x01c13000 0x0400>;
+			clocks = <&ahb_gates 0>;
+			interrupts = <38>;
+			interrupt-names = "mc";
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			syscons = <&syscon>;
+			status = "disabled";
+		};
+
 		usbphy: phy at 01c13400 {
 			#phy-cells = <1>;
 			compatible = "allwinner,sun4i-a10-usb-phy";
drivers/usb/musb/Kconfig +1 -0
index 8180a3a..fab8e9a 100644
@@ -65,6 +65,7 @@ comment "Platform Glue Layer"
 config USB_MUSB_SUNXI
 	tristate "Allwinner (sunxi)"
 	depends on ARCH_SUNXI
+	depends on NOP_USB_XCEIV
 	select GENERIC_PHY
 
 config USB_MUSB_DAVINCI
Signature · 1 line
2.3.1
#27 lore raw

PATCH 9/15 ARM: dts: sun4i: Add USB Dual Role Controller

Hi Hans,

Quoted 13 lines · Hans de Goede

Add a node for the otg/drc usb controller to sun4i-a10.dtsi.

---
 arch/arm/boot/dts/sun4i-a10.dtsi | 12 ++++++++++++
 drivers/usb/musb/Kconfig         |  1 +
 2 files changed, 13 insertions(+)
drivers/usb/musb/Kconfig +0 -0
index 8180a3a..fab8e9a 100644

drivers/usb/musb/Kconfig comment "Platform Glue Layer" · line 68

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

Shouldn't this be in a different patch?

Thanks,

Signature · 4 lines
Julian Calaby

Email: julian.calaby at gmail.com
Profile: http://www.google.com/profiles/julian.calaby/
#28 lore raw

PATCH 9/15 ARM: dts: sun4i: Add USB Dual Role Controller

Hi,

Quoted 11 lines · Julian Calaby

Hi Hans,

Quoted 8 lines · Hans de Goede

Add a node for the otg/drc usb controller to sun4i-a10.dtsi.

---
  arch/arm/boot/dts/sun4i-a10.dtsi | 12 ++++++++++++
  drivers/usb/musb/Kconfig         |  1 +
  2 files changed, 13 insertions(+)
Quoted 11 lines

drivers/usb/musb/Kconfig comment "Platform Glue Layer" · line 68

Quoted 9 lines
drivers/usb/musb/Kconfig +1 -0
index 8180a3a..fab8e9a 100644
@@ -65,6 +65,7 @@ comment "Platform Glue Layer"
  config USB_MUSB_SUNXI
         tristate "Allwinner (sunxi)"
         depends on ARCH_SUNXI
+       depends on NOP_USB_XCEIV

Shouldn't this be in a different patch?

Yes, this was a later fixup commit which got squashed into the wrong patch, thanks for catching this.

This has been fixed in my personal tree, and will be in v2 of this set:
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-wip

Regards,

Hans

#29 lore raw

PATCH 10/15 ARM: dts: sun5i: Add USB Dual Role Controller

In reply to Hans de Goede

Add a node for the otg/drc usb controller to sun5i-a1*.dtsi.

---
 arch/arm/boot/dts/sun5i.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)
arch/arm/boot/dts/sun5i.dtsi +12 -0
index 97b4eb1..cf730d4 100644
@@ -384,6 +384,18 @@
 			status = "disabled";
 		};
 
+		usb_otg: usb at 01c13000 {
+			compatible = "allwinner,sun4i-a10-musb";
+			reg = <0x01c13000 0x0400>;
+			clocks = <&ahb_gates 0>;
+			interrupts = <38>;
+			interrupt-names = "mc";
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			syscons = <&syscon>;
+			status = "disabled";
+		};
+
 		usbphy: phy at 01c13400 {
 			#phy-cells = <1>;
 			compatible = "allwinner,sun5i-a13-usb-phy";
Signature · 1 line
2.3.1
#30 lore raw

PATCH 11/15 ARM: dts: sun7i: Add USB Dual Role Controller

In reply to Hans de Goede

From: Roman Byshko <[email protected]>

Add a node for the otg/drc usb controller to sun7i-a20.dtsi

---
 arch/arm/boot/dts/sun7i-a20.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)
arch/arm/boot/dts/sun7i-a20.dtsi +12 -0
index fb56a1d..1d0b9ac 100644
@@ -653,6 +653,18 @@
 			status = "disabled";
 		};
 
+		usb_otg: usb at 01c13000 {
+			compatible = "allwinner,sun4i-a10-musb";
+			reg = <0x01c13000 0x0400>;
+			clocks = <&ahb_gates 0>;
+			interrupts = <0 38 4>;
+			interrupt-names = "mc";
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			syscons = <&syscon>;
+			status = "disabled";
+		};
+
 		usbphy: phy at 01c13400 {
 			#phy-cells = <1>;
 			compatible = "allwinner,sun7i-a20-usb-phy";
Signature · 1 line
2.3.1
#31 lore raw

PATCH 12/15 ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825

In reply to Hans de Goede

Enable the otg/drc usb controller on the Chuwi V7 CW0825 tablet.

---
 arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 31 +++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts +31 -0
index 97fca89..034396c 100644
@@ -111,6 +111,26 @@
 	status = "okay";
 };
 
+&pio {
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PH5";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+};
+
+&reg_usb0_vbus {
+	status = "okay";
+};
+
 &reg_usb2_vbus {
 	status = "okay";
 };
@@ -121,7 +141,18 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin
+		     &usb0_vbus_detect_pin>;
+	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
+	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
 };
Signature · 1 line
2.3.1
#32 lore raw

PATCH 12/15 ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825

Hi Hans,

Quoted 39 lines · Hans de Goede

Enable the otg/drc usb controller on the Chuwi V7 CW0825 tablet.

---
 arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 31 +++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts +20 -0
index 97fca89..034396c 100644
@@ -111,6 +111,26 @@
 	status = "okay";
 };
 
+&pio {
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PH5";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+};
+
+&reg_usb0_vbus {
+	status = "okay";
+};
+
 &reg_usb2_vbus {
 	status = "okay";
 };

arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts line 150

Quoted 10 lines
arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts +7 -0
@@ -121,7 +141,18 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin
+		     &usb0_vbus_detect_pin>;
+	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	dr_mode = "otg";

Is there a reason to not put that in the DTSI?

All the users seem to be wiring it as OTG.

Thanks!
Maxime

Signature · 10 lines
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- 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/20150310/4a8c827c/attachment.sig>
#33 lore raw

PATCH 12/15 ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825

Hi,

Quoted 45 lines · Maxime Ripard

Hi Hans,

Quoted 42 lines · Hans de Goede

Enable the otg/drc usb controller on the Chuwi V7 CW0825 tablet.

---
  arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 31 +++++++++++++++++++++++++
  1 file changed, 31 insertions(+)
arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts +20 -0
index 97fca89..034396c 100644
@@ -111,6 +111,26 @@
  	status = "okay";
  };
 
+&pio {
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PH5";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+};
+
+&reg_usb0_vbus {
+	status = "okay";
+};
+
  &reg_usb2_vbus {
  	status = "okay";
  };
@@ -121,7 +141,18 @@
  	status = "okay";
  };
 
Quoted 9 lines

arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts line 150

Quoted 7 lines
arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts +7 -0
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin
+		     &usb0_vbus_detect_pin>;
+	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	dr_mode = "otg";

Is there a reason to not put that in the DTSI?

This is not in the dtsi because it is board specific.

Quoted 1 line

All the users seem to be wiring it as OTG.

Sofar I've only enabled the otg on a handful of boards, the otg on the Mele-M9 for example is connected to a usb->sata bridge and as such should be brought up in host only mode.

And on the wobo-i5 (which I still need to create a dts file for) the otg is connected to an usb wifi module.

Regards,

Hans

#34 lore raw

PATCH 12/15 ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825

Quoted 60 lines · Hans de Goede

Hi,

Quoted 45 lines · Maxime Ripard

Hi Hans,

Quoted 42 lines · Hans de Goede

Enable the otg/drc usb controller on the Chuwi V7 CW0825 tablet.

---
 arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 31 +++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts +20 -0
index 97fca89..034396c 100644
@@ -111,6 +111,26 @@
 	status = "okay";
 };
 
+&pio {
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PH5";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+};
+
+&reg_usb0_vbus {
+	status = "okay";
+};
+
 &reg_usb2_vbus {
 	status = "okay";
 };
@@ -121,7 +141,18 @@
 	status = "okay";
 };
 
Quoted 9 lines

arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts line 150

Quoted 7 lines
arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts +7 -0
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin
+		     &usb0_vbus_detect_pin>;
+	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	dr_mode = "otg";

Is there a reason to not put that in the DTSI?

This is not in the dtsi because it is board specific.

Quoted 8 lines
Quoted 1 line

All the users seem to be wiring it as OTG.

Sofar I've only enabled the otg on a handful of boards, the otg on the Mele-M9 for example is connected to a usb->sata bridge and as such should be brought up in host only mode.

And on the wobo-i5 (which I still need to create a dts file for) the otg is connected to an usb wifi module.

Ok, that seems like a good reason :)

Maxime

Signature · 10 lines
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- 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/20150310/3b9a10ef/attachment.sig>
#35 lore raw

PATCH 13/15 ARM: dts: sun5i: Enable USB DRC on UTOO P66

In reply to Hans de Goede

Enable the OTG controller on the UTOO P66 tablet.

---
 arch/arm/boot/dts/sun5i-a13-utoo-p66.dts | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
arch/arm/boot/dts/sun5i-a13-utoo-p66.dts +23 -0
index d1d4d30..8b44874 100644
@@ -160,6 +160,20 @@
 		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
 	};
 
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PG1";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PG2";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
 	i2c_lcd_pins: i2c_lcd_pin at 0 {
 		allwinner,pins = "PG10", "PG12";
 		allwinner,function = "gpio_out";
@@ -218,6 +232,15 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+	id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+	vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
 	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb1_vbus-supply = <&reg_ldo3>;
Signature · 1 line
2.3.1
#36 lore raw

PATCH 14/15 ARM: dts: sun7i: Enable USB DRC on Cubietruck

In reply to Hans de Goede

From: Roman Byshko <[email protected]>

Enable the otg/drc usb controller on the cubietruck.

---
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
arch/arm/boot/dts/sun7i-a20-cubietruck.dts +24 -0
index 8111b0c..ac8ff33 100644
@@ -227,6 +227,20 @@
 		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH19";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PH22";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
 };
 
 &pwm {
@@ -288,6 +302,16 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin
+		    &usb0_vbus_detect_pin>;
+	dr_mode = "otg";
+	id_det-gpios = <&pio 7 19 GPIO_ACTIVE_HIGH>; /* PH19 */
+	vbus_det-gpios = <&pio 7 22 GPIO_ACTIVE_HIGH>; /* PH22 */
+	status = "okay";
+};
+
 &usbphy {
 	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb1_vbus-supply = <&reg_usb1_vbus>;
Signature · 1 line
2.3.1
#37 lore raw

PATCH 15/15 ARM: dts: sun7i: Enable USB DRC on A20-OLinuxIno-Lime

In reply to Hans de Goede

Enable the otg/drc usb controller on the A20-OLinuxIno-Lime.

---
 arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts | 29 ++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts +29 -0
index 68efd2f..b3fda82 100644
@@ -146,6 +146,20 @@
 		allwinner,drive = <SUN4I_PINCTRL_20_MA>;
 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PH5";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
 };
 
 &reg_ahci_5v {
@@ -154,6 +168,10 @@
 	status = "okay";
 };
 
+&reg_usb0_vbus {
+	status = "okay";
+};
+
 &reg_usb1_vbus {
 	status = "okay";
 };
@@ -168,7 +186,18 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin
+		     &usb0_vbus_detect_pin>;
+	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
+	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb1_vbus-supply = <&reg_usb1_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
Signature · 1 line
2.3.1
#38 lore raw

cover musb: Add support for the Allwinner sunxi musb controller

In reply to Hans de Goede
Quoted 4 lines · On Monday 09 March 2015 21:40:13 Hans de Goede wrote:

Hi All,

This patch set has been a while in the making, so I'm very happy to present the end result here, and I hope everyone likes it.

Awesome work!

Quoted 27 lines

Before talking about merging this there are 2 things which I would like to point out:

a) The musb controller in the sunxi SoCs uses some SRAM which needs to be mapped to the musb controller by poking some bits in the SRAM controller, just like the EMAC patches which were send a while back I've chosen to use syscon for this, actually 2 of the patches in this set come directly from the SRAM mapping patchset for the EMAC.

I know that Maxime is not 100% in favor of using syscon:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html

But I disagree with his arguments for writing a special driver for the SRAM controller:
1) syscon was specifically designed for global system control registers like this and is fine to use as long as there are no conflicts where 1 bit is of interest to multiple drivers, and there is no such conflict here
2) Maxime's other arguments seem to boil down to it would be nice / prettier to have a specific driver for this, without really proving a hard need for such a driver. But writing such a driver is going to be a lot of work, and we've a ton of other work to do, and as said there is no real need for a separate driver, syscon works fine for this.
3) I actually believe that having a specific driver for this is a bad idea, because that means inventing a whole new cross driver API for this, and getting those right is, hard, a lot of work, and even then one is still likely to get it wrong. We can avoid all this by going with the proven syscon solution.

Quoted 2 lines

Maxime, can we please have your ack for moving forward with this using syscon? (see above for my arguments why)

I'd like to understand here why we can't use the existing SRAM DT binding instead of the syscon binding.

Arnd

#39 lore raw

cover musb: Add support for the Allwinner sunxi musb controller

Hi Arnd,

Quoted 35 lines · Arnd Bergmann
Quoted 4 lines · On Monday 09 March 2015 21:40:13 Hans de Goede wrote:

Hi All,

This patch set has been a while in the making, so I'm very happy to present the end result here, and I hope everyone likes it.

Awesome work!

Quoted 27 lines

Before talking about merging this there are 2 things which I would like to point out:

a) The musb controller in the sunxi SoCs uses some SRAM which needs to be mapped to the musb controller by poking some bits in the SRAM controller, just like the EMAC patches which were send a while back I've chosen to use syscon for this, actually 2 of the patches in this set come directly from the SRAM mapping patchset for the EMAC.

I know that Maxime is not 100% in favor of using syscon:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html

But I disagree with his arguments for writing a special driver for the SRAM controller:
1) syscon was specifically designed for global system control registers like this and is fine to use as long as there are no conflicts where 1 bit is of interest to multiple drivers, and there is no such conflict here
2) Maxime's other arguments seem to boil down to it would be nice / prettier to have a specific driver for this, without really proving a hard need for such a driver. But writing such a driver is going to be a lot of work, and we've a ton of other work to do, and as said there is no real need for a separate driver, syscon works fine for this.
3) I actually believe that having a specific driver for this is a bad idea, because that means inventing a whole new cross driver API for this, and getting those right is, hard, a lot of work, and even then one is still likely to get it wrong. We can avoid all this by going with the proven syscon solution.

Quoted 5 lines
Quoted 2 lines

Maxime, can we please have your ack for moving forward with this using syscon? (see above for my arguments why)

I'd like to understand here why we can't use the existing SRAM DT binding instead of the syscon binding.

I believe you are talking about "mmio-sram"?

The syscon here represents a switch, to toggle whether a block of SRAM is mapped into the CPU memory space, or to a specific devices private address space. It is not the actual SRAM.

The SRAM DT binding is orthogonal to this, if not irrelevant when the block is mapped privately, as it is no longer visible from the DT's PoV.

Coincidentally, on the A23 this is no longer needed. The SRAM for the FIFO is wholly owned by MUSB and not available to the CPU.

ChenYu

#40 lore raw

cover musb: Add support for the Allwinner sunxi musb controller

Hi,

Quoted 50 lines · Chen-Yu Tsai

Hi Arnd,

Quoted 35 lines · Arnd Bergmann
Quoted 4 lines · On Monday 09 March 2015 21:40:13 Hans de Goede wrote:

Hi All,

This patch set has been a while in the making, so I'm very happy to present the end result here, and I hope everyone likes it.

Awesome work!

Quoted 27 lines

Before talking about merging this there are 2 things which I would like to point out:

a) The musb controller in the sunxi SoCs uses some SRAM which needs to be mapped to the musb controller by poking some bits in the SRAM controller, just like the EMAC patches which were send a while back I've chosen to use syscon for this, actually 2 of the patches in this set come directly from the SRAM mapping patchset for the EMAC.

I know that Maxime is not 100% in favor of using syscon:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html

But I disagree with his arguments for writing a special driver for the SRAM controller:
1) syscon was specifically designed for global system control registers like this and is fine to use as long as there are no conflicts where 1 bit is of interest to multiple drivers, and there is no such conflict here
2) Maxime's other arguments seem to boil down to it would be nice / prettier to have a specific driver for this, without really proving a hard need for such a driver. But writing such a driver is going to be a lot of work, and we've a ton of other work to do, and as said there is no real need for a separate driver, syscon works fine for this.
3) I actually believe that having a specific driver for this is a bad idea, because that means inventing a whole new cross driver API for this, and getting those right is, hard, a lot of work, and even then one is still likely to get it wrong. We can avoid all this by going with the proven syscon solution.

Quoted 5 lines
Quoted 2 lines

Maxime, can we please have your ack for moving forward with this using syscon? (see above for my arguments why)

I'd like to understand here why we can't use the existing SRAM DT binding instead of the syscon binding.

I believe you are talking about "mmio-sram"?

The syscon here represents a switch, to toggle whether a block of SRAM is mapped into the CPU memory space, or to a specific devices private address space. It is not the actual SRAM.

Quoted 5 lines

The SRAM DT binding is orthogonal to this, if not irrelevant when the block is mapped privately, as it is no longer visible from the DT's PoV.

Coincidentally, on the A23 this is no longer needed. The SRAM for the FIFO is wholly owned by MUSB and not available to the CPU.

What ChenYu said :)

Regards,

Hans

#41 lore raw

cover musb: Add support for the Allwinner sunxi musb controller

In reply to Chen-Yu Tsai
Quoted 1 line · On Tuesday 10 March 2015 09:46:24 Chen-Yu Tsai wrote:

I believe you are talking about "mmio-sram"?

Yes.

Quoted 6 lines

The syscon here represents a switch, to toggle whether a block of SRAM is mapped into the CPU memory space, or to a specific devices private address space. It is not the actual SRAM.

The SRAM DT binding is orthogonal to this, if not irrelevant when the block is mapped privately, as it is no longer visible from the DT's PoV.

Ok, got it. I missed this part when reading the introduction. syscon seems fine to me then.

Arnd

#42 lore raw

cover musb: Add support for the Allwinner sunxi musb controller

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

Hi All,

This patch set has been a while in the making, so I'm very happy to present the end result here, and I hope everyone likes it.

Before talking about merging this there are 2 things which I would like to point out:

a) The musb controller in the sunxi SoCs uses some SRAM which needs to be mapped to the musb controller by poking some bits in the SRAM controller, just like the EMAC patches which were send a while back I've chosen to use syscon for this, actually 2 of the patches in this set come directly from the SRAM mapping patchset for the EMAC.

Quoted 5 lines

I know that Maxime is not 100% in favor of using syscon:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html

But I disagree with his arguments for writing a special driver for the SRAM controller:

And I disagree with your disagreement :)

Quoted 3 lines

1) syscon was specifically designed for global system control registers like this and is fine to use as long as there are no conflicts where 1 bit is of interest to multiple drivers, and there is no such conflict here

No. Syscon has been designed for being lazy.

This is a huge abstraction non-sense. You have to put all the logic of dealing with some external register layout in clients drivers, including dealing with the different revisions/SoC that are different from that aspect, and duplicating that code across all client drivers.

Quoted 5 lines

2) Maxime's other arguments seem to boil down to it would be nice / prettier to have a specific driver for this, without really proving a hard need for such a driver. But writing such a driver is going to be a lot of work, and we've a ton of other work to do, and as said there is no real need for a separate driver, syscon works fine for this.

Actually, I already wrote some prototype for this. I'll clean this up and send it tonight/tomorrow.

Quoted 4 lines

3) I actually believe that having a specific driver for this is a bad idea, because that means inventing a whole new cross driver API for this, and getting those right is, hard, a lot of work, and even then one is still likely to get it wrong. We can avoid all this by going with the proven syscon solution.

Except that modifying an in-kernel API, especially when we have two users, is easy. Moving back from syscon is not.

Quoted 2 lines

Maxime, can we please have your ack for moving forward with this using syscon? (see above for my arguments why)

If you can address my objections above, sure.

Thanks for your awesome work on this,
Maxime

Signature · 10 lines
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- 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/20150310/4f70d506/attachment-0001.sig>
#43 lore raw

cover musb: Add support for the Allwinner sunxi musb controller

Hi,

Quoted 34 lines · Maxime Ripard
Quoted 14 lines · Hans de Goede

Hi All,

This patch set has been a while in the making, so I'm very happy to present the end result here, and I hope everyone likes it.

Before talking about merging this there are 2 things which I would like to point out:

a) The musb controller in the sunxi SoCs uses some SRAM which needs to be mapped to the musb controller by poking some bits in the SRAM controller, just like the EMAC patches which were send a while back I've chosen to use syscon for this, actually 2 of the patches in this set come directly from the SRAM mapping patchset for the EMAC.

Quoted 5 lines

I know that Maxime is not 100% in favor of using syscon:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html

But I disagree with his arguments for writing a special driver for the SRAM controller:

And I disagree with your disagreement :)

Quoted 3 lines

1) syscon was specifically designed for global system control registers like this and is fine to use as long as there are no conflicts where 1 bit is of interest to multiple drivers, and there is no such conflict here

No. Syscon has been designed for being lazy.

This is a huge abstraction non-sense. You have to put all the logic of dealing with some external register layout in clients drivers, including dealing with the different revisions/SoC that are different from that aspect, and duplicating that code across all client drivers.

Quoted 8 lines
Quoted 5 lines

2) Maxime's other arguments seem to boil down to it would be nice / prettier to have a specific driver for this, without really proving a hard need for such a driver. But writing such a driver is going to be a lot of work, and we've a ton of other work to do, and as said there is no real need for a separate driver, syscon works fine for this.

Actually, I already wrote some prototype for this. I'll clean this up and send it tonight/tomorrow.

Ok, lets see your prototype and then we'll go from there.

Regards,

Hans