Message ID | 1501575133-20953-2-git-send-email-frank.wang@rock-chips.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi, On Tuesday 01 August 2017 01:42 PM, Frank Wang wrote: > The registers of usb-phy are distributed in grf and usbgrf on some > Rockchip SoCs (e.g RV1108), this patch add a quirk to support this > companion grf design. > > Signed-off-by: Frank Wang <frank.wang@rock-chips.com> > --- > .../bindings/phy/phy-rockchip-inno-usb2.txt | 4 + > drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 112 ++++++++++++++------- > 2 files changed, 78 insertions(+), 38 deletions(-) > > diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt > index 84d59b0..ddf868a 100644 > --- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt > +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt > @@ -18,6 +18,10 @@ Optional properties: > usb-phy output 480m and xin24m. > Refer to clk/clock-bindings.txt for generic clock > consumer properties. > + - rockchip,usbgrf : phandle to the syscon managing the "usb general > + register files". > + - rockchip,companion_grf_quirk : when set driver will request > + "rockchip,usbgrf" phandle as one companion-grf. please send the dt-bindings as a separate patch and cc devicetree list. Thanks Kishon > > Required nodes : a sub-node is required for each port the phy provides. > The sub-node name is used to identify host or otg port, > diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > index 626883d..669e5f6 100644 > --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > @@ -202,6 +202,7 @@ struct rockchip_usb2phy_port { > /** > * struct rockchip_usb2phy: usb2.0 phy driver data. > * @grf: General Register Files regmap. > + * @usbgrf: USB General Register Files regmap. > * @clk: clock struct of phy input clk. > * @clk480m: clock struct of phy output clk. > * @clk_hw: clock struct of phy output clk management. > @@ -216,6 +217,7 @@ struct rockchip_usb2phy_port { > struct rockchip_usb2phy { > struct device *dev; > struct regmap *grf; > + struct regmap *usbgrf; > struct clk *clk; > struct clk *clk480m; > struct clk_hw clk480m_hw; > @@ -225,9 +227,15 @@ struct rockchip_usb2phy { > struct extcon_dev *edev; > const struct rockchip_usb2phy_cfg *phy_cfg; > struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS]; > + unsigned int companion_grf_quirk:1; > }; > > -static inline int property_enable(struct rockchip_usb2phy *rphy, > +static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy) > +{ > + return rphy->companion_grf_quirk ? rphy->usbgrf : rphy->grf; > +} > + > +static inline int property_enable(struct regmap *base, > const struct usb2phy_reg *reg, bool en) > { > unsigned int val, mask, tmp; > @@ -236,17 +244,17 @@ static inline int property_enable(struct rockchip_usb2phy *rphy, > mask = GENMASK(reg->bitend, reg->bitstart); > val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); > > - return regmap_write(rphy->grf, reg->offset, val); > + return regmap_write(base, reg->offset, val); > } > > -static inline bool property_enabled(struct rockchip_usb2phy *rphy, > +static inline bool property_enabled(struct regmap *base, > const struct usb2phy_reg *reg) > { > int ret; > unsigned int tmp, orig; > unsigned int mask = GENMASK(reg->bitend, reg->bitstart); > > - ret = regmap_read(rphy->grf, reg->offset, &orig); > + ret = regmap_read(base, reg->offset, &orig); > if (ret) > return false; > > @@ -258,11 +266,12 @@ static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw) > { > struct rockchip_usb2phy *rphy = > container_of(hw, struct rockchip_usb2phy, clk480m_hw); > + struct regmap *base = get_reg_base(rphy); > int ret; > > /* turn on 480m clk output if it is off */ > - if (!property_enabled(rphy, &rphy->phy_cfg->clkout_ctl)) { > - ret = property_enable(rphy, &rphy->phy_cfg->clkout_ctl, true); > + if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) { > + ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true); > if (ret) > return ret; > > @@ -277,17 +286,19 @@ static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw) > { > struct rockchip_usb2phy *rphy = > container_of(hw, struct rockchip_usb2phy, clk480m_hw); > + struct regmap *base = get_reg_base(rphy); > > /* turn off 480m clk output */ > - property_enable(rphy, &rphy->phy_cfg->clkout_ctl, false); > + property_enable(base, &rphy->phy_cfg->clkout_ctl, false); > } > > static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw) > { > struct rockchip_usb2phy *rphy = > container_of(hw, struct rockchip_usb2phy, clk480m_hw); > + struct regmap *base = get_reg_base(rphy); > > - return property_enabled(rphy, &rphy->phy_cfg->clkout_ctl); > + return property_enabled(base, &rphy->phy_cfg->clkout_ctl); > } > > static unsigned long > @@ -409,13 +420,13 @@ static int rockchip_usb2phy_init(struct phy *phy) > if (rport->mode != USB_DR_MODE_HOST && > rport->mode != USB_DR_MODE_UNKNOWN) { > /* clear bvalid status and enable bvalid detect irq */ > - ret = property_enable(rphy, > + ret = property_enable(rphy->grf, > &rport->port_cfg->bvalid_det_clr, > true); > if (ret) > goto out; > > - ret = property_enable(rphy, > + ret = property_enable(rphy->grf, > &rport->port_cfg->bvalid_det_en, > true); > if (ret) > @@ -429,11 +440,13 @@ static int rockchip_usb2phy_init(struct phy *phy) > } > } else if (rport->port_id == USB2PHY_PORT_HOST) { > /* clear linestate and enable linestate detect irq */ > - ret = property_enable(rphy, &rport->port_cfg->ls_det_clr, true); > + ret = property_enable(rphy->grf, > + &rport->port_cfg->ls_det_clr, true); > if (ret) > goto out; > > - ret = property_enable(rphy, &rport->port_cfg->ls_det_en, true); > + ret = property_enable(rphy->grf, > + &rport->port_cfg->ls_det_en, true); > if (ret) > goto out; > > @@ -449,6 +462,7 @@ static int rockchip_usb2phy_power_on(struct phy *phy) > { > struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); > struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); > + struct regmap *base = get_reg_base(rphy); > int ret; > > dev_dbg(&rport->phy->dev, "port power on\n"); > @@ -460,7 +474,7 @@ static int rockchip_usb2phy_power_on(struct phy *phy) > if (ret) > return ret; > > - ret = property_enable(rphy, &rport->port_cfg->phy_sus, false); > + ret = property_enable(base, &rport->port_cfg->phy_sus, false); > if (ret) > return ret; > > @@ -475,6 +489,7 @@ static int rockchip_usb2phy_power_off(struct phy *phy) > { > struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); > struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); > + struct regmap *base = get_reg_base(rphy); > int ret; > > dev_dbg(&rport->phy->dev, "port power off\n"); > @@ -482,7 +497,7 @@ static int rockchip_usb2phy_power_off(struct phy *phy) > if (rport->suspended) > return 0; > > - ret = property_enable(rphy, &rport->port_cfg->phy_sus, true); > + ret = property_enable(base, &rport->port_cfg->phy_sus, true); > if (ret) > return ret; > > @@ -526,11 +541,11 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work) > bool vbus_attach, sch_work, notify_charger; > > if (rport->utmi_avalid) > - vbus_attach = > - property_enabled(rphy, &rport->port_cfg->utmi_avalid); > + vbus_attach = property_enabled(rphy->grf, > + &rport->port_cfg->utmi_avalid); > else > - vbus_attach = > - property_enabled(rphy, &rport->port_cfg->utmi_bvalid); > + vbus_attach = property_enabled(rphy->grf, > + &rport->port_cfg->utmi_bvalid); > > sch_work = false; > notify_charger = false; > @@ -650,22 +665,28 @@ static const char *chg_to_string(enum power_supply_type chg_type) > static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy, > bool en) > { > - property_enable(rphy, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en); > - property_enable(rphy, &rphy->phy_cfg->chg_det.idp_src_en, en); > + struct regmap *base = get_reg_base(rphy); > + > + property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en); > + property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en); > } > > static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy, > bool en) > { > - property_enable(rphy, &rphy->phy_cfg->chg_det.vdp_src_en, en); > - property_enable(rphy, &rphy->phy_cfg->chg_det.idm_sink_en, en); > + struct regmap *base = get_reg_base(rphy); > + > + property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en); > + property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en); > } > > static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy, > bool en) > { > - property_enable(rphy, &rphy->phy_cfg->chg_det.vdm_src_en, en); > - property_enable(rphy, &rphy->phy_cfg->chg_det.idp_sink_en, en); > + struct regmap *base = get_reg_base(rphy); > + > + property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en); > + property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en); > } > > #define CHG_DCD_POLL_TIME (100 * HZ / 1000) > @@ -677,6 +698,7 @@ static void rockchip_chg_detect_work(struct work_struct *work) > struct rockchip_usb2phy_port *rport = > container_of(work, struct rockchip_usb2phy_port, chg_work.work); > struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); > + struct regmap *base = get_reg_base(rphy); > bool is_dcd, tmout, vout; > unsigned long delay; > > @@ -687,7 +709,7 @@ static void rockchip_chg_detect_work(struct work_struct *work) > if (!rport->suspended) > rockchip_usb2phy_power_off(rport->phy); > /* put the controller in non-driving mode */ > - property_enable(rphy, &rphy->phy_cfg->chg_det.opmode, false); > + property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); > /* Start DCD processing stage 1 */ > rockchip_chg_enable_dcd(rphy, true); > rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD; > @@ -696,7 +718,8 @@ static void rockchip_chg_detect_work(struct work_struct *work) > break; > case USB_CHG_STATE_WAIT_FOR_DCD: > /* get data contact detection status */ > - is_dcd = property_enabled(rphy, &rphy->phy_cfg->chg_det.dp_det); > + is_dcd = property_enabled(rphy->grf, > + &rphy->phy_cfg->chg_det.dp_det); > tmout = ++rphy->dcd_retries == CHG_DCD_MAX_RETRIES; > /* stage 2 */ > if (is_dcd || tmout) { > @@ -713,7 +736,8 @@ static void rockchip_chg_detect_work(struct work_struct *work) > } > break; > case USB_CHG_STATE_DCD_DONE: > - vout = property_enabled(rphy, &rphy->phy_cfg->chg_det.cp_det); > + vout = property_enabled(rphy->grf, > + &rphy->phy_cfg->chg_det.cp_det); > rockchip_chg_enable_primary_det(rphy, false); > if (vout) { > /* Voltage Source on DM, Probe on DP */ > @@ -734,7 +758,8 @@ static void rockchip_chg_detect_work(struct work_struct *work) > } > break; > case USB_CHG_STATE_PRIMARY_DONE: > - vout = property_enabled(rphy, &rphy->phy_cfg->chg_det.dcp_det); > + vout = property_enabled(rphy->grf, > + &rphy->phy_cfg->chg_det.dcp_det); > /* Turn off voltage source */ > rockchip_chg_enable_secondary_det(rphy, false); > if (vout) > @@ -748,7 +773,7 @@ static void rockchip_chg_detect_work(struct work_struct *work) > /* fall through */ > case USB_CHG_STATE_DETECTED: > /* put the controller in normal mode */ > - property_enable(rphy, &rphy->phy_cfg->chg_det.opmode, true); > + property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); > rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work); > dev_info(&rport->phy->dev, "charger = %s\n", > chg_to_string(rphy->chg_type)); > @@ -790,8 +815,7 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work) > if (ret < 0) > goto next_schedule; > > - ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, > - &uhd); > + ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd); > if (ret < 0) > goto next_schedule; > > @@ -845,8 +869,8 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work) > * activate the linestate detection to get the next device > * plug-in irq. > */ > - property_enable(rphy, &rport->port_cfg->ls_det_clr, true); > - property_enable(rphy, &rport->port_cfg->ls_det_en, true); > + property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true); > + property_enable(rphy->grf, &rport->port_cfg->ls_det_en, true); > > /* > * we don't need to rearm the delayed work when the phy port > @@ -869,14 +893,14 @@ static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data) > struct rockchip_usb2phy_port *rport = data; > struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); > > - if (!property_enabled(rphy, &rport->port_cfg->ls_det_st)) > + if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st)) > return IRQ_NONE; > > mutex_lock(&rport->mutex); > > /* disable linestate detect irq and clear its status */ > - property_enable(rphy, &rport->port_cfg->ls_det_en, false); > - property_enable(rphy, &rport->port_cfg->ls_det_clr, true); > + property_enable(rphy->grf, &rport->port_cfg->ls_det_en, false); > + property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true); > > mutex_unlock(&rport->mutex); > > @@ -896,13 +920,13 @@ static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data) > struct rockchip_usb2phy_port *rport = data; > struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); > > - if (!property_enabled(rphy, &rport->port_cfg->bvalid_det_st)) > + if (!property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st)) > return IRQ_NONE; > > mutex_lock(&rport->mutex); > > /* clear bvalid detect irq pending status */ > - property_enable(rphy, &rport->port_cfg->bvalid_det_clr, true); > + property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true); > > mutex_unlock(&rport->mutex); > > @@ -1045,6 +1069,18 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) > if (IS_ERR(rphy->grf)) > return PTR_ERR(rphy->grf); > > + rphy->companion_grf_quirk = > + device_property_read_bool(dev, "rockchip,companion_grf_quirk"); > + if (rphy->companion_grf_quirk) { > + rphy->usbgrf = > + syscon_regmap_lookup_by_phandle(dev->of_node, > + "rockchip,usbgrf"); > + if (IS_ERR(rphy->usbgrf)) > + return PTR_ERR(rphy->usbgrf); > + } else { > + rphy->usbgrf = NULL; > + } > + > if (of_property_read_u32(np, "reg", ®)) { > dev_err(dev, "the reg property is not assigned in %s node\n", > np->name); >
Hi Kishon, On 2017/8/2 13:03, Kishon Vijay Abraham I wrote: > Hi, > > On Tuesday 01 August 2017 01:42 PM, Frank Wang wrote: >> The registers of usb-phy are distributed in grf and usbgrf on some >> Rockchip SoCs (e.g RV1108), this patch add a quirk to support this >> companion grf design. >> >> Signed-off-by: Frank Wang <frank.wang@rock-chips.com> >> --- >> .../bindings/phy/phy-rockchip-inno-usb2.txt | 4 + >> drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 112 ++++++++++++++------- >> 2 files changed, 78 insertions(+), 38 deletions(-) >> >> diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt >> index 84d59b0..ddf868a 100644 >> --- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt >> +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt >> @@ -18,6 +18,10 @@ Optional properties: >> usb-phy output 480m and xin24m. >> Refer to clk/clock-bindings.txt for generic clock >> consumer properties. >> + - rockchip,usbgrf : phandle to the syscon managing the "usb general >> + register files". >> + - rockchip,companion_grf_quirk : when set driver will request >> + "rockchip,usbgrf" phandle as one companion-grf. > please send the dt-bindings as a separate patch and cc devicetree list. Noted and thanks for your comments, I will fix it. BR. Frank > Thanks > Kishon >> >> Required nodes : a sub-node is required for each port the phy provides. >> The sub-node name is used to identify host or otg port, >> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c >> index 626883d..669e5f6 100644 >> --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c >> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c >> @@ -202,6 +202,7 @@ struct rockchip_usb2phy_port { >> /** >> * struct rockchip_usb2phy: usb2.0 phy driver data. >> * @grf: General Register Files regmap. >> + * @usbgrf: USB General Register Files regmap. >> * @clk: clock struct of phy input clk. >> * @clk480m: clock struct of phy output clk. >> * @clk_hw: clock struct of phy output clk management. >> @@ -216,6 +217,7 @@ struct rockchip_usb2phy_port { >> struct rockchip_usb2phy { >> struct device *dev; >> struct regmap *grf; >> + struct regmap *usbgrf; >> struct clk *clk; >> struct clk *clk480m; >> struct clk_hw clk480m_hw; >> @@ -225,9 +227,15 @@ struct rockchip_usb2phy { >> struct extcon_dev *edev; >> const struct rockchip_usb2phy_cfg *phy_cfg; >> struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS]; >> + unsigned int companion_grf_quirk:1; >> }; >> >> -static inline int property_enable(struct rockchip_usb2phy *rphy, >> +static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy) >> +{ >> + return rphy->companion_grf_quirk ? rphy->usbgrf : rphy->grf; >> +} >> + >> +static inline int property_enable(struct regmap *base, >> const struct usb2phy_reg *reg, bool en) >> { >> unsigned int val, mask, tmp; >> @@ -236,17 +244,17 @@ static inline int property_enable(struct rockchip_usb2phy *rphy, >> mask = GENMASK(reg->bitend, reg->bitstart); >> val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); >> >> - return regmap_write(rphy->grf, reg->offset, val); >> + return regmap_write(base, reg->offset, val); >> } >> >> -static inline bool property_enabled(struct rockchip_usb2phy *rphy, >> +static inline bool property_enabled(struct regmap *base, >> const struct usb2phy_reg *reg) >> { >> int ret; >> unsigned int tmp, orig; >> unsigned int mask = GENMASK(reg->bitend, reg->bitstart); >> >> - ret = regmap_read(rphy->grf, reg->offset, &orig); >> + ret = regmap_read(base, reg->offset, &orig); >> if (ret) >> return false; >> >> @@ -258,11 +266,12 @@ static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw) >> { >> struct rockchip_usb2phy *rphy = >> container_of(hw, struct rockchip_usb2phy, clk480m_hw); >> + struct regmap *base = get_reg_base(rphy); >> int ret; >> >> /* turn on 480m clk output if it is off */ >> - if (!property_enabled(rphy, &rphy->phy_cfg->clkout_ctl)) { >> - ret = property_enable(rphy, &rphy->phy_cfg->clkout_ctl, true); >> + if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) { >> + ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true); >> if (ret) >> return ret; >> >> @@ -277,17 +286,19 @@ static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw) >> { >> struct rockchip_usb2phy *rphy = >> container_of(hw, struct rockchip_usb2phy, clk480m_hw); >> + struct regmap *base = get_reg_base(rphy); >> >> /* turn off 480m clk output */ >> - property_enable(rphy, &rphy->phy_cfg->clkout_ctl, false); >> + property_enable(base, &rphy->phy_cfg->clkout_ctl, false); >> } >> >> static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw) >> { >> struct rockchip_usb2phy *rphy = >> container_of(hw, struct rockchip_usb2phy, clk480m_hw); >> + struct regmap *base = get_reg_base(rphy); >> >> - return property_enabled(rphy, &rphy->phy_cfg->clkout_ctl); >> + return property_enabled(base, &rphy->phy_cfg->clkout_ctl); >> } >> >> static unsigned long >> @@ -409,13 +420,13 @@ static int rockchip_usb2phy_init(struct phy *phy) >> if (rport->mode != USB_DR_MODE_HOST && >> rport->mode != USB_DR_MODE_UNKNOWN) { >> /* clear bvalid status and enable bvalid detect irq */ >> - ret = property_enable(rphy, >> + ret = property_enable(rphy->grf, >> &rport->port_cfg->bvalid_det_clr, >> true); >> if (ret) >> goto out; >> >> - ret = property_enable(rphy, >> + ret = property_enable(rphy->grf, >> &rport->port_cfg->bvalid_det_en, >> true); >> if (ret) >> @@ -429,11 +440,13 @@ static int rockchip_usb2phy_init(struct phy *phy) >> } >> } else if (rport->port_id == USB2PHY_PORT_HOST) { >> /* clear linestate and enable linestate detect irq */ >> - ret = property_enable(rphy, &rport->port_cfg->ls_det_clr, true); >> + ret = property_enable(rphy->grf, >> + &rport->port_cfg->ls_det_clr, true); >> if (ret) >> goto out; >> >> - ret = property_enable(rphy, &rport->port_cfg->ls_det_en, true); >> + ret = property_enable(rphy->grf, >> + &rport->port_cfg->ls_det_en, true); >> if (ret) >> goto out; >> >> @@ -449,6 +462,7 @@ static int rockchip_usb2phy_power_on(struct phy *phy) >> { >> struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); >> struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); >> + struct regmap *base = get_reg_base(rphy); >> int ret; >> >> dev_dbg(&rport->phy->dev, "port power on\n"); >> @@ -460,7 +474,7 @@ static int rockchip_usb2phy_power_on(struct phy *phy) >> if (ret) >> return ret; >> >> - ret = property_enable(rphy, &rport->port_cfg->phy_sus, false); >> + ret = property_enable(base, &rport->port_cfg->phy_sus, false); >> if (ret) >> return ret; >> >> @@ -475,6 +489,7 @@ static int rockchip_usb2phy_power_off(struct phy *phy) >> { >> struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); >> struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); >> + struct regmap *base = get_reg_base(rphy); >> int ret; >> >> dev_dbg(&rport->phy->dev, "port power off\n"); >> @@ -482,7 +497,7 @@ static int rockchip_usb2phy_power_off(struct phy *phy) >> if (rport->suspended) >> return 0; >> >> - ret = property_enable(rphy, &rport->port_cfg->phy_sus, true); >> + ret = property_enable(base, &rport->port_cfg->phy_sus, true); >> if (ret) >> return ret; >> >> @@ -526,11 +541,11 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work) >> bool vbus_attach, sch_work, notify_charger; >> >> if (rport->utmi_avalid) >> - vbus_attach = >> - property_enabled(rphy, &rport->port_cfg->utmi_avalid); >> + vbus_attach = property_enabled(rphy->grf, >> + &rport->port_cfg->utmi_avalid); >> else >> - vbus_attach = >> - property_enabled(rphy, &rport->port_cfg->utmi_bvalid); >> + vbus_attach = property_enabled(rphy->grf, >> + &rport->port_cfg->utmi_bvalid); >> >> sch_work = false; >> notify_charger = false; >> @@ -650,22 +665,28 @@ static const char *chg_to_string(enum power_supply_type chg_type) >> static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy, >> bool en) >> { >> - property_enable(rphy, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en); >> - property_enable(rphy, &rphy->phy_cfg->chg_det.idp_src_en, en); >> + struct regmap *base = get_reg_base(rphy); >> + >> + property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en); >> + property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en); >> } >> >> static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy, >> bool en) >> { >> - property_enable(rphy, &rphy->phy_cfg->chg_det.vdp_src_en, en); >> - property_enable(rphy, &rphy->phy_cfg->chg_det.idm_sink_en, en); >> + struct regmap *base = get_reg_base(rphy); >> + >> + property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en); >> + property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en); >> } >> >> static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy, >> bool en) >> { >> - property_enable(rphy, &rphy->phy_cfg->chg_det.vdm_src_en, en); >> - property_enable(rphy, &rphy->phy_cfg->chg_det.idp_sink_en, en); >> + struct regmap *base = get_reg_base(rphy); >> + >> + property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en); >> + property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en); >> } >> >> #define CHG_DCD_POLL_TIME (100 * HZ / 1000) >> @@ -677,6 +698,7 @@ static void rockchip_chg_detect_work(struct work_struct *work) >> struct rockchip_usb2phy_port *rport = >> container_of(work, struct rockchip_usb2phy_port, chg_work.work); >> struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); >> + struct regmap *base = get_reg_base(rphy); >> bool is_dcd, tmout, vout; >> unsigned long delay; >> >> @@ -687,7 +709,7 @@ static void rockchip_chg_detect_work(struct work_struct *work) >> if (!rport->suspended) >> rockchip_usb2phy_power_off(rport->phy); >> /* put the controller in non-driving mode */ >> - property_enable(rphy, &rphy->phy_cfg->chg_det.opmode, false); >> + property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); >> /* Start DCD processing stage 1 */ >> rockchip_chg_enable_dcd(rphy, true); >> rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD; >> @@ -696,7 +718,8 @@ static void rockchip_chg_detect_work(struct work_struct *work) >> break; >> case USB_CHG_STATE_WAIT_FOR_DCD: >> /* get data contact detection status */ >> - is_dcd = property_enabled(rphy, &rphy->phy_cfg->chg_det.dp_det); >> + is_dcd = property_enabled(rphy->grf, >> + &rphy->phy_cfg->chg_det.dp_det); >> tmout = ++rphy->dcd_retries == CHG_DCD_MAX_RETRIES; >> /* stage 2 */ >> if (is_dcd || tmout) { >> @@ -713,7 +736,8 @@ static void rockchip_chg_detect_work(struct work_struct *work) >> } >> break; >> case USB_CHG_STATE_DCD_DONE: >> - vout = property_enabled(rphy, &rphy->phy_cfg->chg_det.cp_det); >> + vout = property_enabled(rphy->grf, >> + &rphy->phy_cfg->chg_det.cp_det); >> rockchip_chg_enable_primary_det(rphy, false); >> if (vout) { >> /* Voltage Source on DM, Probe on DP */ >> @@ -734,7 +758,8 @@ static void rockchip_chg_detect_work(struct work_struct *work) >> } >> break; >> case USB_CHG_STATE_PRIMARY_DONE: >> - vout = property_enabled(rphy, &rphy->phy_cfg->chg_det.dcp_det); >> + vout = property_enabled(rphy->grf, >> + &rphy->phy_cfg->chg_det.dcp_det); >> /* Turn off voltage source */ >> rockchip_chg_enable_secondary_det(rphy, false); >> if (vout) >> @@ -748,7 +773,7 @@ static void rockchip_chg_detect_work(struct work_struct *work) >> /* fall through */ >> case USB_CHG_STATE_DETECTED: >> /* put the controller in normal mode */ >> - property_enable(rphy, &rphy->phy_cfg->chg_det.opmode, true); >> + property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); >> rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work); >> dev_info(&rport->phy->dev, "charger = %s\n", >> chg_to_string(rphy->chg_type)); >> @@ -790,8 +815,7 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work) >> if (ret < 0) >> goto next_schedule; >> >> - ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, >> - &uhd); >> + ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd); >> if (ret < 0) >> goto next_schedule; >> >> @@ -845,8 +869,8 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work) >> * activate the linestate detection to get the next device >> * plug-in irq. >> */ >> - property_enable(rphy, &rport->port_cfg->ls_det_clr, true); >> - property_enable(rphy, &rport->port_cfg->ls_det_en, true); >> + property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true); >> + property_enable(rphy->grf, &rport->port_cfg->ls_det_en, true); >> >> /* >> * we don't need to rearm the delayed work when the phy port >> @@ -869,14 +893,14 @@ static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data) >> struct rockchip_usb2phy_port *rport = data; >> struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); >> >> - if (!property_enabled(rphy, &rport->port_cfg->ls_det_st)) >> + if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st)) >> return IRQ_NONE; >> >> mutex_lock(&rport->mutex); >> >> /* disable linestate detect irq and clear its status */ >> - property_enable(rphy, &rport->port_cfg->ls_det_en, false); >> - property_enable(rphy, &rport->port_cfg->ls_det_clr, true); >> + property_enable(rphy->grf, &rport->port_cfg->ls_det_en, false); >> + property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true); >> >> mutex_unlock(&rport->mutex); >> >> @@ -896,13 +920,13 @@ static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data) >> struct rockchip_usb2phy_port *rport = data; >> struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); >> >> - if (!property_enabled(rphy, &rport->port_cfg->bvalid_det_st)) >> + if (!property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st)) >> return IRQ_NONE; >> >> mutex_lock(&rport->mutex); >> >> /* clear bvalid detect irq pending status */ >> - property_enable(rphy, &rport->port_cfg->bvalid_det_clr, true); >> + property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true); >> >> mutex_unlock(&rport->mutex); >> >> @@ -1045,6 +1069,18 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) >> if (IS_ERR(rphy->grf)) >> return PTR_ERR(rphy->grf); >> >> + rphy->companion_grf_quirk = >> + device_property_read_bool(dev, "rockchip,companion_grf_quirk"); >> + if (rphy->companion_grf_quirk) { >> + rphy->usbgrf = >> + syscon_regmap_lookup_by_phandle(dev->of_node, >> + "rockchip,usbgrf"); >> + if (IS_ERR(rphy->usbgrf)) >> + return PTR_ERR(rphy->usbgrf); >> + } else { >> + rphy->usbgrf = NULL; >> + } >> + >> if (of_property_read_u32(np, "reg", ®)) { >> dev_err(dev, "the reg property is not assigned in %s node\n", >> np->name); >> > >
diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt index 84d59b0..ddf868a 100644 --- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt @@ -18,6 +18,10 @@ Optional properties: usb-phy output 480m and xin24m. Refer to clk/clock-bindings.txt for generic clock consumer properties. + - rockchip,usbgrf : phandle to the syscon managing the "usb general + register files". + - rockchip,companion_grf_quirk : when set driver will request + "rockchip,usbgrf" phandle as one companion-grf. Required nodes : a sub-node is required for each port the phy provides. The sub-node name is used to identify host or otg port, diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 626883d..669e5f6 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -202,6 +202,7 @@ struct rockchip_usb2phy_port { /** * struct rockchip_usb2phy: usb2.0 phy driver data. * @grf: General Register Files regmap. + * @usbgrf: USB General Register Files regmap. * @clk: clock struct of phy input clk. * @clk480m: clock struct of phy output clk. * @clk_hw: clock struct of phy output clk management. @@ -216,6 +217,7 @@ struct rockchip_usb2phy_port { struct rockchip_usb2phy { struct device *dev; struct regmap *grf; + struct regmap *usbgrf; struct clk *clk; struct clk *clk480m; struct clk_hw clk480m_hw; @@ -225,9 +227,15 @@ struct rockchip_usb2phy { struct extcon_dev *edev; const struct rockchip_usb2phy_cfg *phy_cfg; struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS]; + unsigned int companion_grf_quirk:1; }; -static inline int property_enable(struct rockchip_usb2phy *rphy, +static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy) +{ + return rphy->companion_grf_quirk ? rphy->usbgrf : rphy->grf; +} + +static inline int property_enable(struct regmap *base, const struct usb2phy_reg *reg, bool en) { unsigned int val, mask, tmp; @@ -236,17 +244,17 @@ static inline int property_enable(struct rockchip_usb2phy *rphy, mask = GENMASK(reg->bitend, reg->bitstart); val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); - return regmap_write(rphy->grf, reg->offset, val); + return regmap_write(base, reg->offset, val); } -static inline bool property_enabled(struct rockchip_usb2phy *rphy, +static inline bool property_enabled(struct regmap *base, const struct usb2phy_reg *reg) { int ret; unsigned int tmp, orig; unsigned int mask = GENMASK(reg->bitend, reg->bitstart); - ret = regmap_read(rphy->grf, reg->offset, &orig); + ret = regmap_read(base, reg->offset, &orig); if (ret) return false; @@ -258,11 +266,12 @@ static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw) { struct rockchip_usb2phy *rphy = container_of(hw, struct rockchip_usb2phy, clk480m_hw); + struct regmap *base = get_reg_base(rphy); int ret; /* turn on 480m clk output if it is off */ - if (!property_enabled(rphy, &rphy->phy_cfg->clkout_ctl)) { - ret = property_enable(rphy, &rphy->phy_cfg->clkout_ctl, true); + if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) { + ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true); if (ret) return ret; @@ -277,17 +286,19 @@ static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw) { struct rockchip_usb2phy *rphy = container_of(hw, struct rockchip_usb2phy, clk480m_hw); + struct regmap *base = get_reg_base(rphy); /* turn off 480m clk output */ - property_enable(rphy, &rphy->phy_cfg->clkout_ctl, false); + property_enable(base, &rphy->phy_cfg->clkout_ctl, false); } static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw) { struct rockchip_usb2phy *rphy = container_of(hw, struct rockchip_usb2phy, clk480m_hw); + struct regmap *base = get_reg_base(rphy); - return property_enabled(rphy, &rphy->phy_cfg->clkout_ctl); + return property_enabled(base, &rphy->phy_cfg->clkout_ctl); } static unsigned long @@ -409,13 +420,13 @@ static int rockchip_usb2phy_init(struct phy *phy) if (rport->mode != USB_DR_MODE_HOST && rport->mode != USB_DR_MODE_UNKNOWN) { /* clear bvalid status and enable bvalid detect irq */ - ret = property_enable(rphy, + ret = property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true); if (ret) goto out; - ret = property_enable(rphy, + ret = property_enable(rphy->grf, &rport->port_cfg->bvalid_det_en, true); if (ret) @@ -429,11 +440,13 @@ static int rockchip_usb2phy_init(struct phy *phy) } } else if (rport->port_id == USB2PHY_PORT_HOST) { /* clear linestate and enable linestate detect irq */ - ret = property_enable(rphy, &rport->port_cfg->ls_det_clr, true); + ret = property_enable(rphy->grf, + &rport->port_cfg->ls_det_clr, true); if (ret) goto out; - ret = property_enable(rphy, &rport->port_cfg->ls_det_en, true); + ret = property_enable(rphy->grf, + &rport->port_cfg->ls_det_en, true); if (ret) goto out; @@ -449,6 +462,7 @@ static int rockchip_usb2phy_power_on(struct phy *phy) { struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); + struct regmap *base = get_reg_base(rphy); int ret; dev_dbg(&rport->phy->dev, "port power on\n"); @@ -460,7 +474,7 @@ static int rockchip_usb2phy_power_on(struct phy *phy) if (ret) return ret; - ret = property_enable(rphy, &rport->port_cfg->phy_sus, false); + ret = property_enable(base, &rport->port_cfg->phy_sus, false); if (ret) return ret; @@ -475,6 +489,7 @@ static int rockchip_usb2phy_power_off(struct phy *phy) { struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); + struct regmap *base = get_reg_base(rphy); int ret; dev_dbg(&rport->phy->dev, "port power off\n"); @@ -482,7 +497,7 @@ static int rockchip_usb2phy_power_off(struct phy *phy) if (rport->suspended) return 0; - ret = property_enable(rphy, &rport->port_cfg->phy_sus, true); + ret = property_enable(base, &rport->port_cfg->phy_sus, true); if (ret) return ret; @@ -526,11 +541,11 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work) bool vbus_attach, sch_work, notify_charger; if (rport->utmi_avalid) - vbus_attach = - property_enabled(rphy, &rport->port_cfg->utmi_avalid); + vbus_attach = property_enabled(rphy->grf, + &rport->port_cfg->utmi_avalid); else - vbus_attach = - property_enabled(rphy, &rport->port_cfg->utmi_bvalid); + vbus_attach = property_enabled(rphy->grf, + &rport->port_cfg->utmi_bvalid); sch_work = false; notify_charger = false; @@ -650,22 +665,28 @@ static const char *chg_to_string(enum power_supply_type chg_type) static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy, bool en) { - property_enable(rphy, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en); - property_enable(rphy, &rphy->phy_cfg->chg_det.idp_src_en, en); + struct regmap *base = get_reg_base(rphy); + + property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en); + property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en); } static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy, bool en) { - property_enable(rphy, &rphy->phy_cfg->chg_det.vdp_src_en, en); - property_enable(rphy, &rphy->phy_cfg->chg_det.idm_sink_en, en); + struct regmap *base = get_reg_base(rphy); + + property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en); + property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en); } static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy, bool en) { - property_enable(rphy, &rphy->phy_cfg->chg_det.vdm_src_en, en); - property_enable(rphy, &rphy->phy_cfg->chg_det.idp_sink_en, en); + struct regmap *base = get_reg_base(rphy); + + property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en); + property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en); } #define CHG_DCD_POLL_TIME (100 * HZ / 1000) @@ -677,6 +698,7 @@ static void rockchip_chg_detect_work(struct work_struct *work) struct rockchip_usb2phy_port *rport = container_of(work, struct rockchip_usb2phy_port, chg_work.work); struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); + struct regmap *base = get_reg_base(rphy); bool is_dcd, tmout, vout; unsigned long delay; @@ -687,7 +709,7 @@ static void rockchip_chg_detect_work(struct work_struct *work) if (!rport->suspended) rockchip_usb2phy_power_off(rport->phy); /* put the controller in non-driving mode */ - property_enable(rphy, &rphy->phy_cfg->chg_det.opmode, false); + property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); /* Start DCD processing stage 1 */ rockchip_chg_enable_dcd(rphy, true); rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD; @@ -696,7 +718,8 @@ static void rockchip_chg_detect_work(struct work_struct *work) break; case USB_CHG_STATE_WAIT_FOR_DCD: /* get data contact detection status */ - is_dcd = property_enabled(rphy, &rphy->phy_cfg->chg_det.dp_det); + is_dcd = property_enabled(rphy->grf, + &rphy->phy_cfg->chg_det.dp_det); tmout = ++rphy->dcd_retries == CHG_DCD_MAX_RETRIES; /* stage 2 */ if (is_dcd || tmout) { @@ -713,7 +736,8 @@ static void rockchip_chg_detect_work(struct work_struct *work) } break; case USB_CHG_STATE_DCD_DONE: - vout = property_enabled(rphy, &rphy->phy_cfg->chg_det.cp_det); + vout = property_enabled(rphy->grf, + &rphy->phy_cfg->chg_det.cp_det); rockchip_chg_enable_primary_det(rphy, false); if (vout) { /* Voltage Source on DM, Probe on DP */ @@ -734,7 +758,8 @@ static void rockchip_chg_detect_work(struct work_struct *work) } break; case USB_CHG_STATE_PRIMARY_DONE: - vout = property_enabled(rphy, &rphy->phy_cfg->chg_det.dcp_det); + vout = property_enabled(rphy->grf, + &rphy->phy_cfg->chg_det.dcp_det); /* Turn off voltage source */ rockchip_chg_enable_secondary_det(rphy, false); if (vout) @@ -748,7 +773,7 @@ static void rockchip_chg_detect_work(struct work_struct *work) /* fall through */ case USB_CHG_STATE_DETECTED: /* put the controller in normal mode */ - property_enable(rphy, &rphy->phy_cfg->chg_det.opmode, true); + property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work); dev_info(&rport->phy->dev, "charger = %s\n", chg_to_string(rphy->chg_type)); @@ -790,8 +815,7 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work) if (ret < 0) goto next_schedule; - ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, - &uhd); + ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd); if (ret < 0) goto next_schedule; @@ -845,8 +869,8 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work) * activate the linestate detection to get the next device * plug-in irq. */ - property_enable(rphy, &rport->port_cfg->ls_det_clr, true); - property_enable(rphy, &rport->port_cfg->ls_det_en, true); + property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true); + property_enable(rphy->grf, &rport->port_cfg->ls_det_en, true); /* * we don't need to rearm the delayed work when the phy port @@ -869,14 +893,14 @@ static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data) struct rockchip_usb2phy_port *rport = data; struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); - if (!property_enabled(rphy, &rport->port_cfg->ls_det_st)) + if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st)) return IRQ_NONE; mutex_lock(&rport->mutex); /* disable linestate detect irq and clear its status */ - property_enable(rphy, &rport->port_cfg->ls_det_en, false); - property_enable(rphy, &rport->port_cfg->ls_det_clr, true); + property_enable(rphy->grf, &rport->port_cfg->ls_det_en, false); + property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true); mutex_unlock(&rport->mutex); @@ -896,13 +920,13 @@ static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data) struct rockchip_usb2phy_port *rport = data; struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); - if (!property_enabled(rphy, &rport->port_cfg->bvalid_det_st)) + if (!property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st)) return IRQ_NONE; mutex_lock(&rport->mutex); /* clear bvalid detect irq pending status */ - property_enable(rphy, &rport->port_cfg->bvalid_det_clr, true); + property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true); mutex_unlock(&rport->mutex); @@ -1045,6 +1069,18 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) if (IS_ERR(rphy->grf)) return PTR_ERR(rphy->grf); + rphy->companion_grf_quirk = + device_property_read_bool(dev, "rockchip,companion_grf_quirk"); + if (rphy->companion_grf_quirk) { + rphy->usbgrf = + syscon_regmap_lookup_by_phandle(dev->of_node, + "rockchip,usbgrf"); + if (IS_ERR(rphy->usbgrf)) + return PTR_ERR(rphy->usbgrf); + } else { + rphy->usbgrf = NULL; + } + if (of_property_read_u32(np, "reg", ®)) { dev_err(dev, "the reg property is not assigned in %s node\n", np->name);
The registers of usb-phy are distributed in grf and usbgrf on some Rockchip SoCs (e.g RV1108), this patch add a quirk to support this companion grf design. Signed-off-by: Frank Wang <frank.wang@rock-chips.com> --- .../bindings/phy/phy-rockchip-inno-usb2.txt | 4 + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 112 ++++++++++++++------- 2 files changed, 78 insertions(+), 38 deletions(-)