musb: Add support for the Allwinner sunxi musb controller
Subsystems (6)
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
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
@@ -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
PATCH 2/15 phy-sun4i-usb: Add a helper function to update the iscr register
In reply to Hans de GoedeAdd 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
@@ -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
@@ -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
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
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
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_exitcode 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_iscrapproach 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 musbset_vbuscallback 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); intphy_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_iscrfunction, and instead add these 2:void
sun4i_usb_phy_set_id_detect(struct phy *phy, bool val); voidsun4i_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
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_exitcode 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_iscrapproach 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 musbset_vbuscallback 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); intphy_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_iscrfunction, and instead add these 2:
Quoted 8 lines
Quoted 2 lines
void
sun4i_usb_phy_set_id_detect(struct phy *phy, bool val); voidsun4i_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
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_exitcode 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 minimalsun4i_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 musbset_vbuscallback 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 structusb_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); intphy_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
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_exitcode 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.cin 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_irqinterrupt 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 minimalsun4i_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 musbset_vbuscallback 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 structusb_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); intphy_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
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_exitcode 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.cin 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){
structsunxi_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_irqinterrupt 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_irqhandler 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){
structsunxi_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 minimalsun4i_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 musbset_vbuscallback 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 structusb_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); intphy_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
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_exitcode 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.cin 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){
structsunxi_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_irqinterrupt 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_irqhandler 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){
structsunxi_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 minimalsun4i_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 musbset_vbuscallback 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 structusb_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); intphy_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
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_exitcode 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.cin 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){
structsunxi_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_irqinterrupt 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_irqhandler 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){
structsunxi_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 minimalsun4i_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 musbset_vbuscallback 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 structusb_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); intphy_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.cdriver register a structusb_phy, asdrivers/phy/phy-omap-usb2.canddrivers/phy/phy-twl4030-usb.cdoes,
I'm not sure how will that help.
Cheers
Kishon
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_exitcode 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.cin 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){
structsunxi_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_irqinterrupt 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_irqhandler 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){
structsunxi_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 minimalsun4i_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 musbset_vbuscallback 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 structusb_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); intphy_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 whichQuoted 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.cdriver register a structusb_phy, asdrivers/phy/phy-omap-usb2.canddrivers/phy/phy-twl4030-usb.cdoes,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
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_exitcode 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.cin 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){
structsunxi_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_irqhandler 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){
structsunxi_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 minimalsun4i_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 musbset_vbuscallback 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 structusb_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); intphy_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 whichQuoted 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.cdriver register a structusb_phy, asdrivers/phy/phy-omap-usb2.canddrivers/phy/phy-twl4030-usb.cdoes,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
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_exitcode 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.cin 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){
structsunxi_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_irqhandler 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){
structsunxi_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 minimalsun4i_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 musbset_vbuscallback 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 structusb_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); intphy_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 whichQuoted 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.cdriver register a structusb_phy, asdrivers/phy/phy-omap-usb2.canddrivers/phy/phy-twl4030-usb.cdoes,
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
PATCH 3/15 musb: Make musb_write_rxfun* and musb_write_rxhub* work like their tx versions
In reply to Hans de GoedeFor 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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 4/15 musb: Make busctl_offset an io-op rather then a define
In reply to Hans de GoedeThe 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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 5/15 musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
In reply to Hans de GoedeThe 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
@@ -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
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.
Signed-off-by Hans de Goede <[email protected]>
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
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
Signed-off-by Hans de Goede <[email protected]>The patch looks reasonably, but the description seem misleading. I believe the real reason why it's ok to use
__raw_writewfor 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
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
Signed-off-by Hans de Goede <[email protected]>The patch looks reasonably, but the description seem misleading. I believe the real reason why it's ok to use
__raw_writewfor 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_foowrappers, 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
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
Signed-off-by Hans de Goede <[email protected]>The patch looks reasonably, but the description seem misleading. I believe the real reason why it's ok to use
__raw_writewfor 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_foowrappers, 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()andmusb_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
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
Signed-off-by Hans de Goede <[email protected]>The patch looks reasonably, but the description seem misleading. I believe the real reason why it's ok to use
__raw_writewfor 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_foowrappers, 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()andmusb_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_foousage in musb, which is why I've used the non__rawversions 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
PATCH 6/15 musb: Fix platform code being unable to override ep access ops
In reply to Hans de Goedemusb-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
@@ -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
PATCH 7/15 musb: Add support for the Allwinner sunxi musb controller
In reply to Hans de GoedeThis 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 8/15 ARM: dts: sunxi: Add syscon node for controlling SRAM mapping
In reply to Hans de GoedeFrom: 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.
--- 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
@@ -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
@@ -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
@@ -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
PATCH 9/15 ARM: dts: sun4i: Add USB Dual Role Controller
In reply to Hans de GoedeAdd 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
@@ -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
@@ -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
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.Signed-off-by Hans de Goede <[email protected]>--- arch/arm/boot/dts/sun4i-a10.dtsi | 12 ++++++++++++ drivers/usb/musb/Kconfig | 1 + 2 files changed, 13 insertions(+)drivers/usb/musb/Kconfig +0
-0
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/
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.Signed-off-by Hans de Goede <[email protected]>--- 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@@ -65,6 +65,7 @@ comment "Platform Glue Layer" config USB_MUSB_SUNXI tristate "Allwinner (sunxi)" depends on ARCH_SUNXI + depends on NOP_USB_XCEIVShouldn'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
PATCH 10/15 ARM: dts: sun5i: Add USB Dual Role Controller
In reply to Hans de GoedeAdd 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
@@ -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
PATCH 11/15 ARM: dts: sun7i: Add USB Dual Role Controller
In reply to Hans de GoedeFrom: 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
@@ -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
PATCH 12/15 ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825
In reply to Hans de GoedeEnable 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
@@ -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>; + }; +}; + +®_usb0_vbus { + status = "okay"; +}; + ®_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 = <®_usb0_vbus>; usb2_vbus-supply = <®_usb2_vbus>; status = "okay"; };
Signature · 1 line
2.3.1
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.
Signed-off-by Hans de Goede <[email protected]>--- 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@@ -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>; + }; +}; + +®_usb0_vbus { + status = "okay"; +}; + ®_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>
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.
Signed-off-by Hans de Goede <[email protected]>--- 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@@ -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>; + }; +}; + +®_usb0_vbus { + status = "okay"; +}; + ®_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
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.
Signed-off-by Hans de Goede <[email protected]>--- 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@@ -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>; + }; +}; + +®_usb0_vbus { + status = "okay"; +}; + ®_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->satabridge 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>
PATCH 13/15 ARM: dts: sun5i: Enable USB DRC on UTOO P66
In reply to Hans de GoedeEnable 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
@@ -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 = <®_usb0_vbus>; usb1_vbus-supply = <®_ldo3>;
Signature · 1 line
2.3.1
PATCH 14/15 ARM: dts: sun7i: Enable USB DRC on Cubietruck
In reply to Hans de GoedeFrom: 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
@@ -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 = <®_usb0_vbus>; usb1_vbus-supply = <®_usb1_vbus>;
Signature · 1 line
2.3.1
PATCH 15/15 ARM: dts: sun7i: Enable USB DRC on A20-OLinuxIno-Lime
In reply to Hans de GoedeEnable 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
@@ -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>; + }; }; ®_ahci_5v {
@@ -154,6 +168,10 @@ status = "okay"; }; +®_usb0_vbus { + status = "okay"; +}; + ®_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 = <®_usb0_vbus>; usb1_vbus-supply = <®_usb1_vbus>; usb2_vbus-supply = <®_usb2_vbus>; status = "okay";
Signature · 1 line
2.3.1
cover musb: Add support for the Allwinner sunxi musb controller
In reply to Hans de GoedeQuoted 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.htmlBut 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
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.htmlBut 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
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.htmlBut 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
cover musb: Add support for the Allwinner sunxi musb controller
In reply to Chen-Yu TsaiQuoted 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
cover musb: Add support for the Allwinner sunxi musb controller
In reply to Hans de GoedeQuoted 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.htmlBut 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>
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.htmlBut 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