summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrafulla Wadaskar <prafulla@marvell.com>2010-12-07 15:23:39 +0530
committerWolfgang Denk <wd@denx.de>2010-12-16 23:02:43 +0100
commite5f495d1728d108cb08a5b724a5d6741c37b3860 (patch)
tree087f98da930e778452a8301f53aed2e842636b0d
parent6c08d5dcf845c798173b883d7cc3d453de1dbd7e (diff)
downloadu-boot-e5f495d1728d108cb08a5b724a5d6741c37b3860.tar.gz
u-boot-e5f495d1728d108cb08a5b724a5d6741c37b3860.tar.xz
u-boot-e5f495d1728d108cb08a5b724a5d6741c37b3860.zip
gpio: Add Multi-Function-Pin configuration driver for Marvell SoCs
Most of the Marvell SoCs has Multi Function Pin (MFP) configuration registers For ex. ARMADA100. These registers are programmed to expose the specific functionality associated with respective SoC Pins This driver provides configuration APIs, using them, configuration need to be done in board specific code for ex- following code configures MFPs 107 and 108 for UART_TX/RX functionality int board_early_init_f(void) { u32 mfp_cfg[] = { /* Console on UART1 */ MFP107_UART1_RXD, MFP108_UART1_TXD, MFP_EOC /*End of configureation*/ }; /* configure MFP's */ mfp_config(mfp_cfg); return 0; } Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/mvmfp.c87
-rw-r--r--include/mvmfp.h100
3 files changed, 188 insertions, 0 deletions
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 398024c7bc..a5fa2b5d85 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -27,6 +27,7 @@ LIB := $(obj)libgpio.o
COBJS-$(CONFIG_AT91_GPIO) += at91_gpio.o
COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o
+COBJS-$(CONFIG_MARVELL_MFP) += mvmfp.o
COBJS-$(CONFIG_MXC_GPIO) += mxc_gpio.o
COBJS-$(CONFIG_PCA953X) += pca953x.o
COBJS-$(CONFIG_S5P) += s5p_gpio.o
diff --git a/drivers/gpio/mvmfp.c b/drivers/gpio/mvmfp.c
new file mode 100644
index 0000000000..5646ed4370
--- /dev/null
+++ b/drivers/gpio/mvmfp.c
@@ -0,0 +1,87 @@
+/*
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>,
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <mvmfp.h>
+#include <asm/arch/mfp.h>
+#ifdef CONFIG_ARMADA100
+#include <asm/arch/armada100.h>
+#else
+#error Unsupported SoC...
+#endif
+
+/*
+ * mfp_config
+ *
+ * On most of Marvell SoCs (ex. ARMADA100) there is Multi-Funtion-Pin
+ * configuration registers to configure each GPIO/Function pin on the
+ * SoC.
+ *
+ * This function reads the array of values for
+ * MFPR_X registers and programms them into respective
+ * Multi-Function Pin registers.
+ * It supports - Alternate Function Selection programming.
+ *
+ * Whereas,
+ * The Configureation value is constructed using MFP()
+ * array consists of 32bit values as defined in MFP(xx,xx..) macro
+ */
+void mfp_config(u32 *mfp_cfgs)
+{
+ u32 *p_mfpr = NULL;
+ u32 cfg_val, val;
+
+ do {
+ cfg_val = *mfp_cfgs++;
+ /* exit if End of configuration table detected */
+ if (cfg_val == MFP_EOC)
+ break;
+
+ p_mfpr = (u32 *)(MV_MFPR_BASE
+ + MFP_REG_GET_OFFSET(cfg_val));
+
+ /* Write a mfg register as per configuration */
+ val = 0;
+ if (cfg_val & MFP_AF_FLAG)
+ /* Abstract and program Afternate-Func Selection */
+ val |= cfg_val & MFP_AF_MASK;
+ if (cfg_val & MFP_EDGE_FLAG)
+ /* Abstract and program Edge configuration */
+ val |= cfg_val & MFP_LPM_EDGE_MASK;
+ if (cfg_val & MFP_DRIVE_FLAG)
+ /* Abstract and program Drive configuration */
+ val |= cfg_val & MFP_DRIVE_MASK;
+ if (cfg_val & MFP_PULL_FLAG)
+ /* Abstract and program Pullup/down configuration */
+ val |= cfg_val & MFP_PULL_MASK;
+
+ writel(val, p_mfpr);
+ } while (1);
+ /*
+ * perform a read-back of any MFPR register to make sure the
+ * previous writings are finished
+ */
+ readl(p_mfpr);
+}
diff --git a/include/mvmfp.h b/include/mvmfp.h
new file mode 100644
index 0000000000..0b36393f90
--- /dev/null
+++ b/include/mvmfp.h
@@ -0,0 +1,100 @@
+/*
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __MVMFP_H
+#define __MVMFP_H
+
+/*
+ * Header file for MultiFunctionPin (MFP) Configururation framework
+ *
+ * Processors Supported:
+ * 1. Marvell ARMADA100 Processors
+ *
+ * processor to be supported should be added here
+ */
+
+/*
+ * MFP configuration is represented by a 32-bit unsigned integer
+ */
+#define MFP(_off, _pull, _pF, _drv, _dF, _edge, _eF, _afn, _aF) ( \
+ /* bits 31..16 - MFP Register Offset */ (((_off) & 0xffff) << 16) | \
+ /* bits 15..13 - Run Mode Pull State */ (((_pull) & 0x7) << 13) | \
+ /* bit 12 - Unused */ \
+ /* bits 11..10 - Driver Strength */ (((_drv) & 0x3) << 10) | \
+ /* bit 09 - Pull State flag */ (((_pF) & 0x1) << 9) | \
+ /* bit 08 - Drv-strength flag */ (((_dF) & 0x1) << 8) | \
+ /* bit 07 - Edge-det flag */ (((_eF) & 0x1) << 7) | \
+ /* bits 06..04 - Edge Detection */ (((_edge) & 0x7) << 4) | \
+ /* bits 03..00 - Alt-fun flag */ (((_aF) & 0x1) << 3) | \
+ /* bits Alternate-fun select */ ((_afn) & 0x7))
+
+/*
+ * to facilitate the definition, the following macros are provided
+ *
+ * offset, pull,pF, drv,dF, edge,eF ,afn,aF
+ */
+#define MFP_OFFSET_MASK MFP(0xffff, 0,0, 0,0, 0,0, 0,0)
+#define MFP_REG(x) MFP(x, 0,0, 0,0, 0,0, 0,0)
+#define MFP_REG_GET_OFFSET(x) ((x & MFP_OFFSET_MASK) >> 16)
+
+#define MFP_AF_FLAG MFP(0x0000, 0,0, 0,0, 0,0, 0,1)
+#define MFP_DRIVE_FLAG MFP(0x0000, 0,0, 0,1, 0,0, 0,0)
+#define MFP_EDGE_FLAG MFP(0x0000, 0,0, 0,0, 0,1, 0,0)
+#define MFP_PULL_FLAG MFP(0x0000, 0,1, 0,0, 0,0, 0,0)
+
+#define MFP_AF0 MFP(0x0000, 0,0, 0,0, 0,0, 0,1)
+#define MFP_AF1 MFP(0x0000, 0,0, 0,0, 0,0, 1,1)
+#define MFP_AF2 MFP(0x0000, 0,0, 0,0, 0,0, 2,1)
+#define MFP_AF3 MFP(0x0000, 0,0, 0,0, 0,0, 3,1)
+#define MFP_AF4 MFP(0x0000, 0,0, 0,0, 0,0, 4,1)
+#define MFP_AF5 MFP(0x0000, 0,0, 0,0, 0,0, 5,1)
+#define MFP_AF6 MFP(0x0000, 0,0, 0,0, 0,0, 6,1)
+#define MFP_AF7 MFP(0x0000, 0,0, 0,0, 0,0, 7,1)
+#define MFP_AF_MASK MFP(0x0000, 0,0, 0,0, 0,0, 7,0)
+
+#define MFP_LPM_EDGE_NONE MFP(0x0000, 0,0, 0,0, 0,1, 0,0)
+#define MFP_LPM_EDGE_RISE MFP(0x0000, 0,0, 0,0, 1,1, 0,0)
+#define MFP_LPM_EDGE_FALL MFP(0x0000, 0,0, 0,0, 2,1, 0,0)
+#define MFP_LPM_EDGE_BOTH MFP(0x0000, 0,0, 0,0, 3,1, 0,0)
+#define MFP_LPM_EDGE_MASK MFP(0x0000, 0,0, 0,0, 3,0, 0,0)
+
+#define MFP_DRIVE_VERY_SLOW MFP(0x0000, 0,0, 0,1, 0,0, 0,0)
+#define MFP_DRIVE_SLOW MFP(0x0000, 0,0, 1,1, 0,0, 0,0)
+#define MFP_DRIVE_MEDIUM MFP(0x0000, 0,0, 2,1, 0,0, 0,0)
+#define MFP_DRIVE_FAST MFP(0x0000, 0,0, 3,1, 0,0, 0,0)
+#define MFP_DRIVE_MASK MFP(0x0000, 0,0, 3,0, 0,0, 0,0)
+
+#define MFP_PULL_NONE MFP(0x0000, 0,1, 0,0, 0,0, 0,0)
+#define MFP_PULL_LOW MFP(0x0000, 1,1, 0,0, 0,0, 0,0)
+#define MFP_PULL_HIGH MFP(0x0000, 2,1, 0,0, 0,0, 0,0)
+#define MFP_PULL_BOTH MFP(0x0000, 3,1, 0,0, 0,0, 0,0)
+#define MFP_PULL_FLOAT MFP(0x0000, 4,1, 0,0, 0,0, 0,0)
+#define MFP_PULL_MASK MFP(0x0000, 7,0, 0,0, 0,0, 0,0)
+
+#define MFP_EOC 0xffffffff /* indicates end-of-conf */
+
+/* Functions */
+void mfp_config(u32 *mfp_cfgs);
+
+#endif /* __MVMFP_H */