BeagleBoardPinMux

This page is about Pin Multiplex (PinMux) on BeagleBoard (OMAP3). OMAP3 chip has less balls (pins) than the internal logic provides functionality. So each ball (pin) of OMAP3 can have different functionality (e.g. GPIO or I2C.TX). This is controlled by OMAP3 chip internal registers. This page tries to give some details where some info about OMAP3 pin mux can be found in hardware and how this is controlled by software, mainly U-Boot and Linux kernel. The information on this page can be used then e.g. to re-configure pins exposed at Beagle's expansion connector.

=Hardware=

This section tries to give an idea how pin mux on OMAP3 basically works, and looks at the Beagle specific hardware documentation for the expansion connector.

OMAP3
Details of OMAP35x PinMux can be found in OMAP35x Applications Processor TRM (spruf98b.pdf) in section 7.4.4.3 Pad Multiplexing Register Fields (page 814):


 * Each pad (ball, pin) can (but must not) have up to 8 different functionalities assigned to. These are called Mode 0 to Mode 7.
 * Each pad (ball, pin) muxing is controlled by 16bit. So two pads (balls, pins) are controlled by one 32bit register inside OMAP3. Each register can be written/read by 16bit or 32bit accesses.
 * The name of the register is normally formed by the name of Mode0 pad (ball, pin) functionality which is controlled by the lower 16bit of the 32bit register ([15-0]). So don't be confused by register name: The register can configure functionality which isn't reflected by the name.
 * The physical address of the register is given in the table, too. To configure the pad (ball, pin) which is controlled by the upper 16bit of the register ([31-16]) you can do this by a 16bit access to physical_register_address + 0x2
 * Note that the same functionality can be at different pads. E.g. UART1_TX functionality can be on pad controlled by CONTROL_PADCONF_UART1_TX register (Mode0) or CONTROL_PADCONF_DSS_DATA6 (Mode2). Make sure that you configure a logic functionality only to one pin.

Details of PinMux register itself be found in same TRM (spruf98b.pdf) in section 7.4.4 Pad functional Multiplexing and Configuration (page 810):


 * Bits [2-0] and bits [18-16] control the MuxMode of pad A and pad B controlled by this register. Here you can select one of the 8 MuxModes Mode0 to Mode7 you get from table discussed above.
 * Bit [3] and bit [19] select if OMAP3 internal pull-up/-down should be enabled. If pull-up/-down is enabled by this bit, bit [4] and bit [20] configure if it should be a pull-up or a pull-down.
 * Bit [8] and bit [24] select if the pin is an input or a bi-directional pin.

Off- and wake configuration is possible, too, but isn't discussed here.

Beagle
Details of Beagle's expansion header usage can be found in BeagleBoard System Reference Manual in table 20 Expansion connector signals (page 96). This expansion exposes 22 pads (balls, pins) of OMAP3 for your individual use. If you need signals that are not muxed by default, you have to do pin mux changes yourself.


 * Table 20 (page 96) in Beagle SRM gives you an overview, which signals can be muxed to which expansion pin.
 * MUX:0, MUX:1, MUX:2 and MUX:3 in table 20 in Beagle SRM correspond to what is called Mode0 to Mode4 in OMAP35x Applications Processor TRM.
 * To get an idea which CONTROL_PADCONF_xxx you have to touch for correct pin mux, take signal name of Beagle SRM MUX:0 and look for the same Mode0 in OMAP35x Applications Processor TRM. Example:
 * Table 20 in Beagle SRM MUX:0: MMC2_DAT7 -> Table 7-4 in OMAP35x Applications Processor TRM Mode0 MMC2_DAT7: CONTROL_PADCONF_MMC2_DAT6 register, physical 16bit address 0x4800216A.
 * Table 21 (page 97) in Beagle SRM gives an overview of expansion header signals from functionality group point of view.

Note: Expansion header is 1.8V!

=Software=

Controlling the hardware interface (i.e. writing the registers with appropriate values) described above can be done by any software. Up to now, default configuration is that initial pin mux is done by bootloader U-Boot, and later can be overwritten by Linux kernel.


 * Default configuration is that pin mux is set board specific by U-Boot and kernel's pin mux is disabled (i.e. kernel's CONFIG_OMAP_MUX is not set, see below).


 * Kernel's pin mux is known to be somehow broken. While different boards need different pin mux, recent Linux kernel has only one pin mux configuration, which then obviously don't fit any special board. Therefore, kernel's pin mux (see below) is disabled unless you enabled it intentionally. Kernel's pin mux needs some major re-write.

U-Boot
Main PinMux configuration in done in bootloader U-Boot. For beagle, see file board/omap3/beagle/beagle.h.

To do pin mux as described above U-Boot uses some macro magic to configure what is given by OMAP3 hardware. E.g.:

MUX_VAL(CP(MCBSP3_DX),        (IEN | PTD | DIS | M4)) /*GPIO_140*/\


 * MCBSP3_DX: This is the register name without CONTROL_PADCONF_*. I.e. looking into OMAP3xx TRM, this is CONTROL_PADCONF_MCBSP3_DX[15:0] register at physical address 0x4800216C. Mux mode for this pad is
 * MODE0: MCBPS3_TX
 * MODE1: UART2_CTS
 * MODE4: GPIO_140
 * M4: Here, mux MODE4 is selected, enabling GPIO_140 functionality on this pin. This is marked by the trailing comment.
 * IEN: This enables input, i.e. this is pad is configured bi-directional
 * DIS: Disable pull-up/pull-down
 * PTD: Pull type down, ignored if pull is disabled by DIS

Linux kernel
Some additional PinMux configuration is done by Linux kernel, too. Note that this has to be enabled by CONFIG_OMAP_MUX, else this isn't executed. This is done in file arch/arm/mach-omap2/mux.c (section CONFIG_ARCH_OMAP34XX).

Linux kernel uses some different syntax compared to U-Boot for pin mux, but logic is the same. E.g.

MUX_CFG_34XX("AE4_34XX_GPIO136_OUT", 0x164, OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) MUX_CFG_34XX("AF6_34XX_GPIO140_UP", 0x16c, OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT_PULLUP)


 * AE4_34XX_GPIO136_OUT: These are only strings which are used for debug output. This string consists of two parts:
 * the pad name (e.g. AE4) is from OMAP34x and will be different for different OMAPs and different packages
 * the resulting functionality (compare U-Boot's trailing comment)
 * 0x164 and 0x16c: This is the address offset from base address. Looking into OMAP35x TRM this is
 * 0x164: CONTROL_PADCONF_MMC2_DAT4[15:0] at physical address 0x48002164.
 * 0x16c: CONTROL_PADCONF_MCBSP3_DX[15:0] at physical address 0x4800216C.
 * OMAP34XX_MUX_MODE4: Same as M4 like in U-Boot. Configure mux MODE4 here.
 * OMAP34XX_PIN_OUTPUT or OMAP34XX_PIN_INPUT_PULLUP: One macro for the different modes. Done with 3 orred macros in U-Boot.

=Examples=

Add your examples here: What has to be changed to get which signal on expansion connector

UART2
This example uses kernel pin mux to enable configure UART2. These changes were made to a Rev B6, so be sure to check your reference manual and TRM from TI for the proper pins.

Begin by navigating to your kernel's /arch/arm/mach-omap2 folder and edit mux.c as follows:

MUX_CFG_34XX("AF6_34XX_GPIO140_UP", 0x16c,               OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_INPUT_PULLUP) MUX_CFG_34XX("AE6_34XX_GPIO141", 0x16e,               OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_INPUT) MUX_CFG_34XX("AF5_34XX_GPIO142", 0x170,               OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) MUX_CFG_34XX("AE5_34XX_GPIO143", 0x172,               OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_INPUT)

This will change MUX pins 140, 141, 142, and 143 to mode 1, which is defined in the TRM from TI as UART2 functionality. The next thing you will need to do is define another pin as UART2_RX won't work unless you define it, so do this:

MUX_CFG_34XX("AD25_34XX_GPIO147", 0x17a, 		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)

This defines it so that UART2_RX is only being used once as RX. Now you need to invoke these changes, while in the mach-omap2 folder, edit board-omap3beagle.c. Add the following lines to the omap3_beagle_init(void) function after omap_cfg_reg(J25_34XX_GPIO170); :

omap_cfg_reg(AF6_34XX_GPIO140); //CTS omap_cfg_reg(AE6_34XX_GPIO141); //RTS omap_cfg_reg(AF5_34XX_GPIO142); //TX omap_cfg_reg(AE5_34XX_GPIO143); //RX omap_cfg_reg(AD25_34XX_GPIO147);

This invokes the changes to the pin settings that we made in mux.c. Now navigate to arch/arm/plat-omap/include/mach/mux.h and add the following line to the enum at the bottom:

AD25_34XX_GPIO147,

Now you must use kernel's make menuconfig to enable (hit 'Y') kernel pin mux and gpio support as follows:

System Type --> TI OMAP Implementations --> OMAP multiplexing support Device Drivers --> GPIO Support --> /sys/class/gpio/... (sysfs interface)

With these changes, compilie the Linux kernel following the steps on making the uImage.

Now copy the resulting uImage file to your SD card and reboot. When running the console image of Angstrom, you may need to run the command: stty -F /dev/ttyS1 -crtscts This will turn of the RTS/CTS handshaking, and allow the UART to run properly.

That should be it, an easy way to test is to run the command "echo "test" > /dev/ttyS1" and monitor the TX line with an oscilloscope.

=Links=


 * HY research pin mux article
 * eLinux BeagleBoard page