sunxi: clock: Fix EHCI and OHCI clocks on A64
Subsystems (5)
PATCH v2 1/4 sunxi: clock: Fix EHCI and OHCI clocks on A64
EHCI0 is bit 24, EHCI1 - 25, OHCI0 - 28, OHCI1 - 29
Fixes commit fef73766d9ad ("sunxi: clock: Fix OHCI clock gating for H3/H5")
--- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/arm/include/asm/arch-sunxi/clock_sun6i.h +4 -2
@@ -280,8 +280,10 @@ struct sunxi_ccm_reg {#define AHB_GATE_OFFSET_USB_EHCI1 26#define AHB_GATE_OFFSET_USB_EHCI0 24#elif defined(CONFIG_MACH_SUN50I ) -#define AHB_GATE_OFFSET_USB_OHCI0 29 -#define AHB_GATE_OFFSET_USB_EHCI0 25 +#define AHB_GATE_OFFSET_USB_OHCI0 28 +#define AHB_GATE_OFFSET_USB_OHCI1 29 +#define AHB_GATE_OFFSET_USB_EHCI0 24 +#define AHB_GATE_OFFSET_USB_EHCI1 25#else #define AHB_GATE_OFFSET_USB_OHCI1 30#define AHB_GATE_OFFSET_USB_OHCI0 29
Signature · 1 line
2.17.1
PATCH v2 2/4 usb: sunxi: ehci: get rid of ifdefs
We can use compatibles instead.
--- drivers/usb/host/ehci-sunxi.c | 89 +++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 20 deletions(-)
drivers/usb/host/ehci-sunxi.c +69 -20
@@ -22,11 +22,24 @@#define AHB_CLK_DIST 1#endif +enum ehci_sunxi_type { + sun4i_a10_ehci, + sun5i_a13_ehci, + sun6i_a31_ehci, + sun7i_a20_ehci, + sun8i_a23_ehci, + sun8i_a83t_ehci, + sun8i_h3_ehci, + sun9i_a80_ehci, + sun50i_a64_ehci, +}; +struct ehci_sunxi_priv {struct ehci_ctrl ehci;struct sunxi_ccm_reg *ccm;int ahb_gate_mask;/* Mask of ahb_gate0 clk gate bits for this hcd */ struct phy phy; +enum ehci_sunxi_type type; };static int ehci_usb_probe (struct udevice *dev)
@@ -38,6 +51,7 @@ static int ehci_usb_probe(struct udevice *dev)int extra_ahb_gate_mask =0 ;int phys, ret; + priv->type = (enum ehci_sunxi_type )dev_get_driver_data (dev); priv->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE ;if (IS_ERR (priv->ccm))return PTR_ERR (priv->ccm);
@@ -72,18 +86,22 @@ no_phy:* clocks resp. phys. */ priv->ahb_gate_mask =1 <<AHB_GATE_OFFSET_USB_EHCI0 ; -#if defined(CONFIG_MACH_SUNXI_H3_H5 ) || defined(CONFIG_MACH_SUN50I ) - extra_ahb_gate_mask =1 <<AHB_GATE_OFFSET_USB_OHCI0 ; -#endif +if (priv->type == sun8i_h3_ehci || + priv->type == sun50i_a64_ehci) + extra_ahb_gate_mask =1 <<AHB_GATE_OFFSET_USB_OHCI0 ; priv->ahb_gate_mask <<= phys *AHB_CLK_DIST ; extra_ahb_gate_mask <<= phys *AHB_CLK_DIST ;setbits_le32 (&priv->ccm->ahb_gate0, priv->ahb_gate_mask | extra_ahb_gate_mask); -#ifdef CONFIG_SUNXI_GEN_SUN6I -setbits_le32 (&priv->ccm->ahb_reset0_cfg, - priv->ahb_gate_mask | extra_ahb_gate_mask); -#endif +if (priv->type == sun6i_a31_ehci || + priv->type == sun8i_a23_ehci || + priv->type == sun8i_a83t_ehci || + priv->type == sun8i_h3_ehci || + priv->type == sun9i_a80_ehci || + priv->type == sun50i_a64_ehci) +setbits_le32 (&priv->ccm->ahb_reset0_cfg, + priv->ahb_gate_mask | extra_ahb_gate_mask); hcor = (struct ehci_hcor *)((uintptr_t )hccr +HC_LENGTH (ehci_readl (&hccr->cr_capbase)));
@@ -108,25 +126,56 @@ static int ehci_usb_remove(struct udevice *dev)if (ret)return ret; -#ifdef CONFIG_SUNXI_GEN_SUN6I -clrbits_le32 (&priv->ccm->ahb_reset0_cfg, priv->ahb_gate_mask); -#endif +if (priv->type == sun6i_a31_ehci || + priv->type == sun8i_a23_ehci || + priv->type == sun8i_a83t_ehci || + priv->type == sun8i_h3_ehci || + priv->type == sun9i_a80_ehci || + priv->type == sun50i_a64_ehci) +clrbits_le32 (&priv->ccm->ahb_reset0_cfg, priv->ahb_gate_mask);clrbits_le32 (&priv->ccm->ahb_gate0, priv->ahb_gate_mask);return 0 ; }static const struct udevice_id ehci_usb_ids[] = { - { .compatible ="allwinner,sun4i-a10-ehci" , }, - { .compatible ="allwinner,sun5i-a13-ehci" , }, - { .compatible ="allwinner,sun6i-a31-ehci" , }, - { .compatible ="allwinner,sun7i-a20-ehci" , }, - { .compatible ="allwinner,sun8i-a23-ehci" , }, - { .compatible ="allwinner,sun8i-a83t-ehci" , }, - { .compatible ="allwinner,sun8i-h3-ehci" , }, - { .compatible ="allwinner,sun9i-a80-ehci" , }, - { .compatible ="allwinner,sun50i-a64-ehci" , }, - { } + { + .compatible ="allwinner,sun4i-a10-ehci" , + .data = (ulong )sun4i_a10_ehci, + }, + { + .compatible ="allwinner,sun5i-a13-ehci" , + .data = (ulong )sun5i_a13_ehci, + }, + { + .compatible ="allwinner,sun6i-a31-ehci" , + .data = (ulong )sun6i_a31_ehci, + }, + { + .compatible ="allwinner,sun7i-a20-ehci" , + .data = (ulong )sun7i_a20_ehci, + }, + { + .compatible ="allwinner,sun8i-a23-ehci" , + .data = (ulong )sun8i_a23_ehci, + }, + { + .compatible ="allwinner,sun8i-a83t-ehci" , + .data = (ulong )sun8i_a83t_ehci, + }, + { + .compatible ="allwinner,sun8i-h3-ehci" , + .data = (ulong )sun8i_h3_ehci, + }, + { + .compatible ="allwinner,sun9i-a80-ehci" , + .data = (ulong )sun9i_a80_ehci, + }, + { + .compatible ="allwinner,sun50i-a64-ehci" , + .data = (ulong )sun50i_a64_ehci, + }, + {/* sentinel */ } };U_BOOT_DRIVER (ehci_sunxi) = {
Signature · 1 line
2.17.1
PATCH v2 3/4 usb: sunxi: ohci: get rid of ifdefs
In reply to Vasily KhoruzhickWe can use compatibles instead.
--- drivers/usb/host/ohci-sunxi.c | 88 +++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 20 deletions(-)
drivers/usb/host/ohci-sunxi.c +68 -20
@@ -22,12 +22,25 @@#define AHB_CLK_DIST 1#endif +enum ohci_sunxi_type { + sun4i_a10_ohci, + sun5i_a13_ohci, + sun6i_a31_ohci, + sun7i_a20_ohci, + sun8i_a23_ohci, + sun8i_a83t_ohci, + sun8i_h3_ohci, + sun9i_a80_ohci, + sun50i_a64_ohci, +}; +struct ohci_sunxi_priv {struct sunxi_ccm_reg *ccm;ohci_t ohci;int ahb_gate_mask;/* Mask of ahb_gate0 clk gate bits for this hcd */ int usb_gate_mask;/* Mask of usb_clk_cfg clk gate bits for this hcd */ struct phy phy; +enum ohci_sunxi_type type; };static int ohci_usb_probe (struct udevice *dev)
@@ -38,6 +51,7 @@ static int ohci_usb_probe(struct udevice *dev)int extra_ahb_gate_mask =0 ;int phys, ret; + priv->type = (enum ohci_sunxi_type )dev_get_driver_data (dev); priv->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE ;if (IS_ERR (priv->ccm))return PTR_ERR (priv->ccm);
@@ -74,9 +88,8 @@ no_phy:* clocks resp. phys. */ priv->ahb_gate_mask =1 <<AHB_GATE_OFFSET_USB_OHCI0 ; -#ifdef CONFIG_MACH_SUN8I_H3 - extra_ahb_gate_mask =1 <<AHB_GATE_OFFSET_USB_EHCI0 ; -#endif +if (priv->type == sun8i_h3_ohci) + extra_ahb_gate_mask =1 <<AHB_GATE_OFFSET_USB_EHCI0 ; priv->usb_gate_mask =CCM_USB_CTRL_OHCI0_CLK ; priv->ahb_gate_mask <<= phys *AHB_CLK_DIST ; extra_ahb_gate_mask <<= phys *AHB_CLK_DIST ;
@@ -85,10 +98,14 @@ no_phy:setbits_le32 (&priv->ccm->ahb_gate0, priv->ahb_gate_mask | extra_ahb_gate_mask);setbits_le32 (&priv->ccm->usb_clk_cfg, priv->usb_gate_mask); -#ifdef CONFIG_SUNXI_GEN_SUN6I -setbits_le32 (&priv->ccm->ahb_reset0_cfg, - priv->ahb_gate_mask | extra_ahb_gate_mask); -#endif +if (priv->type == sun6i_a31_ohci || + priv->type == sun8i_a23_ohci || + priv->type == sun8i_a83t_ohci || + priv->type == sun8i_h3_ohci || + priv->type == sun9i_a80_ohci || + priv->type == sun50i_a64_ohci) +setbits_le32 (&priv->ccm->ahb_reset0_cfg, + priv->ahb_gate_mask | extra_ahb_gate_mask);return ohci_register (dev, regs); }
@@ -110,9 +127,13 @@ static int ohci_usb_remove(struct udevice *dev)if (ret)return ret; -#ifdef CONFIG_SUNXI_GEN_SUN6I -clrbits_le32 (&priv->ccm->ahb_reset0_cfg, priv->ahb_gate_mask); -#endif +if (priv->type == sun6i_a31_ohci || + priv->type == sun8i_a23_ohci || + priv->type == sun8i_a83t_ohci || + priv->type == sun8i_h3_ohci || + priv->type == sun9i_a80_ohci || + priv->type == sun50i_a64_ohci) +clrbits_le32 (&priv->ccm->ahb_reset0_cfg, priv->ahb_gate_mask);clrbits_le32 (&priv->ccm->usb_clk_cfg, priv->usb_gate_mask);clrbits_le32 (&priv->ccm->ahb_gate0, priv->ahb_gate_mask);
@@ -120,16 +141,43 @@ static int ohci_usb_remove(struct udevice *dev) }static const struct udevice_id ohci_usb_ids[] = { - { .compatible ="allwinner,sun4i-a10-ohci" , }, - { .compatible ="allwinner,sun5i-a13-ohci" , }, - { .compatible ="allwinner,sun6i-a31-ohci" , }, - { .compatible ="allwinner,sun7i-a20-ohci" , }, - { .compatible ="allwinner,sun8i-a23-ohci" , }, - { .compatible ="allwinner,sun8i-a83t-ohci" , }, - { .compatible ="allwinner,sun8i-h3-ohci" , }, - { .compatible ="allwinner,sun9i-a80-ohci" , }, - { .compatible ="allwinner,sun50i-a64-ohci" , }, - { } + { + .compatible ="allwinner,sun4i-a10-ohci" , + .data = (ulong )sun4i_a10_ohci, + }, + { + .compatible ="allwinner,sun5i-a13-ohci" , + .data = (ulong )sun5i_a13_ohci, + }, + { + .compatible ="allwinner,sun6i-a31-ohci" , + .data = (ulong )sun6i_a31_ohci, + }, + { + .compatible ="allwinner,sun7i-a20-ohci" , + .data = (ulong )sun7i_a20_ohci, + }, + { + .compatible ="allwinner,sun8i-a23-ohci" , + .data = (ulong )sun8i_a23_ohci, + }, + { + .compatible ="allwinner,sun8i-a83t-ohci" , + .data = (ulong )sun8i_a83t_ohci, + }, + { + .compatible ="allwinner,sun8i-h3-ohci" , + .data = (ulong )sun8i_h3_ohci, + }, + { + .compatible ="allwinner,sun9i-a80-ohci" , + .data = (ulong )sun9i_a80_ohci, + }, + { + .compatible ="allwinner,sun50i-a64-ohci" , + .data = (ulong )sun50i_a64_ohci, + }, + {/* sentinel */ } };U_BOOT_DRIVER (usb_ohci) = {
Signature · 1 line
2.17.1
PATCH v2 3/4 usb: sunxi: ohci: get rid of ifdefs
Hi,
Quoted 24 lines · Vasily Khoruzhick
We can use compatibles instead.
Signed-off-by Vasily Khoruzhick <[email protected]>--- drivers/usb/host/ohci-sunxi.c | 88 +++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 20 deletions(-)drivers/usb/host/ohci-sunxi.c +9
-0@@ -22,12 +22,25 @@#define AHB_CLK_DIST 1#endif +enum ohci_sunxi_type { + sun4i_a10_ohci, + sun5i_a13_ohci, + sun6i_a31_ohci, + sun7i_a20_ohci, + sun8i_a23_ohci, + sun8i_a83t_ohci, + sun8i_h3_ohci, + sun9i_a80_ohci,
drivers/usb/host/ohci-sunxi.c line 43
Quoted 10 lines
drivers/usb/host/ohci-sunxi.c +4
-0+ sun50i_a64_ohci, +}; +struct ohci_sunxi_priv {struct sunxi_ccm_reg *ccm;ohci_t ohci;int ahb_gate_mask;/* Mask of ahb_gate0 clk gate bits for this hcd */ int usb_gate_mask;/* Mask of usb_clk_cfg clk gate bits for this hcd */ struct phy phy; +enum ohci_sunxi_type type;
I'm really not a big fan of those ID, especially when we already have a structure here that have some very similar data embedded into it. In this particular case, it looks like you just need to add a bool to say if it has a reset, and an int for the extra_ahb_gate_mask, like we have the ahb_gate_mask already.
This also applies to the EHCI patch.
Maxime
Signature · 3 lines
Maxime Ripard, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering https://bootlin.com
PATCH v2 4/4 usb: sunxi: sun50i: enable OHCI0 clock when OHCI1 is in use
In reply to Vasily KhoruzhickOn A64 OHCI1 clock source is OHCI0 clock, so we need to enable OHCI0 clock when OHCI1 is in use.
Fixes commit dd3228170ad7 ("usb: sunxi: Switch to use generic-phy")
--- drivers/usb/host/ohci-sunxi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/usb/host/ohci-sunxi.c +5 -1
@@ -49,6 +49,7 @@ static int ohci_usb_probe(struct udevice *dev)struct ohci_sunxi_priv *priv =dev_get_priv (dev);struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr (dev);int extra_ahb_gate_mask =0 ; +int extra_usb_gate_mask =0 ;int phys, ret; priv->type = (enum ohci_sunxi_type )dev_get_driver_data (dev);
@@ -91,13 +92,16 @@ no_phy:if (priv->type == sun8i_h3_ohci) extra_ahb_gate_mask =1 <<AHB_GATE_OFFSET_USB_EHCI0 ; priv->usb_gate_mask =CCM_USB_CTRL_OHCI0_CLK ; +if (priv->type == sun50i_a64_ohci) + extra_usb_gate_mask =CCM_USB_CTRL_OHCI0_CLK ; priv->ahb_gate_mask <<= phys *AHB_CLK_DIST ; extra_ahb_gate_mask <<= phys *AHB_CLK_DIST ; priv->usb_gate_mask <<= phys;setbits_le32 (&priv->ccm->ahb_gate0, priv->ahb_gate_mask | extra_ahb_gate_mask); -setbits_le32 (&priv->ccm->usb_clk_cfg, priv->usb_gate_mask); +setbits_le32 (&priv->ccm->usb_clk_cfg, + priv->usb_gate_mask | extra_usb_gate_mask); if (priv->type == sun6i_a31_ohci || priv->type == sun8i_a23_ohci || priv->type == sun8i_a83t_ohci ||
Signature · 1 line
2.17.1