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>
This commit is contained in:
parent
5647c03431
commit
477393e787
3 changed files with 292 additions and 14 deletions
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in a new issue