Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1431357 > unrolled thread

[PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support

Started byStephen Boyd <stephen.boyd@linaro.org>
First post2016-06-26 09:30 +0200
Last post2016-07-05 21:40 +0200
Articles 20 on this page of 62 — 9 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:30 +0200
    [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:30 +0200
      Re: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy Peter Chen <hzpeterchen@gmail.com> - 2016-06-29 09:00 +0200
        Re: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy Peter Chen <hzpeterchen@gmail.com> - 2016-06-29 13:50 +0200
          Re: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy Peter Chen <hzpeterchen@gmail.com> - 2016-06-30 04:00 +0200
    [PATCH 09/21] usb: chipidea: Add support for ULPI PHY bus Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 09/21] usb: chipidea: Add support for ULPI PHY bus Peter Chen <hzpeterchen@gmail.com> - 2016-06-29 08:40 +0200
    [PATCH 14/21] usb: chipidea: msm: Add proper clk and reset support Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 14/21] usb: chipidea: msm: Add proper clk and reset  support Peter Chen <hzpeterchen@gmail.com> - 2016-06-29 09:10 +0200
    [PATCH 07/21] usb: chipidea: Notify of reset when switching into host mode Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
    [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy  later Peter Chen <hzpeterchen@gmail.com> - 2016-06-29 04:40 +0200
        Re: [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy  later Peter Chen <hzpeterchen@gmail.com> - 2016-06-30 03:30 +0200
    [PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors Peter Chen <hzpeterchen@gmail.com> - 2016-06-30 03:30 +0200
    [PATCH 03/21] usb: ulpi: Avoid reading/writing in device creation with OF devices Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
    [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy Neil Armstrong <narmstrong@baylibre.com> - 2016-06-28 10:50 +0200
        Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-29 00:10 +0200
          Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy Neil Armstrong <narmstrong@baylibre.com> - 2016-06-29 11:20 +0200
            Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-29 21:00 +0200
    [PATCH 05/21] usb: chipidea: Handle extcon events properly Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 05/21] usb: chipidea: Handle extcon events properly Peter Chen <hzpeterchen@gmail.com> - 2016-06-28 12:10 +0200
    [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS  with vbus extcon Peter Chen <hzpeterchen@gmail.com> - 2016-06-29 05:20 +0200
        Re: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS  with vbus extcon Peter Chen <hzpeterchen@gmail.com> - 2016-06-30 03:40 +0200
          RE: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS  with vbus extcon Jun Li <jun.li@nxp.com> - 2016-06-30 04:10 +0200
    [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY  POR bit kbuild test robot <lkp@intel.com> - 2016-06-27 05:50 +0200
      Re: [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY  POR bit kbuild test robot <lkp@intel.com> - 2016-06-27 07:00 +0200
      Re: [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY  POR bit kbuild test robot <lkp@intel.com> - 2016-06-27 10:00 +0200
      Re: [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY  POR bit Peter Chen <hzpeterchen@gmail.com> - 2016-06-29 14:00 +0200
    [PATCH 02/21] usb: ulpi: Support device discovery via DT Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT kbuild test robot <lkp@intel.com> - 2016-06-27 06:20 +0200
      Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT Heikki Krogerus <heikki.krogerus@linux.intel.com> - 2016-06-27 16:40 +0200
        Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT Heikki Krogerus <heikki.krogerus@linux.intel.com> - 2016-06-28 13:50 +0200
          Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT Peter Chen <hzpeterchen@gmail.com> - 2016-06-29 04:10 +0200
      Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT Rob Herring <robh@kernel.org> - 2016-06-28 23:00 +0200
        Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT Rob Herring <robh@kernel.org> - 2016-07-01 03:10 +0200
    [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the  right time Bjorn Andersson <bjorn.andersson@linaro.org> - 2016-06-28 07:00 +0200
      Re: [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the  right time Peter Chen <hzpeterchen@gmail.com> - 2016-06-29 10:20 +0200
        Re: [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the  right time Peter Chen <hzpeterchen@gmail.com> - 2016-06-30 04:00 +0200
    [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after  reset Peter Chen <hzpeterchen@gmail.com> - 2016-06-29 10:40 +0200
        Re: [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after  reset Peter Chen <hzpeterchen@gmail.com> - 2016-06-30 11:10 +0200
          Re: [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-30 18:30 +0200
    [PATCH 11/21] usb: chipidea: msm: Use hw_write_id_reg() instead of writel directly Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 11/21] usb: chipidea: msm: Use hw_write_id_reg() instead  of writel directly Peter Chen <hzpeterchen@gmail.com> - 2016-06-29 08:50 +0200
    [PATCH 21/21] phy: Add support for Qualcomm's USB HS phy Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
    [PATCH 17/21] usb: chipidea: msm: Make platform data driver local instead of global Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 17/21] usb: chipidea: msm: Make platform data driver  local instead of global Peter Chen <hzpeterchen@gmail.com> - 2016-06-29 13:40 +0200
        Re: [PATCH 17/21] usb: chipidea: msm: Make platform data driver  local instead of global Peter Chen <hzpeterchen@gmail.com> - 2016-06-30 11:20 +0200
    [PATCH 01/21] of: device: Support loading a module with OF based modalias Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      Re: [PATCH 01/21] of: device: Support loading a module with OF based  modalias Bjorn Andersson <bjorn.andersson@linaro.org> - 2016-06-28 06:20 +0200
    [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-26 09:40 +0200
      RE: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place Jun Li <jun.li@nxp.com> - 2016-06-27 10:10 +0200
        RE: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place Stephen Boyd <stephen.boyd@linaro.org> - 2016-06-27 21:10 +0200
          Re: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place Peter Chen <hzpeterchen@gmail.com> - 2016-06-28 11:50 +0200
    Re: [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support John Stultz <john.stultz@linaro.org> - 2016-06-28 05:10 +0200
      Re: [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support John Stultz <john.stultz@linaro.org> - 2016-07-02 08:10 +0200
        Re: [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support John Stultz <john.stultz@linaro.org> - 2016-07-05 21:40 +0200

Page 1 of 4  [1] 2 3 4  Next page →


#1431357 — [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support

FromStephen Boyd <stephen.boyd@linaro.org>
Date2016-06-26 09:30 +0200
Subject[PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
Message-ID<rOcFX-8ei-3@gated-at.bofh.it>
The state of USB ChipIdea support on Qualcomm's platforms is not great.
The DT description of these devices requires up to three different nodes
for what amounts to be the same hardware block, when there should really
only be one. Furthermore, the "phy" driver that is in mainline (phy-msm-usb.c)
duplicates the OTG state machine and touches the ci controller wrapper
registers when it should really be focused on the phy and the ULPI accesses
needed to get the phy working. There's also a slimmed down phy driver for
the msm8916 platform, but really the phy hardware is the same as other MSMs,
so we have two drivers doing pretty much the same thing. This leads to a
situtaion where we have the chipidea core driver, the "phy" driver, and
sometimes the ehci-msm.c driver operating the same device all at the same
time with very little coordination. This just isn't very safe and is
confusing from a driver perspective when trying to figure out who does what.
Finally, there isn't any HSIC support on platforms like apq8074 so we
should add that.

This patch series updates the ChipIdea driver and the MSM wrapper
(ci_hdrc_msm.c) to properly handle the PHY and wrapper bits at the right
times in the right places. To get there, we update the ChipIdea core to
have support for the ULPI phy bus introduced by Heikki. Along the way
we fix bugs with the extcon handling for peripheral and OTG mode controllers
and move the parts of phy-usb-msm.c that are touching the CI controller
wrapper into the wrapper driver (ci_hdrc_msm.c). Finally we add support
for the HSIC phy based on the ULPI bus and rewrite the HS phy driver
(phy-usb-msm.c) as a standard ULPI phy driver.

Once this series is accepted, we should be able to delete the phy-usb-msm.c
phy-qcom-8x16-usb.c, and ehci-msm.c drivers from the tree and use the ULPI
based phy driver (which also lives in drivers/phy/ instead of drivers/usb/phy/)
and the chipidea host core instead.

I've also sent seperate patches for other minor pieces to make this
all work. The full tree can be found here[3], hacks and all to get
things working. I've tested this on the db410c, apq8074 dragonboard,
and ifc6410 with configfs gadgets and otg cables.

TODO:
 * DMA fails on arm64 so we need something like [1] to make it work.

 * The HSIC phy on the apq8074 dragonboard is connected to a usb4604
   device which requires the i2c driver to probe and send an i2c
   sequence before the HSIC controller enumerates or HSIC doesn't work.
   Right now I have a hack to force the controller to probe defer
   once so that usb4604 probes first. This needs a more proper solution
   like having the DT describe a linkage between the controller and
   the usb device so we can enforce probe ordering.
 
 * OTG support requires a working VBUS supply on apq8074 dragonboard
   and that requires changes to the smbb_charger driver to support
   the OTG OVP switch as a regulator[2]. This series needs revival.

 * Sleeping while atomic problems exist when trying to do phy operations
   underneath some spinlocks in the ci core. I have a patch to remove a
   spinlock, but that needs more thought if it's correct. At the least
   it's necessary though because of how we need to initialize the HSIC
   phy after the reset bit is toggled in USBCMD.

[1] https://lkml.org/lkml/2016/2/22/7
[2] http://lkml.kernel.org/g/1449621618-11900-1-git-send-email-tim.bird@sonymobile.com
[3] https://git.linaro.org/people/stephen.boyd/linux.git/shortlog/refs/heads/usb-hsic-8074

Stephen Boyd (21):
  of: device: Support loading a module with OF based modalias
  usb: ulpi: Support device discovery via DT
  usb: ulpi: Avoid reading/writing in device creation with OF devices
  usb: chipidea: Only read/write OTGSC from one place
  usb: chipidea: Handle extcon events properly
  usb: chipidea: Initialize and reinitialize phy later
  usb: chipidea: Notify of reset when switching into host mode
  usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
  usb: chipidea: Add support for ULPI PHY bus
  usb: chipidea: msm: Rely on core to override AHBBURST
  usb: chipidea: msm: Use hw_write_id_reg() instead of writel directly
  usb: chipidea: msm: Keep device runtime enabled
  usb: chipidea: msm: Allow core to get usb phy
  usb: chipidea: msm: Add proper clk and reset support
  usb: chipidea: msm: Mux over secondary phy at the right time
  usb: chipidea: msm: Restore wrapper settings after reset
  usb: chipidea: msm: Make platform data driver local instead of global
  usb: chipidea: msm: Add reset controller for PHY POR bit
  usb: chipidea: msm: Be silent on probe defer errors
  phy: Add support for Qualcomm's USB HSIC phy
  phy: Add support for Qualcomm's USB HS phy

 .../devicetree/bindings/phy/qcom,usb-hs-phy.txt    |  71 ++++++
 .../devicetree/bindings/phy/qcom,usb-hsic-phy.txt  |  60 +++++
 Documentation/devicetree/bindings/usb/ulpi.txt     |  20 ++
 drivers/of/device.c                                |  50 ++++
 drivers/phy/Kconfig                                |  15 ++
 drivers/phy/Makefile                               |   2 +
 drivers/phy/phy-qcom-usb-hs.c                      | 283 +++++++++++++++++++++
 drivers/phy/phy-qcom-usb-hsic.c                    | 161 ++++++++++++
 drivers/usb/chipidea/Kconfig                       |   7 +
 drivers/usb/chipidea/Makefile                      |   1 +
 drivers/usb/chipidea/ci.h                          |  23 +-
 drivers/usb/chipidea/ci_hdrc_msm.c                 | 264 ++++++++++++++++---
 drivers/usb/chipidea/core.c                        |  85 +++----
 drivers/usb/chipidea/host.c                        |   6 +-
 drivers/usb/chipidea/otg.c                         |  81 +++++-
 drivers/usb/chipidea/otg_fsm.c                     |  17 ++
 drivers/usb/chipidea/udc.c                         |   2 +
 drivers/usb/chipidea/ulpi.c                        | 113 ++++++++
 drivers/usb/common/ulpi.c                          |  92 +++++--
 include/linux/of_device.h                          |   6 +
 include/linux/usb/chipidea.h                       |   2 +
 21 files changed, 1238 insertions(+), 123 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
 create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
 create mode 100644 drivers/phy/phy-qcom-usb-hs.c
 create mode 100644 drivers/phy/phy-qcom-usb-hsic.c
 create mode 100644 drivers/usb/chipidea/ulpi.c

-- 
2.9.0.rc2.8.ga28705d

[toc] | [next] | [standalone]


#1431358 — [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy

FromStephen Boyd <stephen.boyd@linaro.org>
Date2016-06-26 09:30 +0200
Subject[PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
Message-ID<rOcFY-8ei-9@gated-at.bofh.it>
In reply to#1431357
The chipidea core gets the usb phy and initializes the phy at the
right point now so we don't need to get the phy in this driver.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 430856ef1be3..07cccd24a87f 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -24,15 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
 		/* use AHB transactor, allow posted data writes */
 		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
-		usb_phy_init(ci->usb_phy);
-		break;
-	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
-		dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
-		/*
-		 * Put the phy in non-driving mode. Otherwise host
-		 * may not detect soft-disconnection.
-		 */
-		usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN);
 		break;
 	default:
 		dev_dbg(dev, "unknown ci_hdrc event\n");
@@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 static int ci_hdrc_msm_probe(struct platform_device *pdev)
 {
 	struct platform_device *plat_ci;
-	struct usb_phy *phy;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
 
-	/*
-	 * OTG(PHY) driver takes care of PHY initialization, clock management,
-	 * powering up VBUS, mapping of registers address space and power
-	 * management.
-	 */
-	phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
-	if (IS_ERR(phy))
-		return PTR_ERR(phy);
-
-	ci_hdrc_msm_platdata.usb_phy = phy;
-
 	plat_ci = ci_hdrc_add_device(&pdev->dev,
 				pdev->resource, pdev->num_resources,
 				&ci_hdrc_msm_platdata);
-- 
2.9.0.rc2.8.ga28705d

[toc] | [prev] | [next] | [standalone]


#1433491 — Re: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy

FromPeter Chen <hzpeterchen@gmail.com>
Date2016-06-29 09:00 +0200
SubjectRe: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
Message-ID<rPhDA-QN-7@gated-at.bofh.it>
In reply to#1431358
On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
> The chipidea core gets the usb phy and initializes the phy at the
> right point now so we don't need to get the phy in this driver.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 21 ---------------------
>  1 file changed, 21 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 430856ef1be3..07cccd24a87f 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -24,15 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
>  		/* use AHB transactor, allow posted data writes */
>  		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> -		usb_phy_init(ci->usb_phy);
> -		break;
> -	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
> -		dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
> -		/*
> -		 * Put the phy in non-driving mode. Otherwise host
> -		 * may not detect soft-disconnection.
> -		 */
> -		usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN);
>  		break;
>  	default:
>  		dev_dbg(dev, "unknown ci_hdrc event\n");
> @@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
>  static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  {
>  	struct platform_device *plat_ci;
> -	struct usb_phy *phy;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
>  
> -	/*
> -	 * OTG(PHY) driver takes care of PHY initialization, clock management,
> -	 * powering up VBUS, mapping of registers address space and power
> -	 * management.
> -	 */
> -	phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
> -	if (IS_ERR(phy))
> -		return PTR_ERR(phy);
> -
> -	ci_hdrc_msm_platdata.usb_phy = phy;
> -
>  	plat_ci = ci_hdrc_add_device(&pdev->dev,
>  				pdev->resource, pdev->num_resources,
>  				&ci_hdrc_msm_platdata);
> -- 

Acked-by: Peter Chen <peter.chen@nxp.com>

-- 

Best Regards,
Peter Chen

[toc] | [prev] | [next] | [standalone]


#1433694 — Re: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy

FromPeter Chen <hzpeterchen@gmail.com>
Date2016-06-29 13:50 +0200
SubjectRe: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
Message-ID<rPmae-3Ff-7@gated-at.bofh.it>
In reply to#1433491
On Wed, Jun 29, 2016 at 02:48:11PM +0800, Peter Chen wrote:
> On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
> > The chipidea core gets the usb phy and initializes the phy at the
> > right point now so we don't need to get the phy in this driver.
> > 
> > Cc: Peter Chen <peter.chen@nxp.com>
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > ---
> >  drivers/usb/chipidea/ci_hdrc_msm.c | 21 ---------------------
> >  1 file changed, 21 deletions(-)
> > 
> > diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> > index 430856ef1be3..07cccd24a87f 100644
> > --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> > +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> > @@ -24,15 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
> >  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
> >  		/* use AHB transactor, allow posted data writes */
> >  		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> > -		usb_phy_init(ci->usb_phy);
> > -		break;
> > -	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
> > -		dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
> > -		/*
> > -		 * Put the phy in non-driving mode. Otherwise host
> > -		 * may not detect soft-disconnection.
> > -		 */
> > -		usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN);
> >  		break;
> >  	default:
> >  		dev_dbg(dev, "unknown ci_hdrc event\n");
> > @@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >  {
> >  	struct platform_device *plat_ci;
> > -	struct usb_phy *phy;
> >  
> >  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> >  
> > -	/*
> > -	 * OTG(PHY) driver takes care of PHY initialization, clock management,
> > -	 * powering up VBUS, mapping of registers address space and power
> > -	 * management.
> > -	 */
> > -	phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
> > -	if (IS_ERR(phy))
> > -		return PTR_ERR(phy);
> > -
> > -	ci_hdrc_msm_platdata.usb_phy = phy;
> > -
> >  	plat_ci = ci_hdrc_add_device(&pdev->dev,
> >  				pdev->resource, pdev->num_resources,
> >  				&ci_hdrc_msm_platdata);
> > -- 
> 

Wait, how about the UTMI PHY? You don't have a platform which needs
to get PHY through the phandle?

-- 

Best Regards,
Peter Chen

[toc] | [prev] | [next] | [standalone]


#1434154 — Re: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy

FromPeter Chen <hzpeterchen@gmail.com>
Date2016-06-30 04:00 +0200
SubjectRe: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
Message-ID<rPzqN-3jh-1@gated-at.bofh.it>
In reply to#1433694
On Wed, Jun 29, 2016 at 12:31:18PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-29 04:34:11)
> > On Wed, Jun 29, 2016 at 02:48:11PM +0800, Peter Chen wrote:
> > > On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
> > > > @@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> > > >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > > >  {
> > > >     struct platform_device *plat_ci;
> > > > -   struct usb_phy *phy;
> > > >  
> > > >     dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> > > >  
> > > > -   /*
> > > > -    * OTG(PHY) driver takes care of PHY initialization, clock management,
> > > > -    * powering up VBUS, mapping of registers address space and power
> > > > -    * management.
> > > > -    */
> > > > -   phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
> > > > -   if (IS_ERR(phy))
> > > > -           return PTR_ERR(phy);
> > > > -
> > > > -   ci_hdrc_msm_platdata.usb_phy = phy;
> > > > -
> > > >     plat_ci = ci_hdrc_add_device(&pdev->dev,
> > > >                             pdev->resource, pdev->num_resources,
> > > >                             &ci_hdrc_msm_platdata);
> > > > -- 
> > > 
> > 
> > Wait, how about the UTMI PHY? You don't have a platform which needs
> > to get PHY through the phandle?
> 
> Sorry I don't understand the question. What is the UTMI PHY? We need to
> get the phy through phandles. The only boards that are using ci_hdrc_msm
> are DT enabled boards.

UTMI PHY is the PHY inside the SoC, I just want to confirm all your PHYs
are at ulpi bus, if they are, you can do that, else, you may need above
way to get the PHY through PHY node.

-- 

Best Regards,
Peter Chen

[toc] | [prev] | [next] | [standalone]


#1431359 — [PATCH 09/21] usb: chipidea: Add support for ULPI PHY bus

FromStephen Boyd <stephen.boyd@linaro.org>
Date2016-06-26 09:40 +0200
Subject[PATCH 09/21] usb: chipidea: Add support for ULPI PHY bus
Message-ID<rOcPD-8ip-1@gated-at.bofh.it>
In reply to#1431357
Some phys for the chipidea controller are controlled via the ULPI
viewport. Add support for the ULPI bus so that these sorts of
phys can be probed and read/written automatically without having
to duplicate the viewport logic in each phy driver.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/Kconfig  |   7 +++
 drivers/usb/chipidea/Makefile |   1 +
 drivers/usb/chipidea/ci.h     |  20 ++++++++
 drivers/usb/chipidea/core.c   |  30 ++++++++---
 drivers/usb/chipidea/ulpi.c   | 113 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 165 insertions(+), 6 deletions(-)
 create mode 100644 drivers/usb/chipidea/ulpi.c

diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig
index 3644a3500b70..4f8c342a8865 100644
--- a/drivers/usb/chipidea/Kconfig
+++ b/drivers/usb/chipidea/Kconfig
@@ -37,4 +37,11 @@ config USB_CHIPIDEA_HOST
 	  Say Y here to enable host controller functionality of the
 	  ChipIdea driver.
 
+config USB_CHIPIDEA_ULPI
+	bool "ChipIdea ULPI PHY support"
+	depends on USB_ULPI_BUS=y || USB_ULPI_BUS=USB_CHIPIDEA
+	help
+	  Say Y here if you have a ULPI PHY attached to your ChipIdea
+	  controller.
+
 endif
diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
index 518e445476c3..39fca5715ed3 100644
--- a/drivers/usb/chipidea/Makefile
+++ b/drivers/usb/chipidea/Makefile
@@ -4,6 +4,7 @@ ci_hdrc-y				:= core.o otg.o debug.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC)	+= udc.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST)	+= host.o
 ci_hdrc-$(CONFIG_USB_OTG_FSM)		+= otg_fsm.o
+ci_hdrc-$(CONFIG_USB_CHIPIDEA_ULPI)	+= ulpi.o
 
 # Glue/Bridge layers go here
 
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index f87805235caa..14aa20525547 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -18,6 +18,8 @@
 #include <linux/usb.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/otg-fsm.h>
+#include <linux/usb/otg.h>
+#include <linux/ulpi/interface.h>
 
 /******************************************************************************
  * DEFINE
@@ -52,6 +54,7 @@ enum ci_hw_regs {
 	OP_ENDPTLISTADDR,
 	OP_TTCTRL,
 	OP_BURSTSIZE,
+	OP_ULPI_VIEWPORT,
 	OP_PORTSC,
 	OP_DEVLC,
 	OP_OTGSC,
@@ -187,6 +190,7 @@ struct hw_bank {
  * @test_mode: the selected test mode
  * @platdata: platform specific information supplied by parent device
  * @vbus_active: is VBUS active
+ * @ulpi: pointer to ULPI device, if any
  * @phy: pointer to PHY, if any
  * @usb_phy: pointer to USB PHY, if any and if using the USB PHY framework
  * @hcd: pointer to usb_hcd for ehci host driver
@@ -236,6 +240,10 @@ struct ci_hdrc {
 
 	struct ci_hdrc_platform_data	*platdata;
 	int				vbus_active;
+#ifdef CONFIG_USB_CHIPIDEA_ULPI
+	struct ulpi			*ulpi;
+	struct ulpi_ops 		ulpi_ops;
+#endif
 	struct phy			*phy;
 	/* old usb_phy interface */
 	struct usb_phy			*usb_phy;
@@ -418,6 +426,17 @@ static inline bool ci_otg_is_fsm_mode(struct ci_hdrc *ci)
 #endif
 }
 
+#if IS_ENABLED(CONFIG_USB_CHIPIDEA_ULPI)
+int ci_ulpi_init(struct ci_hdrc *ci);
+void ci_ulpi_exit(struct ci_hdrc *ci);
+int ci_ulpi_resume(struct ci_hdrc *ci);
+#else
+static inline int ci_ulpi_init(struct ci_hdrc *ci) { return 0; }
+static inline void ci_ulpi_exit(struct ci_hdrc *ci) { }
+static inline int ci_ulpi_resume(struct ci_hdrc *ci) { return 0; }
+#endif
+
+
 u32 hw_read_intr_enable(struct ci_hdrc *ci);
 
 u32 hw_read_intr_status(struct ci_hdrc *ci);
@@ -432,6 +451,7 @@ int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
 				u32 value, unsigned int timeout_ms);
 
 void ci_usb_phy_exit(struct ci_hdrc *ci);
+void hw_phymode_configure(struct ci_hdrc *ci);
 int ci_platform_configure(struct ci_hdrc *ci);
 
 int dbg_create_files(struct ci_hdrc *ci);
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index a01611c7f815..ea84fc0a03a6 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -86,6 +86,7 @@ static const u8 ci_regs_nolpm[] = {
 	[OP_ENDPTLISTADDR]	= 0x18U,
 	[OP_TTCTRL]		= 0x1CU,
 	[OP_BURSTSIZE]		= 0x20U,
+	[OP_ULPI_VIEWPORT]	= 0x30U,
 	[OP_PORTSC]		= 0x44U,
 	[OP_DEVLC]		= 0x84U,
 	[OP_OTGSC]		= 0x64U,
@@ -110,6 +111,7 @@ static const u8 ci_regs_lpm[] = {
 	[OP_ENDPTLISTADDR]	= 0x18U,
 	[OP_TTCTRL]		= 0x1CU,
 	[OP_BURSTSIZE]		= 0x20U,
+	[OP_ULPI_VIEWPORT]	= 0x30U,
 	[OP_PORTSC]		= 0x44U,
 	[OP_DEVLC]		= 0x84U,
 	[OP_OTGSC]		= 0xC4U,
@@ -285,7 +287,7 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
 	return 0;
 }
 
-static void hw_phymode_configure(struct ci_hdrc *ci)
+void hw_phymode_configure(struct ci_hdrc *ci)
 {
 	u32 portsc, lpm, sts = 0;
 
@@ -893,6 +895,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		CI_HDRC_IMX28_WRITE_FIX);
 	ci->supports_runtime_pm = !!(ci->platdata->flags &
 		CI_HDRC_SUPPORTS_RUNTIME_PM);
+	platform_set_drvdata(pdev, ci);
 
 	ret = hw_device_init(ci, base);
 	if (ret < 0) {
@@ -900,6 +903,10 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	ret = ci_ulpi_init(ci);
+	if (ret)
+		return ret;
+
 	if (ci->platdata->phy) {
 		ci->phy = ci->platdata->phy;
 	} else if (ci->platdata->usb_phy) {
@@ -910,11 +917,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
 		/* if both generic PHY and USB PHY layers aren't enabled */
 		if (PTR_ERR(ci->phy) == -ENOSYS &&
-				PTR_ERR(ci->usb_phy) == -ENXIO)
-			return -ENXIO;
+				PTR_ERR(ci->usb_phy) == -ENXIO) {
+			ret = -ENXIO;
+			goto deinit_phy;
+		}
 
-		if (IS_ERR(ci->phy) && IS_ERR(ci->usb_phy))
-			return -EPROBE_DEFER;
+		if (IS_ERR(ci->phy) && IS_ERR(ci->usb_phy)) {
+			ret = -EPROBE_DEFER;
+			goto deinit_phy;
+		}
 
 		if (IS_ERR(ci->phy))
 			ci->phy = NULL;
@@ -993,7 +1004,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		}
 	}
 
-	platform_set_drvdata(pdev, ci);
 	ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED,
 			ci->platdata->name, ci);
 	if (ret)
@@ -1024,6 +1034,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 stop:
 	ci_role_destroy(ci);
 deinit_phy:
+	ci_ulpi_exit(ci);
 
 	return ret;
 }
@@ -1042,6 +1053,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 	ci_extcon_unregister(ci);
 	ci_role_destroy(ci);
 	ci_hdrc_enter_lpm(ci, true);
+	ci_ulpi_exit(ci);
 
 	return 0;
 }
@@ -1089,6 +1101,7 @@ static void ci_controller_suspend(struct ci_hdrc *ci)
 static int ci_controller_resume(struct device *dev)
 {
 	struct ci_hdrc *ci = dev_get_drvdata(dev);
+	int ret;
 
 	dev_dbg(dev, "at %s\n", __func__);
 
@@ -1098,6 +1111,11 @@ static int ci_controller_resume(struct device *dev)
 	}
 
 	ci_hdrc_enter_lpm(ci, false);
+
+	ret = ci_ulpi_resume(ci);
+	if (ret)
+		return ret;
+
 	if (ci->usb_phy) {
 		usb_phy_set_suspend(ci->usb_phy, 0);
 		usb_phy_set_wakeup(ci->usb_phy, false);
diff --git a/drivers/usb/chipidea/ulpi.c b/drivers/usb/chipidea/ulpi.c
new file mode 100644
index 000000000000..3962255ff687
--- /dev/null
+++ b/drivers/usb/chipidea/ulpi.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2016 Linaro Ltd.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/usb/chipidea.h>
+#include <linux/ulpi/interface.h>
+
+#include "ci.h"
+
+#define ULPI_WAKEUP		BIT(31)
+#define ULPI_RUN		BIT(30)
+#define ULPI_WRITE		BIT(29)
+#define ULPI_SYNC_STATE		BIT(27)
+#define ULPI_ADDR(n)		((n) << 16)
+#define ULPI_DATA(n)		(n)
+
+static int ci_ulpi_wait(struct ci_hdrc *ci, u32 mask)
+{
+	unsigned long usec = 10000;
+
+	while (usec--) {
+		if (!hw_read(ci, OP_ULPI_VIEWPORT, mask))
+			return 0;
+
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int ci_ulpi_read(struct ulpi_ops *ops, u8 addr)
+{
+	struct ci_hdrc *ci = dev_get_drvdata(ops->dev);
+	int ret;
+
+	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_WRITE | ULPI_WAKEUP);
+	ret = ci_ulpi_wait(ci, ULPI_WAKEUP);
+	if (ret)
+		return ret;
+
+	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_RUN | ULPI_ADDR(addr));
+	ret = ci_ulpi_wait(ci, ULPI_RUN);
+	if (ret)
+		return ret;
+
+	return hw_read(ci, OP_ULPI_VIEWPORT, GENMASK(15, 8)) >> 8;
+}
+
+static int ci_ulpi_write(struct ulpi_ops *ops, u8 addr, u8 val)
+{
+	struct ci_hdrc *ci = dev_get_drvdata(ops->dev);
+	int ret;
+
+	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_WRITE | ULPI_WAKEUP);
+	ret = ci_ulpi_wait(ci, ULPI_WAKEUP);
+	if (ret)
+		return ret;
+
+	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff,
+		 ULPI_RUN | ULPI_WRITE | ULPI_ADDR(addr) | val);
+	return ci_ulpi_wait(ci, ULPI_RUN);
+}
+
+int ci_ulpi_init(struct ci_hdrc *ci)
+{
+	if (ci->platdata->phy_mode != USBPHY_INTERFACE_MODE_ULPI)
+		return 0;
+
+	/*
+	 * Set PORTSC correctly so we can read/write ULPI registers for
+	 * identification purposes
+	 */
+	hw_phymode_configure(ci);
+
+	ci->ulpi_ops.read = ci_ulpi_read;
+	ci->ulpi_ops.write = ci_ulpi_write;
+	ci->ulpi = ulpi_register_interface(ci->dev, &ci->ulpi_ops);
+	if (IS_ERR(ci->ulpi))
+		dev_err(ci->dev, "failed to register ULPI interface");
+
+	return PTR_ERR_OR_ZERO(ci->ulpi);
+}
+
+void ci_ulpi_exit(struct ci_hdrc *ci)
+{
+	if (ci->ulpi) {
+		ulpi_unregister_interface(ci->ulpi);
+		ci->ulpi = NULL;
+	}
+}
+
+int ci_ulpi_resume(struct ci_hdrc *ci)
+{
+	int cnt = 100000;
+
+	while (cnt-- > 0) {
+		if (hw_read(ci, OP_ULPI_VIEWPORT, ULPI_SYNC_STATE))
+			return 0;
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
-- 
2.9.0.rc2.8.ga28705d

[toc] | [prev] | [next] | [standalone]


#1433478 — Re: [PATCH 09/21] usb: chipidea: Add support for ULPI PHY bus

FromPeter Chen <hzpeterchen@gmail.com>
Date2016-06-29 08:40 +0200
SubjectRe: [PATCH 09/21] usb: chipidea: Add support for ULPI PHY bus
Message-ID<rPhke-Kk-35@gated-at.bofh.it>
In reply to#1431359
On Sun, Jun 26, 2016 at 12:28:26AM -0700, Stephen Boyd wrote:
> Some phys for the chipidea controller are controlled via the ULPI
> viewport. Add support for the ULPI bus so that these sorts of
> phys can be probed and read/written automatically without having
> to duplicate the viewport logic in each phy driver.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/Kconfig  |   7 +++
>  drivers/usb/chipidea/Makefile |   1 +
>  drivers/usb/chipidea/ci.h     |  20 ++++++++
>  drivers/usb/chipidea/core.c   |  30 ++++++++---
>  drivers/usb/chipidea/ulpi.c   | 113 ++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 165 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/usb/chipidea/ulpi.c
> 
> diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig
> index 3644a3500b70..4f8c342a8865 100644
> --- a/drivers/usb/chipidea/Kconfig
> +++ b/drivers/usb/chipidea/Kconfig
> @@ -37,4 +37,11 @@ config USB_CHIPIDEA_HOST
>  	  Say Y here to enable host controller functionality of the
>  	  ChipIdea driver.
>  
> +config USB_CHIPIDEA_ULPI
> +	bool "ChipIdea ULPI PHY support"
> +	depends on USB_ULPI_BUS=y || USB_ULPI_BUS=USB_CHIPIDEA
> +	help
> +	  Say Y here if you have a ULPI PHY attached to your ChipIdea
> +	  controller.
> +
>  endif
> diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
> index 518e445476c3..39fca5715ed3 100644
> --- a/drivers/usb/chipidea/Makefile
> +++ b/drivers/usb/chipidea/Makefile
> @@ -4,6 +4,7 @@ ci_hdrc-y				:= core.o otg.o debug.o
>  ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC)	+= udc.o
>  ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST)	+= host.o
>  ci_hdrc-$(CONFIG_USB_OTG_FSM)		+= otg_fsm.o
> +ci_hdrc-$(CONFIG_USB_CHIPIDEA_ULPI)	+= ulpi.o
>  
>  # Glue/Bridge layers go here
>  
> diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
> index f87805235caa..14aa20525547 100644
> --- a/drivers/usb/chipidea/ci.h
> +++ b/drivers/usb/chipidea/ci.h
> @@ -18,6 +18,8 @@
>  #include <linux/usb.h>
>  #include <linux/usb/gadget.h>
>  #include <linux/usb/otg-fsm.h>
> +#include <linux/usb/otg.h>
> +#include <linux/ulpi/interface.h>
>  
>  /******************************************************************************
>   * DEFINE
> @@ -52,6 +54,7 @@ enum ci_hw_regs {
>  	OP_ENDPTLISTADDR,
>  	OP_TTCTRL,
>  	OP_BURSTSIZE,
> +	OP_ULPI_VIEWPORT,
>  	OP_PORTSC,
>  	OP_DEVLC,
>  	OP_OTGSC,
> @@ -187,6 +190,7 @@ struct hw_bank {
>   * @test_mode: the selected test mode
>   * @platdata: platform specific information supplied by parent device
>   * @vbus_active: is VBUS active
> + * @ulpi: pointer to ULPI device, if any

One more kernel-doc

>   * @phy: pointer to PHY, if any
>   * @usb_phy: pointer to USB PHY, if any and if using the USB PHY framework
>   * @hcd: pointer to usb_hcd for ehci host driver
> @@ -236,6 +240,10 @@ struct ci_hdrc {
>  
>  	struct ci_hdrc_platform_data	*platdata;
>  	int				vbus_active;
> +#ifdef CONFIG_USB_CHIPIDEA_ULPI
> +	struct ulpi			*ulpi;
> +	struct ulpi_ops 		ulpi_ops;
> +#endif
>  	struct phy			*phy;
>  	/* old usb_phy interface */
>  	struct usb_phy			*usb_phy;
> @@ -418,6 +426,17 @@ static inline bool ci_otg_is_fsm_mode(struct ci_hdrc *ci)
>  #endif
>  }
>  

Others are ok, but I can't accept you change current PHY initialization
at your previous patch, so you may need to refine this patch a little.

-- 

Best Regards,
Peter Chen

[toc] | [prev] | [next] | [standalone]


#1431360 — [PATCH 14/21] usb: chipidea: msm: Add proper clk and reset support

FromStephen Boyd <stephen.boyd@linaro.org>
Date2016-06-26 09:40 +0200
Subject[PATCH 14/21] usb: chipidea: msm: Add proper clk and reset support
Message-ID<rOcPE-8ip-5@gated-at.bofh.it>
In reply to#1431357
The msm chipidea controller uses two main clks, an AHB clk to
read/write the MMIO registers and a core clk called the system
clk that drives the controller itself. Add support for these clks
as they're required in all designs.

Also add support for an optional third clk that we need to turn
on to read/write the ULPI phy registers. Some ULPI phys drive
this clk themselves and so it isn't necessary to turn on to probe
a ULPI device, but the HSIC phy doesn't provide one itself, so we
must turn it on here.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 58 +++++++++++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 07cccd24a87f..40249b0e3e93 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -10,11 +10,19 @@
 #include <linux/pm_runtime.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/chipidea.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
 
 #include "ci.h"
 
 #define HS_PHY_AHB_MODE			0x0098
 
+struct ci_hdrc_msm {
+	struct platform_device *ci;
+	struct clk *core_clk;
+	struct clk *iface_clk;
+};
+
 static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 {
 	struct device *dev = ci->gadget.dev.parent;
@@ -43,34 +51,76 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 
 static int ci_hdrc_msm_probe(struct platform_device *pdev)
 {
+	struct ci_hdrc_msm *ci;
 	struct platform_device *plat_ci;
+	struct clk *clk;
+	struct reset_control *reset;
+	int ret;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
 
+	ci = devm_kzalloc(&pdev->dev, sizeof(*ci), GFP_KERNEL);
+	if (!ci)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, ci);
+
+	reset = devm_reset_control_get(&pdev->dev, "core");
+	if (IS_ERR(reset))
+		return PTR_ERR(reset);
+
+	ci->core_clk = clk = devm_clk_get(&pdev->dev, "core");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ci->iface_clk = clk = devm_clk_get(&pdev->dev, "iface");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	reset_control_assert(reset);
+	usleep_range(10000, 12000);
+	reset_control_deassert(reset);
+
+	ret = clk_prepare_enable(ci->core_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(ci->iface_clk);
+	if (ret)
+		goto err_iface;
+
 	plat_ci = ci_hdrc_add_device(&pdev->dev,
 				pdev->resource, pdev->num_resources,
 				&ci_hdrc_msm_platdata);
 	if (IS_ERR(plat_ci)) {
 		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
-		return PTR_ERR(plat_ci);
+		ret = PTR_ERR(plat_ci);
+		goto err_mux;
 	}
 
-	platform_set_drvdata(pdev, plat_ci);
+	ci->ci = plat_ci;
 
 	pm_runtime_no_callbacks(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get(&pdev->dev);
 
 	return 0;
+
+err_mux:
+	clk_disable_unprepare(ci->iface_clk);
+err_iface:
+	clk_disable_unprepare(ci->core_clk);
+	return ret;
 }
 
 static int ci_hdrc_msm_remove(struct platform_device *pdev)
 {
-	struct platform_device *plat_ci = platform_get_drvdata(pdev);
+	struct ci_hdrc_msm *ci = platform_get_drvdata(pdev);
 
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-	ci_hdrc_remove_device(plat_ci);
+	ci_hdrc_remove_device(ci->ci);
+	clk_disable_unprepare(ci->iface_clk);
+	clk_disable_unprepare(ci->core_clk);
 
 	return 0;
 }
-- 
2.9.0.rc2.8.ga28705d

[toc] | [prev] | [next] | [standalone]


#1433494 — Re: [PATCH 14/21] usb: chipidea: msm: Add proper clk and reset support

FromPeter Chen <hzpeterchen@gmail.com>
Date2016-06-29 09:10 +0200
SubjectRe: [PATCH 14/21] usb: chipidea: msm: Add proper clk and reset support
Message-ID<rPhNf-197-5@gated-at.bofh.it>
In reply to#1431360
On Sun, Jun 26, 2016 at 12:28:31AM -0700, Stephen Boyd wrote:
> The msm chipidea controller uses two main clks, an AHB clk to
> read/write the MMIO registers and a core clk called the system
> clk that drives the controller itself. Add support for these clks
> as they're required in all designs.
> 
> Also add support for an optional third clk that we need to turn
> on to read/write the ULPI phy registers. Some ULPI phys drive
> this clk themselves and so it isn't necessary to turn on to probe
> a ULPI device, but the HSIC phy doesn't provide one itself, so we
> must turn it on here.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 58 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 54 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 07cccd24a87f..40249b0e3e93 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -10,11 +10,19 @@
>  #include <linux/pm_runtime.h>
>  #include <linux/usb/gadget.h>
>  #include <linux/usb/chipidea.h>
> +#include <linux/clk.h>
> +#include <linux/reset.h>
>  
>  #include "ci.h"
>  
>  #define HS_PHY_AHB_MODE			0x0098
>  
> +struct ci_hdrc_msm {
> +	struct platform_device *ci;
> +	struct clk *core_clk;
> +	struct clk *iface_clk;
> +};
> +
>  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  {
>  	struct device *dev = ci->gadget.dev.parent;
> @@ -43,34 +51,76 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
>  
>  static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  {
> +	struct ci_hdrc_msm *ci;
>  	struct platform_device *plat_ci;
> +	struct clk *clk;
> +	struct reset_control *reset;
> +	int ret;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
>  
> +	ci = devm_kzalloc(&pdev->dev, sizeof(*ci), GFP_KERNEL);
> +	if (!ci)
> +		return -ENOMEM;
> +	platform_set_drvdata(pdev, ci);
> +
> +	reset = devm_reset_control_get(&pdev->dev, "core");
> +	if (IS_ERR(reset))
> +		return PTR_ERR(reset);
> +
> +	ci->core_clk = clk = devm_clk_get(&pdev->dev, "core");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	ci->iface_clk = clk = devm_clk_get(&pdev->dev, "iface");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);

You say it has three clocks in commit log, why it is only two in the code?
> +
> +	reset_control_assert(reset);
> +	usleep_range(10000, 12000);
> +	reset_control_deassert(reset);
> +
> +	ret = clk_prepare_enable(ci->core_clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(ci->iface_clk);
> +	if (ret)
> +		goto err_iface;
> +
>  	plat_ci = ci_hdrc_add_device(&pdev->dev,
>  				pdev->resource, pdev->num_resources,
>  				&ci_hdrc_msm_platdata);
ci->plat_ci(or ci) = ...

Delete the local variable plat_ci

>  	if (IS_ERR(plat_ci)) {
>  		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> -		return PTR_ERR(plat_ci);
> +		ret = PTR_ERR(plat_ci);
> +		goto err_mux;
>  	}
>  
> -	platform_set_drvdata(pdev, plat_ci);
> +	ci->ci = plat_ci;

[...]


-- 

Best Regards,
Peter Chen

[toc] | [prev] | [next] | [standalone]


#1431361 — [PATCH 07/21] usb: chipidea: Notify of reset when switching into host mode

FromStephen Boyd <stephen.boyd@linaro.org>
Date2016-06-26 09:40 +0200
Subject[PATCH 07/21] usb: chipidea: Notify of reset when switching into host mode
Message-ID<rOcPE-8ip-3@gated-at.bofh.it>
In reply to#1431357
The chipidea/udc.c file sends a CI_HDRC_CONTROLLER_RESET_EVENT to
the wrapper drivers when it calls hw_device_reset(), but that
function is not called from chipidea/host.c. The intent of this
event is to allow the wrapper driver to do any wrapper specific
things after the reset bit has been set in the usb command
register. Therefore, add this event hook in the host role after
we toggle that bit.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/host.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 523c155daea8..3344d3256a60 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -87,6 +87,9 @@ static int ehci_ci_reset(struct usb_hcd *hcd)
 	if (ret)
 		return ret;
 
+	if (ci->platdata->notify_event)
+		ci->platdata->notify_event(ci, CI_HDRC_CONTROLLER_RESET_EVENT);
+
 	return ci_platform_configure(ci);
 }
 
-- 
2.9.0.rc2.8.ga28705d

[toc] | [prev] | [next] | [standalone]


#1431362 — [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later

FromStephen Boyd <stephen.boyd@linaro.org>
Date2016-06-26 09:40 +0200
Subject[PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later
Message-ID<rOcPE-8ip-7@gated-at.bofh.it>
In reply to#1431357
The ULPI phy on qcom platforms needs to be initialized and
powered on after a USB reset and before we toggle the run/stop
bit. Otherwise, the phy locks up and doesn't work properly. Move
the phy initialization to a later point, and shut it down outside
of driver remove so that the phy state is properly managed across
role switches.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci.h   |  3 ++-
 drivers/usb/chipidea/core.c | 23 ++++++++++-------------
 drivers/usb/chipidea/host.c |  5 ++---
 drivers/usb/chipidea/udc.c  |  2 ++
 4 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index cd414559040f..f87805235caa 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -431,7 +431,8 @@ u8 hw_port_test_get(struct ci_hdrc *ci);
 int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
 				u32 value, unsigned int timeout_ms);
 
-void ci_platform_configure(struct ci_hdrc *ci);
+void ci_usb_phy_exit(struct ci_hdrc *ci);
+int ci_platform_configure(struct ci_hdrc *ci);
 
 int dbg_create_files(struct ci_hdrc *ci);
 
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 01390e02ee53..a01611c7f815 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -359,7 +359,7 @@ static int _ci_usb_phy_init(struct ci_hdrc *ci)
  * interfaces
  * @ci: the controller
  */
-static void ci_usb_phy_exit(struct ci_hdrc *ci)
+void ci_usb_phy_exit(struct ci_hdrc *ci)
 {
 	if (ci->phy) {
 		phy_power_off(ci->phy);
@@ -412,9 +412,14 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
  * @ci: the controller
  *
  */
-void ci_platform_configure(struct ci_hdrc *ci)
+int ci_platform_configure(struct ci_hdrc *ci)
 {
 	bool is_device_mode, is_host_mode;
+	int ret;
+
+	ret = ci_usb_phy_init(ci);
+	if (ret)
+		return ret;
 
 	is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC;
 	is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC;
@@ -453,6 +458,8 @@ void ci_platform_configure(struct ci_hdrc *ci)
 			hw_write(ci, OP_BURSTSIZE, RX_BURST_MASK,
 				ci->platdata->rx_burst_size);
 	}
+
+	return 0;
 }
 
 /**
@@ -511,9 +518,7 @@ int hw_device_reset(struct ci_hdrc *ci)
 		return -ENODEV;
 	}
 
-	ci_platform_configure(ci);
-
-	return 0;
+	return ci_platform_configure(ci);
 }
 
 static irqreturn_t ci_irq(int irq, void *data)
@@ -917,12 +922,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 			ci->usb_phy = NULL;
 	}
 
-	ret = ci_usb_phy_init(ci);
-	if (ret) {
-		dev_err(dev, "unable to init phy: %d\n", ret);
-		return ret;
-	}
-
 	ci->hw_bank.phys = res->start;
 
 	ci->irq = platform_get_irq(pdev, 0);
@@ -1025,7 +1024,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 stop:
 	ci_role_destroy(ci);
 deinit_phy:
-	ci_usb_phy_exit(ci);
 
 	return ret;
 }
@@ -1044,7 +1042,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 	ci_extcon_unregister(ci);
 	ci_role_destroy(ci);
 	ci_hdrc_enter_lpm(ci, true);
-	ci_usb_phy_exit(ci);
 
 	return 0;
 }
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 053bac9d983c..523c155daea8 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -87,9 +87,7 @@ static int ehci_ci_reset(struct usb_hcd *hcd)
 	if (ret)
 		return ret;
 
-	ci_platform_configure(ci);
-
-	return ret;
+	return ci_platform_configure(ci);
 }
 
 static const struct ehci_driver_overrides ehci_ci_overrides = {
@@ -186,6 +184,7 @@ static void host_stop(struct ci_hdrc *ci)
 	if (hcd) {
 		usb_remove_hcd(hcd);
 		usb_put_hcd(hcd);
+		ci_usb_phy_exit(ci);
 		if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
 			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
 				regulator_disable(ci->platdata->reg_vbus);
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 065f5d97aa67..8f44e2d1e0c0 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1534,6 +1534,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
 			if (ci->driver)
 				ci->driver->disconnect(&ci->gadget);
 			hw_device_state(ci, 0);
+			ci_usb_phy_exit(ci);
 			if (ci->platdata->notify_event)
 				ci->platdata->notify_event(ci,
 				CI_HDRC_CONTROLLER_STOPPED_EVENT);
@@ -1794,6 +1795,7 @@ static int ci_udc_stop(struct usb_gadget *gadget)
 			ci->platdata->notify_event(ci,
 			CI_HDRC_CONTROLLER_STOPPED_EVENT);
 		spin_unlock_irqrestore(&ci->lock, flags);
+		ci_usb_phy_exit(ci);
 		_gadget_stop_activity(&ci->gadget);
 		spin_lock_irqsave(&ci->lock, flags);
 		pm_runtime_put(&ci->gadget.dev);
-- 
2.9.0.rc2.8.ga28705d

[toc] | [prev] | [next] | [standalone]


#1433410 — Re: [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later

FromPeter Chen <hzpeterchen@gmail.com>
Date2016-06-29 04:40 +0200
SubjectRe: [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later
Message-ID<rPdzX-6MM-1@gated-at.bofh.it>
In reply to#1431362
On Sun, Jun 26, 2016 at 12:28:23AM -0700, Stephen Boyd wrote:
> The ULPI phy on qcom platforms needs to be initialized and
> powered on after a USB reset and before we toggle the run/stop
> bit. Otherwise, the phy locks up and doesn't work properly.

This requirement is so strange, try to see if any other initialization
sequences.
     
Since this driver is multi-platforms, I can't accept this change for
common, if you had to do that, would you please move your changes to
msm glue layer using CI_HDRC_CONTROLLER_RESET_EVENT and
CI_HDRC_CONTROLLER_STOPPED_EVENT? Besides, you need to add one flag
at ci_hdrc_platform_data.flags for your case to avoid normal
initialization.

Peter

> Move
> the phy initialization to a later point, and shut it down outside
> of driver remove so that the phy state is properly managed across
> role switches.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci.h   |  3 ++-
>  drivers/usb/chipidea/core.c | 23 ++++++++++-------------
>  drivers/usb/chipidea/host.c |  5 ++---
>  drivers/usb/chipidea/udc.c  |  2 ++
>  4 files changed, 16 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
> index cd414559040f..f87805235caa 100644
> --- a/drivers/usb/chipidea/ci.h
> +++ b/drivers/usb/chipidea/ci.h
> @@ -431,7 +431,8 @@ u8 hw_port_test_get(struct ci_hdrc *ci);
>  int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
>  				u32 value, unsigned int timeout_ms);
>  
> -void ci_platform_configure(struct ci_hdrc *ci);
> +void ci_usb_phy_exit(struct ci_hdrc *ci);
> +int ci_platform_configure(struct ci_hdrc *ci);
>  
>  int dbg_create_files(struct ci_hdrc *ci);
>  
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 01390e02ee53..a01611c7f815 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -359,7 +359,7 @@ static int _ci_usb_phy_init(struct ci_hdrc *ci)
>   * interfaces
>   * @ci: the controller
>   */
> -static void ci_usb_phy_exit(struct ci_hdrc *ci)
> +void ci_usb_phy_exit(struct ci_hdrc *ci)
>  {
>  	if (ci->phy) {
>  		phy_power_off(ci->phy);
> @@ -412,9 +412,14 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
>   * @ci: the controller
>   *
>   */
> -void ci_platform_configure(struct ci_hdrc *ci)
> +int ci_platform_configure(struct ci_hdrc *ci)
>  {
>  	bool is_device_mode, is_host_mode;
> +	int ret;
> +
> +	ret = ci_usb_phy_init(ci);
> +	if (ret)
> +		return ret;
>  
>  	is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC;
>  	is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC;
> @@ -453,6 +458,8 @@ void ci_platform_configure(struct ci_hdrc *ci)
>  			hw_write(ci, OP_BURSTSIZE, RX_BURST_MASK,
>  				ci->platdata->rx_burst_size);
>  	}
> +
> +	return 0;
>  }
>  
>  /**
> @@ -511,9 +518,7 @@ int hw_device_reset(struct ci_hdrc *ci)
>  		return -ENODEV;
>  	}
>  
> -	ci_platform_configure(ci);
> -
> -	return 0;
> +	return ci_platform_configure(ci);
>  }
>  
>  static irqreturn_t ci_irq(int irq, void *data)
> @@ -917,12 +922,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  			ci->usb_phy = NULL;
>  	}
>  
> -	ret = ci_usb_phy_init(ci);
> -	if (ret) {
> -		dev_err(dev, "unable to init phy: %d\n", ret);
> -		return ret;
> -	}
> -
>  	ci->hw_bank.phys = res->start;
>  
>  	ci->irq = platform_get_irq(pdev, 0);
> @@ -1025,7 +1024,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  stop:
>  	ci_role_destroy(ci);
>  deinit_phy:
> -	ci_usb_phy_exit(ci);
>  
>  	return ret;
>  }
> @@ -1044,7 +1042,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
>  	ci_extcon_unregister(ci);
>  	ci_role_destroy(ci);
>  	ci_hdrc_enter_lpm(ci, true);
> -	ci_usb_phy_exit(ci);
>  
>  	return 0;
>  }
> diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
> index 053bac9d983c..523c155daea8 100644
> --- a/drivers/usb/chipidea/host.c
> +++ b/drivers/usb/chipidea/host.c
> @@ -87,9 +87,7 @@ static int ehci_ci_reset(struct usb_hcd *hcd)
>  	if (ret)
>  		return ret;
>  
> -	ci_platform_configure(ci);
> -
> -	return ret;
> +	return ci_platform_configure(ci);
>  }
>  
>  static const struct ehci_driver_overrides ehci_ci_overrides = {
> @@ -186,6 +184,7 @@ static void host_stop(struct ci_hdrc *ci)
>  	if (hcd) {
>  		usb_remove_hcd(hcd);
>  		usb_put_hcd(hcd);
> +		ci_usb_phy_exit(ci);
>  		if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
>  			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
>  				regulator_disable(ci->platdata->reg_vbus);
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index 065f5d97aa67..8f44e2d1e0c0 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -1534,6 +1534,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
>  			if (ci->driver)
>  				ci->driver->disconnect(&ci->gadget);
>  			hw_device_state(ci, 0);
> +			ci_usb_phy_exit(ci);
>  			if (ci->platdata->notify_event)
>  				ci->platdata->notify_event(ci,
>  				CI_HDRC_CONTROLLER_STOPPED_EVENT);
> @@ -1794,6 +1795,7 @@ static int ci_udc_stop(struct usb_gadget *gadget)
>  			ci->platdata->notify_event(ci,
>  			CI_HDRC_CONTROLLER_STOPPED_EVENT);
>  		spin_unlock_irqrestore(&ci->lock, flags);
> +		ci_usb_phy_exit(ci);
>  		_gadget_stop_activity(&ci->gadget);
>  		spin_lock_irqsave(&ci->lock, flags);
>  		pm_runtime_put(&ci->gadget.dev);
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 

Best Regards,
Peter Chen

[toc] | [prev] | [next] | [standalone]


#1434145 — Re: [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later

FromPeter Chen <hzpeterchen@gmail.com>
Date2016-06-30 03:30 +0200
SubjectRe: [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later
Message-ID<rPyXM-39e-15@gated-at.bofh.it>
In reply to#1433410
On Wed, Jun 29, 2016 at 06:23:50PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-28 19:30:52)
> > On Sun, Jun 26, 2016 at 12:28:23AM -0700, Stephen Boyd wrote:
> > > The ULPI phy on qcom platforms needs to be initialized and
> > > powered on after a USB reset and before we toggle the run/stop
> > > bit. Otherwise, the phy locks up and doesn't work properly.
> > 
> > This requirement is so strange, try to see if any other initialization
> > sequences.
> 
> I think the problem is that the reset bit also resets the phy because
> the phy is part of the same clock domain as the controller. Just a guess
> though.
> 
> >      
> > Since this driver is multi-platforms, I can't accept this change for
> > common, if you had to do that, would you please move your changes to
> > msm glue layer using CI_HDRC_CONTROLLER_RESET_EVENT and
> > CI_HDRC_CONTROLLER_STOPPED_EVENT? Besides, you need to add one flag
> > at ci_hdrc_platform_data.flags for your case to avoid normal
> > initialization.
> 
> Ok, let me see if I can make this work properly in the glue layer. I
> take it that you want me to add a flag for this specific case so that we
> don't do any phy control in the core and leave it up to the glue layer
> to handle, like CI_HDRC_DISABLE_PHY_CONTROL or something?

Yes

-- 

Best Regards,
Peter Chen

[toc] | [prev] | [next] | [standalone]


#1431363 — [PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors

FromStephen Boyd <stephen.boyd@linaro.org>
Date2016-06-26 09:40 +0200
Subject[PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors
Message-ID<rOcPE-8ip-9@gated-at.bofh.it>
In reply to#1431357
If something fails in ci_hdrc_add_device() due to probe defer, we
shouldn't print an error message. Be silent in this case as we'll
try probe again later.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 7d191928e55b..2ed9a181f4b6 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -241,7 +241,8 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
 				     pdev->num_resources, &ci->pdata);
 	if (IS_ERR(plat_ci)) {
-		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
+		if (PTR_ERR(plat_ci) != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
 		ret = PTR_ERR(plat_ci);
 		goto err_mux;
 	}
-- 
2.9.0.rc2.8.ga28705d

[toc] | [prev] | [next] | [standalone]


#1434147 — Re: [PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors

FromPeter Chen <hzpeterchen@gmail.com>
Date2016-06-30 03:30 +0200
SubjectRe: [PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors
Message-ID<rPyXM-39e-23@gated-at.bofh.it>
In reply to#1431363
On Sun, Jun 26, 2016 at 12:28:36AM -0700, Stephen Boyd wrote:
> If something fails in ci_hdrc_add_device() due to probe defer, we
> shouldn't print an error message. Be silent in this case as we'll
> try probe again later.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 7d191928e55b..2ed9a181f4b6 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -241,7 +241,8 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
>  				     pdev->num_resources, &ci->pdata);
>  	if (IS_ERR(plat_ci)) {
> -		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> +		if (PTR_ERR(plat_ci) != -EPROBE_DEFER)
> +			dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
>  		ret = PTR_ERR(plat_ci);
>  		goto err_mux;
>  	}

Why not let ret equals to PTR_ERR(plat_ci) first, and using ret to
compare?

-- 

Best Regards,
Peter Chen

[toc] | [prev] | [next] | [standalone]


#1431364 — [PATCH 03/21] usb: ulpi: Avoid reading/writing in device creation with OF devices

FromStephen Boyd <stephen.boyd@linaro.org>
Date2016-06-26 09:40 +0200
Subject[PATCH 03/21] usb: ulpi: Avoid reading/writing in device creation with OF devices
Message-ID<rOcPE-8ip-11@gated-at.bofh.it>
In reply to#1431357
ULPI devices are matched up against ULPI drivers by reading the
vendor id and product id registers in the ULPI address space.
Before we try to read those registers we'll do a scratch write to
test the interface. Unfortunately, this doesn't work well if the
ULPI device is not powered at the time of device creation. In
that case, the scratch register writes fail and product and
vendor ids can't be read.

If the ULPI spec had some way to describe generic power
requirements for the scratch, product, and vendor registers we
could but power sequencing into the ULPI bus layer and power up
the device before touching the hardware. Unfortunately this
doesn't exist. Furthermore, the power information is device
specific, so it varies from device to device and is not standard.

Let's punt on doing the reads/writes here when we're using DT
backed ULPI devices. This avoids any problems where we need to
power on the device but haven't figured out which device it is
yet to know what sort of regulators, clks, etc. that need to be
turned on for it to work.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/common/ulpi.c | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 980af672bfe3..a6b2a150b176 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -197,25 +197,7 @@ static int ulpi_of_register(struct ulpi *ulpi)
 
 static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 {
-	int ret;
-
-	/* Test the interface */
-	ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa);
-	if (ret < 0)
-		return ret;
-
-	ret = ulpi_read(ulpi, ULPI_SCRATCH);
-	if (ret < 0)
-		return ret;
-
-	if (ret != 0xaa)
-		return -ENODEV;
-
-	ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW);
-	ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8;
-
-	ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
-	ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
+	int ret = -ENODEV;
 
 	ulpi->dev.parent = dev;
 	ulpi->dev.bus = &ulpi_bus;
@@ -230,6 +212,26 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 			return ret;
 	}
 
+	if (ret) {
+		/* Test the interface */
+		ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa);
+		if (ret < 0)
+			return ret;
+
+		ret = ulpi_read(ulpi, ULPI_SCRATCH);
+		if (ret < 0)
+			return ret;
+
+		if (ret != 0xaa)
+			return -ENODEV;
+
+		ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW);
+		ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8;
+
+		ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
+		ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
+	}
+
 	if (of_device_request_module(&ulpi->dev))
 		request_module("ulpi:v%04xp%04x", ulpi->id.vendor,
 			       ulpi->id.product);
-- 
2.9.0.rc2.8.ga28705d

[toc] | [prev] | [next] | [standalone]


#1431365 — [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy

FromStephen Boyd <stephen.boyd@linaro.org>
Date2016-06-26 09:40 +0200
Subject[PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
Message-ID<rOcPE-8ip-13@gated-at.bofh.it>
In reply to#1431357
The HSIC USB controller on qcom SoCs has an integrated all
digital phy controlled via the ULPI viewport.

Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 .../devicetree/bindings/phy/qcom,usb-hsic-phy.txt  |  60 ++++++++
 drivers/phy/Kconfig                                |   7 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-qcom-usb-hsic.c                    | 161 +++++++++++++++++++++
 4 files changed, 229 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
 create mode 100644 drivers/phy/phy-qcom-usb-hsic.c

diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
new file mode 100644
index 000000000000..6b1c6aad2962
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
@@ -0,0 +1,60 @@
+Qualcomm's USB HSIC PHY
+
+PROPERTIES
+
+- compatible:
+    Usage: required
+    Value type: <string>
+    Definition: Should contain "qcom,usb-hsic-phy"
+
+- #phy-cells:
+    Usage: required
+    Value type: <u32>
+    Definition: Should contain 0
+
+- clocks:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: Should contain clock specifier for phy, calibration and
+                optionally a calibration sleep clock
+
+- clock-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "phy, "cal" and optionally "cal_sleep"
+
+- pinctrl-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "init" and "default" in that order
+
+- pinctrl-0:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: List of pinctrl settings to apply to keep HSIC pins in a glitch
+                free state
+
+- pinctrl-1:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: List of pinctrl settings to apply to mux out the HSIC pins
+
+EXAMPLE
+
+usb-controller {
+	ulpi {
+		phy {
+			compatible = "qcom,usb-hsic-phy";
+			#phy-cells = <0>;
+			pinctrl-names = "init", "default";
+			pinctrl-0 = <&hsic_sleep>;
+			pinctrl-1 = <&hsic_default>;
+			clocks = <&gcc GCC_USB_HSIC_CLK>,
+				 <&gcc GCC_USB_HSIC_IO_CAL_CLK>,
+				 <&gcc GCC_USB_HSIC_IO_CAL_SLEEP_CLK>;
+			clock-names = "phy", "cal", "cal_sleep";
+			assigned-clocks = <&gcc GCC_USB_HSIC_IO_CAL_CLK>;
+			assigned-clock-rates = <960000>;
+		};
+	};
+};
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index b869b98835f4..a2866949dc97 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -406,6 +406,13 @@ config PHY_QCOM_UFS
 	help
 	  Support for UFS PHY on QCOM chipsets.
 
+config PHY_QCOM_USB_HSIC
+	tristate "Qualcomm USB HSIC ULPI PHY module"
+	depends on USB_ULPI_BUS
+	select GENERIC_PHY
+	help
+	  Support for the USB HSIC ULPI compliant PHY on QCOM chipsets.
+
 config PHY_TUSB1210
 	tristate "TI TUSB1210 ULPI PHY module"
 	depends on USB_ULPI_BUS
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 9c3e73ccabc4..982e84a290ec 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_PHY_STIH41X_USB)		+= phy-stih41x-usb.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-20nm.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
+obj-$(CONFIG_PHY_QCOM_USB_HSIC) 	+= phy-qcom-usb-hsic.o
 obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
 obj-$(CONFIG_PHY_BRCM_SATA)		+= phy-brcm-sata.o
 obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
diff --git a/drivers/phy/phy-qcom-usb-hsic.c b/drivers/phy/phy-qcom-usb-hsic.c
new file mode 100644
index 000000000000..a81b2f8bfe37
--- /dev/null
+++ b/drivers/phy/phy-qcom-usb-hsic.c
@@ -0,0 +1,161 @@
+/**
+ * Copyright (C) 2016 Linaro Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/ulpi/driver.h>
+#include <linux/ulpi/regs.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/pinctrl-state.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+#include "ulpi_phy.h"
+
+#define ULPI_HSIC_CFG		0x30
+#define ULPI_HSIC_IO_CAL	0x33
+
+struct qcom_usb_hsic_phy {
+	struct ulpi *ulpi;
+	struct phy *phy;
+	struct pinctrl *pctl;
+	struct clk *phy_clk;
+	struct clk *cal_clk;
+	struct clk *cal_sleep_clk;
+};
+
+static int qcom_usb_hsic_phy_power_on(struct phy *phy)
+{
+	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
+	struct ulpi *ulpi = uphy->ulpi;
+	struct pinctrl_state *pins_default;
+	int ret;
+
+	ret = clk_prepare_enable(uphy->phy_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(uphy->cal_clk);
+	if (ret)
+		goto err_cal;
+
+	ret = clk_prepare_enable(uphy->cal_sleep_clk);
+	if (ret)
+		goto err_sleep;
+
+	/* Set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */
+	ret = ulpi_write(ulpi, ULPI_HSIC_IO_CAL, 0xff);
+	if (ret)
+		goto err_ulpi;
+
+	/* Enable periodic IO calibration in HSIC_CFG register */
+	ret = ulpi_write(ulpi, ULPI_HSIC_CFG, 0xa8);
+	if (ret)
+		goto err_ulpi;
+
+	/* Configure pins for HSIC functionality */
+	pins_default = pinctrl_lookup_state(uphy->pctl, PINCTRL_STATE_DEFAULT);
+	if (IS_ERR(pins_default))
+		return PTR_ERR(pins_default);
+
+	ret = pinctrl_select_state(uphy->pctl, pins_default);
+	if (ret)
+		goto err_ulpi;
+
+	 /* Enable HSIC mode in HSIC_CFG register */
+	ret = ulpi_write(ulpi, ULPI_SET(ULPI_HSIC_CFG), 0x01);
+	if (ret)
+		goto err_ulpi;
+
+	/* Disable auto-resume */
+	ret = ulpi_write(ulpi, ULPI_CLR(ULPI_IFC_CTRL),
+			 ULPI_IFC_CTRL_AUTORESUME);
+	if (ret)
+		goto err_ulpi;
+
+	return ret;
+err_ulpi:
+	clk_disable_unprepare(uphy->cal_sleep_clk);
+err_sleep:
+	clk_disable_unprepare(uphy->cal_clk);
+err_cal:
+	clk_disable_unprepare(uphy->phy_clk);
+	return ret;
+}
+
+static int qcom_usb_hsic_phy_power_off(struct phy *phy)
+{
+	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
+
+	clk_disable_unprepare(uphy->cal_sleep_clk);
+	clk_disable_unprepare(uphy->cal_clk);
+	clk_disable_unprepare(uphy->phy_clk);
+
+	return 0;
+}
+
+static const struct phy_ops qcom_usb_hsic_phy_ops = {
+	.power_on = qcom_usb_hsic_phy_power_on,
+	.power_off = qcom_usb_hsic_phy_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int qcom_usb_hsic_phy_probe(struct ulpi *ulpi)
+{
+	struct qcom_usb_hsic_phy *uphy;
+	struct phy_provider *p;
+	struct clk *clk;
+
+	uphy = devm_kzalloc(&ulpi->dev, sizeof(*uphy), GFP_KERNEL);
+	if (!uphy)
+		return -ENOMEM;
+	ulpi_set_drvdata(ulpi, uphy);
+
+	uphy->ulpi = ulpi;
+	uphy->pctl = devm_pinctrl_get(&ulpi->dev);
+	if (IS_ERR(uphy->pctl))
+		return PTR_ERR(uphy->pctl);
+
+	uphy->phy_clk = clk = devm_clk_get(&ulpi->dev, "phy");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->cal_clk = clk = devm_clk_get(&ulpi->dev, "cal");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->phy = devm_phy_create(&ulpi->dev, ulpi->dev.of_node,
+				    &qcom_usb_hsic_phy_ops);
+	if (IS_ERR(uphy->phy))
+		return PTR_ERR(uphy->phy);
+	phy_set_drvdata(uphy->phy, uphy);
+
+	p = devm_of_phy_provider_register(&ulpi->dev, of_phy_simple_xlate);
+	return PTR_ERR_OR_ZERO(p);
+}
+
+
+static const struct of_device_id qcom_usb_hsic_phy_match[] = {
+	{ .compatible = "qcom,usb-hsic-phy", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qcom_usb_hsic_phy_match);
+
+static struct ulpi_driver qcom_usb_hsic_phy_driver = {
+	.probe = qcom_usb_hsic_phy_probe,
+	.driver = {
+		.name = "qcom_usb_hsic_phy",
+		.of_match_table = qcom_usb_hsic_phy_match
+	},
+};
+module_ulpi_driver(qcom_usb_hsic_phy_driver);
+
+MODULE_DESCRIPTION("Qualcomm USB HSIC phy");
+MODULE_LICENSE("GPL v2");
-- 
2.9.0.rc2.8.ga28705d

[toc] | [prev] | [next] | [standalone]


#1432641 — Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy

FromNeil Armstrong <narmstrong@baylibre.com>
Date2016-06-28 10:50 +0200
SubjectRe: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
Message-ID<rOWSt-4vW-1@gated-at.bofh.it>
In reply to#1431365
On 06/26/2016 09:28 AM, Stephen Boyd wrote:
> The HSIC USB controller on qcom SoCs has an integrated all
> digital phy controlled via the ULPI viewport.
> 
> Cc: Kishon Vijay Abraham I <kishon@ti.com>
> Cc: <devicetree@vger.kernel.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  .../devicetree/bindings/phy/qcom,usb-hsic-phy.txt  |  60 ++++++++
>  drivers/phy/Kconfig                                |   7 +
>  drivers/phy/Makefile                               |   1 +
>  drivers/phy/phy-qcom-usb-hsic.c                    | 161 +++++++++++++++++++++
>  4 files changed, 229 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
>  create mode 100644 drivers/phy/phy-qcom-usb-hsic.c
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
> new file mode 100644
> index 000000000000..6b1c6aad2962
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
> @@ -0,0 +1,60 @@
> +Qualcomm's USB HSIC PHY
> +
> +PROPERTIES
> +
> +- compatible:
> +    Usage: required
> +    Value type: <string>
> +    Definition: Should contain "qcom,usb-hsic-phy"
> +
> +- #phy-cells:
> +    Usage: required
> +    Value type: <u32>
> +    Definition: Should contain 0
> +
> +- clocks:
> +    Usage: required
> +    Value type: <prop-encoded-array>
> +    Definition: Should contain clock specifier for phy, calibration and
> +                optionally a calibration sleep clock
> +
> +- clock-names:
> +    Usage: required
> +    Value type: <stringlist>
> +    Definition: Should contain "phy, "cal" and optionally "cal_sleep"
> +

[...]

> +
> +static int qcom_usb_hsic_phy_power_on(struct phy *phy)
> +{
> +	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
> +	struct ulpi *ulpi = uphy->ulpi;
> +	struct pinctrl_state *pins_default;
> +	int ret;
> +
> +	ret = clk_prepare_enable(uphy->phy_clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(uphy->cal_clk);
> +	if (ret)
> +		goto err_cal;
> +
> +	ret = clk_prepare_enable(uphy->cal_sleep_clk);
> +	if (ret)
> +		goto err_sleep;
> +

[...]

> +
> +	return ret;
> +err_ulpi:
> +	clk_disable_unprepare(uphy->cal_sleep_clk);
> +err_sleep:
> +	clk_disable_unprepare(uphy->cal_clk);
> +err_cal:
> +	clk_disable_unprepare(uphy->phy_clk);
> +	return ret;
> +}
> +
> +static int qcom_usb_hsic_phy_power_off(struct phy *phy)
> +{
> +	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
> +
> +	clk_disable_unprepare(uphy->cal_sleep_clk);
> +	clk_disable_unprepare(uphy->cal_clk);
> +	clk_disable_unprepare(uphy->phy_clk);

[...]

> +static int qcom_usb_hsic_phy_probe(struct ulpi *ulpi)
> +{
> +	struct qcom_usb_hsic_phy *uphy;
> +	struct phy_provider *p;
> +	struct clk *clk;
> +
> +	uphy = devm_kzalloc(&ulpi->dev, sizeof(*uphy), GFP_KERNEL);
> +	if (!uphy)
> +		return -ENOMEM;
> +	ulpi_set_drvdata(ulpi, uphy);
> +
> +	uphy->ulpi = ulpi;
> +	uphy->pctl = devm_pinctrl_get(&ulpi->dev);
> +	if (IS_ERR(uphy->pctl))
> +		return PTR_ERR(uphy->pctl);
> +
> +	uphy->phy_clk = clk = devm_clk_get(&ulpi->dev, "phy");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	uphy->cal_clk = clk = devm_clk_get(&ulpi->dev, "cal");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);

Hi Stephen,

In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
it's not present on MDM9615 for example.

Also MDM9615 HSIC requires "core", "alt-core", "phy", "cal" and "iface" clocks.
I assume "core" can be attributed to the main chipidea node, but I think "alt-core" and "iface" should be also optionnal.

Finally, it misses an optional reset line AFAIK mandatory on MDM9615.

Neil

> +
> +	uphy->phy = devm_phy_create(&ulpi->dev, ulpi->dev.of_node,
> +				    &qcom_usb_hsic_phy_ops);
> +	if (IS_ERR(uphy->phy))
> +		return PTR_ERR(uphy->phy);
> +	phy_set_drvdata(uphy->phy, uphy);
> +
> +	p = devm_of_phy_provider_register(&ulpi->dev, of_phy_simple_xlate);
> +	return PTR_ERR_OR_ZERO(p);
> +}
> +
> +
> +static const struct of_device_id qcom_usb_hsic_phy_match[] = {
> +	{ .compatible = "qcom,usb-hsic-phy", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, qcom_usb_hsic_phy_match);
> +
> +static struct ulpi_driver qcom_usb_hsic_phy_driver = {
> +	.probe = qcom_usb_hsic_phy_probe,
> +	.driver = {
> +		.name = "qcom_usb_hsic_phy",
> +		.of_match_table = qcom_usb_hsic_phy_match
> +	},
> +};
> +module_ulpi_driver(qcom_usb_hsic_phy_driver);
> +
> +MODULE_DESCRIPTION("Qualcomm USB HSIC phy");
> +MODULE_LICENSE("GPL v2");
> 

[toc] | [prev] | [next] | [standalone]


#1433350 — Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy

FromStephen Boyd <stephen.boyd@linaro.org>
Date2016-06-29 00:10 +0200
SubjectRe: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
Message-ID<rP9mG-4iI-21@gated-at.bofh.it>
In reply to#1432641
Quoting Neil Armstrong (2016-06-28 01:49:37)
> On 06/26/2016 09:28 AM, Stephen Boyd wrote:
> > +     uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
> > +     if (IS_ERR(clk))
> > +             return PTR_ERR(clk);
> 
> Hi Stephen,
> 
> In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
> it's not present on MDM9615 for example.

The cal_sleep clk is just the sleep clk then (should be a board clk in
DT). Sometimes there's a gate in GCC to allow us to turn it off, other
times there isn't. Either way, it's always wired there so I'll update
the binding to say it isn't optional.

> 
> Also MDM9615 HSIC requires "core", "alt-core", "phy", "cal" and "iface" clocks.
> I assume "core" can be attributed to the main chipidea node, but I think "alt-core" and "iface" should be also optionnal.

Looking at the downstream sources I see this:

        "core_clk"     -> usb_hsic_sys_clk
        "iface_clk"    -> usb_hsic_p_clk
        "alt_core_clk" -> usb_hsic_xcvr_clk

        "cal_clk"      -> usb_hsic_hsio_cal_clk
        "phy_clk"      -> usb_hsic_clk

"core_clk" would be the core clk in ci_hdrc_msm. "iface_clk" would be
the iface clk in ci_hdrc_msm. "cal_clk" would be the cal clk in the hsic
phy and "phy_clk" would be the phy clk in the hsic phy.

That leaves alt_core_clk which seems to be a clock that needs to be on
during the reset assert/deassert and possibly for LPM and USB1.1 FS
modes. Sometimes it's referred to as the "housekeeping" clk. Due to the
way resets are done on msm8974 and later SoCs it looks like this clk was
removed. I can make this an optional clk in the ci_hdrc_msm driver, or
we can have two versions of the ci_hdrc_msm compatible string, one for a
device that has the housekeeping clk and one for the device that
doesn't.

> 
> Finally, it misses an optional reset line AFAIK mandatory on MDM9615.
> 

From what I can tell downstream, all those clks point to the same bit 0
of HSIC_RESET register? So there isn't any phy reset, just the chipidea
controller wrapper reset bit, which should go into the wrapper node?

[toc] | [prev] | [next] | [standalone]


#1433595 — Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy

FromNeil Armstrong <narmstrong@baylibre.com>
Date2016-06-29 11:20 +0200
SubjectRe: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
Message-ID<rPjP3-2kI-13@gated-at.bofh.it>
In reply to#1433350
On 06/28/2016 11:58 PM, Stephen Boyd wrote:
> Quoting Neil Armstrong (2016-06-28 01:49:37)
>> On 06/26/2016 09:28 AM, Stephen Boyd wrote:
>>> +     uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
>>> +     if (IS_ERR(clk))
>>> +             return PTR_ERR(clk);
>>
>> Hi Stephen,
>>
>> In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
>> it's not present on MDM9615 for example.
> 
> The cal_sleep clk is just the sleep clk then (should be a board clk in
> DT). Sometimes there's a gate in GCC to allow us to turn it off, other
> times there isn't. Either way, it's always wired there so I'll update
> the binding to say it isn't optional.

Sorry I don't understand !
What should I do if GCC does not provide a gate here ? And looking at the driver, it could be optional.

> 
>>
>> Also MDM9615 HSIC requires "core", "alt-core", "phy", "cal" and "iface" clocks.
>> I assume "core" can be attributed to the main chipidea node, but I think "alt-core" and "iface" should be also optionnal.
> 
> Looking at the downstream sources I see this:
> 
>         "core_clk"     -> usb_hsic_sys_clk
>         "iface_clk"    -> usb_hsic_p_clk
>         "alt_core_clk" -> usb_hsic_xcvr_clk
> 
>         "cal_clk"      -> usb_hsic_hsio_cal_clk
>         "phy_clk"      -> usb_hsic_clk
> 
> "core_clk" would be the core clk in ci_hdrc_msm. "iface_clk" would be
> the iface clk in ci_hdrc_msm. "cal_clk" would be the cal clk in the hsic
> phy and "phy_clk" would be the phy clk in the hsic phy.
> 
> That leaves alt_core_clk which seems to be a clock that needs to be on
> during the reset assert/deassert and possibly for LPM and USB1.1 FS
> modes. Sometimes it's referred to as the "housekeeping" clk. Due to the
> way resets are done on msm8974 and later SoCs it looks like this clk was
> removed. I can make this an optional clk in the ci_hdrc_msm driver, or
> we can have two versions of the ci_hdrc_msm compatible string, one for a
> device that has the housekeeping clk and one for the device that
> doesn't.

Having it optional would be the best solution I think.

> 
>>
>> Finally, it misses an optional reset line AFAIK mandatory on MDM9615.
>>
> 
> From what I can tell downstream, all those clks point to the same bit 0
> of HSIC_RESET register? So there isn't any phy reset, just the chipidea
> controller wrapper reset bit, which should go into the wrapper node?

Ok, makes sense.

[toc] | [prev] | [next] | [standalone]


Page 1 of 4  [1] 2 3 4  Next page →

Back to top | Article view | linux.kernel


csiph-web