You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
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:
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
|
||||
+14
-2
@@ -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/
|
||||
|
||||
+44
-6
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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_ */
|
||||
|
||||
+21
-10
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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__
|
||||
|
||||
|
||||
Reference in New Issue
Block a user