]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - arch/arm/cpu/tegra114-common/pinmux.c
Tegra114: Dalmore: Add pad config tables/code based on pinmux code
[karo-tx-uboot.git] / arch / arm / cpu / tegra114-common / pinmux.c
index 16368c5bc114f8e84cbcf6c959b74e07bf357f76..4983a05090a2dad037318a42ecec4c6014f54da6 100644 (file)
@@ -39,6 +39,19 @@ struct tegra_pingroup_desc {
 #define PMUX_IO_RESET_SHIFT    8
 #define PMUX_RCV_SEL_SHIFT     9
 
+#define PGRP_HSM_SHIFT         2
+#define PGRP_SCHMT_SHIFT       3
+#define PGRP_LPMD_SHIFT                4
+#define PGRP_LPMD_MASK         (3 << PGRP_LPMD_SHIFT)
+#define PGRP_DRVDN_SHIFT       12
+#define PGRP_DRVDN_MASK                (0x7F << PGRP_DRVDN_SHIFT)
+#define PGRP_DRVUP_SHIFT       20
+#define PGRP_DRVUP_MASK                (0x7F << PGRP_DRVUP_SHIFT)
+#define PGRP_SLWR_SHIFT                28
+#define PGRP_SLWR_MASK         (3 << PGRP_SLWR_SHIFT)
+#define PGRP_SLWF_SHIFT                30
+#define PGRP_SLWF_MASK         (3 << PGRP_SLWF_SHIFT)
+
 /* Convenient macro for defining pin group properties */
 #define PIN(pg_name, vdd, f0, f1, f2, f3, iod) \
        {                                               \
@@ -544,3 +557,184 @@ void pinmux_config_table(struct pingroup_config *config, int len)
        for (i = 0; i < len; i++)
                pinmux_config_pingroup(&config[i]);
 }
+
+static int padgrp_set_drvup_slwf(enum pdrive_pingrp pad, int slwf)
+{
+       struct pmux_tri_ctlr *pmt =
+                       (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+       u32 *pad_slwf = &pmt->pmt_drive[pad];
+       u32 reg;
+
+       /* Error check on pad and slwf */
+       assert(pmux_padgrp_isvalid(pad));
+       assert(pmux_pad_slw_isvalid(slwf));
+
+       /* NONE means unspecified/do not change/use POR value */
+       if (slwf == PGRP_SLWF_NONE)
+               return 0;
+
+       reg = readl(pad_slwf);
+       reg &= ~PGRP_SLWF_MASK;
+       reg |= (slwf << PGRP_SLWF_SHIFT);
+       writel(reg, pad_slwf);
+
+       return 0;
+}
+
+static int padgrp_set_drvdn_slwr(enum pdrive_pingrp pad, int slwr)
+{
+       struct pmux_tri_ctlr *pmt =
+                       (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+       u32 *pad_slwr = &pmt->pmt_drive[pad];
+       u32 reg;
+
+       /* Error check on pad and slwr */
+       assert(pmux_padgrp_isvalid(pad));
+       assert(pmux_pad_slw_isvalid(slwr));
+
+       /* NONE means unspecified/do not change/use POR value */
+       if (slwr == PGRP_SLWR_NONE)
+               return 0;
+
+       reg = readl(pad_slwr);
+       reg &= ~PGRP_SLWR_MASK;
+       reg |= (slwr << PGRP_SLWR_SHIFT);
+       writel(reg, pad_slwr);
+
+       return 0;
+}
+
+static int padgrp_set_drvup(enum pdrive_pingrp pad, int drvup)
+{
+       struct pmux_tri_ctlr *pmt =
+                       (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+       u32 *pad_drvup = &pmt->pmt_drive[pad];
+       u32 reg;
+
+       /* Error check on pad and drvup */
+       assert(pmux_padgrp_isvalid(pad));
+       assert(pmux_pad_drv_isvalid(drvup));
+
+       /* NONE means unspecified/do not change/use POR value */
+       if (drvup == PGRP_DRVUP_NONE)
+               return 0;
+
+       reg = readl(pad_drvup);
+       reg &= ~PGRP_DRVUP_MASK;
+       reg |= (drvup << PGRP_DRVUP_SHIFT);
+       writel(reg, pad_drvup);
+
+       return 0;
+}
+
+static int padgrp_set_drvdn(enum pdrive_pingrp pad, int drvdn)
+{
+       struct pmux_tri_ctlr *pmt =
+                       (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+       u32 *pad_drvdn = &pmt->pmt_drive[pad];
+       u32 reg;
+
+       /* Error check on pad and drvdn */
+       assert(pmux_padgrp_isvalid(pad));
+       assert(pmux_pad_drv_isvalid(drvdn));
+
+       /* NONE means unspecified/do not change/use POR value */
+       if (drvdn == PGRP_DRVDN_NONE)
+               return 0;
+
+       reg = readl(pad_drvdn);
+       reg &= ~PGRP_DRVDN_MASK;
+       reg |= (drvdn << PGRP_DRVDN_SHIFT);
+       writel(reg, pad_drvdn);
+
+       return 0;
+}
+
+static int padgrp_set_lpmd(enum pdrive_pingrp pad, enum pgrp_lpmd lpmd)
+{
+       struct pmux_tri_ctlr *pmt =
+                       (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+       u32 *pad_lpmd = &pmt->pmt_drive[pad];
+       u32 reg;
+
+       /* Error check pad and lpmd value */
+       assert(pmux_padgrp_isvalid(pad));
+       assert(pmux_pad_lpmd_isvalid(lpmd));
+
+       /* NONE means unspecified/do not change/use POR value */
+       if (lpmd == PGRP_LPMD_NONE)
+               return 0;
+
+       reg = readl(pad_lpmd);
+       reg &= ~PGRP_LPMD_MASK;
+       reg |= (lpmd << PGRP_LPMD_SHIFT);
+       writel(reg, pad_lpmd);
+
+       return 0;
+}
+
+static int padgrp_set_schmt(enum pdrive_pingrp pad, enum pgrp_schmt schmt)
+{
+       struct pmux_tri_ctlr *pmt =
+                       (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+       u32 *pad_schmt = &pmt->pmt_drive[pad];
+       u32 reg;
+
+       /* Error check pad */
+       assert(pmux_padgrp_isvalid(pad));
+
+       /* NONE means unspecified/do not change/use POR value */
+       if (schmt == PGRP_SCHMT_NONE)
+               return 0;
+
+       reg = readl(pad_schmt);
+       reg &= ~(1 << PGRP_SCHMT_SHIFT);
+       if (schmt == PGRP_SCHMT_ENABLE)
+               reg |= (0x1 << PGRP_SCHMT_SHIFT);
+       writel(reg, pad_schmt);
+
+       return 0;
+}
+static int padgrp_set_hsm(enum pdrive_pingrp pad, enum pgrp_hsm hsm)
+{
+       struct pmux_tri_ctlr *pmt =
+                       (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+       u32 *pad_hsm = &pmt->pmt_drive[pad];
+       u32 reg;
+
+       /* Error check pad */
+       assert(pmux_padgrp_isvalid(pad));
+
+       /* NONE means unspecified/do not change/use POR value */
+       if (hsm == PGRP_HSM_NONE)
+               return 0;
+
+       reg = readl(pad_hsm);
+       reg &= ~(1 << PGRP_HSM_SHIFT);
+       if (hsm == PGRP_HSM_ENABLE)
+               reg |= (0x1 << PGRP_HSM_SHIFT);
+       writel(reg, pad_hsm);
+
+       return 0;
+}
+
+void padctrl_config_pingroup(struct padctrl_config *config)
+{
+       enum pdrive_pingrp pad = config->padgrp;
+
+       padgrp_set_drvup_slwf(pad, config->slwf);
+       padgrp_set_drvdn_slwr(pad, config->slwr);
+       padgrp_set_drvup(pad, config->drvup);
+       padgrp_set_drvdn(pad, config->drvdn);
+       padgrp_set_lpmd(pad, config->lpmd);
+       padgrp_set_schmt(pad, config->schmt);
+       padgrp_set_hsm(pad, config->hsm);
+}
+
+void padgrp_config_table(struct padctrl_config *config, int len)
+{
+       int i;
+
+       for (i = 0; i < len; i++)
+               padctrl_config_pingroup(&config[i]);
+}