ARM: Tegra: Pinmux: Fix drive strength configuration
Pavan Kunapuli [Fri, 2 Sep 2011 10:02:00 +0000 (15:02 +0530)]
In T30, different pad ctrl group registers have
different pull up and pull down drive strength field
offsets and maximum values. Modified drive_strength
structure to be able to pass the offsets and masks of
each group to ensure that drive strengths are properly
configured.

Bug 870369

Original-Change-Id: Ib1872417542236c95c3b41a1ad860ef8418f5704
Reviewed-on: http://git-master/r/49872
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>

Rebase-Id: R4889bbb8bc0e5fef57d98bc68cd0116a9be3fdbd

arch/arm/mach-tegra/include/mach/pinmux.h
arch/arm/mach-tegra/pinmux-tegra20-tables.c
arch/arm/mach-tegra/pinmux-tegra30-tables.c
arch/arm/mach-tegra/pinmux.c

index 9b5f204..5af201a 100644 (file)
@@ -294,6 +294,10 @@ struct tegra_drive_pingroup_desc {
        const char *name;
        s16 reg_bank;
        s16 reg;
+       u8 drvup_offset;
+       u16 drvup_mask;
+       u8 drvdown_offset;
+       u16 drvdown_mask;
 };
 
 struct tegra_pingroup_desc {
index a1c6aa6..95ceef0 100644 (file)
 #define PULLUPDOWN_REG_A       0xa0
 #define PINGROUP_REG_A         0x868
 
-#define DRIVE_PINGROUP(pg_name, r)                             \
+#define SET_DRIVE_PINGROUP(pg_name, r, drv_down_offset, drv_down_mask, drv_up_offset, drv_up_mask)     \
        [TEGRA_DRIVE_PINGROUP_ ## pg_name] = {                  \
                .name = #pg_name,                               \
                .reg_bank = 3,                                  \
-               .reg = ((r) - PINGROUP_REG_A)                   \
+               .reg = ((r) - PINGROUP_REG_A),                  \
+               .drvup_offset = drv_up_offset,                  \
+               .drvup_mask = drv_up_mask,                      \
+               .drvdown_offset = drv_down_offset,              \
+               .drvdown_mask = drv_down_mask,                  \
        }
 
-static const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
-       DRIVE_PINGROUP(AO1,             0x868),
-       DRIVE_PINGROUP(AO2,             0x86c),
-       DRIVE_PINGROUP(AT1,             0x870),
-       DRIVE_PINGROUP(AT2,             0x874),
-       DRIVE_PINGROUP(CDEV1,           0x878),
-       DRIVE_PINGROUP(CDEV2,           0x87c),
-       DRIVE_PINGROUP(CSUS,            0x880),
-       DRIVE_PINGROUP(DAP1,            0x884),
-       DRIVE_PINGROUP(DAP2,            0x888),
-       DRIVE_PINGROUP(DAP3,            0x88c),
-       DRIVE_PINGROUP(DAP4,            0x890),
-       DRIVE_PINGROUP(DBG,             0x894),
-       DRIVE_PINGROUP(LCD1,            0x898),
-       DRIVE_PINGROUP(LCD2,            0x89c),
-       DRIVE_PINGROUP(SDMMC2,          0x8a0),
-       DRIVE_PINGROUP(SDMMC3,          0x8a4),
-       DRIVE_PINGROUP(SPI,             0x8a8),
-       DRIVE_PINGROUP(UAA,             0x8ac),
-       DRIVE_PINGROUP(UAB,             0x8b0),
-       DRIVE_PINGROUP(UART2,           0x8b4),
-       DRIVE_PINGROUP(UART3,           0x8b8),
-       DRIVE_PINGROUP(VI1,             0x8bc),
-       DRIVE_PINGROUP(VI2,             0x8c0),
-       DRIVE_PINGROUP(XM2A,            0x8c4),
-       DRIVE_PINGROUP(XM2C,            0x8c8),
-       DRIVE_PINGROUP(XM2D,            0x8cc),
-       DRIVE_PINGROUP(XM2CLK,          0x8d0),
-       DRIVE_PINGROUP(MEMCOMP,         0x8d4),
-       DRIVE_PINGROUP(SDIO1,           0x8e0),
-       DRIVE_PINGROUP(CRT,             0x8ec),
-       DRIVE_PINGROUP(DDC,             0x8f0),
-       DRIVE_PINGROUP(GMA,             0x8f4),
-       DRIVE_PINGROUP(GMB,             0x8f8),
-       DRIVE_PINGROUP(GMC,             0x8fc),
-       DRIVE_PINGROUP(GMD,             0x900),
-       DRIVE_PINGROUP(GME,             0x904),
-       DRIVE_PINGROUP(OWR,             0x908),
-       DRIVE_PINGROUP(UAD,             0x90c),
+#define DEFAULT_DRIVE_PINGROUP(pg_name, r)             \
+       [TEGRA_DRIVE_PINGROUP_ ## pg_name] = {          \
+               .name = #pg_name,                       \
+               .reg_bank = 3,                          \
+               .reg = ((r) - PINGROUP_REG_A),          \
+               .drvup_offset = 20,                     \
+               .drvup_mask = 0x1f,                     \
+               .drvdown_offset = 12,                   \
+               .drvdown_mask = 0x1f,                   \
+       }
+
+const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
+       DEFAULT_DRIVE_PINGROUP(AO1,             0x868),
+       DEFAULT_DRIVE_PINGROUP(AO2,             0x86c),
+       DEFAULT_DRIVE_PINGROUP(AT1,             0x870),
+       DEFAULT_DRIVE_PINGROUP(AT2,             0x874),
+       DEFAULT_DRIVE_PINGROUP(CDEV1,           0x878),
+       DEFAULT_DRIVE_PINGROUP(CDEV2,           0x87c),
+       DEFAULT_DRIVE_PINGROUP(CSUS,            0x880),
+       DEFAULT_DRIVE_PINGROUP(DAP1,            0x884),
+       DEFAULT_DRIVE_PINGROUP(DAP2,            0x888),
+       DEFAULT_DRIVE_PINGROUP(DAP3,            0x88c),
+       DEFAULT_DRIVE_PINGROUP(DAP4,            0x890),
+       DEFAULT_DRIVE_PINGROUP(DBG,             0x894),
+       DEFAULT_DRIVE_PINGROUP(LCD1,            0x898),
+       DEFAULT_DRIVE_PINGROUP(LCD2,            0x89c),
+       DEFAULT_DRIVE_PINGROUP(SDMMC2,          0x8a0),
+       DEFAULT_DRIVE_PINGROUP(SDMMC3,          0x8a4),
+       DEFAULT_DRIVE_PINGROUP(SPI,             0x8a8),
+       DEFAULT_DRIVE_PINGROUP(UAA,             0x8ac),
+       DEFAULT_DRIVE_PINGROUP(UAB,             0x8b0),
+       DEFAULT_DRIVE_PINGROUP(UART2,           0x8b4),
+       DEFAULT_DRIVE_PINGROUP(UART3,           0x8b8),
+       DEFAULT_DRIVE_PINGROUP(VI1,             0x8bc),
+       DEFAULT_DRIVE_PINGROUP(VI2,             0x8c0),
+       DEFAULT_DRIVE_PINGROUP(XM2A,            0x8c4),
+       DEFAULT_DRIVE_PINGROUP(XM2C,            0x8c8),
+       DEFAULT_DRIVE_PINGROUP(XM2D,            0x8cc),
+       DEFAULT_DRIVE_PINGROUP(XM2CLK,          0x8d0),
+       DEFAULT_DRIVE_PINGROUP(MEMCOMP,         0x8d4),
+       DEFAULT_DRIVE_PINGROUP(SDIO1,           0x8e0),
+       DEFAULT_DRIVE_PINGROUP(CRT,             0x8ec),
+       DEFAULT_DRIVE_PINGROUP(DDC,             0x8f0),
+       DEFAULT_DRIVE_PINGROUP(GMA,             0x8f4),
+       DEFAULT_DRIVE_PINGROUP(GMB,             0x8f8),
+       DEFAULT_DRIVE_PINGROUP(GMC,             0x8fc),
+       DEFAULT_DRIVE_PINGROUP(GMD,             0x900),
+       DEFAULT_DRIVE_PINGROUP(GME,             0x904),
+       DEFAULT_DRIVE_PINGROUP(OWR,             0x908),
+       DEFAULT_DRIVE_PINGROUP(UAD,             0x90c),
 };
 
 #define PINGROUP(pg_name, vdd, f0, f1, f2, f3, f_safe,         \
index 8419967..9733a2c 100644 (file)
 #define PINGROUP_REG_A 0x868
 #define MUXCTL_REG_A   0x3000
 
-#define DRIVE_PINGROUP(pg_name, r)             \
-       [TEGRA_DRIVE_PINGROUP_ ## pg_name] = {  \
-               .name = #pg_name,               \
-               .reg_bank = 0,                  \
-               .reg = ((r) - PINGROUP_REG_A)   \
+#define SET_DRIVE_PINGROUP(pg_name, r, drv_down_offset, drv_down_mask, drv_up_offset, drv_up_mask)     \
+       [TEGRA_DRIVE_PINGROUP_ ## pg_name] = {                  \
+               .name = #pg_name,                               \
+               .reg_bank = 0,                                  \
+               .reg = ((r) - PINGROUP_REG_A),                  \
+               .drvup_offset = drv_up_offset,                  \
+               .drvup_mask = drv_up_mask,                      \
+               .drvdown_offset = drv_down_offset,              \
+               .drvdown_mask = drv_down_mask,                  \
+       }
+
+#define DEFAULT_DRIVE_PINGROUP(pg_name, r)             \
+       [TEGRA_DRIVE_PINGROUP_ ## pg_name] = {          \
+               .name = #pg_name,                       \
+               .reg_bank = 0,                          \
+               .reg = ((r) - PINGROUP_REG_A),          \
+               .drvup_offset = 20,                     \
+               .drvup_mask = 0x1f,                     \
+               .drvdown_offset = 12,                   \
+               .drvdown_mask = 0x1f,                   \
        }
 
-static const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
-       DRIVE_PINGROUP(AO1,             0x868),
-       DRIVE_PINGROUP(AO2,             0x86c),
-       DRIVE_PINGROUP(AT1,             0x870),
-       DRIVE_PINGROUP(AT2,             0x874),
-       DRIVE_PINGROUP(AT3,             0x878),
-       DRIVE_PINGROUP(AT4,             0x87c),
-       DRIVE_PINGROUP(AT5,             0x880),
-       DRIVE_PINGROUP(CDEV1,           0x884),
-       DRIVE_PINGROUP(CDEV2,           0x888),
-       DRIVE_PINGROUP(CSUS,            0x88c),
-       DRIVE_PINGROUP(DAP1,            0x890),
-       DRIVE_PINGROUP(DAP2,            0x894),
-       DRIVE_PINGROUP(DAP3,            0x898),
-       DRIVE_PINGROUP(DAP4,            0x89c),
-       DRIVE_PINGROUP(DBG,             0x8a0),
-       DRIVE_PINGROUP(LCD1,            0x8a4),
-       DRIVE_PINGROUP(LCD2,            0x8a8),
-       DRIVE_PINGROUP(SDIO2,           0x8ac),
-       DRIVE_PINGROUP(SDIO3,           0x8b0),
-       DRIVE_PINGROUP(SPI,             0x8b4),
-       DRIVE_PINGROUP(UAA,             0x8b8),
-       DRIVE_PINGROUP(UAB,             0x8bc),
-       DRIVE_PINGROUP(UART2,           0x8c0),
-       DRIVE_PINGROUP(UART3,           0x8c4),
-       DRIVE_PINGROUP(VI1,             0x8c8),
-       DRIVE_PINGROUP(SDIO1,           0x8ec),
-       DRIVE_PINGROUP(CRT,             0x8f8),
-       DRIVE_PINGROUP(DDC,             0x8fc),
-       DRIVE_PINGROUP(GMA,             0x900),
-       DRIVE_PINGROUP(GMB,             0x904),
-       DRIVE_PINGROUP(GMC,             0x908),
-       DRIVE_PINGROUP(GMD,             0x90c),
-       DRIVE_PINGROUP(GME,             0x910),
-       DRIVE_PINGROUP(GMF,             0x914),
-       DRIVE_PINGROUP(GMG,             0x918),
-       DRIVE_PINGROUP(GMH,             0x91c),
-       DRIVE_PINGROUP(OWR,             0x920),
-       DRIVE_PINGROUP(UAD,             0x924),
-       DRIVE_PINGROUP(GPV,             0x928),
-       DRIVE_PINGROUP(DEV3,            0x92c),
-       DRIVE_PINGROUP(CEC,             0x938),
+const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
+       DEFAULT_DRIVE_PINGROUP(AO1,             0x868),
+       DEFAULT_DRIVE_PINGROUP(AO2,             0x86c),
+       DEFAULT_DRIVE_PINGROUP(AT1,             0x870),
+       DEFAULT_DRIVE_PINGROUP(AT2,             0x874),
+       DEFAULT_DRIVE_PINGROUP(AT3,             0x878),
+       DEFAULT_DRIVE_PINGROUP(AT4,             0x87c),
+       DEFAULT_DRIVE_PINGROUP(AT5,             0x880),
+       DEFAULT_DRIVE_PINGROUP(CDEV1,           0x884),
+       DEFAULT_DRIVE_PINGROUP(CDEV2,           0x888),
+       DEFAULT_DRIVE_PINGROUP(CSUS,            0x88c),
+       DEFAULT_DRIVE_PINGROUP(DAP1,            0x890),
+       DEFAULT_DRIVE_PINGROUP(DAP2,            0x894),
+       DEFAULT_DRIVE_PINGROUP(DAP3,            0x898),
+       DEFAULT_DRIVE_PINGROUP(DAP4,            0x89c),
+       DEFAULT_DRIVE_PINGROUP(DBG,             0x8a0),
+       DEFAULT_DRIVE_PINGROUP(LCD1,            0x8a4),
+       DEFAULT_DRIVE_PINGROUP(LCD2,            0x8a8),
+       SET_DRIVE_PINGROUP(SDIO2,               0x8ac,  12,     0x7f,   20,     0x7f),
+       SET_DRIVE_PINGROUP(SDIO3,               0x8b0,  12,     0x7f,   20,     0x7f),
+       DEFAULT_DRIVE_PINGROUP(SPI,             0x8b4),
+       DEFAULT_DRIVE_PINGROUP(UAA,             0x8b8),
+       DEFAULT_DRIVE_PINGROUP(UAB,             0x8bc),
+       DEFAULT_DRIVE_PINGROUP(UART2,           0x8c0),
+       DEFAULT_DRIVE_PINGROUP(UART3,           0x8c4),
+       DEFAULT_DRIVE_PINGROUP(VI1,             0x8c8),
+       SET_DRIVE_PINGROUP(SDIO1,               0x8ec,  12,     0x7f,   20,     0x7f),
+       DEFAULT_DRIVE_PINGROUP(CRT,             0x8f8),
+       DEFAULT_DRIVE_PINGROUP(DDC,             0x8fc),
+       SET_DRIVE_PINGROUP(GMA,                 0x900,  14,     0x1f,   19,     0x1f),
+       SET_DRIVE_PINGROUP(GMB,                 0x904,  14,     0x1f,   19,     0x1f),
+       SET_DRIVE_PINGROUP(GMC,                 0x908,  14,     0x1f,   19,     0x1f),
+       SET_DRIVE_PINGROUP(GMD,                 0x90c,  14,     0x1f,   19,     0x1f),
+       DEFAULT_DRIVE_PINGROUP(GME,             0x910),
+       DEFAULT_DRIVE_PINGROUP(GMF,             0x914),
+       DEFAULT_DRIVE_PINGROUP(GMG,             0x918),
+       DEFAULT_DRIVE_PINGROUP(GMH,             0x91c),
+       DEFAULT_DRIVE_PINGROUP(OWR,             0x920),
+       DEFAULT_DRIVE_PINGROUP(UAD,             0x924),
+       DEFAULT_DRIVE_PINGROUP(GPV,             0x928),
+       DEFAULT_DRIVE_PINGROUP(DEV3,            0x92c),
+       DEFAULT_DRIVE_PINGROUP(CEC,             0x938),
 };
 
 #define PINGROUP(pg_name, vdd, f0, f1, f2, f3, fs, iod, reg)   \
index 7cdbdfa..5b36ae2 100644 (file)
@@ -707,6 +707,7 @@ static int tegra_drive_pinmux_set_pull_down(int pg,
 {
        unsigned long flags;
        u32 reg;
+
        if (pg < 0 || pg >=  drive_max)
                return -ERANGE;
 
@@ -716,8 +717,9 @@ static int tegra_drive_pinmux_set_pull_down(int pg,
        spin_lock_irqsave(&mux_lock, flags);
 
        reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
-       reg &= ~(0x1f << 12);
-       reg |= pull_down << 12;
+       reg &= ~(drive_pingroups[pg].drvdown_mask <<
+               drive_pingroups[pg].drvdown_offset);
+       reg |= pull_down << drive_pingroups[pg].drvdown_offset;
        pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
 
        spin_unlock_irqrestore(&mux_lock, flags);
@@ -730,6 +732,7 @@ static int tegra_drive_pinmux_set_pull_up(int pg,
 {
        unsigned long flags;
        u32 reg;
+
        if (pg < 0 || pg >=  drive_max)
                return -ERANGE;
 
@@ -739,8 +742,9 @@ static int tegra_drive_pinmux_set_pull_up(int pg,
        spin_lock_irqsave(&mux_lock, flags);
 
        reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
-       reg &= ~(0x1f << 20);
-       reg |= pull_up << 20;
+       reg &= ~(drive_pingroups[pg].drvup_mask <<
+               drive_pingroups[pg].drvup_offset);
+       reg |= pull_up << drive_pingroups[pg].drvup_offset;
        pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
 
        spin_unlock_irqrestore(&mux_lock, flags);