]> git.sur5r.net Git - u-boot/commitdiff
Tegra114: Dalmore: Add pad config tables/code based on pinmux code
authorTom Warren <twarren@nvidia.com>
Mon, 11 Mar 2013 23:43:49 +0000 (16:43 -0700)
committerTom Warren <twarren@nvidia.com>
Thu, 14 Mar 2013 18:49:14 +0000 (11:49 -0700)
Pad config registers exist in APB_MISC_GP space, and control slew
rate, drive strengh, schmidt, high-speed, and low-power modes for
all of the pingroups in Tegra30. This builds off of the pinmux
way of constructing init tables to configure select pads (SDIOCFG,
for instance) during pinmux_init().

Currently, no padcfg entries exist. SDIO3CFG will be added when the
MMC driver is added as per the TRM to work with the SD-card slot on
Dalmore E1611.

Signed-off-by: Tom Warren <twarren@nvidia.com>
Reviewed-by: Stephen Warren <swarren@nvidia.com>
arch/arm/cpu/tegra114-common/pinmux.c
arch/arm/include/asm/arch-tegra114/pinmux.h
board/nvidia/dalmore/pinmux-config-dalmore.h

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]);
+}
index 53905cb8e9154f1e7cf5aa451e798762168dd654..9c22c08b6e3013fd82e882eefacb8f288c222530 100644 (file)
@@ -215,34 +215,35 @@ enum pdrive_pingrp {
        PDRIVE_PINGROUP_AT5,
        PDRIVE_PINGROUP_CDEV1,
        PDRIVE_PINGROUP_CDEV2,
-       PDRIVE_PINGROUP_CSUS,
-       PDRIVE_PINGROUP_DAP1,
+       PDRIVE_PINGROUP_DAP1 = 10,      /* offset 0x890 */
        PDRIVE_PINGROUP_DAP2,
        PDRIVE_PINGROUP_DAP3,
        PDRIVE_PINGROUP_DAP4,
        PDRIVE_PINGROUP_DBG,
-       PDRIVE_PINGROUP_SDIO3,
+       PDRIVE_PINGROUP_SDIO3 = 18,     /* offset 0x8B0 */
        PDRIVE_PINGROUP_SPI,
        PDRIVE_PINGROUP_UAA,
        PDRIVE_PINGROUP_UAB,
        PDRIVE_PINGROUP_UART2,
        PDRIVE_PINGROUP_UART3,
-       PDRIVE_PINGROUP_SDIO1 = 33,     /* offset 0x8ec */
-       PDRIVE_PINGROUP_CRT = 36,       /* offset 0x8f8 */
-       PDRIVE_PINGROUP_DDC,
+       PDRIVE_PINGROUP_SDIO1 = 33,     /* offset 0x8EC */
+       PDRIVE_PINGROUP_DDC = 37,       /* offset 0x8FC */
        PDRIVE_PINGROUP_GMA,
-       PDRIVE_PINGROUP_GME,
+       PDRIVE_PINGROUP_GME = 42,       /* offset 0x910 */
        PDRIVE_PINGROUP_GMF,
        PDRIVE_PINGROUP_GMG,
        PDRIVE_PINGROUP_GMH,
        PDRIVE_PINGROUP_OWR,
        PDRIVE_PINGROUP_UAD,
-       PDRIVE_PINGROUP_GPV,
        PDRIVE_PINGROUP_DEV3 = 49,      /* offset 0x92c */
        PDRIVE_PINGROUP_CEC = 52,       /* offset 0x938 */
-       PDRIVE_PINGROUP_AT6,
+       PDRIVE_PINGROUP_AT6 = 75,       /* offset 0x994 */
        PDRIVE_PINGROUP_DAP5,
        PDRIVE_PINGROUP_VBUS,
+       PDRIVE_PINGROUP_AO3,
+       PDRIVE_PINGROUP_HVC,
+       PDRIVE_PINGROUP_SDIO4,
+       PDRIVE_PINGROUP_AO0,
        PDRIVE_PINGROUP_COUNT,
 };
 
@@ -470,10 +471,73 @@ enum pmux_vddio {
        PMUX_VDDIO_NONE
 };
 
-/* T114 pin drive group and pin mux registers */
-#define PDRIVE_PINGROUP_OFFSET  (0x868 >> 2)
-#define PMUX_OFFSET     ((0x3000 >> 2) - PDRIVE_PINGROUP_OFFSET - \
-                       PDRIVE_PINGROUP_COUNT)
+#define PGRP_SLWF_NONE -1
+#define PGRP_SLWF_MAX  3
+#define PGRP_SLWR_NONE PGRP_SLWF_NONE
+#define PGRP_SLWR_MAX  PGRP_SLWF_MAX
+
+#define PGRP_DRVUP_NONE        -1
+#define PGRP_DRVUP_MAX 127
+#define PGRP_DRVDN_NONE        PGRP_DRVUP_NONE
+#define PGRP_DRVDN_MAX PGRP_DRVUP_MAX
+
+#define PGRP_SCHMT_NONE        -1
+#define PGRP_HSM_NONE  PGRP_SCHMT_NONE
+
+/* return 1 if a padgrp is in range */
+#define pmux_padgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PDRIVE_PINGROUP_COUNT))
+
+/* return 1 if a slew-rate rising/falling edge value is in range */
+#define pmux_pad_slw_isvalid(slw) (((slw) == PGRP_SLWF_NONE) || \
+                               (((slw) >= 0) && ((slw) <= PGRP_SLWF_MAX)))
+
+/* return 1 if a driver output pull-up/down strength code value is in range */
+#define pmux_pad_drv_isvalid(drv) (((drv) == PGRP_DRVUP_NONE) || \
+                               (((drv) >= 0) && ((drv) <= PGRP_DRVUP_MAX)))
+
+/* return 1 if a low-power mode value is in range */
+#define pmux_pad_lpmd_isvalid(lpm) (((lpm) == PGRP_LPMD_NONE) || \
+                               (((lpm) >= 0) && ((lpm) <= PGRP_LPMD_X)))
+
+/* Defines a pin group cfg's low-power mode select */
+enum pgrp_lpmd {
+       PGRP_LPMD_X8 = 0,
+       PGRP_LPMD_X4,
+       PGRP_LPMD_X2,
+       PGRP_LPMD_X,
+       PGRP_LPMD_NONE = -1,
+};
+
+/* Defines whether a pin group cfg's schmidt is enabled or not */
+enum pgrp_schmt {
+       PGRP_SCHMT_DISABLE = 0,
+       PGRP_SCHMT_ENABLE = 1,
+};
+
+/* Defines whether a pin group cfg's high-speed mode is enabled or not */
+enum pgrp_hsm {
+       PGRP_HSM_DISABLE = 0,
+       PGRP_HSM_ENABLE = 1,
+};
+
+/*
+ * This defines the configuration for a pin group's pad control config
+ */
+struct padctrl_config {
+       enum pdrive_pingrp padgrp;      /* pin group PDRIVE_PINGRP_x */
+       int slwf;                       /* falling edge slew         */
+       int slwr;                       /* rising edge slew          */
+       int drvup;                      /* pull-up drive strength    */
+       int drvdn;                      /* pull-down drive strength  */
+       enum pgrp_lpmd lpmd;            /* low-power mode selection  */
+       enum pgrp_schmt schmt;          /* schmidt enable            */
+       enum pgrp_hsm hsm;              /* high-speed mode enable    */
+};
+
+/* t114 pin drive group and pin mux registers */
+#define PDRIVE_PINGROUP_OFFSET (0x868 >> 2)
+#define PMUX_OFFSET    ((0x3000 >> 2) - PDRIVE_PINGROUP_OFFSET - \
+                               PDRIVE_PINGROUP_COUNT)
 struct pmux_tri_ctlr {
        uint pmt_reserved0;             /* ABP_MISC_PP_ reserved offset 00 */
        uint pmt_reserved1;             /* ABP_MISC_PP_ reserved offset 04 */
@@ -541,4 +605,12 @@ void pinmux_config_table(struct pingroup_config *config, int len);
 /* Set a group of pins from a table */
 void pinmux_init(void);
 
-#endif  /* _TEGRA114_PINMUX_H_ */
+/**
+ * Set the GP pad configs
+ *
+ * @param config       List of config items
+ * @param len          Number of config items in list
+ */
+void padgrp_config_table(struct padctrl_config *config, int len);
+
+#endif /* _TEGRA114_PINMUX_H_ */
index cb48b3ba1f0b852e5976684381ad99429df667f3..3ef6f4eaf6f39bad36cc11f6a97240cd442f0df4 100644 (file)
 
 #define USB_PINMUX CEC_PINMUX
 
+#define DEFAULT_PADCFG(_padgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) \
+       {                                               \
+               .padgrp = PDRIVE_PINGROUP_##_padgrp,    \
+               .slwf   = _slwf,                        \
+               .slwr   = _slwr,                        \
+               .drvup  = _drvup,                       \
+               .drvdn  = _drvdn,                       \
+               .lpmd   = PGRP_LPMD_##_lpmd,            \
+               .schmt  = PGRP_SCHMT_##_schmt,          \
+               .hsm    = PGRP_HSM_##_hsm,              \
+       }
+
 static struct pingroup_config tegra114_pinmux_common[] = {
        /* EXTPERIPH1 pinmux */
        DEFAULT_PINMUX(CLK1_OUT,      EXTPERIPH1,  NORMAL,    NORMAL,   OUTPUT),