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.w...@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", &reg)) {
>               dev_err(dev, "the reg property is not assigned in %s node\n",
>                       np->name);
> 

Reply via email to