diff options
Diffstat (limited to 'arch/arm/mach-orion5x/mpp.c')
-rw-r--r-- | arch/arm/mach-orion5x/mpp.c | 150 |
1 files changed, 15 insertions, 135 deletions
diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c index 2288207726e4..f12c41b98d46 100644 --- a/arch/arm/mach-orion5x/mpp.c +++ b/arch/arm/mach-orion5x/mpp.c | |||
@@ -12,154 +12,34 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/mbus.h> | 13 | #include <linux/mbus.h> |
14 | #include <linux/io.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 | ||
20 | static int is_5181l(void) | 20 | static unsigned int __init orion5x_variant(void) |
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 | } | ||
29 | |||
30 | static int is_5182(void) | ||
31 | { | 21 | { |
32 | u32 dev; | 22 | u32 dev; |
33 | u32 rev; | 23 | u32 rev; |
34 | 24 | ||
35 | orion5x_pcie_id(&dev, &rev); | 25 | orion5x_pcie_id(&dev, &rev); |
36 | 26 | ||
37 | return !!(dev == MV88F5182_DEV_ID); | 27 | if (dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0) |
38 | } | 28 | return MPP_F5181_MASK; |
39 | 29 | ||
40 | static int is_5281(void) | 30 | if (dev == MV88F5182_DEV_ID) |
41 | { | 31 | return MPP_F5182_MASK; |
42 | u32 dev; | ||
43 | u32 rev; | ||
44 | 32 | ||
45 | orion5x_pcie_id(&dev, &rev); | 33 | if (dev == MV88F5281_DEV_ID) |
34 | return MPP_F5281_MASK; | ||
46 | 35 | ||
47 | return !!(dev == MV88F5281_DEV_ID); | 36 | printk(KERN_ERR "MPP setup: unknown orion5x variant " |
37 | "(dev %#x rev %#x)\n", dev, rev); | ||
38 | return 0; | ||
48 | } | 39 | } |
49 | 40 | ||
50 | static int __init determine_type_encoding(int mpp, enum orion5x_mpp_type type) | 41 | void __init orion5x_mpp_conf(unsigned int *mpp_list) |
51 | { | 42 | { |
52 | switch (type) { | 43 | orion_mpp_conf(mpp_list, orion5x_variant(), |
53 | case MPP_UNUSED: | 44 | MPP_MAX, ORION5X_DEV_BUS_VIRT_BASE); |
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 | |||
121 | void __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 | } | 45 | } |