From: Stephen Boyd <hidden> Date: 2016-06-26 07:28:45
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 at 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
From: Stephen Boyd <hidden> Date: 2016-06-26 07:29:05
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 <redacted>
---
drivers/usb/common/ulpi.c | 40 +++++++++++++++++++++-------------------
1 file changed, 21 insertions(+), 19 deletions(-)
@@ -197,25 +197,7 @@ static int ulpi_of_register(struct ulpi *ulpi)staticintulpi_register(structdevice*dev,structulpi*ulpi){-intret;--/* Test the interface */-ret=ulpi_write(ulpi,ULPI_SCRATCH,0xaa);-if(ret<0)-returnret;--ret=ulpi_read(ulpi,ULPI_SCRATCH);-if(ret<0)-returnret;--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;+intret=-ENODEV;ulpi->dev.parent=dev;ulpi->dev.bus=&ulpi_bus;
@@ -230,6 +212,26 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)returnret;}+if(ret){+/* Test the interface */+ret=ulpi_write(ulpi,ULPI_SCRATCH,0xaa);+if(ret<0)+returnret;++ret=ulpi_read(ulpi,ULPI_SCRATCH);+if(ret<0)+returnret;++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);
From: Stephen Boyd <hidden> Date: 2016-06-26 07:29:10
The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
product id ulpi registers. This makes it impossible to make a
ulpi driver match against the id registers. Add support to
discover the ulpi phys via DT to help alleviate this problem.
We'll look for a ulpi bus node underneath the device registering
the ulpi viewport (or the parent of that device to support
chipidea's device layout) and then match up the phy node
underneath that with the ulpi device that's created.
The side benefit of this is that we can use standard DT
properties in the phy node like clks, regulators, gpios, etc.
because we don't have firmware like ACPI to turn these things on
for us. And we can use the DT phy binding to point our phy
consumer to the phy provider.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: <redacted>
Cc: Rob Herring <robh+dt@kernel.org>
Signed-off-by: Stephen Boyd <redacted>
---
Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
drivers/usb/common/ulpi.c | 56 +++++++++++++++++++++++++-
2 files changed, 74 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
@@ -0,0 +1,20 @@+ULPI bus binding+----------------++Phys that are behind a ULPI connection can be described with the following+binding. The host controller shall have a "ulpi" named node as a child, and+that node shall have one enabled node underneath it representing the ulpi+device on the bus.++EXAMPLE+-------++usb {+ compatible = "vendor,usb-controller";++ ulpi {+ phy {+ compatible = "vendor,phy";+ };+ };+};
@@ -152,6 +173,28 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_driver);/* -------------------------------------------------------------------------- */+staticintulpi_of_register(structulpi*ulpi)+{+structdevice_node*np=NULL,*child;++/* Find a ulpi bus underneath the parent or the parent of the parent */+if(ulpi->dev.parent->of_node)+np=of_find_node_by_name(ulpi->dev.parent->of_node,"ulpi");+elseif(ulpi->dev.parent->parent&&+ulpi->dev.parent->parent->of_node)+np=of_find_node_by_name(ulpi->dev.parent->parent->of_node,"ulpi");+if(!np)+return0;++child=of_get_next_available_child(np,NULL);+if(!child)+return-EINVAL;++ulpi->dev.of_node=child;++return0;+}+staticintulpi_register(structdevice*dev,structulpi*ulpi){intret;
From: Stephen Boyd <hidden> Date: 2016-06-26 07:29:12
With the id and vbus detection done via extcon we need to make
sure we poll the status of OTGSC properly by considering what the
extcon is saying, and not just what the register is saying. Let's
move this hw_wait_reg() function to the only place it's used and
simplify it for polling the OTGSC register. Then we can make
certain we only use the hw_read_otgsc() API to read OTGSC, which
will make sure we properly handle extcon events.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Ivan T. Ivanov" <redacted>
Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect")
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/core.c | 32 --------------------------------
drivers/usb/chipidea/otg.c | 35 +++++++++++++++++++++++++++++++----
2 files changed, 31 insertions(+), 36 deletions(-)
@@ -516,38 +516,6 @@ int hw_device_reset(struct ci_hdrc *ci)return0;}-/**-*hw_wait_reg:waittheregistervalue-*-*Sometimes,itneedstowaitregistervaluebeforegoingon.-*Eg,whenswitchtodevicemode,thevbusvalueshouldbelower-*thanOTGSC_BSVbeforeconnectstohost.-*-*@ci:thecontroller-*@reg:registerindex-*@mask:mastbit-*@value:thebitvaluetowait-*@timeout_ms:timeoutinmillisecond-*-*Thisfunctionreturnsanerrorcodeiftimeout-*/-inthw_wait_reg(structci_hdrc*ci,enumci_hw_regsreg,u32mask,-u32value,unsignedinttimeout_ms)-{-unsignedlongelapse=jiffies+msecs_to_jiffies(timeout_ms);--while(hw_read(ci,reg,mask)!=value){-if(time_after(jiffies,elapse)){-dev_err(ci->dev,"timeout waiting for %08x in %d\n",-mask,reg);-return-ETIMEDOUT;-}-msleep(20);-}--return0;-}-staticirqreturn_tci_irq(intirq,void*data){structci_hdrc*ci=data;
From: Stephen Boyd <hidden> Date: 2016-06-26 07:29:14
We're currently emulating the vbus and id interrupts in the OTGSC
read API, but we also need to make sure that if we're handling
the events with extcon that we don't enable the interrupts for
those events in the hardware. Therefore, properly emulate this
register if we're using extcon, but don't enable the interrupts.
This allows me to get my cable connect/disconnect working
properly without getting spurious interrupts on my device that
uses an extcon for these two events.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Ivan T. Ivanov" <redacted>
Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect")
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/otg.c | 46 +++++++++++++++++++++++++++++++++++++++-----
include/linux/usb/chipidea.h | 2 ++
2 files changed, 43 insertions(+), 5 deletions(-)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:29:16
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 <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
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(-)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:29:18
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 <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/host.c | 3 +++
1 file changed, 3 insertions(+)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:29:20
Force the OTG state machine to go forward when we're using an
extcon for vbus detection. In this case, the controller may never
raise an interrupt for AVVIS, so we need to simulate the event by
toggling the appropriate OTG fsm bits and kicking the state
machine again.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/otg_fsm.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:29:22
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 <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Stephen Boyd <redacted>
---
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
@@ -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)+returnret;+if(ci->platdata->phy){ci->phy=ci->platdata->phy;}elseif(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;+gotodeinit_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;+gotodeinit_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);returnret;}
@@ -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);return0;}
From: Stephen Boyd <hidden> Date: 2016-06-26 07:29:24
The core framework already handles setting this parameter with a
platform quirk. Add the appropriate flag so that we always set
AHBBURST to 0. Technically DT should be doing this, but we always
do it for msm chipidea devices so setting the flag in the driver
works just as well.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:29:27
The MSM_USB_BASE macro trick is not very clear, and we're using
it for only one register write so let's just move to using
hw_write_id_reg() and passing the ci pointer instead. That
clearly shows what offset we're using and avoids needing to
include the msm_hsusb_hw.h file when we're going to delete that
file soon.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:29:28
Sometimes the usb wrapper device is part of a power domain that
needs to stay on as long as the device is active. Let's get and
put the device in driver probe/remove so that we keep the power
domain powered as long as the device is attached. We can fine
tune this later to handle wakeup interrupts, etc. for finer grain
power management later, but this is necessary to make sure we can
keep accessing the device right now.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 2 ++
1 file changed, 2 insertions(+)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:29:30
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 <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 21 ---------------------
1 file changed, 21 deletions(-)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:31:46
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 <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
@@ -0,0 +1,71 @@+Qualcomm's USB HS PHY++PROPERTIES++- compatible:+ Usage: required+ Value type: <string>+ Definition: Should contain "qcom,usb-hs-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 the reference and sleep+ clocks++- clock-names:+ Usage: required+ Value type: <stringlist>+ Definition: Should contain "ref" and "sleep" for the reference and sleep+ clocks respectively++- resets:+ Usage: required+ Value type: <prop-encoded-array>+ Definition: Should contain the phy and POR resets++- reset-names:+ Usage: required+ Value type: <stringlist>+ Definition: Should contain "phy" and "por" for the phy and POR resets+ respectively++- v3p3-supply:+ Usage: required+ Value type: <phandle>+ Definition: Should contain a reference to the 3.3V supply++- v1p8-supply:+ Usage: required+ Value type: <phandle>+ Definition: Should contain a reference to the 1.8V supply++- qcom,init-seq:+ Usage: optional+ Value type: <u8 array>+ Definition: Should contain a sequence of ULPI register and address pairs to+ program into the ULPI_EXT_VENDOR_SPECIFIC area. This is related+ to Device Mode Eye Diagram test.++EXAMPLE++otg: usb-controller {+ ulpi {+ phy {+ compatible = "qcom,usb-hs-phy";+ #phy-cells = <0>;+ clocks = <&xo_board>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>;+ clock-names = "ref", "sleep";+ resets = <&gcc GCC_USB2A_PHY_BCR>, <&otg 0>;+ reset-names = "phy", "por";+ v3p3-supply = <&pm8941_l24>;+ v1p8-supply = <&pm8941_l6>;+ qcom,init-seq = /bits/ 8 <0x81 0x63>;+ };+ };+};
From: Stephen Boyd <hidden> Date: 2016-06-26 07:32:43
The HSIC USB controller on qcom SoCs has an integrated all
digital phy controlled via the ULPI viewport.
Cc: Kishon Vijay Abraham I <redacted>
Cc: <redacted>
Signed-off-by: Stephen Boyd <redacted>
---
.../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
From: Stephen Boyd <hidden> Date: 2016-06-26 07:33:14
The MSM chipidea wrapper has two bits that are used to reset the
first or second phy. Add support for these bits via the reset
controller framework, so that phy drivers can reset their
hardware at the right time during initialization.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 43 +++++++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:33:39
If two devices are probed with this same driver, they'll share
the same platform data structure, while the chipidea core layer
writes and modifies it. This can lead to interesting results
especially if one device is an OTG type chipidea controller and
another is a host. Let's create a copy of this structure per each
device instance so that odd things don't happen.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:33:58
When the RESET bit is set in the USBCMD register it resets quite
a few of the wrapper's registers to their reset state. This
includes the GENCONFIG and GENCONFIG2 registers. Currently this
is done by the usb phy and ehci-msm drivers writing into the
controller wrapper's MMIO address space. Let's consolidate the
register writes into the wrapper driver instead so that we
clearly split the wrapper from the phys.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 46 ++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:34:26
We need to pick the correct phy at runtime based on how the SoC
has been wired onto the board. If the secondary phy is used, take
it out of reset and mux over to it by writing into the TCSR
register. Make sure to do this on reset too, because this
register is reset to the default value (primary phy) after the
RESET bit is set in USBCMD.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
1 file changed, 73 insertions(+), 5 deletions(-)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:34:27
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 <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 58 +++++++++++++++++++++++++++++++++++---
1 file changed, 54 insertions(+), 4 deletions(-)
From: Stephen Boyd <hidden> Date: 2016-06-26 07:34:56
In the case of ULPI devices, we want to be able to load the
driver before registering the device so that we don't get stuck
in a loop waiting for the phy module to appear and failing usb
controller probe. Currently we request the ulpi module via the
ulpi ids, but in the DT case we might need to request it with the
OF based modalias instead. Add a common function that allows
anyone to request a module with the OF based modalias.
Cc: Rob Herring <robh+dt@kernel.org>
Cc: <redacted>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/of/device.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/of_device.h | 6 ++++++
2 files changed, 56 insertions(+)
@@ -226,6 +226,56 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)returntsize;}+staticssize_tof_device_modalias_size(structdevice*dev)+{+constchar*compat;+intcplen,i;+ssize_tcsize;++if((!dev)||(!dev->of_node))+return-ENODEV;++/* Name & Type */+csize=5+strlen(dev->of_node->name)+strlen(dev->of_node->type);++/* Get compatible property if any */+compat=of_get_property(dev->of_node,"compatible",&cplen);+if(!compat)+returncsize;++/* Find true end (we tolerate multiple \0 at the end */+for(i=(cplen-1);i>=0&&!compat[i];i--)+cplen--;+if(!cplen)+returncsize;+cplen++;++/* Check space (need cplen+1 chars including final \0) */+returncsize+cplen;+}++intof_device_request_module(structdevice*dev)+{+char*str;+ssize_tsize;+intret;++size=of_device_modalias_size(dev);+if(size<0)+returnsize;++str=kmalloc(size+1,GFP_KERNEL);+if(!str)+return-ENOMEM;++of_device_get_modalias(dev,str,size);+str[size]='\0';+ret=request_module(str);+kfree(str);++returnret;+}+/***of_device_uevent-DisplayOFrelatedueventinformation*/
-----Original Message-----
From: linux-usb-owner at vger.kernel.org [mailto:linux-usb-
owner at vger.kernel.org] On Behalf Of Stephen Boyd
Sent: Sunday, June 26, 2016 3:28 PM
To: linux-usb at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
linux-arm-msm at vger.kernel.org; Andy Gross [off-list ref]; Bjorn
Andersson [off-list ref]; Neil Armstrong
[off-list ref]; Arnd Bergmann [off-list ref]; Felipe Balbi
[off-list ref]; Peter Chen [off-list ref]; Greg Kroah-Hartman
[off-list ref]; Ivan T. Ivanov [off-list ref]
Subject: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
With the id and vbus detection done via extcon we need to make sure we
poll the status of OTGSC properly by considering what the extcon is saying,
and not just what the register is saying. Let's move this hw_wait_reg()
function to the only place it's used and simplify it for polling the OTGSC
register. Then we can make certain we only use the hw_read_otgsc() API to
read OTGSC, which will make sure we properly handle extcon events.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Ivan T. Ivanov" <redacted>
Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID
detect")
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/core.c | 32 --------------------------------
drivers/usb/chipidea/otg.c | 35 +++++++++++++++++++++++++++++++----
2 files changed, 31 insertions(+), 36 deletions(-)
@@ -516,38 +516,6 @@ int hw_device_reset(struct ci_hdrc *ci)return0;}-/**-*hw_wait_reg:waittheregistervalue-*-*Sometimes,itneedstowaitregistervaluebeforegoingon.-*Eg,whenswitchtodevicemode,thevbusvalueshouldbelower-*thanOTGSC_BSVbeforeconnectstohost.-*-*@ci:thecontroller-*@reg:registerindex-*@mask:mastbit-*@value:thebitvaluetowait-*@timeout_ms:timeoutinmillisecond-*-*Thisfunctionreturnsanerrorcodeiftimeout-*/-inthw_wait_reg(structci_hdrc*ci,enumci_hw_regsreg,u32mask,-u32value,unsignedinttimeout_ms)-{-unsignedlongelapse=jiffies+msecs_to_jiffies(timeout_ms);--while(hw_read(ci,reg,mask)!=value){-if(time_after(jiffies,elapse)){-dev_err(ci->dev,"timeout waiting for %08x in %d\n",-mask,reg);-return-ETIMEDOUT;-}-msleep(20);-}--return0;-}-staticirqreturn_tci_irq(intirq,void*data){structci_hdrc*ci=data;
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index
@@ -116,9 +141,11 @@ static void ci_handle_id_switch(struct ci_hdrc *ci) ci_role_stop(ci); if (role == CI_ROLE_GADGET)- /* wait vbus lower than OTGSC_BSV */- hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,- CI_VBUS_STABLE_TIMEOUT_MS);+ /*+ * wait vbus lower than OTGSC_BSV before connecting+ * to host+ */+ hw_wait_otgsc_bsv(ci); ci_role_start(ci, role); }--
2.9.0.rc2.8.ga28705d
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo at vger.kernel.org More majordomo info at
http://vger.kernel.org/majordomo-info.html
From: Heikki Krogerus <heikki.krogerus@linux.intel.com> Date: 2016-06-27 14:35:05
Hi,
I'm fine with most of the patch, except..
On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
quoted hunk
@@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver) struct ulpi *ulpi = to_ulpi_dev(dev); const struct ulpi_device_id *id;- for (id = drv->id_table; id->vendor; id++)+ if (of_driver_match_device(dev, driver))+ return 1;
I don't like this part. We should match separately like that only
if the bus does not support native enumeration, and of course ULPI
with its vendor and product IDs does. There really should always be
IDs to match with here. So exceptions have to be solved before we
attempt matching.
Since we also have to support platforms where the PHY is initially
powered off and reading the IDs from the registers is not possible
because of that, I think we should consider getting the product and
vendor IDs optionally from device properties. Something like this:
From: Stephen Boyd <hidden> Date: 2016-06-27 22:10:40
Quoting Heikki Krogerus (2016-06-27 07:34:22)
Hi,
I'm fine with most of the patch, except..
On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
quoted
@@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver) struct ulpi *ulpi = to_ulpi_dev(dev); const struct ulpi_device_id *id;- for (id = drv->id_table; id->vendor; id++)+ if (of_driver_match_device(dev, driver))+ return 1;
I don't like this part. We should match separately like that only
if the bus does not support native enumeration, and of course ULPI
with its vendor and product IDs does. There really should always be
IDs to match with here. So exceptions have to be solved before we
attempt matching.
Since we also have to support platforms where the PHY is initially
powered off and reading the IDs from the registers is not possible
because of that, I think we should consider getting the product and
vendor IDs optionally from device properties. Something like this:
Ok, I'm a little worried about conflating the powered off problem with
this product/vendor ID missing problem. But if you're ok with that I'll
combine the two patches into one using your approach below.
That should cover both cases. You would just have to create the IDs
yourself in this case.
Right, I would have to make up some IDs in this case. I suppose I can
use the qcom vendor ID 0x05c6 and then product ids 0 and 1 for HS phy
and HSIC phy? That doesn't make me feel great because it's all made up,
but I guess there's no other option. I hope they don't decide to start
populating these ids in the future though and then we may have
conflicting product ids. If that happens I suppose we can do a
workaround based on compatible strings in the DT node. Fun!
Nice side effect of all that is I can drop requesting the module by DT
aliases and things become simpler. I'll try this out.
Hmm. If I try to fix this by selecting RESET_CONTROLLER from the
chipidea Kconfig I get the following recursive Kconfig warning
drivers/usb/Kconfig:39:error: recursive dependency detected!
drivers/usb/Kconfig:39: symbol USB is selected by MOUSE_APPLETOUCH
drivers/input/mouse/Kconfig:187: symbol MOUSE_APPLETOUCH depends on INPUT
drivers/input/Kconfig:8: symbol INPUT is selected by VT
drivers/tty/Kconfig:12: symbol VT is selected by FB_STI
drivers/video/fbdev/Kconfig:674: symbol FB_STI depends on FB
drivers/video/fbdev/Kconfig:5: symbol FB is selected by DRM_KMS_FB_HELPER
drivers/gpu/drm/Kconfig:42: symbol DRM_KMS_FB_HELPER is selected by DRM_KMS_CMA_HELPER
drivers/gpu/drm/Kconfig:98: symbol DRM_KMS_CMA_HELPER is selected by DRM_IMX
drivers/gpu/drm/imx/Kconfig:1: symbol DRM_IMX depends on IMX_IPUV3_CORE
drivers/gpu/ipu-v3/Kconfig:1: symbol IMX_IPUV3_CORE depends on RESET_CONTROLLER
drivers/reset/Kconfig:4: symbol RESET_CONTROLLER is selected by USB_CHIPIDEA
drivers/usb/chipidea/Kconfig:1: symbol USB_CHIPIDEA depends on USB_EHCI_HCD
drivers/usb/host/Kconfig:84: symbol USB_EHCI_HCD depends on USB
Is the proper fix here to have IMX_IPUV3 select RESET_CONTROLLER instead
of depend on it? Doing that leads to another case where rockchip needs
to be changed from a depends on to a select, and then tegra is the same
way. Arnd, any ideas?
From: John Stultz <hidden> Date: 2016-06-28 03:09:38
On Sun, Jun 26, 2016 at 12:28 AM, Stephen Boyd [off-list ref] wrote:
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.
Very excited to see this moving upstream!
Just a heads up, trying to build with this branch gives me:
drivers/usb/Kconfig:39:error: recursive dependency detected!
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/Kconfig:39: symbol USB is selected by MOUSE_APPLETOUCH
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/input/mouse/Kconfig:187: symbol MOUSE_APPLETOUCH depends on INPUT
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/input/Kconfig:8: symbol INPUT is selected by VT
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/tty/Kconfig:12: symbol VT is selected by FB_STI
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/video/fbdev/Kconfig:674: symbol FB_STI depends on FB
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/video/fbdev/Kconfig:5: symbol FB is selected by DRM_KMS_FB_HELPER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/Kconfig:42: symbol DRM_KMS_FB_HELPER is selected
by DRM_KMS_CMA_HELPER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/Kconfig:98: symbol DRM_KMS_CMA_HELPER is selected by DRM_IMX
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/imx/Kconfig:1: symbol DRM_IMX depends on IMX_IPUV3_CORE
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/ipu-v3/Kconfig:1: symbol IMX_IPUV3_CORE depends on
RESET_CONTROLLER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/reset/Kconfig:4: symbol RESET_CONTROLLER is selected by
USB_CHIPIDEA
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/chipidea/Kconfig:1: symbol USB_CHIPIDEA depends on USB_EHCI_HCD
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/host/Kconfig:84: symbol USB_EHCI_HCD depends on USB
drivers/usb/chipidea/otg.c: In function ?hw_write_otgsc?:
drivers/usb/chipidea/otg.c:120:2: warning: format ?%x? expects
argument of type ?unsigned int?, but argument 3 has type ?long
unsigned int? [-Wformat]
drivers/usb/chipidea/otg.c:120:2: warning: format ?%x? expects
argument of type ?unsigned int?, but argument 4 has type ?long
unsigned int? [-Wformat]
I haven't yet been able to test with this, as I need some other fixes
it seems too to deal with some of the iommu changes in my flo-WIP tree
(it can't find of_dma_configure), but will let you know how things
work once I have all that sorted.
thanks
-john
In the case of ULPI devices, we want to be able to load the
driver before registering the device so that we don't get stuck
in a loop waiting for the phy module to appear and failing usb
controller probe. Currently we request the ulpi module via the
ulpi ids, but in the DT case we might need to request it with the
OF based modalias instead. Add a common function that allows
anyone to request a module with the OF based modalias.
Cc: Rob Herring <robh+dt@kernel.org>
Cc: <redacted>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/of/device.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/of_device.h | 6 ++++++
2 files changed, 56 insertions(+)
@@ -226,6 +226,56 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)returntsize;}+staticssize_tof_device_modalias_size(structdevice*dev)+{+constchar*compat;+intcplen,i;+ssize_tcsize;++if((!dev)||(!dev->of_node))+return-ENODEV;++/* Name & Type */+csize=5+strlen(dev->of_node->name)+strlen(dev->of_node->type);
It would be clearer if you replaced 5 with strlen("of:NT"), but...
+
+ /* Get compatible property if any */
+ compat = of_get_property(dev->of_node, "compatible", &cplen);
+ if (!compat)
+ return csize;
+
+ /* Find true end (we tolerate multiple \0 at the end */
+ for (i = (cplen - 1); i >= 0 && !compat[i]; i--)
+ cplen--;
+ if (!cplen)
+ return csize;
+ cplen++;
+
+ /* Check space (need cplen+1 chars including final \0) */
+ return csize + cplen;
+}
...if I understand of_device_get_modalias() correctly you should be able
to replace this function with:
size = of_device_get_modalias(dev, NULL, 0);
snprintf() will not write to NULL, csize will be larger than 0 so tsize
will be returned before it will memcpy() to the buffer.
We need to pick the correct phy at runtime based on how the SoC
has been wired onto the board. If the secondary phy is used, take
it out of reset and mux over to it by writing into the TCSR
register. Make sure to do this on reset too, because this
register is reset to the default value (primary phy) after the
RESET bit is set in USBCMD.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
1 file changed, 73 insertions(+), 5 deletions(-)
+static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
+ struct platform_device *pdev)
+{
+ struct regmap *regmap;
+ struct device_node *syscon;
+ struct device *dev = &pdev->dev;
+ u32 off, val;
+ int ret;
+
+ syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
+ if (!syscon)
+ return 0;
+
+ regmap = syscon_node_to_regmap(syscon);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
+ if (ret < 0) {
+ dev_err(dev, "no offset in syscon\n");
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
+ if (ret < 0) {
+ dev_err(dev, "no value in syscon\n");
+ return -EINVAL;
+ }
+
+ ret = regmap_write(regmap, off, val);
I recently found out (thanks to a comment from Srinivas) that you can
drop the last two error checks by using
of_parse_phandle_with_fixed_args() as in:
struct of_phandle_args args;
ret = of_parse_phandle_with_fixed_args(dev->of_node, "phy-select", 2, 0, &args);
if (ret < 0)
...
regmap = syscon_node_to_regmap(args.np);
of_node_put(args.np);
if (IS_ERR(regmap))
...
ret = regmap_write(regmap, args.args[0], args.args[1]);
+ resource_size_t size;
int ret;
dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
@@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) if (IS_ERR(clk)) return PTR_ERR(clk);+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);+ if (!res)+ return -ENODEV;++ size = resource_size(res);+ ci->base = base = devm_ioremap(&pdev->dev, res->start, size);+ if (!base)+ return -ENOMEM;
Replace these two snippets with:
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ci->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(ci->base))
return PTR_ERR(ci->base);
From: Stephen Boyd <hidden> Date: 2016-06-28 08:34:56
Quoting John Stultz (2016-06-27 20:09:30)
Just a heads up, trying to build with this branch gives me:
drivers/usb/Kconfig:39:error: recursive dependency detected!
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/Kconfig:39: symbol USB is selected by MOUSE_APPLETOUCH
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/input/mouse/Kconfig:187: symbol MOUSE_APPLETOUCH depends on INPUT
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/input/Kconfig:8: symbol INPUT is selected by VT
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/tty/Kconfig:12: symbol VT is selected by FB_STI
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/video/fbdev/Kconfig:674: symbol FB_STI depends on FB
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/video/fbdev/Kconfig:5: symbol FB is selected by DRM_KMS_FB_HELPER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/Kconfig:42: symbol DRM_KMS_FB_HELPER is selected
by DRM_KMS_CMA_HELPER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/Kconfig:98: symbol DRM_KMS_CMA_HELPER is selected by DRM_IMX
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/imx/Kconfig:1: symbol DRM_IMX depends on IMX_IPUV3_CORE
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/ipu-v3/Kconfig:1: symbol IMX_IPUV3_CORE depends on
RESET_CONTROLLER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/reset/Kconfig:4: symbol RESET_CONTROLLER is selected by
USB_CHIPIDEA
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/chipidea/Kconfig:1: symbol USB_CHIPIDEA depends on USB_EHCI_HCD
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/host/Kconfig:84: symbol USB_EHCI_HCD depends on USB
Yeah, sorry I've updated the branch today with fixes reported by kbuild
robot. This problem starts to happen once I start selecting
RESET_CONTROLLER from the chipidea Kconfig symbol. I've layered another
patch on top to fix the build errors I'm seeing, although I'm not sure
it's a great solution.
drivers/usb/chipidea/otg.c: In function ?hw_write_otgsc?:
drivers/usb/chipidea/otg.c:120:2: warning: format ?%x? expects
argument of type ?unsigned int?, but argument 3 has type ?long
unsigned int? [-Wformat]
drivers/usb/chipidea/otg.c:120:2: warning: format ?%x? expects
argument of type ?unsigned int?, but argument 4 has type ?long
unsigned int? [-Wformat]
These are debug print warnings. Nothing to see here...
I haven't yet been able to test with this, as I need some other fixes
it seems too to deal with some of the iommu changes in my flo-WIP tree
(it can't find of_dma_configure), but will let you know how things
work once I have all that sorted.
From: Stephen Boyd <hidden> Date: 2016-06-28 08:39:53
Quoting Bjorn Andersson (2016-06-27 21:51:37)
On Sun 26 Jun 00:28 PDT 2016, Stephen Boyd wrote:
quoted
+static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
+ struct platform_device *pdev)
+{
+ struct regmap *regmap;
+ struct device_node *syscon;
+ struct device *dev = &pdev->dev;
+ u32 off, val;
+ int ret;
+
+ syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
+ if (!syscon)
+ return 0;
+
+ regmap = syscon_node_to_regmap(syscon);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
+ if (ret < 0) {
+ dev_err(dev, "no offset in syscon\n");
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
+ if (ret < 0) {
+ dev_err(dev, "no value in syscon\n");
+ return -EINVAL;
+ }
+
+ ret = regmap_write(regmap, off, val);
I recently found out (thanks to a comment from Srinivas) that you can
drop the last two error checks by using
of_parse_phandle_with_fixed_args() as in:
struct of_phandle_args args;
ret = of_parse_phandle_with_fixed_args(dev->of_node, "phy-select", 2, 0, &args);
if (ret < 0)
...
regmap = syscon_node_to_regmap(args.np);
of_node_put(args.np);
if (IS_ERR(regmap))
...
ret = regmap_write(regmap, args.args[0], args.args[1]);
Awesome, thanks. I'll fold this in.
quoted
+ resource_size_t size;
int ret;
dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
@@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) if (IS_ERR(clk)) return PTR_ERR(clk);+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);+ if (!res)+ return -ENODEV;++ size = resource_size(res);+ ci->base = base = devm_ioremap(&pdev->dev, res->start, size);+ if (!base)+ return -ENOMEM;
Replace these two snippets with:
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ci->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(ci->base))
return PTR_ERR(ci->base);
Unfortunately I can't do that. I'm mapping the base here without
ioremap_resource() because the ci core is mapping it with
devm_ioremap_resource() and that doesn't allow two callers to map the
same address space. If the ci core was a library and not written as a
sub device driver this could be made to work assuming there was some API
to setup the mapping and then another API to do the rest of the ci core
probe.
Or I can add another event like SETUP that would allow me to mux the phy
over early during the ci device probe. I would still need to get a
handle on the registers for the extcon handler though, so that would
need a think.
From: Neil Armstrong <hidden> Date: 2016-06-28 08:49:45
On 06/26/2016 09:28 AM, Stephen Boyd wrote:
quoted hunk
The HSIC USB controller on qcom SoCs has an integrated all
digital phy controlled via the ULPI viewport.
Cc: Kishon Vijay Abraham I <redacted>
Cc: <redacted>
Signed-off-by: Stephen Boyd <redacted>
---
.../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
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
From: Peter Chen <hidden> Date: 2016-06-28 10:08:20
On Sun, Jun 26, 2016 at 12:28:22AM -0700, Stephen Boyd wrote:
quoted hunk
We're currently emulating the vbus and id interrupts in the OTGSC
read API, but we also need to make sure that if we're handling
the events with extcon that we don't enable the interrupts for
those events in the hardware. Therefore, properly emulate this
register if we're using extcon, but don't enable the interrupts.
This allows me to get my cable connect/disconnect working
properly without getting spurious interrupts on my device that
uses an extcon for these two events.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Ivan T. Ivanov" <redacted>
Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect")
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/otg.c | 46 +++++++++++++++++++++++++++++++++++++++-----
include/linux/usb/chipidea.h | 2 ++
2 files changed, 43 insertions(+), 5 deletions(-)
From: Heikki Krogerus <heikki.krogerus@linux.intel.com> Date: 2016-06-28 11:42:15
On Mon, Jun 27, 2016 at 03:10:40PM -0700, Stephen Boyd wrote:
Quoting Heikki Krogerus (2016-06-27 07:34:22)
quoted
Hi,
I'm fine with most of the patch, except..
On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
quoted
@@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver) struct ulpi *ulpi = to_ulpi_dev(dev); const struct ulpi_device_id *id;- for (id = drv->id_table; id->vendor; id++)+ if (of_driver_match_device(dev, driver))+ return 1;
I don't like this part. We should match separately like that only
if the bus does not support native enumeration, and of course ULPI
with its vendor and product IDs does. There really should always be
IDs to match with here. So exceptions have to be solved before we
attempt matching.
Since we also have to support platforms where the PHY is initially
powered off and reading the IDs from the registers is not possible
because of that, I think we should consider getting the product and
vendor IDs optionally from device properties. Something like this:
Ok, I'm a little worried about conflating the powered off problem with
this product/vendor ID missing problem. But if you're ok with that I'll
combine the two patches into one using your approach below.
That should cover both cases. You would just have to create the IDs
yourself in this case.
Right, I would have to make up some IDs in this case. I suppose I can
use the qcom vendor ID 0x05c6 and then product ids 0 and 1 for HS phy
and HSIC phy? That doesn't make me feel great because it's all made up,
but I guess there's no other option. I hope they don't decide to start
populating these ids in the future though and then we may have
conflicting product ids. If that happens I suppose we can do a
workaround based on compatible strings in the DT node. Fun!
Nice side effect of all that is I can drop requesting the module by DT
aliases and things become simpler. I'll try this out.
I was hoping that we could manage with product id 0 as an exception (I
failed to consider that you have multiple PHYs to deal with). I don't
think we can just come up with product id > 0.
I guess we should have the of_driver_match_device() call after all.
Let's just call it conditionally, only in cases where there is no
product ID, to make me feel a bit more better. I don't want to make it
too easy to use.
The properties for the vendor and product ID are still something that
we need to introduce in any case. We have the powered off problem on
all kinds of platforms, and not all of them use DT. Please feel free
to incorporate the diff into the patch you had for the powered off
case if you are OK with it. So I think in your case you would just
need to addthe correct ulpi-vendor id 0x05c6 and ulpi-product id 0 to
the chipidea device node, and I think this would work.
Sorry about the hassle.
Thanks,
--
heikki
From: Stephen Boyd <hidden> Date: 2016-06-28 18:27:12
Quoting Heikki Krogerus (2016-06-28 04:42:05)
On Mon, Jun 27, 2016 at 03:10:40PM -0700, Stephen Boyd wrote:
quoted
Right, I would have to make up some IDs in this case. I suppose I can
use the qcom vendor ID 0x05c6 and then product ids 0 and 1 for HS phy
and HSIC phy? That doesn't make me feel great because it's all made up,
but I guess there's no other option. I hope they don't decide to start
populating these ids in the future though and then we may have
conflicting product ids. If that happens I suppose we can do a
workaround based on compatible strings in the DT node. Fun!
Nice side effect of all that is I can drop requesting the module by DT
aliases and things become simpler. I'll try this out.
I was hoping that we could manage with product id 0 as an exception (I
failed to consider that you have multiple PHYs to deal with). I don't
think we can just come up with product id > 0.
I guess we should have the of_driver_match_device() call after all.
Let's just call it conditionally, only in cases where there is no
product ID, to make me feel a bit more better. I don't want to make it
too easy to use.
The properties for the vendor and product ID are still something that
we need to introduce in any case. We have the powered off problem on
all kinds of platforms, and not all of them use DT. Please feel free
to incorporate the diff into the patch you had for the powered off
case if you are OK with it. So I think in your case you would just
need to addthe correct ulpi-vendor id 0x05c6 and ulpi-product id 0 to
the chipidea device node, and I think this would work.
Hmm ok. I'll have to bring back all the module loading and uevent stuff
based on DT compatible strings then. We'll have the same product id on
HSIC and HS phys, but that isn't a big deal.
From: Rob Herring <robh@kernel.org> Date: 2016-06-28 20:56:52
On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
quoted hunk
The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
product id ulpi registers. This makes it impossible to make a
ulpi driver match against the id registers. Add support to
discover the ulpi phys via DT to help alleviate this problem.
We'll look for a ulpi bus node underneath the device registering
the ulpi viewport (or the parent of that device to support
chipidea's device layout) and then match up the phy node
underneath that with the ulpi device that's created.
The side benefit of this is that we can use standard DT
properties in the phy node like clks, regulators, gpios, etc.
because we don't have firmware like ACPI to turn these things on
for us. And we can use the DT phy binding to point our phy
consumer to the phy provider.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: <redacted>
Cc: Rob Herring <robh+dt@kernel.org>
Signed-off-by: Stephen Boyd <redacted>
---
Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
drivers/usb/common/ulpi.c | 56 +++++++++++++++++++++++++-
2 files changed, 74 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
@@ -0,0 +1,20 @@+ULPI bus binding+----------------++Phys that are behind a ULPI connection can be described with the following+binding. The host controller shall have a "ulpi" named node as a child, and+that node shall have one enabled node underneath it representing the ulpi+device on the bus.
This needs to co-exist with the USB bus binding which has the controller
ports for the child nodes. Maybe use the phy binding?
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?
From: Stephen Boyd <hidden> Date: 2016-06-28 22:09:21
Quoting Rob Herring (2016-06-28 13:56:42)
On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
quoted
The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
product id ulpi registers. This makes it impossible to make a
ulpi driver match against the id registers. Add support to
discover the ulpi phys via DT to help alleviate this problem.
We'll look for a ulpi bus node underneath the device registering
the ulpi viewport (or the parent of that device to support
chipidea's device layout) and then match up the phy node
underneath that with the ulpi device that's created.
The side benefit of this is that we can use standard DT
properties in the phy node like clks, regulators, gpios, etc.
because we don't have firmware like ACPI to turn these things on
for us. And we can use the DT phy binding to point our phy
consumer to the phy provider.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: <redacted>
Cc: Rob Herring <robh+dt@kernel.org>
Signed-off-by: Stephen Boyd <redacted>
---
Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
drivers/usb/common/ulpi.c | 56 +++++++++++++++++++++++++-
2 files changed, 74 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
@@ -0,0 +1,20 @@+ULPI bus binding+----------------++Phys that are behind a ULPI connection can be described with the following+binding. The host controller shall have a "ulpi" named node as a child, and+that node shall have one enabled node underneath it representing the ulpi+device on the bus.
This needs to co-exist with the USB bus binding which has the controller
ports for the child nodes. Maybe use the phy binding?
Which binding is that? bindings/usb/usb-device.txt? This ulpi binding is
to describe phys that are accessed through the ulpi "viewport" in the
usb controller. So controller ports don't come into the picture here.
From: Peter Chen <hidden> Date: 2016-06-29 02:00:27
On Tue, Jun 28, 2016 at 02:42:05PM +0300, Heikki Krogerus wrote:
On Mon, Jun 27, 2016 at 03:10:40PM -0700, Stephen Boyd wrote:
quoted
Quoting Heikki Krogerus (2016-06-27 07:34:22)
quoted
Hi,
I'm fine with most of the patch, except..
On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
quoted
@@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver) struct ulpi *ulpi = to_ulpi_dev(dev); const struct ulpi_device_id *id;- for (id = drv->id_table; id->vendor; id++)+ if (of_driver_match_device(dev, driver))+ return 1;
I don't like this part. We should match separately like that only
if the bus does not support native enumeration, and of course ULPI
with its vendor and product IDs does. There really should always be
IDs to match with here. So exceptions have to be solved before we
attempt matching.
Since we also have to support platforms where the PHY is initially
powered off and reading the IDs from the registers is not possible
because of that, I think we should consider getting the product and
vendor IDs optionally from device properties. Something like this:
Ok, I'm a little worried about conflating the powered off problem with
this product/vendor ID missing problem. But if you're ok with that I'll
combine the two patches into one using your approach below.
That should cover both cases. You would just have to create the IDs
yourself in this case.
Right, I would have to make up some IDs in this case. I suppose I can
use the qcom vendor ID 0x05c6 and then product ids 0 and 1 for HS phy
and HSIC phy? That doesn't make me feel great because it's all made up,
but I guess there's no other option. I hope they don't decide to start
populating these ids in the future though and then we may have
conflicting product ids. If that happens I suppose we can do a
workaround based on compatible strings in the DT node. Fun!
Nice side effect of all that is I can drop requesting the module by DT
aliases and things become simpler. I'll try this out.
I was hoping that we could manage with product id 0 as an exception (I
failed to consider that you have multiple PHYs to deal with). I don't
think we can just come up with product id > 0.
I guess we should have the of_driver_match_device() call after all.
Let's just call it conditionally, only in cases where there is no
product ID, to make me feel a bit more better. I don't want to make it
too easy to use.
The properties for the vendor and product ID are still something that
we need to introduce in any case. We have the powered off problem on
all kinds of platforms, and not all of them use DT.
I am thinking power sequence framework, how power sequence elements
(eg, clock, reset-gpios) can get for non-DT platform? Does ACPI does power
sequence for x86 platforms?
--
Best Regards,
Peter Chen
From: Peter Chen <hidden> Date: 2016-06-29 02:38:09
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
quoted hunk
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 <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
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(-)
@@ -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 at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Peter Chen <hidden> Date: 2016-06-29 03:16:26
On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
Force the OTG state machine to go forward when we're using an
extcon for vbus detection. In this case, the controller may never
raise an interrupt for AVVIS, so we need to simulate the event by
toggling the appropriate OTG fsm bits and kicking the state
machine again.
Well, I think you may misunderstand the OTG FSM and dual-role.
From my and Felipe's point, there are seldom users for USB FSM,
there are only OTG FSM spec and related OTG certification.
The OTG FSM needs related SoC support, the vbus will be off at
several states, and the SRP should be supported by SoC.
By default, the dts needs below properties for disabling it if you
choose otg fsm support at kernel configuration.
&usbotg1 {
vbus-supply = <®_usb_otg1_vbus>;
srp-disable;
hnp-disable;
adp-disable;
status = "okay";
};
See Documentation/devicetree/bindings/usb/generic.txt.
Peter
--
2.9.0.rc2.8.ga28705d
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Peter Chen <hidden> Date: 2016-06-29 06:33:26
On Sun, Jun 26, 2016 at 12:28:26AM -0700, Stephen Boyd wrote:
quoted hunk
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 <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Stephen Boyd <redacted>
---
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
* @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
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
From: Peter Chen <hidden> Date: 2016-06-29 06:39:21
On Sun, Jun 26, 2016 at 12:28:27AM -0700, Stephen Boyd wrote:
The core framework already handles setting this parameter with a
platform quirk. Add the appropriate flag so that we always set
AHBBURST to 0. Technically DT should be doing this, but we always
do it for msm chipidea devices so setting the flag in the driver
works just as well.
You still need to set AHB burst value at dts, this flag is just for
override, see below:
ahb-burst-config = <0x0>;
--
2.9.0.rc2.8.ga28705d
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Peter Chen <hidden> Date: 2016-06-29 06:44:07
On Sun, Jun 26, 2016 at 12:28:28AM -0700, Stephen Boyd wrote:
quoted hunk
The MSM_USB_BASE macro trick is not very clear, and we're using
it for only one register write so let's just move to using
hw_write_id_reg() and passing the ci pointer instead. That
clearly shows what offset we're using and avoids needing to
include the msm_hsusb_hw.h file when we're going to delete that
file soon.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
From: Peter Chen <hidden> Date: 2016-06-29 06:53:03
On Sun, Jun 26, 2016 at 12:28:29AM -0700, Stephen Boyd wrote:
Sometimes the usb wrapper device is part of a power domain that
needs to stay on as long as the device is active. Let's get and
put the device in driver probe/remove so that we keep the power
domain powered as long as the device is attached. We can fine
tune this later to handle wakeup interrupts, etc. for finer grain
power management later, but this is necessary to make sure we can
keep accessing the device right now.
Since some of the controllers work abnormal if we enables runtime
pm unconditionally, so I use one system flag CI_HDRC_SUPPORTS_RUNTIME_PM
for it. I can't understand why you can't access device without enable
parent's runtime pm, the controller will not enter runtime suspend
without that flag.
Peter
@@ -80,6 +80,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)pm_runtime_no_callbacks(&pdev->dev);pm_runtime_enable(&pdev->dev);+pm_runtime_get(&pdev->dev);return0;}
@@ -88,6 +89,7 @@ static int ci_hdrc_msm_remove(struct platform_device *pdev){structplatform_device*plat_ci=platform_get_drvdata(pdev);+pm_runtime_put(&pdev->dev);pm_runtime_disable(&pdev->dev);ci_hdrc_remove_device(plat_ci);
--
2.9.0.rc2.8.ga28705d
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Peter Chen <hidden> Date: 2016-06-29 06:55:13
On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
quoted hunk
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 <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 21 ---------------------
1 file changed, 21 deletions(-)
From: Peter Chen <hidden> Date: 2016-06-29 07:09:14
On Sun, Jun 26, 2016 at 12:28:31AM -0700, Stephen Boyd wrote:
quoted hunk
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 <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 58 +++++++++++++++++++++++++++++++++++---
1 file changed, 54 insertions(+), 4 deletions(-)
From: Peter Chen <hidden> Date: 2016-06-29 08:16:05
On Sun, Jun 26, 2016 at 12:28:32AM -0700, Stephen Boyd wrote:
We need to pick the correct phy at runtime based on how the SoC
has been wired onto the board. If the secondary phy is used, take
it out of reset and mux over to it by writing into the TCSR
register. Make sure to do this on reset too, because this
register is reset to the default value (primary phy) after the
RESET bit is set in USBCMD.
@@ -49,12 +59,58 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = { .notify_event = ci_hdrc_msm_notify_event, };+static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,+ struct platform_device *pdev)+{+ struct regmap *regmap;+ struct device_node *syscon;+ struct device *dev = &pdev->dev;+ u32 off, val;+ int ret;++ syscon = of_parse_phandle(dev->of_node, "phy-select", 0);+ if (!syscon)+ return 0;++ regmap = syscon_node_to_regmap(syscon);+ if (IS_ERR(regmap))+ return PTR_ERR(regmap);++ ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);+ if (ret < 0) {+ dev_err(dev, "no offset in syscon\n");+ return -EINVAL;+ }++ ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);+ if (ret < 0) {+ dev_err(dev, "no value in syscon\n");+ return -EINVAL;+ }++ ret = regmap_write(regmap, off, val);+ if (ret)+ return ret;++ ci->secondary_phy = !!val;+ if (ci->secondary_phy) {+ val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);+ val |= HS_PHY_DIG_CLAMP_N;+ writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);+ }++ return 0;+}+ 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;+ struct resource *res;+ void __iomem *base;+ resource_size_t size; int ret; dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
@@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) if (IS_ERR(clk)) return PTR_ERR(clk);+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);+ if (!res)+ return -ENODEV;++ size = resource_size(res);+ ci->base = base = devm_ioremap(&pdev->dev, res->start, size);+ if (!base)+ return -ENOMEM;+
The core will do the ioremap too, you can't remap io address two times.
The offset larger than 0x200 is vendor specific, you can map it as
the second io region.
@@ -88,9 +153,12 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) if (ret) goto err_iface;- plat_ci = ci_hdrc_add_device(&pdev->dev,- pdev->resource, pdev->num_resources,- &ci_hdrc_msm_platdata);+ ret = ci_hdrc_msm_mux_phy(ci, pdev);+ if (ret)+ goto err_mux;++ 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"); ret = PTR_ERR(plat_ci);
--
2.9.0.rc2.8.ga28705d
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Peter Chen <hidden> Date: 2016-06-29 08:34:25
On Sun, Jun 26, 2016 at 12:28:33AM -0700, Stephen Boyd wrote:
quoted hunk
When the RESET bit is set in the USBCMD register it resets quite
a few of the wrapper's registers to their reset state. This
includes the GENCONFIG and GENCONFIG2 registers. Currently this
is done by the usb phy and ehci-msm drivers writing into the
controller wrapper's MMIO address space. Let's consolidate the
register writes into the wrapper driver instead so that we
clearly split the wrapper from the phys.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 46 ++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
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.
quoted
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.
quoted
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?
From: Peter Chen <hidden> Date: 2016-06-29 11:36:27
On Sun, Jun 26, 2016 at 12:28:34AM -0700, Stephen Boyd wrote:
quoted hunk
If two devices are probed with this same driver, they'll share
the same platform data structure, while the chipidea core layer
writes and modifies it. This can lead to interesting results
especially if one device is an OTG type chipidea controller and
another is a host. Let's create a copy of this structure per each
device instance so that odd things don't happen.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
From: Peter Chen <hidden> Date: 2016-06-29 11:41:14
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:
quoted
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 <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 21 ---------------------
1 file changed, 21 deletions(-)
From: Peter Chen <hidden> Date: 2016-06-29 11:52:03
On Sun, Jun 26, 2016 at 12:28:35AM -0700, Stephen Boyd wrote:
quoted hunk
The MSM chipidea wrapper has two bits that are used to reset the
first or second phy. Add support for these bits via the reset
controller framework, so that phy drivers can reset their
hardware at the right time during initialization.
Cc: Peter Chen <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 43 +++++++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
--
2.9.0.rc2.8.ga28705d
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
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.
You should set the property to point to &sleep_clk which should be under
the "clocks" node at the root of the OF tree. For example, see the
sleep_clk node in arch/arm/boot/dts/qcom-apq8064.dtsi.
From: Stephen Boyd <hidden> Date: 2016-06-29 18:59:21
Quoting Peter Chen (2016-06-28 23:32:11)
On Sun, Jun 26, 2016 at 12:28:27AM -0700, Stephen Boyd wrote:
quoted
The core framework already handles setting this parameter with a
platform quirk. Add the appropriate flag so that we always set
AHBBURST to 0. Technically DT should be doing this, but we always
do it for msm chipidea devices so setting the flag in the driver
works just as well.
You still need to set AHB burst value at dts, this flag is just for
override, see below:
ahb-burst-config = <0x0>;
Right, I have added that to dts now, but the CI_HDRC_OVERRIDE_AHB_BURST
flag allows us to specify it from the platdata structure in the
ci_hdrc_msm.c file. As the value is zero for msm type controllers, I
left it out of the static definition of platdata because all the
non-initialized members of that structure are going to be zero anyway. I
can explicitly set it to zero to make it more clear if you like.
I take it this means it should look like:
#define HS_PHY_GENCONFIG
#define HS_PHY_TXFIFO_IDLE_FORCE_DIS
?
quoted
@@ -141,6 +172,13 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) if (!base) return -ENOMEM;+ ci->vbus_edev = extcon_get_edev_by_phandle(&pdev->dev, 0);+ if (IS_ERR(ci->vbus_edev)) {+ if (PTR_ERR(ci->vbus_edev) != -ENODEV)+ return PTR_ERR(ci->vbus_edev);+ ci->vbus_edev = NULL;+ }+
Why not using ci->platdata->vbus_extcon directly?
Because ci->platdata->vbus_extcon is assigned after the child platform
driver probes, and we have no idea when that will happen from the
ci_hdrc_msm driver probe. If we try after ci_hdrc_add_device() we'll
race with the driver probe and only get the pointer sometimes.
From: Stephen Boyd <hidden> Date: 2016-06-29 19:17:12
Quoting Peter Chen (2016-06-29 04:29:25)
On Sun, Jun 26, 2016 at 12:28:34AM -0700, Stephen Boyd wrote:
quoted
@@ -204,7 +201,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) of_node_put(ulpi_node); plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,- pdev->num_resources, &ci_hdrc_msm_platdata);+ pdev->num_resources, &ci->pdata); if (IS_ERR(plat_ci)) { dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n"); ret = PTR_ERR(plat_ci);
You can do something like ci_hdrc_usb2.c, it looks simpler.
Do what exactly? I'd rather not do a structure copy because that wastes
some memory for a structure that is just a template. We add some more
code here to assign values directly, but that is smaller size wise than
the large platdata structure that only has a few values set in it.
From: Stephen Boyd <hidden> Date: 2016-06-29 19:28:58
Quoting Peter Chen (2016-06-29 01:08:52)
On Sun, Jun 26, 2016 at 12:28:32AM -0700, Stephen Boyd wrote:
quoted
We need to pick the correct phy at runtime based on how the SoC
has been wired onto the board. If the secondary phy is used, take
it out of reset and mux over to it by writing into the TCSR
register. Make sure to do this on reset too, because this
register is reset to the default value (primary phy) after the
RESET bit is set in USBCMD.
@@ -49,12 +59,58 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = { .notify_event = ci_hdrc_msm_notify_event, };+static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,+ struct platform_device *pdev)+{+ struct regmap *regmap;+ struct device_node *syscon;+ struct device *dev = &pdev->dev;+ u32 off, val;+ int ret;++ syscon = of_parse_phandle(dev->of_node, "phy-select", 0);+ if (!syscon)+ return 0;++ regmap = syscon_node_to_regmap(syscon);+ if (IS_ERR(regmap))+ return PTR_ERR(regmap);++ ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);+ if (ret < 0) {+ dev_err(dev, "no offset in syscon\n");+ return -EINVAL;+ }++ ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);+ if (ret < 0) {+ dev_err(dev, "no value in syscon\n");+ return -EINVAL;+ }++ ret = regmap_write(regmap, off, val);+ if (ret)+ return ret;++ ci->secondary_phy = !!val;+ if (ci->secondary_phy) {+ val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);+ val |= HS_PHY_DIG_CLAMP_N;+ writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);+ }++ return 0;+}+ 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;+ struct resource *res;+ void __iomem *base;+ resource_size_t size; int ret; dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
@@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) if (IS_ERR(clk)) return PTR_ERR(clk);+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);+ if (!res)+ return -ENODEV;++ size = resource_size(res);+ ci->base = base = devm_ioremap(&pdev->dev, res->start, size);+ if (!base)+ return -ENOMEM;+
The core will do the ioremap too, you can't remap io address two times.
You can ioremap an address twice, but it's not a great solution. On ARM,
at least, we detect the double mapping and return the same virtual
address the second time.
The offset larger than 0x200 is vendor specific, you can map it as
the second io region.
Ok. That would mean we need to adjust the binding then to have to reg
properties? Or we can limit the size of the resource in the core and the
size of the resource here can be bumped up by 0x200. So DT still says
one resource for the entire ci address space but we don't map anything
more than what we use. Something like this?
---8<----
From: Stephen Boyd <hidden> Date: 2016-06-29 19:31:18
Quoting Peter Chen (2016-06-29 04:34:11)
On Wed, Jun 29, 2016 at 02:48:11PM +0800, Peter Chen wrote:
quoted
On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
quoted
@@ -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.
From: Stephen Boyd <hidden> Date: 2016-06-30 00:43:30
Quoting Peter Chen (2016-06-28 23:46:00)
On Sun, Jun 26, 2016 at 12:28:29AM -0700, Stephen Boyd wrote:
quoted
Sometimes the usb wrapper device is part of a power domain that
needs to stay on as long as the device is active. Let's get and
put the device in driver probe/remove so that we keep the power
domain powered as long as the device is attached. We can fine
tune this later to handle wakeup interrupts, etc. for finer grain
power management later, but this is necessary to make sure we can
keep accessing the device right now.
Since some of the controllers work abnormal if we enables runtime
pm unconditionally, so I use one system flag CI_HDRC_SUPPORTS_RUNTIME_PM
for it. I can't understand why you can't access device without enable
parent's runtime pm, the controller will not enter runtime suspend
without that flag.
Correct, the child device of ci_hdrc_msm will be able to do runtime PM
and keep the parent enabled if the CI_HDRC_SUPPORTS_RUNTIME_PM flag is
set. But even if that flag isn't set, the ci_hdrc_msm driver is calling
pm_runtime_enable() on the same device that it would be called on if the
CI_HDRC_SUPPORTS_RUNTIME_PM flag was set. That allows runtime PM
transition of child devices such as the usb ports (usb1-port1 for
example) to propagate up all the way to the ci_hdrc_msm device and
disable any attached power domains.
Why don't we call runtime PM functions on the ci->dev for all cases of
ci->supports_runtime_pm? It seems like the glue drivers should be
managing their own device power states and the ci->dev should be managed
by core.c code.
Another solution would be to remove the call to pm_runtime_enable() from
ci_hdrc_msm. That would make sure we don't call the power domain code
when the device changes runtime PM states and rely on the fact that
power domains are turned on during device driver probe.
From: Stephen Boyd <hidden> Date: 2016-06-30 01:19:59
Quoting Peter Chen (2016-06-28 20:09:13)
On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
quoted
Force the OTG state machine to go forward when we're using an
extcon for vbus detection. In this case, the controller may never
raise an interrupt for AVVIS, so we need to simulate the event by
toggling the appropriate OTG fsm bits and kicking the state
machine again.
Well, I think you may misunderstand the OTG FSM and dual-role.
From my and Felipe's point, there are seldom users for USB FSM,
there are only OTG FSM spec and related OTG certification.
Probably yes.
The OTG FSM needs related SoC support, the vbus will be off at
several states, and the SRP should be supported by SoC.
By default, the dts needs below properties for disabling it if you
choose otg fsm support at kernel configuration.
&usbotg1 {
vbus-supply = <®_usb_otg1_vbus>;
srp-disable;
hnp-disable;
adp-disable;
status = "okay";
};
See Documentation/devicetree/bindings/usb/generic.txt.
Does this mean we should be setting all those properties if we're using
an extcon for vbus and id? I have noticed that vbus is powered off after
some time when no device is connected and we're in A_HOST state because
the timeout for a B device connection happens.
From: Stephen Boyd <hidden> Date: 2016-06-30 01:23:50
Quoting Peter Chen (2016-06-28 19:30:52)
On Sun, Jun 26, 2016 at 12:28:23AM -0700, Stephen Boyd wrote:
quoted
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?
From: Peter Chen <hidden> Date: 2016-06-30 01:26:04
On Wed, Jun 29, 2016 at 11:59:21AM -0700, Stephen Boyd wrote:
Quoting Peter Chen (2016-06-28 23:32:11)
quoted
On Sun, Jun 26, 2016 at 12:28:27AM -0700, Stephen Boyd wrote:
quoted
The core framework already handles setting this parameter with a
platform quirk. Add the appropriate flag so that we always set
AHBBURST to 0. Technically DT should be doing this, but we always
do it for msm chipidea devices so setting the flag in the driver
works just as well.
You still need to set AHB burst value at dts, this flag is just for
override, see below:
ahb-burst-config = <0x0>;
Right, I have added that to dts now, but the CI_HDRC_OVERRIDE_AHB_BURST
flag allows us to specify it from the platdata structure in the
ci_hdrc_msm.c file. As the value is zero for msm type controllers, I
left it out of the static definition of platdata because all the
non-initialized members of that structure are going to be zero anyway. I
can explicitly set it to zero to make it more clear if you like.
I suggest setting it explicitly at dts, at current code, it is set
as zero explicitly too:)
--
Best Regards,
Peter Chen
From: Peter Chen <hidden> Date: 2016-06-30 01:28:26
On Sun, Jun 26, 2016 at 12:28:36AM -0700, Stephen Boyd wrote:
quoted hunk
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 <redacted>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <redacted>
---
drivers/usb/chipidea/ci_hdrc_msm.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
From: Stephen Boyd <hidden> Date: 2016-06-30 01:29:02
Quoting Peter Chen (2016-06-28 23:26:00)
On Sun, Jun 26, 2016 at 12:28:26AM -0700, Stephen Boyd wrote:
quoted
@@ -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
Done.
quoted
* @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
From: Peter Chen <hidden> Date: 2016-06-30 01:29:30
On Wed, Jun 29, 2016 at 06:23:50PM -0700, Stephen Boyd wrote:
Quoting Peter Chen (2016-06-28 19:30:52)
quoted
On Sun, Jun 26, 2016 at 12:28:23AM -0700, Stephen Boyd wrote:
quoted
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.
quoted
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?
From: Peter Chen <hidden> Date: 2016-06-30 01:35:27
On Wed, Jun 29, 2016 at 06:19:59PM -0700, Stephen Boyd wrote:
Quoting Peter Chen (2016-06-28 20:09:13)
quoted
On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
quoted
Force the OTG state machine to go forward when we're using an
extcon for vbus detection. In this case, the controller may never
raise an interrupt for AVVIS, so we need to simulate the event by
toggling the appropriate OTG fsm bits and kicking the state
machine again.
Well, I think you may misunderstand the OTG FSM and dual-role.
From my and Felipe's point, there are seldom users for USB FSM,
there are only OTG FSM spec and related OTG certification.
Probably yes.
quoted
The OTG FSM needs related SoC support, the vbus will be off at
several states, and the SRP should be supported by SoC.
By default, the dts needs below properties for disabling it if you
choose otg fsm support at kernel configuration.
&usbotg1 {
vbus-supply = <®_usb_otg1_vbus>;
srp-disable;
hnp-disable;
adp-disable;
status = "okay";
};
See Documentation/devicetree/bindings/usb/generic.txt.
Does this mean we should be setting all those properties if we're using
an extcon for vbus and id?
It is not related to how we know vbus and id. If your controller is
otg-capable, and you don't want to enable OTG FSM (just want dual-role),
you should set them at dts since the zImage is multi-platforms, the
CONFIG_USB_OTG and CONFIG_USB_OTG_FSM may be chosen.
I have noticed that vbus is powered off after
some time when no device is connected and we're in A_HOST state because
the timeout for a B device connection happens.
I think it is not you want, but it is OTG compliance.
--
Best Regards,
Peter Chen