diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-14 16:06:58 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-14 16:06:58 -0700 |
commit | 85082fd7cbe3173198aac0eb5e85ab1edcc6352c (patch) | |
tree | edbc09b7945994f78668d218fa02e991c3b3b365 /arch/arm/mach-orion5x/mpp.c | |
parent | 666484f0250db2e016948d63b3ef33e202e3b8d0 (diff) | |
parent | 53ffe3b440aa85af6fc4eda09b2d44bcdd312d4d (diff) |
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (241 commits)
[ARM] 5171/1: ep93xx: fix compilation of modules using clocks
[ARM] 5133/2: at91sam9g20 defconfig file
[ARM] 5130/4: Support for the at91sam9g20
[ARM] 5160/1: IOP3XX: gpio/gpiolib support
[ARM] at91: Fix NAND FLASH timings for at91sam9x evaluation kits.
[ARM] 5084/1: zylonite: Register AC97 device
[ARM] 5085/2: PXA: Move AC97 over to the new central device declaration model
[ARM] 5120/1: pxa: correct platform driver names for PXA25x and PXA27x UDC drivers
[ARM] 5147/1: pxaficp_ir: drop pxa_gpio_mode calls, as pin setting
[ARM] 5145/1: PXA2xx: provide api to control IrDA pins state
[ARM] 5144/1: pxaficp_ir: cleanup includes
[ARM] pxa: remove pxa_set_cken()
[ARM] pxa: allow clk aliases
[ARM] Feroceon: don't disable BPU on boot
[ARM] Orion: LED support for HP mv2120
[ARM] Orion: add RD88F5181L-FXO support
[ARM] Orion: add RD88F5181L-GE support
[ARM] Orion: add Netgear WNR854T support
[ARM] s3c2410_defconfig: update for current build
[ARM] Acer n30: Minor style and indentation fixes.
...
Diffstat (limited to 'arch/arm/mach-orion5x/mpp.c')
-rw-r--r-- | arch/arm/mach-orion5x/mpp.c | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c new file mode 100644 index 00000000000..a48cadb0159 --- /dev/null +++ b/arch/arm/mach-orion5x/mpp.c @@ -0,0 +1,163 @@ +/* + * arch/arm/mach-orion5x/mpp.c + * + * MPP functions for Marvell Orion 5x SoCs + * + * 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. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mbus.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include "common.h" +#include "mpp.h" + +static int is_5181l(void) +{ + u32 dev; + u32 rev; + + orion5x_pcie_id(&dev, &rev); + + return !!(dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0); +} + +static int is_5182(void) +{ + u32 dev; + u32 rev; + + orion5x_pcie_id(&dev, &rev); + + return !!(dev == MV88F5182_DEV_ID); +} + +static int is_5281(void) +{ + u32 dev; + u32 rev; + + orion5x_pcie_id(&dev, &rev); + + return !!(dev == MV88F5281_DEV_ID); +} + +static int __init determine_type_encoding(int mpp, enum orion5x_mpp_type type) +{ + switch (type) { + case MPP_UNUSED: + case MPP_GPIO: + if (mpp == 0) + return 3; + if (mpp >= 1 && mpp <= 15) + return 0; + if (mpp >= 16 && mpp <= 19) { + if (is_5182()) + return 5; + if (type == MPP_UNUSED) + return 0; + } + return -1; + + case MPP_PCIE_RST_OUTn: + if (mpp == 0) + return 0; + return -1; + + case MPP_PCI_ARB: + if (mpp >= 0 && mpp <= 7) + return 2; + return -1; + + case MPP_PCI_PMEn: + if (mpp == 2) + return 3; + return -1; + + case MPP_GIGE: + if (mpp >= 8 && mpp <= 19) + return 1; + return -1; + + case MPP_NAND: + if (is_5182() || is_5281()) { + if (mpp >= 4 && mpp <= 7) + return 4; + if (mpp >= 12 && mpp <= 17) + return 4; + } + return -1; + + case MPP_PCI_CLK: + if (is_5181l() && mpp >= 6 && mpp <= 7) + return 5; + return -1; + + case MPP_SATA_LED: + if (is_5182()) { + if (mpp >= 4 && mpp <= 7) + return 5; + if (mpp >= 12 && mpp <= 15) + return 5; + } + return -1; + + case MPP_UART: + if (mpp >= 16 && mpp <= 19) + return 0; + return -1; + } + + printk(KERN_INFO "unknown MPP type %d\n", type); + + return -1; +} + +void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode) +{ + u32 mpp_0_7_ctrl = readl(MPP_0_7_CTRL); + u32 mpp_8_15_ctrl = readl(MPP_8_15_CTRL); + u32 mpp_16_19_ctrl = readl(MPP_16_19_CTRL); + + while (mode->mpp >= 0) { + u32 *reg; + int num_type; + int shift; + + if (mode->mpp >= 0 && mode->mpp <= 7) + reg = &mpp_0_7_ctrl; + else if (mode->mpp >= 8 && mode->mpp <= 15) + reg = &mpp_8_15_ctrl; + else if (mode->mpp >= 16 && mode->mpp <= 19) + reg = &mpp_16_19_ctrl; + else { + printk(KERN_ERR "orion5x_mpp_conf: invalid MPP " + "(%d)\n", mode->mpp); + continue; + } + + num_type = determine_type_encoding(mode->mpp, mode->type); + if (num_type < 0) { + printk(KERN_ERR "orion5x_mpp_conf: invalid MPP " + "combination (%d, %d)\n", mode->mpp, + mode->type); + continue; + } + + shift = (mode->mpp & 7) << 2; + *reg &= ~(0xf << shift); + *reg |= (num_type & 0xf) << shift; + + orion5x_gpio_set_valid(mode->mpp, !!(mode->type == MPP_GPIO)); + + mode++; + } + + writel(mpp_0_7_ctrl, MPP_0_7_CTRL); + writel(mpp_8_15_ctrl, MPP_8_15_CTRL); + writel(mpp_16_19_ctrl, MPP_16_19_CTRL); +} |