1
0
Fork 0

Tegra114: Dalmore: Add pad config tables/code based on pinmux code

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>
utp
Tom Warren 2013-03-11 16:43:49 -07:00
parent 5647c03431
commit 477393e787
3 changed files with 292 additions and 14 deletions

View 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]);
}

View 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_ */

View File

@ -79,6 +79,18 @@
#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),