forked from Minki/linux
phy: tegra: Changes for v4.7-rc1
This set of patches adds support for the Tegra XUSB pad controller. The controller provides a set of pads (lanes) that are used for I/O by other IP blocks within Tegra SoCs (PCIe, SATA and XUSB). -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJXI3hiAAoJEN0jrNd/PrOhSeIP/0ziDYSAgTbB30L2CJNLnyp3 xnbn6YHLsZVcwD4Pxlu9TW2z4iqCz3BU7Glbv0zc8tGGW9OzaPPH2M/+Vl8neM5O fRaP/hd2FlW9leiPU/xNU4gdGycRuk94clxObNtS8g3qKxl2KsQeZBWiMfIPsJRE IvK57SmLtznDgigtV2xJjH90OkwycAWQBi6r7pcttnLWB5qAEkMl0EnVz35q6EOM 8EXOSjMATdrxRwE3FjRDzzSWPUpRHG61DC4krMpo8VgHXyqUdR1o5VwxEPIBcL3W td/oPZrUNAa7z/IoSdH9SD9IEc1OIwZOmcwFkOsFjFRn118gx+RE7pd8QkvKaCGU CDfqHS76pgOrnHOLWCtuYMagrPtwI2H8KOqx2VOLdKQghez1ykk0gCpKqp5CLGC1 G4VQp1jK7y4dB97K3C5/8WfntNSczE+kb61B3Q3gHKaP8GfvBtdhGfP+POXwp4bC rrw8kienv3sws11GTZXMHhQWVGgbWxenPh+Fjj43fnI8YSoweC9xErWmxQyUYcov xv+ryi+BoGyr36IbX2dng7peRzgxGadMRFwOJ0EVBw27nGZNuULwgtFSgYcCTZRY 6wJKxGX8EWpI034LVyhbrPy34cIFTSkzZCeYvENWzPNCw7y+bC7hjBewPMPDNF7U 63BEtuIczTyzgUjcav+s =JRT5 -----END PGP SIGNATURE----- Merge tag 'tegra-for-4.7-phy' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers Merge "phy: tegra: Changes for v4.7-rc1" from Thierry Reding: This set of patches adds support for the Tegra XUSB pad controller. The controller provides a set of pads (lanes) that are used for I/O by other IP blocks within Tegra SoCs (PCIe, SATA and XUSB). * tag 'tegra-for-4.7-phy' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: phy: tegra: Add Tegra210 support phy: Add Tegra XUSB pad controller support dt-bindings: phy: tegra-xusb-padctl: Add Tegra210 support dt-bindings: phy: Add NVIDIA Tegra XUSB pad controller binding phy: core: Allow children node to be overridden clk: tegra: Add interface to enable hardware control of SATA/XUSB PLLs
This commit is contained in:
commit
4ace926172
@ -0,0 +1,733 @@
|
||||
Device tree binding for NVIDIA Tegra XUSB pad controller
|
||||
========================================================
|
||||
|
||||
The Tegra XUSB pad controller manages a set of I/O lanes (with differential
|
||||
signals) which connect directly to pins/pads on the SoC package. Each lane
|
||||
is controlled by a HW block referred to as a "pad" in the Tegra hardware
|
||||
documentation. Each such "pad" may control either one or multiple lanes,
|
||||
and thus contains any logic common to all its lanes. Each lane can be
|
||||
separately configured and powered up.
|
||||
|
||||
Some of the lanes are high-speed lanes, which can be used for PCIe, SATA or
|
||||
super-speed USB. Other lanes are for various types of low-speed, full-speed
|
||||
or high-speed USB (such as UTMI, ULPI and HSIC). The XUSB pad controller
|
||||
contains a software-configurable mux that sits between the I/O controller
|
||||
ports (e.g. PCIe) and the lanes.
|
||||
|
||||
In addition to per-lane configuration, USB 3.0 ports may require additional
|
||||
settings on a per-board basis.
|
||||
|
||||
Pads will be represented as children of the top-level XUSB pad controller
|
||||
device tree node. Each lane exposed by the pad will be represented by its
|
||||
own subnode and can be referenced by users of the lane using the standard
|
||||
PHY bindings, as described by the phy-bindings.txt file in this directory.
|
||||
|
||||
The Tegra hardware documentation refers to the connection between the XUSB
|
||||
pad controller and the XUSB controller as "ports". This is confusing since
|
||||
"port" is typically used to denote the physical USB receptacle. The device
|
||||
tree binding in this document uses the term "port" to refer to the logical
|
||||
abstraction of the signals that are routed to a USB receptacle (i.e. a PHY
|
||||
for the USB signal, the VBUS power supply, the USB 2.0 companion port for
|
||||
USB 3.0 receptacles, ...).
|
||||
|
||||
Required properties:
|
||||
--------------------
|
||||
- compatible: Must be:
|
||||
- Tegra124: "nvidia,tegra124-xusb-padctl"
|
||||
- Tegra132: "nvidia,tegra132-xusb-padctl", "nvidia,tegra124-xusb-padctl"
|
||||
- Tegra210: "nvidia,tegra210-xusb-padctl"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
- reset-names: Must include the following entries:
|
||||
- "padctl"
|
||||
|
||||
|
||||
Pad nodes:
|
||||
==========
|
||||
|
||||
A required child node named "pads" contains a list of subnodes, one for each
|
||||
of the pads exposed by the XUSB pad controller. Each pad may need additional
|
||||
resources that can be referenced in its pad node.
|
||||
|
||||
The "status" property is used to enable or disable the use of a pad. If set
|
||||
to "disabled", the pad will not be used on the given board. In order to use
|
||||
the pad and any of its lanes, this property must be set to "okay".
|
||||
|
||||
For Tegra124 and Tegra132, the following pads exist: usb2, ulpi, hsic, pcie
|
||||
and sata. No extra resources are required for operation of these pads.
|
||||
|
||||
For Tegra210, the following pads exist: usb2, hsic, pcie and sata. Below is
|
||||
a description of the properties of each pad.
|
||||
|
||||
UTMI pad:
|
||||
---------
|
||||
|
||||
Required properties:
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
- clock-names: Must contain the following entries:
|
||||
- "trk": phandle and specifier referring to the USB2 tracking clock
|
||||
|
||||
HSIC pad:
|
||||
---------
|
||||
|
||||
Required properties:
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
- clock-names: Must contain the following entries:
|
||||
- "trk": phandle and specifier referring to the HSIC tracking clock
|
||||
|
||||
PCIe pad:
|
||||
---------
|
||||
|
||||
Required properties:
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
- clock-names: Must contain the following entries:
|
||||
- "pll": phandle and specifier referring to the PLLE
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
- reset-names: Must contain the following entries:
|
||||
- "phy": reset for the PCIe UPHY block
|
||||
|
||||
SATA pad:
|
||||
---------
|
||||
|
||||
Required properties:
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
- reset-names: Must contain the following entries:
|
||||
- "phy": reset for the SATA UPHY block
|
||||
|
||||
|
||||
PHY nodes:
|
||||
==========
|
||||
|
||||
Each pad node has a child named "lanes" that contains one or more children of
|
||||
its own, each representing one of the lanes controlled by the pad.
|
||||
|
||||
Required properties:
|
||||
--------------------
|
||||
- status: Defines the operation status of the PHY. Valid values are:
|
||||
- "disabled": the PHY is disabled
|
||||
- "okay": the PHY is enabled
|
||||
- #phy-cells: Should be 0. Since each lane represents a single PHY, there is
|
||||
no need for an additional specifier.
|
||||
- nvidia,function: The output function of the PHY. See below for a list of
|
||||
valid functions per SoC generation.
|
||||
|
||||
For Tegra124 and Tegra132, the list of valid PHY nodes is given below:
|
||||
- usb2: usb2-0, usb2-1, usb2-2
|
||||
- functions: "snps", "xusb", "uart"
|
||||
- ulpi: ulpi-0
|
||||
- functions: "snps", "xusb"
|
||||
- hsic: hsic-0, hsic-1
|
||||
- functions: "snps", "xusb"
|
||||
- pcie: pcie-0, pcie-1, pcie-2, pcie-3, pcie-4
|
||||
- functions: "pcie", "usb3-ss"
|
||||
- sata: sata-0
|
||||
- functions: "usb3-ss", "sata"
|
||||
|
||||
For Tegra210, the list of valid PHY nodes is given below:
|
||||
- utmi: utmi-0, utmi-1, utmi-2, utmi-3
|
||||
- functions: "snps", "xusb", "uart"
|
||||
- hsic: hsic-0, hsic-1
|
||||
- functions: "snps", "xusb"
|
||||
- pcie: pcie-0, pcie-1, pcie-2, pcie-3, pcie-4, pcie-5, pcie-6
|
||||
- functions: "pcie-x1", "usb3-ss", "pcie-x4"
|
||||
- sata: sata-0
|
||||
- functions: "usb3-ss", "sata"
|
||||
|
||||
|
||||
Port nodes:
|
||||
===========
|
||||
|
||||
A required child node named "ports" contains a list of all the ports exposed
|
||||
by the XUSB pad controller. Per-port configuration is only required for USB.
|
||||
|
||||
USB2 ports:
|
||||
-----------
|
||||
|
||||
Required properties:
|
||||
- status: Defines the operation status of the port. Valid values are:
|
||||
- "disabled": the port is disabled
|
||||
- "okay": the port is enabled
|
||||
- mode: A string that determines the mode in which to run the port. Valid
|
||||
values are:
|
||||
- "host": for USB host mode
|
||||
- "device": for USB device mode
|
||||
- "otg": for USB OTG mode
|
||||
|
||||
Optional properties:
|
||||
- nvidia,internal: A boolean property whose presence determines that a port
|
||||
is internal. In the absence of this property the port is considered to be
|
||||
external.
|
||||
- vbus-supply: phandle to a regulator supplying the VBUS voltage.
|
||||
|
||||
ULPI ports:
|
||||
-----------
|
||||
|
||||
Optional properties:
|
||||
- status: Defines the operation status of the port. Valid values are:
|
||||
- "disabled": the port is disabled
|
||||
- "okay": the port is enabled
|
||||
- nvidia,internal: A boolean property whose presence determines that a port
|
||||
is internal. In the absence of this property the port is considered to be
|
||||
external.
|
||||
- vbus-supply: phandle to a regulator supplying the VBUS voltage.
|
||||
|
||||
HSIC ports:
|
||||
-----------
|
||||
|
||||
Required properties:
|
||||
- status: Defines the operation status of the port. Valid values are:
|
||||
- "disabled": the port is disabled
|
||||
- "okay": the port is enabled
|
||||
|
||||
Optional properties:
|
||||
- vbus-supply: phandle to a regulator supplying the VBUS voltage.
|
||||
|
||||
Super-speed USB ports:
|
||||
----------------------
|
||||
|
||||
Required properties:
|
||||
- status: Defines the operation status of the port. Valid values are:
|
||||
- "disabled": the port is disabled
|
||||
- "okay": the port is enabled
|
||||
- nvidia,usb2-companion: A single cell that specifies the physical port number
|
||||
to map this super-speed USB port to. The range of valid port numbers varies
|
||||
with the SoC generation:
|
||||
- 0-2: for Tegra124 and Tegra132
|
||||
- 0-3: for Tegra210
|
||||
|
||||
Optional properties:
|
||||
- nvidia,internal: A boolean property whose presence determines that a port
|
||||
is internal. In the absence of this property the port is considered to be
|
||||
external.
|
||||
|
||||
For Tegra124 and Tegra132, the XUSB pad controller exposes the following
|
||||
ports:
|
||||
- 3x USB2: usb2-0, usb2-1, usb2-2
|
||||
- 1x ULPI: ulpi-0
|
||||
- 2x HSIC: hsic-0, hsic-1
|
||||
- 2x super-speed USB: usb3-0, usb3-1
|
||||
|
||||
For Tegra210, the XUSB pad controller exposes the following ports:
|
||||
- 4x USB2: usb2-0, usb2-1, usb2-2, usb2-3
|
||||
- 2x HSIC: hsic-0, hsic-1
|
||||
- 4x super-speed USB: usb3-0, usb3-1, usb3-2, usb3-3
|
||||
|
||||
|
||||
Examples:
|
||||
=========
|
||||
|
||||
Tegra124 and Tegra132:
|
||||
----------------------
|
||||
|
||||
SoC include:
|
||||
|
||||
padctl@7009f000 {
|
||||
/* for Tegra124 */
|
||||
compatible = "nvidia,tegra124-xusb-padctl";
|
||||
/* for Tegra132 */
|
||||
compatible = "nvidia,tegra132-xusb-padctl",
|
||||
"nvidia,tegra124-xusb-padctl";
|
||||
reg = <0x0 0x7009f000 0x0 0x1000>;
|
||||
resets = <&tegra_car 142>;
|
||||
reset-names = "padctl";
|
||||
|
||||
pads {
|
||||
usb2 {
|
||||
status = "disabled";
|
||||
|
||||
lanes {
|
||||
usb2-0 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
usb2-1 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
usb2-2 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ulpi {
|
||||
status = "disabled";
|
||||
|
||||
lanes {
|
||||
ulpi-0 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
hsic {
|
||||
status = "disabled";
|
||||
|
||||
lanes {
|
||||
hsic-0 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
hsic-1 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pcie {
|
||||
status = "disabled";
|
||||
|
||||
lanes {
|
||||
pcie-0 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
pcie-1 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
pcie-2 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
pcie-3 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
pcie-4 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sata {
|
||||
status = "disabled";
|
||||
|
||||
lanes {
|
||||
sata-0 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ports {
|
||||
usb2-0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb2-1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb2-2 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ulpi-0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
hsic-0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
hsic-1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb3-0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb3-1 {
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Board file:
|
||||
|
||||
padctl@7009f000 {
|
||||
status = "okay";
|
||||
|
||||
pads {
|
||||
usb2 {
|
||||
status = "okay";
|
||||
|
||||
lanes {
|
||||
usb2-0 {
|
||||
nvidia,function = "xusb";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usb2-1 {
|
||||
nvidia,function = "xusb";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usb2-2 {
|
||||
nvidia,function = "xusb";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pcie {
|
||||
status = "okay";
|
||||
|
||||
lanes {
|
||||
pcie-0 {
|
||||
nvidia,function = "usb3-ss";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
pcie-2 {
|
||||
nvidia,function = "pcie";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
pcie-4 {
|
||||
nvidia,function = "pcie";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sata {
|
||||
status = "okay";
|
||||
|
||||
lanes {
|
||||
sata-0 {
|
||||
nvidia,function = "sata";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ports {
|
||||
/* Micro A/B */
|
||||
usb2-0 {
|
||||
status = "okay";
|
||||
mode = "otg";
|
||||
};
|
||||
|
||||
/* Mini PCIe */
|
||||
usb2-1 {
|
||||
status = "okay";
|
||||
mode = "host";
|
||||
};
|
||||
|
||||
/* USB3 */
|
||||
usb2-2 {
|
||||
status = "okay";
|
||||
mode = "host";
|
||||
|
||||
vbus-supply = <&vdd_usb3_vbus>;
|
||||
};
|
||||
|
||||
usb3-0 {
|
||||
nvidia,port = <2>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Tegra210:
|
||||
---------
|
||||
|
||||
SoC include:
|
||||
|
||||
padctl@7009f000 {
|
||||
compatible = "nvidia,tegra210-xusb-padctl";
|
||||
reg = <0x0 0x7009f000 0x0 0x1000>;
|
||||
resets = <&tegra_car 142>;
|
||||
reset-names = "padctl";
|
||||
|
||||
status = "disabled";
|
||||
|
||||
pads {
|
||||
usb2 {
|
||||
clocks = <&tegra_car TEGRA210_CLK_USB2_TRK>;
|
||||
clock-names = "trk";
|
||||
status = "disabled";
|
||||
|
||||
lanes {
|
||||
usb2-0 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
usb2-1 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
usb2-2 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
usb2-3 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
hsic {
|
||||
clocks = <&tegra_car TEGRA210_CLK_HSIC_TRK>;
|
||||
clock-names = "trk";
|
||||
status = "disabled";
|
||||
|
||||
lanes {
|
||||
hsic-0 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
hsic-1 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pcie {
|
||||
clocks = <&tegra_car TEGRA210_CLK_PLL_E>;
|
||||
clock-names = "pll";
|
||||
resets = <&tegra_car 205>;
|
||||
reset-names = "phy";
|
||||
status = "disabled";
|
||||
|
||||
lanes {
|
||||
pcie-0 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
pcie-1 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
pcie-2 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
pcie-3 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
pcie-4 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
pcie-5 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
pcie-6 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sata {
|
||||
clocks = <&tegra_car TEGRA210_CLK_PLL_E>;
|
||||
clock-names = "pll";
|
||||
resets = <&tegra_car 204>;
|
||||
reset-names = "phy";
|
||||
status = "disabled";
|
||||
|
||||
lanes {
|
||||
sata-0 {
|
||||
status = "disabled";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ports {
|
||||
usb2-0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb2-1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb2-2 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb2-3 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
hsic-0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
hsic-1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb3-0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb3-1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb3-2 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb3-3 {
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Board file:
|
||||
|
||||
padctl@7009f000 {
|
||||
status = "okay";
|
||||
|
||||
pads {
|
||||
usb2 {
|
||||
status = "okay";
|
||||
|
||||
lanes {
|
||||
usb2-0 {
|
||||
nvidia,function = "xusb";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usb2-1 {
|
||||
nvidia,function = "xusb";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usb2-2 {
|
||||
nvidia,function = "xusb";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usb2-3 {
|
||||
nvidia,function = "xusb";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pcie {
|
||||
status = "okay";
|
||||
|
||||
lanes {
|
||||
pcie-0 {
|
||||
nvidia,function = "pcie-x1";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
pcie-1 {
|
||||
nvidia,function = "pcie-x4";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
pcie-2 {
|
||||
nvidia,function = "pcie-x4";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
pcie-3 {
|
||||
nvidia,function = "pcie-x4";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
pcie-4 {
|
||||
nvidia,function = "pcie-x4";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
pcie-5 {
|
||||
nvidia,function = "usb3-ss";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
pcie-6 {
|
||||
nvidia,function = "usb3-ss";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sata {
|
||||
status = "okay";
|
||||
|
||||
lanes {
|
||||
sata-0 {
|
||||
nvidia,function = "sata";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ports {
|
||||
usb2-0 {
|
||||
status = "okay";
|
||||
mode = "otg";
|
||||
};
|
||||
|
||||
usb2-1 {
|
||||
status = "okay";
|
||||
vbus-supply = <&vdd_5v0_rtl>;
|
||||
mode = "host";
|
||||
};
|
||||
|
||||
usb2-2 {
|
||||
status = "okay";
|
||||
vbus-supply = <&vdd_usb_vbus>;
|
||||
mode = "host";
|
||||
};
|
||||
|
||||
usb2-3 {
|
||||
status = "okay";
|
||||
mode = "host";
|
||||
};
|
||||
|
||||
usb3-0 {
|
||||
status = "okay";
|
||||
nvidia,lanes = "pcie-6";
|
||||
nvidia,port = <1>;
|
||||
};
|
||||
|
||||
usb3-1 {
|
||||
status = "okay";
|
||||
nvidia,lanes = "pcie-5";
|
||||
nvidia,port = <2>;
|
||||
};
|
||||
};
|
||||
};
|
@ -1,6 +1,12 @@
|
||||
Device tree binding for NVIDIA Tegra XUSB pad controller
|
||||
========================================================
|
||||
|
||||
NOTE: It turns out that this binding isn't an accurate description of the XUSB
|
||||
pad controller. While the description is good enough for the functional subset
|
||||
required for PCIe and SATA, it lacks the flexibility to represent the features
|
||||
needed for USB. For the new binding, see ../phy/nvidia,tegra-xusb-padctl.txt.
|
||||
The binding described in this file is deprecated and should not be used.
|
||||
|
||||
The Tegra XUSB pad controller manages a set of lanes, each of which can be
|
||||
assigned to one out of a set of different pads. Some of these pads have an
|
||||
associated PHY that must be powered up before the pad can be used.
|
||||
|
@ -31,16 +31,28 @@ should provide its own implementation of of_xlate. of_xlate is used only for
|
||||
dt boot case.
|
||||
|
||||
#define of_phy_provider_register(dev, xlate) \
|
||||
__of_phy_provider_register((dev), THIS_MODULE, (xlate))
|
||||
__of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
|
||||
|
||||
#define devm_of_phy_provider_register(dev, xlate) \
|
||||
__devm_of_phy_provider_register((dev), THIS_MODULE, (xlate))
|
||||
__devm_of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
|
||||
|
||||
of_phy_provider_register and devm_of_phy_provider_register macros can be used to
|
||||
register the phy_provider and it takes device and of_xlate as
|
||||
arguments. For the dt boot case, all PHY providers should use one of the above
|
||||
2 macros to register the PHY provider.
|
||||
|
||||
Often the device tree nodes associated with a PHY provider will contain a set
|
||||
of children that each represent a single PHY. Some bindings may nest the child
|
||||
nodes within extra levels for context and extensibility, in which case the low
|
||||
level of_phy_provider_register_full() and devm_of_phy_provider_register_full()
|
||||
macros can be used to override the node containing the children.
|
||||
|
||||
#define of_phy_provider_register_full(dev, children, xlate) \
|
||||
__of_phy_provider_register(dev, children, THIS_MODULE, xlate)
|
||||
|
||||
#define devm_of_phy_provider_register_full(dev, children, xlate) \
|
||||
__devm_of_phy_provider_register_full(dev, children, THIS_MODULE, xlate)
|
||||
|
||||
void devm_of_phy_provider_unregister(struct device *dev,
|
||||
struct phy_provider *phy_provider);
|
||||
void of_phy_provider_unregister(struct phy_provider *phy_provider);
|
||||
|
@ -175,6 +175,19 @@
|
||||
#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14)
|
||||
#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12)
|
||||
|
||||
#define SATA_PLL_CFG0 0x490
|
||||
#define SATA_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0)
|
||||
#define SATA_PLL_CFG0_PADPLL_USE_LOCKDET BIT(2)
|
||||
#define SATA_PLL_CFG0_PADPLL_SLEEP_IDDQ BIT(13)
|
||||
#define SATA_PLL_CFG0_SEQ_ENABLE BIT(24)
|
||||
|
||||
#define XUSBIO_PLL_CFG0 0x51c
|
||||
#define XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0)
|
||||
#define XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL BIT(2)
|
||||
#define XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET BIT(6)
|
||||
#define XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ BIT(13)
|
||||
#define XUSBIO_PLL_CFG0_SEQ_ENABLE BIT(24)
|
||||
|
||||
#define UTMIPLL_HW_PWRDN_CFG0 0x52c
|
||||
#define UTMIPLL_HW_PWRDN_CFG0_UTMIPLL_LOCK BIT(31)
|
||||
#define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE BIT(25)
|
||||
@ -416,6 +429,51 @@ static const char *mux_pllmcp_clkm[] = {
|
||||
#define PLLU_MISC0_WRITE_MASK 0xbfffffff
|
||||
#define PLLU_MISC1_WRITE_MASK 0x00000007
|
||||
|
||||
void tegra210_xusb_pll_hw_control_enable(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl_relaxed(clk_base + XUSBIO_PLL_CFG0);
|
||||
val &= ~(XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL |
|
||||
XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL);
|
||||
val |= XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET |
|
||||
XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ;
|
||||
writel_relaxed(val, clk_base + XUSBIO_PLL_CFG0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra210_xusb_pll_hw_control_enable);
|
||||
|
||||
void tegra210_xusb_pll_hw_sequence_start(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl_relaxed(clk_base + XUSBIO_PLL_CFG0);
|
||||
val |= XUSBIO_PLL_CFG0_SEQ_ENABLE;
|
||||
writel_relaxed(val, clk_base + XUSBIO_PLL_CFG0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra210_xusb_pll_hw_sequence_start);
|
||||
|
||||
void tegra210_sata_pll_hw_control_enable(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl_relaxed(clk_base + SATA_PLL_CFG0);
|
||||
val &= ~SATA_PLL_CFG0_PADPLL_RESET_SWCTL;
|
||||
val |= SATA_PLL_CFG0_PADPLL_USE_LOCKDET |
|
||||
SATA_PLL_CFG0_PADPLL_SLEEP_IDDQ;
|
||||
writel_relaxed(val, clk_base + SATA_PLL_CFG0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra210_sata_pll_hw_control_enable);
|
||||
|
||||
void tegra210_sata_pll_hw_sequence_start(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl_relaxed(clk_base + SATA_PLL_CFG0);
|
||||
val |= SATA_PLL_CFG0_SEQ_ENABLE;
|
||||
writel_relaxed(val, clk_base + SATA_PLL_CFG0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra210_sata_pll_hw_sequence_start);
|
||||
|
||||
static inline void _pll_misc_chk_default(void __iomem *base,
|
||||
struct tegra_clk_pll_params *params,
|
||||
u8 misc_num, u32 default_val, u32 mask)
|
||||
|
@ -421,4 +421,6 @@ config PHY_CYGNUS_PCIE
|
||||
Enable this to support the Broadcom Cygnus PCIe PHY.
|
||||
If unsure, say N.
|
||||
|
||||
source "drivers/phy/tegra/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
@ -52,3 +52,5 @@ obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o
|
||||
obj-$(CONFIG_PHY_BRCMSTB_SATA) += phy-brcmstb-sata.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/
|
||||
|
@ -141,7 +141,7 @@ static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
|
||||
if (phy_provider->dev->of_node == node)
|
||||
return phy_provider;
|
||||
|
||||
for_each_child_of_node(phy_provider->dev->of_node, child)
|
||||
for_each_child_of_node(phy_provider->children, child)
|
||||
if (child == node)
|
||||
return phy_provider;
|
||||
}
|
||||
@ -811,24 +811,59 @@ EXPORT_SYMBOL_GPL(devm_phy_destroy);
|
||||
/**
|
||||
* __of_phy_provider_register() - create/register phy provider with the framework
|
||||
* @dev: struct device of the phy provider
|
||||
* @children: device node containing children (if different from dev->of_node)
|
||||
* @owner: the module owner containing of_xlate
|
||||
* @of_xlate: function pointer to obtain phy instance from phy provider
|
||||
*
|
||||
* Creates struct phy_provider from dev and of_xlate function pointer.
|
||||
* This is used in the case of dt boot for finding the phy instance from
|
||||
* phy provider.
|
||||
*
|
||||
* If the PHY provider doesn't nest children directly but uses a separate
|
||||
* child node to contain the individual children, the @children parameter
|
||||
* can be used to override the default. If NULL, the default (dev->of_node)
|
||||
* will be used. If non-NULL, the device node must be a child (or further
|
||||
* descendant) of dev->of_node. Otherwise an ERR_PTR()-encoded -EINVAL
|
||||
* error code is returned.
|
||||
*/
|
||||
struct phy_provider *__of_phy_provider_register(struct device *dev,
|
||||
struct module *owner, struct phy * (*of_xlate)(struct device *dev,
|
||||
struct of_phandle_args *args))
|
||||
struct device_node *children, struct module *owner,
|
||||
struct phy * (*of_xlate)(struct device *dev,
|
||||
struct of_phandle_args *args))
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
|
||||
/*
|
||||
* If specified, the device node containing the children must itself
|
||||
* be the provider's device node or a child (or further descendant)
|
||||
* thereof.
|
||||
*/
|
||||
if (children) {
|
||||
struct device_node *parent = of_node_get(children), *next;
|
||||
|
||||
while (parent) {
|
||||
if (parent == dev->of_node)
|
||||
break;
|
||||
|
||||
next = of_get_parent(parent);
|
||||
of_node_put(parent);
|
||||
parent = next;
|
||||
}
|
||||
|
||||
if (!parent)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
of_node_put(parent);
|
||||
} else {
|
||||
children = dev->of_node;
|
||||
}
|
||||
|
||||
phy_provider = kzalloc(sizeof(*phy_provider), GFP_KERNEL);
|
||||
if (!phy_provider)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
phy_provider->dev = dev;
|
||||
phy_provider->children = of_node_get(children);
|
||||
phy_provider->owner = owner;
|
||||
phy_provider->of_xlate = of_xlate;
|
||||
|
||||
@ -854,8 +889,9 @@ EXPORT_SYMBOL_GPL(__of_phy_provider_register);
|
||||
* on the devres data, then, devres data is freed.
|
||||
*/
|
||||
struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
|
||||
struct module *owner, struct phy * (*of_xlate)(struct device *dev,
|
||||
struct of_phandle_args *args))
|
||||
struct device_node *children, struct module *owner,
|
||||
struct phy * (*of_xlate)(struct device *dev,
|
||||
struct of_phandle_args *args))
|
||||
{
|
||||
struct phy_provider **ptr, *phy_provider;
|
||||
|
||||
@ -863,7 +899,8 @@ struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
phy_provider = __of_phy_provider_register(dev, owner, of_xlate);
|
||||
phy_provider = __of_phy_provider_register(dev, children, owner,
|
||||
of_xlate);
|
||||
if (!IS_ERR(phy_provider)) {
|
||||
*ptr = phy_provider;
|
||||
devres_add(dev, ptr);
|
||||
@ -888,6 +925,7 @@ void of_phy_provider_unregister(struct phy_provider *phy_provider)
|
||||
|
||||
mutex_lock(&phy_provider_mutex);
|
||||
list_del(&phy_provider->list);
|
||||
of_node_put(phy_provider->children);
|
||||
kfree(phy_provider);
|
||||
mutex_unlock(&phy_provider_mutex);
|
||||
}
|
||||
|
8
drivers/phy/tegra/Kconfig
Normal file
8
drivers/phy/tegra/Kconfig
Normal file
@ -0,0 +1,8 @@
|
||||
config PHY_TEGRA_XUSB
|
||||
tristate "NVIDIA Tegra XUSB pad controller driver"
|
||||
depends on ARCH_TEGRA
|
||||
help
|
||||
Choose this option if you have an NVIDIA Tegra SoC.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called phy-tegra-xusb.
|
6
drivers/phy/tegra/Makefile
Normal file
6
drivers/phy/tegra/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
obj-$(CONFIG_PHY_TEGRA_XUSB) += phy-tegra-xusb.o
|
||||
|
||||
phy-tegra-xusb-y += xusb.o
|
||||
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_124_SOC) += xusb-tegra124.o
|
||||
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_132_SOC) += xusb-tegra124.o
|
||||
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_210_SOC) += xusb-tegra210.o
|
1752
drivers/phy/tegra/xusb-tegra124.c
Normal file
1752
drivers/phy/tegra/xusb-tegra124.c
Normal file
File diff suppressed because it is too large
Load Diff
2045
drivers/phy/tegra/xusb-tegra210.c
Normal file
2045
drivers/phy/tegra/xusb-tegra210.c
Normal file
File diff suppressed because it is too large
Load Diff
1021
drivers/phy/tegra/xusb.c
Normal file
1021
drivers/phy/tegra/xusb.c
Normal file
File diff suppressed because it is too large
Load Diff
421
drivers/phy/tegra/xusb.h
Normal file
421
drivers/phy/tegra/xusb.h
Normal file
@ -0,0 +1,421 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2015, Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#ifndef __PHY_TEGRA_XUSB_H
|
||||
#define __PHY_TEGRA_XUSB_H
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
/* legacy entry points for backwards-compatibility */
|
||||
int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev);
|
||||
int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev);
|
||||
|
||||
struct phy;
|
||||
struct phy_provider;
|
||||
struct platform_device;
|
||||
struct regulator;
|
||||
|
||||
/*
|
||||
* lanes
|
||||
*/
|
||||
struct tegra_xusb_lane_soc {
|
||||
const char *name;
|
||||
|
||||
unsigned int offset;
|
||||
unsigned int shift;
|
||||
unsigned int mask;
|
||||
|
||||
const char * const *funcs;
|
||||
unsigned int num_funcs;
|
||||
};
|
||||
|
||||
struct tegra_xusb_lane {
|
||||
const struct tegra_xusb_lane_soc *soc;
|
||||
struct tegra_xusb_pad *pad;
|
||||
struct device_node *np;
|
||||
struct list_head list;
|
||||
unsigned int function;
|
||||
unsigned int index;
|
||||
};
|
||||
|
||||
int tegra_xusb_lane_parse_dt(struct tegra_xusb_lane *lane,
|
||||
struct device_node *np);
|
||||
|
||||
struct tegra_xusb_usb2_lane {
|
||||
struct tegra_xusb_lane base;
|
||||
|
||||
u32 hs_curr_level_offset;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_usb2_lane *
|
||||
to_usb2_lane(struct tegra_xusb_lane *lane)
|
||||
{
|
||||
return container_of(lane, struct tegra_xusb_usb2_lane, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_ulpi_lane {
|
||||
struct tegra_xusb_lane base;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_ulpi_lane *
|
||||
to_ulpi_lane(struct tegra_xusb_lane *lane)
|
||||
{
|
||||
return container_of(lane, struct tegra_xusb_ulpi_lane, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_hsic_lane {
|
||||
struct tegra_xusb_lane base;
|
||||
|
||||
u32 strobe_trim;
|
||||
u32 rx_strobe_trim;
|
||||
u32 rx_data_trim;
|
||||
u32 tx_rtune_n;
|
||||
u32 tx_rtune_p;
|
||||
u32 tx_rslew_n;
|
||||
u32 tx_rslew_p;
|
||||
bool auto_term;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_hsic_lane *
|
||||
to_hsic_lane(struct tegra_xusb_lane *lane)
|
||||
{
|
||||
return container_of(lane, struct tegra_xusb_hsic_lane, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_pcie_lane {
|
||||
struct tegra_xusb_lane base;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_pcie_lane *
|
||||
to_pcie_lane(struct tegra_xusb_lane *lane)
|
||||
{
|
||||
return container_of(lane, struct tegra_xusb_pcie_lane, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_sata_lane {
|
||||
struct tegra_xusb_lane base;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_sata_lane *
|
||||
to_sata_lane(struct tegra_xusb_lane *lane)
|
||||
{
|
||||
return container_of(lane, struct tegra_xusb_sata_lane, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_lane_ops {
|
||||
struct tegra_xusb_lane *(*probe)(struct tegra_xusb_pad *pad,
|
||||
struct device_node *np,
|
||||
unsigned int index);
|
||||
void (*remove)(struct tegra_xusb_lane *lane);
|
||||
};
|
||||
|
||||
/*
|
||||
* pads
|
||||
*/
|
||||
struct tegra_xusb_pad_soc;
|
||||
struct tegra_xusb_padctl;
|
||||
|
||||
struct tegra_xusb_pad_ops {
|
||||
struct tegra_xusb_pad *(*probe)(struct tegra_xusb_padctl *padctl,
|
||||
const struct tegra_xusb_pad_soc *soc,
|
||||
struct device_node *np);
|
||||
void (*remove)(struct tegra_xusb_pad *pad);
|
||||
};
|
||||
|
||||
struct tegra_xusb_pad_soc {
|
||||
const char *name;
|
||||
|
||||
const struct tegra_xusb_lane_soc *lanes;
|
||||
unsigned int num_lanes;
|
||||
|
||||
const struct tegra_xusb_pad_ops *ops;
|
||||
};
|
||||
|
||||
struct tegra_xusb_pad {
|
||||
const struct tegra_xusb_pad_soc *soc;
|
||||
struct tegra_xusb_padctl *padctl;
|
||||
struct phy_provider *provider;
|
||||
struct phy **lanes;
|
||||
struct device dev;
|
||||
|
||||
const struct tegra_xusb_lane_ops *ops;
|
||||
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_pad *to_tegra_xusb_pad(struct device *dev)
|
||||
{
|
||||
return container_of(dev, struct tegra_xusb_pad, dev);
|
||||
}
|
||||
|
||||
int tegra_xusb_pad_init(struct tegra_xusb_pad *pad,
|
||||
struct tegra_xusb_padctl *padctl,
|
||||
struct device_node *np);
|
||||
int tegra_xusb_pad_register(struct tegra_xusb_pad *pad,
|
||||
const struct phy_ops *ops);
|
||||
void tegra_xusb_pad_unregister(struct tegra_xusb_pad *pad);
|
||||
|
||||
struct tegra_xusb_usb2_pad {
|
||||
struct tegra_xusb_pad base;
|
||||
|
||||
struct clk *clk;
|
||||
unsigned int enable;
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_usb2_pad *
|
||||
to_usb2_pad(struct tegra_xusb_pad *pad)
|
||||
{
|
||||
return container_of(pad, struct tegra_xusb_usb2_pad, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_ulpi_pad {
|
||||
struct tegra_xusb_pad base;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_ulpi_pad *
|
||||
to_ulpi_pad(struct tegra_xusb_pad *pad)
|
||||
{
|
||||
return container_of(pad, struct tegra_xusb_ulpi_pad, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_hsic_pad {
|
||||
struct tegra_xusb_pad base;
|
||||
|
||||
struct regulator *supply;
|
||||
struct clk *clk;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_hsic_pad *
|
||||
to_hsic_pad(struct tegra_xusb_pad *pad)
|
||||
{
|
||||
return container_of(pad, struct tegra_xusb_hsic_pad, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_pcie_pad {
|
||||
struct tegra_xusb_pad base;
|
||||
|
||||
struct reset_control *rst;
|
||||
struct clk *pll;
|
||||
|
||||
unsigned int enable;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_pcie_pad *
|
||||
to_pcie_pad(struct tegra_xusb_pad *pad)
|
||||
{
|
||||
return container_of(pad, struct tegra_xusb_pcie_pad, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_sata_pad {
|
||||
struct tegra_xusb_pad base;
|
||||
|
||||
struct reset_control *rst;
|
||||
struct clk *pll;
|
||||
|
||||
unsigned int enable;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_sata_pad *
|
||||
to_sata_pad(struct tegra_xusb_pad *pad)
|
||||
{
|
||||
return container_of(pad, struct tegra_xusb_sata_pad, base);
|
||||
}
|
||||
|
||||
/*
|
||||
* ports
|
||||
*/
|
||||
struct tegra_xusb_port_ops;
|
||||
|
||||
struct tegra_xusb_port {
|
||||
struct tegra_xusb_padctl *padctl;
|
||||
struct tegra_xusb_lane *lane;
|
||||
unsigned int index;
|
||||
|
||||
struct list_head list;
|
||||
struct device dev;
|
||||
|
||||
const struct tegra_xusb_port_ops *ops;
|
||||
};
|
||||
|
||||
struct tegra_xusb_lane_map {
|
||||
unsigned int port;
|
||||
const char *type;
|
||||
unsigned int index;
|
||||
const char *func;
|
||||
};
|
||||
|
||||
struct tegra_xusb_lane *
|
||||
tegra_xusb_port_find_lane(struct tegra_xusb_port *port,
|
||||
const struct tegra_xusb_lane_map *map,
|
||||
const char *function);
|
||||
|
||||
struct tegra_xusb_port *
|
||||
tegra_xusb_find_port(struct tegra_xusb_padctl *padctl, const char *type,
|
||||
unsigned int index);
|
||||
|
||||
struct tegra_xusb_usb2_port {
|
||||
struct tegra_xusb_port base;
|
||||
|
||||
struct regulator *supply;
|
||||
bool internal;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_usb2_port *
|
||||
to_usb2_port(struct tegra_xusb_port *port)
|
||||
{
|
||||
return container_of(port, struct tegra_xusb_usb2_port, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_usb2_port *
|
||||
tegra_xusb_find_usb2_port(struct tegra_xusb_padctl *padctl,
|
||||
unsigned int index);
|
||||
|
||||
struct tegra_xusb_ulpi_port {
|
||||
struct tegra_xusb_port base;
|
||||
|
||||
struct regulator *supply;
|
||||
bool internal;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_ulpi_port *
|
||||
to_ulpi_port(struct tegra_xusb_port *port)
|
||||
{
|
||||
return container_of(port, struct tegra_xusb_ulpi_port, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_hsic_port {
|
||||
struct tegra_xusb_port base;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_hsic_port *
|
||||
to_hsic_port(struct tegra_xusb_port *port)
|
||||
{
|
||||
return container_of(port, struct tegra_xusb_hsic_port, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_usb3_port {
|
||||
struct tegra_xusb_port base;
|
||||
struct regulator *supply;
|
||||
bool context_saved;
|
||||
unsigned int port;
|
||||
bool internal;
|
||||
|
||||
u32 tap1;
|
||||
u32 amp;
|
||||
u32 ctle_z;
|
||||
u32 ctle_g;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_usb3_port *
|
||||
to_usb3_port(struct tegra_xusb_port *port)
|
||||
{
|
||||
return container_of(port, struct tegra_xusb_usb3_port, base);
|
||||
}
|
||||
|
||||
struct tegra_xusb_usb3_port *
|
||||
tegra_xusb_find_usb3_port(struct tegra_xusb_padctl *padctl,
|
||||
unsigned int index);
|
||||
|
||||
struct tegra_xusb_port_ops {
|
||||
int (*enable)(struct tegra_xusb_port *port);
|
||||
void (*disable)(struct tegra_xusb_port *port);
|
||||
struct tegra_xusb_lane *(*map)(struct tegra_xusb_port *port);
|
||||
};
|
||||
|
||||
/*
|
||||
* pad controller
|
||||
*/
|
||||
struct tegra_xusb_padctl_soc;
|
||||
|
||||
struct tegra_xusb_padctl_ops {
|
||||
struct tegra_xusb_padctl *
|
||||
(*probe)(struct device *dev,
|
||||
const struct tegra_xusb_padctl_soc *soc);
|
||||
void (*remove)(struct tegra_xusb_padctl *padctl);
|
||||
|
||||
int (*usb3_save_context)(struct tegra_xusb_padctl *padctl,
|
||||
unsigned int index);
|
||||
int (*hsic_set_idle)(struct tegra_xusb_padctl *padctl,
|
||||
unsigned int index, bool idle);
|
||||
int (*usb3_set_lfps_detect)(struct tegra_xusb_padctl *padctl,
|
||||
unsigned int index, bool enable);
|
||||
};
|
||||
|
||||
struct tegra_xusb_padctl_soc {
|
||||
const struct tegra_xusb_pad_soc * const *pads;
|
||||
unsigned int num_pads;
|
||||
|
||||
struct {
|
||||
struct {
|
||||
const struct tegra_xusb_port_ops *ops;
|
||||
unsigned int count;
|
||||
} usb2, ulpi, hsic, usb3;
|
||||
} ports;
|
||||
|
||||
const struct tegra_xusb_padctl_ops *ops;
|
||||
};
|
||||
|
||||
struct tegra_xusb_padctl {
|
||||
struct device *dev;
|
||||
void __iomem *regs;
|
||||
struct mutex lock;
|
||||
struct reset_control *rst;
|
||||
|
||||
const struct tegra_xusb_padctl_soc *soc;
|
||||
|
||||
struct tegra_xusb_pad *pcie;
|
||||
struct tegra_xusb_pad *sata;
|
||||
struct tegra_xusb_pad *ulpi;
|
||||
struct tegra_xusb_pad *usb2;
|
||||
struct tegra_xusb_pad *hsic;
|
||||
|
||||
struct list_head ports;
|
||||
struct list_head lanes;
|
||||
struct list_head pads;
|
||||
|
||||
unsigned int enable;
|
||||
|
||||
struct clk *clk;
|
||||
};
|
||||
|
||||
static inline void padctl_writel(struct tegra_xusb_padctl *padctl, u32 value,
|
||||
unsigned long offset)
|
||||
{
|
||||
dev_dbg(padctl->dev, "%08lx < %08x\n", offset, value);
|
||||
writel(value, padctl->regs + offset);
|
||||
}
|
||||
|
||||
static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl,
|
||||
unsigned long offset)
|
||||
{
|
||||
u32 value = readl(padctl->regs + offset);
|
||||
dev_dbg(padctl->dev, "%08lx > %08x\n", offset, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
struct tegra_xusb_lane *tegra_xusb_find_lane(struct tegra_xusb_padctl *padctl,
|
||||
const char *name,
|
||||
unsigned int index);
|
||||
|
||||
#if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC)
|
||||
extern const struct tegra_xusb_padctl_soc tegra124_xusb_padctl_soc;
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
|
||||
extern const struct tegra_xusb_padctl_soc tegra210_xusb_padctl_soc;
|
||||
#endif
|
||||
|
||||
#endif /* __PHY_TEGRA_XUSB_H */
|
@ -873,7 +873,7 @@ static const struct of_device_id tegra_xusb_padctl_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match);
|
||||
|
||||
static int tegra_xusb_padctl_probe(struct platform_device *pdev)
|
||||
int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra_xusb_padctl *padctl;
|
||||
const struct of_device_id *match;
|
||||
@ -955,8 +955,9 @@ reset:
|
||||
reset_control_assert(padctl->rst);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra_xusb_padctl_legacy_probe);
|
||||
|
||||
static int tegra_xusb_padctl_remove(struct platform_device *pdev)
|
||||
int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra_xusb_padctl *padctl = platform_get_drvdata(pdev);
|
||||
int err;
|
||||
@ -969,17 +970,4 @@ static int tegra_xusb_padctl_remove(struct platform_device *pdev)
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct platform_driver tegra_xusb_padctl_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-xusb-padctl",
|
||||
.of_match_table = tegra_xusb_padctl_of_match,
|
||||
},
|
||||
.probe = tegra_xusb_padctl_probe,
|
||||
.remove = tegra_xusb_padctl_remove,
|
||||
};
|
||||
module_platform_driver(tegra_xusb_padctl_driver);
|
||||
|
||||
MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
|
||||
MODULE_DESCRIPTION("Tegra 124 XUSB Pad Control driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
EXPORT_SYMBOL_GPL(tegra_xusb_padctl_legacy_remove);
|
||||
|
@ -121,4 +121,9 @@ static inline void tegra_cpu_clock_resume(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void tegra210_xusb_pll_hw_control_enable(void);
|
||||
extern void tegra210_xusb_pll_hw_sequence_start(void);
|
||||
extern void tegra210_sata_pll_hw_control_enable(void);
|
||||
extern void tegra210_sata_pll_hw_sequence_start(void);
|
||||
|
||||
#endif /* __LINUX_CLK_TEGRA_H_ */
|
||||
|
@ -77,6 +77,7 @@ struct phy {
|
||||
*/
|
||||
struct phy_provider {
|
||||
struct device *dev;
|
||||
struct device_node *children;
|
||||
struct module *owner;
|
||||
struct list_head list;
|
||||
struct phy * (*of_xlate)(struct device *dev,
|
||||
@ -93,10 +94,16 @@ struct phy_lookup {
|
||||
#define to_phy(a) (container_of((a), struct phy, dev))
|
||||
|
||||
#define of_phy_provider_register(dev, xlate) \
|
||||
__of_phy_provider_register((dev), THIS_MODULE, (xlate))
|
||||
__of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
|
||||
|
||||
#define devm_of_phy_provider_register(dev, xlate) \
|
||||
__devm_of_phy_provider_register((dev), THIS_MODULE, (xlate))
|
||||
__devm_of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
|
||||
|
||||
#define of_phy_provider_register_full(dev, children, xlate) \
|
||||
__of_phy_provider_register(dev, children, THIS_MODULE, xlate)
|
||||
|
||||
#define devm_of_phy_provider_register_full(dev, children, xlate) \
|
||||
__devm_of_phy_provider_register(dev, children, THIS_MODULE, xlate)
|
||||
|
||||
static inline void phy_set_drvdata(struct phy *phy, void *data)
|
||||
{
|
||||
@ -147,11 +154,13 @@ struct phy *devm_phy_create(struct device *dev, struct device_node *node,
|
||||
void phy_destroy(struct phy *phy);
|
||||
void devm_phy_destroy(struct device *dev, struct phy *phy);
|
||||
struct phy_provider *__of_phy_provider_register(struct device *dev,
|
||||
struct module *owner, struct phy * (*of_xlate)(struct device *dev,
|
||||
struct of_phandle_args *args));
|
||||
struct device_node *children, struct module *owner,
|
||||
struct phy * (*of_xlate)(struct device *dev,
|
||||
struct of_phandle_args *args));
|
||||
struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
|
||||
struct module *owner, struct phy * (*of_xlate)(struct device *dev,
|
||||
struct of_phandle_args *args));
|
||||
struct device_node *children, struct module *owner,
|
||||
struct phy * (*of_xlate)(struct device *dev,
|
||||
struct of_phandle_args *args));
|
||||
void of_phy_provider_unregister(struct phy_provider *phy_provider);
|
||||
void devm_of_phy_provider_unregister(struct device *dev,
|
||||
struct phy_provider *phy_provider);
|
||||
@ -312,15 +321,17 @@ static inline void devm_phy_destroy(struct device *dev, struct phy *phy)
|
||||
}
|
||||
|
||||
static inline struct phy_provider *__of_phy_provider_register(
|
||||
struct device *dev, struct module *owner, struct phy * (*of_xlate)(
|
||||
struct device *dev, struct of_phandle_args *args))
|
||||
struct device *dev, struct device_node *children, struct module *owner,
|
||||
struct phy * (*of_xlate)(struct device *dev,
|
||||
struct of_phandle_args *args))
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
}
|
||||
|
||||
static inline struct phy_provider *__devm_of_phy_provider_register(struct device
|
||||
*dev, struct module *owner, struct phy * (*of_xlate)(struct device *dev,
|
||||
struct of_phandle_args *args))
|
||||
*dev, struct device_node *children, struct module *owner,
|
||||
struct phy * (*of_xlate)(struct device *dev,
|
||||
struct of_phandle_args *args))
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
}
|
||||
|
30
include/linux/phy/tegra/xusb.h
Normal file
30
include/linux/phy/tegra/xusb.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#ifndef PHY_TEGRA_XUSB_H
|
||||
#define PHY_TEGRA_XUSB_H
|
||||
|
||||
struct tegra_xusb_padctl;
|
||||
struct device;
|
||||
|
||||
struct tegra_xusb_padctl *tegra_xusb_padctl_get(struct device *dev);
|
||||
void tegra_xusb_padctl_put(struct tegra_xusb_padctl *padctl);
|
||||
|
||||
int tegra_xusb_padctl_usb3_save_context(struct tegra_xusb_padctl *padctl,
|
||||
unsigned int port);
|
||||
int tegra_xusb_padctl_hsic_set_idle(struct tegra_xusb_padctl *padctl,
|
||||
unsigned int port, bool idle);
|
||||
int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl,
|
||||
unsigned int port, bool enable);
|
||||
|
||||
#endif /* PHY_TEGRA_XUSB_H */
|
@ -26,6 +26,7 @@
|
||||
|
||||
#define TEGRA_FUSE_SKU_CALIB_0 0xf0
|
||||
#define TEGRA30_FUSE_SATA_CALIB 0x124
|
||||
#define TEGRA_FUSE_USB_CALIB_EXT_0 0x250
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user