All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RESEND] phy: sun4i-usb: fix phy write on H3 and newer
@ 2021-11-16  9:35 ` Evgeny Boger
  0 siblings, 0 replies; 4+ messages in thread
From: Evgeny Boger @ 2021-11-16  9:35 UTC (permalink / raw)
  To: linux-sunxi
  Cc: Evgeny Boger, linux-arm-kernel, Maxime Ripard, Chen-Yu Tsai,
	Jernej Skrabec, Yangtao Li, Icenowy Zheng, andre.przywara

On older SoCs (prior to H3) PHY register are accessed by manipulating
the common register for all PHYs. PHY index is specified by pulsing
usbc bit.

Newer SoCs leave the access procedure mostly unchanged, the
difference being that the latch registers are separate for each PHY.

Additionally, accessing USB PHY registers is only possible if phy0 is
routed to musb IP instead of HCI.

Introduce phy_reg_access_v2 cfg flag for H3 (H2+, H5),
R40 (V40, A40i, T3), V3s (V3, S3) and A64 SoCs.

On A83t, H6, H616, T507 and probably on more recent hardware,
these PHY registers are not used in vendor BSP.
So don't set v2 flag for these even newer SoCs as a precaution.

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
---
 drivers/phy/allwinner/phy-sun4i-usb.c | 44 ++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index 788dd5cdbb7d..cf10e385f199 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -119,6 +119,7 @@ struct sun4i_usb_phy_cfg {
 	bool dedicated_clocks;
 	bool enable_pmu_unk1;
 	bool phy0_dual_route;
+	bool phy_reg_access_v2;
 	int missing_phys;
 };
 
@@ -192,13 +193,38 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
 				int len)
 {
 	struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
-	u32 temp, usbc_bit = BIT(phy->index * 2);
+	u32 otgctl_val, temp, usbc_bit;
 	void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
+	void __iomem *phyctl_latch;
 	unsigned long flags;
 	int i;
 
 	spin_lock_irqsave(&phy_data->reg_lock, flags);
 
+	/* On older SoCs (prior to H3) PHY register are accessed by manipulating the
+	 * common register for all PHYs. PHY index is specified by pulsing usbc bit.
+	 * Newer SoCs leave the access procedure mostly unchanged, the difference
+	 * being that the latch registers are separate for each PHY.
+	 */
+	if (phy_data->cfg->phy_reg_access_v2) {
+		if (phy->index == 0)
+			phyctl_latch = phy_data->base + phy_data->cfg->phyctl_offset;
+		else
+			phyctl_latch = phy->pmu + phy_data->cfg->phyctl_offset;
+		usbc_bit = 1;
+
+		/* Accessing USB PHY registers is only possible if phy0 is routed to musb.
+		 * As it's not clear whether is this related to actual PHY
+		 * routing or rather the hardware is just reusing the same bit,
+		 * don't check phy0_dual_route here.
+		 */
+		otgctl_val = readl(phy_data->base + REG_PHY_OTGCTL);
+		writel(otgctl_val | OTGCTL_ROUTE_MUSB, phy_data->base + REG_PHY_OTGCTL);
+	} else {
+		phyctl_latch = phyctl;
+		usbc_bit = BIT(phy->index * 2);
+	}
+
 	if (phy_data->cfg->phyctl_offset == REG_PHYCTL_A33) {
 		/* SoCs newer than A33 need us to set phyctl to 0 explicitly */
 		writel(0, phyctl);
@@ -224,17 +250,21 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
 		writeb(temp, phyctl);
 
 		/* pulse usbc_bit */
-		temp = readb(phyctl);
+		temp = readb(phyctl_latch);
 		temp |= usbc_bit;
-		writeb(temp, phyctl);
+		writeb(temp, phyctl_latch);
 
-		temp = readb(phyctl);
+		temp = readb(phyctl_latch);
 		temp &= ~usbc_bit;
-		writeb(temp, phyctl);
+		writeb(temp, phyctl_latch);
 
 		data >>= 1;
 	}
 
+	/* Restore PHY routing and the rest of OTGCTL */
+	if (phy_data->cfg->phy_reg_access_v2)
+		writel(otgctl_val, phy_data->base + REG_PHY_OTGCTL);
+
 	spin_unlock_irqrestore(&phy_data->reg_lock, flags);
 }
 
@@ -927,6 +957,7 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
 	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
+	.phy_reg_access_v2 = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
@@ -937,6 +968,7 @@ static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
 	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
+	.phy_reg_access_v2 = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
@@ -947,6 +979,7 @@ static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
 	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
+	.phy_reg_access_v2 = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
@@ -957,6 +990,7 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
 	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
+	.phy_reg_access_v2 = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH RESEND] phy: sun4i-usb: fix phy write on H3 and newer
@ 2021-11-16  9:35 ` Evgeny Boger
  0 siblings, 0 replies; 4+ messages in thread
From: Evgeny Boger @ 2021-11-16  9:35 UTC (permalink / raw)
  To: linux-sunxi
  Cc: Evgeny Boger, linux-arm-kernel, Maxime Ripard, Chen-Yu Tsai,
	Jernej Skrabec, Yangtao Li, Icenowy Zheng, andre.przywara

On older SoCs (prior to H3) PHY register are accessed by manipulating
the common register for all PHYs. PHY index is specified by pulsing
usbc bit.

Newer SoCs leave the access procedure mostly unchanged, the
difference being that the latch registers are separate for each PHY.

Additionally, accessing USB PHY registers is only possible if phy0 is
routed to musb IP instead of HCI.

Introduce phy_reg_access_v2 cfg flag for H3 (H2+, H5),
R40 (V40, A40i, T3), V3s (V3, S3) and A64 SoCs.

On A83t, H6, H616, T507 and probably on more recent hardware,
these PHY registers are not used in vendor BSP.
So don't set v2 flag for these even newer SoCs as a precaution.

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
---
 drivers/phy/allwinner/phy-sun4i-usb.c | 44 ++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index 788dd5cdbb7d..cf10e385f199 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -119,6 +119,7 @@ struct sun4i_usb_phy_cfg {
 	bool dedicated_clocks;
 	bool enable_pmu_unk1;
 	bool phy0_dual_route;
+	bool phy_reg_access_v2;
 	int missing_phys;
 };
 
@@ -192,13 +193,38 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
 				int len)
 {
 	struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
-	u32 temp, usbc_bit = BIT(phy->index * 2);
+	u32 otgctl_val, temp, usbc_bit;
 	void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
+	void __iomem *phyctl_latch;
 	unsigned long flags;
 	int i;
 
 	spin_lock_irqsave(&phy_data->reg_lock, flags);
 
+	/* On older SoCs (prior to H3) PHY register are accessed by manipulating the
+	 * common register for all PHYs. PHY index is specified by pulsing usbc bit.
+	 * Newer SoCs leave the access procedure mostly unchanged, the difference
+	 * being that the latch registers are separate for each PHY.
+	 */
+	if (phy_data->cfg->phy_reg_access_v2) {
+		if (phy->index == 0)
+			phyctl_latch = phy_data->base + phy_data->cfg->phyctl_offset;
+		else
+			phyctl_latch = phy->pmu + phy_data->cfg->phyctl_offset;
+		usbc_bit = 1;
+
+		/* Accessing USB PHY registers is only possible if phy0 is routed to musb.
+		 * As it's not clear whether is this related to actual PHY
+		 * routing or rather the hardware is just reusing the same bit,
+		 * don't check phy0_dual_route here.
+		 */
+		otgctl_val = readl(phy_data->base + REG_PHY_OTGCTL);
+		writel(otgctl_val | OTGCTL_ROUTE_MUSB, phy_data->base + REG_PHY_OTGCTL);
+	} else {
+		phyctl_latch = phyctl;
+		usbc_bit = BIT(phy->index * 2);
+	}
+
 	if (phy_data->cfg->phyctl_offset == REG_PHYCTL_A33) {
 		/* SoCs newer than A33 need us to set phyctl to 0 explicitly */
 		writel(0, phyctl);
@@ -224,17 +250,21 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
 		writeb(temp, phyctl);
 
 		/* pulse usbc_bit */
-		temp = readb(phyctl);
+		temp = readb(phyctl_latch);
 		temp |= usbc_bit;
-		writeb(temp, phyctl);
+		writeb(temp, phyctl_latch);
 
-		temp = readb(phyctl);
+		temp = readb(phyctl_latch);
 		temp &= ~usbc_bit;
-		writeb(temp, phyctl);
+		writeb(temp, phyctl_latch);
 
 		data >>= 1;
 	}
 
+	/* Restore PHY routing and the rest of OTGCTL */
+	if (phy_data->cfg->phy_reg_access_v2)
+		writel(otgctl_val, phy_data->base + REG_PHY_OTGCTL);
+
 	spin_unlock_irqrestore(&phy_data->reg_lock, flags);
 }
 
@@ -927,6 +957,7 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
 	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
+	.phy_reg_access_v2 = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
@@ -937,6 +968,7 @@ static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
 	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
+	.phy_reg_access_v2 = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
@@ -947,6 +979,7 @@ static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
 	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
+	.phy_reg_access_v2 = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
@@ -957,6 +990,7 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
 	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
+	.phy_reg_access_v2 = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH RESEND] phy: sun4i-usb: fix phy write on H3 and newer
  2021-11-16  9:35 ` Evgeny Boger
@ 2021-12-12 13:14   ` Evgeny Boger
  -1 siblings, 0 replies; 4+ messages in thread
From: Evgeny Boger @ 2021-12-12 13:14 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: linux-arm-kernel, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Yangtao Li, Icenowy Zheng, andre.przywara, linux-sunxi

Hi Maxime!

I'm sorry to bother you, but is there anything else I can do to make 
this patch merged?
It's been sitting there for 5 months already.


16.11.2021 12:35, Evgeny Boger пишет:
> On older SoCs (prior to H3) PHY register are accessed by manipulating
> the common register for all PHYs. PHY index is specified by pulsing
> usbc bit.
>
> Newer SoCs leave the access procedure mostly unchanged, the
> difference being that the latch registers are separate for each PHY.
>
> Additionally, accessing USB PHY registers is only possible if phy0 is
> routed to musb IP instead of HCI.
>
> Introduce phy_reg_access_v2 cfg flag for H3 (H2+, H5),
> R40 (V40, A40i, T3), V3s (V3, S3) and A64 SoCs.
>
> On A83t, H6, H616, T507 and probably on more recent hardware,
> these PHY registers are not used in vendor BSP.
> So don't set v2 flag for these even newer SoCs as a precaution.
>
> Signed-off-by: Evgeny Boger <boger@wirenboard.com>
> ---
>   drivers/phy/allwinner/phy-sun4i-usb.c | 44 ++++++++++++++++++++++++---
>   1 file changed, 39 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
> index 788dd5cdbb7d..cf10e385f199 100644
> --- a/drivers/phy/allwinner/phy-sun4i-usb.c
> +++ b/drivers/phy/allwinner/phy-sun4i-usb.c
> @@ -119,6 +119,7 @@ struct sun4i_usb_phy_cfg {
>   	bool dedicated_clocks;
>   	bool enable_pmu_unk1;
>   	bool phy0_dual_route;
> +	bool phy_reg_access_v2;
>   	int missing_phys;
>   };
>   
> @@ -192,13 +193,38 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
>   				int len)
>   {
>   	struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
> -	u32 temp, usbc_bit = BIT(phy->index * 2);
> +	u32 otgctl_val, temp, usbc_bit;
>   	void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
> +	void __iomem *phyctl_latch;
>   	unsigned long flags;
>   	int i;
>   
>   	spin_lock_irqsave(&phy_data->reg_lock, flags);
>   
> +	/* On older SoCs (prior to H3) PHY register are accessed by manipulating the
> +	 * common register for all PHYs. PHY index is specified by pulsing usbc bit.
> +	 * Newer SoCs leave the access procedure mostly unchanged, the difference
> +	 * being that the latch registers are separate for each PHY.
> +	 */
> +	if (phy_data->cfg->phy_reg_access_v2) {
> +		if (phy->index == 0)
> +			phyctl_latch = phy_data->base + phy_data->cfg->phyctl_offset;
> +		else
> +			phyctl_latch = phy->pmu + phy_data->cfg->phyctl_offset;
> +		usbc_bit = 1;
> +
> +		/* Accessing USB PHY registers is only possible if phy0 is routed to musb.
> +		 * As it's not clear whether is this related to actual PHY
> +		 * routing or rather the hardware is just reusing the same bit,
> +		 * don't check phy0_dual_route here.
> +		 */
> +		otgctl_val = readl(phy_data->base + REG_PHY_OTGCTL);
> +		writel(otgctl_val | OTGCTL_ROUTE_MUSB, phy_data->base + REG_PHY_OTGCTL);
> +	} else {
> +		phyctl_latch = phyctl;
> +		usbc_bit = BIT(phy->index * 2);
> +	}
> +
>   	if (phy_data->cfg->phyctl_offset == REG_PHYCTL_A33) {
>   		/* SoCs newer than A33 need us to set phyctl to 0 explicitly */
>   		writel(0, phyctl);
> @@ -224,17 +250,21 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
>   		writeb(temp, phyctl);
>   
>   		/* pulse usbc_bit */
> -		temp = readb(phyctl);
> +		temp = readb(phyctl_latch);
>   		temp |= usbc_bit;
> -		writeb(temp, phyctl);
> +		writeb(temp, phyctl_latch);
>   
> -		temp = readb(phyctl);
> +		temp = readb(phyctl_latch);
>   		temp &= ~usbc_bit;
> -		writeb(temp, phyctl);
> +		writeb(temp, phyctl_latch);
>   
>   		data >>= 1;
>   	}
>   
> +	/* Restore PHY routing and the rest of OTGCTL */
> +	if (phy_data->cfg->phy_reg_access_v2)
> +		writel(otgctl_val, phy_data->base + REG_PHY_OTGCTL);
> +
>   	spin_unlock_irqrestore(&phy_data->reg_lock, flags);
>   }
>   
> @@ -927,6 +957,7 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
>   	.dedicated_clocks = true,
>   	.enable_pmu_unk1 = true,
>   	.phy0_dual_route = true,
> +	.phy_reg_access_v2 = true,
>   };
>   
>   static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
> @@ -937,6 +968,7 @@ static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
>   	.dedicated_clocks = true,
>   	.enable_pmu_unk1 = true,
>   	.phy0_dual_route = true,
> +	.phy_reg_access_v2 = true,
>   };
>   
>   static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
> @@ -947,6 +979,7 @@ static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
>   	.dedicated_clocks = true,
>   	.enable_pmu_unk1 = true,
>   	.phy0_dual_route = true,
> +	.phy_reg_access_v2 = true,
>   };
>   
>   static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
> @@ -957,6 +990,7 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
>   	.dedicated_clocks = true,
>   	.enable_pmu_unk1 = true,
>   	.phy0_dual_route = true,
> +	.phy_reg_access_v2 = true,
>   };
>   
>   static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {


-- 
С уважением,
     Евгений Богер / Evgeny Boger
     CTO, Wiren Board Team
     https://wirenboard.com/ru
     +7 495 150 66 19 (# 33)


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH RESEND] phy: sun4i-usb: fix phy write on H3 and newer
@ 2021-12-12 13:14   ` Evgeny Boger
  0 siblings, 0 replies; 4+ messages in thread
From: Evgeny Boger @ 2021-12-12 13:14 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: linux-arm-kernel, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Yangtao Li, Icenowy Zheng, andre.przywara, linux-sunxi

Hi Maxime!

I'm sorry to bother you, but is there anything else I can do to make 
this patch merged?
It's been sitting there for 5 months already.


16.11.2021 12:35, Evgeny Boger пишет:
> On older SoCs (prior to H3) PHY register are accessed by manipulating
> the common register for all PHYs. PHY index is specified by pulsing
> usbc bit.
>
> Newer SoCs leave the access procedure mostly unchanged, the
> difference being that the latch registers are separate for each PHY.
>
> Additionally, accessing USB PHY registers is only possible if phy0 is
> routed to musb IP instead of HCI.
>
> Introduce phy_reg_access_v2 cfg flag for H3 (H2+, H5),
> R40 (V40, A40i, T3), V3s (V3, S3) and A64 SoCs.
>
> On A83t, H6, H616, T507 and probably on more recent hardware,
> these PHY registers are not used in vendor BSP.
> So don't set v2 flag for these even newer SoCs as a precaution.
>
> Signed-off-by: Evgeny Boger <boger@wirenboard.com>
> ---
>   drivers/phy/allwinner/phy-sun4i-usb.c | 44 ++++++++++++++++++++++++---
>   1 file changed, 39 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
> index 788dd5cdbb7d..cf10e385f199 100644
> --- a/drivers/phy/allwinner/phy-sun4i-usb.c
> +++ b/drivers/phy/allwinner/phy-sun4i-usb.c
> @@ -119,6 +119,7 @@ struct sun4i_usb_phy_cfg {
>   	bool dedicated_clocks;
>   	bool enable_pmu_unk1;
>   	bool phy0_dual_route;
> +	bool phy_reg_access_v2;
>   	int missing_phys;
>   };
>   
> @@ -192,13 +193,38 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
>   				int len)
>   {
>   	struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
> -	u32 temp, usbc_bit = BIT(phy->index * 2);
> +	u32 otgctl_val, temp, usbc_bit;
>   	void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
> +	void __iomem *phyctl_latch;
>   	unsigned long flags;
>   	int i;
>   
>   	spin_lock_irqsave(&phy_data->reg_lock, flags);
>   
> +	/* On older SoCs (prior to H3) PHY register are accessed by manipulating the
> +	 * common register for all PHYs. PHY index is specified by pulsing usbc bit.
> +	 * Newer SoCs leave the access procedure mostly unchanged, the difference
> +	 * being that the latch registers are separate for each PHY.
> +	 */
> +	if (phy_data->cfg->phy_reg_access_v2) {
> +		if (phy->index == 0)
> +			phyctl_latch = phy_data->base + phy_data->cfg->phyctl_offset;
> +		else
> +			phyctl_latch = phy->pmu + phy_data->cfg->phyctl_offset;
> +		usbc_bit = 1;
> +
> +		/* Accessing USB PHY registers is only possible if phy0 is routed to musb.
> +		 * As it's not clear whether is this related to actual PHY
> +		 * routing or rather the hardware is just reusing the same bit,
> +		 * don't check phy0_dual_route here.
> +		 */
> +		otgctl_val = readl(phy_data->base + REG_PHY_OTGCTL);
> +		writel(otgctl_val | OTGCTL_ROUTE_MUSB, phy_data->base + REG_PHY_OTGCTL);
> +	} else {
> +		phyctl_latch = phyctl;
> +		usbc_bit = BIT(phy->index * 2);
> +	}
> +
>   	if (phy_data->cfg->phyctl_offset == REG_PHYCTL_A33) {
>   		/* SoCs newer than A33 need us to set phyctl to 0 explicitly */
>   		writel(0, phyctl);
> @@ -224,17 +250,21 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
>   		writeb(temp, phyctl);
>   
>   		/* pulse usbc_bit */
> -		temp = readb(phyctl);
> +		temp = readb(phyctl_latch);
>   		temp |= usbc_bit;
> -		writeb(temp, phyctl);
> +		writeb(temp, phyctl_latch);
>   
> -		temp = readb(phyctl);
> +		temp = readb(phyctl_latch);
>   		temp &= ~usbc_bit;
> -		writeb(temp, phyctl);
> +		writeb(temp, phyctl_latch);
>   
>   		data >>= 1;
>   	}
>   
> +	/* Restore PHY routing and the rest of OTGCTL */
> +	if (phy_data->cfg->phy_reg_access_v2)
> +		writel(otgctl_val, phy_data->base + REG_PHY_OTGCTL);
> +
>   	spin_unlock_irqrestore(&phy_data->reg_lock, flags);
>   }
>   
> @@ -927,6 +957,7 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
>   	.dedicated_clocks = true,
>   	.enable_pmu_unk1 = true,
>   	.phy0_dual_route = true,
> +	.phy_reg_access_v2 = true,
>   };
>   
>   static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
> @@ -937,6 +968,7 @@ static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
>   	.dedicated_clocks = true,
>   	.enable_pmu_unk1 = true,
>   	.phy0_dual_route = true,
> +	.phy_reg_access_v2 = true,
>   };
>   
>   static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
> @@ -947,6 +979,7 @@ static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
>   	.dedicated_clocks = true,
>   	.enable_pmu_unk1 = true,
>   	.phy0_dual_route = true,
> +	.phy_reg_access_v2 = true,
>   };
>   
>   static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
> @@ -957,6 +990,7 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
>   	.dedicated_clocks = true,
>   	.enable_pmu_unk1 = true,
>   	.phy0_dual_route = true,
> +	.phy_reg_access_v2 = true,
>   };
>   
>   static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {


-- 
С уважением,
     Евгений Богер / Evgeny Boger
     CTO, Wiren Board Team
     https://wirenboard.com/ru
     +7 495 150 66 19 (# 33)


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-12-12 13:16 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-16  9:35 [PATCH RESEND] phy: sun4i-usb: fix phy write on H3 and newer Evgeny Boger
2021-11-16  9:35 ` Evgeny Boger
2021-12-12 13:14 ` Evgeny Boger
2021-12-12 13:14   ` Evgeny Boger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.