Haavard Skinnemoen | 610b362 | 2008-08-29 21:09:49 +0200 | [diff] [blame] | 1 | AVR32 Port multiplexer configuration |
| 2 | ==================================== |
| 3 | |
| 4 | On AVR32 chips, most external I/O pins are routed through a port |
| 5 | multiplexer. There are currently two kinds of port multiplexer |
| 6 | hardware around with different register interfaces: |
| 7 | |
| 8 | * PIO (AT32AP700x; this is also used on ARM AT91 chips) |
| 9 | * GPIO (all other AVR32 chips) |
| 10 | |
| 11 | The "PIO" variant supports multiplexing up to two peripherals per pin |
| 12 | in addition to GPIO (software control). Each pin has configurable |
| 13 | pull-up, glitch filter, interrupt and multi-drive capabilities. |
| 14 | |
| 15 | The "GPIO" variant supports multiplexing up to four peripherals per |
| 16 | pin in addition to GPIO. Each pin has configurable |
| 17 | pull-up/pull-down/buskeeper, glitch filter, interrupt, open-drain and |
| 18 | schmitt-trigger capabilities, as well as configurable drive strength |
| 19 | and slew rate control. |
| 20 | |
| 21 | Both controllers are configured using the same API, but the functions |
| 22 | may accept different values for some parameters depending on the |
| 23 | actual portmux implementation, and some parameters may be ignored by |
| 24 | one of the implementation (e.g. the "PIO" implementation will ignore |
| 25 | the drive strength flags since the hardware doesn't support |
| 26 | configurable drive strength.) |
| 27 | |
| 28 | Selecting the portmux implementation |
| 29 | ------------------------------------ |
| 30 | Since u-boot is lacking a Kconfig-style configuration engine, the |
| 31 | portmux implementation must be selected manually by defining one of |
| 32 | the following symbols: |
| 33 | |
| 34 | CONFIG_PORTMUX_PIO |
| 35 | CONFIG_PORTMUX_GPIO |
| 36 | |
| 37 | depending on which implementation the chip in question uses. |
| 38 | |
| 39 | Identifying pins |
| 40 | ---------------- |
| 41 | The portmux configuration functions described below identify the pins |
| 42 | to act on based on two parameters: A "port" (i.e. a block of pins |
| 43 | that somehow belong together) and a pin mask. Both are defined in an |
| 44 | implementation-specific manner. |
| 45 | |
| 46 | The available ports are defined on the form |
| 47 | |
| 48 | #define PORTMUX_PORT_A (something) |
| 49 | |
| 50 | where "A" matches the identifier given in the chip's data sheet, and |
| 51 | "something" is whatever the portmux implementation needs to identify |
| 52 | the port (usually a memory address). |
| 53 | |
| 54 | The pin mask is a bitmask where each '1' bit indicates a pin to apply |
| 55 | the current operation to. The width of the bitmask may vary from port |
| 56 | to port, but it is never wider than 32 bits (which is the width of |
| 57 | 'unsigned long' on avr32). |
| 58 | |
| 59 | Selecting functions |
| 60 | ------------------- |
| 61 | Each pin can either be assigned to one of a predefined set of on-chip |
| 62 | peripherals, or it can be set up to be controlled by software. For the |
| 63 | former case, the portmux implementation defines an enum containing all |
| 64 | the possible peripheral functions that can be selected. For example, |
| 65 | the PIO implementation, which allows multiplexing two peripherals per |
| 66 | pin, defines it like this: |
| 67 | |
| 68 | enum portmux_function { |
| 69 | PORTMUX_FUNC_A, |
| 70 | PORTMUX_FUNC_B, |
| 71 | }; |
| 72 | |
| 73 | To configure a set of pins to be connected to a given peripheral |
| 74 | function, the following function is used. |
| 75 | |
| 76 | void portmux_select_peripheral(void *port, unsigned long pin_mask, |
| 77 | enum portmux_function func, unsigned long flags); |
| 78 | |
| 79 | To configure a set of pins to be controlled by software (GPIO), the |
| 80 | following function is used. In this case, no "function" argument is |
| 81 | required since "GPIO" is a function in its own right. |
| 82 | |
| 83 | void portmux_select_gpio(void *port, unsigned int pin_mask, |
| 84 | unsigned long flags); |
| 85 | |
| 86 | Both of these functions take a "flags" parameter which may be used to |
| 87 | alter the default configuration of the pin. This is a bitmask of |
| 88 | various flags defined in an implementation-specific way, but the names |
| 89 | of the flags are the same on all implementations. |
| 90 | |
| 91 | PORTMUX_DIR_OUTPUT |
| 92 | PORTMUX_DIR_INPUT |
| 93 | |
Thomas Weber | 6726631 | 2012-03-24 22:44:01 +0000 | [diff] [blame] | 94 | These mutually-exclusive flags configure the initial direction of the |
Haavard Skinnemoen | 610b362 | 2008-08-29 21:09:49 +0200 | [diff] [blame] | 95 | pins. PORTMUX_DIR_OUTPUT means that the pins are driven by the CPU, |
| 96 | while PORTMUX_DIR_INPUT means that the pins are tristated by the CPU. |
| 97 | These flags are ignored by portmux_select_peripheral(). |
| 98 | |
| 99 | PORTMUX_INIT_HIGH |
| 100 | PORTMUX_INIT_LOW |
| 101 | |
| 102 | These mutually-exclusive flags configure the initial state of the |
| 103 | pins: High (Vdd) or low (Vss). They are only effective when |
| 104 | portmux_select_gpio() is called with the PORTMUX_DIR_OUTPUT flag set. |
| 105 | |
| 106 | PORTMUX_PULL_UP |
| 107 | PORTMUX_PULL_DOWN |
| 108 | PORTMUX_BUSKEEPER |
| 109 | |
| 110 | These mutually-exclusive flags are used to enable any on-chip CMOS |
| 111 | resistors connected to the pins. PORTMUX_PULL_UP causes the pins to be |
| 112 | pulled up to Vdd, PORTMUX_PULL_DOWN causes the pins to be pulled down |
| 113 | to Vss, and PORTMUX_BUSKEEPER will keep the pins in whatever state |
| 114 | they were left in by whatever was driving them last. If none of the |
| 115 | flags are specified, the pins are left floating if no one are driving |
| 116 | them; this is only recommended for always-output pins (e.g. extern |
| 117 | address and control lines driven by the CPU.) |
| 118 | |
| 119 | Note that the "PIO" implementation will silently ignore the |
| 120 | PORTMUX_PULL_DOWN flag and interpret PORTMUX_BUSKEEPER as |
| 121 | PORTMUX_PULL_UP. |
| 122 | |
| 123 | PORTMUX_DRIVE_MIN |
| 124 | PORTMUX_DRIVE_LOW |
| 125 | PORTMUX_DRIVE_HIGH |
| 126 | PORTMUX_DRIVE_MAX |
| 127 | |
Thomas Weber | 6726631 | 2012-03-24 22:44:01 +0000 | [diff] [blame] | 128 | These mutually-exclusive flags determine the drive strength of the |
Haavard Skinnemoen | 610b362 | 2008-08-29 21:09:49 +0200 | [diff] [blame] | 129 | pins. PORTMUX_DRIVE_MIN will give low power-consumption, but may cause |
| 130 | corruption of high-speed signals. PORTMUX_DRIVE_MAX will give high |
| 131 | power-consumption, but may be necessary on pins toggling at very high |
| 132 | speeds. PORTMUX_DRIVE_LOW and PORTMUX_DRIVE_HIGH specify something in |
| 133 | between the other two. |
| 134 | |
| 135 | Note that setting the drive strength too high may cause excessive |
| 136 | overshoot and EMI problems, which may in turn cause signal corruption. |
| 137 | Also note that the "PIO" implementation will silently ignore these |
| 138 | flags. |
| 139 | |
| 140 | PORTMUX_OPEN_DRAIN |
| 141 | |
| 142 | This flag will configure the pins as "open drain", i.e. setting the |
| 143 | pin state to 0 will drive it low, while setting it to 1 will leave it |
| 144 | floating (or, in most cases, let it be pulled high by an internal or |
| 145 | external pull-up resistor.) In the data sheet for chips using the |
| 146 | "PIO" variant, this mode is called "multi-driver". |
| 147 | |
| 148 | Enabling specific peripherals |
| 149 | ----------------------------- |
| 150 | In addition to the above functions, each chip provides a set of |
| 151 | functions for setting up the port multiplexer to use a given |
| 152 | peripheral. The following are some of the functions available. |
| 153 | |
| 154 | All the functions below take a "drive_strength" parameter, which must |
| 155 | be one of the PORTMUX_DRIVE_x flags specified above. Any other |
| 156 | portmux flags will be silently filtered out. |
| 157 | |
| 158 | To set up the External Bus Interface (EBI), call |
| 159 | |
| 160 | void portmux_enable_ebi(unsigned int bus_width, |
| 161 | unsigned long flags, unsigned long drive_strength) |
| 162 | |
| 163 | where "bus_width" must be either 16 or 32. "flags" can be any |
| 164 | combination of the following flags. |
| 165 | |
| 166 | PORTMUX_EBI_CS(x) /* Enable chip select x */ |
| 167 | PORTMUX_EBI_NAND /* Enable NAND flash interface */ |
| 168 | PORTMUX_EBI_CF(x) /* Enable CompactFlash interface x */ |
| 169 | PORTMUX_EBI_NWAIT /* Enable NWAIT signal */ |
| 170 | |
| 171 | To set up a USART, call |
| 172 | |
| 173 | void portmux_enable_usartX(unsigned long drive_strength); |
| 174 | |
| 175 | where X is replaced by the USART instance to be configured. |
| 176 | |
| 177 | To set up an ethernet MAC: |
| 178 | |
| 179 | void portmux_enable_macbX(unsigned long flags, |
| 180 | unsigned long drive_strength); |
| 181 | |
| 182 | where X is replaced by the MACB instance to be configured. "flags" can |
| 183 | be any combination of the following flags. |
| 184 | |
| 185 | PORTMUX_MACB_RMII /* Just set up the RMII interface */ |
| 186 | PORTMUX_MACB_MII /* Set up full MII interface */ |
| 187 | PORTMUX_MACB_SPEED /* Enable the SPEED pin */ |
| 188 | |
| 189 | To set up the MMC controller: |
| 190 | |
| 191 | void portmux_enable_mmci(unsigned long slot, unsigned long flags |
| 192 | unsigned long drive_strength); |
| 193 | |
| 194 | where "slot" identifies which of the alternative SD card slots to |
| 195 | enable. "flags" can be any combination of the following flags: |
| 196 | |
| 197 | PORTMUX_MMCI_4BIT /* Enable 4-bit SD card interface */ |
| 198 | PORTMUX_MMCI_8BIT /* Enable 8-bit MMC+ interface */ |
| 199 | PORTMUX_MMCI_EXT_PULLUP /* Board has external pull-ups */ |
| 200 | |
| 201 | To set up a SPI controller: |
| 202 | |
| 203 | void portmux_enable_spiX(unsigned long cs_mask, |
| 204 | unsigned long drive_strength); |
| 205 | |
| 206 | where X is replaced by the SPI instance to be configured. "cs_mask" is |
| 207 | a 4-bit bitmask specifying which of the four standard chip select |
| 208 | lines to set up as GPIOs. |