diff options
| author | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2013-03-15 20:50:43 +0100 | 
|---|---|---|
| committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2013-03-15 20:50:43 +0100 | 
| commit | b27673ccbd3d5435319b5c09c3e7061f559f925d (patch) | |
| tree | 24c58f5a1e950ec107f40690032ac89c62d3ad83 /arch/arm/cpu/tegra30-common/pinmux.c | |
| parent | 6579d15c58e2b6b051f126ea8b77dd767252aa14 (diff) | |
| parent | 477393e7875cf4261f107fdfb8887309ea7fc3f7 (diff) | |
| download | olio-uboot-2014.01-b27673ccbd3d5435319b5c09c3e7061f559f925d.tar.xz olio-uboot-2014.01-b27673ccbd3d5435319b5c09c3e7061f559f925d.zip | |
Merge branch 'u-boot-tegra/master' into 'u-boot-arm/master'
Diffstat (limited to 'arch/arm/cpu/tegra30-common/pinmux.c')
| -rw-r--r-- | arch/arm/cpu/tegra30-common/pinmux.c | 190 | 
1 files changed, 189 insertions, 1 deletions
| diff --git a/arch/arm/cpu/tegra30-common/pinmux.c b/arch/arm/cpu/tegra30-common/pinmux.c index 122665fd3..eecf0580b 100644 --- a/arch/arm/cpu/tegra30-common/pinmux.c +++ b/arch/arm/cpu/tegra30-common/pinmux.c @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved. + * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.   *   * This program is free software; you can redistribute it and/or modify it   * under the terms and conditions of the GNU General Public License, @@ -38,6 +38,19 @@ struct tegra_pingroup_desc {  #define PMUX_LOCK_SHIFT		7  #define PMUX_IO_RESET_SHIFT	8 +#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)	\  	{						\ @@ -504,3 +517,178 @@ 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)); + +	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)); + +	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]); +} |