Commit 362f6729 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull USB/PHY updates from Greg KH:
 "Here is the big patchset of USB and PHY driver updates for 4.13-rc1.

  On the PHY side, they decided to move files around to "make things
  easier" in their tree. Hopefully that wasn't a mistake, but in
  linux-next testing, we haven't had any reported problems.

  There's the usual set of gadget and xhci and musb updates in here as
  well, along with a number of smaller updates for a raft of different
  USB drivers. Full details in the shortlog, nothing really major.

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

* tag 'usb-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (173 commits)
  Add USB quirk for HVR-950q to avoid intermittent device resets
  USB hub_probe: rework ugly goto-into-compound-statement
  usb: host: ohci-pxa27x: Handle return value of clk_prepare_enable
  USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick
  usbip: Fix uninitialized variable bug in vhci
  usb: core: read USB ports from DT in the usbport LED trigger driver
  dt-bindings: leds: document new trigger-sources property
  usb: typec: ucsi: Add ACPI driver
  usb: typec: Add support for UCSI interface
  usb: musb: compress return logic into one line
  USB: serial: propagate late probe errors
  USB: serial: refactor port endpoint setup
  usb: musb: tusb6010_omap: Convert to DMAengine API
  ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines
  usb: musb: tusb6010: Handle DMA TX completion in DMA callback as well
  usb: musb: tusb6010_omap: Allocate DMA channels upfront
  usb: musb: tusb6010_omap: Create new struct for DMA data/parameters
  usb: musb: tusb6010_omap: Use one musb_ep_select call in tusb_omap_dma_program
  usb: musb: tusb6010: Add MUSB_G_NO_SKB_RESERVE to quirks
  usb: musb: Add quirk to avoid skb reserve in gadget mode
  ...
parents 4422d80e 6836796d
...@@ -55,14 +55,6 @@ Description: ...@@ -55,14 +55,6 @@ Description:
Indicates the maximum USB speed supported by this port. Indicates the maximum USB speed supported by this port.
Users: Users:
What: /sys/class/udc/<udc>/maximum_speed
Date: June 2011
KernelVersion: 3.1
Contact: Felipe Balbi <balbi@kernel.org>
Description:
Indicates the maximum USB speed supported by this port.
Users:
What: /sys/class/udc/<udc>/soft_connect What: /sys/class/udc/<udc>/soft_connect
Date: June 2011 Date: June 2011
KernelVersion: 3.1 KernelVersion: 3.1
...@@ -91,3 +83,11 @@ Description: ...@@ -91,3 +83,11 @@ Description:
'configured', and 'suspended'; however not all USB Device 'configured', and 'suspended'; however not all USB Device
Controllers support reporting all states. Controllers support reporting all states.
Users: Users:
What: /sys/class/udc/<udc>/function
Date: June 2017
KernelVersion: 4.13
Contact: Felipe Balbi <balbi@kernel.org>
Description:
Prints out name of currently running USB Gadget Driver.
Users:
What: /config/usb-gadget/gadget/functions/uac1.name What: /config/usb-gadget/gadget/functions/uac1.name
Date: Sep 2014 Date: June 2017
KernelVersion: 3.18 KernelVersion: 4.14
Description: Description:
The attributes: The attributes:
audio_buf_size - audio buffer size c_chmask - capture channel mask
fn_cap - capture pcm device file name c_srate - capture sampling rate
fn_cntl - control device file name c_ssize - capture sample size (bytes)
fn_play - playback pcm device file name p_chmask - playback channel mask
req_buf_size - ISO OUT endpoint request buffer size p_srate - playback sampling rate
req_count - ISO OUT endpoint request count p_ssize - playback sample size (bytes)
req_number - the number of pre-allocated request
for both capture and playback
What: /config/usb-gadget/gadget/functions/uac1_legacy.name
Date: Sep 2014
KernelVersion: 3.18
Description:
The attributes:
audio_buf_size - audio buffer size
fn_cap - capture pcm device file name
fn_cntl - control device file name
fn_play - playback pcm device file name
req_buf_size - ISO OUT endpoint request buffer size
req_count - ISO OUT endpoint request count
...@@ -30,6 +30,21 @@ Description: ...@@ -30,6 +30,21 @@ Description:
Valid values: source, sink Valid values: source, sink
What: /sys/class/typec/<port>/port_type
Date: May 2017
Contact: Badhri Jagan Sridharan <Badhri@google.com>
Description:
Indicates the type of the port. This attribute can be used for
requesting a change in the port type. Port type change is
supported as a synchronous operation, so write(2) to the
attribute will not return until the operation has finished.
Valid values:
- source (The port will behave as source only DFP port)
- sink (The port will behave as sink only UFP port)
- dual (The port will behave as dual-role-data and
dual-role-power port)
What: /sys/class/typec/<port>/vconn_source What: /sys/class/typec/<port>/vconn_source
Date: April 2017 Date: April 2017
Contact: Heikki Krogerus <heikki.krogerus@linux.intel.com> Contact: Heikki Krogerus <heikki.krogerus@linux.intel.com>
......
Common leds properties. * Common leds properties.
LED and flash LED devices provide the same basic functionality as current LED and flash LED devices provide the same basic functionality as current
regulators, but extended with LED and flash LED specific features like regulators, but extended with LED and flash LED specific features like
...@@ -49,6 +49,22 @@ Optional properties for child nodes: ...@@ -49,6 +49,22 @@ Optional properties for child nodes:
- panic-indicator : This property specifies that the LED should be used, - panic-indicator : This property specifies that the LED should be used,
if at all possible, as a panic indicator. if at all possible, as a panic indicator.
- trigger-sources : List of devices which should be used as a source triggering
this LED activity. Some LEDs can be related to a specific
device and should somehow indicate its state. E.g. USB 2.0
LED may react to device(s) in a USB 2.0 port(s).
Another common example is switch or router with multiple
Ethernet ports each of them having its own LED assigned
(assuming they are not hardwired). In such cases this
property should contain phandle(s) of related source
device(s).
In many cases LED can be related to more than one device
(e.g. one USB LED vs. multiple USB ports). Each source
should be represented by a node in the device tree and be
referenced by a phandle and a set of phandle arguments. A
length of arguments should be specified by the
#trigger-source-cells property in the source node.
Required properties for flash LED child nodes: Required properties for flash LED child nodes:
- flash-max-microamp : Maximum flash LED supply current in microamperes. - flash-max-microamp : Maximum flash LED supply current in microamperes.
- flash-max-timeout-us : Maximum timeout in microseconds after which the flash - flash-max-timeout-us : Maximum timeout in microseconds after which the flash
...@@ -59,7 +75,17 @@ property can be omitted. ...@@ -59,7 +75,17 @@ property can be omitted.
For controllers that have no configurable timeout the flash-max-timeout-us For controllers that have no configurable timeout the flash-max-timeout-us
property can be omitted. property can be omitted.
Examples: * Trigger source providers
Each trigger source should be represented by a device tree node. It may be e.g.
a USB port or an Ethernet device.
Required properties for trigger source:
- #trigger-source-cells : Number of cells in a source trigger. Typically 0 for
nodes of simple trigger sources (e.g. a specific USB
port).
* Examples
gpio-leds { gpio-leds {
compatible = "gpio-leds"; compatible = "gpio-leds";
...@@ -69,6 +95,11 @@ gpio-leds { ...@@ -69,6 +95,11 @@ gpio-leds {
linux,default-trigger = "heartbeat"; linux,default-trigger = "heartbeat";
gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
}; };
usb {
gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
trigger-sources = <&ohci_port1>, <&ehci_port1>;
};
}; };
max77693-led { max77693-led {
......
...@@ -3,9 +3,10 @@ Driver for Broadcom Northstar USB 3.0 PHY ...@@ -3,9 +3,10 @@ Driver for Broadcom Northstar USB 3.0 PHY
Required properties: Required properties:
- compatible: one of: "brcm,ns-ax-usb3-phy", "brcm,ns-bx-usb3-phy". - compatible: one of: "brcm,ns-ax-usb3-phy", "brcm,ns-bx-usb3-phy".
- reg: register mappings for DMP (Device Management Plugin) and ChipCommon B - reg: address of MDIO bus device
MMI. - usb3-dmp-syscon: phandle to syscon with DMP (Device Management Plugin)
- reg-names: "dmp" and "ccb-mii" registers
- #phy-cells: must be 0
Initialization of USB 3.0 PHY depends on Northstar version. There are currently Initialization of USB 3.0 PHY depends on Northstar version. There are currently
three known series: Ax, Bx and Cx. three known series: Ax, Bx and Cx.
...@@ -15,9 +16,19 @@ Known B1: BCM4707 rev 6 ...@@ -15,9 +16,19 @@ Known B1: BCM4707 rev 6
Known C0: BCM47094 rev 0 Known C0: BCM47094 rev 0
Example: Example:
usb3-phy { mdio: mdio@0 {
compatible = "brcm,ns-ax-usb3-phy"; reg = <0x0>;
reg = <0x18105000 0x1000>, <0x18003000 0x1000>; #size-cells = <1>;
reg-names = "dmp", "ccb-mii"; #address-cells = <0>;
#phy-cells = <0>;
usb3-phy@10 {
compatible = "brcm,ns-ax-usb3-phy";
reg = <0x10>;
usb3-dmp-syscon = <&usb3_dmp>;
#phy-cells = <0>;
};
};
usb3_dmp: syscon@18105000 {
reg = <0x18105000 0x1000>;
}; };
BROADCOM NORTHSTAR2 USB2 (DUAL ROLE DEVICE) PHY
Required properties:
- compatible: brcm,ns2-drd-phy
- reg: offset and length of the NS2 PHY related registers.
- reg-names
The below registers must be provided.
icfg - for DRD ICFG configurations
rst-ctrl - for DRD IDM reset
crmu-ctrl - for CRMU core vdd, PHY and PHY PLL reset
usb2-strap - for port over current polarity reversal
- #phy-cells: Must be 0. No args required.
- vbus-gpios: vbus gpio binding
- id-gpios: id gpio binding
Refer to phy/phy-bindings.txt for the generic PHY binding properties
Example:
usbdrd_phy: phy@66000960 {
#phy-cells = <0>;
compatible = "brcm,ns2-drd-phy";
reg = <0x66000960 0x24>,
<0x67012800 0x4>,
<0x6501d148 0x4>,
<0x664d0700 0x4>;
reg-names = "icfg", "rst-ctrl",
"crmu-ctrl", "usb2-strap";
id-gpios = <&gpio_g 30 0>;
vbus-gpios = <&gpio_g 31 0>;
};
...@@ -7,12 +7,13 @@ Required properties: ...@@ -7,12 +7,13 @@ Required properties:
"brcm,iproc-ns2-sata-phy" "brcm,iproc-ns2-sata-phy"
"brcm,iproc-nsp-sata-phy" "brcm,iproc-nsp-sata-phy"
"brcm,phy-sata3" "brcm,phy-sata3"
"brcm,iproc-sr-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
- reg-names: should be "phy" and "phy-ctrl" - reg-names: should be "phy" and "phy-ctrl"
The "phy-ctrl" registers are only required for The "phy-ctrl" registers are only required for
"brcm,iproc-ns2-sata-phy". "brcm,iproc-ns2-sata-phy" and "brcm,iproc-sr-sata-phy".
Sub-nodes: Sub-nodes:
Each port's PHY should be represented as a sub-node. Each port's PHY should be represented as a sub-node.
...@@ -23,8 +24,8 @@ Sub-nodes required properties: ...@@ -23,8 +24,8 @@ Sub-nodes required properties:
Sub-nodes optional properties: Sub-nodes optional properties:
- brcm,enable-ssc: use spread spectrum clocking (SSC) on this port - brcm,enable-ssc: use spread spectrum clocking (SSC) on this port
This property is not applicable for "brcm,iproc-ns2-sata-phy" and This property is not applicable for "brcm,iproc-ns2-sata-phy",
"brcm,iproc-nsp-sata-phy". "brcm,iproc-nsp-sata-phy" and "brcm,iproc-sr-sata-phy".
Example: Example:
sata-phy@f0458100 { sata-phy@f0458100 {
......
* Amlogic Meson GXL and GXM USB2 PHY binding
Required properties:
- compatible: Should be "amlogic,meson-gxl-usb2-phy"
- reg: The base address and length of the registers
- #phys-cells: must be 0 (see phy-bindings.txt in this directory)
Optional properties:
- phy-supply: see phy-bindings.txt in this directory
Example:
usb2_phy0: phy@78000 {
compatible = "amlogic,meson-gxl-usb2-phy";
#phy-cells = <0>;
reg = <0x0 0x78000 0x0 0x20>;
};
* Amlogic Meson8b and GXBB USB2 PHY * Amlogic Meson8, Meson8b and GXBB USB2 PHY
Required properties: Required properties:
- compatible: Depending on the platform this should be one of: - compatible: Depending on the platform this should be one of:
"amlogic,meson8-usb2-phy"
"amlogic,meson8b-usb2-phy" "amlogic,meson8b-usb2-phy"
"amlogic,meson-gxbb-usb2-phy" "amlogic,meson-gxbb-usb2-phy"
- reg: The base address and length of the registers - reg: The base address and length of the registers
......
Motorola CPCAP PMIC USB PHY binding
Required properties:
compatible: Shall be either "motorola,cpcap-usb-phy" or
"motorola,mapphone-cpcap-usb-phy"
#phy-cells: Shall be 0
interrupts: CPCAP PMIC interrupts used by the USB PHY
interrupt-names: Interrupt names
io-channels: IIO ADC channels used by the USB PHY
io-channel-names: IIO ADC channel names
vusb-supply: Regulator for the PHY
Optional properties:
pinctrl: Optional alternate pin modes for the PHY
pinctrl-names: Names for optional pin modes
mode-gpios: Optional GPIOs for configuring alternate modes
Example:
cpcap_usb2_phy: phy {
compatible = "motorola,mapphone-cpcap-usb-phy";
pinctrl-0 = <&usb_gpio_mux_sel1 &usb_gpio_mux_sel2>;
pinctrl-1 = <&usb_ulpi_pins>;
pinctrl-2 = <&usb_utmi_pins>;
pinctrl-3 = <&uart3_pins>;
pinctrl-names = "default", "ulpi", "utmi", "uart";
#phy-cells = <0>;
interrupts-extended = <
&cpcap 15 0 &cpcap 14 0 &cpcap 28 0 &cpcap 19 0
&cpcap 18 0 &cpcap 17 0 &cpcap 16 0 &cpcap 49 0
&cpcap 48 1
>;
interrupt-names =
"id_ground", "id_float", "se0conn", "vbusvld",
"sessvld", "sessend", "se1", "dm", "dp";
mode-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH
&gpio1 0 GPIO_ACTIVE_HIGH>;
io-channels = <&cpcap_adc 2>, <&cpcap_adc 7>;
io-channel-names = "vbus", "id";
vusb-supply = <&vusb>;
};
...@@ -2,6 +2,7 @@ ROCKCHIP USB2.0 PHY WITH INNO IP BLOCK ...@@ -2,6 +2,7 @@ ROCKCHIP USB2.0 PHY WITH INNO IP BLOCK
Required properties (phy (parent) node): Required properties (phy (parent) node):
- compatible : should be one of the listed compatibles: - compatible : should be one of the listed compatibles:
* "rockchip,rk3228-usb2phy"
* "rockchip,rk3328-usb2phy" * "rockchip,rk3328-usb2phy"
* "rockchip,rk3366-usb2phy" * "rockchip,rk3366-usb2phy"
* "rockchip,rk3399-usb2phy" * "rockchip,rk3399-usb2phy"
......
* Renesas R-Car generation 3 USB 3.0 PHY
This file provides information on what the device node for the R-Car generation
3 USB 3.0 PHY contains.
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
need this driver.
Required properties:
- compatible: "renesas,r8a7795-usb3-phy" if the device is a part of an R8A7795
SoC.
"renesas,r8a7796-usb3-phy" if the device is a part of an R8A7796
SoC.
"renesas,rcar-gen3-usb3-phy" for a generic R-Car Gen3 compatible
device.
When compatible with the generic version, nodes must list the
SoC-specific version corresponding to the platform first
followed by the generic version.
- reg: offset and length of the USB 3.0 PHY register block.
- clocks: A list of phandles and clock-specifier pairs.
- clock-names: Name of the clocks.
- The funcional clock must be "usb3-if".
- The usb3's external clock must be "usb3s_clk".
- The usb2's external clock must be "usb_extal". If you want to use the ssc,
the clock-frequency must not be 0.
- #phy-cells: see phy-bindings.txt in the same directory, must be <0>.
Optional properties:
- renesas,ssc-range: Enable/disable spread spectrum clock (ssc) by using
the following values as u32:
- 0 (or the property doesn't exist): disable the ssc
- 4980: enable the ssc as -4980 ppm
- 4492: enable the ssc as -4492 ppm
- 4003: enable the ssc as -4003 ppm
Example (R-Car H3):
usb-phy@e65ee000 {
compatible = "renesas,r8a7795-usb3-phy",
"renesas,rcar-gen3-usb3-phy";
reg = <0 0xe65ee000 0 0x90>;
clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>, <&usb_extal>;
clock-names = "usb3-if", "usb3s_clk", "usb_extal";
};
...@@ -45,6 +45,8 @@ Optional properties: ...@@ -45,6 +45,8 @@ Optional properties:
a free-running PHY clock. a free-running PHY clock.
- snps,dis-del-phy-power-chg-quirk: when set core will change PHY power - snps,dis-del-phy-power-chg-quirk: when set core will change PHY power
from P0 to P1/P2/P3 without delay. from P0 to P1/P2/P3 without delay.
- snps,dis-tx-ipgap-linecheck-quirk: when set, disable u2mac linestate check
during HS transmit.
- snps,is-utmi-l1-suspend: true when DWC3 asserts output signal - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
utmi_l1_suspend_n, false when asserts utmi_sleep_n utmi_l1_suspend_n, false when asserts utmi_sleep_n
- snps,hird-threshold: HIRD threshold - snps,hird-threshold: HIRD threshold
......
Broadcom IPROC USB Device controller.
The device node is used for UDCs integrated into Broadcom's
iProc family (Northstar2, Cygnus) of SoCs'. The UDC is based
on Synopsys Designware Cores AHB Subsystem Device Controller
IP.
Required properties:
- compatible: Add the compatibility strings for supported platforms.
For Broadcom NS2 platform, add "brcm,ns2-udc","brcm,iproc-udc".
For Broadcom Cygnus platform, add "brcm,cygnus-udc", "brcm,iproc-udc".
- reg: Offset and length of UDC register set
- interrupts: description of interrupt line
- phys: phandle to phy node.
Example:
udc_dwc: usb@664e0000 {
compatible = "brcm,ns2-udc", "brcm,iproc-udc";
reg = <0x664e0000 0x2000>;
interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
phys = <&usbdrd_phy>;
...@@ -10,6 +10,7 @@ Optional properties: ...@@ -10,6 +10,7 @@ Optional properties:
- big-endian-desc : boolean, set this for hcds with big-endian descriptors - big-endian-desc : boolean, set this for hcds with big-endian descriptors
- big-endian : boolean, for hcds with big-endian-regs + big-endian-desc - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc
- 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
- 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
- phys : phandle + phy specifier pair - phys : phandle + phy specifier pair
......
This diff is collapsed.
...@@ -16,7 +16,10 @@ Linux USB API ...@@ -16,7 +16,10 @@ Linux USB API
persist persist
error-codes error-codes
writing_usb_driver writing_usb_driver
dwc3
writing_musb_glue_layer writing_musb_glue_layer
typec
usb3-debug-port
.. only:: subproject and html .. only:: subproject and html
......
...@@ -16,10 +16,11 @@ provided by gadgets. ...@@ -16,10 +16,11 @@ provided by gadgets.
13. RNDIS function 13. RNDIS function
14. SERIAL function 14. SERIAL function
15. SOURCESINK function 15. SOURCESINK function
16. UAC1 function 16. UAC1 function (legacy implementation)
17. UAC2 function 17. UAC2 function
18. UVC function 18. UVC function
19. PRINTER function 19. PRINTER function
20. UAC1 function (new API)
1. ACM function 1. ACM function
...@@ -589,15 +590,16 @@ device: run the gadget ...@@ -589,15 +590,16 @@ device: run the gadget
host: test-usb (tools/usb/testusb.c) host: test-usb (tools/usb/testusb.c)
16. UAC1 function 16. UAC1 function (legacy implementation)
================= =================
The function is provided by usb_f_uac1.ko module. The function is provided by usb_f_uac1_legacy.ko module.
Function-specific configfs interface Function-specific configfs interface
------------------------------------ ------------------------------------
The function name to use when creating the function directory is "uac1". The function name to use when creating the function directory
is "uac1_legacy".
The uac1 function provides these attributes in its function directory: The uac1 function provides these attributes in its function directory:
audio_buf_size - audio buffer size audio_buf_size - audio buffer size
...@@ -772,3 +774,46 @@ host: ...@@ -772,3 +774,46 @@ host:
More advanced testing can be done with the prn_example More advanced testing can be done with the prn_example
described in Documentation/usb/gadget-printer.txt. described in Documentation/usb/gadget-printer.txt.
20. UAC1 function (virtual ALSA card, using u_audio API)
=================
The function is provided by usb_f_uac1.ko module.
It will create a virtual ALSA card and the audio streams are simply
sinked to and sourced from it.
Function-specific configfs interface
------------------------------------
The function name to use when creating the function directory is "uac1".
The uac1 function provides these attributes in its function directory:
c_chmask - capture channel mask
c_srate - capture sampling rate
c_ssize - capture sample size (bytes)
p_chmask - playback channel mask
p_srate - playback sampling rate
p_ssize - playback sample size (bytes)
req_number - the number of pre-allocated request for both capture
and playback
The attributes have sane default values.
Testing the UAC1 function
-------------------------
device: run the gadget
host: aplay -l # should list our USB Audio Gadget
This function does not require real hardware support, it just
sends a stream of audio data to/from the host. In order to
actually hear something at the device side, a command similar
to this must be used at the device side:
$ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 &
e.g.:
$ arecord -f dat -t wav -D hw:CARD=UAC1Gadget,DEV=0 | \
aplay -D default:CARD=OdroidU3
...@@ -1843,8 +1843,8 @@ F: drivers/i2c/busses/i2c-st.c ...@@ -1843,8 +1843,8 @@ F: drivers/i2c/busses/i2c-st.c
F: drivers/media/rc/st_rc.c F: drivers/media/rc/st_rc.c
F: drivers/media/platform/sti/c8sectpfe/ F: drivers/media/platform/sti/c8sectpfe/
F: drivers/mmc/host/sdhci-st.c F: drivers/mmc/host/sdhci-st.c
F: drivers/phy/phy-miphy28lp.c F: drivers/phy/st/phy-miphy28lp.c
F: drivers/phy/phy-stih407-usb.c F: drivers/phy/st/phy-stih407-usb.c
F: drivers/pinctrl/pinctrl-st.c F: drivers/pinctrl/pinctrl-st.c
F: drivers/remoteproc/st_remoteproc.c F: drivers/remoteproc/st_remoteproc.c
F: drivers/remoteproc/st_slim_rproc.c F: drivers/remoteproc/st_slim_rproc.c
...@@ -10840,11 +10840,11 @@ L: linux-iio@vger.kernel.org ...@@ -10840,11 +10840,11 @@ L: linux-iio@vger.kernel.org
S: Supported S: Supported
F: drivers/iio/adc/rcar_gyro_adc.c F: drivers/iio/adc/rcar_gyro_adc.c
RENESAS USB2 PHY DRIVER RENESAS USB PHY DRIVER
M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
L: linux-renesas-soc@vger.kernel.org L: linux-renesas-soc@vger.kernel.org
S: Maintained S: Maintained
F: drivers/phy/phy-rcar-gen3-usb2.c F: drivers/phy/renesas/phy-rcar-gen3-usb*.c
RESET CONTROLLER FRAMEWORK RESET CONTROLLER FRAMEWORK
M: Philipp Zabel <p.zabel@pengutronix.de> M: Philipp Zabel <p.zabel@pengutronix.de>
...@@ -11246,12 +11246,12 @@ L: linux-kernel@vger.kernel.org ...@@ -11246,12 +11246,12 @@ L: linux-kernel@vger.kernel.org
S: Supported S: Supported
F: Documentation/devicetree/bindings/phy/samsung-phy.txt F: Documentation/devicetree/bindings/phy/samsung-phy.txt
F: Documentation/phy/samsung-usb2.txt F: Documentation/phy/samsung-usb2.txt
F: drivers/phy/phy-exynos4210-usb2.c F: drivers/phy/samsung/phy-exynos4210-usb2.c
F: drivers/phy/phy-exynos4x12-usb2.c F: drivers/phy/samsung/phy-exynos4x12-usb2.c
F: drivers/phy/phy-exynos5250-usb2.c F: drivers/phy/samsung/phy-exynos5250-usb2.c
F: drivers/phy/phy-s5pv210-usb2.c F: drivers/phy/samsung/phy-s5pv210-usb2.c
F: drivers/phy/phy-samsung-usb2.c F: drivers/phy/samsung/phy-samsung-usb2.c
F: drivers/phy/phy-samsung-usb2.h F: drivers/phy/samsung/phy-samsung-usb2.h
SERIAL DRIVERS SERIAL DRIVERS
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
......
...@@ -249,6 +249,24 @@ static const struct dma_slave_map omap24xx_sdma_map[] = { ...@@ -249,6 +249,24 @@ static const struct dma_slave_map omap24xx_sdma_map[] = {
{ "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) }, { "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) },
{ "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) }, { "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) },
{ "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) }, { "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) },
/* external DMA requests when tusb6010 is used */
{ "musb-tusb", "dmareq0", SDMA_FILTER_PARAM(2) },
{ "musb-tusb", "dmareq1", SDMA_FILTER_PARAM(3) },
{ "musb-tusb", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */
{ "musb-tusb", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */
{ "musb-tusb", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */
{ "musb-tusb", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */
};
static const struct dma_slave_map omap24xx_sdma_dt_map[] = {
/* external DMA requests when tusb6010 is used */
{ "musb-hdrc.1.auto", "dmareq0", SDMA_FILTER_PARAM(2) },
{ "musb-hdrc.1.auto", "dmareq1", SDMA_FILTER_PARAM(3) },
{ "musb-hdrc.1.auto", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */
{ "musb-hdrc.1.auto", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */
{ "musb-hdrc.1.auto", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */
{ "musb-hdrc.1.auto", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */
}; };
static const struct dma_slave_map omap3xxx_sdma_map[] = { static const struct dma_slave_map omap3xxx_sdma_map[] = {
...@@ -346,6 +364,12 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) ...@@ -346,6 +364,12 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
__func__); __func__);
return -ENODEV; return -ENODEV;
} }
} else {
if (soc_is_omap24xx()) {
/* DMA slave map for drivers not yet converted to DT */
p.slave_map = omap24xx_sdma_dt_map;
p.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map);
}
} }
pdev = omap_device_build(name, 0, oh, &p, sizeof(p)); pdev = omap_device_build(name, 0, oh, &p, sizeof(p));
......
...@@ -2884,3 +2884,19 @@ void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode) ...@@ -2884,3 +2884,19 @@ void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
else else
dev->fwnode = fwnode; dev->fwnode = fwnode;
} }
/**
* device_set_of_node_from_dev - reuse device-tree node of another device
* @dev: device whose device-tree node is being set
* @dev2: device whose device-tree node is being reused
*
* Takes another reference to the new device-tree node after first dropping
* any reference held to the old node.
*/
void device_set_of_node_from_dev(struct device *dev, const struct device *dev2)
{
of_node_put(dev->of_node);
dev->of_node = of_node_get(dev2->of_node);
dev->of_node_reused = true;
}
EXPORT_SYMBOL_GPL(device_set_of_node_from_dev);
...@@ -23,6 +23,9 @@ int pinctrl_bind_pins(struct device *dev) ...@@ -23,6 +23,9 @@ int pinctrl_bind_pins(struct device *dev)
{ {
int ret; int ret;
if (dev->of_node_reused)
return 0;
dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL); dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL);
if (!dev->pins) if (!dev->pins)
return -ENOMEM; return -ENOMEM;
......
...@@ -916,12 +916,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg( ...@@ -916,12 +916,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
return NULL; return NULL;
} }
/* When the port_window is used, one frame must cover the window */
if (port_window) {
burst = port_window;
port_window_bytes = port_window * es_bytes[es];
}
/* Now allocate and setup the descriptor. */ /* Now allocate and setup the descriptor. */
d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC); d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC);
if (!d) if (!d)
...@@ -931,6 +925,21 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg( ...@@ -931,6 +925,21 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
d->dev_addr = dev_addr; d->dev_addr = dev_addr;
d->es = es; d->es = es;
/* When the port_window is used, one frame must cover the window */
if (port_window) {
burst = port_window;
port_window_bytes = port_window * es_bytes[es];
d->ei = 1;
/*
* One frame covers the port_window and by configure
* the source frame index to be -1 * (port_window - 1)
* we instruct the sDMA that after a frame is processed
* it should move back to the start of the window.
*/
d->fi = -(port_window_bytes - 1);
}
d->ccr = c->ccr | CCR_SYNC_FRAME; d->ccr = c->ccr | CCR_SYNC_FRAME;
if (dir == DMA_DEV_TO_MEM) { if (dir == DMA_DEV_TO_MEM) {
d->csdp = CSDP_DST_BURST_64 | CSDP_DST_PACKED; d->csdp = CSDP_DST_BURST_64 | CSDP_DST_PACKED;
...@@ -955,14 +964,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg( ...@@ -955,14 +964,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
d->ccr |= CCR_SRC_AMODE_POSTINC; d->ccr |= CCR_SRC_AMODE_POSTINC;
if (port_window) { if (port_window) {
d->ccr |= CCR_DST_AMODE_DBLIDX; d->ccr |= CCR_DST_AMODE_DBLIDX;
d->ei = 1;
/*
* One frame covers the port_window and by configure
* the source frame index to be -1 * (port_window - 1)
* we instruct the sDMA that after a frame is processed
* it should move back to the start of the window.
*/
d->fi = -(port_window_bytes - 1);
if (port_window_bytes >= 64) if (port_window_bytes >= 64)
d->csdp |= CSDP_DST_BURST_64; d->csdp |= CSDP_DST_BURST_64;
...@@ -1018,16 +1019,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg( ...@@ -1018,16 +1019,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
osg->addr = sg_dma_address(sgent); osg->addr = sg_dma_address(sgent);
osg->en = en; osg->en = en;
osg->fn = sg_dma_len(sgent) / frame_bytes; osg->fn = sg_dma_len(sgent) / frame_bytes;
if (port_window && dir == DMA_DEV_TO_MEM) {
osg->ei = 1;
/*
* One frame covers the port_window and by configure
* the source frame index to be -1 * (port_window - 1)
* we instruct the sDMA that after a frame is processed
* it should move back to the start of the window.
*/
osg->fi = -(port_window_bytes - 1);
}
if (d->using_ll) { if (d->using_ll) {
osg->t2_desc = dma_pool_alloc(od->desc_pool, GFP_ATOMIC, osg->t2_desc = dma_pool_alloc(od->desc_pool, GFP_ATOMIC,
......
...@@ -115,6 +115,7 @@ config EXTCON_PALMAS ...@@ -115,6 +115,7 @@ config EXTCON_PALMAS
config EXTCON_QCOM_SPMI_MISC config EXTCON_QCOM_SPMI_MISC
tristate "Qualcomm USB extcon support" tristate "Qualcomm USB extcon support"
depends on ARCH_QCOM || COMPILE_TEST
help help
Say Y here to enable SPMI PMIC based USB cable detection Say Y here to enable SPMI PMIC based USB cable detection
support on Qualcomm PMICs such as PM8941. support on Qualcomm PMICs such as PM8941.
......
...@@ -1271,9 +1271,7 @@ static int arizona_extcon_get_micd_configs(struct device *dev, ...@@ -1271,9 +1271,7 @@ static int arizona_extcon_get_micd_configs(struct device *dev,
goto out; goto out;
nconfs /= entries_per_config; nconfs /= entries_per_config;
micd_configs = devm_kcalloc(dev, nconfs, sizeof(*micd_configs),
micd_configs = devm_kzalloc(dev,
nconfs * sizeof(struct arizona_micd_range),
GFP_KERNEL); GFP_KERNEL);
if (!micd_configs) { if (!micd_configs) {
ret = -ENOMEM; ret = -ENOMEM;
......
...@@ -94,8 +94,7 @@ static int int3496_probe(struct platform_device *pdev) ...@@ -94,8 +94,7 @@ static int int3496_probe(struct platform_device *pdev)
struct int3496_data *data; struct int3496_data *data;
int ret; int ret;
ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), ret = devm_acpi_dev_add_driver_gpios(dev, acpi_int3496_default_gpios);
acpi_int3496_default_gpios);
if (ret) { if (ret) {
dev_err(dev, "can't add GPIO ACPI mapping\n"); dev_err(dev, "can't add GPIO ACPI mapping\n");
return ret; return ret;
...@@ -169,8 +168,6 @@ static int int3496_remove(struct platform_device *pdev) ...@@ -169,8 +168,6 @@ static int int3496_remove(struct platform_device *pdev)
devm_free_irq(&pdev->dev, data->usb_id_irq, data); devm_free_irq(&pdev->dev, data->usb_id_irq, data);
cancel_delayed_work_sync(&data->work); cancel_delayed_work_sync(&data->work);
acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev));
return 0; return 0;
} }
......
...@@ -964,12 +964,12 @@ EXPORT_SYMBOL_GPL(extcon_unregister_notifier); ...@@ -964,12 +964,12 @@ EXPORT_SYMBOL_GPL(extcon_unregister_notifier);
/** /**
* extcon_register_notifier_all() - Register a notifier block for all connectors * extcon_register_notifier_all() - Register a notifier block for all connectors
* @edev: the extcon device that has the external connecotr. * @edev: the extcon device that has the external connector.
* @nb: a notifier block to be registered. * @nb: a notifier block to be registered.
* *
* This fucntion registers a notifier block in order to receive the state * This function registers a notifier block in order to receive the state
* change of all supported external connectors from extcon device. * change of all supported external connectors from extcon device.
* And The second parameter given to the callback of nb (val) is * And the second parameter given to the callback of nb (val) is
* the current state and third parameter is the edev pointer. * the current state and third parameter is the edev pointer.
* *
* Returns 0 if success or error number if fail * Returns 0 if success or error number if fail
...@@ -1252,9 +1252,8 @@ int extcon_dev_register(struct extcon_dev *edev) ...@@ -1252,9 +1252,8 @@ int extcon_dev_register(struct extcon_dev *edev)
} }
spin_lock_init(&edev->lock); spin_lock_init(&edev->lock);
edev->nh = devm_kcalloc(&edev->dev, edev->max_supported,
edev->nh = devm_kzalloc(&edev->dev, sizeof(*edev->nh), GFP_KERNEL);
sizeof(*edev->nh) * edev->max_supported, GFP_KERNEL);
if (!edev->nh) { if (!edev->nh) {
ret = -ENOMEM; ret = -ENOMEM;
goto err_dev; goto err_dev;
......
This diff is collapsed.
...@@ -3,64 +3,21 @@ ...@@ -3,64 +3,21 @@
# #
obj-$(CONFIG_GENERIC_PHY) += phy-core.o obj-$(CONFIG_GENERIC_PHY) += phy-core.o
obj-$(CONFIG_PHY_BCM_NS_USB2) += phy-bcm-ns-usb2.o
obj-$(CONFIG_PHY_BCM_NS_USB3) += phy-bcm-ns-usb3.o
obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o
obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o
obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o
obj-$(CONFIG_PHY_DM816X_USB) += phy-dm816x-usb.o
obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o
obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o
obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o
obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
obj-$(CONFIG_PHY_PXA_28NM_USB2) += phy-pxa-28nm-usb2.o
obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o
obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o
obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o
obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o
obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o
obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o
obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o
obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o
obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o
obj-$(CONFIG_PHY_HI6220_USB) += phy-hi6220-usb.o
obj-$(CONFIG_PHY_MT65XX_USB3) += phy-mt65xx-usb3.o obj-$(CONFIG_PHY_MT65XX_USB3) += phy-mt65xx-usb3.o
obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o
obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o
obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o
phy-exynos-usb2-y += phy-samsung-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
obj-$(CONFIG_PHY_EXYNOS_PCIE) += phy-exynos-pcie.o
obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o
obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.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-qmp-20nm.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.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_TUSB1210) += phy-tusb1210.o
obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o
obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_ARCH_SUNXI) += allwinner/
obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o obj-$(CONFIG_ARCH_MESON) += amlogic/
obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o obj-$(CONFIG_ARCH_RENESAS) += renesas/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-y += broadcom/ \
hisilicon/ \
marvell/ \
motorola/ \
qualcomm/ \
samsung/ \
st/ \
ti/
#
# Phy drivers for Allwinner platforms
#
config PHY_SUN4I_USB
tristate "Allwinner sunxi SoC USB PHY driver"
depends on ARCH_SUNXI && HAS_IOMEM && OF
depends on RESET_CONTROLLER
depends on EXTCON
depends on POWER_SUPPLY
depends on USB_SUPPORT
select GENERIC_PHY
select USB_COMMON
help
Enable this to support the transceiver that is part of Allwinner
sunxi SoCs.
This driver controls the entire USB PHY block, both the USB OTG
parts, as well as the 2 regular USB 2 host PHYs.
config PHY_SUN9I_USB
tristate "Allwinner sun9i SoC USB PHY driver"
depends on ARCH_SUNXI && HAS_IOMEM && OF
depends on RESET_CONTROLLER
depends on USB_SUPPORT
select USB_COMMON
select GENERIC_PHY
help
Enable this to support the transceiver that is part of Allwinner
sun9i SoCs.
This driver controls each individual USB 2 host PHY.
obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o
obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o
#
# Phy drivers for Amlogic platforms
#
config PHY_MESON8B_USB2
tristate "Meson8, Meson8b and GXBB USB2 PHY driver"
default ARCH_MESON
depends on OF && (ARCH_MESON || COMPILE_TEST)
depends on USB_SUPPORT
select USB_COMMON
select GENERIC_PHY
help
Enable this to support the Meson USB2 PHYs found in Meson8,
Meson8b and GXBB SoCs.
If unsure, say N.
config PHY_MESON_GXL_USB2
tristate "Meson GXL and GXM USB2 PHY drivers"
default ARCH_MESON
depends on OF && (ARCH_MESON || COMPILE_TEST)
depends on USB_SUPPORT
select USB_COMMON
select GENERIC_PHY
select REGMAP_MMIO
help
Enable this to support the Meson USB2 PHYs found in Meson
GXL and GXM SoCs.
If unsure, say N.
obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o
obj-$(CONFIG_PHY_MESON_GXL_USB2) += phy-meson-gxl-usb2.o
/*
* Meson GXL and GXM USB2 PHY driver
*
* Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/usb/of.h>
/* bits [31:27] are read-only */
#define U2P_R0 0x0
#define U2P_R0_BYPASS_SEL BIT(0)
#define U2P_R0_BYPASS_DM_EN BIT(1)
#define U2P_R0_BYPASS_DP_EN BIT(2)
#define U2P_R0_TXBITSTUFF_ENH BIT(3)
#define U2P_R0_TXBITSTUFF_EN BIT(4)
#define U2P_R0_DM_PULLDOWN BIT(5)
#define U2P_R0_DP_PULLDOWN BIT(6)
#define U2P_R0_DP_VBUS_VLD_EXT_SEL BIT(7)
#define U2P_R0_DP_VBUS_VLD_EXT BIT(8)
#define U2P_R0_ADP_PRB_EN BIT(9)
#define U2P_R0_ADP_DISCHARGE BIT(10)
#define U2P_R0_ADP_CHARGE BIT(11)
#define U2P_R0_DRV_VBUS BIT(12)
#define U2P_R0_ID_PULLUP BIT(13)
#define U2P_R0_LOOPBACK_EN_B BIT(14)
#define U2P_R0_OTG_DISABLE BIT(15)
#define U2P_R0_COMMON_ONN BIT(16)
#define U2P_R0_FSEL_MASK GENMASK(19, 17)
#define U2P_R0_REF_CLK_SEL_MASK GENMASK(21, 20)
#define U2P_R0_POWER_ON_RESET BIT(22)
#define U2P_R0_V_ATE_TEST_EN_B_MASK GENMASK(24, 23)
#define U2P_R0_ID_SET_ID_DQ BIT(25)
#define U2P_R0_ATE_RESET BIT(26)
#define U2P_R0_FSV_MINUS BIT(27)
#define U2P_R0_FSV_PLUS BIT(28)
#define U2P_R0_BYPASS_DM_DATA BIT(29)
#define U2P_R0_BYPASS_DP_DATA BIT(30)
#define U2P_R1 0x4
#define U2P_R1_BURN_IN_TEST BIT(0)
#define U2P_R1_ACA_ENABLE BIT(1)
#define U2P_R1_DCD_ENABLE BIT(2)
#define U2P_R1_VDAT_SRC_EN_B BIT(3)
#define U2P_R1_VDAT_DET_EN_B BIT(4)
#define U2P_R1_CHARGES_SEL BIT(5)
#define U2P_R1_TX_PREEMP_PULSE_TUNE BIT(6)
#define U2P_R1_TX_PREEMP_AMP_TUNE_MASK GENMASK(8, 7)
#define U2P_R1_TX_RES_TUNE_MASK GENMASK(10, 9)
#define U2P_R1_TX_RISE_TUNE_MASK GENMASK(12, 11)
#define U2P_R1_TX_VREF_TUNE_MASK GENMASK(16, 13)
#define U2P_R1_TX_FSLS_TUNE_MASK GENMASK(20, 17)
#define U2P_R1_TX_HSXV_TUNE_MASK GENMASK(22, 21)
#define U2P_R1_OTG_TUNE_MASK GENMASK(25, 23)
#define U2P_R1_SQRX_TUNE_MASK GENMASK(28, 26)
#define U2P_R1_COMP_DIS_TUNE_MASK GENMASK(31, 29)
/* bits [31:14] are read-only */
#define U2P_R2 0x8
#define U2P_R2_DATA_IN_MASK GENMASK(3, 0)
#define U2P_R2_DATA_IN_EN_MASK GENMASK(7, 4)
#define U2P_R2_ADDR_MASK GENMASK(11, 8)
#define U2P_R2_DATA_OUT_SEL BIT(12)
#define U2P_R2_CLK BIT(13)
#define U2P_R2_DATA_OUT_MASK GENMASK(17, 14)
#define U2P_R2_ACA_PIN_RANGE_C BIT(18)
#define U2P_R2_ACA_PIN_RANGE_B BIT(19)
#define U2P_R2_ACA_PIN_RANGE_A BIT(20)
#define U2P_R2_ACA_PIN_GND BIT(21)
#define U2P_R2_ACA_PIN_FLOAT BIT(22)
#define U2P_R2_CHARGE_DETECT BIT(23)
#define U2P_R2_DEVICE_SESSION_VALID BIT(24)
#define U2P_R2_ADP_PROBE BIT(25)
#define U2P_R2_ADP_SENSE BIT(26)
#define U2P_R2_SESSION_END BIT(27)
#define U2P_R2_VBUS_VALID BIT(28)
#define U2P_R2_B_VALID BIT(29)
#define U2P_R2_A_VALID BIT(30)
#define U2P_R2_ID_DIG BIT(31)
#define U2P_R3 0xc
#define RESET_COMPLETE_TIME 500
struct phy_meson_gxl_usb2_priv {
struct regmap *regmap;
enum phy_mode mode;
int is_enabled;
};
static const struct regmap_config phy_meson_gxl_usb2_regmap_conf = {
.reg_bits = 8,
.val_bits = 32,
.reg_stride = 4,
.max_register = U2P_R3,
};
static int phy_meson_gxl_usb2_reset(struct phy *phy)
{
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
if (priv->is_enabled) {
/* reset the PHY and wait until settings are stabilized */
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
U2P_R0_POWER_ON_RESET);
udelay(RESET_COMPLETE_TIME);
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
0);
udelay(RESET_COMPLETE_TIME);
}
return 0;
}
static int phy_meson_gxl_usb2_set_mode(struct phy *phy, enum phy_mode mode)
{
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
switch (mode) {
case PHY_MODE_USB_HOST:
case PHY_MODE_USB_OTG:
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
U2P_R0_DM_PULLDOWN);
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
U2P_R0_DP_PULLDOWN);
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP, 0);
break;
case PHY_MODE_USB_DEVICE:
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
0);
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
0);
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP,
U2P_R0_ID_PULLUP);
break;
default:
return -EINVAL;
}
phy_meson_gxl_usb2_reset(phy);
priv->mode = mode;
return 0;
}
static int phy_meson_gxl_usb2_power_off(struct phy *phy)
{
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
priv->is_enabled = 0;
/* power off the PHY by putting it into reset mode */
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
U2P_R0_POWER_ON_RESET);
return 0;
}
static int phy_meson_gxl_usb2_power_on(struct phy *phy)
{
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
int ret;
priv->is_enabled = 1;
/* power on the PHY by taking it out of reset mode */
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0);
ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode);
if (ret) {
phy_meson_gxl_usb2_power_off(phy);
dev_err(&phy->dev, "Failed to initialize PHY with mode %d\n",
priv->mode);
return ret;
}
return 0;
}
static const struct phy_ops phy_meson_gxl_usb2_ops = {
.power_on = phy_meson_gxl_usb2_power_on,
.power_off = phy_meson_gxl_usb2_power_off,
.set_mode = phy_meson_gxl_usb2_set_mode,
.reset = phy_meson_gxl_usb2_reset,
.owner = THIS_MODULE,
};
static int phy_meson_gxl_usb2_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct phy_provider *phy_provider;
struct resource *res;
struct phy_meson_gxl_usb2_priv *priv;
struct phy *phy;
void __iomem *base;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
platform_set_drvdata(pdev, priv);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
switch (of_usb_get_dr_mode_by_phy(dev->of_node, -1)) {
case USB_DR_MODE_PERIPHERAL:
priv->mode = PHY_MODE_USB_DEVICE;
break;
case USB_DR_MODE_OTG:
priv->mode = PHY_MODE_USB_OTG;
break;
case USB_DR_MODE_HOST:
default:
priv->mode = PHY_MODE_USB_HOST;
break;
}
priv->regmap = devm_regmap_init_mmio(dev, base,
&phy_meson_gxl_usb2_regmap_conf);
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
phy = devm_phy_create(dev, NULL, &phy_meson_gxl_usb2_ops);
if (IS_ERR(phy)) {
dev_err(dev, "failed to create PHY\n");
return PTR_ERR(phy);
}
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 of_device_id phy_meson_gxl_usb2_of_match[] = {
{ .compatible = "amlogic,meson-gxl-usb2-phy", },
{ },
};
MODULE_DEVICE_TABLE(of, phy_meson_gxl_usb2_of_match);
static struct platform_driver phy_meson_gxl_usb2_driver = {
.probe = phy_meson_gxl_usb2_probe,
.driver = {
.name = "phy-meson-gxl-usb2",
.of_match_table = phy_meson_gxl_usb2_of_match,
},
};
module_platform_driver(phy_meson_gxl_usb2_driver);
MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
MODULE_DESCRIPTION("Meson GXL and GXM USB2 PHY driver");
MODULE_LICENSE("GPL v2");
/* /*
* Meson8b and GXBB USB2 PHY driver * Meson8, Meson8b and GXBB USB2 PHY driver
* *
* Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com> * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
* *
...@@ -266,6 +266,7 @@ static int phy_meson8b_usb2_probe(struct platform_device *pdev) ...@@ -266,6 +266,7 @@ static int phy_meson8b_usb2_probe(struct platform_device *pdev)
} }
static const struct of_device_id phy_meson8b_usb2_of_match[] = { static const struct of_device_id phy_meson8b_usb2_of_match[] = {
{ .compatible = "amlogic,meson8-usb2-phy", },
{ .compatible = "amlogic,meson8b-usb2-phy", }, { .compatible = "amlogic,meson8b-usb2-phy", },
{ .compatible = "amlogic,meson-gxbb-usb2-phy", }, { .compatible = "amlogic,meson-gxbb-usb2-phy", },
{ }, { },
...@@ -282,5 +283,5 @@ static struct platform_driver phy_meson8b_usb2_driver = { ...@@ -282,5 +283,5 @@ static struct platform_driver phy_meson8b_usb2_driver = {
module_platform_driver(phy_meson8b_usb2_driver); module_platform_driver(phy_meson8b_usb2_driver);
MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
MODULE_DESCRIPTION("Meson8b and GXBB USB2 PHY driver"); MODULE_DESCRIPTION("Meson8, Meson8b and GXBB USB2 PHY driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#
# Phy drivers for Broadcom platforms
#
config PHY_CYGNUS_PCIE
tristate "Broadcom Cygnus PCIe PHY driver"
depends on OF && (ARCH_BCM_CYGNUS || COMPILE_TEST)
select GENERIC_PHY
default ARCH_BCM_CYGNUS
help
Enable this to support the Broadcom Cygnus PCIe PHY.
If unsure, say N.
config BCM_KONA_USB2_PHY
tristate "Broadcom Kona USB2 PHY Driver"
depends on HAS_IOMEM
select GENERIC_PHY
help
Enable this to support the Broadcom Kona USB 2.0 PHY.
config PHY_BCM_NS_USB2
tristate "Broadcom Northstar USB 2.0 PHY Driver"
depends on ARCH_BCM_IPROC || COMPILE_TEST
depends on HAS_IOMEM && OF
select GENERIC_PHY
help
Enable this to support Broadcom USB 2.0 PHY connected to the USB
controller on Northstar family.
config PHY_BCM_NS_USB3
tristate "Broadcom Northstar USB 3.0 PHY Driver"
depends on ARCH_BCM_IPROC || COMPILE_TEST
depends on HAS_IOMEM && OF
select GENERIC_PHY
select MDIO_DEVICE
help
Enable this to support Broadcom USB 3.0 PHY connected to the USB
controller on Northstar family.
config PHY_NS2_PCIE
tristate "Broadcom Northstar2 PCIe PHY driver"
depends on OF && MDIO_BUS_MUX_BCM_IPROC
select GENERIC_PHY
default ARCH_BCM_IPROC
help
Enable this to support the Broadcom Northstar2 PCIe PHY.
If unsure, say N.
config PHY_NS2_USB_DRD
tristate "Broadcom Northstar2 USB DRD PHY support"
depends on OF && (ARCH_BCM_IPROC || COMPILE_TEST)
select GENERIC_PHY
select EXTCON
default ARCH_BCM_IPROC
help
Enable this to support the Broadcom Northstar2 USB DRD PHY.
This driver initializes the PHY in either HOST or DEVICE mode.
The host or device configuration is read from device tree.
If unsure, say N.
config PHY_BRCM_SATA
tristate "Broadcom SATA PHY driver"
depends on ARCH_BRCMSTB || ARCH_BCM_IPROC || BMIPS_GENERIC || COMPILE_TEST
depends on OF
select GENERIC_PHY
default ARCH_BCM_IPROC
help
Enable this to support the Broadcom SATA PHY.
If unsure, say N.
obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o
obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o
obj-$(CONFIG_PHY_BCM_NS_USB2) += phy-bcm-ns-usb2.o
obj-$(CONFIG_PHY_BCM_NS_USB3) += phy-bcm-ns-usb3.o
obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o
obj-$(CONFIG_PHY_NS2_USB_DRD) += phy-bcm-ns2-usbdrd.o
obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o
...@@ -16,7 +16,9 @@ ...@@ -16,7 +16,9 @@
#include <linux/bcma/bcma.h> #include <linux/bcma/bcma.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/mdio.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/phy/phy.h> #include <linux/phy/phy.h>
...@@ -52,7 +54,10 @@ struct bcm_ns_usb3 { ...@@ -52,7 +54,10 @@ struct bcm_ns_usb3 {
enum bcm_ns_family family; enum bcm_ns_family family;
void __iomem *dmp; void __iomem *dmp;
void __iomem *ccb_mii; void __iomem *ccb_mii;
struct mdio_device *mdiodev;
struct phy *phy; struct phy *phy;
int (*phy_write)(struct bcm_ns_usb3 *usb3, u16 reg, u16 value);
}; };
static const struct of_device_id bcm_ns_usb3_id_table[] = { static const struct of_device_id bcm_ns_usb3_id_table[] = {
...@@ -68,63 +73,16 @@ static const struct of_device_id bcm_ns_usb3_id_table[] = { ...@@ -68,63 +73,16 @@ static const struct of_device_id bcm_ns_usb3_id_table[] = {
}; };
MODULE_DEVICE_TABLE(of, bcm_ns_usb3_id_table); MODULE_DEVICE_TABLE(of, bcm_ns_usb3_id_table);
static int bcm_ns_usb3_wait_reg(struct bcm_ns_usb3 *usb3, void __iomem *addr,
u32 mask, u32 value, unsigned long timeout)
{
unsigned long deadline = jiffies + timeout;
u32 val;
do {
val = readl(addr);
if ((val & mask) == value)
return 0;
cpu_relax();
udelay(10);
} while (!time_after_eq(jiffies, deadline));
dev_err(usb3->dev, "Timeout waiting for register %p\n", addr);
return -EBUSY;
}
static inline int bcm_ns_usb3_mii_mng_wait_idle(struct bcm_ns_usb3 *usb3)
{
return bcm_ns_usb3_wait_reg(usb3, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL,
0x0100, 0x0000,
usecs_to_jiffies(BCM_NS_USB3_MII_MNG_TIMEOUT_US));
}
static int bcm_ns_usb3_mdio_phy_write(struct bcm_ns_usb3 *usb3, u16 reg, static int bcm_ns_usb3_mdio_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
u16 value) u16 value)
{ {
u32 tmp = 0; return usb3->phy_write(usb3, reg, value);
int err;
err = bcm_ns_usb3_mii_mng_wait_idle(usb3);
if (err < 0) {
dev_err(usb3->dev, "Couldn't write 0x%08x value\n", value);
return err;
}
/* TODO: Use a proper MDIO bus layer */
tmp |= 0x58020000; /* Magic value for MDIO PHY write */
tmp |= reg << 18;
tmp |= value;
writel(tmp, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA);
return 0;
} }
static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3) static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
{ {
int err; int err;
/* Enable MDIO. Setting MDCDIV as 26 */
writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL);
/* Wait for MDIO? */
udelay(2);
/* USB3 PLL Block */ /* USB3 PLL Block */
err = bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG, err = bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG,
BCM_NS_USB3_PHY_PLL30_BLOCK); BCM_NS_USB3_PHY_PLL30_BLOCK);
...@@ -143,9 +101,6 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3) ...@@ -143,9 +101,6 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
/* Deaaserting PLL Reset */ /* Deaaserting PLL Reset */
bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL1, 0x8000); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL1, 0x8000);
/* Waiting MII Mgt interface idle */
bcm_ns_usb3_mii_mng_wait_idle(usb3);
/* Deasserting USB3 system reset */ /* Deasserting USB3 system reset */
writel(0, usb3->dmp + BCMA_RESET_CTL); writel(0, usb3->dmp + BCMA_RESET_CTL);
...@@ -169,9 +124,6 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3) ...@@ -169,9 +124,6 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
/* Enabling SSC */ /* Enabling SSC */
bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_TX_PMD_CONTROL1, 0x1003); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_TX_PMD_CONTROL1, 0x1003);
/* Waiting MII Mgt interface idle */
bcm_ns_usb3_mii_mng_wait_idle(usb3);
return 0; return 0;
} }
...@@ -179,12 +131,6 @@ static int bcm_ns_usb3_phy_init_ns_ax(struct bcm_ns_usb3 *usb3) ...@@ -179,12 +131,6 @@ static int bcm_ns_usb3_phy_init_ns_ax(struct bcm_ns_usb3 *usb3)
{ {
int err; int err;
/* Enable MDIO. Setting MDCDIV as 26 */
writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL);
/* Wait for MDIO? */
udelay(2);
/* PLL30 block */ /* PLL30 block */
err = bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG, err = bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG,
BCM_NS_USB3_PHY_PLL30_BLOCK); BCM_NS_USB3_PHY_PLL30_BLOCK);
...@@ -205,9 +151,6 @@ static int bcm_ns_usb3_phy_init_ns_ax(struct bcm_ns_usb3 *usb3) ...@@ -205,9 +151,6 @@ static int bcm_ns_usb3_phy_init_ns_ax(struct bcm_ns_usb3 *usb3)
bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_TX_PMD_CONTROL1, 0x1003); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_TX_PMD_CONTROL1, 0x1003);
/* Waiting MII Mgt interface idle */
bcm_ns_usb3_mii_mng_wait_idle(usb3);
/* Deasserting USB3 system reset */ /* Deasserting USB3 system reset */
writel(0, usb3->dmp + BCMA_RESET_CTL); writel(0, usb3->dmp + BCMA_RESET_CTL);
...@@ -242,6 +185,128 @@ static const struct phy_ops ops = { ...@@ -242,6 +185,128 @@ static const struct phy_ops ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
/**************************************************
* MDIO driver code
**************************************************/
static int bcm_ns_usb3_mdiodev_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
u16 value)
{
struct mdio_device *mdiodev = usb3->mdiodev;
return mdiobus_write(mdiodev->bus, mdiodev->addr, reg, value);
}
static int bcm_ns_usb3_mdio_probe(struct mdio_device *mdiodev)
{
struct device *dev = &mdiodev->dev;
const struct of_device_id *of_id;
struct phy_provider *phy_provider;
struct device_node *syscon_np;
struct bcm_ns_usb3 *usb3;
struct resource res;
int err;
usb3 = devm_kzalloc(dev, sizeof(*usb3), GFP_KERNEL);
if (!usb3)
return -ENOMEM;
usb3->dev = dev;
usb3->mdiodev = mdiodev;
of_id = of_match_device(bcm_ns_usb3_id_table, dev);
if (!of_id)
return -EINVAL;
usb3->family = (enum bcm_ns_family)of_id->data;
syscon_np = of_parse_phandle(dev->of_node, "usb3-dmp-syscon", 0);
err = of_address_to_resource(syscon_np, 0, &res);
of_node_put(syscon_np);
if (err)
return err;
usb3->dmp = devm_ioremap_resource(dev, &res);
if (IS_ERR(usb3->dmp)) {
dev_err(dev, "Failed to map DMP regs\n");
return PTR_ERR(usb3->dmp);
}
usb3->phy_write = bcm_ns_usb3_mdiodev_phy_write;
usb3->phy = devm_phy_create(dev, NULL, &ops);
if (IS_ERR(usb3->phy)) {
dev_err(dev, "Failed to create PHY\n");
return PTR_ERR(usb3->phy);
}
phy_set_drvdata(usb3->phy, usb3);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
}
static struct mdio_driver bcm_ns_usb3_mdio_driver = {
.mdiodrv = {
.driver = {
.name = "bcm_ns_mdio_usb3",
.of_match_table = bcm_ns_usb3_id_table,
},
},
.probe = bcm_ns_usb3_mdio_probe,
};
/**************************************************
* Platform driver code
**************************************************/
static int bcm_ns_usb3_wait_reg(struct bcm_ns_usb3 *usb3, void __iomem *addr,
u32 mask, u32 value, unsigned long timeout)
{
unsigned long deadline = jiffies + timeout;
u32 val;
do {
val = readl(addr);
if ((val & mask) == value)
return 0;
cpu_relax();
udelay(10);
} while (!time_after_eq(jiffies, deadline));
dev_err(usb3->dev, "Timeout waiting for register %p\n", addr);
return -EBUSY;
}
static inline int bcm_ns_usb3_mii_mng_wait_idle(struct bcm_ns_usb3 *usb3)
{
return bcm_ns_usb3_wait_reg(usb3, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL,
0x0100, 0x0000,
usecs_to_jiffies(BCM_NS_USB3_MII_MNG_TIMEOUT_US));
}
static int bcm_ns_usb3_platform_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
u16 value)
{
u32 tmp = 0;
int err;
err = bcm_ns_usb3_mii_mng_wait_idle(usb3);
if (err < 0) {
dev_err(usb3->dev, "Couldn't write 0x%08x value\n", value);
return err;
}
/* TODO: Use a proper MDIO bus layer */
tmp |= 0x58020000; /* Magic value for MDIO PHY write */
tmp |= reg << 18;
tmp |= value;
writel(tmp, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA);
return bcm_ns_usb3_mii_mng_wait_idle(usb3);
}
static int bcm_ns_usb3_probe(struct platform_device *pdev) static int bcm_ns_usb3_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -275,6 +340,14 @@ static int bcm_ns_usb3_probe(struct platform_device *pdev) ...@@ -275,6 +340,14 @@ static int bcm_ns_usb3_probe(struct platform_device *pdev)
return PTR_ERR(usb3->ccb_mii); return PTR_ERR(usb3->ccb_mii);
} }
/* Enable MDIO. Setting MDCDIV as 26 */
writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL);
/* Wait for MDIO? */
udelay(2);
usb3->phy_write = bcm_ns_usb3_platform_phy_write;
usb3->phy = devm_phy_create(dev, NULL, &ops); usb3->phy = devm_phy_create(dev, NULL, &ops);
if (IS_ERR(usb3->phy)) { if (IS_ERR(usb3->phy)) {
dev_err(dev, "Failed to create PHY\n"); dev_err(dev, "Failed to create PHY\n");
...@@ -298,6 +371,35 @@ static struct platform_driver bcm_ns_usb3_driver = { ...@@ -298,6 +371,35 @@ static struct platform_driver bcm_ns_usb3_driver = {
.of_match_table = bcm_ns_usb3_id_table, .of_match_table = bcm_ns_usb3_id_table,
}, },
}; };
module_platform_driver(bcm_ns_usb3_driver);
static int __init bcm_ns_usb3_module_init(void)
{
int err;
/*
* For backward compatibility we register as MDIO and platform driver.
* After getting MDIO binding commonly used (e.g. switching all DT files
* to use it) we should deprecate the old binding and eventually drop
* support for it.
*/
err = mdio_driver_register(&bcm_ns_usb3_mdio_driver);
if (err)
return err;
err = platform_driver_register(&bcm_ns_usb3_driver);
if (err)
mdio_driver_unregister(&bcm_ns_usb3_mdio_driver);
return err;
}
module_init(bcm_ns_usb3_module_init);
static void __exit bcm_ns_usb3_module_exit(void)
{
platform_driver_unregister(&bcm_ns_usb3_driver);
mdio_driver_unregister(&bcm_ns_usb3_mdio_driver);
}
module_exit(bcm_ns_usb3_module_exit)
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
This diff is collapsed.
...@@ -46,6 +46,7 @@ enum brcm_sata_phy_version { ...@@ -46,6 +46,7 @@ enum brcm_sata_phy_version {
BRCM_SATA_PHY_STB_40NM, BRCM_SATA_PHY_STB_40NM,
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,
}; };
struct brcm_sata_port { struct brcm_sata_port {
...@@ -81,12 +82,17 @@ enum sata_phy_regs { ...@@ -81,12 +82,17 @@ enum sata_phy_regs {
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,
PLL_ACTRL6 = 0x86,
PLL1_REG_BANK = 0x060, PLL1_REG_BANK = 0x060,
PLL1_ACTRL2 = 0x82, PLL1_ACTRL2 = 0x82,
PLL1_ACTRL3 = 0x83, PLL1_ACTRL3 = 0x83,
PLL1_ACTRL4 = 0x84, PLL1_ACTRL4 = 0x84,
TX_REG_BANK = 0x070,
TX_ACTRL0 = 0x80,
TX_ACTRL0_TXPOL_FLIP = BIT(6),
OOB_REG_BANK = 0x150, OOB_REG_BANK = 0x150,
OOB1_REG_BANK = 0x160, OOB1_REG_BANK = 0x160,
OOB_CTRL1 = 0x80, OOB_CTRL1 = 0x80,
...@@ -347,6 +353,68 @@ static int brcm_nsp_sata_init(struct brcm_sata_port *port) ...@@ -347,6 +353,68 @@ static int brcm_nsp_sata_init(struct brcm_sata_port *port)
return 0; return 0;
} }
/* SR PHY PLL0 registers */
#define SR_PLL0_ACTRL6_MAGIC 0xa
/* SR PHY PLL1 registers */
#define SR_PLL1_ACTRL2_MAGIC 0x32
#define SR_PLL1_ACTRL3_MAGIC 0x2
#define SR_PLL1_ACTRL4_MAGIC 0x3e8
static int brcm_sr_sata_init(struct brcm_sata_port *port)
{
struct brcm_sata_phy *priv = port->phy_priv;
struct device *dev = port->phy_priv->dev;
void __iomem *base = priv->phy_base;
unsigned int val, try;
/* Configure PHY PLL register bank 1 */
val = SR_PLL1_ACTRL2_MAGIC;
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
val = SR_PLL1_ACTRL3_MAGIC;
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
val = SR_PLL1_ACTRL4_MAGIC;
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
/* Configure PHY PLL register bank 0 */
val = SR_PLL0_ACTRL6_MAGIC;
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_ACTRL6, 0x0, val);
/* Wait for PHY PLL lock by polling pll_lock bit */
try = 50;
do {
val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
BLOCK0_XGXSSTATUS);
if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
break;
msleep(20);
try--;
} while (try);
if ((val & BLOCK0_XGXSSTATUS_PLL_LOCK) == 0) {
/* PLL did not lock; give up */
dev_err(dev, "port%d PLL did not lock\n", port->portnum);
return -ETIMEDOUT;
}
/* Invert Tx polarity */
brcm_sata_phy_wr(base, TX_REG_BANK, TX_ACTRL0,
~TX_ACTRL0_TXPOL_FLIP, TX_ACTRL0_TXPOL_FLIP);
/* Configure OOB control to handle 100MHz reference clock */
val = ((0xc << OOB_CTRL1_BURST_MAX_SHIFT) |
(0x4 << OOB_CTRL1_BURST_MIN_SHIFT) |
(0x8 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT) |
(0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT));
brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL1, 0x0, val);
val = ((0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT) |
(0x2 << OOB_CTRL2_BURST_CNT_SHIFT) |
(0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT));
brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL2, 0x0, val);
return 0;
}
static int brcm_sata_phy_init(struct phy *phy) static int brcm_sata_phy_init(struct phy *phy)
{ {
int rc; int rc;
...@@ -363,6 +431,9 @@ static int brcm_sata_phy_init(struct phy *phy) ...@@ -363,6 +431,9 @@ static int brcm_sata_phy_init(struct phy *phy)
case BRCM_SATA_PHY_IPROC_NSP: case BRCM_SATA_PHY_IPROC_NSP:
rc = brcm_nsp_sata_init(port); rc = brcm_nsp_sata_init(port);
break; break;
case BRCM_SATA_PHY_IPROC_SR:
rc = brcm_sr_sata_init(port);
break;
default: default:
rc = -ENODEV; rc = -ENODEV;
} }
...@@ -384,6 +455,8 @@ static const struct of_device_id brcm_sata_phy_of_match[] = { ...@@ -384,6 +455,8 @@ static const struct of_device_id brcm_sata_phy_of_match[] = {
.data = (void *)BRCM_SATA_PHY_IPROC_NS2 }, .data = (void *)BRCM_SATA_PHY_IPROC_NS2 },
{ .compatible = "brcm,iproc-nsp-sata-phy", { .compatible = "brcm,iproc-nsp-sata-phy",
.data = (void *)BRCM_SATA_PHY_IPROC_NSP }, .data = (void *)BRCM_SATA_PHY_IPROC_NSP },
{ .compatible = "brcm,iproc-sr-sata-phy",
.data = (void *)BRCM_SATA_PHY_IPROC_SR },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match); MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);
......
#
# Phy drivers for Hisilicon platforms
#
config PHY_HI6220_USB
tristate "hi6220 USB PHY support"
depends on (ARCH_HISI && ARM64) || COMPILE_TEST
select GENERIC_PHY
select MFD_SYSCON
help
Enable this to support the HISILICON HI6220 USB PHY.
To compile this driver as a module, choose M here.
config PHY_HIX5HD2_SATA
tristate "HIX5HD2 SATA PHY Driver"
depends on ARCH_HIX5HD2 && OF && HAS_IOMEM
select GENERIC_PHY
select MFD_SYSCON
help
Support for SATA PHY on Hisilicon hix5hd2 Soc.
obj-$(CONFIG_PHY_HI6220_USB) += phy-hi6220-usb.o
obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o
#
# Phy drivers for Marvell platforms
#
config ARMADA375_USBCLUSTER_PHY
def_bool y
depends on MACH_ARMADA_375 || COMPILE_TEST
depends on OF && HAS_IOMEM
select GENERIC_PHY
config PHY_BERLIN_SATA
tristate "Marvell Berlin SATA PHY driver"
depends on ARCH_BERLIN && HAS_IOMEM && OF
select GENERIC_PHY
help
Enable this to support the SATA PHY on Marvell Berlin SoCs.
config PHY_BERLIN_USB
tristate "Marvell Berlin USB PHY Driver"
depends on ARCH_BERLIN && RESET_CONTROLLER && HAS_IOMEM && OF
select GENERIC_PHY
help
Enable this to support the USB PHY on Marvell Berlin SoCs.
config PHY_MVEBU_SATA
def_bool y
depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD
depends on OF
select GENERIC_PHY
config PHY_PXA_28NM_HSIC
tristate "Marvell USB HSIC 28nm PHY Driver"
depends on HAS_IOMEM
select GENERIC_PHY
help
Enable this to support Marvell USB HSIC PHY driver for Marvell
SoC. This driver will do the PHY initialization and shutdown.
The PHY driver will be used by Marvell ehci driver.
To compile this driver as a module, choose M here.
config PHY_PXA_28NM_USB2
tristate "Marvell USB 2.0 28nm PHY Driver"
depends on HAS_IOMEM
select GENERIC_PHY
help
Enable this to support Marvell USB 2.0 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.
obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o
obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o
obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.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_USB2) += phy-pxa-28nm-usb2.o
#
# Phy drivers for Motorola devices
#
config PHY_CPCAP_USB
tristate "CPCAP PMIC USB PHY driver"
depends on USB_SUPPORT && IIO
depends on USB_MUSB_HDRC || USB_MUSB_HDRC=n
select GENERIC_PHY
select USB_PHY
help
Enable this for USB to work on Motorola phones and tablets
such as Droid 4.
#
# Makefile for the phy drivers.
#
obj-$(CONFIG_PHY_CPCAP_USB) += phy-cpcap-usb.o
This diff is collapsed.
#
# Phy drivers for Qualcomm platforms
#
config PHY_QCOM_APQ8064_SATA
tristate "Qualcomm APQ8064 SATA SerDes/PHY driver"
depends on ARCH_QCOM
depends on HAS_IOMEM
depends on OF
select GENERIC_PHY
config PHY_QCOM_IPQ806X_SATA
tristate "Qualcomm IPQ806x SATA SerDes/PHY driver"
depends on ARCH_QCOM
depends on HAS_IOMEM
depends on OF
select GENERIC_PHY
config PHY_QCOM_QMP
tristate "Qualcomm QMP PHY Driver"
depends on OF && COMMON_CLK && (ARCH_QCOM || COMPILE_TEST)
select GENERIC_PHY
help
Enable this to support the QMP PHY transceiver that is used
with controllers such as PCIe, UFS, and USB on Qualcomm chips.
config PHY_QCOM_QUSB2
tristate "Qualcomm QUSB2 PHY Driver"
depends on OF && (ARCH_QCOM || COMPILE_TEST)
depends on NVMEM || !NVMEM
select GENERIC_PHY
help
Enable this to support the HighSpeed QUSB2 PHY transceiver for USB
controllers on Qualcomm chips. This driver supports the high-speed
PHY which is usually paired with either the ChipIdea or Synopsys DWC3
USB IPs on MSM SOCs.
config PHY_QCOM_UFS
tristate "Qualcomm UFS PHY driver"
depends on OF && ARCH_QCOM
select GENERIC_PHY
help
Support for UFS PHY on QCOM chipsets.
config PHY_QCOM_USB_HS
tristate "Qualcomm USB HS PHY module"
depends on USB_ULPI_BUS
depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in
select GENERIC_PHY
help
Support for the USB high-speed ULPI compliant phy on Qualcomm
chipsets.
config PHY_QCOM_USB_HSIC
tristate "Qualcomm USB HSIC ULPI PHY module"
depends on USB_ULPI_BUS
select GENERIC_PHY
help
Support for the USB HSIC ULPI compliant PHY on QCOM chipsets.
obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.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-qmp-14nm.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o
obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o
obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o
...@@ -11,12 +11,11 @@ ...@@ -11,12 +11,11 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/phy/phy.h>
#include <linux/reset.h> #include <linux/reset.h>
#include <linux/extcon.h> #include <linux/extcon.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include "ulpi_phy.h"
#define ULPI_PWR_CLK_MNG_REG 0x88 #define ULPI_PWR_CLK_MNG_REG 0x88
# define ULPI_PWR_OTG_COMP_DISABLE BIT(0) # define ULPI_PWR_OTG_COMP_DISABLE BIT(0)
......
...@@ -8,13 +8,12 @@ ...@@ -8,13 +8,12 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/ulpi/driver.h> #include <linux/ulpi/driver.h>
#include <linux/ulpi/regs.h> #include <linux/ulpi/regs.h>
#include <linux/phy/phy.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinctrl-state.h> #include <linux/pinctrl/pinctrl-state.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/clk.h> #include <linux/clk.h>
#include "ulpi_phy.h"
#define ULPI_HSIC_CFG 0x30 #define ULPI_HSIC_CFG 0x30
#define ULPI_HSIC_IO_CAL 0x33 #define ULPI_HSIC_IO_CAL 0x33
......
#
# Phy drivers for Renesas platforms
#
config PHY_RCAR_GEN2
tristate "Renesas R-Car generation 2 USB PHY driver"
depends on ARCH_RENESAS
depends on GENERIC_PHY
help
Support for USB PHY found on Renesas R-Car generation 2 SoCs.
config PHY_RCAR_GEN3_USB2
tristate "Renesas R-Car generation 3 USB 2.0 PHY driver"
depends on ARCH_RENESAS
depends on EXTCON
select GENERIC_PHY
help
Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs.
config PHY_RCAR_GEN3_USB3
tristate "Renesas R-Car generation 3 USB 3.0 PHY driver"
depends on ARCH_RENESAS || COMPILE_TEST
select GENERIC_PHY
help
Support for USB 3.0 PHY found on Renesas R-Car generation 3 SoCs.
obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o
obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o
obj-$(CONFIG_PHY_RCAR_GEN3_USB3) += phy-rcar-gen3-usb3.o
/*
* Renesas R-Car Gen3 for USB3.0 PHY driver
*
* 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/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#define USB30_CLKSET0 0x034
#define USB30_CLKSET1 0x036
#define USB30_SSC_SET 0x038
#define USB30_PHY_ENABLE 0x060
#define USB30_VBUS_EN 0x064
/* USB30_CLKSET0 */
#define CLKSET0_PRIVATE 0x05c0
#define CLKSET0_USB30_FSEL_USB_EXTAL 0x0002
/* USB30_CLKSET1 */
#define CLKSET1_USB30_PLL_MULTI_SHIFT 6
#define CLKSET1_USB30_PLL_MULTI_USB_EXTAL (0x64 << \
CLKSET1_USB30_PLL_MULTI_SHIFT)
#define CLKSET1_PHYRESET BIT(4) /* 1: reset */
#define CLKSET1_REF_CLKDIV BIT(3) /* 1: USB_EXTAL */
#define CLKSET1_PRIVATE_2_1 BIT(1) /* Write B'01 */
#define CLKSET1_REF_CLK_SEL BIT(0) /* 1: USB3S0_CLK_P */
/* USB30_SSC_SET */
#define SSC_SET_SSC_EN BIT(12)
#define SSC_SET_RANGE_SHIFT 9
#define SSC_SET_RANGE_4980 (0x0 << SSC_SET_RANGE_SHIFT)
#define SSC_SET_RANGE_4492 (0x1 << SSC_SET_RANGE_SHIFT)
#define SSC_SET_RANGE_4003 (0x2 << SSC_SET_RANGE_SHIFT)
/* USB30_PHY_ENABLE */
#define PHY_ENABLE_RESET_EN BIT(4)
/* USB30_VBUS_EN */
#define VBUS_EN_VBUS_EN BIT(1)
struct rcar_gen3_usb3 {
void __iomem *base;
struct phy *phy;
u32 ssc_range;
bool usb3s_clk;
bool usb_extal;
};
static void write_clkset1_for_usb_extal(struct rcar_gen3_usb3 *r, bool reset)
{
u16 val = CLKSET1_USB30_PLL_MULTI_USB_EXTAL |
CLKSET1_REF_CLKDIV | CLKSET1_PRIVATE_2_1;
if (reset)
val |= CLKSET1_PHYRESET;
writew(val, r->base + USB30_CLKSET1);
}
static void rcar_gen3_phy_usb3_enable_ssc(struct rcar_gen3_usb3 *r)
{
u16 val = SSC_SET_SSC_EN;
switch (r->ssc_range) {
case 4980:
val |= SSC_SET_RANGE_4980;
break;
case 4492:
val |= SSC_SET_RANGE_4492;
break;
case 4003:
val |= SSC_SET_RANGE_4003;
break;
default:
dev_err(&r->phy->dev, "%s: unsupported range (%x)\n", __func__,
r->ssc_range);
return;
}
writew(val, r->base + USB30_SSC_SET);
}
static void rcar_gen3_phy_usb3_select_usb_extal(struct rcar_gen3_usb3 *r)
{
write_clkset1_for_usb_extal(r, false);
if (r->ssc_range)
rcar_gen3_phy_usb3_enable_ssc(r);
writew(CLKSET0_PRIVATE | CLKSET0_USB30_FSEL_USB_EXTAL,
r->base + USB30_CLKSET0);
writew(PHY_ENABLE_RESET_EN, r->base + USB30_PHY_ENABLE);
write_clkset1_for_usb_extal(r, true);
usleep_range(10, 20);
write_clkset1_for_usb_extal(r, false);
}
static int rcar_gen3_phy_usb3_init(struct phy *p)
{
struct rcar_gen3_usb3 *r = phy_get_drvdata(p);
dev_vdbg(&r->phy->dev, "%s: enter (%d, %d, %d)\n", __func__,
r->usb3s_clk, r->usb_extal, r->ssc_range);
if (!r->usb3s_clk && r->usb_extal)
rcar_gen3_phy_usb3_select_usb_extal(r);
/* Enables VBUS detection anyway */
writew(VBUS_EN_VBUS_EN, r->base + USB30_VBUS_EN);
return 0;
}
static const struct phy_ops rcar_gen3_phy_usb3_ops = {
.init = rcar_gen3_phy_usb3_init,
.owner = THIS_MODULE,
};
static const struct of_device_id rcar_gen3_phy_usb3_match_table[] = {
{ .compatible = "renesas,rcar-gen3-usb3-phy" },
{ }
};
MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb3_match_table);
static int rcar_gen3_phy_usb3_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct rcar_gen3_usb3 *r;
struct phy_provider *provider;
struct resource *res;
int ret = 0;
struct clk *clk;
if (!dev->of_node) {
dev_err(dev, "This driver needs device tree\n");
return -EINVAL;
}
r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL);
if (!r)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
r->base = devm_ioremap_resource(dev, res);
if (IS_ERR(r->base))
return PTR_ERR(r->base);
clk = devm_clk_get(dev, "usb3s_clk");
if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
r->usb3s_clk = !!clk_get_rate(clk);
clk_disable_unprepare(clk);
}
clk = devm_clk_get(dev, "usb_extal");
if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
r->usb_extal = !!clk_get_rate(clk);
clk_disable_unprepare(clk);
}
if (!r->usb3s_clk && !r->usb_extal) {
dev_err(dev, "This driver needs usb3s_clk and/or usb_extal\n");
ret = -EINVAL;
goto error;
}
/*
* devm_phy_create() will call pm_runtime_enable(&phy->dev);
* And then, phy-core will manage runtime pm for this device.
*/
pm_runtime_enable(dev);
r->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb3_ops);
if (IS_ERR(r->phy)) {
dev_err(dev, "Failed to create USB3 PHY\n");
ret = PTR_ERR(r->phy);
goto error;
}
of_property_read_u32(dev->of_node, "renesas,ssc-range", &r->ssc_range);
platform_set_drvdata(pdev, r);
phy_set_drvdata(r->phy, r);
provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
if (IS_ERR(provider)) {
dev_err(dev, "Failed to register PHY provider\n");
ret = PTR_ERR(provider);
goto error;
}
return 0;
error:
pm_runtime_disable(dev);
return ret;
}
static int rcar_gen3_phy_usb3_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
return 0;
};
static struct platform_driver rcar_gen3_phy_usb3_driver = {
.driver = {
.name = "phy_rcar_gen3_usb3",
.of_match_table = rcar_gen3_phy_usb3_match_table,
},
.probe = rcar_gen3_phy_usb3_probe,
.remove = rcar_gen3_phy_usb3_remove,
};
module_platform_driver(rcar_gen3_phy_usb3_driver);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Renesas R-Car Gen3 USB 3.0 PHY");
MODULE_AUTHOR("Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>");
#
# Phy drivers for Rockchip platforms
#
config PHY_ROCKCHIP_DP
tristate "Rockchip Display Port PHY Driver"
depends on ARCH_ROCKCHIP && OF
select GENERIC_PHY
help
Enable this to support the Rockchip Display Port PHY.
config PHY_ROCKCHIP_EMMC
tristate "Rockchip EMMC PHY Driver"
depends on ARCH_ROCKCHIP && OF
select GENERIC_PHY
help
Enable this to support the Rockchip EMMC PHY.
config PHY_ROCKCHIP_INNO_USB2
tristate "Rockchip INNO USB2PHY Driver"
depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
depends on COMMON_CLK
depends on EXTCON
depends on USB_SUPPORT
select GENERIC_PHY
select USB_COMMON
help
Support for Rockchip USB2.0 PHY with Innosilicon IP block.
config PHY_ROCKCHIP_PCIE
tristate "Rockchip PCIe PHY Driver"
depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST
select GENERIC_PHY
select MFD_SYSCON
help
Enable this to support the Rockchip PCIe PHY.
config PHY_ROCKCHIP_TYPEC
tristate "Rockchip TYPEC PHY Driver"
depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
select EXTCON
select GENERIC_PHY
select RESET_CONTROLLER
help
Enable this to support the Rockchip USB TYPEC PHY.
config PHY_ROCKCHIP_USB
tristate "Rockchip USB2 PHY Driver"
depends on ARCH_ROCKCHIP && OF
select GENERIC_PHY
help
Enable this to support the Rockchip USB 2.0 PHY.
obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.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_TYPEC) += phy-rockchip-typec.o
obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
...@@ -406,7 +406,8 @@ static int rockchip_usb2phy_init(struct phy *phy) ...@@ -406,7 +406,8 @@ static int rockchip_usb2phy_init(struct phy *phy)
mutex_lock(&rport->mutex); mutex_lock(&rport->mutex);
if (rport->port_id == USB2PHY_PORT_OTG) { if (rport->port_id == USB2PHY_PORT_OTG) {
if (rport->mode != USB_DR_MODE_HOST) { if (rport->mode != USB_DR_MODE_HOST &&
rport->mode != USB_DR_MODE_UNKNOWN) {
/* clear bvalid status and enable bvalid detect irq */ /* clear bvalid status and enable bvalid detect irq */
ret = property_enable(rphy, ret = property_enable(rphy,
&rport->port_cfg->bvalid_det_clr, &rport->port_cfg->bvalid_det_clr,
...@@ -421,7 +422,7 @@ static int rockchip_usb2phy_init(struct phy *phy) ...@@ -421,7 +422,7 @@ static int rockchip_usb2phy_init(struct phy *phy)
goto out; goto out;
schedule_delayed_work(&rport->otg_sm_work, schedule_delayed_work(&rport->otg_sm_work,
OTG_SCHEDULE_DELAY); OTG_SCHEDULE_DELAY * 3);
} else { } else {
/* If OTG works in host only mode, do nothing. */ /* If OTG works in host only mode, do nothing. */
dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode); dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
...@@ -463,6 +464,9 @@ static int rockchip_usb2phy_power_on(struct phy *phy) ...@@ -463,6 +464,9 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
if (ret) if (ret)
return ret; return ret;
/* waiting for the utmi_clk to become stable */
usleep_range(1500, 2000);
rport->suspended = false; rport->suspended = false;
return 0; return 0;
} }
...@@ -493,7 +497,8 @@ static int rockchip_usb2phy_exit(struct phy *phy) ...@@ -493,7 +497,8 @@ static int rockchip_usb2phy_exit(struct phy *phy)
struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
if (rport->port_id == USB2PHY_PORT_OTG && if (rport->port_id == USB2PHY_PORT_OTG &&
rport->mode != USB_DR_MODE_HOST) { rport->mode != USB_DR_MODE_HOST &&
rport->mode != USB_DR_MODE_UNKNOWN) {
cancel_delayed_work_sync(&rport->otg_sm_work); cancel_delayed_work_sync(&rport->otg_sm_work);
cancel_delayed_work_sync(&rport->chg_work); cancel_delayed_work_sync(&rport->chg_work);
} else if (rport->port_id == USB2PHY_PORT_HOST) } else if (rport->port_id == USB2PHY_PORT_HOST)
...@@ -970,7 +975,8 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy, ...@@ -970,7 +975,8 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
mutex_init(&rport->mutex); mutex_init(&rport->mutex);
rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1); rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
if (rport->mode == USB_DR_MODE_HOST) { if (rport->mode == USB_DR_MODE_HOST ||
rport->mode == USB_DR_MODE_UNKNOWN) {
ret = 0; ret = 0;
goto out; goto out;
} }
...@@ -1138,6 +1144,65 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) ...@@ -1138,6 +1144,65 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
return ret; return ret;
} }
static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = {
{
.reg = 0x760,
.num_ports = 2,
.clkout_ctl = { 0x0768, 4, 4, 1, 0 },
.port_cfgs = {
[USB2PHY_PORT_OTG] = {
.phy_sus = { 0x0760, 15, 0, 0, 0x1d1 },
.bvalid_det_en = { 0x0680, 3, 3, 0, 1 },
.bvalid_det_st = { 0x0690, 3, 3, 0, 1 },
.bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
.ls_det_en = { 0x0680, 2, 2, 0, 1 },
.ls_det_st = { 0x0690, 2, 2, 0, 1 },
.ls_det_clr = { 0x06a0, 2, 2, 0, 1 },
.utmi_bvalid = { 0x0480, 4, 4, 0, 1 },
.utmi_ls = { 0x0480, 3, 2, 0, 1 },
},
[USB2PHY_PORT_HOST] = {
.phy_sus = { 0x0764, 15, 0, 0, 0x1d1 },
.ls_det_en = { 0x0680, 4, 4, 0, 1 },
.ls_det_st = { 0x0690, 4, 4, 0, 1 },
.ls_det_clr = { 0x06a0, 4, 4, 0, 1 }
}
},
.chg_det = {
.opmode = { 0x0760, 3, 0, 5, 1 },
.cp_det = { 0x0884, 4, 4, 0, 1 },
.dcp_det = { 0x0884, 3, 3, 0, 1 },
.dp_det = { 0x0884, 5, 5, 0, 1 },
.idm_sink_en = { 0x0768, 8, 8, 0, 1 },
.idp_sink_en = { 0x0768, 7, 7, 0, 1 },
.idp_src_en = { 0x0768, 9, 9, 0, 1 },
.rdm_pdwn_en = { 0x0768, 10, 10, 0, 1 },
.vdm_src_en = { 0x0768, 12, 12, 0, 1 },
.vdp_src_en = { 0x0768, 11, 11, 0, 1 },
},
},
{
.reg = 0x800,
.num_ports = 2,
.clkout_ctl = { 0x0808, 4, 4, 1, 0 },
.port_cfgs = {
[USB2PHY_PORT_OTG] = {
.phy_sus = { 0x800, 15, 0, 0, 0x1d1 },
.ls_det_en = { 0x0684, 0, 0, 0, 1 },
.ls_det_st = { 0x0694, 0, 0, 0, 1 },
.ls_det_clr = { 0x06a4, 0, 0, 0, 1 }
},
[USB2PHY_PORT_HOST] = {
.phy_sus = { 0x804, 15, 0, 0, 0x1d1 },
.ls_det_en = { 0x0684, 1, 1, 0, 1 },
.ls_det_st = { 0x0694, 1, 1, 0, 1 },
.ls_det_clr = { 0x06a4, 1, 1, 0, 1 }
}
},
},
{ /* sentinel */ }
};
static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = { static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
{ {
.reg = 0x100, .reg = 0x100,
...@@ -1263,6 +1328,7 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = { ...@@ -1263,6 +1328,7 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
}; };
static const struct of_device_id rockchip_usb2phy_dt_match[] = { static const struct of_device_id rockchip_usb2phy_dt_match[] = {
{ .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
{ .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs }, { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs }, { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs }, { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
......
#
# Phy drivers for Samsung platforms
#
config PHY_EXYNOS_DP_VIDEO
tristate "EXYNOS SoC series Display Port PHY driver"
depends on OF
depends on ARCH_EXYNOS || COMPILE_TEST
default ARCH_EXYNOS
select GENERIC_PHY
help
Support for Display Port PHY found on Samsung EXYNOS SoCs.
config PHY_EXYNOS_MIPI_VIDEO
tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
depends on HAS_IOMEM
depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
select GENERIC_PHY
default y if ARCH_S5PV210 || ARCH_EXYNOS
help
Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P
and EXYNOS SoCs.
config PHY_EXYNOS_PCIE
bool "Exynos PCIe PHY driver"
depends on OF && (ARCH_EXYNOS || COMPILE_TEST)
select GENERIC_PHY
help
Enable PCIe PHY support for Exynos SoC series.
This driver provides PHY interface for Exynos PCIe controller.
config PHY_SAMSUNG_USB2
tristate "Samsung USB 2.0 PHY driver"
depends on HAS_IOMEM
depends on USB_EHCI_EXYNOS || USB_OHCI_EXYNOS || USB_DWC2
select GENERIC_PHY
select MFD_SYSCON
default ARCH_EXYNOS
help
Enable this to support the Samsung USB 2.0 PHY driver for Samsung
SoCs. This driver provides the interface for USB 2.0 PHY. Support
for particular PHYs will be enabled based on the SoC type in addition
to this driver.
config PHY_EXYNOS4210_USB2
bool
depends on PHY_SAMSUNG_USB2
default CPU_EXYNOS4210
config PHY_EXYNOS4X12_USB2
bool
depends on PHY_SAMSUNG_USB2
default SOC_EXYNOS3250 || SOC_EXYNOS4212 || SOC_EXYNOS4412
config PHY_EXYNOS5250_USB2
bool
depends on PHY_SAMSUNG_USB2
default SOC_EXYNOS5250 || SOC_EXYNOS5420
config PHY_S5PV210_USB2
bool "Support for S5PV210"
depends on PHY_SAMSUNG_USB2
depends on ARCH_S5PV210
help
Enable USB PHY support for S5PV210. This option requires that Samsung
USB 2.0 PHY driver is enabled and means that support for this
particular SoC is compiled in the driver. In case of S5PV210 two phys
are available - device and host.
config PHY_EXYNOS5_USBDRD
tristate "Exynos5 SoC series USB DRD PHY driver"
depends on ARCH_EXYNOS && OF
depends on HAS_IOMEM
depends on USB_DWC3_EXYNOS
select GENERIC_PHY
select MFD_SYSCON
default y
help
Enable USB DRD PHY support for Exynos 5 SoC series.
This driver provides PHY interface for USB 3.0 DRD controller
present on Exynos5 SoC series.
config PHY_EXYNOS5250_SATA
tristate "Exynos5250 Sata SerDes/PHY driver"
depends on SOC_EXYNOS5250
depends on HAS_IOMEM
depends on OF
select GENERIC_PHY
select I2C
select I2C_S3C2410
select MFD_SYSCON
help
Enable this to support SATA SerDes/Phy found on Samsung's
Exynos5250 based SoCs.This SerDes/Phy supports SATA 1.5 Gb/s,
SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host
port to accept one SATA device.
obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o
obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
obj-$(CONFIG_PHY_EXYNOS_PCIE) += phy-exynos-pcie.o
obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o
phy-exynos-usb2-y += phy-samsung-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o
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.
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