Skip to content

Commit 4eae163

Browse files
claudiubezneavinodkoul
authored andcommitted
phy: renesas: rcar-gen3-usb2: Add support to initialize the bus
The Renesas RZ/G3S need to initialize the USB BUS before transferring data due to hardware limitation. As the register that need to be touched for this is in the address space of the USB PHY, and the UBS PHY need to be initialized before any other USB drivers handling data transfer, add support to initialize the USB BUS. As the USB PHY is probed before any other USB drivers that enables clocks and de-assert the reset signals and the BUS initialization is done in the probe phase, we need to add code to de-assert reset signal and runtime resume the device (which enables its clocks) before accessing the registers. As the reset signals are not required by the USB PHY driver for the other USB PHY hardware variants, the reset signals and runtime PM was handled only in the function that initialize the USB BUS. The PHY initialization was done right after runtime PM enable to have all in place when the PHYs are registered. Signed-off-by: Claudiu Beznea <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 0d5a213 commit 4eae163

File tree

1 file changed

+47
-3
lines changed

1 file changed

+47
-3
lines changed

drivers/phy/renesas/phy-rcar-gen3-usb2.c

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
#include <linux/platform_device.h>
2020
#include <linux/pm_runtime.h>
2121
#include <linux/regulator/consumer.h>
22+
#include <linux/reset.h>
2223
#include <linux/string.h>
2324
#include <linux/usb/of.h>
2425
#include <linux/workqueue.h>
2526

2627
/******* USB2.0 Host registers (original offset is +0x200) *******/
2728
#define USB2_INT_ENABLE 0x000
29+
#define USB2_AHB_BUS_CTR 0x008
2830
#define USB2_USBCTR 0x00c
2931
#define USB2_SPD_RSM_TIMSET 0x10c
3032
#define USB2_OC_TIMSET 0x110
@@ -40,6 +42,10 @@
4042
#define USB2_INT_ENABLE_USBH_INTB_EN BIT(2) /* For EHCI */
4143
#define USB2_INT_ENABLE_USBH_INTA_EN BIT(1) /* For OHCI */
4244

45+
/* AHB_BUS_CTR */
46+
#define USB2_AHB_BUS_CTR_MBL_MASK GENMASK(1, 0)
47+
#define USB2_AHB_BUS_CTR_MBL_INCR4 2
48+
4349
/* USBCTR */
4450
#define USB2_USBCTR_DIRPD BIT(2)
4551
#define USB2_USBCTR_PLL_RST BIT(1)
@@ -111,6 +117,7 @@ struct rcar_gen3_chan {
111117
struct extcon_dev *extcon;
112118
struct rcar_gen3_phy rphys[NUM_OF_PHYS];
113119
struct regulator *vbus;
120+
struct reset_control *rstc;
114121
struct work_struct work;
115122
struct mutex lock; /* protects rphys[...].powered */
116123
enum usb_dr_mode dr_mode;
@@ -125,6 +132,7 @@ struct rcar_gen3_chan {
125132
struct rcar_gen3_phy_drv_data {
126133
const struct phy_ops *phy_usb2_ops;
127134
bool no_adp_ctrl;
135+
bool init_bus;
128136
};
129137

130138
/*
@@ -650,6 +658,35 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
650658
return candidate;
651659
}
652660

661+
static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
662+
{
663+
struct device *dev = channel->dev;
664+
int ret;
665+
u32 val;
666+
667+
channel->rstc = devm_reset_control_array_get_shared(dev);
668+
if (IS_ERR(channel->rstc))
669+
return PTR_ERR(channel->rstc);
670+
671+
ret = pm_runtime_resume_and_get(dev);
672+
if (ret)
673+
return ret;
674+
675+
ret = reset_control_deassert(channel->rstc);
676+
if (ret)
677+
goto rpm_put;
678+
679+
val = readl(channel->base + USB2_AHB_BUS_CTR);
680+
val &= ~USB2_AHB_BUS_CTR_MBL_MASK;
681+
val |= USB2_AHB_BUS_CTR_MBL_INCR4;
682+
writel(val, channel->base + USB2_AHB_BUS_CTR);
683+
684+
rpm_put:
685+
pm_runtime_put(dev);
686+
687+
return ret;
688+
}
689+
653690
static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
654691
{
655692
const struct rcar_gen3_phy_drv_data *phy_data;
@@ -703,6 +740,15 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
703740
goto error;
704741
}
705742

743+
platform_set_drvdata(pdev, channel);
744+
channel->dev = dev;
745+
746+
if (phy_data->init_bus) {
747+
ret = rcar_gen3_phy_usb2_init_bus(channel);
748+
if (ret)
749+
goto error;
750+
}
751+
706752
channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl;
707753
if (phy_data->no_adp_ctrl)
708754
channel->obint_enable_bits = USB2_OBINT_IDCHG_EN;
@@ -733,9 +779,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
733779
channel->vbus = NULL;
734780
}
735781

736-
platform_set_drvdata(pdev, channel);
737-
channel->dev = dev;
738-
739782
provider = devm_of_phy_provider_register(dev, rcar_gen3_phy_usb2_xlate);
740783
if (IS_ERR(provider)) {
741784
dev_err(dev, "Failed to register PHY provider\n");
@@ -762,6 +805,7 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
762805
if (channel->is_otg_channel)
763806
device_remove_file(&pdev->dev, &dev_attr_role);
764807

808+
reset_control_assert(channel->rstc);
765809
pm_runtime_disable(&pdev->dev);
766810
};
767811

0 commit comments

Comments
 (0)