davinci: update pin-multiplexing support
Update MUX support to be more general and useful across multiple SoCs in the DaVinci family. Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
This commit is contained in:
parent
617b925f94
commit
5526b3f7e3
|
@ -18,6 +18,32 @@ config MACH_DAVINCI_EVM
|
|||
Configure this option to specify the whether the board used
|
||||
for development is a DaVinci EVM
|
||||
|
||||
|
||||
config DAVINCI_MUX
|
||||
bool "DAVINCI multiplexing support"
|
||||
depends on ARCH_DAVINCI
|
||||
default y
|
||||
help
|
||||
Pin multiplexing support for DAVINCI boards. If your bootloader
|
||||
sets the multiplexing correctly, say N. Otherwise, or if unsure,
|
||||
say Y.
|
||||
|
||||
config DAVINCI_MUX_DEBUG
|
||||
bool "Multiplexing debug output"
|
||||
depends on DAVINCI_MUX
|
||||
help
|
||||
Makes the multiplexing functions print out a lot of debug info.
|
||||
This is useful if you want to find out the correct values of the
|
||||
multiplexing registers.
|
||||
|
||||
config DAVINCI_MUX_WARNINGS
|
||||
bool "Warn about pins the bootloader didn't set up"
|
||||
depends on DAVINCI_MUX
|
||||
help
|
||||
Choose Y here to warn whenever driver initialization logic needs
|
||||
to change the pin multiplexing setup. When there are no warnings
|
||||
printed, it's safe to deselect DAVINCI_MUX for your product.
|
||||
|
||||
config DAVINCI_RESET_CLOCKS
|
||||
bool "Reset unused clocks during boot"
|
||||
depends on ARCH_DAVINCI
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
# Common objects
|
||||
obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \
|
||||
gpio.o mux.o devices.o dma.o usb.o
|
||||
gpio.o devices.o dma.o usb.o
|
||||
|
||||
obj-$(CONFIG_DAVINCI_MUX) += mux.o
|
||||
|
||||
# Board specific
|
||||
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include <mach/hardware.h>
|
||||
#include <mach/i2c.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/cputype.h>
|
||||
#include <mach/mux.h>
|
||||
|
||||
#define DAVINCI_I2C_BASE 0x01C21000
|
||||
|
||||
|
@ -45,6 +47,9 @@ static struct platform_device davinci_i2c_device = {
|
|||
|
||||
void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
|
||||
{
|
||||
if (cpu_is_davinci_dm644x())
|
||||
davinci_cfg_reg(DM644X_I2C);
|
||||
|
||||
davinci_i2c_device.dev.platform_data = pdata;
|
||||
(void) platform_device_register(&davinci_i2c_device);
|
||||
}
|
||||
|
|
|
@ -1,55 +1,183 @@
|
|||
/*
|
||||
* DaVinci pin multiplexing defines
|
||||
* Table of the DAVINCI register configurations for the PINMUX combinations
|
||||
*
|
||||
* Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* Based on linux/include/asm-arm/arch-omap/mux.h:
|
||||
* Copyright (C) 2003 - 2005 Nokia Corporation
|
||||
*
|
||||
* Written by Tony Lindgren
|
||||
*
|
||||
* 2007 (c) MontaVista Software, Inc. This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*
|
||||
* Copyright (C) 2008 Texas Instruments.
|
||||
*/
|
||||
#ifndef __ASM_ARCH_MUX_H
|
||||
#define __ASM_ARCH_MUX_H
|
||||
|
||||
#define DAVINCI_MUX_AEAW0 0
|
||||
#define DAVINCI_MUX_AEAW1 1
|
||||
#define DAVINCI_MUX_AEAW2 2
|
||||
#define DAVINCI_MUX_AEAW3 3
|
||||
#define DAVINCI_MUX_AEAW4 4
|
||||
#define DAVINCI_MUX_AECS4 10
|
||||
#define DAVINCI_MUX_AECS5 11
|
||||
#define DAVINCI_MUX_VLYNQWD0 12
|
||||
#define DAVINCI_MUX_VLYNQWD1 13
|
||||
#define DAVINCI_MUX_VLSCREN 14
|
||||
#define DAVINCI_MUX_VLYNQEN 15
|
||||
#define DAVINCI_MUX_HDIREN 16
|
||||
#define DAVINCI_MUX_ATAEN 17
|
||||
#define DAVINCI_MUX_RGB666 22
|
||||
#define DAVINCI_MUX_RGB888 23
|
||||
#define DAVINCI_MUX_LOEEN 24
|
||||
#define DAVINCI_MUX_LFLDEN 25
|
||||
#define DAVINCI_MUX_CWEN 26
|
||||
#define DAVINCI_MUX_CFLDEN 27
|
||||
#define DAVINCI_MUX_HPIEN 29
|
||||
#define DAVINCI_MUX_1394EN 30
|
||||
#define DAVINCI_MUX_EMACEN 31
|
||||
#ifndef __INC_MACH_MUX_H
|
||||
#define __INC_MACH_MUX_H
|
||||
|
||||
#define DAVINCI_MUX_LEVEL2 32
|
||||
#define DAVINCI_MUX_UART0 (DAVINCI_MUX_LEVEL2 + 0)
|
||||
#define DAVINCI_MUX_UART1 (DAVINCI_MUX_LEVEL2 + 1)
|
||||
#define DAVINCI_MUX_UART2 (DAVINCI_MUX_LEVEL2 + 2)
|
||||
#define DAVINCI_MUX_U2FLO (DAVINCI_MUX_LEVEL2 + 3)
|
||||
#define DAVINCI_MUX_PWM0 (DAVINCI_MUX_LEVEL2 + 4)
|
||||
#define DAVINCI_MUX_PWM1 (DAVINCI_MUX_LEVEL2 + 5)
|
||||
#define DAVINCI_MUX_PWM2 (DAVINCI_MUX_LEVEL2 + 6)
|
||||
#define DAVINCI_MUX_I2C (DAVINCI_MUX_LEVEL2 + 7)
|
||||
#define DAVINCI_MUX_SPI (DAVINCI_MUX_LEVEL2 + 8)
|
||||
#define DAVINCI_MUX_MSTK (DAVINCI_MUX_LEVEL2 + 9)
|
||||
#define DAVINCI_MUX_ASP (DAVINCI_MUX_LEVEL2 + 10)
|
||||
#define DAVINCI_MUX_CLK0 (DAVINCI_MUX_LEVEL2 + 16)
|
||||
#define DAVINCI_MUX_CLK1 (DAVINCI_MUX_LEVEL2 + 17)
|
||||
#define DAVINCI_MUX_TIMIN (DAVINCI_MUX_LEVEL2 + 18)
|
||||
/* System module registers */
|
||||
#define PINMUX0 0x00
|
||||
#define PINMUX1 0x04
|
||||
/* dm355 only */
|
||||
#define PINMUX2 0x08
|
||||
#define PINMUX3 0x0c
|
||||
#define PINMUX4 0x10
|
||||
#define INTMUX 0x18
|
||||
#define EVTMUX 0x1c
|
||||
|
||||
extern void davinci_mux_peripheral(unsigned int mux, unsigned int enable);
|
||||
struct mux_config {
|
||||
const char *name;
|
||||
const char *mux_reg_name;
|
||||
const unsigned char mux_reg;
|
||||
const unsigned char mask_offset;
|
||||
const unsigned char mask;
|
||||
const unsigned char mode;
|
||||
bool debug;
|
||||
};
|
||||
|
||||
#endif /* __ASM_ARCH_MUX_H */
|
||||
enum davinci_dm644x_index {
|
||||
/* ATA and HDDIR functions */
|
||||
DM644X_HDIREN,
|
||||
DM644X_ATAEN,
|
||||
DM644X_ATAEN_DISABLE,
|
||||
|
||||
/* HPI functions */
|
||||
DM644X_HPIEN_DISABLE,
|
||||
|
||||
/* AEAW functions */
|
||||
DM644X_AEAW,
|
||||
|
||||
/* Memory Stick */
|
||||
DM644X_MSTK,
|
||||
|
||||
/* I2C */
|
||||
DM644X_I2C,
|
||||
|
||||
/* ASP function */
|
||||
DM644X_MCBSP,
|
||||
|
||||
/* UART1 */
|
||||
DM644X_UART1,
|
||||
|
||||
/* UART2 */
|
||||
DM644X_UART2,
|
||||
|
||||
/* PWM0 */
|
||||
DM644X_PWM0,
|
||||
|
||||
/* PWM1 */
|
||||
DM644X_PWM1,
|
||||
|
||||
/* PWM2 */
|
||||
DM644X_PWM2,
|
||||
|
||||
/* VLYNQ function */
|
||||
DM644X_VLYNQEN,
|
||||
DM644X_VLSCREN,
|
||||
DM644X_VLYNQWD,
|
||||
|
||||
/* EMAC and MDIO function */
|
||||
DM644X_EMACEN,
|
||||
|
||||
/* GPIO3V[0:16] pins */
|
||||
DM644X_GPIO3V,
|
||||
|
||||
/* GPIO pins */
|
||||
DM644X_GPIO0,
|
||||
DM644X_GPIO3,
|
||||
DM644X_GPIO43_44,
|
||||
DM644X_GPIO46_47,
|
||||
|
||||
/* VPBE */
|
||||
DM644X_RGB666,
|
||||
|
||||
/* LCD */
|
||||
DM644X_LOEEN,
|
||||
DM644X_LFLDEN,
|
||||
};
|
||||
|
||||
enum davinci_dm646x_index {
|
||||
/* ATA function */
|
||||
DM646X_ATAEN,
|
||||
|
||||
/* AUDIO Clock */
|
||||
DM646X_AUDCK1,
|
||||
DM646X_AUDCK0,
|
||||
|
||||
/* CRGEN Control */
|
||||
DM646X_CRGMUX,
|
||||
|
||||
/* VPIF Control */
|
||||
DM646X_STSOMUX_DISABLE,
|
||||
DM646X_STSIMUX_DISABLE,
|
||||
DM646X_PTSOMUX_DISABLE,
|
||||
DM646X_PTSIMUX_DISABLE,
|
||||
|
||||
/* TSIF Control */
|
||||
DM646X_STSOMUX,
|
||||
DM646X_STSIMUX,
|
||||
DM646X_PTSOMUX_PARALLEL,
|
||||
DM646X_PTSIMUX_PARALLEL,
|
||||
DM646X_PTSOMUX_SERIAL,
|
||||
DM646X_PTSIMUX_SERIAL,
|
||||
};
|
||||
|
||||
enum davinci_dm355_index {
|
||||
/* MMC/SD 0 */
|
||||
DM355_MMCSD0,
|
||||
|
||||
/* MMC/SD 1 */
|
||||
DM355_SD1_CLK,
|
||||
DM355_SD1_CMD,
|
||||
DM355_SD1_DATA3,
|
||||
DM355_SD1_DATA2,
|
||||
DM355_SD1_DATA1,
|
||||
DM355_SD1_DATA0,
|
||||
|
||||
/* I2C */
|
||||
DM355_I2C_SDA,
|
||||
DM355_I2C_SCL,
|
||||
|
||||
/* ASP0 function */
|
||||
DM355_MCBSP0_BDX,
|
||||
DM355_MCBSP0_X,
|
||||
DM355_MCBSP0_BFSX,
|
||||
DM355_MCBSP0_BDR,
|
||||
DM355_MCBSP0_R,
|
||||
DM355_MCBSP0_BFSR,
|
||||
|
||||
/* SPI0 */
|
||||
DM355_SPI0_SDI,
|
||||
DM355_SPI0_SDENA0,
|
||||
DM355_SPI0_SDENA1,
|
||||
|
||||
/* IRQ muxing */
|
||||
DM355_INT_EDMA_CC,
|
||||
DM355_INT_EDMA_TC0_ERR,
|
||||
DM355_INT_EDMA_TC1_ERR,
|
||||
|
||||
/* EDMA event muxing */
|
||||
DM355_EVT8_ASP1_TX,
|
||||
DM355_EVT9_ASP1_RX,
|
||||
DM355_EVT26_MMC0_RX,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DAVINCI_MUX
|
||||
/* setup pin muxing */
|
||||
extern void davinci_mux_init(void);
|
||||
extern int davinci_mux_register(const struct mux_config *pins,
|
||||
unsigned long size);
|
||||
extern int davinci_cfg_reg(unsigned long reg_cfg);
|
||||
#else
|
||||
/* boot loader does it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */
|
||||
static inline void davinci_mux_init(void) {}
|
||||
static inline int davinci_mux_register(const struct mux_config *pins,
|
||||
unsigned long size) { return 0; }
|
||||
static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; }
|
||||
#endif
|
||||
|
||||
#endif /* __INC_MACH_MUX_H */
|
||||
|
|
|
@ -1,42 +1,103 @@
|
|||
/*
|
||||
* DaVinci pin multiplexing configurations
|
||||
* Utility to set the DAVINCI MUX register from a table in mux.h
|
||||
*
|
||||
* Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* Based on linux/arch/arm/plat-omap/mux.c:
|
||||
* Copyright (C) 2003 - 2005 Nokia Corporation
|
||||
*
|
||||
* Written by Tony Lindgren
|
||||
*
|
||||
* 2007 (c) MontaVista Software, Inc. This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*
|
||||
* Copyright (C) 2008 Texas Instruments.
|
||||
*/
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include <mach/mux.h>
|
||||
|
||||
/* System control register offsets */
|
||||
#define PINMUX0 0x00
|
||||
#define PINMUX1 0x04
|
||||
static const struct mux_config *mux_table;
|
||||
static unsigned long pin_table_sz;
|
||||
|
||||
static DEFINE_SPINLOCK(mux_lock);
|
||||
|
||||
void davinci_mux_peripheral(unsigned int mux, unsigned int enable)
|
||||
int __init davinci_mux_register(const struct mux_config *pins,
|
||||
unsigned long size)
|
||||
{
|
||||
void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
|
||||
u32 pinmux, muxreg = PINMUX0;
|
||||
mux_table = pins;
|
||||
pin_table_sz = size;
|
||||
|
||||
if (mux >= DAVINCI_MUX_LEVEL2) {
|
||||
muxreg = PINMUX1;
|
||||
mux -= DAVINCI_MUX_LEVEL2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the DAVINCI MUX register based on the table
|
||||
*/
|
||||
int __init_or_module davinci_cfg_reg(const unsigned long index)
|
||||
{
|
||||
static DEFINE_SPINLOCK(mux_spin_lock);
|
||||
void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
|
||||
unsigned long flags;
|
||||
const struct mux_config *cfg;
|
||||
unsigned int reg_orig = 0, reg = 0;
|
||||
unsigned int mask, warn = 0;
|
||||
|
||||
if (!mux_table)
|
||||
BUG();
|
||||
|
||||
if (index >= pin_table_sz) {
|
||||
printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
|
||||
index, pin_table_sz);
|
||||
dump_stack();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
spin_lock(&mux_lock);
|
||||
pinmux = __raw_readl(base + muxreg);
|
||||
if (enable)
|
||||
pinmux |= (1 << mux);
|
||||
else
|
||||
pinmux &= ~(1 << mux);
|
||||
__raw_writel(pinmux, base + muxreg);
|
||||
spin_unlock(&mux_lock);
|
||||
cfg = &mux_table[index];
|
||||
|
||||
if (cfg->name == NULL) {
|
||||
printk(KERN_ERR "No entry for the specified index\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Update the mux register in question */
|
||||
if (cfg->mask) {
|
||||
unsigned tmp1, tmp2;
|
||||
|
||||
spin_lock_irqsave(&mux_spin_lock, flags);
|
||||
reg_orig = __raw_readl(base + cfg->mux_reg);
|
||||
|
||||
mask = (cfg->mask << cfg->mask_offset);
|
||||
tmp1 = reg_orig & mask;
|
||||
reg = reg_orig & ~mask;
|
||||
|
||||
tmp2 = (cfg->mode << cfg->mask_offset);
|
||||
reg |= tmp2;
|
||||
|
||||
if (tmp1 != tmp2)
|
||||
warn = 1;
|
||||
|
||||
__raw_writel(reg, base + cfg->mux_reg);
|
||||
spin_unlock_irqrestore(&mux_spin_lock, flags);
|
||||
}
|
||||
|
||||
if (warn) {
|
||||
#ifdef CONFIG_DAVINCI_MUX_WARNINGS
|
||||
printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DAVINCI_MUX_DEBUG
|
||||
if (cfg->debug || warn) {
|
||||
printk(KERN_WARNING "MUX: Setting register %s\n", cfg->name);
|
||||
printk(KERN_WARNING " %s (0x%08x) = 0x%08x -> 0x%08x\n",
|
||||
cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(davinci_cfg_reg);
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Pin-multiplex helper macros for TI DaVinci family devices
|
||||
*
|
||||
* Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* 2007 (c) MontaVista Software, Inc. This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*
|
||||
* Copyright (C) 2008 Texas Instruments.
|
||||
*/
|
||||
#ifndef _MACH_DAVINCI_MUX_H_
|
||||
#define _MACH_DAVINCI_MUX_H_
|
||||
|
||||
#include <mach/mux.h>
|
||||
|
||||
#define MUX_CFG(soc, desc, muxreg, mode_offset, mode_mask, mux_mode, dbg)\
|
||||
[soc##_##desc] = { \
|
||||
.name = #desc, \
|
||||
.debug = dbg, \
|
||||
.mux_reg_name = "PINMUX"#muxreg, \
|
||||
.mux_reg = PINMUX##muxreg, \
|
||||
.mask_offset = mode_offset, \
|
||||
.mask = mode_mask, \
|
||||
.mode = mux_mode, \
|
||||
},
|
||||
|
||||
#define INT_CFG(soc, desc, mode_offset, mode_mask, mux_mode, dbg) \
|
||||
[soc##_##desc] = { \
|
||||
.name = #desc, \
|
||||
.debug = dbg, \
|
||||
.mux_reg_name = "INTMUX", \
|
||||
.mux_reg = INTMUX, \
|
||||
.mask_offset = mode_offset, \
|
||||
.mask = mode_mask, \
|
||||
.mode = mux_mode, \
|
||||
},
|
||||
|
||||
#define EVT_CFG(soc, desc, mode_offset, mode_mask, mux_mode, dbg) \
|
||||
[soc##_##desc] = { \
|
||||
.name = #desc, \
|
||||
.debug = dbg, \
|
||||
.mux_reg_name = "EVTMUX", \
|
||||
.mux_reg = EVTMUX, \
|
||||
.mask_offset = mode_offset, \
|
||||
.mask = mode_mask, \
|
||||
.mode = mux_mode, \
|
||||
},
|
||||
|
||||
#endif /* _MACH_DAVINCI_MUX_H */
|
Loading…
Reference in New Issue