]> git.sur5r.net Git - u-boot/blobdiff - arch/arm/mach-tegra/tegra210/xusb-padctl.c
treewide: replace with error() with pr_err()
[u-boot] / arch / arm / mach-tegra / tegra210 / xusb-padctl.c
index 3c10a96aa39695a81ab28ea334b101d68651b0a4..a3e3e378e18079390ca7df6030477047ec5155f0 100644 (file)
@@ -8,51 +8,86 @@
 
 #include <common.h>
 #include <errno.h>
-#include <fdtdec.h>
-#include <malloc.h>
+#include <dm/of_access.h>
+#include <dm/ofnode.h>
 
-#include <asm/io.h>
+#include "../xusb-padctl-common.h"
 
 #include <asm/arch/clock.h>
-#include <asm/arch-tegra/xusb-padctl.h>
 
 #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
 
-struct tegra_xusb_phy_ops {
-       int (*prepare)(struct tegra_xusb_phy *phy);
-       int (*enable)(struct tegra_xusb_phy *phy);
-       int (*disable)(struct tegra_xusb_phy *phy);
-       int (*unprepare)(struct tegra_xusb_phy *phy);
+DECLARE_GLOBAL_DATA_PTR;
+
+enum tegra210_function {
+       TEGRA210_FUNC_SNPS,
+       TEGRA210_FUNC_XUSB,
+       TEGRA210_FUNC_UART,
+       TEGRA210_FUNC_PCIE_X1,
+       TEGRA210_FUNC_PCIE_X4,
+       TEGRA210_FUNC_USB3,
+       TEGRA210_FUNC_SATA,
+       TEGRA210_FUNC_RSVD,
 };
 
-struct tegra_xusb_phy {
-       const struct tegra_xusb_phy_ops *ops;
-
-       struct tegra_xusb_padctl *padctl;
+static const char *const tegra210_functions[] = {
+       "snps",
+       "xusb",
+       "uart",
+       "pcie-x1",
+       "pcie-x4",
+       "usb3",
+       "sata",
+       "rsvd",
 };
 
-struct tegra_xusb_padctl {
-       struct fdt_resource regs;
+static const unsigned int tegra210_otg_functions[] = {
+       TEGRA210_FUNC_SNPS,
+       TEGRA210_FUNC_XUSB,
+       TEGRA210_FUNC_UART,
+       TEGRA210_FUNC_RSVD,
+};
 
-       unsigned int enable;
+static const unsigned int tegra210_usb_functions[] = {
+       TEGRA210_FUNC_SNPS,
+       TEGRA210_FUNC_XUSB,
+};
 
-       struct tegra_xusb_phy phys[2];
+static const unsigned int tegra210_pci_functions[] = {
+       TEGRA210_FUNC_PCIE_X1,
+       TEGRA210_FUNC_USB3,
+       TEGRA210_FUNC_SATA,
+       TEGRA210_FUNC_PCIE_X4,
 };
 
-static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl,
-                              unsigned long offset)
-{
-       u32 value = readl(padctl->regs.start + offset);
-       debug("padctl: %08lx > %08x\n", offset, value);
-       return value;
-}
+#define TEGRA210_LANE(_name, _offset, _shift, _mask, _iddq, _funcs)    \
+       {                                                               \
+               .name = _name,                                          \
+               .offset = _offset,                                      \
+               .shift = _shift,                                        \
+               .mask = _mask,                                          \
+               .iddq = _iddq,                                          \
+               .num_funcs = ARRAY_SIZE(tegra210_##_funcs##_functions), \
+               .funcs = tegra210_##_funcs##_functions,                 \
+       }
 
-static inline void padctl_writel(struct tegra_xusb_padctl *padctl,
-                                u32 value, unsigned long offset)
-{
-       debug("padctl: %08lx < %08x\n", offset, value);
-       writel(value, padctl->regs.start + offset);
-}
+static const struct tegra_xusb_padctl_lane tegra210_lanes[] = {
+       TEGRA210_LANE("otg-0",     0x004,  0, 0x3, 0, otg),
+       TEGRA210_LANE("otg-1",     0x004,  2, 0x3, 0, otg),
+       TEGRA210_LANE("otg-2",     0x004,  4, 0x3, 0, otg),
+       TEGRA210_LANE("otg-3",     0x004,  6, 0x3, 0, otg),
+       TEGRA210_LANE("usb2-bias", 0x004, 18, 0x3, 0, otg),
+       TEGRA210_LANE("hsic-0",    0x004, 14, 0x1, 0, usb),
+       TEGRA210_LANE("hsic-1",    0x004, 15, 0x1, 0, usb),
+       TEGRA210_LANE("pcie-0",    0x028, 12, 0x3, 1, pci),
+       TEGRA210_LANE("pcie-1",    0x028, 14, 0x3, 2, pci),
+       TEGRA210_LANE("pcie-2",    0x028, 16, 0x3, 3, pci),
+       TEGRA210_LANE("pcie-3",    0x028, 18, 0x3, 4, pci),
+       TEGRA210_LANE("pcie-4",    0x028, 20, 0x3, 5, pci),
+       TEGRA210_LANE("pcie-5",    0x028, 22, 0x3, 6, pci),
+       TEGRA210_LANE("pcie-6",    0x028, 24, 0x3, 7, pci),
+       TEGRA210_LANE("sata-0",    0x028, 30, 0x3, 8, pci),
+};
 
 #define XUSB_PADCTL_ELPG_PROGRAM 0x024
 #define  XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 31)
@@ -90,7 +125,7 @@ static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
        u32 value;
 
        if (padctl->enable == 0) {
-               error("unbalanced enable/disable");
+               pr_err("unbalanced enable/disable");
                return 0;
        }
 
@@ -248,7 +283,10 @@ static int pcie_phy_enable(struct tegra_xusb_phy *phy)
                if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE)
                        break;
        }
-
+       if (!(value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE)) {
+               debug("  timeout\n");
+               return -ETIMEDOUT;
+       }
        debug("  done\n");
 
        value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
@@ -264,7 +302,10 @@ static int pcie_phy_enable(struct tegra_xusb_phy *phy)
                if ((value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE) == 0)
                        break;
        }
-
+       if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE) {
+               debug("  timeout\n");
+               return -ETIMEDOUT;
+       }
        debug("  done\n");
 
        value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
@@ -279,7 +320,10 @@ static int pcie_phy_enable(struct tegra_xusb_phy *phy)
                if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS)
                        break;
        }
-
+       if (!(value & XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS)) {
+               debug("  timeout\n");
+               return -ETIMEDOUT;
+       }
        debug("  done\n");
 
        value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
@@ -295,7 +339,10 @@ static int pcie_phy_enable(struct tegra_xusb_phy *phy)
                if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE)
                        break;
        }
-
+       if (!(value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE)) {
+               debug("  timeout\n");
+               return -ETIMEDOUT;
+       }
        debug("  done\n");
 
        value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
@@ -310,7 +357,10 @@ static int pcie_phy_enable(struct tegra_xusb_phy *phy)
                if ((value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE) == 0)
                        break;
        }
-
+       if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE) {
+               debug("  timeout\n");
+               return -ETIMEDOUT;
+       }
        debug("  done\n");
 
        value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
@@ -358,138 +408,50 @@ static const struct tegra_xusb_phy_ops pcie_phy_ops = {
        .unprepare = phy_unprepare,
 };
 
-static struct tegra_xusb_padctl *padctl = &(struct tegra_xusb_padctl) {
-       .phys = {
-               [0] = {
-                       .ops = &pcie_phy_ops,
-               },
+static struct tegra_xusb_phy tegra210_phys[] = {
+       {
+               .type = TEGRA_XUSB_PADCTL_PCIE,
+               .ops = &pcie_phy_ops,
+               .padctl = &padctl,
        },
 };
 
-static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl,
-                                     const void *fdt, int node)
-{
-       int err;
-
-       err = fdt_get_resource(fdt, node, "reg", 0, &padctl->regs);
-       if (err < 0) {
-               error("registers not found");
-               return err;
-       }
-
-       debug("regs: %pa-%pa\n", &padctl->regs.start,
-             &padctl->regs.end);
-
-       return 0;
-}
+static const struct tegra_xusb_padctl_soc tegra210_socdata = {
+       .lanes = tegra210_lanes,
+       .num_lanes = ARRAY_SIZE(tegra210_lanes),
+       .functions = tegra210_functions,
+       .num_functions = ARRAY_SIZE(tegra210_functions),
+       .phys = tegra210_phys,
+       .num_phys = ARRAY_SIZE(tegra210_phys),
+};
 
-static int process_nodes(const void *fdt, int nodes[], unsigned int count)
+void tegra_xusb_padctl_init(void)
 {
-       unsigned int i;
-       int err;
-
-       debug("> %s(fdt=%p, nodes=%p, count=%u)\n", __func__, fdt, nodes,
-             count);
-
-       for (i = 0; i < count; i++) {
-               enum fdt_compat_id id;
-
-               if (!fdtdec_get_is_enabled(fdt, nodes[i]))
-                       continue;
-
-               id = fdtdec_lookup(fdt, nodes[i]);
-               switch (id) {
-               case COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL:
-               case COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL:
-                       break;
-
-               default:
-                       error("unsupported compatible: %s",
-                             fdtdec_get_compatible(id));
-                       continue;
+       ofnode nodes[1];
+       int count = 0;
+       int ret;
+
+       debug("%s: start\n", __func__);
+       if (of_live_active()) {
+               struct device_node *np = of_find_compatible_node(NULL, NULL,
+                                               "nvidia,tegra210-xusb-padctl");
+
+               debug("np=%p\n", np);
+               if (np) {
+                       nodes[0] = np_to_ofnode(np);
+                       count = 1;
                }
-
-               err = tegra_xusb_padctl_parse_dt(padctl, fdt, nodes[i]);
-               if (err < 0) {
-                       error("failed to parse DT: %d",
-                             err);
-                       continue;
-               }
-
-               /* deassert XUSB padctl reset */
-               reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0);
-
-               /* only a single instance is supported */
-               break;
-       }
-
-       debug("< %s()\n", __func__);
-       return 0;
-}
-
-struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type)
-{
-       struct tegra_xusb_phy *phy = NULL;
-
-       switch (type) {
-       case TEGRA_XUSB_PADCTL_PCIE:
-               phy = &padctl->phys[0];
-               phy->padctl = padctl;
-               break;
+       } else {
+               int node_offsets[1];
+               int i;
+
+               count = fdtdec_find_aliases_for_id(gd->fdt_blob, "padctl",
+                               COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL,
+                               node_offsets, ARRAY_SIZE(node_offsets));
+               for (i = 0; i < count; i++)
+                       nodes[i] = offset_to_ofnode(node_offsets[i]);
        }
 
-       return phy;
-}
-
-int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy)
-{
-       if (phy && phy->ops && phy->ops->prepare)
-               return phy->ops->prepare(phy);
-
-       return phy ? -ENOSYS : -EINVAL;
-}
-
-int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy)
-{
-       if (phy && phy->ops && phy->ops->enable)
-               return phy->ops->enable(phy);
-
-       return phy ? -ENOSYS : -EINVAL;
-}
-
-int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy)
-{
-       if (phy && phy->ops && phy->ops->disable)
-               return phy->ops->disable(phy);
-
-       return phy ? -ENOSYS : -EINVAL;
-}
-
-int tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy)
-{
-       if (phy && phy->ops && phy->ops->unprepare)
-               return phy->ops->unprepare(phy);
-
-       return phy ? -ENOSYS : -EINVAL;
-}
-
-void tegra_xusb_padctl_init(const void *fdt)
-{
-       int count, nodes[1];
-
-       debug("> %s(fdt=%p)\n", __func__, fdt);
-
-       count = fdtdec_find_aliases_for_id(fdt, "padctl",
-                                          COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL,
-                                          nodes, ARRAY_SIZE(nodes));
-       if (process_nodes(fdt, nodes, count))
-               return;
-
-       count = fdtdec_find_aliases_for_id(fdt, "padctl",
-                                          COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL,
-                                          nodes, ARRAY_SIZE(nodes));
-       if (process_nodes(fdt, nodes, count))
-               return;
-
-       debug("< %s()\n", __func__);
+       ret = tegra_xusb_process_nodes(nodes, count, &tegra210_socdata);
+       debug("%s: done, ret=%d\n", __func__, ret);
 }