mpp.c (a18f22a968de17b29f2310cdb7ba69163e65ec15) | mpp.c (554cdaefd1cf7bb54b209c4e68c7cec87ce442a9) |
---|---|
1/* 2 * arch/arm/mach-orion5x/mpp.c 3 * 4 * MPP functions for Marvell Orion 5x SoCs 5 * 6 * This file is licensed under the terms of the GNU General Public 7 * License version 2. This program is licensed "as is" without any 8 * warranty of any kind, whether express or implied. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/mbus.h> 14#include <linux/io.h> | 1/* 2 * arch/arm/mach-orion5x/mpp.c 3 * 4 * MPP functions for Marvell Orion 5x SoCs 5 * 6 * This file is licensed under the terms of the GNU General Public 7 * License version 2. This program is licensed "as is" without any 8 * warranty of any kind, whether express or implied. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/mbus.h> 14#include <linux/io.h> |
15#include <asm/gpio.h> | |
16#include <mach/hardware.h> | 15#include <mach/hardware.h> |
17#include "common.h" | 16#include <plat/mpp.h> |
18#include "mpp.h" | 17#include "mpp.h" |
18#include "common.h" |
|
19 | 19 |
20static int is_5181l(void) | 20static unsigned int __init orion5x_variant(void) |
21{ 22 u32 dev; 23 u32 rev; 24 25 orion5x_pcie_id(&dev, &rev); 26 | 21{ 22 u32 dev; 23 u32 rev; 24 25 orion5x_pcie_id(&dev, &rev); 26 |
27 return !!(dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0); 28} | 27 if (dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0) 28 return MPP_F5181_MASK; |
29 | 29 |
30static int is_5182(void) 31{ 32 u32 dev; 33 u32 rev; | 30 if (dev == MV88F5182_DEV_ID) 31 return MPP_F5182_MASK; |
34 | 32 |
35 orion5x_pcie_id(&dev, &rev); | 33 if (dev == MV88F5281_DEV_ID) 34 return MPP_F5281_MASK; |
36 | 35 |
37 return !!(dev == MV88F5182_DEV_ID); | 36 printk(KERN_ERR "MPP setup: unknown orion5x variant " 37 "(dev %#x rev %#x)\n", dev, rev); 38 return 0; |
38} 39 | 39} 40 |
40static int is_5281(void) | 41void __init orion5x_mpp_conf(unsigned int *mpp_list) |
41{ | 42{ |
42 u32 dev; 43 u32 rev; 44 45 orion5x_pcie_id(&dev, &rev); 46 47 return !!(dev == MV88F5281_DEV_ID); | 43 orion_mpp_conf(mpp_list, orion5x_variant(), 44 MPP_MAX, ORION5X_DEV_BUS_VIRT_BASE); |
48} | 45} |
49 50static int __init determine_type_encoding(int mpp, enum orion5x_mpp_type type) 51{ 52 switch (type) { 53 case MPP_UNUSED: 54 case MPP_GPIO: 55 if (mpp == 0) 56 return 3; 57 if (mpp >= 1 && mpp <= 15) 58 return 0; 59 if (mpp >= 16 && mpp <= 19) { 60 if (is_5182()) 61 return 5; 62 if (type == MPP_UNUSED) 63 return 0; 64 } 65 return -1; 66 67 case MPP_PCIE_RST_OUTn: 68 if (mpp == 0) 69 return 0; 70 return -1; 71 72 case MPP_PCI_ARB: 73 if (mpp >= 0 && mpp <= 7) 74 return 2; 75 return -1; 76 77 case MPP_PCI_PMEn: 78 if (mpp == 2) 79 return 3; 80 return -1; 81 82 case MPP_GIGE: 83 if (mpp >= 8 && mpp <= 19) 84 return 1; 85 return -1; 86 87 case MPP_NAND: 88 if (is_5182() || is_5281()) { 89 if (mpp >= 4 && mpp <= 7) 90 return 4; 91 if (mpp >= 12 && mpp <= 17) 92 return 4; 93 } 94 return -1; 95 96 case MPP_PCI_CLK: 97 if (is_5181l() && mpp >= 6 && mpp <= 7) 98 return 5; 99 return -1; 100 101 case MPP_SATA_LED: 102 if (is_5182()) { 103 if (mpp >= 4 && mpp <= 7) 104 return 5; 105 if (mpp >= 12 && mpp <= 15) 106 return 5; 107 } 108 return -1; 109 110 case MPP_UART: 111 if (mpp >= 16 && mpp <= 19) 112 return 0; 113 return -1; 114 } 115 116 printk(KERN_INFO "unknown MPP type %d\n", type); 117 118 return -1; 119} 120 121void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode) 122{ 123 u32 mpp_0_7_ctrl = readl(MPP_0_7_CTRL); 124 u32 mpp_8_15_ctrl = readl(MPP_8_15_CTRL); 125 u32 mpp_16_19_ctrl = readl(MPP_16_19_CTRL); 126 127 for ( ; mode->mpp >= 0; mode++) { 128 u32 *reg; 129 int num_type; 130 int shift; 131 132 if (mode->mpp >= 0 && mode->mpp <= 7) 133 reg = &mpp_0_7_ctrl; 134 else if (mode->mpp >= 8 && mode->mpp <= 15) 135 reg = &mpp_8_15_ctrl; 136 else if (mode->mpp >= 16 && mode->mpp <= 19) 137 reg = &mpp_16_19_ctrl; 138 else { 139 printk(KERN_ERR "orion5x_mpp_conf: invalid MPP " 140 "(%d)\n", mode->mpp); 141 continue; 142 } 143 144 num_type = determine_type_encoding(mode->mpp, mode->type); 145 if (num_type < 0) { 146 printk(KERN_ERR "orion5x_mpp_conf: invalid MPP " 147 "combination (%d, %d)\n", mode->mpp, 148 mode->type); 149 continue; 150 } 151 152 shift = (mode->mpp & 7) << 2; 153 *reg &= ~(0xf << shift); 154 *reg |= (num_type & 0xf) << shift; 155 156 if (mode->type == MPP_UNUSED && (mode->mpp < 16 || is_5182())) 157 orion_gpio_set_unused(mode->mpp); 158 159 orion_gpio_set_valid(mode->mpp, !!(mode->type == MPP_GPIO)); 160 } 161 162 writel(mpp_0_7_ctrl, MPP_0_7_CTRL); 163 writel(mpp_8_15_ctrl, MPP_8_15_CTRL); 164 writel(mpp_16_19_ctrl, MPP_16_19_CTRL); 165} | |