uboot/arch/powerpc/cpu/ppc4xx/gpio.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2007-2008
   3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <asm/processor.h>
  10#include <asm/io.h>
  11#include <asm/ppc4xx-gpio.h>
  12
  13/* Only compile this file for boards with GPIO support */
  14#if defined(GPIO0_BASE)
  15
  16#if defined(CONFIG_SYS_4xx_GPIO_TABLE)
  17gpio_param_s const gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CONFIG_SYS_4xx_GPIO_TABLE;
  18#endif
  19
  20#if defined(GPIO0_OSRL)
  21/* Only some 4xx variants support alternate funtions on the GPIO's */
  22void gpio_config(int pin, int in_out, int gpio_alt, int out_val)
  23{
  24        u32 mask;
  25        u32 mask2;
  26        u32 val;
  27        u32 offs = 0;
  28        u32 offs2 = 0;
  29        int pin2 = pin << 1;
  30
  31        if (pin >= GPIO_MAX) {
  32                offs = 0x100;
  33                pin -= GPIO_MAX;
  34        }
  35
  36        if (pin >= GPIO_MAX/2) {
  37                offs2 = 0x4;
  38                pin2 = (pin - GPIO_MAX/2) << 1;
  39        }
  40
  41        mask = 0x80000000 >> pin;
  42        mask2 = 0xc0000000 >> pin2;
  43
  44        /* first set TCR to 0 */
  45        out_be32((void *)GPIO0_TCR + offs, in_be32((void *)GPIO0_TCR + offs) & ~mask);
  46
  47        if (in_out == GPIO_OUT) {
  48                val = in_be32((void *)GPIO0_OSRL + offs + offs2) & ~mask2;
  49                switch (gpio_alt) {
  50                case GPIO_ALT1:
  51                        val |= GPIO_ALT1_SEL >> pin2;
  52                        break;
  53                case GPIO_ALT2:
  54                        val |= GPIO_ALT2_SEL >> pin2;
  55                        break;
  56                case GPIO_ALT3:
  57                        val |= GPIO_ALT3_SEL >> pin2;
  58                        break;
  59                }
  60                out_be32((void *)GPIO0_OSRL + offs + offs2, val);
  61
  62                /* setup requested output value */
  63                if (out_val == GPIO_OUT_0)
  64                        out_be32((void *)GPIO0_OR + offs,
  65                                 in_be32((void *)GPIO0_OR + offs) & ~mask);
  66                else if (out_val == GPIO_OUT_1)
  67                        out_be32((void *)GPIO0_OR + offs,
  68                                 in_be32((void *)GPIO0_OR + offs) | mask);
  69
  70                /* now configure TCR to drive output if selected */
  71                out_be32((void *)GPIO0_TCR + offs,
  72                         in_be32((void *)GPIO0_TCR + offs) | mask);
  73        } else {
  74                val = in_be32((void *)GPIO0_ISR1L + offs + offs2) & ~mask2;
  75                val |= GPIO_IN_SEL >> pin2;
  76                out_be32((void *)GPIO0_ISR1L + offs + offs2, val);
  77        }
  78}
  79#endif /* GPIO_OSRL */
  80
  81void gpio_write_bit(int pin, int val)
  82{
  83        u32 offs = 0;
  84
  85        if (pin >= GPIO_MAX) {
  86                offs = 0x100;
  87                pin -= GPIO_MAX;
  88        }
  89
  90        if (val)
  91                out_be32((void *)GPIO0_OR + offs,
  92                         in_be32((void *)GPIO0_OR + offs) | GPIO_VAL(pin));
  93        else
  94                out_be32((void *)GPIO0_OR + offs,
  95                         in_be32((void *)GPIO0_OR + offs) & ~GPIO_VAL(pin));
  96}
  97
  98int gpio_read_out_bit(int pin)
  99{
 100        u32 offs = 0;
 101
 102        if (pin >= GPIO_MAX) {
 103                offs = 0x100;
 104                pin -= GPIO_MAX;
 105        }
 106
 107        return (in_be32((void *)GPIO0_OR + offs) & GPIO_VAL(pin) ? 1 : 0);
 108}
 109
 110int gpio_read_in_bit(int pin)
 111{
 112        u32 offs = 0;
 113
 114        if (pin >= GPIO_MAX) {
 115                offs = 0x100;
 116                pin -= GPIO_MAX;
 117        }
 118
 119        return (in_be32((void *)GPIO0_IR + offs) & GPIO_VAL(pin) ? 1 : 0);
 120}
 121
 122#if defined(CONFIG_SYS_4xx_GPIO_TABLE)
 123void gpio_set_chip_configuration(void)
 124{
 125        unsigned char i=0, j=0, offs=0, gpio_core;
 126        unsigned long reg, core_add;
 127
 128        for (gpio_core=0; gpio_core<GPIO_GROUP_MAX; gpio_core++) {
 129                j = 0;
 130                offs = 0;
 131                /* GPIO config of the GPIOs 0 to 31 */
 132                for (i=0; i<GPIO_MAX; i++, j++) {
 133                        if (i == GPIO_MAX/2) {
 134                                offs = 4;
 135                                j = i-16;
 136                        }
 137
 138                        core_add = gpio_tab[gpio_core][i].add;
 139
 140                        if ((gpio_tab[gpio_core][i].in_out == GPIO_IN) ||
 141                            (gpio_tab[gpio_core][i].in_out == GPIO_BI)) {
 142
 143                                switch (gpio_tab[gpio_core][i].alt_nb) {
 144                                case GPIO_SEL:
 145                                        break;
 146
 147                                case GPIO_ALT1:
 148                                        reg = in_be32((void *)GPIO_IS1(core_add+offs))
 149                                                & ~(GPIO_MASK >> (j*2));
 150                                        reg = reg | (GPIO_IN_SEL >> (j*2));
 151                                        out_be32((void *)GPIO_IS1(core_add+offs), reg);
 152                                        break;
 153
 154                                case GPIO_ALT2:
 155                                        reg = in_be32((void *)GPIO_IS2(core_add+offs))
 156                                                & ~(GPIO_MASK >> (j*2));
 157                                        reg = reg | (GPIO_IN_SEL >> (j*2));
 158                                        out_be32((void *)GPIO_IS2(core_add+offs), reg);
 159                                        break;
 160
 161                                case GPIO_ALT3:
 162                                        reg = in_be32((void *)GPIO_IS3(core_add+offs))
 163                                                & ~(GPIO_MASK >> (j*2));
 164                                        reg = reg | (GPIO_IN_SEL >> (j*2));
 165                                        out_be32((void *)GPIO_IS3(core_add+offs), reg);
 166                                        break;
 167                                }
 168                        }
 169
 170                        if ((gpio_tab[gpio_core][i].in_out == GPIO_OUT) ||
 171                            (gpio_tab[gpio_core][i].in_out == GPIO_BI)) {
 172
 173                                u32 gpio_alt_sel = 0;
 174
 175                                switch (gpio_tab[gpio_core][i].alt_nb) {
 176                                case GPIO_SEL:
 177                                        /*
 178                                         * Setup output value
 179                                         * 1 -> high level
 180                                         * 0 -> low level
 181                                         * else -> don't touch
 182                                         */
 183                                        reg = in_be32((void *)GPIO_OR(core_add));
 184                                        if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)
 185                                                reg |= (0x80000000 >> (i));
 186                                        else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)
 187                                                reg &= ~(0x80000000 >> (i));
 188                                        out_be32((void *)GPIO_OR(core_add), reg);
 189
 190                                        reg = in_be32((void *)GPIO_TCR(core_add)) |
 191                                                (0x80000000 >> (i));
 192                                        out_be32((void *)GPIO_TCR(core_add), reg);
 193
 194                                        reg = in_be32((void *)GPIO_OS(core_add+offs))
 195                                                & ~(GPIO_MASK >> (j*2));
 196                                        out_be32((void *)GPIO_OS(core_add+offs), reg);
 197                                        reg = in_be32((void *)GPIO_TS(core_add+offs))
 198                                                & ~(GPIO_MASK >> (j*2));
 199                                        out_be32((void *)GPIO_TS(core_add+offs), reg);
 200                                        break;
 201
 202                                case GPIO_ALT1:
 203                                        gpio_alt_sel = GPIO_ALT1_SEL;
 204                                        break;
 205
 206                                case GPIO_ALT2:
 207                                        gpio_alt_sel = GPIO_ALT2_SEL;
 208                                        break;
 209
 210                                case GPIO_ALT3:
 211                                        gpio_alt_sel = GPIO_ALT3_SEL;
 212                                        break;
 213                                }
 214
 215                                if (0 != gpio_alt_sel) {
 216                                        reg = in_be32((void *)GPIO_OS(core_add+offs))
 217                                                & ~(GPIO_MASK >> (j*2));
 218                                        reg = reg | (gpio_alt_sel >> (j*2));
 219                                        out_be32((void *)GPIO_OS(core_add+offs), reg);
 220
 221                                        if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1) {
 222                                                reg = in_be32((void *)GPIO_TCR(core_add))
 223                                                        | (0x80000000 >> (i));
 224                                                out_be32((void *)GPIO_TCR(core_add), reg);
 225                                                reg = in_be32((void *)GPIO_TS(core_add+offs))
 226                                                        & ~(GPIO_MASK >> (j*2));
 227                                                out_be32((void *)GPIO_TS(core_add+offs), reg);
 228                                        } else {
 229                                                reg = in_be32((void *)GPIO_TCR(core_add))
 230                                                        & ~(0x80000000 >> (i));
 231                                                out_be32((void *)GPIO_TCR(core_add), reg);
 232                                                reg = in_be32((void *)GPIO_TS(core_add+offs))
 233                                                        & ~(GPIO_MASK >> (j*2));
 234                                                reg = reg | (gpio_alt_sel >> (j*2));
 235                                                out_be32((void *)GPIO_TS(core_add+offs), reg);
 236                                        }
 237                                }
 238                        }
 239                }
 240        }
 241}
 242
 243#endif /* GPIO0_BASE */
 244#endif /* CONFIG_SYS_4xx_GPIO_TABLE */
 245