aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreric miao <eric.miao@marvell.com>2008-01-02 22:25:56 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-01-26 10:07:56 -0500
commit7f7c8a619253c83cf3b1071df3b001811d0c1a6c (patch)
treeb4a80e57ef93e3d669e1cadb561ba975e2ce2228
parent0ad1fbc86045c2a27ff082c02344131be072699f (diff)
[ARM] pxa: make MFP configuration processor independent
There are two reasons for making the MFP configuration to be processor independent, i.e. removing the relationship of configuration bits with actual MFPR register settings: 1. power management sometimes requires the MFP to be configured differently when in run mode or in low power mode 2. for future integration of pxa{25x,27x} GPIO configurations The modifications include: 1. introducing of processor independent MFP configuration bits, as defined in [include/asm-arm/arch-pxa/mfp.h]: bit 0.. 9 - MFP Pin Number (1024 Pins Maximum) bit 10..12 - Alternate Function Selection bit 13..15 - Drive Strength bit 16..18 - Low Power Mode State bit 19..20 - Low Power Mode Edge Detection bit 21..22 - Run Mode Pull State and so on, 2. moving the processor dependent code from mfp.h into mfp-pxa3xx.h 3. cleaning up of the MFPR bit definitions 4. mapping of processor independent MFP configuration into processor specific MFPR register settings is now totally encapsulated within pxa3xx_mfp_config() 5. using of "unsigned long" instead of invented type of "mfp_cfg_t" according to Documentation/CodingStyle Chapter 5, usage of this in platform code will be slowly removed in later patches Signed-off-by: eric miao <eric.miao@marvell.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mach-pxa/mfp.c97
-rw-r--r--include/asm-arm/arch-pxa/mfp-pxa3xx.h115
-rw-r--r--include/asm-arm/arch-pxa/mfp.h262
3 files changed, 265 insertions, 209 deletions
diff --git a/arch/arm/mach-pxa/mfp.c b/arch/arm/mach-pxa/mfp.c
index 785ae0ddb84f..c66b1cd7df64 100644
--- a/arch/arm/mach-pxa/mfp.c
+++ b/arch/arm/mach-pxa/mfp.c
@@ -20,6 +20,7 @@
20 20
21#include <asm/hardware.h> 21#include <asm/hardware.h>
22#include <asm/arch/mfp.h> 22#include <asm/arch/mfp.h>
23#include <asm/arch/mfp-pxa3xx.h>
23 24
24/* mfp_spin_lock is used to ensure that MFP register configuration 25/* mfp_spin_lock is used to ensure that MFP register configuration
25 * (most likely a read-modify-write operation) is atomic, and that 26 * (most likely a read-modify-write operation) is atomic, and that
@@ -28,43 +29,105 @@
28static DEFINE_SPINLOCK(mfp_spin_lock); 29static DEFINE_SPINLOCK(mfp_spin_lock);
29 30
30static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE); 31static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE);
32
33struct pxa3xx_mfp_pin {
34 unsigned long config; /* -1 for not configured */
35 unsigned long mfpr_off; /* MFPRxx Register offset */
36 unsigned long mfpr_run; /* Run-Mode Register Value */
37 unsigned long mfpr_lpm; /* Low Power Mode Register Value */
38};
39
31static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX]; 40static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX];
32 41
42/* mapping of MFP_LPM_* definitions to MFPR_LPM_* register bits */
43const static unsigned long mfpr_lpm[] = {
44 MFPR_LPM_INPUT,
45 MFPR_LPM_DRIVE_LOW,
46 MFPR_LPM_DRIVE_HIGH,
47 MFPR_LPM_PULL_LOW,
48 MFPR_LPM_PULL_HIGH,
49 MFPR_LPM_FLOAT,
50};
51
52/* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */
53const static unsigned long mfpr_pull[] = {
54 MFPR_PULL_NONE,
55 MFPR_PULL_LOW,
56 MFPR_PULL_HIGH,
57 MFPR_PULL_BOTH,
58};
59
60/* mapping of MFP_LPM_EDGE_* definitions to MFPR_EDGE_* register bits */
61const static unsigned long mfpr_edge[] = {
62 MFPR_EDGE_NONE,
63 MFPR_EDGE_RISE,
64 MFPR_EDGE_FALL,
65 MFPR_EDGE_BOTH,
66};
67
33#define mfpr_readl(off) \ 68#define mfpr_readl(off) \
34 __raw_readl(mfpr_mmio_base + (off)) 69 __raw_readl(mfpr_mmio_base + (off))
35 70
36#define mfpr_writel(off, val) \ 71#define mfpr_writel(off, val) \
37 __raw_writel(val, mfpr_mmio_base + (off)) 72 __raw_writel(val, mfpr_mmio_base + (off))
38 73
74#define mfp_configured(p) ((p)->config != -1)
75
39/* 76/*
40 * perform a read-back of any MFPR register to make sure the 77 * perform a read-back of any MFPR register to make sure the
41 * previous writings are finished 78 * previous writings are finished
42 */ 79 */
43#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0) 80#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0)
44 81
45static inline void __mfp_config(int pin, unsigned long val) 82static inline void __mfp_config_run(struct pxa3xx_mfp_pin *p)
46{ 83{
47 unsigned long off = mfp_table[pin].mfpr_off; 84 if (mfp_configured(p))
85 mfpr_writel(p->mfpr_off, p->mfpr_run);
86}
48 87
49 mfp_table[pin].mfpr_val = val; 88static inline void __mfp_config_lpm(struct pxa3xx_mfp_pin *p)
50 mfpr_writel(off, val); 89{
90 if (mfp_configured(p) && p->mfpr_lpm != p->mfpr_run)
91 mfpr_writel(p->mfpr_off, p->mfpr_lpm);
51} 92}
52 93
53void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num) 94void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num)
54{ 95{
55 int i, pin; 96 unsigned long flags;
56 unsigned long val, flags; 97 int i;
57 mfp_cfg_t *mfp_cfg = mfp_cfgs;
58 98
59 spin_lock_irqsave(&mfp_spin_lock, flags); 99 spin_lock_irqsave(&mfp_spin_lock, flags);
60 100
61 for (i = 0; i < num; i++, mfp_cfg++) { 101 for (i = 0; i < num; i++, mfp_cfgs++) {
62 pin = MFP_CFG_PIN(*mfp_cfg); 102 unsigned long tmp, c = *mfp_cfgs;
63 val = MFP_CFG_VAL(*mfp_cfg); 103 struct pxa3xx_mfp_pin *p;
104 int pin, af, drv, lpm, edge, pull;
64 105
106 pin = MFP_PIN(c);
65 BUG_ON(pin >= MFP_PIN_MAX); 107 BUG_ON(pin >= MFP_PIN_MAX);
66 108 p = &mfp_table[pin];
67 __mfp_config(pin, val); 109
110 af = MFP_AF(c);
111 drv = MFP_DS(c);
112 lpm = MFP_LPM_STATE(c);
113 edge = MFP_LPM_EDGE(c);
114 pull = MFP_PULL(c);
115
116 /* run-mode pull settings will conflict with MFPR bits of
117 * low power mode state, calculate mfpr_run and mfpr_lpm
118 * individually if pull != MFP_PULL_NONE
119 */
120 tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv);
121
122 if (likely(pull == MFP_PULL_NONE)) {
123 p->mfpr_run = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
124 p->mfpr_lpm = p->mfpr_run;
125 } else {
126 p->mfpr_lpm = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
127 p->mfpr_run = tmp | mfpr_pull[pull];
128 }
129
130 p->config = c; __mfp_config_run(p);
68 } 131 }
69 132
70 mfpr_sync(); 133 mfpr_sync();
@@ -110,7 +173,8 @@ void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map)
110 173
111 do { 174 do {
112 mfp_table[i].mfpr_off = offset; 175 mfp_table[i].mfpr_off = offset;
113 mfp_table[i].mfpr_val = 0; 176 mfp_table[i].mfpr_run = 0;
177 mfp_table[i].mfpr_lpm = 0;
114 offset += 4; i++; 178 offset += 4; i++;
115 } while ((i <= p->end) && (p->end != -1)); 179 } while ((i <= p->end) && (p->end != -1));
116 } 180 }
@@ -120,5 +184,8 @@ void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map)
120 184
121void __init pxa3xx_init_mfp(void) 185void __init pxa3xx_init_mfp(void)
122{ 186{
123 memset(mfp_table, 0, sizeof(mfp_table)); 187 int i;
188
189 for (i = 0; i < ARRAY_SIZE(mfp_table); i++)
190 mfp_table[i].config = -1;
124} 191}
diff --git a/include/asm-arm/arch-pxa/mfp-pxa3xx.h b/include/asm-arm/arch-pxa/mfp-pxa3xx.h
index 5da1857d5476..1f6b35c015d0 100644
--- a/include/asm-arm/arch-pxa/mfp-pxa3xx.h
+++ b/include/asm-arm/arch-pxa/mfp-pxa3xx.h
@@ -1,6 +1,69 @@
1#ifndef __ASM_ARCH_MFP_PXA3XX_H 1#ifndef __ASM_ARCH_MFP_PXA3XX_H
2#define __ASM_ARCH_MFP_PXA3XX_H 2#define __ASM_ARCH_MFP_PXA3XX_H
3 3
4#define MFPR_BASE (0x40e10000)
5#define MFPR_SIZE (PAGE_SIZE)
6
7/* MFPR register bit definitions */
8#define MFPR_PULL_SEL (0x1 << 15)
9#define MFPR_PULLUP_EN (0x1 << 14)
10#define MFPR_PULLDOWN_EN (0x1 << 13)
11#define MFPR_SLEEP_SEL (0x1 << 9)
12#define MFPR_SLEEP_OE_N (0x1 << 7)
13#define MFPR_EDGE_CLEAR (0x1 << 6)
14#define MFPR_EDGE_FALL_EN (0x1 << 5)
15#define MFPR_EDGE_RISE_EN (0x1 << 4)
16
17#define MFPR_SLEEP_DATA(x) ((x) << 8)
18#define MFPR_DRIVE(x) (((x) & 0x7) << 10)
19#define MFPR_AF_SEL(x) (((x) & 0x7) << 0)
20
21#define MFPR_EDGE_NONE (0)
22#define MFPR_EDGE_RISE (MFPR_EDGE_RISE_EN)
23#define MFPR_EDGE_FALL (MFPR_EDGE_FALL_EN)
24#define MFPR_EDGE_BOTH (MFPR_EDGE_RISE | MFPR_EDGE_FALL)
25
26/*
27 * Table that determines the low power modes outputs, with actual settings
28 * used in parentheses for don't-care values. Except for the float output,
29 * the configured driven and pulled levels match, so if there is a need for
30 * non-LPM pulled output, the same configuration could probably be used.
31 *
32 * Output value sleep_oe_n sleep_data pullup_en pulldown_en pull_sel
33 * (bit 7) (bit 8) (bit 14) (bit 13) (bit 15)
34 *
35 * Input 0 X(0) X(0) X(0) 0
36 * Drive 0 0 0 0 X(1) 0
37 * Drive 1 0 1 X(1) 0 0
38 * Pull hi (1) 1 X(1) 1 0 0
39 * Pull lo (0) 1 X(0) 0 1 0
40 * Z (float) 1 X(0) 0 0 0
41 */
42#define MFPR_LPM_INPUT (0)
43#define MFPR_LPM_DRIVE_LOW (MFPR_SLEEP_DATA(0) | MFPR_PULLDOWN_EN)
44#define MFPR_LPM_DRIVE_HIGH (MFPR_SLEEP_DATA(1) | MFPR_PULLUP_EN)
45#define MFPR_LPM_PULL_LOW (MFPR_LPM_DRIVE_LOW | MFPR_SLEEP_OE_N)
46#define MFPR_LPM_PULL_HIGH (MFPR_LPM_DRIVE_HIGH | MFPR_SLEEP_OE_N)
47#define MFPR_LPM_FLOAT (MFPR_SLEEP_OE_N)
48#define MFPR_LPM_MASK (0xe080)
49
50/*
51 * The pullup and pulldown state of the MFP pin at run mode is by default
52 * determined by the selected alternate function. In case that some buggy
53 * devices need to override this default behavior, the definitions below
54 * indicates the setting of corresponding MFPR bits
55 *
56 * Definition pull_sel pullup_en pulldown_en
57 * MFPR_PULL_NONE 0 0 0
58 * MFPR_PULL_LOW 1 0 1
59 * MFPR_PULL_HIGH 1 1 0
60 * MFPR_PULL_BOTH 1 1 1
61 */
62#define MFPR_PULL_NONE (0)
63#define MFPR_PULL_LOW (MFPR_PULL_SEL | MFPR_PULLDOWN_EN)
64#define MFPR_PULL_BOTH (MFPR_PULL_LOW | MFPR_PULLUP_EN)
65#define MFPR_PULL_HIGH (MFPR_PULL_SEL | MFPR_PULLUP_EN)
66
4/* PXA3xx common MFP configurations - processor specific ones defined 67/* PXA3xx common MFP configurations - processor specific ones defined
5 * in mfp-pxa300.h and mfp-pxa320.h 68 * in mfp-pxa300.h and mfp-pxa320.h
6 */ 69 */
@@ -134,4 +197,56 @@
134#define GPIO5_2_GPIO MFP_CFG(GPIO5_2, AF0) 197#define GPIO5_2_GPIO MFP_CFG(GPIO5_2, AF0)
135#define GPIO6_2_GPIO MFP_CFG(GPIO6_2, AF0) 198#define GPIO6_2_GPIO MFP_CFG(GPIO6_2, AF0)
136 199
200/*
201 * each MFP pin will have a MFPR register, since the offset of the
202 * register varies between processors, the processor specific code
203 * should initialize the pin offsets by pxa3xx_mfp_init_addr()
204 *
205 * pxa3xx_mfp_init_addr - accepts a table of "pxa3xx_mfp_addr_map"
206 * structure, which represents a range of MFP pins from "start" to
207 * "end", with the offset begining at "offset", to define a single
208 * pin, let "end" = -1
209 *
210 * use
211 *
212 * MFP_ADDR_X() to define a range of pins
213 * MFP_ADDR() to define a single pin
214 * MFP_ADDR_END to signal the end of pin offset definitions
215 */
216struct pxa3xx_mfp_addr_map {
217 unsigned int start;
218 unsigned int end;
219 unsigned long offset;
220};
221
222#define MFP_ADDR_X(start, end, offset) \
223 { MFP_PIN_##start, MFP_PIN_##end, offset }
224
225#define MFP_ADDR(pin, offset) \
226 { MFP_PIN_##pin, -1, offset }
227
228#define MFP_ADDR_END { MFP_PIN_INVALID, 0 }
229
230/*
231 * pxa3xx_mfp_read()/pxa3xx_mfp_write() - for direct read/write access
232 * to the MFPR register
233 */
234unsigned long pxa3xx_mfp_read(int mfp);
235void pxa3xx_mfp_write(int mfp, unsigned long mfpr_val);
236
237/*
238 * pxa3xx_mfp_config - configure the MFPR registers
239 *
240 * used by board specific initialization code
241 */
242void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num);
243
244/*
245 * pxa3xx_mfp_init_addr() - initialize the mapping between mfp pin
246 * index and MFPR register offset
247 *
248 * used by processor specific code
249 */
250void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *);
251void __init pxa3xx_init_mfp(void);
137#endif /* __ASM_ARCH_MFP_PXA3XX_H */ 252#endif /* __ASM_ARCH_MFP_PXA3XX_H */
diff --git a/include/asm-arm/arch-pxa/mfp.h b/include/asm-arm/arch-pxa/mfp.h
index 60fbed1b2e89..02f6157396d3 100644
--- a/include/asm-arm/arch-pxa/mfp.h
+++ b/include/asm-arm/arch-pxa/mfp.h
@@ -16,9 +16,6 @@
16#ifndef __ASM_ARCH_MFP_H 16#ifndef __ASM_ARCH_MFP_H
17#define __ASM_ARCH_MFP_H 17#define __ASM_ARCH_MFP_H
18 18
19#define MFPR_BASE (0x40e10000)
20#define MFPR_SIZE (PAGE_SIZE)
21
22#define mfp_to_gpio(m) ((m) % 128) 19#define mfp_to_gpio(m) ((m) % 128)
23 20
24/* list of all the configurable MFP pins */ 21/* list of all the configurable MFP pins */
@@ -217,114 +214,21 @@ enum {
217}; 214};
218 215
219/* 216/*
220 * Table that determines the low power modes outputs, with actual settings
221 * used in parentheses for don't-care values. Except for the float output,
222 * the configured driven and pulled levels match, so if there is a need for
223 * non-LPM pulled output, the same configuration could probably be used.
224 *
225 * Output value sleep_oe_n sleep_data pullup_en pulldown_en pull_sel
226 * (bit 7) (bit 8) (bit 14d) (bit 13d)
227 *
228 * Drive 0 0 0 0 X (1) 0
229 * Drive 1 0 1 X (1) 0 0
230 * Pull hi (1) 1 X(1) 1 0 0
231 * Pull lo (0) 1 X(0) 0 1 0
232 * Z (float) 1 X(0) 0 0 0
233 */
234#define MFP_LPM_DRIVE_LOW 0x8
235#define MFP_LPM_DRIVE_HIGH 0x6
236#define MFP_LPM_PULL_HIGH 0x7
237#define MFP_LPM_PULL_LOW 0x9
238#define MFP_LPM_FLOAT 0x1
239#define MFP_LPM_PULL_NEITHER 0x0
240
241/*
242 * The pullup and pulldown state of the MFP pin is by default determined by
243 * selected alternate function. In case some buggy devices need to override
244 * this default behavior, pxa3xx_mfp_set_pull() can be invoked with one of
245 * the following definition as the parameter.
246 *
247 * Definition pull_sel pullup_en pulldown_en
248 * MFP_PULL_HIGH 1 1 0
249 * MFP_PULL_LOW 1 0 1
250 * MFP_PULL_BOTH 1 1 1
251 * MFP_PULL_NONE 1 0 0
252 * MFP_PULL_DEFAULT 0 X X
253 *
254 * NOTE: pxa3xx_mfp_set_pull() will modify the PULLUP_EN and PULLDOWN_EN
255 * bits, which will cause potential conflicts with the low power mode
256 * setting, device drivers should take care of this
257 */
258#define MFP_PULL_BOTH (0x7u)
259#define MFP_PULL_HIGH (0x6u)
260#define MFP_PULL_LOW (0x5u)
261#define MFP_PULL_NONE (0x4u)
262#define MFP_PULL_DEFAULT (0x0u)
263
264#define MFP_AF0 (0)
265#define MFP_AF1 (1)
266#define MFP_AF2 (2)
267#define MFP_AF3 (3)
268#define MFP_AF4 (4)
269#define MFP_AF5 (5)
270#define MFP_AF6 (6)
271#define MFP_AF7 (7)
272
273#define MFP_DS01X (0)
274#define MFP_DS02X (1)
275#define MFP_DS03X (2)
276#define MFP_DS04X (3)
277#define MFP_DS06X (4)
278#define MFP_DS08X (5)
279#define MFP_DS10X (6)
280#define MFP_DS12X (7)
281
282#define MFP_EDGE_BOTH 0x3
283#define MFP_EDGE_RISE 0x2
284#define MFP_EDGE_FALL 0x1
285#define MFP_EDGE_NONE 0x0
286
287#define MFPR_AF_MASK 0x0007
288#define MFPR_DRV_MASK 0x1c00
289#define MFPR_RDH_MASK 0x0200
290#define MFPR_LPM_MASK 0xe180
291#define MFPR_PULL_MASK 0xe000
292#define MFPR_EDGE_MASK 0x0070
293
294#define MFPR_ALT_OFFSET 0
295#define MFPR_ERE_OFFSET 4
296#define MFPR_EFE_OFFSET 5
297#define MFPR_EC_OFFSET 6
298#define MFPR_SON_OFFSET 7
299#define MFPR_SD_OFFSET 8
300#define MFPR_SS_OFFSET 9
301#define MFPR_DRV_OFFSET 10
302#define MFPR_PD_OFFSET 13
303#define MFPR_PU_OFFSET 14
304#define MFPR_PS_OFFSET 15
305
306#define MFPR(af, drv, rdh, lpm, edge) \
307 (((af) & 0x7) | (((drv) & 0x7) << 10) |\
308 (((rdh) & 0x1) << 9) |\
309 (((lpm) & 0x3) << 7) |\
310 (((lpm) & 0x4) << 12)|\
311 (((lpm) & 0x8) << 10)|\
312 ((!(edge)) << 6) |\
313 (((edge) & 0x1) << 5) |\
314 (((edge) & 0x2) << 3))
315
316/*
317 * a possible MFP configuration is represented by a 32-bit integer 217 * a possible MFP configuration is represented by a 32-bit integer
318 * bit 0..15 - MFPR value (16-bit) 218 *
319 * bit 16..31 - mfp pin index (used to obtain the MFPR offset) 219 * bit 0.. 9 - MFP Pin Number (1024 Pins Maximum)
220 * bit 10..12 - Alternate Function Selection
221 * bit 13..15 - Drive Strength
222 * bit 16..18 - Low Power Mode State
223 * bit 19..20 - Low Power Mode Edge Detection
224 * bit 21..22 - Run Mode Pull State
320 * 225 *
321 * to facilitate the definition, the following macros are provided 226 * to facilitate the definition, the following macros are provided
322 * 227 *
323 * MFPR_DEFAULT - default MFPR value, with 228 * MFP_CFG_DEFAULT - default MFP configuration value, with
324 * alternate function = 0, 229 * alternate function = 0,
325 * drive strength = fast 1mA (MFP_DS01X) 230 * drive strength = fast 3mA (MFP_DS03X)
326 * low power mode = default 231 * low power mode = default
327 * release dalay hold = false (RDH bit)
328 * edge detection = none 232 * edge detection = none
329 * 233 *
330 * MFP_CFG - default MFPR value with alternate function 234 * MFP_CFG - default MFPR value with alternate function
@@ -334,104 +238,74 @@ enum {
334 * low power mode 238 * low power mode
335 * MFP_CFG_X - default MFPR value with alternate function, 239 * MFP_CFG_X - default MFPR value with alternate function,
336 * pin drive strength and low power mode 240 * pin drive strength and low power mode
337 *
338 * use
339 *
340 * MFP_CFG_PIN - to get the MFP pin index
341 * MFP_CFG_VAL - to get the corresponding MFPR value
342 */ 241 */
343 242
344typedef uint32_t mfp_cfg_t; 243typedef unsigned long mfp_cfg_t;
345 244
346#define MFP_CFG_PIN(mfp_cfg) (((mfp_cfg) >> 16) & 0xffff) 245#define MFP_PIN(x) ((x) & 0x3ff)
347#define MFP_CFG_VAL(mfp_cfg) ((mfp_cfg) & 0xffff) 246
348 247#define MFP_AF0 (0x0 << 10)
349/* 248#define MFP_AF1 (0x1 << 10)
350 * MFP register defaults to 249#define MFP_AF2 (0x2 << 10)
351 * drive strength fast 3mA (010'b) 250#define MFP_AF3 (0x3 << 10)
352 * edge detection logic disabled 251#define MFP_AF4 (0x4 << 10)
353 * alternate function 0 252#define MFP_AF5 (0x5 << 10)
354 */ 253#define MFP_AF6 (0x6 << 10)
355#define MFPR_DEFAULT (0x0840) 254#define MFP_AF7 (0x7 << 10)
255#define MFP_AF_MASK (0x7 << 10)
256#define MFP_AF(x) (((x) >> 10) & 0x7)
257
258#define MFP_DS01X (0x0 << 13)
259#define MFP_DS02X (0x1 << 13)
260#define MFP_DS03X (0x2 << 13)
261#define MFP_DS04X (0x3 << 13)
262#define MFP_DS06X (0x4 << 13)
263#define MFP_DS08X (0x5 << 13)
264#define MFP_DS10X (0x6 << 13)
265#define MFP_DS13X (0x7 << 13)
266#define MFP_DS_MASK (0x7 << 13)
267#define MFP_DS(x) (((x) >> 13) & 0x7)
268
269#define MFP_LPM_INPUT (0x0 << 16)
270#define MFP_LPM_DRIVE_LOW (0x1 << 16)
271#define MFP_LPM_DRIVE_HIGH (0x2 << 16)
272#define MFP_LPM_PULL_LOW (0x3 << 16)
273#define MFP_LPM_PULL_HIGH (0x4 << 16)
274#define MFP_LPM_FLOAT (0x5 << 16)
275#define MFP_LPM_STATE_MASK (0x7 << 16)
276#define MFP_LPM_STATE(x) (((x) >> 16) & 0x7)
277
278#define MFP_LPM_EDGE_NONE (0x0 << 19)
279#define MFP_LPM_EDGE_RISE (0x1 << 19)
280#define MFP_LPM_EDGE_FALL (0x2 << 19)
281#define MFP_LPM_EDGE_BOTH (0x3 << 19)
282#define MFP_LPM_EDGE_MASK (0x3 << 19)
283#define MFP_LPM_EDGE(x) (((x) >> 19) & 0x3)
284
285#define MFP_PULL_NONE (0x0 << 21)
286#define MFP_PULL_LOW (0x1 << 21)
287#define MFP_PULL_HIGH (0x2 << 21)
288#define MFP_PULL_BOTH (0x3 << 21)
289#define MFP_PULL_MASK (0x3 << 21)
290#define MFP_PULL(x) (((x) >> 21) & 0x3)
291
292#define MFP_CFG_DEFAULT (MFP_AF0 | MFP_DS03X | MFP_LPM_INPUT |\
293 MFP_LPM_EDGE_NONE | MFP_PULL_NONE)
356 294
357#define MFP_CFG(pin, af) \ 295#define MFP_CFG(pin, af) \
358 ((MFP_PIN_##pin << 16) | MFPR_DEFAULT | (MFP_##af)) 296 ((MFP_CFG_DEFAULT & ~MFP_AF_MASK) |\
297 (MFP_PIN(MFP_PIN_##pin) | MFP_##af))
359 298
360#define MFP_CFG_DRV(pin, af, drv) \ 299#define MFP_CFG_DRV(pin, af, drv) \
361 ((MFP_PIN_##pin << 16) | (MFPR_DEFAULT & ~MFPR_DRV_MASK) |\ 300 ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK)) |\
362 ((MFP_##drv) << 10) | (MFP_##af)) 301 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv))
363 302
364#define MFP_CFG_LPM(pin, af, lpm) \ 303#define MFP_CFG_LPM(pin, af, lpm) \
365 ((MFP_PIN_##pin << 16) | (MFPR_DEFAULT & ~MFPR_LPM_MASK) |\ 304 ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_LPM_STATE_MASK)) |\
366 (((MFP_LPM_##lpm) & 0x3) << 7) |\ 305 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_LPM_##lpm))
367 (((MFP_LPM_##lpm) & 0x4) << 12) |\
368 (((MFP_LPM_##lpm) & 0x8) << 10) |\
369 (MFP_##af))
370 306
371#define MFP_CFG_X(pin, af, drv, lpm) \ 307#define MFP_CFG_X(pin, af, drv, lpm) \
372 ((MFP_PIN_##pin << 16) |\ 308 ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\
373 (MFPR_DEFAULT & ~(MFPR_DRV_MASK | MFPR_LPM_MASK)) |\ 309 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm))
374 ((MFP_##drv) << 10) | (MFP_##af) |\
375 (((MFP_LPM_##lpm) & 0x3) << 7) |\
376 (((MFP_LPM_##lpm) & 0x4) << 12) |\
377 (((MFP_LPM_##lpm) & 0x8) << 10))
378
379/*
380 * each MFP pin will have a MFPR register, since the offset of the
381 * register varies between processors, the processor specific code
382 * should initialize the pin offsets by pxa3xx_mfp_init_addr()
383 *
384 * pxa3xx_mfp_init_addr - accepts a table of "pxa3xx_mfp_addr_map"
385 * structure, which represents a range of MFP pins from "start" to
386 * "end", with the offset begining at "offset", to define a single
387 * pin, let "end" = -1
388 *
389 * use
390 *
391 * MFP_ADDR_X() to define a range of pins
392 * MFP_ADDR() to define a single pin
393 * MFP_ADDR_END to signal the end of pin offset definitions
394 */
395struct pxa3xx_mfp_addr_map {
396 unsigned int start;
397 unsigned int end;
398 unsigned long offset;
399};
400
401#define MFP_ADDR_X(start, end, offset) \
402 { MFP_PIN_##start, MFP_PIN_##end, offset }
403
404#define MFP_ADDR(pin, offset) \
405 { MFP_PIN_##pin, -1, offset }
406
407#define MFP_ADDR_END { MFP_PIN_INVALID, 0 }
408
409struct pxa3xx_mfp_pin {
410 unsigned long mfpr_off; /* MFPRxx register offset */
411 unsigned long mfpr_val; /* MFPRxx register value */
412};
413
414/*
415 * pxa3xx_mfp_read()/pxa3xx_mfp_write() - for direct read/write access
416 * to the MFPR register
417 */
418unsigned long pxa3xx_mfp_read(int mfp);
419void pxa3xx_mfp_write(int mfp, unsigned long mfpr_val);
420
421/*
422 * pxa3xx_mfp_config - configure the MFPR registers
423 *
424 * used by board specific initialization code
425 */
426void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num);
427
428/*
429 * pxa3xx_mfp_init_addr() - initialize the mapping between mfp pin
430 * index and MFPR register offset
431 *
432 * used by processor specific code
433 */
434void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *);
435void __init pxa3xx_init_mfp(void);
436 310
437#endif /* __ASM_ARCH_MFP_H */ 311#endif /* __ASM_ARCH_MFP_H */