uboot/arch/avr32/cpu/at32ap700x/portmux.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2006, 2008 Atmel Corporation
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6#include <common.h>
   7
   8#include <asm/io.h>
   9
  10#include <asm/arch/chip-features.h>
  11#include <asm/arch/hardware.h>
  12#include <asm/arch/portmux.h>
  13
  14/*
  15 * Lots of small functions here. We depend on --gc-sections getting
  16 * rid of the ones we don't need.
  17 */
  18void portmux_enable_ebi(unsigned int bus_width, unsigned int addr_width,
  19                unsigned long flags, unsigned long drive_strength)
  20{
  21        unsigned long porte_mask = 0;
  22
  23        if (bus_width > 16)
  24                portmux_select_peripheral(PORTMUX_PORT_E, 0xffff,
  25                                PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
  26        if (addr_width > 23)
  27                porte_mask |= (((1 << (addr_width - 23)) - 1) & 7) << 16;
  28        if (flags & PORTMUX_EBI_CS(2))
  29                porte_mask |= 1 << 25;
  30        if (flags & PORTMUX_EBI_CS(4))
  31                porte_mask |= 1 << 21;
  32        if (flags & PORTMUX_EBI_CS(5))
  33                porte_mask |= 1 << 22;
  34        if (flags & (PORTMUX_EBI_CF(0) | PORTMUX_EBI_CF(1)))
  35                porte_mask |= (1 << 19) | (1 << 20) | (1 << 23);
  36
  37        portmux_select_peripheral(PORTMUX_PORT_E, porte_mask,
  38                        PORTMUX_FUNC_A, 0);
  39
  40        if (flags & PORTMUX_EBI_NWAIT)
  41                portmux_select_peripheral(PORTMUX_PORT_E, 1 << 24,
  42                                PORTMUX_FUNC_A, PORTMUX_PULL_UP);
  43}
  44
  45#ifdef AT32AP700x_CHIP_HAS_MACB
  46void portmux_enable_macb0(unsigned long flags, unsigned long drive_strength)
  47{
  48        unsigned long portc_mask;
  49
  50        portc_mask = (1 << 3)   /* TXD0 */
  51                | (1 << 4)      /* TXD1 */
  52                | (1 << 7)      /* TXEN */
  53                | (1 << 8)      /* TXCK */
  54                | (1 << 9)      /* RXD0 */
  55                | (1 << 10)     /* RXD1 */
  56                | (1 << 13)     /* RXER */
  57                | (1 << 15)     /* RXDV */
  58                | (1 << 16)     /* MDC  */
  59                | (1 << 17);    /* MDIO */
  60
  61        if (flags & PORTMUX_MACB_MII)
  62                portc_mask |= (1 << 0)  /* COL  */
  63                        | (1 << 1)      /* CRS  */
  64                        | (1 << 2)      /* TXER */
  65                        | (1 << 5)      /* TXD2 */
  66                        | (1 << 6)      /* TXD3 */
  67                        | (1 << 11)     /* RXD2 */
  68                        | (1 << 12)     /* RXD3 */
  69                        | (1 << 14);    /* RXCK */
  70
  71        if (flags & PORTMUX_MACB_SPEED)
  72                portc_mask |= (1 << 18);/* SPD  */
  73
  74        /* REVISIT: Some pins are probably pure outputs */
  75        portmux_select_peripheral(PORTMUX_PORT_C, portc_mask,
  76                        PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
  77}
  78
  79void portmux_enable_macb1(unsigned long flags, unsigned long drive_strength)
  80{
  81        unsigned long portc_mask = 0;
  82        unsigned long portd_mask;
  83
  84        portd_mask = (1 << 13)  /* TXD0 */
  85                | (1 << 14)     /* TXD1 */
  86                | (1 << 11)     /* TXEN */
  87                | (1 << 12)     /* TXCK */
  88                | (1 << 10)     /* RXD0 */
  89                | (1 << 6)      /* RXD1 */
  90                | (1 << 5)      /* RXER */
  91                | (1 << 4)      /* RXDV */
  92                | (1 << 3)      /* MDC  */
  93                | (1 << 2);     /* MDIO */
  94
  95        if (flags & PORTMUX_MACB_MII)
  96                portc_mask = (1 << 19)  /* COL  */
  97                        | (1 << 23)     /* CRS  */
  98                        | (1 << 26)     /* TXER */
  99                        | (1 << 27)     /* TXD2 */
 100                        | (1 << 28)     /* TXD3 */
 101                        | (1 << 29)     /* RXD2 */
 102                        | (1 << 30)     /* RXD3 */
 103                        | (1 << 24);    /* RXCK */
 104
 105        if (flags & PORTMUX_MACB_SPEED)
 106                portd_mask |= (1 << 15);/* SPD  */
 107
 108        /* REVISIT: Some pins are probably pure outputs */
 109        portmux_select_peripheral(PORTMUX_PORT_D, portd_mask,
 110                        PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
 111        portmux_select_peripheral(PORTMUX_PORT_C, portc_mask,
 112                        PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
 113}
 114#endif
 115
 116#ifdef AT32AP700x_CHIP_HAS_MMCI
 117void portmux_enable_mmci(unsigned int slot, unsigned long flags,
 118                unsigned long drive_strength)
 119{
 120        unsigned long mask;
 121        unsigned long portmux_flags = PORTMUX_PULL_UP;
 122
 123        /* First, the common CLK signal. It doesn't need a pull-up */
 124        portmux_select_peripheral(PORTMUX_PORT_A, 1 << 10,
 125                        PORTMUX_FUNC_A, 0);
 126
 127        if (flags & PORTMUX_MMCI_EXT_PULLUP)
 128                portmux_flags = 0;
 129
 130        /* Then, the per-slot signals */
 131        switch (slot) {
 132        case 0:
 133                mask = (1 << 11) | (1 << 12);   /* CMD and DATA0 */
 134                if (flags & PORTMUX_MMCI_4BIT)
 135                        /* DATA1..DATA3 */
 136                        mask |= (1 << 13) | (1 << 14) | (1 << 15);
 137                portmux_select_peripheral(PORTMUX_PORT_A, mask,
 138                                PORTMUX_FUNC_A, portmux_flags);
 139                break;
 140        case 1:
 141                mask = (1 << 6) | (1 << 7);     /* CMD and DATA0 */
 142                if (flags & PORTMUX_MMCI_4BIT)
 143                        /* DATA1..DATA3 */
 144                        mask |= (1 << 8) | (1 << 9) | (1 << 10);
 145                portmux_select_peripheral(PORTMUX_PORT_B, mask,
 146                                PORTMUX_FUNC_B, portmux_flags);
 147                break;
 148        }
 149}
 150#endif
 151
 152#ifdef AT32AP700x_CHIP_HAS_SPI
 153void portmux_enable_spi0(unsigned long cs_mask, unsigned long drive_strength)
 154{
 155        unsigned long pin_mask;
 156
 157        /* MOSI and SCK */
 158        portmux_select_peripheral(PORTMUX_PORT_A, (1 << 1) | (1 << 2),
 159                        PORTMUX_FUNC_A, 0);
 160        /* MISO may float */
 161        portmux_select_peripheral(PORTMUX_PORT_A, 1 << 0,
 162                        PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
 163
 164        /* Set up NPCSx as GPIO outputs, initially high */
 165        pin_mask = (cs_mask & 7) << 3;
 166        if (cs_mask & (1 << 3))
 167                pin_mask |= 1 << 20;
 168
 169        portmux_select_gpio(PORTMUX_PORT_A, pin_mask,
 170                        PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH);
 171}
 172
 173void portmux_enable_spi1(unsigned long cs_mask, unsigned long drive_strength)
 174{
 175        /* MOSI and SCK */
 176        portmux_select_peripheral(PORTMUX_PORT_B, (1 << 1) | (1 << 5),
 177                        PORTMUX_FUNC_B, 0);
 178        /* MISO may float */
 179        portmux_select_peripheral(PORTMUX_PORT_B, 1 << 0,
 180                        PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
 181
 182        /* Set up NPCSx as GPIO outputs, initially high */
 183        portmux_select_gpio(PORTMUX_PORT_B, (cs_mask & 7) << 2,
 184                        PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH);
 185        portmux_select_gpio(PORTMUX_PORT_A, (cs_mask & 8) << (27 - 3),
 186                        PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH);
 187}
 188#endif
 189
 190#ifdef AT32AP700x_CHIP_HAS_LCDC
 191void portmux_enable_lcdc(int pin_config)
 192{
 193        unsigned long portc_mask = 0;
 194        unsigned long portd_mask = 0;
 195        unsigned long porte_mask = 0;
 196
 197        switch (pin_config) {
 198        case 0:
 199                portc_mask = (1 << 19)  /* CC     */
 200                        | (1 << 20)     /* HSYNC  */
 201                        | (1 << 21)     /* PCLK   */
 202                        | (1 << 22)     /* VSYNC  */
 203                        | (1 << 23)     /* DVAL   */
 204                        | (1 << 24)     /* MODE   */
 205                        | (1 << 25)     /* PWR    */
 206                        | (1 << 26)     /* DATA0  */
 207                        | (1 << 27)     /* DATA1  */
 208                        | (1 << 28)     /* DATA2  */
 209                        | (1 << 29)     /* DATA3  */
 210                        | (1 << 30)     /* DATA4  */
 211                        | (1 << 31);    /* DATA5  */
 212
 213                portd_mask = (1 << 0)   /* DATA6  */
 214                        | (1 << 1)      /* DATA7  */
 215                        | (1 << 2)      /* DATA8  */
 216                        | (1 << 3)      /* DATA9  */
 217                        | (1 << 4)      /* DATA10 */
 218                        | (1 << 5)      /* DATA11 */
 219                        | (1 << 6)      /* DATA12 */
 220                        | (1 << 7)      /* DATA13 */
 221                        | (1 << 8)      /* DATA14 */
 222                        | (1 << 9)      /* DATA15 */
 223                        | (1 << 10)     /* DATA16 */
 224                        | (1 << 11)     /* DATA17 */
 225                        | (1 << 12)     /* DATA18 */
 226                        | (1 << 13)     /* DATA19 */
 227                        | (1 << 14)     /* DATA20 */
 228                        | (1 << 15)     /* DATA21 */
 229                        | (1 << 16)     /* DATA22 */
 230                        | (1 << 17);    /* DATA23 */
 231                break;
 232
 233        case 1:
 234                portc_mask = (1 << 20)  /* HSYNC  */
 235                        | (1 << 21)     /* PCLK   */
 236                        | (1 << 22)     /* VSYNC  */
 237                        | (1 << 25)     /* PWR    */
 238                        | (1 << 31);    /* DATA5  */
 239
 240                portd_mask = (1 << 0)   /* DATA6  */
 241                        | (1 << 1)      /* DATA7  */
 242                        | (1 << 7)      /* DATA13 */
 243                        | (1 << 8)      /* DATA14 */
 244                        | (1 << 9)      /* DATA15 */
 245                        | (1 << 16)     /* DATA22 */
 246                        | (1 << 17);    /* DATA23 */
 247
 248                porte_mask = (1 << 0)   /* CC     */
 249                        | (1 << 1)      /* DVAL   */
 250                        | (1 << 2)      /* MODE   */
 251                        | (1 << 3)      /* DATA0  */
 252                        | (1 << 4)      /* DATA1  */
 253                        | (1 << 5)      /* DATA2  */
 254                        | (1 << 6)      /* DATA3  */
 255                        | (1 << 7)      /* DATA4  */
 256                        | (1 << 8)      /* DATA8  */
 257                        | (1 << 9)      /* DATA9  */
 258                        | (1 << 10)     /* DATA10 */
 259                        | (1 << 11)     /* DATA11 */
 260                        | (1 << 12)     /* DATA12 */
 261                        | (1 << 13)     /* DATA16 */
 262                        | (1 << 14)     /* DATA17 */
 263                        | (1 << 15)     /* DATA18 */
 264                        | (1 << 16)     /* DATA19 */
 265                        | (1 << 17)     /* DATA20 */
 266                        | (1 << 18);    /* DATA21 */
 267                break;
 268        }
 269
 270        /* REVISIT: Some pins are probably pure outputs */
 271        portmux_select_peripheral(PORTMUX_PORT_C, portc_mask,
 272                        PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
 273        portmux_select_peripheral(PORTMUX_PORT_D, portd_mask,
 274                        PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
 275        portmux_select_peripheral(PORTMUX_PORT_E, porte_mask,
 276                        PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
 277}
 278#endif
 279