Comments
Patch
@@ -27,6 +27,7 @@ LIB := $(obj)libgpio.o
COBJS-$(CONFIG_AT91_GPIO) += at91_gpio.o
COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o
+COBJS-$(CONFIG_MFP) += mfp.o
COBJS-$(CONFIG_MXC_GPIO) += mxc_gpio.o
COBJS-$(CONFIG_PCA953X) += pca953x.o
COBJS-$(CONFIG_S5P) += s5p_gpio.o
new file mode 100644
@@ -0,0 +1,103 @@
+/*
+ * (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 <mfp.h>
+#include <asm/arch/mfp.h>
+#ifdef CONFIG_ARMADA100
+#include <asm/arch/armada100.h>
+#define MFPR_BASE ARMD1_MFPR_BASE;
+#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 ARMD_MFP()
+ * array consists of 32bit values as-
+ * Bits 31-16 : Mfp instance number (i.e. MFPR no. to be programmed)
+ * Bits 15-13 : PULL_UP/PULL_DOWN selection
+ * Bits 11:10 : Pin Driver strength
+ * Bits 6-4 : Edge detection configuration
+ * Bits 2-0 : Alternate Function Selection
+ *
+ * For more details please refer respective Product Software Manual
+ */
+void mfp_config(u32 *mfp_cfgs)
+{
+ u32 *p_mfpr = NULL;
+ u32 val, cfg_val, mfpr_no;
+
+ do {
+ cfg_val = *mfp_cfgs++;
+ /* exit if End of configuration table detected */
+ if (cfg_val == MFP_EOC)
+ break;
+ /* abstract mfpr tobe programmed from configuration value */
+ mfpr_no = (cfg_val & MFP_PINNO_MASK) >> 16;
+ BUG_ON(mfpr_no >= MFP_PIN_MAX);
+
+ p_mfpr = (u32 *)MFPR_BASE;
+ MFPR_PTR_UPDATE(p_mfpr, mfpr_no);
+ /*p_mfpr contains address of register to be programmed */
+
+ /* Read-modify-Write a mfg register as per configuration */
+ val = readl(p_mfpr);
+ if (cfg_val & MFP_CFG_AF) {
+ /* Abstract and program Afternate-Func Selection */
+ val &= ~MFP_AF_MASK;
+ val |= cfg_val & MFP_AF_MASK;
+ } if (cfg_val & MFP_CFG_EDGE) {
+ /* Abstract and program Edge configuration */
+ val &= ~MFP_LPM_EDGE_MASK;
+ val |= cfg_val & MFP_LPM_EDGE_MASK;
+ } if (cfg_val & MFP_CFG_DRIVE) {
+ /* Abstract and program Drive configuration */
+ val &= ~MFP_DRIVE_MASK;
+ val |= cfg_val & MFP_DRIVE_MASK;
+ } if (cfg_val & MFP_CFG_PULL) {
+ /* Abstract and program Pullup/down configuration */
+ val &= ~MFP_PULL_MASK;
+ 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);
+}
new file mode 100644
@@ -0,0 +1,97 @@
+/*
+ * (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 __MFP_H
+#define __MFP_H
+
+/*
+ * Header file for MultiFunctionPin (MFP) Configururation framework
+ *
+ * Processors Supported:
+ * 1. Marvell ARMADA100 Processors
+ *
+ * processor to be supported should be added here
+ */
+
+#define MFP_EOC 0xffffffff /* flag to indicate end-of-configuration */
+
+/*
+ * Possible MFP configuration is represented by a 32-bit unsigned integer
+ *
+ * bit 0.. 2 - Alternate Function Selection
+ * bit 4.. 6 - Edge Detection
+ * bit 7.. 9 - Type of configuration
+ * bit 10..11 - Drive Strength
+ * bit 13..15 - Run Mode Pull State
+ * bit 16..31 - Used to hold MFP number to be configured
+ *
+ * to facilitate the definition, the following macros are provided
+ */
+
+#define MFP_AF0 (0x0 << 0)
+#define MFP_AF1 (0x1 << 0)
+#define MFP_AF2 (0x2 << 0)
+#define MFP_AF3 (0x3 << 0)
+#define MFP_AF4 (0x4 << 0)
+#define MFP_AF5 (0x5 << 0)
+#define MFP_AF6 (0x6 << 0)
+#define MFP_AF7 (0x7 << 0)
+#define MFP_AF_MASK (0x7 << 0)
+
+#define MFP_LPM_EDGE_NONE (0x0 << 4)
+#define MFP_LPM_EDGE_RISE (0x1 << 4)
+#define MFP_LPM_EDGE_FALL (0x2 << 4)
+#define MFP_LPM_EDGE_BOTH (0x3 << 4)
+#define MFP_LPM_EDGE_MASK (0x3 << 4)
+
+/* unused bits are used to identify config type */
+#define MFP_CFG_AF (0x1 << 7)
+#define MFP_CFG_DRIVE (0x1 << 8)
+#define MFP_CFG_EDGE (0x1 << 9)
+#define MFP_CFG_PULL (0x1 << 3)
+
+#define MFP_DRIVE_VERY_SLOW (0x0 << 10)
+#define MFP_DRIVE_SLOW (0x1 << 10)
+#define MFP_DRIVE_MEDIUM (0x2 << 10)
+#define MFP_DRIVE_FAST (0x3 << 10)
+#define MFP_DRIVE_MASK (0x3 << 10)
+
+#define MFP_PULL_NONE (0x0 << 13)
+#define MFP_PULL_LOW (0x1 << 13)
+#define MFP_PULL_HIGH (0x2 << 13)
+#define MFP_PULL_BOTH (0x3 << 13)
+#define MFP_PULL_FLOAT (0x4 << 13)
+#define MFP_PULL_MASK (0x7 << 13)
+
+#define MFP_PINNO_MASK (0xffff << 16)
+
+#define MFP_AF(af) (MFP_CFG_AF | MFP_AF##af)
+#define MFP_DRIVE(drv) (MFP_CFG_DRIVE | MFP_DRIVE_##drv)
+#define MFP_EDGE(edge) (MFP_CFG_EDGE | MFP_LPM_EDGE_##edge)
+#define MFP_PULL(pull) (MFP_CFG_PULL | MFP_PULL_##pull)
+#define MFP(pin) (MFP_PINNO_MASK & (pin << 16))
+
+void mfp_config(u32 *mfp_cfgs);
+
+#endif /* __MFP_H */