mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-17 07:28:51 +09:00
![Haavard Skinnemoen](/assets/img/avatar_default.png)
- Separate the portmux configuration functionality from the GPIO pin control API. - Separate the controller-specific code from the chip-specific code. - Allow "ganged" port configuration (multiple pins at once). - Add more flexibility to the "canned" peripheral select functions: - Allow using more than 23 address bits, more chip selects, as well as NAND- and CF-specific pins. - Make the MACB SPEED pin optional, and choose between MII/RMII using a parameter instead of an #ifdef. - Make it possible to use other MMC slots than slot 0, and support different MMC/SDCard data bus widths. - Use more reasonable pull-up defaults; floating pins may consume a lot of power. - Get rid of some custom portmux code from the mimc200 board code. The old gpio/portmux API couldn't really handle its requirements, but the new one can. - Add documentation. The end result is slightly smaller code for all boards. Which isn't really the point, but at least it isn't any larger. This has been verified on ATSTK1002 and ATNGW100. I'd appreciate if the board maintainers could help me test this on their boards. In particular, the mimc200 port has lost a lot of code, so I'm hoping Mark can help me out. Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com> Cc: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com> Cc: Mark Jackson <mpfj@mimc.co.uk> Cc: Alex Raimondi <alex.raimondi@miromico.ch> Cc: Julien May <julien.may@miromico.ch> Changes since v1: * Enable pullup on NWAIT * Add missing include to portmux-pio.h * Rename CONFIG_PIO2 -> CONFIG_PORTMUX_PIO to match docs
209 lines
7.7 KiB
Plaintext
209 lines
7.7 KiB
Plaintext
AVR32 Port multiplexer configuration
|
|
====================================
|
|
|
|
On AVR32 chips, most external I/O pins are routed through a port
|
|
multiplexer. There are currently two kinds of port multiplexer
|
|
hardware around with different register interfaces:
|
|
|
|
* PIO (AT32AP700x; this is also used on ARM AT91 chips)
|
|
* GPIO (all other AVR32 chips)
|
|
|
|
The "PIO" variant supports multiplexing up to two peripherals per pin
|
|
in addition to GPIO (software control). Each pin has configurable
|
|
pull-up, glitch filter, interrupt and multi-drive capabilities.
|
|
|
|
The "GPIO" variant supports multiplexing up to four peripherals per
|
|
pin in addition to GPIO. Each pin has configurable
|
|
pull-up/pull-down/buskeeper, glitch filter, interrupt, open-drain and
|
|
schmitt-trigger capabilities, as well as configurable drive strength
|
|
and slew rate control.
|
|
|
|
Both controllers are configured using the same API, but the functions
|
|
may accept different values for some parameters depending on the
|
|
actual portmux implementation, and some parameters may be ignored by
|
|
one of the implementation (e.g. the "PIO" implementation will ignore
|
|
the drive strength flags since the hardware doesn't support
|
|
configurable drive strength.)
|
|
|
|
Selecting the portmux implementation
|
|
------------------------------------
|
|
Since u-boot is lacking a Kconfig-style configuration engine, the
|
|
portmux implementation must be selected manually by defining one of
|
|
the following symbols:
|
|
|
|
CONFIG_PORTMUX_PIO
|
|
CONFIG_PORTMUX_GPIO
|
|
|
|
depending on which implementation the chip in question uses.
|
|
|
|
Identifying pins
|
|
----------------
|
|
The portmux configuration functions described below identify the pins
|
|
to act on based on two parameters: A "port" (i.e. a block of pins
|
|
that somehow belong together) and a pin mask. Both are defined in an
|
|
implementation-specific manner.
|
|
|
|
The available ports are defined on the form
|
|
|
|
#define PORTMUX_PORT_A (something)
|
|
|
|
where "A" matches the identifier given in the chip's data sheet, and
|
|
"something" is whatever the portmux implementation needs to identify
|
|
the port (usually a memory address).
|
|
|
|
The pin mask is a bitmask where each '1' bit indicates a pin to apply
|
|
the current operation to. The width of the bitmask may vary from port
|
|
to port, but it is never wider than 32 bits (which is the width of
|
|
'unsigned long' on avr32).
|
|
|
|
Selecting functions
|
|
-------------------
|
|
Each pin can either be assigned to one of a predefined set of on-chip
|
|
peripherals, or it can be set up to be controlled by software. For the
|
|
former case, the portmux implementation defines an enum containing all
|
|
the possible peripheral functions that can be selected. For example,
|
|
the PIO implementation, which allows multiplexing two peripherals per
|
|
pin, defines it like this:
|
|
|
|
enum portmux_function {
|
|
PORTMUX_FUNC_A,
|
|
PORTMUX_FUNC_B,
|
|
};
|
|
|
|
To configure a set of pins to be connected to a given peripheral
|
|
function, the following function is used.
|
|
|
|
void portmux_select_peripheral(void *port, unsigned long pin_mask,
|
|
enum portmux_function func, unsigned long flags);
|
|
|
|
To configure a set of pins to be controlled by software (GPIO), the
|
|
following function is used. In this case, no "function" argument is
|
|
required since "GPIO" is a function in its own right.
|
|
|
|
void portmux_select_gpio(void *port, unsigned int pin_mask,
|
|
unsigned long flags);
|
|
|
|
Both of these functions take a "flags" parameter which may be used to
|
|
alter the default configuration of the pin. This is a bitmask of
|
|
various flags defined in an implementation-specific way, but the names
|
|
of the flags are the same on all implementations.
|
|
|
|
PORTMUX_DIR_OUTPUT
|
|
PORTMUX_DIR_INPUT
|
|
|
|
These mutually-exlusive flags configure the initial direction of the
|
|
pins. PORTMUX_DIR_OUTPUT means that the pins are driven by the CPU,
|
|
while PORTMUX_DIR_INPUT means that the pins are tristated by the CPU.
|
|
These flags are ignored by portmux_select_peripheral().
|
|
|
|
PORTMUX_INIT_HIGH
|
|
PORTMUX_INIT_LOW
|
|
|
|
These mutually-exclusive flags configure the initial state of the
|
|
pins: High (Vdd) or low (Vss). They are only effective when
|
|
portmux_select_gpio() is called with the PORTMUX_DIR_OUTPUT flag set.
|
|
|
|
PORTMUX_PULL_UP
|
|
PORTMUX_PULL_DOWN
|
|
PORTMUX_BUSKEEPER
|
|
|
|
These mutually-exclusive flags are used to enable any on-chip CMOS
|
|
resistors connected to the pins. PORTMUX_PULL_UP causes the pins to be
|
|
pulled up to Vdd, PORTMUX_PULL_DOWN causes the pins to be pulled down
|
|
to Vss, and PORTMUX_BUSKEEPER will keep the pins in whatever state
|
|
they were left in by whatever was driving them last. If none of the
|
|
flags are specified, the pins are left floating if no one are driving
|
|
them; this is only recommended for always-output pins (e.g. extern
|
|
address and control lines driven by the CPU.)
|
|
|
|
Note that the "PIO" implementation will silently ignore the
|
|
PORTMUX_PULL_DOWN flag and interpret PORTMUX_BUSKEEPER as
|
|
PORTMUX_PULL_UP.
|
|
|
|
PORTMUX_DRIVE_MIN
|
|
PORTMUX_DRIVE_LOW
|
|
PORTMUX_DRIVE_HIGH
|
|
PORTMUX_DRIVE_MAX
|
|
|
|
These mutually-exlusive flags determine the drive strength of the
|
|
pins. PORTMUX_DRIVE_MIN will give low power-consumption, but may cause
|
|
corruption of high-speed signals. PORTMUX_DRIVE_MAX will give high
|
|
power-consumption, but may be necessary on pins toggling at very high
|
|
speeds. PORTMUX_DRIVE_LOW and PORTMUX_DRIVE_HIGH specify something in
|
|
between the other two.
|
|
|
|
Note that setting the drive strength too high may cause excessive
|
|
overshoot and EMI problems, which may in turn cause signal corruption.
|
|
Also note that the "PIO" implementation will silently ignore these
|
|
flags.
|
|
|
|
PORTMUX_OPEN_DRAIN
|
|
|
|
This flag will configure the pins as "open drain", i.e. setting the
|
|
pin state to 0 will drive it low, while setting it to 1 will leave it
|
|
floating (or, in most cases, let it be pulled high by an internal or
|
|
external pull-up resistor.) In the data sheet for chips using the
|
|
"PIO" variant, this mode is called "multi-driver".
|
|
|
|
Enabling specific peripherals
|
|
-----------------------------
|
|
In addition to the above functions, each chip provides a set of
|
|
functions for setting up the port multiplexer to use a given
|
|
peripheral. The following are some of the functions available.
|
|
|
|
All the functions below take a "drive_strength" parameter, which must
|
|
be one of the PORTMUX_DRIVE_x flags specified above. Any other
|
|
portmux flags will be silently filtered out.
|
|
|
|
To set up the External Bus Interface (EBI), call
|
|
|
|
void portmux_enable_ebi(unsigned int bus_width,
|
|
unsigned long flags, unsigned long drive_strength)
|
|
|
|
where "bus_width" must be either 16 or 32. "flags" can be any
|
|
combination of the following flags.
|
|
|
|
PORTMUX_EBI_CS(x) /* Enable chip select x */
|
|
PORTMUX_EBI_NAND /* Enable NAND flash interface */
|
|
PORTMUX_EBI_CF(x) /* Enable CompactFlash interface x */
|
|
PORTMUX_EBI_NWAIT /* Enable NWAIT signal */
|
|
|
|
To set up a USART, call
|
|
|
|
void portmux_enable_usartX(unsigned long drive_strength);
|
|
|
|
where X is replaced by the USART instance to be configured.
|
|
|
|
To set up an ethernet MAC:
|
|
|
|
void portmux_enable_macbX(unsigned long flags,
|
|
unsigned long drive_strength);
|
|
|
|
where X is replaced by the MACB instance to be configured. "flags" can
|
|
be any combination of the following flags.
|
|
|
|
PORTMUX_MACB_RMII /* Just set up the RMII interface */
|
|
PORTMUX_MACB_MII /* Set up full MII interface */
|
|
PORTMUX_MACB_SPEED /* Enable the SPEED pin */
|
|
|
|
To set up the MMC controller:
|
|
|
|
void portmux_enable_mmci(unsigned long slot, unsigned long flags
|
|
unsigned long drive_strength);
|
|
|
|
where "slot" identifies which of the alternative SD card slots to
|
|
enable. "flags" can be any combination of the following flags:
|
|
|
|
PORTMUX_MMCI_4BIT /* Enable 4-bit SD card interface */
|
|
PORTMUX_MMCI_8BIT /* Enable 8-bit MMC+ interface */
|
|
PORTMUX_MMCI_EXT_PULLUP /* Board has external pull-ups */
|
|
|
|
To set up a SPI controller:
|
|
|
|
void portmux_enable_spiX(unsigned long cs_mask,
|
|
unsigned long drive_strength);
|
|
|
|
where X is replaced by the SPI instance to be configured. "cs_mask" is
|
|
a 4-bit bitmask specifying which of the four standard chip select
|
|
lines to set up as GPIOs.
|