mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
pinctrl: iproc-gpio: Fix incorrect pinconf configurations
Fix drive strength for AON/CRMU controller; fix pull-up/down setting
for CCM/CDRU controller.
Fixes: 616043d58a
("pinctrl: Rename gpio driver from cygnus to iproc")
Signed-off-by: Li Jin <li.jin@broadcom.com>
Link: https://lore.kernel.org/r/1567054348-19685-2-git-send-email-srinath.mannam@broadcom.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
1fdbc02ce1
commit
398a1f50e3
@ -54,8 +54,12 @@
|
|||||||
/* drive strength control for ASIU GPIO */
|
/* drive strength control for ASIU GPIO */
|
||||||
#define IPROC_GPIO_ASIU_DRV0_CTRL_OFFSET 0x58
|
#define IPROC_GPIO_ASIU_DRV0_CTRL_OFFSET 0x58
|
||||||
|
|
||||||
/* drive strength control for CCM/CRMU (AON) GPIO */
|
/* pinconf for CCM GPIO */
|
||||||
#define IPROC_GPIO_DRV0_CTRL_OFFSET 0x00
|
#define IPROC_GPIO_PULL_DN_OFFSET 0x10
|
||||||
|
#define IPROC_GPIO_PULL_UP_OFFSET 0x14
|
||||||
|
|
||||||
|
/* pinconf for CRMU(aon) GPIO and CCM GPIO*/
|
||||||
|
#define IPROC_GPIO_DRV_CTRL_OFFSET 0x00
|
||||||
|
|
||||||
#define GPIO_BANK_SIZE 0x200
|
#define GPIO_BANK_SIZE 0x200
|
||||||
#define NGPIOS_PER_BANK 32
|
#define NGPIOS_PER_BANK 32
|
||||||
@ -76,6 +80,12 @@ enum iproc_pinconf_param {
|
|||||||
IPROC_PINCON_MAX,
|
IPROC_PINCON_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum iproc_pinconf_ctrl_type {
|
||||||
|
IOCTRL_TYPE_AON = 1,
|
||||||
|
IOCTRL_TYPE_CDRU,
|
||||||
|
IOCTRL_TYPE_INVALID,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iproc GPIO core
|
* Iproc GPIO core
|
||||||
*
|
*
|
||||||
@ -100,6 +110,7 @@ struct iproc_gpio {
|
|||||||
|
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
void __iomem *io_ctrl;
|
void __iomem *io_ctrl;
|
||||||
|
enum iproc_pinconf_ctrl_type io_ctrl_type;
|
||||||
|
|
||||||
raw_spinlock_t lock;
|
raw_spinlock_t lock;
|
||||||
|
|
||||||
@ -461,20 +472,44 @@ static const struct pinctrl_ops iproc_pctrl_ops = {
|
|||||||
static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
|
static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
|
||||||
bool disable, bool pull_up)
|
bool disable, bool pull_up)
|
||||||
{
|
{
|
||||||
|
void __iomem *base;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
unsigned int shift;
|
||||||
|
u32 val_1, val_2;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&chip->lock, flags);
|
raw_spin_lock_irqsave(&chip->lock, flags);
|
||||||
|
if (chip->io_ctrl_type == IOCTRL_TYPE_CDRU) {
|
||||||
|
base = chip->io_ctrl;
|
||||||
|
shift = IPROC_GPIO_SHIFT(gpio);
|
||||||
|
|
||||||
if (disable) {
|
val_1 = readl(base + IPROC_GPIO_PULL_UP_OFFSET);
|
||||||
iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio, false);
|
val_2 = readl(base + IPROC_GPIO_PULL_DN_OFFSET);
|
||||||
|
if (disable) {
|
||||||
|
/* no pull-up or pull-down */
|
||||||
|
val_1 &= ~BIT(shift);
|
||||||
|
val_2 &= ~BIT(shift);
|
||||||
|
} else if (pull_up) {
|
||||||
|
val_1 |= BIT(shift);
|
||||||
|
val_2 &= ~BIT(shift);
|
||||||
|
} else {
|
||||||
|
val_1 &= ~BIT(shift);
|
||||||
|
val_2 |= BIT(shift);
|
||||||
|
}
|
||||||
|
writel(val_1, base + IPROC_GPIO_PULL_UP_OFFSET);
|
||||||
|
writel(val_2, base + IPROC_GPIO_PULL_DN_OFFSET);
|
||||||
} else {
|
} else {
|
||||||
iproc_set_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio,
|
if (disable) {
|
||||||
pull_up);
|
iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio,
|
||||||
iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio, true);
|
false);
|
||||||
|
} else {
|
||||||
|
iproc_set_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio,
|
||||||
|
pull_up);
|
||||||
|
iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio,
|
||||||
|
true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&chip->lock, flags);
|
raw_spin_unlock_irqrestore(&chip->lock, flags);
|
||||||
|
|
||||||
dev_dbg(chip->dev, "gpio:%u set pullup:%d\n", gpio, pull_up);
|
dev_dbg(chip->dev, "gpio:%u set pullup:%d\n", gpio, pull_up);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -483,14 +518,35 @@ static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
|
|||||||
static void iproc_gpio_get_pull(struct iproc_gpio *chip, unsigned gpio,
|
static void iproc_gpio_get_pull(struct iproc_gpio *chip, unsigned gpio,
|
||||||
bool *disable, bool *pull_up)
|
bool *disable, bool *pull_up)
|
||||||
{
|
{
|
||||||
|
void __iomem *base;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
unsigned int shift;
|
||||||
|
u32 val_1, val_2;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&chip->lock, flags);
|
raw_spin_lock_irqsave(&chip->lock, flags);
|
||||||
*disable = !iproc_get_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio);
|
if (chip->io_ctrl_type == IOCTRL_TYPE_CDRU) {
|
||||||
*pull_up = iproc_get_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio);
|
base = chip->io_ctrl;
|
||||||
|
shift = IPROC_GPIO_SHIFT(gpio);
|
||||||
|
|
||||||
|
val_1 = readl(base + IPROC_GPIO_PULL_UP_OFFSET) & BIT(shift);
|
||||||
|
val_2 = readl(base + IPROC_GPIO_PULL_DN_OFFSET) & BIT(shift);
|
||||||
|
|
||||||
|
*pull_up = val_1 ? true : false;
|
||||||
|
*disable = (val_1 | val_2) ? false : true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
*disable = !iproc_get_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio);
|
||||||
|
*pull_up = iproc_get_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio);
|
||||||
|
}
|
||||||
raw_spin_unlock_irqrestore(&chip->lock, flags);
|
raw_spin_unlock_irqrestore(&chip->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DRV_STRENGTH_OFFSET(gpio, bit, type) ((type) == IOCTRL_TYPE_AON ? \
|
||||||
|
((2 - (bit)) * 4 + IPROC_GPIO_DRV_CTRL_OFFSET) : \
|
||||||
|
((type) == IOCTRL_TYPE_CDRU) ? \
|
||||||
|
((bit) * 4 + IPROC_GPIO_DRV_CTRL_OFFSET) : \
|
||||||
|
((bit) * 4 + IPROC_GPIO_REG(gpio, IPROC_GPIO_ASIU_DRV0_CTRL_OFFSET)))
|
||||||
|
|
||||||
static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
|
static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
|
||||||
unsigned strength)
|
unsigned strength)
|
||||||
{
|
{
|
||||||
@ -505,11 +561,8 @@ static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
|
|||||||
|
|
||||||
if (chip->io_ctrl) {
|
if (chip->io_ctrl) {
|
||||||
base = chip->io_ctrl;
|
base = chip->io_ctrl;
|
||||||
offset = IPROC_GPIO_DRV0_CTRL_OFFSET;
|
|
||||||
} else {
|
} else {
|
||||||
base = chip->base;
|
base = chip->base;
|
||||||
offset = IPROC_GPIO_REG(gpio,
|
|
||||||
IPROC_GPIO_ASIU_DRV0_CTRL_OFFSET);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shift = IPROC_GPIO_SHIFT(gpio);
|
shift = IPROC_GPIO_SHIFT(gpio);
|
||||||
@ -520,11 +573,11 @@ static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
|
|||||||
raw_spin_lock_irqsave(&chip->lock, flags);
|
raw_spin_lock_irqsave(&chip->lock, flags);
|
||||||
strength = (strength / 2) - 1;
|
strength = (strength / 2) - 1;
|
||||||
for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
|
for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
|
||||||
|
offset = DRV_STRENGTH_OFFSET(gpio, i, chip->io_ctrl_type);
|
||||||
val = readl(base + offset);
|
val = readl(base + offset);
|
||||||
val &= ~BIT(shift);
|
val &= ~BIT(shift);
|
||||||
val |= ((strength >> i) & 0x1) << shift;
|
val |= ((strength >> i) & 0x1) << shift;
|
||||||
writel(val, base + offset);
|
writel(val, base + offset);
|
||||||
offset += 4;
|
|
||||||
}
|
}
|
||||||
raw_spin_unlock_irqrestore(&chip->lock, flags);
|
raw_spin_unlock_irqrestore(&chip->lock, flags);
|
||||||
|
|
||||||
@ -541,11 +594,8 @@ static int iproc_gpio_get_strength(struct iproc_gpio *chip, unsigned gpio,
|
|||||||
|
|
||||||
if (chip->io_ctrl) {
|
if (chip->io_ctrl) {
|
||||||
base = chip->io_ctrl;
|
base = chip->io_ctrl;
|
||||||
offset = IPROC_GPIO_DRV0_CTRL_OFFSET;
|
|
||||||
} else {
|
} else {
|
||||||
base = chip->base;
|
base = chip->base;
|
||||||
offset = IPROC_GPIO_REG(gpio,
|
|
||||||
IPROC_GPIO_ASIU_DRV0_CTRL_OFFSET);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shift = IPROC_GPIO_SHIFT(gpio);
|
shift = IPROC_GPIO_SHIFT(gpio);
|
||||||
@ -553,10 +603,10 @@ static int iproc_gpio_get_strength(struct iproc_gpio *chip, unsigned gpio,
|
|||||||
raw_spin_lock_irqsave(&chip->lock, flags);
|
raw_spin_lock_irqsave(&chip->lock, flags);
|
||||||
*strength = 0;
|
*strength = 0;
|
||||||
for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
|
for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
|
||||||
|
offset = DRV_STRENGTH_OFFSET(gpio, i, chip->io_ctrl_type);
|
||||||
val = readl(base + offset) & BIT(shift);
|
val = readl(base + offset) & BIT(shift);
|
||||||
val >>= shift;
|
val >>= shift;
|
||||||
*strength += (val << i);
|
*strength += (val << i);
|
||||||
offset += 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert to mA */
|
/* convert to mA */
|
||||||
@ -734,6 +784,7 @@ static int iproc_gpio_probe(struct platform_device *pdev)
|
|||||||
u32 ngpios, pinconf_disable_mask = 0;
|
u32 ngpios, pinconf_disable_mask = 0;
|
||||||
int irq, ret;
|
int irq, ret;
|
||||||
bool no_pinconf = false;
|
bool no_pinconf = false;
|
||||||
|
enum iproc_pinconf_ctrl_type io_ctrl_type = IOCTRL_TYPE_INVALID;
|
||||||
|
|
||||||
/* NSP does not support drive strength config */
|
/* NSP does not support drive strength config */
|
||||||
if (of_device_is_compatible(dev->of_node, "brcm,iproc-nsp-gpio"))
|
if (of_device_is_compatible(dev->of_node, "brcm,iproc-nsp-gpio"))
|
||||||
@ -764,8 +815,15 @@ static int iproc_gpio_probe(struct platform_device *pdev)
|
|||||||
dev_err(dev, "unable to map I/O memory\n");
|
dev_err(dev, "unable to map I/O memory\n");
|
||||||
return PTR_ERR(chip->io_ctrl);
|
return PTR_ERR(chip->io_ctrl);
|
||||||
}
|
}
|
||||||
|
if (of_device_is_compatible(dev->of_node,
|
||||||
|
"brcm,cygnus-ccm-gpio"))
|
||||||
|
io_ctrl_type = IOCTRL_TYPE_CDRU;
|
||||||
|
else
|
||||||
|
io_ctrl_type = IOCTRL_TYPE_AON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chip->io_ctrl_type = io_ctrl_type;
|
||||||
|
|
||||||
if (of_property_read_u32(dev->of_node, "ngpios", &ngpios)) {
|
if (of_property_read_u32(dev->of_node, "ngpios", &ngpios)) {
|
||||||
dev_err(&pdev->dev, "missing ngpios DT property\n");
|
dev_err(&pdev->dev, "missing ngpios DT property\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
Loading…
Reference in New Issue
Block a user