]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/pci/host/pci-tegra.c
PCI: tegra: Use of_device_get_match_data()
[karo-tx-linux.git] / drivers / pci / host / pci-tegra.c
index c388468c202a75efd28bef26eaafb190690c5856..2d520755b1d735e01f165b50f97e8eaff165ec09 100644 (file)
@@ -9,6 +9,8 @@
  *
  * Bits taken from arch/arm/mach-dove/pcie.c
  *
+ * Author: Thierry Reding <treding@nvidia.com>
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -32,7 +34,7 @@
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/msi.h>
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
 
 #define AFI_PEXBIAS_CTRL_0             0x168
 
-#define RP_VEND_XP     0x00000F00
+#define RP_VEND_XP     0x00000f00
 #define  RP_VEND_XP_DL_UP      (1 << 30)
 
-#define RP_PRIV_MISC   0x00000FE0
-#define  RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xE << 0)
-#define  RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xF << 0)
+#define RP_PRIV_MISC   0x00000fe0
+#define  RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xe << 0)
+#define  RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xf << 0)
 
 #define RP_LINK_CONTROL_STATUS                 0x00000090
 #define  RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000
 #define  RP_LINK_CONTROL_STATUS_LINKSTAT_MASK  0x3fff0000
 
-#define PADS_CTL_SEL           0x0000009C
+#define PADS_CTL_SEL           0x0000009c
 
-#define PADS_CTL               0x000000A0
+#define PADS_CTL               0x000000a0
 #define  PADS_CTL_IDDQ_1L      (1 << 0)
 #define  PADS_CTL_TX_DATA_EN_1L        (1 << 6)
 #define  PADS_CTL_RX_DATA_EN_1L        (1 << 10)
 
-#define PADS_PLL_CTL_TEGRA20                   0x000000B8
-#define PADS_PLL_CTL_TEGRA30                   0x000000B4
+#define PADS_PLL_CTL_TEGRA20                   0x000000b8
+#define PADS_PLL_CTL_TEGRA30                   0x000000b4
 #define  PADS_PLL_CTL_RST_B4SM                 (1 << 1)
 #define  PADS_PLL_CTL_LOCKDET                  (1 << 8)
 #define  PADS_PLL_CTL_REFCLK_MASK              (0x3 << 16)
 #define  PADS_PLL_CTL_TXCLKREF_DIV5            (1 << 20)
 #define  PADS_PLL_CTL_TXCLKREF_BUF_EN          (1 << 22)
 
-#define PADS_REFCLK_CFG0                       0x000000C8
-#define PADS_REFCLK_CFG1                       0x000000CC
-#define PADS_REFCLK_BIAS                       0x000000D0
+#define PADS_REFCLK_CFG0                       0x000000c8
+#define PADS_REFCLK_CFG1                       0x000000cc
+#define PADS_REFCLK_BIAS                       0x000000d0
 
 /*
  * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit
 #define PADS_REFCLK_CFG_PREDI_SHIFT            8  /* 11:8 */
 #define PADS_REFCLK_CFG_DRVI_SHIFT             12 /* 15:12 */
 
-/* Default value provided by HW engineering is 0xfa5c */
-#define PADS_REFCLK_CFG_VALUE \
-       ( \
-               (0x17 << PADS_REFCLK_CFG_TERM_SHIFT)   | \
-               (0    << PADS_REFCLK_CFG_E_TERM_SHIFT) | \
-               (0xa  << PADS_REFCLK_CFG_PREDI_SHIFT)  | \
-               (0xf  << PADS_REFCLK_CFG_DRVI_SHIFT)     \
-       )
-
 struct tegra_msi {
        struct msi_controller chip;
        DECLARE_BITMAP(used, INT_PCI_MSI_NR);
@@ -247,11 +240,13 @@ struct tegra_msi {
 };
 
 /* used to differentiate between Tegra SoC generations */
-struct tegra_pcie_soc_data {
+struct tegra_pcie_soc {
        unsigned int num_ports;
        unsigned int msi_base_shift;
        u32 pads_pll_ctl;
        u32 tx_ref_sel;
+       u32 pads_refclk_cfg0;
+       u32 pads_refclk_cfg1;
        bool has_pex_clkreq_en;
        bool has_pex_bias_ctrl;
        bool has_intr_prsnt_sense;
@@ -274,7 +269,6 @@ struct tegra_pcie {
        struct list_head buses;
        struct resource *cs;
 
-       struct resource all;
        struct resource io;
        struct resource pio;
        struct resource mem;
@@ -306,7 +300,7 @@ struct tegra_pcie {
        struct regulator_bulk_data *supplies;
        unsigned int num_supplies;
 
-       const struct tegra_pcie_soc_data *soc_data;
+       const struct tegra_pcie_soc *soc;
        struct dentry *debugfs;
 };
 
@@ -548,8 +542,8 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
 
 static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
 {
-       const struct tegra_pcie_soc_data *soc = port->pcie->soc_data;
        unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
+       const struct tegra_pcie_soc *soc = port->pcie->soc;
        unsigned long value;
 
        /* enable reference clock */
@@ -568,8 +562,8 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
 
 static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
 {
-       const struct tegra_pcie_soc_data *soc = port->pcie->soc_data;
        unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
+       const struct tegra_pcie_soc *soc = port->pcie->soc;
        unsigned long value;
 
        /* assert port reset */
@@ -623,30 +617,21 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
        sys->mem_offset = pcie->offset.mem;
        sys->io_offset = pcie->offset.io;
 
-       err = devm_request_resource(pcie->dev, &pcie->all, &pcie->io);
-       if (err < 0)
-               return err;
-
-       err = devm_request_resource(pcie->dev, &ioport_resource, &pcie->pio);
-       if (err < 0)
-               return err;
-
-       err = devm_request_resource(pcie->dev, &pcie->all, &pcie->mem);
+       err = devm_request_resource(pcie->dev, &iomem_resource, &pcie->io);
        if (err < 0)
                return err;
 
-       err = devm_request_resource(pcie->dev, &pcie->all, &pcie->prefetch);
-       if (err)
-               return err;
-
        pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset);
        pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
        pci_add_resource_offset(&sys->resources, &pcie->prefetch,
                                sys->mem_offset);
        pci_add_resource(&sys->resources, &pcie->busn);
 
-       pci_ioremap_io(pcie->pio.start, pcie->io.start);
+       err = devm_request_pci_bus_resources(pcie->dev, &sys->resources);
+       if (err < 0)
+               return err;
 
+       pci_remap_iospace(&pcie->pio, pcie->io.start);
        return 1;
 }
 
@@ -789,7 +774,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 
 static int tegra_pcie_pll_wait(struct tegra_pcie *pcie, unsigned long timeout)
 {
-       const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+       const struct tegra_pcie_soc *soc = pcie->soc;
        u32 value;
 
        timeout = jiffies + msecs_to_jiffies(timeout);
@@ -805,7 +790,7 @@ static int tegra_pcie_pll_wait(struct tegra_pcie *pcie, unsigned long timeout)
 
 static int tegra_pcie_phy_enable(struct tegra_pcie *pcie)
 {
-       const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+       const struct tegra_pcie_soc *soc = pcie->soc;
        u32 value;
        int err;
 
@@ -838,12 +823,6 @@ static int tegra_pcie_phy_enable(struct tegra_pcie *pcie)
        value |= PADS_PLL_CTL_RST_B4SM;
        pads_writel(pcie, value, soc->pads_pll_ctl);
 
-       /* Configure the reference clock driver */
-       value = PADS_REFCLK_CFG_VALUE | (PADS_REFCLK_CFG_VALUE << 16);
-       pads_writel(pcie, value, PADS_REFCLK_CFG0);
-       if (soc->num_ports > 2)
-               pads_writel(pcie, PADS_REFCLK_CFG_VALUE, PADS_REFCLK_CFG1);
-
        /* wait for the PLL to lock */
        err = tegra_pcie_pll_wait(pcie, 500);
        if (err < 0) {
@@ -866,7 +845,7 @@ static int tegra_pcie_phy_enable(struct tegra_pcie *pcie)
 
 static int tegra_pcie_phy_disable(struct tegra_pcie *pcie)
 {
-       const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+       const struct tegra_pcie_soc *soc = pcie->soc;
        u32 value;
 
        /* disable TX/RX data */
@@ -927,6 +906,7 @@ static int tegra_pcie_port_phy_power_off(struct tegra_pcie_port *port)
 
 static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
 {
+       const struct tegra_pcie_soc *soc = pcie->soc;
        struct tegra_pcie_port *port;
        int err;
 
@@ -952,6 +932,12 @@ static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
                }
        }
 
+       /* Configure the reference clock driver */
+       pads_writel(pcie, soc->pads_refclk_cfg0, PADS_REFCLK_CFG0);
+
+       if (soc->num_ports > 2)
+               pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
+
        return 0;
 }
 
@@ -988,7 +974,7 @@ static int tegra_pcie_phy_power_off(struct tegra_pcie *pcie)
 
 static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
 {
-       const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+       const struct tegra_pcie_soc *soc = pcie->soc;
        struct tegra_pcie_port *port;
        unsigned long value;
        int err;
@@ -1081,7 +1067,7 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie)
 
 static int tegra_pcie_power_on(struct tegra_pcie *pcie)
 {
-       const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+       const struct tegra_pcie_soc *soc = pcie->soc;
        int err;
 
        reset_control_assert(pcie->pcie_xrst);
@@ -1131,7 +1117,7 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
 
 static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
 {
-       const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+       const struct tegra_pcie_soc *soc = pcie->soc;
 
        pcie->pex_clk = devm_clk_get(pcie->dev, "pex");
        if (IS_ERR(pcie->pex_clk))
@@ -1248,7 +1234,7 @@ static int tegra_pcie_port_get_phys(struct tegra_pcie_port *port)
 
 static int tegra_pcie_phys_get(struct tegra_pcie *pcie)
 {
-       const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+       const struct tegra_pcie_soc *soc = pcie->soc;
        struct device_node *np = pcie->dev->of_node;
        struct tegra_pcie_port *port;
        int err;
@@ -1500,7 +1486,7 @@ static const struct irq_domain_ops msi_domain_ops = {
 static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)
 {
        struct platform_device *pdev = to_platform_device(pcie->dev);
-       const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+       const struct tegra_pcie_soc *soc = pcie->soc;
        struct tegra_msi *msi = &pcie->msi;
        unsigned long base;
        int err;
@@ -1813,8 +1799,8 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
 
 static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
 {
-       const struct tegra_pcie_soc_data *soc = pcie->soc_data;
        struct device_node *np = pcie->dev->of_node, *port;
+       const struct tegra_pcie_soc *soc = pcie->soc;
        struct of_pci_range_parser parser;
        struct of_pci_range range;
        u32 lanes = 0, mask = 0;
@@ -1822,12 +1808,6 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
        struct resource res;
        int err;
 
-       memset(&pcie->all, 0, sizeof(pcie->all));
-       pcie->all.flags = IORESOURCE_MEM;
-       pcie->all.name = np->full_name;
-       pcie->all.start = ~0;
-       pcie->all.end = 0;
-
        if (of_pci_range_parser_init(&parser, np)) {
                dev_err(pcie->dev, "missing \"ranges\" property\n");
                return -EINVAL;
@@ -1880,18 +1860,8 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
                        }
                        break;
                }
-
-               if (res.start <= pcie->all.start)
-                       pcie->all.start = res.start;
-
-               if (res.end >= pcie->all.end)
-                       pcie->all.end = res.end;
        }
 
-       err = devm_request_resource(pcie->dev, &iomem_resource, &pcie->all);
-       if (err < 0)
-               return err;
-
        err = of_pci_parse_bus_range(np, &pcie->busn);
        if (err < 0) {
                dev_err(pcie->dev, "failed to parse ranges property: %d\n",
@@ -2073,11 +2043,12 @@ static int tegra_pcie_enable(struct tegra_pcie *pcie)
        return 0;
 }
 
-static const struct tegra_pcie_soc_data tegra20_pcie_data = {
+static const struct tegra_pcie_soc tegra20_pcie = {
        .num_ports = 2,
        .msi_base_shift = 0,
        .pads_pll_ctl = PADS_PLL_CTL_TEGRA20,
        .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10,
+       .pads_refclk_cfg0 = 0xfa5cfa5c,
        .has_pex_clkreq_en = false,
        .has_pex_bias_ctrl = false,
        .has_intr_prsnt_sense = false,
@@ -2085,11 +2056,13 @@ static const struct tegra_pcie_soc_data tegra20_pcie_data = {
        .has_gen2 = false,
 };
 
-static const struct tegra_pcie_soc_data tegra30_pcie_data = {
+static const struct tegra_pcie_soc tegra30_pcie = {
        .num_ports = 3,
        .msi_base_shift = 8,
        .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
        .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
+       .pads_refclk_cfg0 = 0xfa5cfa5c,
+       .pads_refclk_cfg1 = 0xfa5cfa5c,
        .has_pex_clkreq_en = true,
        .has_pex_bias_ctrl = true,
        .has_intr_prsnt_sense = true,
@@ -2097,11 +2070,12 @@ static const struct tegra_pcie_soc_data tegra30_pcie_data = {
        .has_gen2 = false,
 };
 
-static const struct tegra_pcie_soc_data tegra124_pcie_data = {
+static const struct tegra_pcie_soc tegra124_pcie = {
        .num_ports = 2,
        .msi_base_shift = 8,
        .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
        .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
+       .pads_refclk_cfg0 = 0x44ac44ac,
        .has_pex_clkreq_en = true,
        .has_pex_bias_ctrl = true,
        .has_intr_prsnt_sense = true,
@@ -2110,12 +2084,11 @@ static const struct tegra_pcie_soc_data tegra124_pcie_data = {
 };
 
 static const struct of_device_id tegra_pcie_of_match[] = {
-       { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie_data },
-       { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie_data },
-       { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie_data },
+       { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie },
+       { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie },
+       { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie },
        { },
 };
-MODULE_DEVICE_TABLE(of, tegra_pcie_of_match);
 
 static void *tegra_pcie_ports_seq_start(struct seq_file *s, loff_t *pos)
 {
@@ -2228,29 +2201,22 @@ remove:
 
 static int tegra_pcie_probe(struct platform_device *pdev)
 {
-       const struct of_device_id *match;
        struct tegra_pcie *pcie;
        int err;
 
-       match = of_match_device(tegra_pcie_of_match, &pdev->dev);
-       if (!match)
-               return -ENODEV;
-
        pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
        if (!pcie)
                return -ENOMEM;
 
+       pcie->soc = of_device_get_match_data(&pdev->dev);
        INIT_LIST_HEAD(&pcie->buses);
        INIT_LIST_HEAD(&pcie->ports);
-       pcie->soc_data = match->data;
        pcie->dev = &pdev->dev;
 
        err = tegra_pcie_parse_dt(pcie);
        if (err < 0)
                return err;
 
-       pcibios_min_mem = 0;
-
        err = tegra_pcie_get_resources(pcie);
        if (err < 0) {
                dev_err(&pdev->dev, "failed to request resources: %d\n", err);
@@ -2306,8 +2272,4 @@ static struct platform_driver tegra_pcie_driver = {
        },
        .probe = tegra_pcie_probe,
 };
-module_platform_driver(tegra_pcie_driver);
-
-MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
-MODULE_DESCRIPTION("NVIDIA Tegra PCIe driver");
-MODULE_LICENSE("GPL v2");
+builtin_platform_driver(tegra_pcie_driver);