From 9fdab9bd6324314cbdfe96a6da5edef6c29ed5e6 Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Wed, 9 Jan 2019 14:43:36 +0000 Subject: [PATCH 549/806] pinctrl-bcm2835: Add support for BCM2838 GPIO configuration on BCM2838 is largely the same as BCM2835 except for the pull up/down configuration. The old mechanism has been replaced by new registers which don't require the fixed delay. Detect BCN2838 at run-time and use the new mechanism. Backwards compatibility for the device-tree configuration has been retained. --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 58 ++++++++++++++++++++------- 1 file changed, 44 insertions(+), 14 deletions(-) --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -67,6 +67,12 @@ #define GPPUD 0x94 /* Pin Pull-up/down Enable */ #define GPPUDCLK0 0x98 /* Pin Pull-up/down Enable Clock */ +/* 2711 has a different mechanism for pin pull-up/down/enable */ +#define GPPUPPDN0 0xe4 /* Pin pull-up/down for pins 15:0 */ +#define GPPUPPDN1 0xe8 /* Pin pull-up/down for pins 31:16 */ +#define GPPUPPDN2 0xec /* Pin pull-up/down for pins 47:32 */ +#define GPPUPPDN3 0xf0 /* Pin pull-up/down for pins 57:48 */ + #define FSEL_REG(p) (GPFSEL0 + (((p) / 10) * 4)) #define FSEL_SHIFT(p) (((p) % 10) * 3) #define GPIO_REG_OFFSET(p) ((p) / 32) @@ -915,21 +921,45 @@ static void bcm2835_pull_config_set(stru unsigned int pin, unsigned int arg) { u32 off, bit; + /* BCM2835, BCM2836 & BCM2837 return 'gpio' for this unused register */ + int is_2835 = bcm2835_gpio_rd(pc, GPPUPPDN3) == 0x6770696f; - off = GPIO_REG_OFFSET(pin); - bit = GPIO_REG_SHIFT(pin); - - bcm2835_gpio_wr(pc, GPPUD, arg & 3); - /* - * BCM2835 datasheet say to wait 150 cycles, but not of what. - * But the VideoCore firmware delay for this operation - * based nearly on the same amount of VPU cycles and this clock - * runs at 250 MHz. - */ - udelay(1); - bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); - udelay(1); - bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); + if (is_2835) { + off = GPIO_REG_OFFSET(pin); + bit = GPIO_REG_SHIFT(pin); + /* + * BCM2835 datasheet say to wait 150 cycles, but not of what. + * But the VideoCore firmware delay for this operation + * based nearly on the same amount of VPU cycles and this clock + * runs at 250 MHz. + */ + bcm2835_gpio_wr(pc, GPPUD, arg & 3); + udelay(1); + bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); + udelay(1); + bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); + } else { + u32 reg; + int lsb; + + off = (pin >> 4); + if (off > 3) + return; + lsb = (pin & 0xf) << 1; + + /* The up/down semantics are reversed compared to BCM2835. + * Instead of updating all the device tree files, translate the + * values here. + */ + if (arg == 2) + arg = 1; + else if (arg == 1) + arg = 2; + reg = bcm2835_gpio_rd(pc, GPPUPPDN0 + (off *4)); + reg &= ~(0x3 << lsb); + reg |= (arg & 3) << lsb; + bcm2835_gpio_wr(pc, GPPUPPDN0 + (off * 4), reg); + } } static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev,