Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1431357 > unrolled thread
| Started by | Stephen Boyd <stephen.boyd@linaro.org> |
|---|---|
| First post | 2016-06-26 09:30 +0200 |
| Last post | 2016-07-05 21:40 +0200 |
| Articles | 20 on this page of 62 — 9 participants |
Back to article view | Back to linux.kernel
[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 →
| From | Stephen Boyd <stephen.boyd@linaro.org> |
|---|---|
| Date | 2016-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]
| From | Stephen Boyd <stephen.boyd@linaro.org> |
|---|---|
| Date | 2016-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]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-06-29 09:00 +0200 |
| Subject | Re: [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]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-06-29 13:50 +0200 |
| Subject | Re: [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]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-06-30 04:00 +0200 |
| Subject | Re: [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]
| From | Stephen Boyd <stephen.boyd@linaro.org> |
|---|---|
| Date | 2016-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]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-06-29 08:40 +0200 |
| Subject | Re: [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]
| From | Stephen Boyd <stephen.boyd@linaro.org> |
|---|---|
| Date | 2016-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]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-06-29 09:10 +0200 |
| Subject | Re: [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]
| From | Stephen Boyd <stephen.boyd@linaro.org> |
|---|---|
| Date | 2016-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]
| From | Stephen Boyd <stephen.boyd@linaro.org> |
|---|---|
| Date | 2016-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]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-06-29 04:40 +0200 |
| Subject | Re: [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]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-06-30 03:30 +0200 |
| Subject | Re: [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]
| From | Stephen Boyd <stephen.boyd@linaro.org> |
|---|---|
| Date | 2016-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]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-06-30 03:30 +0200 |
| Subject | Re: [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]
| From | Stephen Boyd <stephen.boyd@linaro.org> |
|---|---|
| Date | 2016-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]
| From | Stephen Boyd <stephen.boyd@linaro.org> |
|---|---|
| Date | 2016-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]
| From | Neil Armstrong <narmstrong@baylibre.com> |
|---|---|
| Date | 2016-06-28 10:50 +0200 |
| Subject | Re: [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]
| From | Stephen Boyd <stephen.boyd@linaro.org> |
|---|---|
| Date | 2016-06-29 00:10 +0200 |
| Subject | Re: [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]
| From | Neil Armstrong <narmstrong@baylibre.com> |
|---|---|
| Date | 2016-06-29 11:20 +0200 |
| Subject | Re: [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