Commit 43419b09 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge branches 'tegra/pci' and 'tegra/usb' into next/late

This is a prerequisite for enabling the Tegra XUSB, all the
branches should be merged already at the time we get here.

* tegra/pci:
  PCI: tegra: Support per-lane PHYs
  dt-bindings: pci: tegra: Update for per-lane PHYs
  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

* tegra/usb:
  usb: xhci: tegra: Add Tegra210 support
  usb: xhci: Add NVIDIA Tegra XUSB controller driver
  dt-bindings: usb: xhci-tegra: Add Tegra210 XUSB controller support
  dt-bindings: usb: Add NVIDIA Tegra XUSB controller binding
  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
......@@ -60,11 +60,14 @@ Required properties:
- afi
- pcie_x
Required properties on Tegra124 and later:
Required properties on Tegra124 and later (deprecated):
- phys: Must contain an entry for each entry in phy-names.
- phy-names: Must include the following entries:
- pcie
These properties are deprecated in favour of per-lane PHYs define in each of
the root ports (see below).
Power supplies for Tegra20:
- avdd-pex-supply: Power supply for analog PCIe logic. Must supply 1.05 V.
- vdd-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
......@@ -122,11 +125,22 @@ Required properties:
- Root port 0 uses 4 lanes, root port 1 is unused.
- Both root ports use 2 lanes.
Example:
Required properties for Tegra124 and later:
- phys: Must contain an phandle to a PHY for each entry in phy-names.
- phy-names: Must include an entry for each active lane. Note that the number
of entries does not have to (though usually will) be equal to the specified
number of lanes in the nvidia,num-lanes property. Entries are of the form
"pcie-N": where N ranges from 0 to the value specified in nvidia,num-lanes.
Examples:
=========
Tegra20:
--------
SoC DTSI:
pcie-controller {
pcie-controller@80003000 {
compatible = "nvidia,tegra20-pcie";
device_type = "pci";
reg = <0x80003000 0x00000800 /* PADS registers */
......@@ -186,10 +200,9 @@ SoC DTSI:
};
};
Board DTS:
pcie-controller {
pcie-controller@80003000 {
status = "okay";
vdd-supply = <&pci_vdd_reg>;
......@@ -222,3 +235,204 @@ if a device on the PCI bus provides a non-probeable bus such as I2C or SPI,
device nodes need to be added in order to allow the bus' children to be
instantiated at the proper location in the operating system's device tree (as
illustrated by the optional nodes in the example above).
Tegra30:
--------
SoC DTSI:
pcie-controller@00003000 {
compatible = "nvidia,tegra30-pcie";
device_type = "pci";
reg = <0x00003000 0x00000800 /* PADS registers */
0x00003800 0x00000200 /* AFI registers */
0x10000000 0x10000000>; /* configuration space */
reg-names = "pads", "afi", "cs";
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH /* controller interrupt */
GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
interrupt-names = "intr", "msi";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
bus-range = <0x00 0xff>;
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x82000000 0 0x00000000 0x00000000 0 0x00001000 /* port 0 configuration space */
0x82000000 0 0x00001000 0x00001000 0 0x00001000 /* port 1 configuration space */
0x82000000 0 0x00004000 0x00004000 0 0x00001000 /* port 2 configuration space */
0x81000000 0 0 0x02000000 0 0x00010000 /* downstream I/O */
0x82000000 0 0x20000000 0x20000000 0 0x08000000 /* non-prefetchable memory */
0xc2000000 0 0x28000000 0x28000000 0 0x18000000>; /* prefetchable memory */
clocks = <&tegra_car TEGRA30_CLK_PCIE>,
<&tegra_car TEGRA30_CLK_AFI>,
<&tegra_car TEGRA30_CLK_PLL_E>,
<&tegra_car TEGRA30_CLK_CML0>;
clock-names = "pex", "afi", "pll_e", "cml";
resets = <&tegra_car 70>,
<&tegra_car 72>,
<&tegra_car 74>;
reset-names = "pex", "afi", "pcie_x";
status = "disabled";
pci@1,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x00000000 0 0x1000>;
reg = <0x000800 0 0 0 0>;
status = "disabled";
#address-cells = <3>;
#size-cells = <2>;
ranges;
nvidia,num-lanes = <2>;
};
pci@2,0 {
device_type = "pci";
assigned-addresses = <0x82001000 0 0x00001000 0 0x1000>;
reg = <0x001000 0 0 0 0>;
status = "disabled";
#address-cells = <3>;
#size-cells = <2>;
ranges;
nvidia,num-lanes = <2>;
};
pci@3,0 {
device_type = "pci";
assigned-addresses = <0x82001800 0 0x00004000 0 0x1000>;
reg = <0x001800 0 0 0 0>;
status = "disabled";
#address-cells = <3>;
#size-cells = <2>;
ranges;
nvidia,num-lanes = <2>;
};
};
Board DTS:
pcie-controller@00003000 {
status = "okay";
avdd-pexa-supply = <&ldo1_reg>;
vdd-pexa-supply = <&ldo1_reg>;
avdd-pexb-supply = <&ldo1_reg>;
vdd-pexb-supply = <&ldo1_reg>;
avdd-pex-pll-supply = <&ldo1_reg>;
avdd-plle-supply = <&ldo1_reg>;
vddio-pex-ctl-supply = <&sys_3v3_reg>;
hvdd-pex-supply = <&sys_3v3_pexs_reg>;
pci@1,0 {
status = "okay";
};
pci@3,0 {
status = "okay";
};
};
Tegra124:
---------
SoC DTSI:
pcie-controller@01003000 {
compatible = "nvidia,tegra124-pcie";
device_type = "pci";
reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */
0x0 0x01003800 0x0 0x00000800 /* AFI registers */
0x0 0x02000000 0x0 0x10000000>; /* configuration space */
reg-names = "pads", "afi", "cs";
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
<GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
interrupt-names = "intr", "msi";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
bus-range = <0x00 0xff>;
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x82000000 0 0x01000000 0x0 0x01000000 0 0x00001000 /* port 0 configuration space */
0x82000000 0 0x01001000 0x0 0x01001000 0 0x00001000 /* port 1 configuration space */
0x81000000 0 0x0 0x0 0x12000000 0 0x00010000 /* downstream I/O (64 KiB) */
0x82000000 0 0x13000000 0x0 0x13000000 0 0x0d000000 /* non-prefetchable memory (208 MiB) */
0xc2000000 0 0x20000000 0x0 0x20000000 0 0x20000000>; /* prefetchable memory (512 MiB) */
clocks = <&tegra_car TEGRA124_CLK_PCIE>,
<&tegra_car TEGRA124_CLK_AFI>,
<&tegra_car TEGRA124_CLK_PLL_E>,
<&tegra_car TEGRA124_CLK_CML0>;
clock-names = "pex", "afi", "pll_e", "cml";
resets = <&tegra_car 70>,
<&tegra_car 72>,
<&tegra_car 74>;
reset-names = "pex", "afi", "pcie_x";
status = "disabled";
pci@1,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>;
reg = <0x000800 0 0 0 0>;
status = "disabled";
#address-cells = <3>;
#size-cells = <2>;
ranges;
nvidia,num-lanes = <2>;
};
pci@2,0 {
device_type = "pci";
assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>;
reg = <0x001000 0 0 0 0>;
status = "disabled";
#address-cells = <3>;
#size-cells = <2>;
ranges;
nvidia,num-lanes = <1>;
};
};
Board DTS:
pcie-controller@01003000 {
status = "okay";
avddio-pex-supply = <&vdd_1v05_run>;
dvddio-pex-supply = <&vdd_1v05_run>;
avdd-pex-pll-supply = <&vdd_1v05_run>;
hvdd-pex-supply = <&vdd_3v3_lp0>;
hvdd-pex-pll-e-supply = <&vdd_3v3_lp0>;
vddio-pex-ctl-supply = <&vdd_3v3_lp0>;
avdd-pll-erefe-supply = <&avdd_1v05_run>;
/* Mini PCIe */
pci@1,0 {
phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
phy-names = "pcie-0";
status = "okay";
};
/* Gigabit Ethernet */
pci@2,0 {
phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>;
phy-names = "pcie-0";
status = "okay";
};
};
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.
......
NVIDIA Tegra xHCI controller
============================
The Tegra xHCI controller supports both USB2 and USB3 interfaces exposed by
the Tegra XUSB pad controller.
Required properties:
--------------------
- compatible: Must be:
- Tegra124: "nvidia,tegra124-xusb"
- Tegra132: "nvidia,tegra132-xusb", "nvidia,tegra124-xusb"
- Tegra210: "nvidia,tegra210-xusb"
- reg: Must contain the base and length of the xHCI host registers, XUSB FPCI
registers and XUSB IPFS registers.
- reg-names: Must contain the following entries:
- "hcd"
- "fpci"
- "ipfs"
- interrupts: Must contain the xHCI host interrupt and the mailbox interrupt.
- clocks: Must contain an entry for each entry in clock-names.
See ../clock/clock-bindings.txt for details.
- clock-names: Must include the following entries:
- xusb_host
- xusb_host_src
- xusb_falcon_src
- xusb_ss
- xusb_ss_src
- xusb_ss_div2
- xusb_hs_src
- xusb_fs_src
- pll_u_480m
- clk_m
- pll_e
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
- xusb_host
- xusb_ss
- xusb_src
Note that xusb_src is the shared reset for xusb_{ss,hs,fs,falcon,host}_src.
- nvidia,xusb-padctl: phandle to the XUSB pad controller that is used to
configure the USB pads used by the XHCI controller
For Tegra124 and Tegra132:
- avddio-pex-supply: PCIe/USB3 analog logic power supply. Must supply 1.05 V.
- dvddio-pex-supply: PCIe/USB3 digital logic power supply. Must supply 1.05 V.
- avdd-usb-supply: USB controller power supply. Must supply 3.3 V.
- avdd-pll-utmip-supply: UTMI PLL power supply. Must supply 1.8 V.
- avdd-pll-erefe-supply: PLLE reference PLL power supply. Must supply 1.05 V.
- avdd-usb-ss-pll-supply: PCIe/USB3 PLL power supply. Must supply 1.05 V.
- hvdd-usb-ss-supply: High-voltage PCIe/USB3 power supply. Must supply 3.3 V.
- hvdd-usb-ss-pll-e-supply: High-voltage PLLE power supply. Must supply 3.3 V.
For Tegra210:
- dvddio-pex-supply: PCIe/USB3 analog logic power supply. Must supply 1.05 V.
- hvddio-pex-supply: High-voltage PCIe/USB3 power supply. Must supply 1.8 V.
- avdd-usb-supply: USB controller power supply. Must supply 3.3 V.
- avdd-pll-utmip-supply: UTMI PLL power supply. Must supply 1.8 V.
- avdd-pll-uerefe-supply: PLLE reference PLL power supply. Must supply 1.05 V.
- dvdd-pex-pll-supply: PCIe/USB3 PLL power supply. Must supply 1.05 V.
- hvdd-pex-pll-e-supply: High-voltage PLLE power supply. Must supply 1.8 V.
Optional properties:
--------------------
- phys: Must contain an entry for each entry in phy-names.
See ../phy/phy-bindings.txt for details.
- phy-names: Should include an entry for each PHY used by the controller. The
following PHYs are available:
- Tegra124: usb2-0, usb2-1, usb2-2, hsic-0, hsic-1, usb3-0, usb3-1
- Tegra132: usb2-0, usb2-1, usb2-2, hsic-0, hsic-1, usb3-0, usb3-1
- Tegra210: usb2-0, usb2-1, usb2-2, usb2-3, hsic-0, usb3-0, usb3-1, usb3-2,
usb3-3
Example:
--------
usb@0,70090000 {
compatible = "nvidia,tegra124-xusb";
reg = <0x0 0x70090000 0x0 0x8000>,
<0x0 0x70098000 0x0 0x1000>,
<0x0 0x70099000 0x0 0x1000>;
reg-names = "hcd", "fpci", "ipfs";
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA124_CLK_XUSB_HOST>,
<&tegra_car TEGRA124_CLK_XUSB_HOST_SRC>,
<&tegra_car TEGRA124_CLK_XUSB_FALCON_SRC>,
<&tegra_car TEGRA124_CLK_XUSB_SS>,
<&tegra_car TEGRA124_CLK_XUSB_SS_DIV2>,
<&tegra_car TEGRA124_CLK_XUSB_SS_SRC>,
<&tegra_car TEGRA124_CLK_XUSB_HS_SRC>,
<&tegra_car TEGRA124_CLK_XUSB_FS_SRC>,
<&tegra_car TEGRA124_CLK_PLL_U_480M>,
<&tegra_car TEGRA124_CLK_CLK_M>,
<&tegra_car TEGRA124_CLK_PLL_E>;
clock-names = "xusb_host", "xusb_host_src", "xusb_falcon_src",
"xusb_ss", "xusb_ss_div2", "xusb_ss_src",
"xusb_hs_src", "xusb_fs_src", "pll_u_480m",
"clk_m", "pll_e";
resets = <&tegra_car 89>, <&tegra_car 156>, <&tegra_car 143>;
reset-names = "xusb_host", "xusb_ss", "xusb_src";
nvidia,xusb-padctl = <&padctl>;
phys = <&{/padctl@0,7009f000/pads/usb2/usb2-1}>, /* mini-PCIe USB */
<&{/padctl@0,7009f000/pads/usb2/usb2-2}>, /* USB A */
<&{/padctl@0,7009f000/pads/pcie/pcie-0}>; /* USB A */
phy-names = "utmi-1", "utmi-2", "usb3-0";
avddio-pex-supply = <&vdd_1v05_run>;
dvddio-pex-supply = <&vdd_1v05_run>;
avdd-usb-supply = <&vdd_3v3_lp0>;
avdd-pll-utmip-supply = <&vddio_1v8>;
avdd-pll-erefe-supply = <&avdd_1v05_run>;
avdd-usb-ss-pll-supply = <&vdd_1v05_run>;
hvdd-usb-ss-supply = <&vdd_3v3_lp0>;
hvdd-usb-ss-pll-e-supply = <&vdd_3v3_lp0>;
};
......@@ -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)
......
......@@ -295,6 +295,7 @@ struct tegra_pcie {
struct reset_control *afi_rst;
struct reset_control *pcie_xrst;
bool legacy_phy;
struct phy *phy;
struct tegra_msi msi;
......@@ -311,11 +312,14 @@ struct tegra_pcie {
struct tegra_pcie_port {
struct tegra_pcie *pcie;
struct device_node *np;
struct list_head list;
struct resource regs;
void __iomem *base;
unsigned int index;
unsigned int lanes;
struct phy **phys;
};
struct tegra_pcie_bus {
......@@ -860,6 +864,128 @@ static int tegra_pcie_phy_enable(struct tegra_pcie *pcie)
return 0;
}
static int tegra_pcie_phy_disable(struct tegra_pcie *pcie)
{
const struct tegra_pcie_soc_data *soc = pcie->soc_data;
u32 value;
/* disable TX/RX data */
value = pads_readl(pcie, PADS_CTL);
value &= ~(PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L);
pads_writel(pcie, value, PADS_CTL);
/* override IDDQ */
value = pads_readl(pcie, PADS_CTL);
value |= PADS_CTL_IDDQ_1L;
pads_writel(pcie, PADS_CTL, value);
/* reset PLL */
value = pads_readl(pcie, soc->pads_pll_ctl);
value &= ~PADS_PLL_CTL_RST_B4SM;
pads_writel(pcie, value, soc->pads_pll_ctl);
usleep_range(20, 100);
return 0;
}
static int tegra_pcie_port_phy_power_on(struct tegra_pcie_port *port)
{
struct device *dev = port->pcie->dev;
unsigned int i;
int err;
for (i = 0; i < port->lanes; i++) {
err = phy_power_on(port->phys[i]);
if (err < 0) {
dev_err(dev, "failed to power on PHY#%u: %d\n", i,
err);
return err;
}
}
return 0;
}
static int tegra_pcie_port_phy_power_off(struct tegra_pcie_port *port)
{
struct device *dev = port->pcie->dev;
unsigned int i;
int err;
for (i = 0; i < port->lanes; i++) {
err = phy_power_off(port->phys[i]);
if (err < 0) {
dev_err(dev, "failed to power off PHY#%u: %d\n", i,
err);
return err;
}
}
return 0;
}
static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
{
struct tegra_pcie_port *port;
int err;
if (pcie->legacy_phy) {
if (pcie->phy)
err = phy_power_on(pcie->phy);
else
err = tegra_pcie_phy_enable(pcie);
if (err < 0)
dev_err(pcie->dev, "failed to power on PHY: %d\n", err);
return err;
}
list_for_each_entry(port, &pcie->ports, list) {
err = tegra_pcie_port_phy_power_on(port);
if (err < 0) {
dev_err(pcie->dev,
"failed to power on PCIe port %u PHY: %d\n",
port->index, err);
return err;
}
}
return 0;
}
static int tegra_pcie_phy_power_off(struct tegra_pcie *pcie)
{
struct tegra_pcie_port *port;
int err;
if (pcie->legacy_phy) {
if (pcie->phy)
err = phy_power_off(pcie->phy);
else
err = tegra_pcie_phy_disable(pcie);
if (err < 0)
dev_err(pcie->dev, "failed to power off PHY: %d\n",
err);
return err;
}
list_for_each_entry(port, &pcie->ports, list) {
err = tegra_pcie_port_phy_power_off(port);
if (err < 0) {
dev_err(pcie->dev,
"failed to power off PCIe port %u PHY: %d\n",
port->index, err);
return err;
}
}
return 0;
}
static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
{
const struct tegra_pcie_soc_data *soc = pcie->soc_data;
......@@ -899,13 +1025,9 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
afi_writel(pcie, value, AFI_FUSE);
}
if (!pcie->phy)
err = tegra_pcie_phy_enable(pcie);
else
err = phy_power_on(pcie->phy);
err = tegra_pcie_phy_power_on(pcie);
if (err < 0) {
dev_err(pcie->dev, "failed to power on PHY: %d\n", err);
dev_err(pcie->dev, "failed to power on PHY(s): %d\n", err);
return err;
}
......@@ -942,9 +1064,9 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie)
/* TODO: disable and unprepare clocks? */
err = phy_power_off(pcie->phy);
err = tegra_pcie_phy_power_off(pcie);
if (err < 0)
dev_warn(pcie->dev, "failed to power off PHY: %d\n", err);
dev_err(pcie->dev, "failed to power off PHY(s): %d\n", err);
reset_control_assert(pcie->pcie_xrst);
reset_control_assert(pcie->afi_rst);
......@@ -1049,6 +1171,100 @@ static int tegra_pcie_resets_get(struct tegra_pcie *pcie)
return 0;
}
static int tegra_pcie_phys_get_legacy(struct tegra_pcie *pcie)
{
int err;
pcie->phy = devm_phy_optional_get(pcie->dev, "pcie");
if (IS_ERR(pcie->phy)) {
err = PTR_ERR(pcie->phy);
dev_err(pcie->dev, "failed to get PHY: %d\n", err);
return err;
}
err = phy_init(pcie->phy);
if (err < 0) {
dev_err(pcie->dev, "failed to initialize PHY: %d\n", err);
return err;
}
pcie->legacy_phy = true;
return 0;
}
static struct phy *devm_of_phy_optional_get_index(struct device *dev,
struct device_node *np,
const char *consumer,
unsigned int index)
{
struct phy *phy;
char *name;
name = kasprintf(GFP_KERNEL, "%s-%u", consumer, index);
if (!name)
return ERR_PTR(-ENOMEM);
phy = devm_of_phy_get(dev, np, name);
kfree(name);
if (IS_ERR(phy) && PTR_ERR(phy) == -ENODEV)
phy = NULL;
return phy;
}
static int tegra_pcie_port_get_phys(struct tegra_pcie_port *port)
{
struct device *dev = port->pcie->dev;
struct phy *phy;
unsigned int i;
int err;
port->phys = devm_kcalloc(dev, sizeof(phy), port->lanes, GFP_KERNEL);
if (!port->phys)
return -ENOMEM;
for (i = 0; i < port->lanes; i++) {
phy = devm_of_phy_optional_get_index(dev, port->np, "pcie", i);
if (IS_ERR(phy)) {
dev_err(dev, "failed to get PHY#%u: %ld\n", i,
PTR_ERR(phy));
return PTR_ERR(phy);
}
err = phy_init(phy);
if (err < 0) {
dev_err(dev, "failed to initialize PHY#%u: %d\n", i,
err);
return err;
}
port->phys[i] = phy;
}
return 0;
}
static int tegra_pcie_phys_get(struct tegra_pcie *pcie)
{
const struct tegra_pcie_soc_data *soc = pcie->soc_data;
struct device_node *np = pcie->dev->of_node;
struct tegra_pcie_port *port;
int err;
if (!soc->has_gen2 || of_find_property(np, "phys", NULL) != NULL)
return tegra_pcie_phys_get_legacy(pcie);
list_for_each_entry(port, &pcie->ports, list) {
err = tegra_pcie_port_get_phys(port);
if (err < 0)
return err;
}
return 0;
}
static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
{
struct platform_device *pdev = to_platform_device(pcie->dev);
......@@ -1067,16 +1283,9 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
return err;
}
pcie->phy = devm_phy_optional_get(pcie->dev, "pcie");
if (IS_ERR(pcie->phy)) {
err = PTR_ERR(pcie->phy);
dev_err(&pdev->dev, "failed to get PHY: %d\n", err);
return err;
}
err = phy_init(pcie->phy);
err = tegra_pcie_phys_get(pcie);
if (err < 0) {
dev_err(&pdev->dev, "failed to initialize PHY: %d\n", err);
dev_err(&pdev->dev, "failed to get PHYs: %d\n", err);
return err;
}
......@@ -1752,6 +1961,7 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
rp->index = index;
rp->lanes = value;
rp->pcie = pcie;
rp->np = port;
rp->base = devm_ioremap_resource(pcie->dev, &rp->regs);
if (IS_ERR(rp->base))
......
......@@ -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);
}
......
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.
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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* 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 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev)
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);
......@@ -69,6 +69,15 @@ config USB_XHCI_RCAR
Say 'Y' to enable the support for the xHCI host controller
found in Renesas R-Car ARM SoCs.
config USB_XHCI_TEGRA
tristate "xHCI support for NVIDIA Tegra SoCs"
depends on PHY_TEGRA_XUSB
depends on RESET_CONTROLLER
select FW_LOADER
---help---
Say 'Y' to enable the support for the xHCI host controller
found in NVIDIA Tegra124 and later SoCs.
endif # USB_XHCI_HCD
config USB_EHCI_HCD
......
......@@ -68,6 +68,7 @@ obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o
obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o
obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o
obj-$(CONFIG_USB_XHCI_TEGRA) += xhci-tegra.o
obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o
obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o
obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
......
This diff is collapsed.
......@@ -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);
}
......
/*
* 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 */
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