summaryrefslogtreecommitdiff
path: root/drivers/usb/host/xhci-tegra.c
diff options
context:
space:
mode:
authorKrishna Yarlagadda <kyarlagadda@nvidia.com>2013-10-21 18:05:03 +0530
committerKrishna Yarlagadda <kyarlagadda@nvidia.com>2013-11-06 22:50:23 -0800
commit167b94dd8bc07af7cd8208f5f7f11a57ddfa21b1 (patch)
treeea3dfeaa2a464337fabb8c106c084f6319d35e28 /drivers/usb/host/xhci-tegra.c
parent2fd5a703dbea9a9ef071cdc1af8e9c45838f0052 (diff)
usb: xhci: tegra: add dt support
Add dt support for xhci driver Bug 1357627 Change-Id: Ibdaebd8bb68e8000ab6a9e0fbe8de7fe62dc52e0 Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com> Reviewed-on: http://git-master/r/301796 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
Diffstat (limited to 'drivers/usb/host/xhci-tegra.c')
-rw-r--r--drivers/usb/host/xhci-tegra.c262
1 files changed, 208 insertions, 54 deletions
diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index 617c55ccdb7d..1efa653c51bf 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -37,15 +37,19 @@
#include <linux/tegra-powergate.h>
#include <linux/firmware.h>
#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+
#include <mach/tegra_usb_pad_ctrl.h>
#include <mach/tegra_usb_pmc.h>
#include <mach/pm_domains.h>
#include <mach/mc.h>
#include <mach/xusb.h>
-#include "../../../arch/arm/mach-tegra/iomap.h" /* HACK -- remove */
#include "xhci-tegra.h"
#include "xhci.h"
+#include "../../../arch/arm/mach-tegra/fuse.h"
/* macros */
#define FW_IOCTL_LOG_DEQUEUE_LOW (4)
@@ -353,7 +357,10 @@ struct tegra_xhci_hcd {
struct tegra_xusb_platform_data *pdata;
struct tegra_xusb_board_data *bdata;
+ struct tegra_xusb_chip_calib *cdata;
struct tegra_xusb_padctl_regs *padregs;
+ const struct tegra_xusb_soc_config *soc_config;
+ u64 tegra_xusb_dmamask;
/* mailbox variables */
struct mutex mbox_lock;
@@ -572,9 +579,9 @@ static void pmc_init(struct tegra_xhci_hcd *tegra)
if (BIT(XUSB_UTMI_INDEX + pad) & tegra->bdata->portmap) {
dev_dbg(dev, "%s utmi pad %d\n", __func__, pad);
pmc = &pmc_data[pad];
- if (tegra->pdata->pmc_portmap)
+ if (tegra->soc_config->pmc_portmap)
pmc->instance = PMC_PORTMAP_MASK(
- tegra->pdata->pmc_portmap,
+ tegra->soc_config->pmc_portmap,
pad);
else
pmc->instance = pad;
@@ -817,7 +824,7 @@ static inline void fw_log_update_deq_pointer(
reg |= ((physical_addr >> 16) & 0xffff); /* higher 16-bits */
iowrite32(reg, tegra->fpci_base + XUSB_CFG_ARU_FW_SCRATCH);
- dev_dbg(dev, "new 0x%p physical addr 0x%x\n", deq, physical_addr);
+ dev_dbg(dev, "new 0x%p physical addr 0x%x\n", deq, (u32)physical_addr);
}
static inline bool circ_buffer_full(struct circ_buf *circ)
@@ -1062,8 +1069,10 @@ static int fw_log_init(struct tegra_xhci_hcd *tegra)
return -ENOMEM;
}
- dev_info(&pdev->dev, "%d bytes log buffer physical 0x%u virtual 0x%p\n",
- FW_LOG_RING_SIZE, tegra->log.phys_addr, tegra->log.virt_addr);
+ dev_info(&pdev->dev,
+ "%d bytes log buffer physical 0x%u virtual 0x%p\n",
+ FW_LOG_RING_SIZE, (u32)tegra->log.phys_addr,
+ tegra->log.virt_addr);
memset(tegra->log.virt_addr, 0, FW_LOG_RING_SIZE);
tegra->log.dequeue = tegra->log.virt_addr;
@@ -1155,7 +1164,7 @@ static void fw_log_deinit(struct tegra_xhci_hcd *tegra)
static int hsic_power_rail_enable(struct tegra_xhci_hcd *tegra)
{
struct device *dev = &tegra->pdev->dev;
- struct tegra_xusb_regulator_name *supply = &tegra->pdata->bdata->supply;
+ struct tegra_xusb_regulator_name *supply = &tegra->bdata->supply;
int ret;
if (tegra->vddio_hsic_reg)
@@ -1641,7 +1650,7 @@ static int tegra_xusb_partitions_clk_init(struct tegra_xhci_hcd *tegra)
return PTR_ERR(tegra->emc_clk);
}
- if (tegra->pdata->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2) {
+ if (tegra->soc_config->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2) {
tegra->pll_re_vco_clk = devm_clk_get(&pdev->dev, "pll_re_vco");
if (IS_ERR(tegra->pll_re_vco_clk)) {
dev_err(&pdev->dev, "Failed to get refPLLE clock\n");
@@ -1690,7 +1699,7 @@ static int tegra_xusb_partitions_clk_init(struct tegra_xhci_hcd *tegra)
goto get_ss_clk_failed;
}
- if (tegra->pdata->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2) {
+ if (tegra->soc_config->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2) {
err = clk_enable(tegra->pll_re_vco_clk);
if (err) {
dev_err(&pdev->dev, "Failed to enable refPLLE clk\n");
@@ -1715,7 +1724,7 @@ clk_get_clk_m_failed:
tegra->pll_u_480M = NULL;
get_pll_u_480M_failed:
- if (tegra->pdata->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2)
+ if (tegra->soc_config->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2)
tegra->pll_re_vco_clk = NULL;
get_pll_re_vco_clk_failed:
@@ -1728,14 +1737,14 @@ static void tegra_xusb_partitions_clk_deinit(struct tegra_xhci_hcd *tegra)
{
clk_disable(tegra->ss_clk);
clk_disable(tegra->host_clk);
- if (tegra->pdata->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2)
+ if (tegra->soc_config->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2)
clk_disable(tegra->pll_re_vco_clk);
tegra->ss_clk = NULL;
tegra->host_clk = NULL;
tegra->ss_src_clk = NULL;
tegra->clk_m = NULL;
tegra->pll_u_480M = NULL;
- if (tegra->pdata->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2)
+ if (tegra->soc_config->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2)
tegra->pll_re_vco_clk = NULL;
}
@@ -1807,7 +1816,7 @@ tegra_xusb_request_clk_rate(struct tegra_xhci_hcd *tegra,
int fw_req_rate = rate, cur_rate;
/* Do not handle clock change as needed for HS disconnect issue */
- if (tegra->pdata->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2) {
+ if (tegra->soc_config->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2) {
*sw_resp = CMD_DATA(fw_req_rate) | CMD_TYPE(MBOX_CMD_ACK);
return ret;
}
@@ -2095,13 +2104,13 @@ static void tegra_xhci_program_utmip_pad(struct tegra_xhci_hcd *tegra,
USB2_OTG_FS_SLEW | USB2_OTG_LS_RSLEW |
USB2_OTG_PD | USB2_OTG_PD2 | USB2_OTG_PD_ZI);
- reg |= tegra->pdata->hs_slew;
- reg |= (port == 2) ? tegra->pdata->ls_rslew_pad2 :
- port ? tegra->pdata->ls_rslew_pad1 :
- tegra->pdata->ls_rslew_pad0;
- reg |= (port == 2) ? tegra->pdata->hs_curr_level_pad2 :
- port ? tegra->pdata->hs_curr_level_pad1 :
- tegra->pdata->hs_curr_level_pad0;
+ reg |= tegra->soc_config->hs_slew;
+ reg |= (port == 2) ? tegra->soc_config->ls_rslew_pad2 :
+ port ? tegra->soc_config->ls_rslew_pad1 :
+ tegra->soc_config->ls_rslew_pad0;
+ reg |= (port == 2) ? tegra->cdata->hs_curr_level_pad2 :
+ port ? tegra->cdata->hs_curr_level_pad1 :
+ tegra->cdata->hs_curr_level_pad0;
writel(reg, tegra->padctl_base + ctl0_offset);
reg = readl(tegra->padctl_base + ctl1_offset);
@@ -2109,8 +2118,8 @@ static void tegra_xhci_program_utmip_pad(struct tegra_xhci_hcd *tegra,
| USB2_OTG_PD_CHRP_FORCE_POWERUP
| USB2_OTG_PD_DISC_FORCE_POWERUP
| USB2_OTG_PD_DR);
- reg |= (tegra->pdata->hs_iref_cap << 9) |
- (tegra->pdata->hs_term_range_adj << 3);
+ reg |= (tegra->cdata->hs_iref_cap << 9) |
+ (tegra->cdata->hs_term_range_adj << 3);
writel(reg, tegra->padctl_base + ctl1_offset);
/*Release OTG port if not in host mode*/
@@ -2143,12 +2152,12 @@ static void tegra_xhci_program_ss_pad(struct tegra_xhci_hcd *tegra,
reg = readl(tegra->padctl_base + ctl2_offset);
reg &= ~(IOPHY_USB3_RXWANDER | IOPHY_USB3_RXEQ |
IOPHY_USB3_CDRCNTL);
- reg |= tegra->pdata->rx_wander | tegra->pdata->rx_eq |
- tegra->pdata->cdr_cntl;
+ reg |= tegra->soc_config->rx_wander | tegra->soc_config->rx_eq |
+ tegra->soc_config->cdr_cntl;
writel(reg, tegra->padctl_base + ctl2_offset);
reg = readl(tegra->padctl_base + ctl4_offset);
- reg = tegra->pdata->dfe_cntl;
+ reg = tegra->soc_config->dfe_cntl;
writel(reg, tegra->padctl_base + ctl4_offset);
reg = readl(tegra->padctl_base + ctl5_offset);
@@ -2157,7 +2166,7 @@ static void tegra_xhci_program_ss_pad(struct tegra_xhci_hcd *tegra,
reg = readl(tegra->padctl_base + MISC_PAD_CTL_2_0(port));
reg &= ~SPARE_IN(~0);
- reg |= SPARE_IN(tegra->pdata->spare_in);
+ reg |= SPARE_IN(tegra->soc_config->spare_in);
writel(reg, tegra->padctl_base + MISC_PAD_CTL_2_0(port));
if (xusb_use_sata_lane(tegra)) {
@@ -2167,7 +2176,7 @@ static void tegra_xhci_program_ss_pad(struct tegra_xhci_hcd *tegra,
reg = readl(tegra->padctl_base + MISC_PAD_S0_CTL_2_0);
reg &= ~SPARE_IN(~0);
- reg |= SPARE_IN(tegra->pdata->spare_in);
+ reg |= SPARE_IN(tegra->soc_config->spare_in);
writel(reg, tegra->padctl_base + MISC_PAD_S0_CTL_2_0);
}
@@ -2194,7 +2203,7 @@ tegra_xhci_padctl_portmap_and_caps(struct tegra_xhci_hcd *tegra)
reg = readl(tegra->padctl_base + padregs->usb2_bias_pad_ctl0_0);
reg &= ~(USB2_BIAS_HS_SQUELCH_LEVEL | USB2_BIAS_HS_DISCON_LEVEL);
- reg |= tegra->pdata->hs_squelch_level | tegra->pdata->hs_disc_lvl;
+ reg |= tegra->cdata->hs_squelch_level | tegra->soc_config->hs_disc_lvl;
writel(reg, tegra->padctl_base + padregs->usb2_bias_pad_ctl0_0);
reg = readl(tegra->padctl_base + padregs->snps_oc_map_0);
@@ -2685,7 +2694,7 @@ static int tegra_xhci_host_elpg_entry(struct tegra_xhci_hcd *tegra)
tegra->host_pwr_gated = true;
clk_disable(tegra->host_clk);
- if (tegra->pdata->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2)
+ if (tegra->soc_config->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2)
clk_disable(tegra->pll_re_vco_clk);
clk_disable(tegra->emc_clk);
/* set port ownership to SNPS */
@@ -2875,7 +2884,6 @@ static void tegra_xhci_war_for_tctrl_rctrl(struct tegra_xhci_hcd *tegra)
{
struct tegra_xusb_padctl_regs *padregs = tegra->padregs;
u32 reg, utmip_rctrl_val, utmip_tctrl_val, pad_mux, portmux, portowner;
- int port;
portmux = USB2_OTG_PAD_PORT_MASK(0) | USB2_OTG_PAD_PORT_MASK(1);
portowner = USB2_OTG_PAD_PORT_OWNER_XUSB(0) |
@@ -2960,7 +2968,7 @@ tegra_xhci_host_partition_elpg_exit(struct tegra_xhci_hcd *tegra)
return 0;
clk_enable(tegra->emc_clk);
- if (tegra->pdata->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2)
+ if (tegra->soc_config->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2)
clk_enable(tegra->pll_re_vco_clk);
if (tegra->lp0_exit) {
@@ -3359,20 +3367,20 @@ static int xhci_plat_setup(struct usb_hcd *hcd)
}
static int tegra_xhci_request_mem_region(struct platform_device *pdev,
- const char *name, void __iomem **region)
+ int num, void __iomem **region)
{
struct resource *res;
void __iomem *mem;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, num);
if (!res) {
- dev_err(&pdev->dev, "memory resource %s doesn't exist\n", name);
+ dev_err(&pdev->dev, "memory resource %d doesn't exist\n", num);
return -ENODEV;
}
mem = devm_request_and_ioremap(&pdev->dev, res);
if (!mem) {
- dev_err(&pdev->dev, "failed to ioremap for %s\n", name);
+ dev_err(&pdev->dev, "failed to ioremap for %d\n", num);
return -EFAULT;
}
*region = mem;
@@ -3381,16 +3389,16 @@ static int tegra_xhci_request_mem_region(struct platform_device *pdev,
}
static int tegra_xhci_request_irq(struct platform_device *pdev,
- const char *rscname, irq_handler_t handler, unsigned long irqflags,
+ int num, irq_handler_t handler, unsigned long irqflags,
const char *devname, int *irq_no)
{
int ret;
struct tegra_xhci_hcd *tegra = platform_get_drvdata(pdev);
struct resource *res;
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, rscname);
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, num);
if (!res) {
- dev_err(&pdev->dev, "irq resource %s doesn't exist\n", rscname);
+ dev_err(&pdev->dev, "irq resource %d doesn't exist\n", num);
return -ENODEV;
}
@@ -3399,7 +3407,7 @@ static int tegra_xhci_request_irq(struct platform_device *pdev,
if (ret != 0) {
dev_err(&pdev->dev,
"failed to request_irq for %s (irq %d), error = %d\n",
- devname, res->start, ret);
+ devname, (int)res->start, ret);
return ret;
}
*irq_no = res->start;
@@ -3739,7 +3747,7 @@ static int init_bootloader_firmware(struct tegra_xhci_hcd *tegra)
if (!fw_mmio_base) {
dev_err(&pdev->dev, "error mapping fw memory 0x%x\n",
- fw_mem_phy_addr);
+ (u32)fw_mem_phy_addr);
return -ENOMEM;
}
@@ -3750,7 +3758,7 @@ static int init_bootloader_firmware(struct tegra_xhci_hcd *tegra)
fw_mem_phy_addr, fw_size);
if (!fw_mmio_base) {
dev_err(&pdev->dev, "error mapping fw memory 0x%x\n",
- fw_mem_phy_addr);
+ (u32)fw_mem_phy_addr);
return -ENOMEM;
}
@@ -3935,7 +3943,7 @@ eanble_ss_clk_failed:
clk_disable(tegra->host_clk);
enable_host_clk_failed:
- if (tegra->pdata->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2)
+ if (tegra->soc_config->quirks & TEGRA_XUSB_USE_HS_SRC_CLOCK2)
clk_disable(tegra->pll_re_vco_clk);
return err;
}
@@ -4140,6 +4148,105 @@ static int tegra_xhci_otg_notify(struct notifier_block *nb,
return NOTIFY_OK;
}
+static void tegra_xusb_read_board_data(struct tegra_xhci_hcd *tegra)
+{
+ struct tegra_xusb_board_data *bdata = tegra->bdata;
+ struct device_node *node = tegra->pdev->dev.of_node;
+ int ret;
+
+ bdata->uses_external_pmic = of_property_read_bool(node,
+ "nvidia,uses_external_pmic");
+ bdata->gpio_controls_muxed_ss_lanes = of_property_read_bool(node,
+ "nvidia,gpio_controls_muxed_ss_lanes");
+ ret = of_property_read_u32(node, "nvidia,gpio_ss1_sata",
+ &bdata->gpio_ss1_sata);
+ ret = of_property_read_u32(node, "nvidia,portmap",
+ &bdata->portmap);
+ ret = of_property_read_u8(node, "nvidia,ss_portmap",
+ &bdata->ss_portmap);
+ ret = of_property_read_u8(node, "nvidia,lane_owner",
+ &bdata->lane_owner);
+ ret = of_property_read_u8(node, "nvidia,ulpicap",
+ &bdata->ulpicap);
+ ret = of_property_read_string_index(node, "nvidia,supply_utmi_vbuses",
+ 0, &bdata->supply.utmi_vbuses[0]);
+ ret = of_property_read_string_index(node, "nvidia,supply_utmi_vbuses",
+ 1, &bdata->supply.utmi_vbuses[1]);
+ ret = of_property_read_string_index(node, "nvidia,supply_utmi_vbuses",
+ 2, &bdata->supply.utmi_vbuses[2]);
+ ret = of_property_read_string(node, "nvidia,supply_s3p3v",
+ &bdata->supply.s3p3v);
+ ret = of_property_read_string(node, "nvidia,supply_s1p8v",
+ &bdata->supply.s1p8v);
+ ret = of_property_read_string(node, "nvidia,supply_vddio_hsic",
+ &bdata->supply.vddio_hsic);
+ ret = of_property_read_string(node, "nvidia,supply_s1p05v",
+ &bdata->supply.s1p05v);
+ /* TODO: add read for tegra_xusb_hsic_config
+ * Add error conditions check
+ */
+}
+
+static void tegra_xusb_read_calib_data(struct tegra_xhci_hcd *tegra)
+{
+ u32 usb_calib0 = tegra_fuse_readl(FUSE_SKU_USB_CALIB_0);
+ struct tegra_xusb_chip_calib *cdata = tegra->cdata;
+
+ pr_info("tegra_xusb_read_usb_calib: usb_calib0 = 0x%08x\n", usb_calib0);
+ /*
+ * read from usb_calib0 and pass to driver
+ * set HS_CURR_LEVEL (PAD0) = usb_calib0[5:0]
+ * set TERM_RANGE_ADJ = usb_calib0[10:7]
+ * set HS_SQUELCH_LEVEL = usb_calib0[12:11]
+ * set HS_IREF_CAP = usb_calib0[14:13]
+ * set HS_CURR_LEVEL (PAD1) = usb_calib0[20:15]
+ */
+
+ cdata->hs_curr_level_pad0 = (usb_calib0 >> 0) & 0x3f;
+ cdata->hs_term_range_adj = (usb_calib0 >> 7) & 0xf;
+ cdata->hs_squelch_level = (usb_calib0 >> 11) & 0x3;
+ cdata->hs_iref_cap = (usb_calib0 >> 13) & 0x3;
+ cdata->hs_curr_level_pad1 = (usb_calib0 >> 15) & 0x3f;
+ cdata->hs_curr_level_pad2 = (usb_calib0 >> 15) & 0x3f;
+}
+
+static const struct tegra_xusb_soc_config tegra114_soc_config = {
+ .pmc_portmap = (TEGRA_XUSB_UTMIP_PMC_PORT0 << 0) |
+ (TEGRA_XUSB_UTMIP_PMC_PORT2 << 4),
+ .quirks = TEGRA_XUSB_USE_HS_SRC_CLOCK2,
+ .rx_wander = (0x3 << 4),
+ .rx_eq = (0x3928 << 8),
+ .cdr_cntl = (0x26 << 24),
+ .dfe_cntl = 0x002008EE,
+ .hs_slew = (0xE << 6),
+ .ls_rslew_pad0 = (0x3 << 14),
+ .ls_rslew_pad1 = (0x0 << 14),
+ .hs_disc_lvl = (0x5 << 2),
+ .spare_in = 0x0,
+};
+
+static const struct tegra_xusb_soc_config tegra124_soc_config = {
+ .pmc_portmap = (TEGRA_XUSB_UTMIP_PMC_PORT0 << 0) |
+ (TEGRA_XUSB_UTMIP_PMC_PORT1 << 4) |
+ (TEGRA_XUSB_UTMIP_PMC_PORT2 << 8),
+ .rx_wander = (0xF << 4),
+ .rx_eq = (0xF070 << 8),
+ .cdr_cntl = (0x26 << 24),
+ .dfe_cntl = 0x002008EE,
+ .hs_slew = (0xE << 6),
+ .ls_rslew_pad0 = (0x3 << 14),
+ .ls_rslew_pad1 = (0x0 << 14),
+ .ls_rslew_pad2 = (0x0 << 14),
+ .hs_disc_lvl = (0x5 << 2),
+ .spare_in = 0x1,
+};
+
+static struct of_device_id tegra_xhci_of_match[] = {
+ { .compatible = "nvidia,tegra114-xhci", .data = &tegra114_soc_config },
+ { .compatible = "nvidia,tegra124-xhci", .data = &tegra124_soc_config },
+ { },
+};
+
/* TODO: we have to refine error handling in tegra_xhci_probe() */
static int tegra_xhci_probe(struct platform_device *pdev)
{
@@ -4148,6 +4255,9 @@ static int tegra_xhci_probe(struct platform_device *pdev)
unsigned pad;
u32 val;
int ret;
+ int irq;
+ const struct tegra_xusb_soc_config *soc_config;
+ const struct of_device_id *match;
BUILD_BUG_ON(sizeof(struct cfgtbl) != 256);
@@ -4164,9 +4274,44 @@ static int tegra_xhci_probe(struct platform_device *pdev)
mutex_init(&tegra->mbox_lock);
tegra->init_done = false;
+
+ tegra->bdata = devm_kzalloc(&pdev->dev, sizeof(
+ struct tegra_xusb_board_data),
+ GFP_KERNEL);
+ if (!tegra->bdata) {
+ dev_err(&pdev->dev, "memory alloc failed\n");
+ return -ENOMEM;
+ }
+ tegra->cdata = devm_kzalloc(&pdev->dev, sizeof(
+ struct tegra_xusb_chip_calib),
+ GFP_KERNEL);
+ if (!tegra->cdata) {
+ dev_err(&pdev->dev, "memory alloc failed\n");
+ return -ENOMEM;
+ }
+ match = of_match_device(tegra_xhci_of_match, &pdev->dev);
+ if (!match) {
+ dev_err(&pdev->dev, "Error: No device match found\n");
+ return -ENODEV;
+ }
+ soc_config = match->data;
+ /* Right now device-tree probed devices don't get dma_mask set.
+ * Since shared usb code relies on it, set it here for now.
+ * Once we have dma capability bindings this can go away.
+ */
+ tegra->tegra_xusb_dmamask = DMA_BIT_MASK(64);
+ if (!pdev->dev.dma_mask)
+ pdev->dev.dma_mask = &tegra->tegra_xusb_dmamask;
+
tegra->pdev = pdev;
+ tegra_xusb_read_calib_data(tegra);
+ tegra_xusb_read_board_data(tegra);
tegra->pdata = dev_get_platdata(&pdev->dev);
- tegra->bdata = tegra->pdata->bdata;
+ tegra->bdata->portmap = tegra->pdata->portmap;
+ if (tegra->bdata->portmap == NULL)
+ return -ENODEV;
+ tegra->bdata->lane_owner = tegra->pdata->lane_owner;
+ tegra->soc_config = soc_config;
tegra->ss_pwr_gated = false;
tegra->host_pwr_gated = false;
tegra->hc_in_elpg = false;
@@ -4174,20 +4319,22 @@ static int tegra_xhci_probe(struct platform_device *pdev)
tegra->host_resume_req = false;
tegra->lp0_exit = false;
- ret = tegra_xhci_request_mem_region(pdev, "padctl",
- &tegra->padctl_base);
+ /* request resource padctl base address */
+ ret = tegra_xhci_request_mem_region(pdev, 3, &tegra->padctl_base);
if (ret) {
dev_err(&pdev->dev, "failed to map padctl\n");
return ret;
}
- ret = tegra_xhci_request_mem_region(pdev, "fpci", &tegra->fpci_base);
+ /* request resource fpci base address */
+ ret = tegra_xhci_request_mem_region(pdev, 1, &tegra->fpci_base);
if (ret) {
dev_err(&pdev->dev, "failed to map fpci\n");
return ret;
}
- ret = tegra_xhci_request_mem_region(pdev, "ipfs", &tegra->ipfs_base);
+ /* request resource ipfs base address */
+ ret = tegra_xhci_request_mem_region(pdev, 2, &tegra->ipfs_base);
if (ret) {
dev_err(&pdev->dev, "failed to map ipfs\n");
return ret;
@@ -4241,7 +4388,8 @@ static int tegra_xhci_probe(struct platform_device *pdev)
/* reset the pointer back to NULL. driver uses it */
/* platform_set_drvdata(pdev, NULL); */
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "host");
+ /* request resource host base address */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "mem resource host doesn't exist\n");
ret = -ENODEV;
@@ -4360,7 +4508,8 @@ static int tegra_xhci_probe2(struct tegra_xhci_hcd *tegra)
return -ENOMEM;
}
- ret = tegra_xhci_request_mem_region(pdev, "host", &hcd->regs);
+ /* request resource host base address */
+ ret = tegra_xhci_request_mem_region(pdev, 0, &hcd->regs);
if (ret) {
dev_err(&pdev->dev, "failed to map host\n");
goto err_put_usb2_hcd;
@@ -4368,7 +4517,8 @@ static int tegra_xhci_probe2(struct tegra_xhci_hcd *tegra)
hcd->rsrc_start = tegra->host_phy_base;
hcd->rsrc_len = tegra->host_phy_size;
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "host");
+ /* Register interrupt handler for HOST */
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
dev_err(&pdev->dev, "irq resource host doesn't exist\n");
ret = -ENODEV;
@@ -4435,7 +4585,8 @@ static int tegra_xhci_probe2(struct tegra_xhci_hcd *tegra)
/* Register interrupt handler for SMI line to handle mailbox
* interrupt from firmware
*/
- ret = tegra_xhci_request_irq(pdev, "host-smi", tegra_xhci_smi_irq,
+
+ ret = tegra_xhci_request_irq(pdev, 1, tegra_xhci_smi_irq,
IRQF_SHARED, "tegra_xhci_mbox_irq", &tegra->smi_irq);
if (ret != 0)
goto err_remove_usb3_hcd;
@@ -4444,19 +4595,21 @@ static int tegra_xhci_probe2(struct tegra_xhci_hcd *tegra)
* handle wake on connect irqs interrupt from
* firmware
*/
- ret = tegra_xhci_request_irq(pdev, "padctl", tegra_xhci_padctl_irq,
+ ret = tegra_xhci_request_irq(pdev, 2, tegra_xhci_padctl_irq,
IRQF_SHARED | IRQF_TRIGGER_HIGH,
"tegra_xhci_padctl_irq", &tegra->padctl_irq);
if (ret != 0)
goto err_remove_usb3_hcd;
- ret = tegra_xhci_request_irq(pdev, "usb2", pmc_usb_phy_wake_isr,
+ /* Register interrupt wake handler for USB2 */
+ ret = tegra_xhci_request_irq(pdev, 4, pmc_usb_phy_wake_isr,
IRQF_SHARED | IRQF_TRIGGER_HIGH, "pmc_usb_phy_wake_isr",
&tegra->usb2_irq);
if (ret != 0)
goto err_remove_usb3_hcd;
- ret = tegra_xhci_request_irq(pdev, "usb3", pmc_usb_phy_wake_isr,
+ /* Register interrupt wake handler for USB3 */
+ ret = tegra_xhci_request_irq(pdev, 3, pmc_usb_phy_wake_isr,
IRQF_SHARED | IRQF_TRIGGER_HIGH, "pmc_usb_phy_wake_isr",
&tegra->usb3_irq);
if (ret != 0)
@@ -4576,6 +4729,7 @@ static struct platform_driver tegra_xhci_driver = {
#endif
.driver = {
.name = "tegra-xhci",
+ .of_match_table = tegra_xhci_of_match,
},
};
MODULE_ALIAS("platform:tegra-xhci");