Commit 9703fc8c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB/PHY updates from Greg KH:
 "Here is the big USB/PHY driver patches for 4.20-rc1

  Lots of USB changes in here, primarily in these areas:

   - typec updates and new drivers

   - new PHY drivers

   - dwc2 driver updates and additions (this old core keeps getting
     added to new devices.)

   - usbtmc major update based on the industry group coming together and
     working to add new features and performance to the driver.

   - USB gadget additions for new features

   - USB gadget configfs updates

   - chipidea driver updates

   - other USB gadget updates

   - USB serial driver updates

   - renesas driver updates

   - xhci driver updates

   - other tiny USB driver updates

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'usb-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (229 commits)
  usb: phy: ab8500: silence some uninitialized variable warnings
  usb: xhci: tegra: Add genpd support
  usb: xhci: tegra: Power-off power-domains on removal
  usbip:vudc: BUG kmalloc-2048 (Not tainted): Poison overwritten
  usbip: tools: fix atoi() on non-null terminated string
  USB: misc: appledisplay: fix backlight update_status return code
  phy: phy-pxa-usb: add a new driver
  usb: host: add DT bindings for faraday fotg2
  usb: host: ohci-at91: fix request of irq for optional gpio
  usb/early: remove set but not used variable 'remain_length'
  usb: typec: Fix copy/paste on typec_set_vconn_role() kerneldoc
  usb: typec: tcpm: Report back negotiated PPS voltage and current
  USB: core: remove set but not used variable 'udev'
  usb: core: fix memory leak on port_dev_path allocation
  USB: net2280: Remove ->disconnect() callback from net2280_pullup()
  usb: dwc2: disable power_down on rockchip devices
  usb: gadget: udc: renesas_usb3: add support for r8a77990
  dt-bindings: usb: renesas_usb3: add bindings for r8a77990
  usb: gadget: udc: renesas_usb3: Add r8a774a1 support
  USB: serial: cypress_m8: remove set but not used variable 'iflag'
  ...
parents da19a102 b8d9ee24
...@@ -25,38 +25,3 @@ Description: ...@@ -25,38 +25,3 @@ Description:
4.2.2. 4.2.2.
The files are read only. The files are read only.
What: /sys/bus/usb/drivers/usbtmc/*/TermChar
Date: August 2008
Contact: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Description:
This file is the TermChar value to be sent to the USB TMC
device as described by the document, "Universal Serial Bus Test
and Measurement Class Specification
(USBTMC) Revision 1.0" as published by the USB-IF.
Note that the TermCharEnabled file determines if this value is
sent to the device or not.
What: /sys/bus/usb/drivers/usbtmc/*/TermCharEnabled
Date: August 2008
Contact: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Description:
This file determines if the TermChar is to be sent to the
device on every transaction or not. For more details about
this, please see the document, "Universal Serial Bus Test and
Measurement Class Specification (USBTMC) Revision 1.0" as
published by the USB-IF.
What: /sys/bus/usb/drivers/usbtmc/*/auto_abort
Date: August 2008
Contact: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Description:
This file determines if the transaction of the USB TMC
device is to be automatically aborted if there is any error.
For more details about this, please see the document,
"Universal Serial Bus Test and Measurement Class Specification
(USBTMC) Revision 1.0" as published by the USB-IF.
...@@ -12,6 +12,10 @@ Date: Dec 2014 ...@@ -12,6 +12,10 @@ Date: Dec 2014
KernelVersion: 4.0 KernelVersion: 4.0
Description: Control descriptors Description: Control descriptors
All attributes read only:
bInterfaceNumber - USB interface number for this
streaming interface
What: /config/usb-gadget/gadget/functions/uvc.name/control/class What: /config/usb-gadget/gadget/functions/uvc.name/control/class
Date: Dec 2014 Date: Dec 2014
KernelVersion: 4.0 KernelVersion: 4.0
...@@ -109,6 +113,10 @@ Date: Dec 2014 ...@@ -109,6 +113,10 @@ Date: Dec 2014
KernelVersion: 4.0 KernelVersion: 4.0
Description: Streaming descriptors Description: Streaming descriptors
All attributes read only:
bInterfaceNumber - USB interface number for this
streaming interface
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/class What: /config/usb-gadget/gadget/functions/uvc.name/streaming/class
Date: Dec 2014 Date: Dec 2014
KernelVersion: 4.0 KernelVersion: 4.0
...@@ -160,6 +168,10 @@ Description: Specific MJPEG format descriptors ...@@ -160,6 +168,10 @@ Description: Specific MJPEG format descriptors
All attributes read only, All attributes read only,
except bmaControls and bDefaultFrameIndex: except bmaControls and bDefaultFrameIndex:
bFormatIndex - unique id for this format descriptor;
only defined after parent header is
linked into the streaming class;
read-only
bmaControls - this format's data for bmaControls in bmaControls - this format's data for bmaControls in
the streaming header the streaming header
bmInterfaceFlags - specifies interlace information, bmInterfaceFlags - specifies interlace information,
...@@ -177,6 +189,10 @@ Date: Dec 2014 ...@@ -177,6 +189,10 @@ Date: Dec 2014
KernelVersion: 4.0 KernelVersion: 4.0
Description: Specific MJPEG frame descriptors Description: Specific MJPEG frame descriptors
bFrameIndex - unique id for this framedescriptor;
only defined after parent format is
linked into the streaming header;
read-only
dwFrameInterval - indicates how frame interval can be dwFrameInterval - indicates how frame interval can be
programmed; a number of values programmed; a number of values
separated by newline can be specified separated by newline can be specified
...@@ -204,6 +220,10 @@ Date: Dec 2014 ...@@ -204,6 +220,10 @@ Date: Dec 2014
KernelVersion: 4.0 KernelVersion: 4.0
Description: Specific uncompressed format descriptors Description: Specific uncompressed format descriptors
bFormatIndex - unique id for this format descriptor;
only defined after parent header is
linked into the streaming class;
read-only
bmaControls - this format's data for bmaControls in bmaControls - this format's data for bmaControls in
the streaming header the streaming header
bmInterfaceFlags - specifies interlace information, bmInterfaceFlags - specifies interlace information,
...@@ -224,6 +244,10 @@ Date: Dec 2014 ...@@ -224,6 +244,10 @@ Date: Dec 2014
KernelVersion: 4.0 KernelVersion: 4.0
Description: Specific uncompressed frame descriptors Description: Specific uncompressed frame descriptors
bFrameIndex - unique id for this framedescriptor;
only defined after parent format is
linked into the streaming header;
read-only
dwFrameInterval - indicates how frame interval can be dwFrameInterval - indicates how frame interval can be
programmed; a number of values programmed; a number of values
separated by newline can be specified separated by newline can be specified
......
...@@ -189,6 +189,16 @@ Description: ...@@ -189,6 +189,16 @@ Description:
The file will read "hotplug", "wired" and "not used" if the The file will read "hotplug", "wired" and "not used" if the
information is available, and "unknown" otherwise. information is available, and "unknown" otherwise.
What: /sys/bus/usb/devices/.../(hub interface)/portX/location
Date: October 2018
Contact: Bjørn Mork <bjorn@mork.no>
Description:
Some platforms provide usb port physical location through
firmware. This is used by the kernel to pair up logical ports
mapping to the same physical connector. The attribute exposes the
raw location value as a hex integer.
What: /sys/bus/usb/devices/.../(hub interface)/portX/quirks What: /sys/bus/usb/devices/.../(hub interface)/portX/quirks
Date: May 2018 Date: May 2018
Contact: Nicolas Boichat <drinkcat@chromium.org> Contact: Nicolas Boichat <drinkcat@chromium.org>
...@@ -219,7 +229,14 @@ Description: ...@@ -219,7 +229,14 @@ Description:
ports and report them to the kernel. This attribute is to expose ports and report them to the kernel. This attribute is to expose
the number of over-current situation occurred on a specific port the number of over-current situation occurred on a specific port
to user space. This file will contain an unsigned 32 bit value to user space. This file will contain an unsigned 32 bit value
which wraps to 0 after its maximum is reached. which wraps to 0 after its maximum is reached. This file supports
poll() for monitoring changes to this value in user space.
Any time this value changes the corresponding hub device will send a
udev event with the following attributes:
OVER_CURRENT_PORT=/sys/bus/usb/devices/.../(hub interface)/portX
OVER_CURRENT_COUNT=[current value of this sysfs attribute]
What: /sys/bus/usb/devices/.../(hub interface)/portX/usb3_lpm_permit What: /sys/bus/usb/devices/.../(hub interface)/portX/usb3_lpm_permit
Date: November 2015 Date: November 2015
......
...@@ -4623,7 +4623,8 @@ ...@@ -4623,7 +4623,8 @@
usbcore.old_scheme_first= usbcore.old_scheme_first=
[USB] Start with the old device initialization [USB] Start with the old device initialization
scheme (default 0 = off). scheme, applies only to low and full-speed devices
(default 0 = off).
usbcore.usbfs_memory_mb= usbcore.usbfs_memory_mb=
[USB] Memory limit (in MB) for buffers allocated by [USB] Memory limit (in MB) for buffers allocated by
......
...@@ -29,15 +29,15 @@ Required properties for usb-c-connector with power delivery support: ...@@ -29,15 +29,15 @@ Required properties for usb-c-connector with power delivery support:
in "Universal Serial Bus Power Delivery Specification" chapter 6.4.1.2 in "Universal Serial Bus Power Delivery Specification" chapter 6.4.1.2
Source_Capabilities Message, the order of each entry(PDO) should follow Source_Capabilities Message, the order of each entry(PDO) should follow
the PD spec chapter 6.4.1. Required for power source and power dual role. the PD spec chapter 6.4.1. Required for power source and power dual role.
User can specify the source PDO array via PDO_FIXED/BATT/VAR() defined in User can specify the source PDO array via PDO_FIXED/BATT/VAR/PPS_APDO()
dt-bindings/usb/pd.h. defined in dt-bindings/usb/pd.h.
- sink-pdos: An array of u32 with each entry providing supported power - sink-pdos: An array of u32 with each entry providing supported power
sink data object(PDO), the detailed bit definitions of PDO can be found sink data object(PDO), the detailed bit definitions of PDO can be found
in "Universal Serial Bus Power Delivery Specification" chapter 6.4.1.3 in "Universal Serial Bus Power Delivery Specification" chapter 6.4.1.3
Sink Capabilities Message, the order of each entry(PDO) should follow Sink Capabilities Message, the order of each entry(PDO) should follow
the PD spec chapter 6.4.1. Required for power sink and power dual role. the PD spec chapter 6.4.1. Required for power sink and power dual role.
User can specify the sink PDO array via PDO_FIXED/BATT/VAR() defined in User can specify the sink PDO array via PDO_FIXED/BATT/VAR/PPS_APDO() defined
dt-bindings/usb/pd.h. in dt-bindings/usb/pd.h.
- op-sink-microwatt: Sink required operating power in microwatt, if source - op-sink-microwatt: Sink required operating power in microwatt, if source
can't offer the power, Capability Mismatch is set. Required for power can't offer the power, Capability Mismatch is set. Required for power
sink and power dual role. sink and power dual role.
......
...@@ -8,6 +8,7 @@ Required properties: ...@@ -8,6 +8,7 @@ Required properties:
"brcm,iproc-nsp-sata-phy" "brcm,iproc-nsp-sata-phy"
"brcm,phy-sata3" "brcm,phy-sata3"
"brcm,iproc-sr-sata-phy" "brcm,iproc-sr-sata-phy"
"brcm,bcm63138-sata-phy"
- address-cells: should be 1 - address-cells: should be 1
- size-cells: should be 0 - size-cells: should be 0
- reg: register ranges for the PHY PCB interface - reg: register ranges for the PHY PCB interface
......
Cadence MHDP DisplayPort SD0801 PHY binding
===========================================
This binding describes the Cadence SD0801 PHY hardware included with
the Cadence MHDP DisplayPort controller.
-------------------------------------------------------------------------------
Required properties (controller (parent) node):
- compatible : Should be "cdns,dp-phy"
- reg : Defines the following sets of registers in the parent
mhdp device:
- Offset of the DPTX PHY configuration registers
- Offset of the SD0801 PHY configuration registers
- #phy-cells : from the generic PHY bindings, must be 0.
Optional properties:
- num_lanes : Number of DisplayPort lanes to use (1, 2 or 4)
- max_bit_rate : Maximum DisplayPort link bit rate to use, in Mbps (2160,
2430, 2700, 3240, 4320, 5400 or 8100)
-------------------------------------------------------------------------------
Example:
dp_phy: phy@f0fb030a00 {
compatible = "cdns,dp-phy";
reg = <0xf0 0xfb030a00 0x0 0x00000040>,
<0xf0 0xfb500000 0x0 0x00100000>;
num_lanes = <4>;
max_bit_rate = <8100>;
#phy-cells = <0>;
};
ROCKCHIP HDMI PHY WITH INNO IP BLOCK
Required properties:
- compatible : should be one of the listed compatibles:
* "rockchip,rk3228-hdmi-phy",
* "rockchip,rk3328-hdmi-phy";
- reg : Address and length of the hdmi phy control register set
- clocks : phandle + clock specifier for the phy clocks
- clock-names : string, clock name, must contain "sysclk" for system
control and register configuration, "refoclk" for crystal-
oscillator reference PLL clock input and "refpclk" for pclk-
based refeference PLL clock input.
- #clock-cells: should be 0.
- clock-output-names : shall be the name for the output clock.
- interrupts : phandle + interrupt specified for the hdmiphy interrupt
- #phy-cells : must be 0. See ./phy-bindings.txt for details.
Optional properties for rk3328-hdmi-phy:
- nvmem-cells = phandle + nvmem specifier for the cpu-version efuse
- nvmem-cell-names : "cpu-version" to read the chip version, required
for adjustment to some frequency settings
Example:
hdmi_phy: hdmi-phy@12030000 {
compatible = "rockchip,rk3228-hdmi-phy";
reg = <0x12030000 0x10000>;
#phy-cells = <0>;
clocks = <&cru PCLK_HDMI_PHY>, <&xin24m>, <&cru DCLK_HDMIPHY>;
clock-names = "sysclk", "refoclk", "refpclk";
#clock-cells = <0>;
clock-output-names = "hdmi_phy";
status = "disabled";
};
Then the PHY can be used in other nodes such as:
hdmi: hdmi@200a0000 {
compatible = "rockchip,rk3228-dw-hdmi";
...
phys = <&hdmi_phy>;
phy-names = "hdmi";
...
};
...@@ -10,16 +10,20 @@ Required properties: ...@@ -10,16 +10,20 @@ Required properties:
"qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996, "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
"qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996, "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996,
"qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845, "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845,
"qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845. "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845,
"qcom,sdm845-qmp-ufs-phy" for UFS QMP phy on sdm845.
- reg: - reg:
- For "qcom,sdm845-qmp-usb3-phy": - index 0: address and length of register set for PHY's common
- index 0: address and length of register set for PHY's common serdes serdes block.
block. - index 1: address and length of the DP_COM control block (for
- named register "dp_com" (using reg-names): address and length of the "qcom,sdm845-qmp-usb3-phy" only).
DP_COM control block.
- For all others: - reg-names:
- offset and length of register set for PHY's common serdes block. - For "qcom,sdm845-qmp-usb3-phy":
- Should be: "reg-base", "dp_com"
- For all others:
- The reg-names property shouldn't be defined.
- #clock-cells: must be 1 - #clock-cells: must be 1
- Phy pll outputs a bunch of clocks for Tx, Rx and Pipe - Phy pll outputs a bunch of clocks for Tx, Rx and Pipe
...@@ -35,6 +39,7 @@ Required properties: ...@@ -35,6 +39,7 @@ Required properties:
"aux" for phy aux clock, "aux" for phy aux clock,
"ref" for 19.2 MHz ref clk, "ref" for 19.2 MHz ref clk,
"com_aux" for phy common block aux clock, "com_aux" for phy common block aux clock,
"ref_aux" for phy reference aux clock,
For "qcom,msm8996-qmp-pcie-phy" must contain: For "qcom,msm8996-qmp-pcie-phy" must contain:
"aux", "cfg_ahb", "ref". "aux", "cfg_ahb", "ref".
For "qcom,msm8996-qmp-usb3-phy" must contain: For "qcom,msm8996-qmp-usb3-phy" must contain:
......
* Renesas R-Car generation 3 USB 2.0 PHY * Renesas R-Car generation 3 USB 2.0 PHY
This file provides information on what the device node for the R-Car generation This file provides information on what the device node for the R-Car generation
3 USB 2.0 PHY contains. 3 and RZ/G2 USB 2.0 PHY contain.
Required properties: Required properties:
- compatible: "renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795 - compatible: "renesas,usb2-phy-r8a774a1" if the device is a part of an R8A774A1
SoC.
"renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795
SoC. SoC.
"renesas,usb2-phy-r8a7796" if the device is a part of an R8A7796 "renesas,usb2-phy-r8a7796" if the device is a part of an R8A7796
SoC. SoC.
...@@ -14,7 +16,8 @@ Required properties: ...@@ -14,7 +16,8 @@ Required properties:
R8A77990 SoC. R8A77990 SoC.
"renesas,usb2-phy-r8a77995" if the device is a part of an "renesas,usb2-phy-r8a77995" if the device is a part of an
R8A77995 SoC. R8A77995 SoC.
"renesas,rcar-gen3-usb2-phy" for a generic R-Car Gen3 compatible device. "renesas,rcar-gen3-usb2-phy" for a generic R-Car Gen3 or RZ/G2
compatible device.
When compatible with the generic version, nodes must list the When compatible with the generic version, nodes must list the
SoC-specific version corresponding to the platform first SoC-specific version corresponding to the platform first
...@@ -31,6 +34,8 @@ channel as USB OTG: ...@@ -31,6 +34,8 @@ channel as USB OTG:
- interrupts: interrupt specifier for the PHY. - interrupts: interrupt specifier for the PHY.
- vbus-supply: Phandle to a regulator that provides power to the VBUS. This - vbus-supply: Phandle to a regulator that provides power to the VBUS. This
regulator will be managed during the PHY power on/off sequence. regulator will be managed during the PHY power on/off sequence.
- renesas,no-otg-pins: boolean, specify when a board does not provide proper
otg pins.
Example (R-Car H3): Example (R-Car H3):
......
* Renesas R-Car generation 3 USB 3.0 PHY * Renesas R-Car generation 3 USB 3.0 PHY
This file provides information on what the device node for the R-Car generation This file provides information on what the device node for the R-Car generation
3 USB 3.0 PHY contains. 3 and RZ/G2 USB 3.0 PHY contain.
If you want to enable spread spectrum clock (ssc), you should use USB_EXTAL If you want to enable spread spectrum clock (ssc), you should use USB_EXTAL
instead of USB3_CLK. However, if you don't want to these features, you don't instead of USB3_CLK. However, if you don't want to these features, you don't
need this driver. need this driver.
Required properties: Required properties:
- compatible: "renesas,r8a7795-usb3-phy" if the device is a part of an R8A7795 - compatible: "renesas,r8a774a1-usb3-phy" if the device is a part of an R8A774A1
SoC.
"renesas,r8a7795-usb3-phy" if the device is a part of an R8A7795
SoC. SoC.
"renesas,r8a7796-usb3-phy" if the device is a part of an R8A7796 "renesas,r8a7796-usb3-phy" if the device is a part of an R8A7796
SoC. SoC.
"renesas,r8a77965-usb3-phy" if the device is a part of an "renesas,r8a77965-usb3-phy" if the device is a part of an
R8A77965 SoC. R8A77965 SoC.
"renesas,rcar-gen3-usb3-phy" for a generic R-Car Gen3 compatible "renesas,rcar-gen3-usb3-phy" for a generic R-Car Gen3 or RZ/G2
device. compatible device.
When compatible with the generic version, nodes must list the When compatible with the generic version, nodes must list the
SoC-specific version corresponding to the platform first SoC-specific version corresponding to the platform first
......
Socionext UniPhier PCIe PHY bindings
This describes the devicetree bindings for PHY interface built into
PCIe controller implemented on Socionext UniPhier SoCs.
Required properties:
- compatible: Should contain one of the following:
"socionext,uniphier-ld20-pcie-phy" - for LD20 PHY
"socionext,uniphier-pxs3-pcie-phy" - for PXs3 PHY
- reg: Specifies offset and length of the register set for the device.
- #phy-cells: Must be zero.
- clocks: A phandle to the clock gate for PCIe glue layer including
this phy.
- resets: A phandle to the reset line for PCIe glue layer including
this phy.
Optional properties:
- socionext,syscon: A phandle to system control to set configurations
for phy.
Refer to phy/phy-bindings.txt for the generic PHY binding properties.
Example:
pcie_phy: phy@66038000 {
compatible = "socionext,uniphier-ld20-pcie-phy";
reg = <0x66038000 0x4000>;
#phy-cells = <0>;
clocks = <&sys_clk 24>;
resets = <&sys_rst 24>;
socionext,syscon = <&soc_glue>;
};
Socionext UniPhier USB2 PHY
This describes the devicetree bindings for PHY interface built into
USB2 controller implemented on Socionext UniPhier SoCs.
Pro4 SoC has both USB2 and USB3 host controllers, however, this USB3
controller doesn't include its own High-Speed PHY. This needs to specify
USB2 PHY instead of USB3 HS-PHY.
Required properties:
- compatible: Should contain one of the following:
"socionext,uniphier-pro4-usb2-phy" - for Pro4 SoC
"socionext,uniphier-ld11-usb2-phy" - for LD11 SoC
Sub-nodes:
Each PHY should be represented as a sub-node.
Sub-nodes required properties:
- #phy-cells: Should be 0.
- reg: The number of the PHY.
Sub-nodes optional properties:
- vbus-supply: A phandle to the regulator for USB VBUS.
Refer to phy/phy-bindings.txt for the generic PHY binding properties.
Example:
soc-glue@5f800000 {
...
usb-phy {
compatible = "socionext,uniphier-ld11-usb2-phy";
usb_phy0: phy@0 {
reg = <0>;
#phy-cells = <0>;
};
...
};
};
usb@5a800100 {
compatible = "socionext,uniphier-ehci", "generic-ehci";
...
phy-names = "usb";
phys = <&usb_phy0>;
};
Socionext UniPhier USB3 High-Speed (HS) PHY
This describes the devicetree bindings for PHY interfaces built into
USB3 controller implemented on Socionext UniPhier SoCs.
Although the controller includes High-Speed PHY and Super-Speed PHY,
this describes about High-Speed PHY.
Required properties:
- compatible: Should contain one of the following:
"socionext,uniphier-pro4-usb3-hsphy" - for Pro4 SoC
"socionext,uniphier-pxs2-usb3-hsphy" - for PXs2 SoC
"socionext,uniphier-ld20-usb3-hsphy" - for LD20 SoC
"socionext,uniphier-pxs3-usb3-hsphy" - for PXs3 SoC
- reg: Specifies offset and length of the register set for the device.
- #phy-cells: Should be 0.
- clocks: A list of phandles to the clock gate for USB3 glue layer.
According to the clock-names, appropriate clocks are required.
- clock-names: Should contain the following:
"gio", "link" - for Pro4 SoC
"phy", "phy-ext", "link" - for PXs3 SoC, "phy-ext" is optional.
"phy", "link" - for others
- resets: A list of phandles to the reset control for USB3 glue layer.
According to the reset-names, appropriate resets are required.
- reset-names: Should contain the following:
"gio", "link" - for Pro4 SoC
"phy", "link" - for others
Optional properties:
- vbus-supply: A phandle to the regulator for USB VBUS.
- nvmem-cells: Phandles to nvmem cell that contains the trimming data.
Available only for HS-PHY implemented on LD20 and PXs3, and
if unspecified, default value is used.
- nvmem-cell-names: Should be the following names, which correspond to
each nvmem-cells.
All of the 3 parameters associated with the following names are
required for each port, if any one is omitted, the trimming data
of the port will not be set at all.
"rterm", "sel_t", "hs_i" - Each cell name for phy parameters
Refer to phy/phy-bindings.txt for the generic PHY binding properties.
Example:
usb-glue@65b00000 {
compatible = "socionext,uniphier-ld20-dwc3-glue",
"simple-mfd";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x65b00000 0x400>;
usb_vbus0: regulator {
...
};
usb_hsphy0: hs-phy@200 {
compatible = "socionext,uniphier-ld20-usb3-hsphy";
reg = <0x200 0x10>;
#phy-cells = <0>;
clock-names = "link", "phy";
clocks = <&sys_clk 14>, <&sys_clk 16>;
reset-names = "link", "phy";
resets = <&sys_rst 14>, <&sys_rst 16>;
vbus-supply = <&usb_vbus0>;
nvmem-cell-names = "rterm", "sel_t", "hs_i";
nvmem-cells = <&usb_rterm0>, <&usb_sel_t0>,
<&usb_hs_i0>;
};
...
};
Socionext UniPhier USB3 Super-Speed (SS) PHY
This describes the devicetree bindings for PHY interfaces built into
USB3 controller implemented on Socionext UniPhier SoCs.
Although the controller includes High-Speed PHY and Super-Speed PHY,
this describes about Super-Speed PHY.
Required properties:
- compatible: Should contain one of the following:
"socionext,uniphier-pro4-usb3-ssphy" - for Pro4 SoC
"socionext,uniphier-pxs2-usb3-ssphy" - for PXs2 SoC
"socionext,uniphier-ld20-usb3-ssphy" - for LD20 SoC
"socionext,uniphier-pxs3-usb3-ssphy" - for PXs3 SoC
- reg: Specifies offset and length of the register set for the device.
- #phy-cells: Should be 0.
- clocks: A list of phandles to the clock gate for USB3 glue layer.
According to the clock-names, appropriate clocks are required.
- clock-names:
"gio", "link" - for Pro4 SoC
"phy", "phy-ext", "link" - for PXs3 SoC, "phy-ext" is optional.
"phy", "link" - for others
- resets: A list of phandles to the reset control for USB3 glue layer.
According to the reset-names, appropriate resets are required.
- reset-names:
"gio", "link" - for Pro4 SoC
"phy", "link" - for others
Optional properties:
- vbus-supply: A phandle to the regulator for USB VBUS.
Refer to phy/phy-bindings.txt for the generic PHY binding properties.
Example:
usb-glue@65b00000 {
compatible = "socionext,uniphier-ld20-dwc3-glue",
"simple-mfd";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x65b00000 0x400>;
usb_vbus0: regulator {
...
};
usb_ssphy0: ss-phy@300 {
compatible = "socionext,uniphier-ld20-usb3-ssphy";
reg = <0x300 0x10>;
#phy-cells = <0>;
clock-names = "link", "phy";
clocks = <&sys_clk 14>, <&sys_clk 16>;
reset-names = "link", "phy";
resets = <&sys_rst 14>, <&sys_rst 16>;
vbus-supply = <&usb_vbus0>;
};
...
};
...@@ -80,6 +80,8 @@ Optional properties: ...@@ -80,6 +80,8 @@ Optional properties:
controller. It's expected that a mux state of 0 indicates device mode and a controller. It's expected that a mux state of 0 indicates device mode and a
mux state of 1 indicates host mode. mux state of 1 indicates host mode.
- mux-control-names: Shall be "usb_switch" if mux-controls is specified. - mux-control-names: Shall be "usb_switch" if mux-controls is specified.
- pinctrl-names: Names for optional pin modes in "default", "host", "device"
- pinctrl-n: alternate pin modes
i.mx specific properties i.mx specific properties
- fsl,usbmisc: phandler of non-core register device, with one - fsl,usbmisc: phandler of non-core register device, with one
......
...@@ -19,6 +19,7 @@ Exception for clocks: ...@@ -19,6 +19,7 @@ Exception for clocks:
"cavium,octeon-7130-usb-uctl" "cavium,octeon-7130-usb-uctl"
"qcom,dwc3" "qcom,dwc3"
"samsung,exynos5250-dwusb3" "samsung,exynos5250-dwusb3"
"samsung,exynos5433-dwusb3"
"samsung,exynos7-dwusb3" "samsung,exynos7-dwusb3"
"sprd,sc9860-dwc3" "sprd,sc9860-dwc3"
"st,stih407-dwc3" "st,stih407-dwc3"
......
* Marvell PXA/MMP EHCI controller.
Required properties:
- compatible: must be "marvell,pxau2o-ehci"
- reg: physical base addresses of the controller and length of memory mapped region
- interrupts: one EHCI controller interrupt should be described here
- clocks: phandle list of usb clocks
- clock-names: should be "USBCLK"
- phys: phandle for the PHY device
- phy-names: should be "usb"
Example:
ehci0: usb-ehci@d4208000 {
compatible = "marvell,pxau2o-ehci";
reg = <0xd4208000 0x200>;
interrupts = <44>;
clocks = <&soc_clocks MMP2_CLK_USB>;
clock-names = "USBCLK";
phys = <&usb_otg_phy>;
phy-names = "usb";
};
...@@ -83,6 +83,8 @@ Required properties: ...@@ -83,6 +83,8 @@ Required properties:
- compatible: should be one of the following - - compatible: should be one of the following -
"samsung,exynos5250-dwusb3": for USB 3.0 DWC3 controller on "samsung,exynos5250-dwusb3": for USB 3.0 DWC3 controller on
Exynos5250/5420. Exynos5250/5420.
"samsung,exynos5433-dwusb3": for USB 3.0 DWC3 controller on
Exynos5433.
"samsung,exynos7-dwusb3": for USB 3.0 DWC3 controller on Exynos7. "samsung,exynos7-dwusb3": for USB 3.0 DWC3 controller on Exynos7.
- #address-cells, #size-cells : should be '1' if the device has sub-nodes - #address-cells, #size-cells : should be '1' if the device has sub-nodes
with 'reg' property. with 'reg' property.
......
Faraday FOTG Host controller
This OTG-capable USB host controller is found in Cortina Systems
Gemini and other SoC products.
Required properties:
- compatible: should be one of:
"faraday,fotg210"
"cortina,gemini-usb", "faraday,fotg210"
- reg: should contain one register range i.e. start and length
- interrupts: description of the interrupt line
Optional properties:
- clocks: should contain the IP block clock
- clock-names: should be "PCLK" for the IP block clock
Required properties for "cortina,gemini-usb" compatible:
- syscon: a phandle to the system controller to access PHY registers
Optional properties for "cortina,gemini-usb" compatible:
- cortina,gemini-mini-b: boolean property that indicates that a Mini-B
OTG connector is in use
- wakeup-source: see power/wakeup-source.txt
Example for Gemini:
usb@68000000 {
compatible = "cortina,gemini-usb", "faraday,fotg210";
reg = <0x68000000 0x1000>;
interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cc 12>;
clock-names = "PCLK";
syscon = <&syscon>;
wakeup-source;
};
...@@ -5,10 +5,19 @@ Required properties : ...@@ -5,10 +5,19 @@ Required properties :
- reg : I2C slave address - reg : I2C slave address
- interrupts : Interrupt specifier - interrupts : Interrupt specifier
Optional properties : Required sub-node:
- fcs,operating-sink-microwatt : - connector : The "usb-c-connector" attached to the FUSB302 IC. The bindings
Minimum amount of power accepted from a sink of the connector node are specified in:
when negotiating
Documentation/devicetree/bindings/connector/usb-connector.txt
Deprecated properties :
- fcs,max-sink-microvolt : Maximum sink voltage accepted by port controller
- fcs,max-sink-microamp : Maximum sink current accepted by port controller
- fcs,max-sink-microwatt : Maximum sink power accepted by port controller
- fcs,operating-sink-microwatt : Minimum amount of power accepted from a sink
when negotiating
Example: Example:
...@@ -17,7 +26,16 @@ fusb302: typec-portc@54 { ...@@ -17,7 +26,16 @@ fusb302: typec-portc@54 {
reg = <0x54>; reg = <0x54>;
interrupt-parent = <&nmi_intc>; interrupt-parent = <&nmi_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>; interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
fcs,max-sink-microvolt = <12000000>;
fcs,max-sink-microamp = <3000000>; usb_con: connector {
fcs,max-sink-microwatt = <36000000>; compatible = "usb-c-connector";
label = "USB-C";
power-role = "dual";
try-power-role = "sink";
source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
PDO_VAR(3000, 12000, 3000)
PDO_PPS_APDO(3000, 11000, 3000)>;
op-sink-microwatt = <10000000>;
};
}; };
...@@ -2,11 +2,13 @@ Renesas Electronics USB3.0 Peripheral driver ...@@ -2,11 +2,13 @@ Renesas Electronics USB3.0 Peripheral driver
Required properties: Required properties:
- compatible: Must contain one of the following: - compatible: Must contain one of the following:
- "renesas,r8a774a1-usb3-peri"
- "renesas,r8a7795-usb3-peri" - "renesas,r8a7795-usb3-peri"
- "renesas,r8a7796-usb3-peri" - "renesas,r8a7796-usb3-peri"
- "renesas,r8a77965-usb3-peri" - "renesas,r8a77965-usb3-peri"
- "renesas,rcar-gen3-usb3-peri" for a generic R-Car Gen3 compatible - "renesas,r8a77990-usb3-peri"
device - "renesas,rcar-gen3-usb3-peri" for a generic R-Car Gen3 or RZ/G2
compatible device
When compatible with the generic version, nodes must list the When compatible with the generic version, nodes must list the
SoC-specific version corresponding to the platform first SoC-specific version corresponding to the platform first
......
...@@ -4,7 +4,9 @@ Required properties: ...@@ -4,7 +4,9 @@ Required properties:
- compatible: Must contain one or more of the following: - compatible: Must contain one or more of the following:
- "renesas,usbhs-r8a7743" for r8a7743 (RZ/G1M) compatible device - "renesas,usbhs-r8a7743" for r8a7743 (RZ/G1M) compatible device
- "renesas,usbhs-r8a7744" for r8a7744 (RZ/G1N) compatible device
- "renesas,usbhs-r8a7745" for r8a7745 (RZ/G1E) compatible device - "renesas,usbhs-r8a7745" for r8a7745 (RZ/G1E) compatible device
- "renesas,usbhs-r8a774a1" for r8a774a1 (RZ/G2M) compatible device
- "renesas,usbhs-r8a7790" for r8a7790 (R-Car H2) compatible device - "renesas,usbhs-r8a7790" for r8a7790 (R-Car H2) compatible device
- "renesas,usbhs-r8a7791" for r8a7791 (R-Car M2-W) compatible device - "renesas,usbhs-r8a7791" for r8a7791 (R-Car M2-W) compatible device
- "renesas,usbhs-r8a7792" for r8a7792 (R-Car V2H) compatible device - "renesas,usbhs-r8a7792" for r8a7792 (R-Car V2H) compatible device
...@@ -13,10 +15,11 @@ Required properties: ...@@ -13,10 +15,11 @@ Required properties:
- "renesas,usbhs-r8a7795" for r8a7795 (R-Car H3) compatible device - "renesas,usbhs-r8a7795" for r8a7795 (R-Car H3) compatible device
- "renesas,usbhs-r8a7796" for r8a7796 (R-Car M3-W) compatible device - "renesas,usbhs-r8a7796" for r8a7796 (R-Car M3-W) compatible device
- "renesas,usbhs-r8a77965" for r8a77965 (R-Car M3-N) compatible device - "renesas,usbhs-r8a77965" for r8a77965 (R-Car M3-N) compatible device
- "renesas,usbhs-r8a77990" for r8a77990 (R-Car E3) compatible device
- "renesas,usbhs-r8a77995" for r8a77995 (R-Car D3) compatible device - "renesas,usbhs-r8a77995" for r8a77995 (R-Car D3) compatible device
- "renesas,usbhs-r7s72100" for r7s72100 (RZ/A1) compatible device - "renesas,usbhs-r7s72100" for r7s72100 (RZ/A1) compatible device
- "renesas,rcar-gen2-usbhs" for R-Car Gen2 or RZ/G1 compatible devices - "renesas,rcar-gen2-usbhs" for R-Car Gen2 or RZ/G1 compatible devices
- "renesas,rcar-gen3-usbhs" for R-Car Gen3 compatible device - "renesas,rcar-gen3-usbhs" for R-Car Gen3 or RZ/G2 compatible devices
- "renesas,rza1-usbhs" for RZ/A1 compatible device - "renesas,rza1-usbhs" for RZ/A1 compatible device
When compatible with the generic version, nodes must list the When compatible with the generic version, nodes must list the
...@@ -25,7 +28,11 @@ Required properties: ...@@ -25,7 +28,11 @@ Required properties:
- reg: Base address and length of the register for the USBHS - reg: Base address and length of the register for the USBHS
- interrupts: Interrupt specifier for the USBHS - interrupts: Interrupt specifier for the USBHS
- clocks: A list of phandle + clock specifier pairs - clocks: A list of phandle + clock specifier pairs.
- In case of "renesas,rcar-gen3-usbhs", two clocks are required.
First clock should be peripheral and second one should be host.
- In case of except above, one clock is required. First clock
should be peripheral.
Optional properties: Optional properties:
- renesas,buswait: Integer to use BUSWAIT register - renesas,buswait: Integer to use BUSWAIT register
......
...@@ -15,7 +15,11 @@ Optional properties: ...@@ -15,7 +15,11 @@ Optional properties:
- needs-reset-on-resume : boolean, set this to force EHCI reset after resume - needs-reset-on-resume : boolean, set this to force EHCI reset after resume
- has-transaction-translator : boolean, set this if EHCI have a Transaction - has-transaction-translator : boolean, set this if EHCI have a Transaction
Translator built into the root hub. Translator built into the root hub.
- clocks : a list of phandle + clock specifier pairs - clocks : a list of phandle + clock specifier pairs. In case of Renesas
R-Car Gen3 SoCs:
- if a host only channel: first clock should be host.
- if a USB DRD channel: first clock should be host and second one
should be peripheral.
- phys : see usb-hcd.txt in the current directory - phys : see usb-hcd.txt in the current directory
- resets : phandle + reset specifier pair - resets : phandle + reset specifier pair
......
...@@ -12,7 +12,11 @@ Optional properties: ...@@ -12,7 +12,11 @@ Optional properties:
- no-big-frame-no : boolean, set if frame_no lives in bits [15:0] of HCCA - no-big-frame-no : boolean, set if frame_no lives in bits [15:0] of HCCA
- remote-wakeup-connected: remote wakeup is wired on the platform - remote-wakeup-connected: remote wakeup is wired on the platform
- num-ports : u32, to override the detected port count - num-ports : u32, to override the detected port count
- clocks : a list of phandle + clock specifier pairs - clocks : a list of phandle + clock specifier pairs. In case of Renesas
R-Car Gen3 SoCs:
- if a host only channel: first clock should be host.
- if a USB DRD channel: first clock should be host and second one
should be peripheral.
- phys : see usb-hcd.txt in the current directory - phys : see usb-hcd.txt in the current directory
- resets : a list of phandle + reset specifier pairs - resets : a list of phandle + reset specifier pairs
......
...@@ -8,6 +8,8 @@ Required properties: ...@@ -8,6 +8,8 @@ Required properties:
- "marvell,armada-375-xhci" for Armada 375 SoCs - "marvell,armada-375-xhci" for Armada 375 SoCs
- "marvell,armada-380-xhci" for Armada 38x SoCs - "marvell,armada-380-xhci" for Armada 38x SoCs
- "renesas,xhci-r8a7743" for r8a7743 SoC - "renesas,xhci-r8a7743" for r8a7743 SoC
- "renesas,xhci-r8a7744" for r8a7744 SoC
- "renesas,xhci-r8a774a1" for r8a774a1 SoC
- "renesas,xhci-r8a7790" for r8a7790 SoC - "renesas,xhci-r8a7790" for r8a7790 SoC
- "renesas,xhci-r8a7791" for r8a7791 SoC - "renesas,xhci-r8a7791" for r8a7791 SoC
- "renesas,xhci-r8a7793" for r8a7793 SoC - "renesas,xhci-r8a7793" for r8a7793 SoC
...@@ -17,7 +19,8 @@ Required properties: ...@@ -17,7 +19,8 @@ Required properties:
- "renesas,xhci-r8a77990" for r8a77990 SoC - "renesas,xhci-r8a77990" for r8a77990 SoC
- "renesas,rcar-gen2-xhci" for a generic R-Car Gen2 or RZ/G1 compatible - "renesas,rcar-gen2-xhci" for a generic R-Car Gen2 or RZ/G1 compatible
device device
- "renesas,rcar-gen3-xhci" for a generic R-Car Gen3 compatible device - "renesas,rcar-gen3-xhci" for a generic R-Car Gen3 or RZ/G2 compatible
device
- "xhci-platform" (deprecated) - "xhci-platform" (deprecated)
When compatible with the generic version, nodes must list the When compatible with the generic version, nodes must list the
......
...@@ -201,7 +201,7 @@ Code Seq#(hex) Include File Comments ...@@ -201,7 +201,7 @@ Code Seq#(hex) Include File Comments
'X' 01 linux/pktcdvd.h conflict! 'X' 01 linux/pktcdvd.h conflict!
'Y' all linux/cyclades.h 'Y' all linux/cyclades.h
'Z' 14-15 drivers/message/fusion/mptctl.h 'Z' 14-15 drivers/message/fusion/mptctl.h
'[' 00-07 linux/usb/tmc.h USB Test and Measurement Devices '[' 00-3F linux/usb/tmc.h USB Test and Measurement Devices
<mailto:gregkh@linuxfoundation.org> <mailto:gregkh@linuxfoundation.org>
'a' all linux/atm*.h, linux/sonet.h ATM on linux 'a' all linux/atm*.h, linux/sonet.h ATM on linux
<http://lrcwww.epfl.ch/> <http://lrcwww.epfl.ch/>
......
...@@ -15443,6 +15443,12 @@ F: Documentation/driver-api/usb/typec_bus.rst ...@@ -15443,6 +15443,12 @@ F: Documentation/driver-api/usb/typec_bus.rst
F: drivers/usb/typec/altmodes/ F: drivers/usb/typec/altmodes/
F: include/linux/usb/typec_altmode.h F: include/linux/usb/typec_altmode.h
USB TYPEC PORT CONTROLLER DRIVERS
M: Guenter Roeck <linux@roeck-us.net>
L: linux-usb@vger.kernel.org
S: Maintained
F: drivers/usb/typec/tcpm/
USB UHCI DRIVER USB UHCI DRIVER
M: Alan Stern <stern@rowland.harvard.edu> M: Alan Stern <stern@rowland.harvard.edu>
L: linux-usb@vger.kernel.org L: linux-usb@vger.kernel.org
......
...@@ -277,21 +277,12 @@ struct platform_device pxa168_device_u2o = { ...@@ -277,21 +277,12 @@ struct platform_device pxa168_device_u2o = {
#if IS_ENABLED(CONFIG_USB_EHCI_MV_U2O) #if IS_ENABLED(CONFIG_USB_EHCI_MV_U2O)
struct resource pxa168_u2oehci_resources[] = { struct resource pxa168_u2oehci_resources[] = {
/* regbase */
[0] = { [0] = {
.start = PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET, .start = PXA168_U2O_REGBASE,
.end = PXA168_U2O_REGBASE + USB_REG_RANGE, .end = PXA168_U2O_REGBASE + USB_REG_RANGE,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
.name = "capregs",
}, },
/* phybase */
[1] = { [1] = {
.start = PXA168_U2O_PHYBASE,
.end = PXA168_U2O_PHYBASE + USB_PHY_RANGE,
.flags = IORESOURCE_MEM,
.name = "phyregs",
},
[2] = {
.start = IRQ_PXA168_USB1, .start = IRQ_PXA168_USB1,
.end = IRQ_PXA168_USB1, .end = IRQ_PXA168_USB1,
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
......
...@@ -116,6 +116,7 @@ static void em28xx_audio_isocirq(struct urb *urb) ...@@ -116,6 +116,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
stride = runtime->frame_bits >> 3; stride = runtime->frame_bits >> 3;
for (i = 0; i < urb->number_of_packets; i++) { for (i = 0; i < urb->number_of_packets; i++) {
unsigned long flags;
int length = int length =
urb->iso_frame_desc[i].actual_length / stride; urb->iso_frame_desc[i].actual_length / stride;
cp = (unsigned char *)urb->transfer_buffer + cp = (unsigned char *)urb->transfer_buffer +
...@@ -137,7 +138,7 @@ static void em28xx_audio_isocirq(struct urb *urb) ...@@ -137,7 +138,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
length * stride); length * stride);
} }
snd_pcm_stream_lock(substream); snd_pcm_stream_lock_irqsave(substream, flags);
dev->adev.hwptr_done_capture += length; dev->adev.hwptr_done_capture += length;
if (dev->adev.hwptr_done_capture >= if (dev->adev.hwptr_done_capture >=
...@@ -153,7 +154,7 @@ static void em28xx_audio_isocirq(struct urb *urb) ...@@ -153,7 +154,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
period_elapsed = 1; period_elapsed = 1;
} }
snd_pcm_stream_unlock(substream); snd_pcm_stream_unlock_irqrestore(substream, flags);
} }
if (period_elapsed) if (period_elapsed)
snd_pcm_period_elapsed(substream); snd_pcm_period_elapsed(substream);
......
...@@ -777,6 +777,7 @@ EXPORT_SYMBOL_GPL(em28xx_set_mode); ...@@ -777,6 +777,7 @@ EXPORT_SYMBOL_GPL(em28xx_set_mode);
static void em28xx_irq_callback(struct urb *urb) static void em28xx_irq_callback(struct urb *urb)
{ {
struct em28xx *dev = urb->context; struct em28xx *dev = urb->context;
unsigned long flags;
int i; int i;
switch (urb->status) { switch (urb->status) {
...@@ -793,9 +794,9 @@ static void em28xx_irq_callback(struct urb *urb) ...@@ -793,9 +794,9 @@ static void em28xx_irq_callback(struct urb *urb)
} }
/* Copy data from URB */ /* Copy data from URB */
spin_lock(&dev->slock); spin_lock_irqsave(&dev->slock, flags);
dev->usb_ctl.urb_data_copy(dev, urb); dev->usb_ctl.urb_data_copy(dev, urb);
spin_unlock(&dev->slock); spin_unlock_irqrestore(&dev->slock, flags);
/* Reset urb buffers */ /* Reset urb buffers */
for (i = 0; i < urb->number_of_packets; i++) { for (i = 0; i < urb->number_of_packets; i++) {
......
...@@ -419,6 +419,7 @@ static void tm6000_irq_callback(struct urb *urb) ...@@ -419,6 +419,7 @@ static void tm6000_irq_callback(struct urb *urb)
{ {
struct tm6000_dmaqueue *dma_q = urb->context; struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq); struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
unsigned long flags;
int i; int i;
switch (urb->status) { switch (urb->status) {
...@@ -436,9 +437,9 @@ static void tm6000_irq_callback(struct urb *urb) ...@@ -436,9 +437,9 @@ static void tm6000_irq_callback(struct urb *urb)
break; break;
} }
spin_lock(&dev->slock); spin_lock_irqsave(&dev->slock, flags);
tm6000_isoc_copy(urb); tm6000_isoc_copy(urb);
spin_unlock(&dev->slock); spin_unlock_irqrestore(&dev->slock, flags);
/* Reset urb buffers */ /* Reset urb buffers */
for (i = 0; i < urb->number_of_packets; i++) { for (i = 0; i < urb->number_of_packets; i++) {
......
...@@ -43,6 +43,7 @@ config PHY_XGENE ...@@ -43,6 +43,7 @@ config PHY_XGENE
source "drivers/phy/allwinner/Kconfig" source "drivers/phy/allwinner/Kconfig"
source "drivers/phy/amlogic/Kconfig" source "drivers/phy/amlogic/Kconfig"
source "drivers/phy/broadcom/Kconfig" source "drivers/phy/broadcom/Kconfig"
source "drivers/phy/cadence/Kconfig"
source "drivers/phy/hisilicon/Kconfig" source "drivers/phy/hisilicon/Kconfig"
source "drivers/phy/lantiq/Kconfig" source "drivers/phy/lantiq/Kconfig"
source "drivers/phy/marvell/Kconfig" source "drivers/phy/marvell/Kconfig"
...@@ -54,6 +55,7 @@ source "drivers/phy/ralink/Kconfig" ...@@ -54,6 +55,7 @@ source "drivers/phy/ralink/Kconfig"
source "drivers/phy/renesas/Kconfig" source "drivers/phy/renesas/Kconfig"
source "drivers/phy/rockchip/Kconfig" source "drivers/phy/rockchip/Kconfig"
source "drivers/phy/samsung/Kconfig" source "drivers/phy/samsung/Kconfig"
source "drivers/phy/socionext/Kconfig"
source "drivers/phy/st/Kconfig" source "drivers/phy/st/Kconfig"
source "drivers/phy/tegra/Kconfig" source "drivers/phy/tegra/Kconfig"
source "drivers/phy/ti/Kconfig" source "drivers/phy/ti/Kconfig"
......
...@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_RENESAS) += renesas/ ...@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_RENESAS) += renesas/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-y += broadcom/ \ obj-y += broadcom/ \
cadence/ \
hisilicon/ \ hisilicon/ \
marvell/ \ marvell/ \
motorola/ \ motorola/ \
...@@ -22,5 +23,6 @@ obj-y += broadcom/ \ ...@@ -22,5 +23,6 @@ obj-y += broadcom/ \
qualcomm/ \ qualcomm/ \
ralink/ \ ralink/ \
samsung/ \ samsung/ \
socionext/ \
st/ \ st/ \
ti/ ti/
...@@ -60,7 +60,8 @@ config PHY_NS2_USB_DRD ...@@ -60,7 +60,8 @@ config PHY_NS2_USB_DRD
config PHY_BRCM_SATA config PHY_BRCM_SATA
tristate "Broadcom SATA PHY driver" tristate "Broadcom SATA PHY driver"
depends on ARCH_BRCMSTB || ARCH_BCM_IPROC || BMIPS_GENERIC || COMPILE_TEST depends on ARCH_BRCMSTB || ARCH_BCM_IPROC || BMIPS_GENERIC || \
ARCH_BCM_63XX || COMPILE_TEST
depends on OF depends on OF
select GENERIC_PHY select GENERIC_PHY
default ARCH_BCM_IPROC default ARCH_BCM_IPROC
......
...@@ -153,8 +153,8 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev) ...@@ -153,8 +153,8 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev)
struct cygnus_pcie_phy *p; struct cygnus_pcie_phy *p;
if (of_property_read_u32(child, "reg", &id)) { if (of_property_read_u32(child, "reg", &id)) {
dev_err(dev, "missing reg property for %s\n", dev_err(dev, "missing reg property for %pOFn\n",
child->name); child);
ret = -EINVAL; ret = -EINVAL;
goto put_child; goto put_child;
} }
......
...@@ -47,6 +47,7 @@ enum brcm_sata_phy_version { ...@@ -47,6 +47,7 @@ enum brcm_sata_phy_version {
BRCM_SATA_PHY_IPROC_NS2, BRCM_SATA_PHY_IPROC_NS2,
BRCM_SATA_PHY_IPROC_NSP, BRCM_SATA_PHY_IPROC_NSP,
BRCM_SATA_PHY_IPROC_SR, BRCM_SATA_PHY_IPROC_SR,
BRCM_SATA_PHY_DSL_28NM,
}; };
enum brcm_sata_phy_rxaeq_mode { enum brcm_sata_phy_rxaeq_mode {
...@@ -96,7 +97,10 @@ enum sata_phy_regs { ...@@ -96,7 +97,10 @@ enum sata_phy_regs {
PLLCONTROL_0_FREQ_DET_RESTART = BIT(13), PLLCONTROL_0_FREQ_DET_RESTART = BIT(13),
PLLCONTROL_0_FREQ_MONITOR = BIT(12), PLLCONTROL_0_FREQ_MONITOR = BIT(12),
PLLCONTROL_0_SEQ_START = BIT(15), PLLCONTROL_0_SEQ_START = BIT(15),
PLL_CAP_CHARGE_TIME = 0x83,
PLL_VCO_CAL_THRESH = 0x84,
PLL_CAP_CONTROL = 0x85, PLL_CAP_CONTROL = 0x85,
PLL_FREQ_DET_TIME = 0x86,
PLL_ACTRL2 = 0x8b, PLL_ACTRL2 = 0x8b,
PLL_ACTRL2_SELDIV_MASK = 0x1f, PLL_ACTRL2_SELDIV_MASK = 0x1f,
PLL_ACTRL2_SELDIV_SHIFT = 9, PLL_ACTRL2_SELDIV_SHIFT = 9,
...@@ -106,6 +110,9 @@ enum sata_phy_regs { ...@@ -106,6 +110,9 @@ enum sata_phy_regs {
PLL1_ACTRL2 = 0x82, PLL1_ACTRL2 = 0x82,
PLL1_ACTRL3 = 0x83, PLL1_ACTRL3 = 0x83,
PLL1_ACTRL4 = 0x84, PLL1_ACTRL4 = 0x84,
PLL1_ACTRL5 = 0x85,
PLL1_ACTRL6 = 0x86,
PLL1_ACTRL7 = 0x87,
TX_REG_BANK = 0x070, TX_REG_BANK = 0x070,
TX_ACTRL0 = 0x80, TX_ACTRL0 = 0x80,
...@@ -119,6 +126,8 @@ enum sata_phy_regs { ...@@ -119,6 +126,8 @@ enum sata_phy_regs {
AEQ_FRC_EQ_FORCE = BIT(0), AEQ_FRC_EQ_FORCE = BIT(0),
AEQ_FRC_EQ_FORCE_VAL = BIT(1), AEQ_FRC_EQ_FORCE_VAL = BIT(1),
AEQRX_REG_BANK_1 = 0xe0, AEQRX_REG_BANK_1 = 0xe0,
AEQRX_SLCAL0_CTRL0 = 0x82,
AEQRX_SLCAL1_CTRL0 = 0x86,
OOB_REG_BANK = 0x150, OOB_REG_BANK = 0x150,
OOB1_REG_BANK = 0x160, OOB1_REG_BANK = 0x160,
...@@ -168,6 +177,7 @@ static inline void __iomem *brcm_sata_pcb_base(struct brcm_sata_port *port) ...@@ -168,6 +177,7 @@ static inline void __iomem *brcm_sata_pcb_base(struct brcm_sata_port *port)
switch (priv->version) { switch (priv->version) {
case BRCM_SATA_PHY_STB_28NM: case BRCM_SATA_PHY_STB_28NM:
case BRCM_SATA_PHY_IPROC_NS2: case BRCM_SATA_PHY_IPROC_NS2:
case BRCM_SATA_PHY_DSL_28NM:
size = SATA_PCB_REG_28NM_SPACE_SIZE; size = SATA_PCB_REG_28NM_SPACE_SIZE;
break; break;
case BRCM_SATA_PHY_STB_40NM: case BRCM_SATA_PHY_STB_40NM:
...@@ -482,6 +492,61 @@ static int brcm_sr_sata_init(struct brcm_sata_port *port) ...@@ -482,6 +492,61 @@ static int brcm_sr_sata_init(struct brcm_sata_port *port)
return 0; return 0;
} }
static int brcm_dsl_sata_init(struct brcm_sata_port *port)
{
void __iomem *base = brcm_sata_pcb_base(port);
struct device *dev = port->phy_priv->dev;
unsigned int try;
u32 tmp;
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL7, 0, 0x873);
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL6, 0, 0xc000);
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
0, 0x3089);
usleep_range(1000, 2000);
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
0, 0x3088);
usleep_range(1000, 2000);
brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, AEQRX_SLCAL0_CTRL0,
0, 0x3000);
brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, AEQRX_SLCAL1_CTRL0,
0, 0x3000);
usleep_range(1000, 2000);
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_CAP_CHARGE_TIME, 0, 0x32);
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_VCO_CAL_THRESH, 0, 0xa);
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_FREQ_DET_TIME, 0, 0x64);
usleep_range(1000, 2000);
/* Acquire PLL lock */
try = 50;
while (try) {
tmp = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
BLOCK0_XGXSSTATUS);
if (tmp & BLOCK0_XGXSSTATUS_PLL_LOCK)
break;
msleep(20);
try--;
};
if (!try) {
/* PLL did not lock; give up */
dev_err(dev, "port%d PLL did not lock\n", port->portnum);
return -ETIMEDOUT;
}
dev_dbg(dev, "port%d initialized\n", port->portnum);
return 0;
}
static int brcm_sata_phy_init(struct phy *phy) static int brcm_sata_phy_init(struct phy *phy)
{ {
int rc; int rc;
...@@ -501,6 +566,9 @@ static int brcm_sata_phy_init(struct phy *phy) ...@@ -501,6 +566,9 @@ static int brcm_sata_phy_init(struct phy *phy)
case BRCM_SATA_PHY_IPROC_SR: case BRCM_SATA_PHY_IPROC_SR:
rc = brcm_sr_sata_init(port); rc = brcm_sr_sata_init(port);
break; break;
case BRCM_SATA_PHY_DSL_28NM:
rc = brcm_dsl_sata_init(port);
break;
default: default:
rc = -ENODEV; rc = -ENODEV;
} }
...@@ -552,6 +620,8 @@ static const struct of_device_id brcm_sata_phy_of_match[] = { ...@@ -552,6 +620,8 @@ static const struct of_device_id brcm_sata_phy_of_match[] = {
.data = (void *)BRCM_SATA_PHY_IPROC_NSP }, .data = (void *)BRCM_SATA_PHY_IPROC_NSP },
{ .compatible = "brcm,iproc-sr-sata-phy", { .compatible = "brcm,iproc-sr-sata-phy",
.data = (void *)BRCM_SATA_PHY_IPROC_SR }, .data = (void *)BRCM_SATA_PHY_IPROC_SR },
{ .compatible = "brcm,bcm63138-sata-phy",
.data = (void *)BRCM_SATA_PHY_DSL_28NM },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match); MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);
...@@ -600,8 +670,8 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) ...@@ -600,8 +670,8 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
struct brcm_sata_port *port; struct brcm_sata_port *port;
if (of_property_read_u32(child, "reg", &id)) { if (of_property_read_u32(child, "reg", &id)) {
dev_err(dev, "missing reg property in node %s\n", dev_err(dev, "missing reg property in node %pOFn\n",
child->name); child);
ret = -EINVAL; ret = -EINVAL;
goto put_child; goto put_child;
} }
......
...@@ -372,10 +372,8 @@ static int brcm_usb_phy_probe(struct platform_device *pdev) ...@@ -372,10 +372,8 @@ static int brcm_usb_phy_probe(struct platform_device *pdev)
clk_disable(priv->usb_30_clk); clk_disable(priv->usb_30_clk);
phy_provider = devm_of_phy_provider_register(dev, brcm_usb_phy_xlate); phy_provider = devm_of_phy_provider_register(dev, brcm_usb_phy_xlate);
if (IS_ERR(phy_provider))
return PTR_ERR(phy_provider);
return 0; return PTR_ERR_OR_ZERO(phy_provider);
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
......
#
# Phy driver for Cadence MHDP DisplayPort controller
#
config PHY_CADENCE_DP
tristate "Cadence MHDP DisplayPort PHY driver"
depends on OF
depends on HAS_IOMEM
select GENERIC_PHY
help
Support for Cadence MHDP DisplayPort PHY.
obj-$(CONFIG_PHY_CADENCE_DP) += phy-cadence-dp.o
This diff is collapsed.
...@@ -156,7 +156,6 @@ static int ltq_rcu_usb2_of_parse(struct ltq_rcu_usb2_priv *priv, ...@@ -156,7 +156,6 @@ static int ltq_rcu_usb2_of_parse(struct ltq_rcu_usb2_priv *priv,
{ {
struct device *dev = priv->dev; struct device *dev = priv->dev;
const __be32 *offset; const __be32 *offset;
int ret;
priv->reg_bits = of_device_get_match_data(dev); priv->reg_bits = of_device_get_match_data(dev);
...@@ -196,10 +195,8 @@ static int ltq_rcu_usb2_of_parse(struct ltq_rcu_usb2_priv *priv, ...@@ -196,10 +195,8 @@ static int ltq_rcu_usb2_of_parse(struct ltq_rcu_usb2_priv *priv,
} }
priv->phy_reset = devm_reset_control_get_optional(dev, "phy"); priv->phy_reset = devm_reset_control_get_optional(dev, "phy");
if (IS_ERR(priv->phy_reset))
return PTR_ERR(priv->phy_reset);
return 0; return PTR_ERR_OR_ZERO(priv->phy_reset);
} }
static int ltq_rcu_usb2_phy_probe(struct platform_device *pdev) static int ltq_rcu_usb2_phy_probe(struct platform_device *pdev)
......
...@@ -59,3 +59,14 @@ config PHY_PXA_28NM_USB2 ...@@ -59,3 +59,14 @@ config PHY_PXA_28NM_USB2
The PHY driver will be used by Marvell udc/ehci/otg driver. The PHY driver will be used by Marvell udc/ehci/otg driver.
To compile this driver as a module, choose M here. To compile this driver as a module, choose M here.
config PHY_PXA_USB
tristate "Marvell PXA USB PHY Driver"
depends on ARCH_PXA || ARCH_MMP
select GENERIC_PHY
help
Enable this to support Marvell PXA USB PHY driver for Marvell
SoC. This driver will do the PHY initialization and shutdown.
The PHY driver will be used by Marvell udc/ehci/otg driver.
To compile this driver as a module, choose M here.
...@@ -6,3 +6,4 @@ obj-$(CONFIG_PHY_MVEBU_CP110_COMPHY) += phy-mvebu-cp110-comphy.o ...@@ -6,3 +6,4 @@ obj-$(CONFIG_PHY_MVEBU_CP110_COMPHY) += phy-mvebu-cp110-comphy.o
obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o
obj-$(CONFIG_PHY_PXA_28NM_USB2) += phy-pxa-28nm-usb2.o obj-$(CONFIG_PHY_PXA_28NM_USB2) += phy-pxa-28nm-usb2.o
obj-$(CONFIG_PHY_PXA_USB) += phy-pxa-usb.o
...@@ -231,14 +231,14 @@ static int phy_berlin_sata_probe(struct platform_device *pdev) ...@@ -231,14 +231,14 @@ static int phy_berlin_sata_probe(struct platform_device *pdev)
struct phy_berlin_desc *phy_desc; struct phy_berlin_desc *phy_desc;
if (of_property_read_u32(child, "reg", &phy_id)) { if (of_property_read_u32(child, "reg", &phy_id)) {
dev_err(dev, "missing reg property in node %s\n", dev_err(dev, "missing reg property in node %pOFn\n",
child->name); child);
ret = -EINVAL; ret = -EINVAL;
goto put_child; goto put_child;
} }
if (phy_id >= ARRAY_SIZE(phy_berlin_power_down_bits)) { if (phy_id >= ARRAY_SIZE(phy_berlin_power_down_bits)) {
dev_err(dev, "invalid reg in node %s\n", child->name); dev_err(dev, "invalid reg in node %pOFn\n", child);
ret = -EINVAL; ret = -EINVAL;
goto put_child; goto put_child;
} }
......
This diff is collapsed.
...@@ -50,6 +50,23 @@ config PHY_QCOM_UFS ...@@ -50,6 +50,23 @@ config PHY_QCOM_UFS
help help
Support for UFS PHY on QCOM chipsets. Support for UFS PHY on QCOM chipsets.
if PHY_QCOM_UFS
config PHY_QCOM_UFS_14NM
tristate
default PHY_QCOM_UFS
help
Support for 14nm UFS QMP phy present on QCOM chipsets.
config PHY_QCOM_UFS_20NM
tristate
default PHY_QCOM_UFS
depends on BROKEN
help
Support for 20nm UFS QMP phy present on QCOM chipsets.
endif
config PHY_QCOM_USB_HS config PHY_QCOM_USB_HS
tristate "Qualcomm USB HS PHY module" tristate "Qualcomm USB HS PHY module"
depends on USB_ULPI_BUS depends on USB_ULPI_BUS
......
...@@ -5,7 +5,7 @@ obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o ...@@ -5,7 +5,7 @@ obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.o obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.o
obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o obj-$(CONFIG_PHY_QCOM_UFS_14NM) += phy-qcom-ufs-qmp-14nm.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o obj-$(CONFIG_PHY_QCOM_UFS_20NM) += phy-qcom-ufs-qmp-20nm.o
obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o
obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o
This diff is collapsed.
...@@ -184,6 +184,8 @@ ...@@ -184,6 +184,8 @@
#define QSERDES_V3_COM_VCO_TUNE2_MODE0 0x0f8 #define QSERDES_V3_COM_VCO_TUNE2_MODE0 0x0f8
#define QSERDES_V3_COM_VCO_TUNE1_MODE1 0x0fc #define QSERDES_V3_COM_VCO_TUNE1_MODE1 0x0fc
#define QSERDES_V3_COM_VCO_TUNE2_MODE1 0x100 #define QSERDES_V3_COM_VCO_TUNE2_MODE1 0x100
#define QSERDES_V3_COM_VCO_TUNE_INITVAL1 0x104
#define QSERDES_V3_COM_VCO_TUNE_INITVAL2 0x108
#define QSERDES_V3_COM_VCO_TUNE_TIMER1 0x11c #define QSERDES_V3_COM_VCO_TUNE_TIMER1 0x11c
#define QSERDES_V3_COM_VCO_TUNE_TIMER2 0x120 #define QSERDES_V3_COM_VCO_TUNE_TIMER2 0x120
#define QSERDES_V3_COM_CLK_SELECT 0x138 #define QSERDES_V3_COM_CLK_SELECT 0x138
...@@ -211,8 +213,13 @@ ...@@ -211,8 +213,13 @@
/* Only for QMP V3 PHY - RX registers */ /* Only for QMP V3 PHY - RX registers */
#define QSERDES_V3_RX_UCDR_SO_GAIN_HALF 0x00c #define QSERDES_V3_RX_UCDR_SO_GAIN_HALF 0x00c
#define QSERDES_V3_RX_UCDR_SO_GAIN 0x014 #define QSERDES_V3_RX_UCDR_SO_GAIN 0x014
#define QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF 0x024
#define QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER 0x028
#define QSERDES_V3_RX_UCDR_SVS_SO_GAIN 0x02c
#define QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN 0x030 #define QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN 0x030
#define QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE 0x034 #define QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE 0x034
#define QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW 0x03c
#define QSERDES_V3_RX_UCDR_PI_CONTROLS 0x044
#define QSERDES_V3_RX_RX_TERM_BW 0x07c #define QSERDES_V3_RX_RX_TERM_BW 0x07c
#define QSERDES_V3_RX_VGA_CAL_CNTRL1 0x0bc #define QSERDES_V3_RX_VGA_CAL_CNTRL1 0x0bc
#define QSERDES_V3_RX_VGA_CAL_CNTRL2 0x0c0 #define QSERDES_V3_RX_VGA_CAL_CNTRL2 0x0c0
...@@ -239,6 +246,8 @@ ...@@ -239,6 +246,8 @@
#define QPHY_V3_PCS_TXMGN_V3 0x018 #define QPHY_V3_PCS_TXMGN_V3 0x018
#define QPHY_V3_PCS_TXMGN_V4 0x01c #define QPHY_V3_PCS_TXMGN_V4 0x01c
#define QPHY_V3_PCS_TXMGN_LS 0x020 #define QPHY_V3_PCS_TXMGN_LS 0x020
#define QPHY_V3_PCS_TX_LARGE_AMP_DRV_LVL 0x02c
#define QPHY_V3_PCS_TX_SMALL_AMP_DRV_LVL 0x034
#define QPHY_V3_PCS_TXDEEMPH_M6DB_V0 0x024 #define QPHY_V3_PCS_TXDEEMPH_M6DB_V0 0x024
#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0 0x028 #define QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0 0x028
#define QPHY_V3_PCS_TXDEEMPH_M6DB_V1 0x02c #define QPHY_V3_PCS_TXDEEMPH_M6DB_V1 0x02c
...@@ -275,6 +284,12 @@ ...@@ -275,6 +284,12 @@
#define QPHY_V3_PCS_FLL_CNT_VAL_L 0x0cc #define QPHY_V3_PCS_FLL_CNT_VAL_L 0x0cc
#define QPHY_V3_PCS_FLL_CNT_VAL_H_TOL 0x0d0 #define QPHY_V3_PCS_FLL_CNT_VAL_H_TOL 0x0d0
#define QPHY_V3_PCS_FLL_MAN_CODE 0x0d4 #define QPHY_V3_PCS_FLL_MAN_CODE 0x0d4
#define QPHY_V3_PCS_RX_SYM_RESYNC_CTRL 0x134
#define QPHY_V3_PCS_RX_MIN_HIBERN8_TIME 0x138
#define QPHY_V3_PCS_RX_SIGDET_CTRL1 0x13c
#define QPHY_V3_PCS_RX_SIGDET_CTRL2 0x140
#define QPHY_V3_PCS_TX_MID_TERM_CTRL1 0x1bc
#define QPHY_V3_PCS_MULTI_LANE_CTRL1 0x1c4
#define QPHY_V3_PCS_RX_SIGDET_LVL 0x1d8 #define QPHY_V3_PCS_RX_SIGDET_LVL 0x1d8
#define QPHY_V3_PCS_REFGEN_REQ_CONFIG1 0x20c #define QPHY_V3_PCS_REFGEN_REQ_CONFIG1 0x20c
#define QPHY_V3_PCS_REFGEN_REQ_CONFIG2 0x210 #define QPHY_V3_PCS_REFGEN_REQ_CONFIG2 0x210
......
...@@ -800,7 +800,9 @@ static int qusb2_phy_probe(struct platform_device *pdev) ...@@ -800,7 +800,9 @@ static int qusb2_phy_probe(struct platform_device *pdev)
ret = devm_regulator_bulk_get(dev, num, qphy->vregs); ret = devm_regulator_bulk_get(dev, num, qphy->vregs);
if (ret) { if (ret) {
dev_err(dev, "failed to get regulator supplies\n"); if (ret != -EPROBE_DEFER)
dev_err(dev, "failed to get regulator supplies: %d\n",
ret);
return ret; return ret;
} }
......
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/phy/phy.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/phy/phy-qcom-ufs.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/delay.h> #include <linux/delay.h>
......
...@@ -431,56 +431,6 @@ static void ufs_qcom_phy_disable_ref_clk(struct ufs_qcom_phy *phy) ...@@ -431,56 +431,6 @@ static void ufs_qcom_phy_disable_ref_clk(struct ufs_qcom_phy *phy)
} }
} }
#define UFS_REF_CLK_EN (1 << 5)
static void ufs_qcom_phy_dev_ref_clk_ctrl(struct phy *generic_phy, bool enable)
{
struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
if (phy->dev_ref_clk_ctrl_mmio &&
(enable ^ phy->is_dev_ref_clk_enabled)) {
u32 temp = readl_relaxed(phy->dev_ref_clk_ctrl_mmio);
if (enable)
temp |= UFS_REF_CLK_EN;
else
temp &= ~UFS_REF_CLK_EN;
/*
* If we are here to disable this clock immediately after
* entering into hibern8, we need to make sure that device
* ref_clk is active atleast 1us after the hibern8 enter.
*/
if (!enable)
udelay(1);
writel_relaxed(temp, phy->dev_ref_clk_ctrl_mmio);
/* ensure that ref_clk is enabled/disabled before we return */
wmb();
/*
* If we call hibern8 exit after this, we need to make sure that
* device ref_clk is stable for atleast 1us before the hibern8
* exit command.
*/
if (enable)
udelay(1);
phy->is_dev_ref_clk_enabled = enable;
}
}
void ufs_qcom_phy_enable_dev_ref_clk(struct phy *generic_phy)
{
ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, true);
}
EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_dev_ref_clk);
void ufs_qcom_phy_disable_dev_ref_clk(struct phy *generic_phy)
{
ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, false);
}
EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_dev_ref_clk);
/* Turn ON M-PHY RMMI interface clocks */ /* Turn ON M-PHY RMMI interface clocks */
static int ufs_qcom_phy_enable_iface_clk(struct ufs_qcom_phy *phy) static int ufs_qcom_phy_enable_iface_clk(struct ufs_qcom_phy *phy)
{ {
......
# SPDX-License-Identifier: GPL-2.0
# #
# Phy drivers for Renesas platforms # Phy drivers for Renesas platforms
# #
......
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o
obj-$(CONFIG_PHY_RCAR_GEN3_PCIE) += phy-rcar-gen3-pcie.o obj-$(CONFIG_PHY_RCAR_GEN3_PCIE) += phy-rcar-gen3-pcie.o
obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o
......
// SPDX-License-Identifier: GPL-2.0
/* /*
* Renesas R-Car Gen2 PHY driver * Renesas R-Car Gen2 PHY driver
* *
* Copyright (C) 2014 Renesas Solutions Corp. * Copyright (C) 2014 Renesas Solutions Corp.
* Copyright (C) 2014 Cogent Embedded, Inc. * Copyright (C) 2014 Cogent Embedded, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/ */
#include <linux/clk.h> #include <linux/clk.h>
......
// SPDX-License-Identifier: GPL-2.0
/* /*
* Renesas R-Car Gen3 for USB2.0 PHY driver * Renesas R-Car Gen3 for USB2.0 PHY driver
* *
...@@ -6,10 +7,6 @@ ...@@ -6,10 +7,6 @@
* This is based on the phy-rcar-gen2 driver: * This is based on the phy-rcar-gen2 driver:
* Copyright (C) 2014 Renesas Solutions Corp. * Copyright (C) 2014 Renesas Solutions Corp.
* Copyright (C) 2014 Cogent Embedded, Inc. * Copyright (C) 2014 Cogent Embedded, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/ */
#include <linux/extcon-provider.h> #include <linux/extcon-provider.h>
...@@ -81,18 +78,29 @@ ...@@ -81,18 +78,29 @@
#define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */ #define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */
#define USB2_ADPCTRL_DRVVBUS BIT(4) #define USB2_ADPCTRL_DRVVBUS BIT(4)
#define RCAR_GEN3_PHY_HAS_DEDICATED_PINS 1
struct rcar_gen3_chan { struct rcar_gen3_chan {
void __iomem *base; void __iomem *base;
struct extcon_dev *extcon; struct extcon_dev *extcon;
struct phy *phy; struct phy *phy;
struct regulator *vbus; struct regulator *vbus;
struct work_struct work; struct work_struct work;
enum usb_dr_mode dr_mode;
bool extcon_host; bool extcon_host;
bool has_otg_pins; bool is_otg_channel;
bool uses_otg_pins;
}; };
/*
* Combination about is_otg_channel and uses_otg_pins:
*
* Parameters || Behaviors
* is_otg_channel | uses_otg_pins || irqs | role sysfs
* ---------------------+---------------++--------------+------------
* true | true || enabled | enabled
* true | false || disabled | enabled
* false | any || disabled | disabled
*/
static void rcar_gen3_phy_usb2_work(struct work_struct *work) static void rcar_gen3_phy_usb2_work(struct work_struct *work)
{ {
struct rcar_gen3_chan *ch = container_of(work, struct rcar_gen3_chan, struct rcar_gen3_chan *ch = container_of(work, struct rcar_gen3_chan,
...@@ -147,6 +155,18 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus) ...@@ -147,6 +155,18 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
writel(val, usb2_base + USB2_ADPCTRL); writel(val, usb2_base + USB2_ADPCTRL);
} }
static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable)
{
void __iomem *usb2_base = ch->base;
u32 val = readl(usb2_base + USB2_OBINTEN);
if (ch->uses_otg_pins && enable)
val |= USB2_OBINT_BITS;
else
val &= ~USB2_OBINT_BITS;
writel(val, usb2_base + USB2_OBINTEN);
}
static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch) static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch)
{ {
rcar_gen3_set_linectrl(ch, 1, 1); rcar_gen3_set_linectrl(ch, 1, 1);
...@@ -192,20 +212,19 @@ static void rcar_gen3_init_for_a_peri(struct rcar_gen3_chan *ch) ...@@ -192,20 +212,19 @@ static void rcar_gen3_init_for_a_peri(struct rcar_gen3_chan *ch)
static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch) static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch)
{ {
void __iomem *usb2_base = ch->base; rcar_gen3_control_otg_irq(ch, 0);
u32 val;
val = readl(usb2_base + USB2_OBINTEN); rcar_gen3_enable_vbus_ctrl(ch, 1);
writel(val & ~USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
rcar_gen3_enable_vbus_ctrl(ch, 0);
rcar_gen3_init_for_host(ch); rcar_gen3_init_for_host(ch);
writel(val | USB2_OBINT_BITS, usb2_base + USB2_OBINTEN); rcar_gen3_control_otg_irq(ch, 1);
} }
static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch) static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
{ {
if (!ch->uses_otg_pins)
return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true;
return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
} }
...@@ -237,7 +256,7 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr, ...@@ -237,7 +256,7 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
bool is_b_device; bool is_b_device;
enum phy_mode cur_mode, new_mode; enum phy_mode cur_mode, new_mode;
if (!ch->has_otg_pins || !ch->phy->init_count) if (!ch->is_otg_channel || !ch->phy->init_count)
return -EIO; return -EIO;
if (!strncmp(buf, "host", strlen("host"))) if (!strncmp(buf, "host", strlen("host")))
...@@ -275,7 +294,7 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr, ...@@ -275,7 +294,7 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr,
{ {
struct rcar_gen3_chan *ch = dev_get_drvdata(dev); struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
if (!ch->has_otg_pins || !ch->phy->init_count) if (!ch->is_otg_channel || !ch->phy->init_count)
return -EIO; return -EIO;
return sprintf(buf, "%s\n", rcar_gen3_is_host(ch) ? "host" : return sprintf(buf, "%s\n", rcar_gen3_is_host(ch) ? "host" :
...@@ -291,8 +310,7 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch) ...@@ -291,8 +310,7 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
val = readl(usb2_base + USB2_VBCTRL); val = readl(usb2_base + USB2_VBCTRL);
writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL); writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA); writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
val = readl(usb2_base + USB2_OBINTEN); rcar_gen3_control_otg_irq(ch, 1);
writel(val | USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
val = readl(usb2_base + USB2_ADPCTRL); val = readl(usb2_base + USB2_ADPCTRL);
writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
val = readl(usb2_base + USB2_LINECTRL1); val = readl(usb2_base + USB2_LINECTRL1);
...@@ -314,7 +332,7 @@ static int rcar_gen3_phy_usb2_init(struct phy *p) ...@@ -314,7 +332,7 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET); writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
/* Initialize otg part */ /* Initialize otg part */
if (channel->has_otg_pins) if (channel->is_otg_channel)
rcar_gen3_init_otg(channel); rcar_gen3_init_otg(channel);
return 0; return 0;
...@@ -388,21 +406,10 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) ...@@ -388,21 +406,10 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
} }
static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
{ { .compatible = "renesas,usb2-phy-r8a7795" },
.compatible = "renesas,usb2-phy-r8a7795", { .compatible = "renesas,usb2-phy-r8a7796" },
.data = (void *)RCAR_GEN3_PHY_HAS_DEDICATED_PINS, { .compatible = "renesas,usb2-phy-r8a77965" },
}, { .compatible = "renesas,rcar-gen3-usb2-phy" },
{
.compatible = "renesas,usb2-phy-r8a7796",
.data = (void *)RCAR_GEN3_PHY_HAS_DEDICATED_PINS,
},
{
.compatible = "renesas,usb2-phy-r8a77965",
.data = (void *)RCAR_GEN3_PHY_HAS_DEDICATED_PINS,
},
{
.compatible = "renesas,rcar-gen3-usb2-phy",
},
{ } { }
}; };
MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb2_match_table); MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb2_match_table);
...@@ -445,10 +452,13 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) ...@@ -445,10 +452,13 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
dev_err(dev, "No irq handler (%d)\n", irq); dev_err(dev, "No irq handler (%d)\n", irq);
} }
if (of_usb_get_dr_mode_by_phy(dev->of_node, 0) == USB_DR_MODE_OTG) { channel->dr_mode = of_usb_get_dr_mode_by_phy(dev->of_node, 0);
if (channel->dr_mode != USB_DR_MODE_UNKNOWN) {
int ret; int ret;
channel->has_otg_pins = (uintptr_t)of_device_get_match_data(dev); channel->is_otg_channel = true;
channel->uses_otg_pins = !of_property_read_bool(dev->of_node,
"renesas,no-otg-pins");
channel->extcon = devm_extcon_dev_allocate(dev, channel->extcon = devm_extcon_dev_allocate(dev,
rcar_gen3_phy_cable); rcar_gen3_phy_cable);
if (IS_ERR(channel->extcon)) if (IS_ERR(channel->extcon))
...@@ -490,7 +500,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) ...@@ -490,7 +500,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
dev_err(dev, "Failed to register PHY provider\n"); dev_err(dev, "Failed to register PHY provider\n");
ret = PTR_ERR(provider); ret = PTR_ERR(provider);
goto error; goto error;
} else if (channel->has_otg_pins) { } else if (channel->is_otg_channel) {
int ret; int ret;
ret = device_create_file(dev, &dev_attr_role); ret = device_create_file(dev, &dev_attr_role);
...@@ -510,7 +520,7 @@ static int rcar_gen3_phy_usb2_remove(struct platform_device *pdev) ...@@ -510,7 +520,7 @@ static int rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
{ {
struct rcar_gen3_chan *channel = platform_get_drvdata(pdev); struct rcar_gen3_chan *channel = platform_get_drvdata(pdev);
if (channel->has_otg_pins) if (channel->is_otg_channel)
device_remove_file(&pdev->dev, &dev_attr_role); device_remove_file(&pdev->dev, &dev_attr_role);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
......
// SPDX-License-Identifier: GPL-2.0
/* /*
* Renesas R-Car Gen3 for USB3.0 PHY driver * Renesas R-Car Gen3 for USB3.0 PHY driver
* *
* Copyright (C) 2017 Renesas Electronics Corporation * Copyright (C) 2017 Renesas Electronics Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/ */
#include <linux/clk.h> #include <linux/clk.h>
......
...@@ -15,6 +15,14 @@ config PHY_ROCKCHIP_EMMC ...@@ -15,6 +15,14 @@ config PHY_ROCKCHIP_EMMC
help help
Enable this to support the Rockchip EMMC PHY. Enable this to support the Rockchip EMMC PHY.
config PHY_ROCKCHIP_INNO_HDMI
tristate "Rockchip INNO HDMI PHY Driver"
depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
depends on COMMON_CLK
select GENERIC_PHY
help
Enable this to support the Rockchip Innosilicon HDMI PHY.
config PHY_ROCKCHIP_INNO_USB2 config PHY_ROCKCHIP_INNO_USB2
tristate "Rockchip INNO USB2PHY Driver" tristate "Rockchip INNO USB2PHY Driver"
depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
......
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
......
...@@ -337,8 +337,8 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev) ...@@ -337,8 +337,8 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
if (of_property_read_u32(dev->of_node, "reg", &reg_offset)) { if (of_property_read_u32(dev->of_node, "reg", &reg_offset)) {
dev_err(dev, "missing reg property in node %s\n", dev_err(dev, "missing reg property in node %pOFn\n",
dev->of_node->name); dev->of_node);
return -EINVAL; return -EINVAL;
} }
......
This diff is collapsed.
...@@ -1116,8 +1116,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) ...@@ -1116,8 +1116,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
} }
if (of_property_read_u32(np, "reg", &reg)) { if (of_property_read_u32(np, "reg", &reg)) {
dev_err(dev, "the reg property is not assigned in %s node\n", dev_err(dev, "the reg property is not assigned in %pOFn node\n",
np->name); np);
return -EINVAL; return -EINVAL;
} }
...@@ -1143,8 +1143,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) ...@@ -1143,8 +1143,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
} }
if (!rphy->phy_cfg) { if (!rphy->phy_cfg) {
dev_err(dev, "no phy-config can be matched with %s node\n", dev_err(dev, "no phy-config can be matched with %pOFn node\n",
np->name); np);
return -EINVAL; return -EINVAL;
} }
......
...@@ -1145,8 +1145,8 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev) ...@@ -1145,8 +1145,8 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
} }
if (!tcphy->port_cfgs) { if (!tcphy->port_cfgs) {
dev_err(dev, "no phy-config can be matched with %s node\n", dev_err(dev, "no phy-config can be matched with %pOFn node\n",
np->name); np);
return -EINVAL; return -EINVAL;
} }
...@@ -1186,8 +1186,8 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev) ...@@ -1186,8 +1186,8 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
continue; continue;
if (IS_ERR(phy)) { if (IS_ERR(phy)) {
dev_err(dev, "failed to create phy: %s\n", dev_err(dev, "failed to create phy: %pOFn\n",
child_np->name); child_np);
pm_runtime_disable(dev); pm_runtime_disable(dev);
return PTR_ERR(phy); return PTR_ERR(phy);
} }
......
...@@ -36,7 +36,22 @@ static int enable_usb_uart; ...@@ -36,7 +36,22 @@ static int enable_usb_uart;
#define HIWORD_UPDATE(val, mask) \ #define HIWORD_UPDATE(val, mask) \
((val) | (mask) << 16) ((val) | (mask) << 16)
#define UOC_CON0_SIDDQ BIT(13) #define UOC_CON0 0x00
#define UOC_CON0_SIDDQ BIT(13)
#define UOC_CON0_DISABLE BIT(4)
#define UOC_CON0_COMMON_ON_N BIT(0)
#define UOC_CON2 0x08
#define UOC_CON2_SOFT_CON_SEL BIT(2)
#define UOC_CON3 0x0c
/* bits present on rk3188 and rk3288 phys */
#define UOC_CON3_UTMI_TERMSEL_FULLSPEED BIT(5)
#define UOC_CON3_UTMI_XCVRSEELCT_FSTRANSC (1 << 3)
#define UOC_CON3_UTMI_XCVRSEELCT_MASK (3 << 3)
#define UOC_CON3_UTMI_OPMODE_NODRIVING (1 << 1)
#define UOC_CON3_UTMI_OPMODE_MASK (3 << 1)
#define UOC_CON3_UTMI_SUSPENDN BIT(0)
struct rockchip_usb_phys { struct rockchip_usb_phys {
int reg; int reg;
...@@ -46,7 +61,8 @@ struct rockchip_usb_phys { ...@@ -46,7 +61,8 @@ struct rockchip_usb_phys {
struct rockchip_usb_phy_base; struct rockchip_usb_phy_base;
struct rockchip_usb_phy_pdata { struct rockchip_usb_phy_pdata {
struct rockchip_usb_phys *phys; struct rockchip_usb_phys *phys;
int (*init_usb_uart)(struct regmap *grf); int (*init_usb_uart)(struct regmap *grf,
const struct rockchip_usb_phy_pdata *pdata);
int usb_uart_phy; int usb_uart_phy;
}; };
...@@ -208,8 +224,8 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base, ...@@ -208,8 +224,8 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base,
rk_phy->np = child; rk_phy->np = child;
if (of_property_read_u32(child, "reg", &reg_offset)) { if (of_property_read_u32(child, "reg", &reg_offset)) {
dev_err(base->dev, "missing reg property in node %s\n", dev_err(base->dev, "missing reg property in node %pOFn\n",
child->name); child);
return -EINVAL; return -EINVAL;
} }
...@@ -313,28 +329,88 @@ static const struct rockchip_usb_phy_pdata rk3066a_pdata = { ...@@ -313,28 +329,88 @@ static const struct rockchip_usb_phy_pdata rk3066a_pdata = {
}, },
}; };
static int __init rockchip_init_usb_uart_common(struct regmap *grf,
const struct rockchip_usb_phy_pdata *pdata)
{
int regoffs = pdata->phys[pdata->usb_uart_phy].reg;
int ret;
u32 val;
/*
* COMMON_ON and DISABLE settings are described in the TRM,
* but were not present in the original code.
* Also disable the analog phy components to save power.
*/
val = HIWORD_UPDATE(UOC_CON0_COMMON_ON_N
| UOC_CON0_DISABLE
| UOC_CON0_SIDDQ,
UOC_CON0_COMMON_ON_N
| UOC_CON0_DISABLE
| UOC_CON0_SIDDQ);
ret = regmap_write(grf, regoffs + UOC_CON0, val);
if (ret)
return ret;
val = HIWORD_UPDATE(UOC_CON2_SOFT_CON_SEL,
UOC_CON2_SOFT_CON_SEL);
ret = regmap_write(grf, regoffs + UOC_CON2, val);
if (ret)
return ret;
val = HIWORD_UPDATE(UOC_CON3_UTMI_OPMODE_NODRIVING
| UOC_CON3_UTMI_XCVRSEELCT_FSTRANSC
| UOC_CON3_UTMI_TERMSEL_FULLSPEED,
UOC_CON3_UTMI_SUSPENDN
| UOC_CON3_UTMI_OPMODE_MASK
| UOC_CON3_UTMI_XCVRSEELCT_MASK
| UOC_CON3_UTMI_TERMSEL_FULLSPEED);
ret = regmap_write(grf, UOC_CON3, val);
if (ret)
return ret;
return 0;
}
#define RK3188_UOC0_CON0 0x10c
#define RK3188_UOC0_CON0_BYPASSSEL BIT(9)
#define RK3188_UOC0_CON0_BYPASSDMEN BIT(8)
/*
* Enable the bypass of uart2 data through the otg usb phy.
* See description of rk3288-variant for details.
*/
static int __init rk3188_init_usb_uart(struct regmap *grf,
const struct rockchip_usb_phy_pdata *pdata)
{
u32 val;
int ret;
ret = rockchip_init_usb_uart_common(grf, pdata);
if (ret)
return ret;
val = HIWORD_UPDATE(RK3188_UOC0_CON0_BYPASSSEL
| RK3188_UOC0_CON0_BYPASSDMEN,
RK3188_UOC0_CON0_BYPASSSEL
| RK3188_UOC0_CON0_BYPASSDMEN);
ret = regmap_write(grf, RK3188_UOC0_CON0, val);
if (ret)
return ret;
return 0;
}
static const struct rockchip_usb_phy_pdata rk3188_pdata = { static const struct rockchip_usb_phy_pdata rk3188_pdata = {
.phys = (struct rockchip_usb_phys[]){ .phys = (struct rockchip_usb_phys[]){
{ .reg = 0x10c, .pll_name = "sclk_otgphy0_480m" }, { .reg = 0x10c, .pll_name = "sclk_otgphy0_480m" },
{ .reg = 0x11c, .pll_name = "sclk_otgphy1_480m" }, { .reg = 0x11c, .pll_name = "sclk_otgphy1_480m" },
{ /* sentinel */ } { /* sentinel */ }
}, },
.init_usb_uart = rk3188_init_usb_uart,
.usb_uart_phy = 0,
}; };
#define RK3288_UOC0_CON0 0x320
#define RK3288_UOC0_CON0_COMMON_ON_N BIT(0)
#define RK3288_UOC0_CON0_DISABLE BIT(4)
#define RK3288_UOC0_CON2 0x328
#define RK3288_UOC0_CON2_SOFT_CON_SEL BIT(2)
#define RK3288_UOC0_CON3 0x32c #define RK3288_UOC0_CON3 0x32c
#define RK3288_UOC0_CON3_UTMI_SUSPENDN BIT(0)
#define RK3288_UOC0_CON3_UTMI_OPMODE_NODRIVING (1 << 1)
#define RK3288_UOC0_CON3_UTMI_OPMODE_MASK (3 << 1)
#define RK3288_UOC0_CON3_UTMI_XCVRSEELCT_FSTRANSC (1 << 3)
#define RK3288_UOC0_CON3_UTMI_XCVRSEELCT_MASK (3 << 3)
#define RK3288_UOC0_CON3_UTMI_TERMSEL_FULLSPEED BIT(5)
#define RK3288_UOC0_CON3_BYPASSDMEN BIT(6) #define RK3288_UOC0_CON3_BYPASSDMEN BIT(6)
#define RK3288_UOC0_CON3_BYPASSSEL BIT(7) #define RK3288_UOC0_CON3_BYPASSSEL BIT(7)
...@@ -353,40 +429,13 @@ static const struct rockchip_usb_phy_pdata rk3188_pdata = { ...@@ -353,40 +429,13 @@ static const struct rockchip_usb_phy_pdata rk3188_pdata = {
* *
* The actual code in the vendor kernel does some things differently. * The actual code in the vendor kernel does some things differently.
*/ */
static int __init rk3288_init_usb_uart(struct regmap *grf) static int __init rk3288_init_usb_uart(struct regmap *grf,
const struct rockchip_usb_phy_pdata *pdata)
{ {
u32 val; u32 val;
int ret; int ret;
/* ret = rockchip_init_usb_uart_common(grf, pdata);
* COMMON_ON and DISABLE settings are described in the TRM,
* but were not present in the original code.
* Also disable the analog phy components to save power.
*/
val = HIWORD_UPDATE(RK3288_UOC0_CON0_COMMON_ON_N
| RK3288_UOC0_CON0_DISABLE
| UOC_CON0_SIDDQ,
RK3288_UOC0_CON0_COMMON_ON_N
| RK3288_UOC0_CON0_DISABLE
| UOC_CON0_SIDDQ);
ret = regmap_write(grf, RK3288_UOC0_CON0, val);
if (ret)
return ret;
val = HIWORD_UPDATE(RK3288_UOC0_CON2_SOFT_CON_SEL,
RK3288_UOC0_CON2_SOFT_CON_SEL);
ret = regmap_write(grf, RK3288_UOC0_CON2, val);
if (ret)
return ret;
val = HIWORD_UPDATE(RK3288_UOC0_CON3_UTMI_OPMODE_NODRIVING
| RK3288_UOC0_CON3_UTMI_XCVRSEELCT_FSTRANSC
| RK3288_UOC0_CON3_UTMI_TERMSEL_FULLSPEED,
RK3288_UOC0_CON3_UTMI_SUSPENDN
| RK3288_UOC0_CON3_UTMI_OPMODE_MASK
| RK3288_UOC0_CON3_UTMI_XCVRSEELCT_MASK
| RK3288_UOC0_CON3_UTMI_TERMSEL_FULLSPEED);
ret = regmap_write(grf, RK3288_UOC0_CON3, val);
if (ret) if (ret)
return ret; return ret;
...@@ -516,7 +565,7 @@ static int __init rockchip_init_usb_uart(void) ...@@ -516,7 +565,7 @@ static int __init rockchip_init_usb_uart(void)
return PTR_ERR(grf); return PTR_ERR(grf);
} }
ret = data->init_usb_uart(grf); ret = data->init_usb_uart(grf, data);
if (ret) { if (ret) {
pr_err("%s: could not init usb_uart, %d\n", __func__, ret); pr_err("%s: could not init usb_uart, %d\n", __func__, ret);
enable_usb_uart = 0; enable_usb_uart = 0;
......
#
# PHY drivers for Socionext platforms.
#
config PHY_UNIPHIER_USB2
tristate "UniPhier USB2 PHY driver"
depends on ARCH_UNIPHIER || COMPILE_TEST
depends on OF && HAS_IOMEM
select GENERIC_PHY
select MFD_SYSCON
help
Enable this to support USB PHY implemented on USB2 controller
on UniPhier SoCs. This driver provides interface to interact
with USB 2.0 PHY that is part of the UniPhier SoC.
In case of Pro4, it is necessary to specify this USB2 PHY instead
of USB3 HS-PHY.
config PHY_UNIPHIER_USB3
tristate "UniPhier USB3 PHY driver"
depends on ARCH_UNIPHIER || COMPILE_TEST
depends on OF && HAS_IOMEM
select GENERIC_PHY
help
Enable this to support USB PHY implemented in USB3 controller
on UniPhier SoCs. This controller supports USB3.0 and lower speed.
config PHY_UNIPHIER_PCIE
tristate "Uniphier PHY driver for PCIe controller"
depends on (ARCH_UNIPHIER || COMPILE_TEST) && OF
default PCIE_UNIPHIER
select GENERIC_PHY
help
Enable this to support PHY implemented in PCIe controller
on UniPhier SoCs. This driver supports LD20 and PXs3 SoCs.
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the phy drivers.
#
obj-$(CONFIG_PHY_UNIPHIER_USB2) += phy-uniphier-usb2.o
obj-$(CONFIG_PHY_UNIPHIER_USB3) += phy-uniphier-usb3hs.o phy-uniphier-usb3ss.o
obj-$(CONFIG_PHY_UNIPHIER_PCIE) += phy-uniphier-pcie.o
// SPDX-License-Identifier: GPL-2.0
/*
* phy-uniphier-pcie.c - PHY driver for UniPhier PCIe controller
* Copyright 2018, Socionext Inc.
* Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
*/
#include <linux/bitops.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/resource.h>
/* PHY */
#define PCL_PHY_TEST_I 0x2000
#define PCL_PHY_TEST_O 0x2004
#define TESTI_DAT_MASK GENMASK(13, 6)
#define TESTI_ADR_MASK GENMASK(5, 1)
#define TESTI_WR_EN BIT(0)
#define PCL_PHY_RESET 0x200c
#define PCL_PHY_RESET_N_MNMODE BIT(8) /* =1:manual */
#define PCL_PHY_RESET_N BIT(0) /* =1:deasssert */
/* SG */
#define SG_USBPCIESEL 0x590
#define SG_USBPCIESEL_PCIE BIT(0)
#define PCL_PHY_R00 0
#define RX_EQ_ADJ_EN BIT(3) /* enable for EQ adjustment */
#define PCL_PHY_R06 6
#define RX_EQ_ADJ GENMASK(5, 0) /* EQ adjustment value */
#define RX_EQ_ADJ_VAL 0
#define PCL_PHY_R26 26
#define VCO_CTRL GENMASK(7, 4) /* Tx VCO adjustment value */
#define VCO_CTRL_INIT_VAL 5
struct uniphier_pciephy_priv {
void __iomem *base;
struct device *dev;
struct clk *clk;
struct reset_control *rst;
const struct uniphier_pciephy_soc_data *data;
};
struct uniphier_pciephy_soc_data {
bool has_syscon;
};
static void uniphier_pciephy_testio_write(struct uniphier_pciephy_priv *priv,
u32 data)
{
/* need to read TESTO twice after accessing TESTI */
writel(data, priv->base + PCL_PHY_TEST_I);
readl(priv->base + PCL_PHY_TEST_O);
readl(priv->base + PCL_PHY_TEST_O);
}
static void uniphier_pciephy_set_param(struct uniphier_pciephy_priv *priv,
u32 reg, u32 mask, u32 param)
{
u32 val;
/* read previous data */
val = FIELD_PREP(TESTI_DAT_MASK, 1);
val |= FIELD_PREP(TESTI_ADR_MASK, reg);
uniphier_pciephy_testio_write(priv, val);
val = readl(priv->base + PCL_PHY_TEST_O);
/* update value */
val &= ~FIELD_PREP(TESTI_DAT_MASK, mask);
val = FIELD_PREP(TESTI_DAT_MASK, mask & param);
val |= FIELD_PREP(TESTI_ADR_MASK, reg);
uniphier_pciephy_testio_write(priv, val);
uniphier_pciephy_testio_write(priv, val | TESTI_WR_EN);
uniphier_pciephy_testio_write(priv, val);
/* read current data as dummy */
val = FIELD_PREP(TESTI_DAT_MASK, 1);
val |= FIELD_PREP(TESTI_ADR_MASK, reg);
uniphier_pciephy_testio_write(priv, val);
readl(priv->base + PCL_PHY_TEST_O);
}
static void uniphier_pciephy_assert(struct uniphier_pciephy_priv *priv)
{
u32 val;
val = readl(priv->base + PCL_PHY_RESET);
val &= ~PCL_PHY_RESET_N;
val |= PCL_PHY_RESET_N_MNMODE;
writel(val, priv->base + PCL_PHY_RESET);
}
static void uniphier_pciephy_deassert(struct uniphier_pciephy_priv *priv)
{
u32 val;
val = readl(priv->base + PCL_PHY_RESET);
val |= PCL_PHY_RESET_N_MNMODE | PCL_PHY_RESET_N;
writel(val, priv->base + PCL_PHY_RESET);
}
static int uniphier_pciephy_init(struct phy *phy)
{
struct uniphier_pciephy_priv *priv = phy_get_drvdata(phy);
int ret;
ret = clk_prepare_enable(priv->clk);
if (ret)
return ret;
ret = reset_control_deassert(priv->rst);
if (ret)
goto out_clk_disable;
uniphier_pciephy_set_param(priv, PCL_PHY_R00,
RX_EQ_ADJ_EN, RX_EQ_ADJ_EN);
uniphier_pciephy_set_param(priv, PCL_PHY_R06, RX_EQ_ADJ,
FIELD_PREP(RX_EQ_ADJ, RX_EQ_ADJ_VAL));
uniphier_pciephy_set_param(priv, PCL_PHY_R26, VCO_CTRL,
FIELD_PREP(VCO_CTRL, VCO_CTRL_INIT_VAL));
usleep_range(1, 10);
uniphier_pciephy_deassert(priv);
usleep_range(1, 10);
return 0;
out_clk_disable:
clk_disable_unprepare(priv->clk);
return ret;
}
static int uniphier_pciephy_exit(struct phy *phy)
{
struct uniphier_pciephy_priv *priv = phy_get_drvdata(phy);
uniphier_pciephy_assert(priv);
reset_control_assert(priv->rst);
clk_disable_unprepare(priv->clk);
return 0;
}
static const struct phy_ops uniphier_pciephy_ops = {
.init = uniphier_pciephy_init,
.exit = uniphier_pciephy_exit,
.owner = THIS_MODULE,
};
static int uniphier_pciephy_probe(struct platform_device *pdev)
{
struct uniphier_pciephy_priv *priv;
struct phy_provider *phy_provider;
struct device *dev = &pdev->dev;
struct regmap *regmap;
struct resource *res;
struct phy *phy;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->data = of_device_get_match_data(dev);
if (WARN_ON(!priv->data))
return -EINVAL;
priv->dev = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->base = devm_ioremap_resource(dev, res);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
priv->clk = devm_clk_get(dev, NULL);
if (IS_ERR(priv->clk))
return PTR_ERR(priv->clk);
priv->rst = devm_reset_control_get_shared(dev, NULL);
if (IS_ERR(priv->rst))
return PTR_ERR(priv->rst);
phy = devm_phy_create(dev, dev->of_node, &uniphier_pciephy_ops);
if (IS_ERR(phy))
return PTR_ERR(phy);
regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
"socionext,syscon");
if (!IS_ERR(regmap) && priv->data->has_syscon)
regmap_update_bits(regmap, SG_USBPCIESEL,
SG_USBPCIESEL_PCIE, SG_USBPCIESEL_PCIE);
phy_set_drvdata(phy, priv);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
}
static const struct uniphier_pciephy_soc_data uniphier_ld20_data = {
.has_syscon = true,
};
static const struct uniphier_pciephy_soc_data uniphier_pxs3_data = {
.has_syscon = false,
};
static const struct of_device_id uniphier_pciephy_match[] = {
{
.compatible = "socionext,uniphier-ld20-pcie-phy",
.data = &uniphier_ld20_data,
},
{
.compatible = "socionext,uniphier-pxs3-pcie-phy",
.data = &uniphier_pxs3_data,
},
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, uniphier_pciephy_match);
static struct platform_driver uniphier_pciephy_driver = {
.probe = uniphier_pciephy_probe,
.driver = {
.name = "uniphier-pcie-phy",
.of_match_table = uniphier_pciephy_match,
},
};
module_platform_driver(uniphier_pciephy_driver);
MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
MODULE_DESCRIPTION("UniPhier PHY driver for PCIe controller");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/*
* phy-uniphier-usb2.c - PHY driver for UniPhier USB2 controller
* Copyright 2015-2018 Socionext Inc.
* Author:
* Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
*/
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#define SG_USBPHY1CTRL 0x500
#define SG_USBPHY1CTRL2 0x504
#define SG_USBPHY2CTRL 0x508
#define SG_USBPHY2CTRL2 0x50c /* LD11 */
#define SG_USBPHY12PLL 0x50c /* Pro4 */
#define SG_USBPHY3CTRL 0x510
#define SG_USBPHY3CTRL2 0x514
#define SG_USBPHY4CTRL 0x518 /* Pro4 */
#define SG_USBPHY4CTRL2 0x51c /* Pro4 */
#define SG_USBPHY34PLL 0x51c /* Pro4 */
struct uniphier_u2phy_param {
u32 offset;
u32 value;
};
struct uniphier_u2phy_soc_data {
struct uniphier_u2phy_param config0;
struct uniphier_u2phy_param config1;
};
struct uniphier_u2phy_priv {
struct regmap *regmap;
struct phy *phy;
struct regulator *vbus;
const struct uniphier_u2phy_soc_data *data;
struct uniphier_u2phy_priv *next;
};
static int uniphier_u2phy_power_on(struct phy *phy)
{
struct uniphier_u2phy_priv *priv = phy_get_drvdata(phy);
int ret = 0;
if (priv->vbus)
ret = regulator_enable(priv->vbus);
return ret;
}
static int uniphier_u2phy_power_off(struct phy *phy)
{
struct uniphier_u2phy_priv *priv = phy_get_drvdata(phy);
if (priv->vbus)
regulator_disable(priv->vbus);
return 0;
}
static int uniphier_u2phy_init(struct phy *phy)
{
struct uniphier_u2phy_priv *priv = phy_get_drvdata(phy);
if (!priv->data)
return 0;
regmap_write(priv->regmap, priv->data->config0.offset,
priv->data->config0.value);
regmap_write(priv->regmap, priv->data->config1.offset,
priv->data->config1.value);
return 0;
}
static struct phy *uniphier_u2phy_xlate(struct device *dev,
struct of_phandle_args *args)
{
struct uniphier_u2phy_priv *priv = dev_get_drvdata(dev);
while (priv && args->np != priv->phy->dev.of_node)
priv = priv->next;
if (!priv) {
dev_err(dev, "Failed to find appropriate phy\n");
return ERR_PTR(-EINVAL);
}
return priv->phy;
}
static const struct phy_ops uniphier_u2phy_ops = {
.init = uniphier_u2phy_init,
.power_on = uniphier_u2phy_power_on,
.power_off = uniphier_u2phy_power_off,
.owner = THIS_MODULE,
};
static int uniphier_u2phy_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *parent, *child;
struct uniphier_u2phy_priv *priv = NULL, *next = NULL;
struct phy_provider *phy_provider;
struct regmap *regmap;
const struct uniphier_u2phy_soc_data *data;
int ret, data_idx, ndatas;
data = of_device_get_match_data(dev);
if (WARN_ON(!data))
return -EINVAL;
/* get number of data */
for (ndatas = 0; data[ndatas].config0.offset; ndatas++)
;
parent = of_get_parent(dev->of_node);
regmap = syscon_node_to_regmap(parent);
of_node_put(parent);
if (IS_ERR(regmap)) {
dev_err(dev, "Failed to get regmap\n");
return PTR_ERR(regmap);
}
for_each_child_of_node(dev->of_node, child) {
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv) {
ret = -ENOMEM;
goto out_put_child;
}
priv->regmap = regmap;
priv->vbus = devm_regulator_get_optional(dev, "vbus");
if (IS_ERR(priv->vbus)) {
if (PTR_ERR(priv->vbus) == -EPROBE_DEFER) {
ret = PTR_ERR(priv->vbus);
goto out_put_child;
}
priv->vbus = NULL;
}
priv->phy = devm_phy_create(dev, child, &uniphier_u2phy_ops);
if (IS_ERR(priv->phy)) {
dev_err(dev, "Failed to create phy\n");
ret = PTR_ERR(priv->phy);
goto out_put_child;
}
ret = of_property_read_u32(child, "reg", &data_idx);
if (ret) {
dev_err(dev, "Failed to get reg property\n");
goto out_put_child;
}
if (data_idx < ndatas)
priv->data = &data[data_idx];
else
dev_warn(dev, "No phy configuration: %s\n",
child->full_name);
phy_set_drvdata(priv->phy, priv);
priv->next = next;
next = priv;
}
dev_set_drvdata(dev, priv);
phy_provider = devm_of_phy_provider_register(dev,
uniphier_u2phy_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
out_put_child:
of_node_put(child);
return ret;
}
static const struct uniphier_u2phy_soc_data uniphier_pro4_data[] = {
{
.config0 = { SG_USBPHY1CTRL, 0x05142400 },
.config1 = { SG_USBPHY12PLL, 0x00010010 },
},
{
.config0 = { SG_USBPHY2CTRL, 0x05142400 },
.config1 = { SG_USBPHY12PLL, 0x00010010 },
},
{
.config0 = { SG_USBPHY3CTRL, 0x05142400 },
.config1 = { SG_USBPHY34PLL, 0x00010010 },
},
{
.config0 = { SG_USBPHY4CTRL, 0x05142400 },
.config1 = { SG_USBPHY34PLL, 0x00010010 },
},
{ /* sentinel */ }
};
static const struct uniphier_u2phy_soc_data uniphier_ld11_data[] = {
{
.config0 = { SG_USBPHY1CTRL, 0x82280000 },
.config1 = { SG_USBPHY1CTRL2, 0x00000106 },
},
{
.config0 = { SG_USBPHY2CTRL, 0x82280000 },
.config1 = { SG_USBPHY2CTRL2, 0x00000106 },
},
{
.config0 = { SG_USBPHY3CTRL, 0x82280000 },
.config1 = { SG_USBPHY3CTRL2, 0x00000106 },
},
{ /* sentinel */ }
};
static const struct of_device_id uniphier_u2phy_match[] = {
{
.compatible = "socionext,uniphier-pro4-usb2-phy",
.data = &uniphier_pro4_data,
},
{
.compatible = "socionext,uniphier-ld11-usb2-phy",
.data = &uniphier_ld11_data,
},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, uniphier_u2phy_match);
static struct platform_driver uniphier_u2phy_driver = {
.probe = uniphier_u2phy_probe,
.driver = {
.name = "uniphier-usb2-phy",
.of_match_table = uniphier_u2phy_match,
},
};
module_platform_driver(uniphier_u2phy_driver);
MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
MODULE_DESCRIPTION("UniPhier PHY driver for USB2 controller");
MODULE_LICENSE("GPL v2");
This diff is collapsed.
This diff is collapsed.
...@@ -115,8 +115,8 @@ int tegra_xusb_lane_parse_dt(struct tegra_xusb_lane *lane, ...@@ -115,8 +115,8 @@ int tegra_xusb_lane_parse_dt(struct tegra_xusb_lane *lane,
err = match_string(lane->soc->funcs, lane->soc->num_funcs, function); err = match_string(lane->soc->funcs, lane->soc->num_funcs, function);
if (err < 0) { if (err < 0) {
dev_err(dev, "invalid function \"%s\" for lane \"%s\"\n", dev_err(dev, "invalid function \"%s\" for lane \"%pOFn\"\n",
function, np->name); function, np);
return err; return err;
} }
......
...@@ -144,6 +144,7 @@ ...@@ -144,6 +144,7 @@
#define PMBR1 0x0D #define PMBR1 0x0D
#define GPIO_USB_4PIN_ULPI_2430C (3 << 0) #define GPIO_USB_4PIN_ULPI_2430C (3 << 0)
static irqreturn_t twl4030_usb_irq(int irq, void *_twl);
/* /*
* If VBUS is valid or ID is ground, then we know a * If VBUS is valid or ID is ground, then we know a
* cable is present and we need to be runtime-enabled * cable is present and we need to be runtime-enabled
...@@ -395,6 +396,33 @@ static void __twl4030_phy_power(struct twl4030_usb *twl, int on) ...@@ -395,6 +396,33 @@ static void __twl4030_phy_power(struct twl4030_usb *twl, int on)
WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
} }
static int __maybe_unused twl4030_usb_suspend(struct device *dev)
{
struct twl4030_usb *twl = dev_get_drvdata(dev);
/*
* we need enabled runtime on resume,
* so turn irq off here, so we do not get it early
* note: wakeup on usb plug works independently of this
*/
dev_dbg(twl->dev, "%s\n", __func__);
disable_irq(twl->irq);
return 0;
}
static int __maybe_unused twl4030_usb_resume(struct device *dev)
{
struct twl4030_usb *twl = dev_get_drvdata(dev);
dev_dbg(twl->dev, "%s\n", __func__);
enable_irq(twl->irq);
/* check whether cable status changed */
twl4030_usb_irq(0, twl);
return 0;
}
static int __maybe_unused twl4030_usb_runtime_suspend(struct device *dev) static int __maybe_unused twl4030_usb_runtime_suspend(struct device *dev)
{ {
struct twl4030_usb *twl = dev_get_drvdata(dev); struct twl4030_usb *twl = dev_get_drvdata(dev);
...@@ -655,6 +683,7 @@ static const struct phy_ops ops = { ...@@ -655,6 +683,7 @@ static const struct phy_ops ops = {
static const struct dev_pm_ops twl4030_usb_pm_ops = { static const struct dev_pm_ops twl4030_usb_pm_ops = {
SET_RUNTIME_PM_OPS(twl4030_usb_runtime_suspend, SET_RUNTIME_PM_OPS(twl4030_usb_runtime_suspend,
twl4030_usb_runtime_resume, NULL) twl4030_usb_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(twl4030_usb_suspend, twl4030_usb_resume)
}; };
static int twl4030_usb_probe(struct platform_device *pdev) static int twl4030_usb_probe(struct platform_device *pdev)
......
...@@ -867,6 +867,8 @@ config INTEL_CHT_INT33FE ...@@ -867,6 +867,8 @@ config INTEL_CHT_INT33FE
tristate "Intel Cherry Trail ACPI INT33FE Driver" tristate "Intel Cherry Trail ACPI INT33FE Driver"
depends on X86 && ACPI && I2C && REGULATOR depends on X86 && ACPI && I2C && REGULATOR
depends on CHARGER_BQ24190=y || (CHARGER_BQ24190=m && m) depends on CHARGER_BQ24190=y || (CHARGER_BQ24190=m && m)
depends on USB_ROLES_INTEL_XHCI=y || (USB_ROLES_INTEL_XHCI=m && m)
depends on TYPEC_MUX_PI3USB30532=y || (TYPEC_MUX_PI3USB30532=m && m)
---help--- ---help---
This driver add support for the INT33FE ACPI device found on This driver add support for the INT33FE ACPI device found on
some Intel Cherry Trail devices. some Intel Cherry Trail devices.
......
...@@ -35,7 +35,7 @@ struct cht_int33fe_data { ...@@ -35,7 +35,7 @@ struct cht_int33fe_data {
struct i2c_client *fusb302; struct i2c_client *fusb302;
struct i2c_client *pi3usb30532; struct i2c_client *pi3usb30532;
/* Contain a list-head must be per device */ /* Contain a list-head must be per device */
struct device_connection connections[3]; struct device_connection connections[5];
}; };
/* /*
...@@ -175,19 +175,20 @@ static int cht_int33fe_probe(struct platform_device *pdev) ...@@ -175,19 +175,20 @@ static int cht_int33fe_probe(struct platform_device *pdev)
return -EPROBE_DEFER; /* Wait for i2c-adapter to load */ return -EPROBE_DEFER; /* Wait for i2c-adapter to load */
} }
data->connections[0].endpoint[0] = "i2c-fusb302"; data->connections[0].endpoint[0] = "port0";
data->connections[0].endpoint[1] = "i2c-pi3usb30532"; data->connections[0].endpoint[1] = "i2c-pi3usb30532";
data->connections[0].id = "typec-switch"; data->connections[0].id = "typec-switch";
data->connections[1].endpoint[0] = "i2c-fusb302"; data->connections[1].endpoint[0] = "port0";
data->connections[1].endpoint[1] = "i2c-pi3usb30532"; data->connections[1].endpoint[1] = "i2c-pi3usb30532";
data->connections[1].id = "typec-mux"; data->connections[1].id = "typec-mux";
data->connections[2].endpoint[0] = "i2c-fusb302"; data->connections[2].endpoint[0] = "port0";
data->connections[2].endpoint[1] = "intel_xhci_usb_sw-role-switch"; data->connections[2].endpoint[1] = "i2c-pi3usb30532";
data->connections[2].id = "usb-role-switch"; data->connections[2].id = "idff01m01";
data->connections[3].endpoint[0] = "i2c-fusb302";
data->connections[3].endpoint[1] = "intel_xhci_usb_sw-role-switch";
data->connections[3].id = "usb-role-switch";
device_connection_add(&data->connections[0]); device_connections_add(data->connections);
device_connection_add(&data->connections[1]);
device_connection_add(&data->connections[2]);
memset(&board_info, 0, sizeof(board_info)); memset(&board_info, 0, sizeof(board_info));
strlcpy(board_info.type, "typec_fusb302", I2C_NAME_SIZE); strlcpy(board_info.type, "typec_fusb302", I2C_NAME_SIZE);
...@@ -218,9 +219,7 @@ static int cht_int33fe_probe(struct platform_device *pdev) ...@@ -218,9 +219,7 @@ static int cht_int33fe_probe(struct platform_device *pdev)
if (data->max17047) if (data->max17047)
i2c_unregister_device(data->max17047); i2c_unregister_device(data->max17047);
device_connection_remove(&data->connections[2]); device_connections_remove(data->connections);
device_connection_remove(&data->connections[1]);
device_connection_remove(&data->connections[0]);
return -EPROBE_DEFER; /* Wait for the i2c-adapter to load */ return -EPROBE_DEFER; /* Wait for the i2c-adapter to load */
} }
...@@ -234,9 +233,7 @@ static int cht_int33fe_remove(struct platform_device *pdev) ...@@ -234,9 +233,7 @@ static int cht_int33fe_remove(struct platform_device *pdev)
if (data->max17047) if (data->max17047)
i2c_unregister_device(data->max17047); i2c_unregister_device(data->max17047);
device_connection_remove(&data->connections[2]); device_connections_remove(data->connections);
device_connection_remove(&data->connections[1]);
device_connection_remove(&data->connections[0]);
return 0; return 0;
} }
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/phy/phy.h> #include <linux/phy/phy.h>
#include <linux/phy/phy-qcom-ufs.h>
#include "ufshcd.h" #include "ufshcd.h"
#include "ufshcd-pltfrm.h" #include "ufshcd-pltfrm.h"
...@@ -191,22 +190,9 @@ static int ufs_qcom_init_lane_clks(struct ufs_qcom_host *host) ...@@ -191,22 +190,9 @@ static int ufs_qcom_init_lane_clks(struct ufs_qcom_host *host)
static int ufs_qcom_link_startup_post_change(struct ufs_hba *hba) static int ufs_qcom_link_startup_post_change(struct ufs_hba *hba)
{ {
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
struct phy *phy = host->generic_phy;
u32 tx_lanes; u32 tx_lanes;
int err = 0;
err = ufs_qcom_get_connected_tx_lanes(hba, &tx_lanes);
if (err)
goto out;
err = ufs_qcom_phy_set_tx_lane_enable(phy, tx_lanes); return ufs_qcom_get_connected_tx_lanes(hba, &tx_lanes);
if (err)
dev_err(hba->dev, "%s: ufs_qcom_phy_set_tx_lane_enable failed\n",
__func__);
out:
return err;
} }
static int ufs_qcom_check_hibern8(struct ufs_hba *hba) static int ufs_qcom_check_hibern8(struct ufs_hba *hba)
...@@ -934,10 +920,8 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba, ...@@ -934,10 +920,8 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
{ {
u32 val; u32 val;
struct ufs_qcom_host *host = ufshcd_get_variant(hba); struct ufs_qcom_host *host = ufshcd_get_variant(hba);
struct phy *phy = host->generic_phy;
struct ufs_qcom_dev_params ufs_qcom_cap; struct ufs_qcom_dev_params ufs_qcom_cap;
int ret = 0; int ret = 0;
int res = 0;
if (!dev_req_params) { if (!dev_req_params) {
pr_err("%s: incoming dev_req_params is NULL\n", __func__); pr_err("%s: incoming dev_req_params is NULL\n", __func__);
...@@ -1004,12 +988,6 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba, ...@@ -1004,12 +988,6 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
} }
val = ~(MAX_U32 << dev_req_params->lane_tx); val = ~(MAX_U32 << dev_req_params->lane_tx);
res = ufs_qcom_phy_set_tx_lane_enable(phy, val);
if (res) {
dev_err(hba->dev, "%s: ufs_qcom_phy_set_tx_lane_enable() failed res = %d\n",
__func__, res);
ret = res;
}
/* cache the power mode parameters to use internally */ /* cache the power mode parameters to use internally */
memcpy(&host->dev_req_params, memcpy(&host->dev_req_params,
...@@ -1266,10 +1244,6 @@ static int ufs_qcom_init(struct ufs_hba *hba) ...@@ -1266,10 +1244,6 @@ static int ufs_qcom_init(struct ufs_hba *hba)
} }
} }
/* update phy revision information before calling phy_init() */
ufs_qcom_phy_save_controller_version(host->generic_phy,
host->hw_ver.major, host->hw_ver.minor, host->hw_ver.step);
err = ufs_qcom_init_lane_clks(host); err = ufs_qcom_init_lane_clks(host);
if (err) if (err)
goto out_variant_clear; goto out_variant_clear;
......
...@@ -129,11 +129,6 @@ enum { ...@@ -129,11 +129,6 @@ enum {
MASK_CLK_NS_REG = 0xFFFC00, MASK_CLK_NS_REG = 0xFFFC00,
}; };
enum ufs_qcom_phy_init_type {
UFS_PHY_INIT_FULL,
UFS_PHY_INIT_CFG_RESTORE,
};
/* QCOM UFS debug print bit mask */ /* QCOM UFS debug print bit mask */
#define UFS_QCOM_DBG_PRINT_REGS_EN BIT(0) #define UFS_QCOM_DBG_PRINT_REGS_EN BIT(0)
#define UFS_QCOM_DBG_PRINT_ICE_REGS_EN BIT(1) #define UFS_QCOM_DBG_PRINT_ICE_REGS_EN BIT(1)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -17,7 +17,8 @@ void ci_handle_vbus_change(struct ci_hdrc *ci); ...@@ -17,7 +17,8 @@ void ci_handle_vbus_change(struct ci_hdrc *ci);
static inline void ci_otg_queue_work(struct ci_hdrc *ci) static inline void ci_otg_queue_work(struct ci_hdrc *ci)
{ {
disable_irq_nosync(ci->irq); disable_irq_nosync(ci->irq);
queue_work(ci->wq, &ci->work); if (queue_work(ci->wq, &ci->work) == false)
enable_irq(ci->irq);
} }
#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */ #endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -701,6 +701,7 @@ static int params_show(struct seq_file *seq, void *v) ...@@ -701,6 +701,7 @@ static int params_show(struct seq_file *seq, void *v)
print_param(seq, p, besl); print_param(seq, p, besl);
print_param(seq, p, hird_threshold_en); print_param(seq, p, hird_threshold_en);
print_param(seq, p, hird_threshold); print_param(seq, p, hird_threshold);
print_param(seq, p, service_interval);
print_param(seq, p, host_dma); print_param(seq, p, host_dma);
print_param(seq, p, g_dma); print_param(seq, p, g_dma);
print_param(seq, p, g_dma_desc); print_param(seq, p, g_dma_desc);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment