brcm2708: organize kernel patches
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.19 / 950-0502-pinctrl-bcm2835-Add-support-for-BCM2838.patch
1 From 9fdab9bd6324314cbdfe96a6da5edef6c29ed5e6 Mon Sep 17 00:00:00 2001
2 From: Tim Gover <tim.gover@raspberrypi.org>
3 Date: Wed, 9 Jan 2019 14:43:36 +0000
4 Subject: [PATCH] pinctrl-bcm2835: Add support for BCM2838
5
6 GPIO configuration on BCM2838 is largely the same as BCM2835 except for
7 the pull up/down configuration. The old mechanism has been replaced
8 by new registers which don't require the fixed delay.
9
10 Detect BCN2838 at run-time and use the new mechanism. Backwards
11 compatibility for the device-tree configuration has been retained.
12 ---
13 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 58 ++++++++++++++++++++-------
14 1 file changed, 44 insertions(+), 14 deletions(-)
15
16 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
17 +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
18 @@ -67,6 +67,12 @@
19 #define GPPUD 0x94 /* Pin Pull-up/down Enable */
20 #define GPPUDCLK0 0x98 /* Pin Pull-up/down Enable Clock */
21
22 +/* 2711 has a different mechanism for pin pull-up/down/enable */
23 +#define GPPUPPDN0 0xe4 /* Pin pull-up/down for pins 15:0 */
24 +#define GPPUPPDN1 0xe8 /* Pin pull-up/down for pins 31:16 */
25 +#define GPPUPPDN2 0xec /* Pin pull-up/down for pins 47:32 */
26 +#define GPPUPPDN3 0xf0 /* Pin pull-up/down for pins 57:48 */
27 +
28 #define FSEL_REG(p) (GPFSEL0 + (((p) / 10) * 4))
29 #define FSEL_SHIFT(p) (((p) % 10) * 3)
30 #define GPIO_REG_OFFSET(p) ((p) / 32)
31 @@ -915,21 +921,45 @@ static void bcm2835_pull_config_set(stru
32 unsigned int pin, unsigned int arg)
33 {
34 u32 off, bit;
35 + /* BCM2835, BCM2836 & BCM2837 return 'gpio' for this unused register */
36 + int is_2835 = bcm2835_gpio_rd(pc, GPPUPPDN3) == 0x6770696f;
37
38 - off = GPIO_REG_OFFSET(pin);
39 - bit = GPIO_REG_SHIFT(pin);
40 -
41 - bcm2835_gpio_wr(pc, GPPUD, arg & 3);
42 - /*
43 - * BCM2835 datasheet say to wait 150 cycles, but not of what.
44 - * But the VideoCore firmware delay for this operation
45 - * based nearly on the same amount of VPU cycles and this clock
46 - * runs at 250 MHz.
47 - */
48 - udelay(1);
49 - bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit));
50 - udelay(1);
51 - bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0);
52 + if (is_2835) {
53 + off = GPIO_REG_OFFSET(pin);
54 + bit = GPIO_REG_SHIFT(pin);
55 + /*
56 + * BCM2835 datasheet say to wait 150 cycles, but not of what.
57 + * But the VideoCore firmware delay for this operation
58 + * based nearly on the same amount of VPU cycles and this clock
59 + * runs at 250 MHz.
60 + */
61 + bcm2835_gpio_wr(pc, GPPUD, arg & 3);
62 + udelay(1);
63 + bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit));
64 + udelay(1);
65 + bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0);
66 + } else {
67 + u32 reg;
68 + int lsb;
69 +
70 + off = (pin >> 4);
71 + if (off > 3)
72 + return;
73 + lsb = (pin & 0xf) << 1;
74 +
75 + /* The up/down semantics are reversed compared to BCM2835.
76 + * Instead of updating all the device tree files, translate the
77 + * values here.
78 + */
79 + if (arg == 2)
80 + arg = 1;
81 + else if (arg == 1)
82 + arg = 2;
83 + reg = bcm2835_gpio_rd(pc, GPPUPPDN0 + (off *4));
84 + reg &= ~(0x3 << lsb);
85 + reg |= (arg & 3) << lsb;
86 + bcm2835_gpio_wr(pc, GPPUPPDN0 + (off * 4), reg);
87 + }
88 }
89
90 static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev,