Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751696AbdHBGui (ORCPT ); Wed, 2 Aug 2017 02:50:38 -0400 Received: from regular1.263xmail.com ([211.150.99.137]:44657 "EHLO regular1.263xmail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751073AbdHBGuh (ORCPT ); Wed, 2 Aug 2017 02:50:37 -0400 X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ABS-CHECKED: 4 X-RL-SENDER: frank.wang@rock-chips.com X-FST-TO: wmc@rock-chips.com X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: frank.wang@rock-chips.com X-UNIQUE-TAG: <7ce0a594337c5a9d1c352c249ed57d5d> X-ATTACHMENT-NUM: 0 X-DNS-TYPE: 0 Subject: Re: [PATCH 1/3] phy: rockchip-inno-usb2: add companion grf quirk To: Kishon Vijay Abraham I Cc: heiko@sntech.de, gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, huangtao@rock-chips.com, william.wu@rock-chips.com, daniel.meng@rock-chips.com, kever.yang@rock-chips.com, andy.yan@rock-chips.com, wmc@rock-chips.com References: <1501575133-20953-1-git-send-email-frank.wang@rock-chips.com> <1501575133-20953-2-git-send-email-frank.wang@rock-chips.com> From: Frank Wang Message-ID: Date: Wed, 2 Aug 2017 14:50:04 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Content-Language: en-US Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 15559 Lines: 387 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 >> --- >> .../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); >> > >