|
59 | 59 | #define GPPUDCLK0 0x98 /* Pin Pull-up/down Enable Clock */ |
60 | 60 | #define GP_GPIO_PUP_PDN_CNTRL_REG0 0xe4 /* 2711 Pin Pull-up/down select */ |
61 | 61 |
|
| 62 | +/* 2711 has a different mechanism for pin pull-up/down/enable */ |
| 63 | +#define GPPUPPDN0 0xe4 /* Pin pull-up/down for pins 15:0 */ |
| 64 | +#define GPPUPPDN1 0xe8 /* Pin pull-up/down for pins 31:16 */ |
| 65 | +#define GPPUPPDN2 0xec /* Pin pull-up/down for pins 47:32 */ |
| 66 | +#define GPPUPPDN3 0xf0 /* Pin pull-up/down for pins 57:48 */ |
| 67 | + |
62 | 68 | #define FSEL_REG(p) (GPFSEL0 + (((p) / 10) * 4)) |
63 | 69 | #define FSEL_SHIFT(p) (((p) % 10) * 3) |
64 | 70 | #define GPIO_REG_OFFSET(p) ((p) / 32) |
@@ -915,21 +921,45 @@ static void bcm2835_pull_config_set(struct bcm2835_pinctrl *pc, |
915 | 921 | unsigned int pin, unsigned int arg) |
916 | 922 | { |
917 | 923 | u32 off, bit; |
918 | | - |
919 | | - off = GPIO_REG_OFFSET(pin); |
920 | | - bit = GPIO_REG_SHIFT(pin); |
921 | | - |
922 | | - bcm2835_gpio_wr(pc, GPPUD, arg & 3); |
923 | | - /* |
924 | | - * BCM2835 datasheet say to wait 150 cycles, but not of what. |
925 | | - * But the VideoCore firmware delay for this operation |
926 | | - * based nearly on the same amount of VPU cycles and this clock |
927 | | - * runs at 250 MHz. |
928 | | - */ |
929 | | - udelay(1); |
930 | | - bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); |
931 | | - udelay(1); |
932 | | - bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); |
| 924 | + /* BCM2835, BCM2836 & BCM2837 return 'gpio' for this unused register */ |
| 925 | + int is_2835 = bcm2835_gpio_rd(pc, GPPUPPDN3) == 0x6770696f; |
| 926 | + |
| 927 | + if (is_2835) { |
| 928 | + off = GPIO_REG_OFFSET(pin); |
| 929 | + bit = GPIO_REG_SHIFT(pin); |
| 930 | + /* |
| 931 | + * BCM2835 datasheet say to wait 150 cycles, but not of what. |
| 932 | + * But the VideoCore firmware delay for this operation |
| 933 | + * based nearly on the same amount of VPU cycles and this clock |
| 934 | + * runs at 250 MHz. |
| 935 | + */ |
| 936 | + bcm2835_gpio_wr(pc, GPPUD, arg & 3); |
| 937 | + udelay(1); |
| 938 | + bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); |
| 939 | + udelay(1); |
| 940 | + bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); |
| 941 | + } else { |
| 942 | + u32 reg; |
| 943 | + int lsb; |
| 944 | + |
| 945 | + off = (pin >> 4); |
| 946 | + if (off > 3) |
| 947 | + return; |
| 948 | + lsb = (pin & 0xf) << 1; |
| 949 | + |
| 950 | + /* The up/down semantics are reversed compared to BCM2835. |
| 951 | + * Instead of updating all the device tree files, translate the |
| 952 | + * values here. |
| 953 | + */ |
| 954 | + if (arg == 2) |
| 955 | + arg = 1; |
| 956 | + else if (arg == 1) |
| 957 | + arg = 2; |
| 958 | + reg = bcm2835_gpio_rd(pc, GPPUPPDN0 + (off *4)); |
| 959 | + reg &= ~(0x3 << lsb); |
| 960 | + reg |= (arg & 3) << lsb; |
| 961 | + bcm2835_gpio_wr(pc, GPPUPPDN0 + (off * 4), reg); |
| 962 | + } |
933 | 963 | } |
934 | 964 |
|
935 | 965 | static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev, |
|
0 commit comments