Merge branches 'release', 'cpuidle-2.6.25' and 'idle' into release
[linux-2.6] / arch / powerpc / sysdev / cpm2.c
1 /*
2  * General Purpose functions for the global management of the
3  * 8260 Communication Processor Module.
4  * Copyright (c) 1999-2001 Dan Malek <dan@embeddedalley.com>
5  * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
6  *      2.3.99 Updates
7  *
8  * 2006 (c) MontaVista Software, Inc.
9  * Vitaly Bordug <vbordug@ru.mvista.com>
10  *      Merged to arch/powerpc from arch/ppc/syslib/cpm2_common.c
11  *
12  * This file is licensed under the terms of the GNU General Public License
13  * version 2. This program is licensed "as is" without any warranty of any
14  * kind, whether express or implied.
15  */
16
17 /*
18  *
19  * In addition to the individual control of the communication
20  * channels, there are a few functions that globally affect the
21  * communication processor.
22  *
23  * Buffer descriptors must be allocated from the dual ported memory
24  * space.  The allocator for that is here.  When the communication
25  * process is reset, we reclaim the memory available.  There is
26  * currently no deallocator for this memory.
27  */
28 #include <linux/errno.h>
29 #include <linux/sched.h>
30 #include <linux/kernel.h>
31 #include <linux/param.h>
32 #include <linux/string.h>
33 #include <linux/mm.h>
34 #include <linux/interrupt.h>
35 #include <linux/module.h>
36 #include <linux/of.h>
37
38 #include <asm/io.h>
39 #include <asm/irq.h>
40 #include <asm/mpc8260.h>
41 #include <asm/page.h>
42 #include <asm/pgtable.h>
43 #include <asm/cpm2.h>
44 #include <asm/rheap.h>
45 #include <asm/fs_pd.h>
46
47 #include <sysdev/fsl_soc.h>
48
49 #ifndef CONFIG_PPC_CPM_NEW_BINDING
50 static void cpm2_dpinit(void);
51 #endif
52
53 cpm_cpm2_t __iomem *cpmp; /* Pointer to comm processor space */
54
55 /* We allocate this here because it is used almost exclusively for
56  * the communication processor devices.
57  */
58 cpm2_map_t __iomem *cpm2_immr;
59
60 #define CPM_MAP_SIZE    (0x40000)       /* 256k - the PQ3 reserve this amount
61                                            of space for CPM as it is larger
62                                            than on PQ2 */
63
64 void __init cpm2_reset(void)
65 {
66 #ifdef CONFIG_PPC_85xx
67         cpm2_immr = ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE);
68 #else
69         cpm2_immr = ioremap(get_immrbase(), CPM_MAP_SIZE);
70 #endif
71
72         /* Reclaim the DP memory for our use.
73          */
74 #ifdef CONFIG_PPC_CPM_NEW_BINDING
75         cpm_muram_init();
76 #else
77         cpm2_dpinit();
78 #endif
79
80         /* Tell everyone where the comm processor resides.
81          */
82         cpmp = &cpm2_immr->im_cpm;
83 }
84
85 static DEFINE_SPINLOCK(cmd_lock);
86
87 #define MAX_CR_CMD_LOOPS        10000
88
89 int cpm_command(u32 command, u8 opcode)
90 {
91         int i, ret;
92         unsigned long flags;
93
94         spin_lock_irqsave(&cmd_lock, flags);
95
96         ret = 0;
97         out_be32(&cpmp->cp_cpcr, command | opcode | CPM_CR_FLG);
98         for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
99                 if ((in_be32(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0)
100                         goto out;
101
102         printk(KERN_ERR "%s(): Not able to issue CPM command\n", __FUNCTION__);
103         ret = -EIO;
104 out:
105         spin_unlock_irqrestore(&cmd_lock, flags);
106         return ret;
107 }
108 EXPORT_SYMBOL(cpm_command);
109
110 /* Set a baud rate generator.  This needs lots of work.  There are
111  * eight BRGs, which can be connected to the CPM channels or output
112  * as clocks.  The BRGs are in two different block of internal
113  * memory mapped space.
114  * The baud rate clock is the system clock divided by something.
115  * It was set up long ago during the initial boot phase and is
116  * is given to us.
117  * Baud rate clocks are zero-based in the driver code (as that maps
118  * to port numbers).  Documentation uses 1-based numbering.
119  */
120 #define BRG_INT_CLK     (get_brgfreq())
121 #define BRG_UART_CLK    (BRG_INT_CLK/16)
122
123 /* This function is used by UARTS, or anything else that uses a 16x
124  * oversampled clock.
125  */
126 void
127 cpm_setbrg(uint brg, uint rate)
128 {
129         u32 __iomem *bp;
130
131         /* This is good enough to get SMCs running.....
132         */
133         if (brg < 4) {
134                 bp = cpm2_map_size(im_brgc1, 16);
135         } else {
136                 bp = cpm2_map_size(im_brgc5, 16);
137                 brg -= 4;
138         }
139         bp += brg;
140         out_be32(bp, (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN);
141
142         cpm2_unmap(bp);
143 }
144
145 /* This function is used to set high speed synchronous baud rate
146  * clocks.
147  */
148 void
149 cpm2_fastbrg(uint brg, uint rate, int div16)
150 {
151         u32 __iomem *bp;
152         u32 val;
153
154         if (brg < 4) {
155                 bp = cpm2_map_size(im_brgc1, 16);
156         } else {
157                 bp = cpm2_map_size(im_brgc5, 16);
158                 brg -= 4;
159         }
160         bp += brg;
161         val = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN;
162         if (div16)
163                 val |= CPM_BRG_DIV16;
164
165         out_be32(bp, val);
166         cpm2_unmap(bp);
167 }
168
169 int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
170 {
171         int ret = 0;
172         int shift;
173         int i, bits = 0;
174         cpmux_t __iomem *im_cpmux;
175         u32 __iomem *reg;
176         u32 mask = 7;
177
178         u8 clk_map[][3] = {
179                 {CPM_CLK_FCC1, CPM_BRG5, 0},
180                 {CPM_CLK_FCC1, CPM_BRG6, 1},
181                 {CPM_CLK_FCC1, CPM_BRG7, 2},
182                 {CPM_CLK_FCC1, CPM_BRG8, 3},
183                 {CPM_CLK_FCC1, CPM_CLK9, 4},
184                 {CPM_CLK_FCC1, CPM_CLK10, 5},
185                 {CPM_CLK_FCC1, CPM_CLK11, 6},
186                 {CPM_CLK_FCC1, CPM_CLK12, 7},
187                 {CPM_CLK_FCC2, CPM_BRG5, 0},
188                 {CPM_CLK_FCC2, CPM_BRG6, 1},
189                 {CPM_CLK_FCC2, CPM_BRG7, 2},
190                 {CPM_CLK_FCC2, CPM_BRG8, 3},
191                 {CPM_CLK_FCC2, CPM_CLK13, 4},
192                 {CPM_CLK_FCC2, CPM_CLK14, 5},
193                 {CPM_CLK_FCC2, CPM_CLK15, 6},
194                 {CPM_CLK_FCC2, CPM_CLK16, 7},
195                 {CPM_CLK_FCC3, CPM_BRG5, 0},
196                 {CPM_CLK_FCC3, CPM_BRG6, 1},
197                 {CPM_CLK_FCC3, CPM_BRG7, 2},
198                 {CPM_CLK_FCC3, CPM_BRG8, 3},
199                 {CPM_CLK_FCC3, CPM_CLK13, 4},
200                 {CPM_CLK_FCC3, CPM_CLK14, 5},
201                 {CPM_CLK_FCC3, CPM_CLK15, 6},
202                 {CPM_CLK_FCC3, CPM_CLK16, 7},
203                 {CPM_CLK_SCC1, CPM_BRG1, 0},
204                 {CPM_CLK_SCC1, CPM_BRG2, 1},
205                 {CPM_CLK_SCC1, CPM_BRG3, 2},
206                 {CPM_CLK_SCC1, CPM_BRG4, 3},
207                 {CPM_CLK_SCC1, CPM_CLK11, 4},
208                 {CPM_CLK_SCC1, CPM_CLK12, 5},
209                 {CPM_CLK_SCC1, CPM_CLK3, 6},
210                 {CPM_CLK_SCC1, CPM_CLK4, 7},
211                 {CPM_CLK_SCC2, CPM_BRG1, 0},
212                 {CPM_CLK_SCC2, CPM_BRG2, 1},
213                 {CPM_CLK_SCC2, CPM_BRG3, 2},
214                 {CPM_CLK_SCC2, CPM_BRG4, 3},
215                 {CPM_CLK_SCC2, CPM_CLK11, 4},
216                 {CPM_CLK_SCC2, CPM_CLK12, 5},
217                 {CPM_CLK_SCC2, CPM_CLK3, 6},
218                 {CPM_CLK_SCC2, CPM_CLK4, 7},
219                 {CPM_CLK_SCC3, CPM_BRG1, 0},
220                 {CPM_CLK_SCC3, CPM_BRG2, 1},
221                 {CPM_CLK_SCC3, CPM_BRG3, 2},
222                 {CPM_CLK_SCC3, CPM_BRG4, 3},
223                 {CPM_CLK_SCC3, CPM_CLK5, 4},
224                 {CPM_CLK_SCC3, CPM_CLK6, 5},
225                 {CPM_CLK_SCC3, CPM_CLK7, 6},
226                 {CPM_CLK_SCC3, CPM_CLK8, 7},
227                 {CPM_CLK_SCC4, CPM_BRG1, 0},
228                 {CPM_CLK_SCC4, CPM_BRG2, 1},
229                 {CPM_CLK_SCC4, CPM_BRG3, 2},
230                 {CPM_CLK_SCC4, CPM_BRG4, 3},
231                 {CPM_CLK_SCC4, CPM_CLK5, 4},
232                 {CPM_CLK_SCC4, CPM_CLK6, 5},
233                 {CPM_CLK_SCC4, CPM_CLK7, 6},
234                 {CPM_CLK_SCC4, CPM_CLK8, 7},
235         };
236
237         im_cpmux = cpm2_map(im_cpmux);
238
239         switch (target) {
240         case CPM_CLK_SCC1:
241                 reg = &im_cpmux->cmx_scr;
242                 shift = 24;
243         case CPM_CLK_SCC2:
244                 reg = &im_cpmux->cmx_scr;
245                 shift = 16;
246                 break;
247         case CPM_CLK_SCC3:
248                 reg = &im_cpmux->cmx_scr;
249                 shift = 8;
250                 break;
251         case CPM_CLK_SCC4:
252                 reg = &im_cpmux->cmx_scr;
253                 shift = 0;
254                 break;
255         case CPM_CLK_FCC1:
256                 reg = &im_cpmux->cmx_fcr;
257                 shift = 24;
258                 break;
259         case CPM_CLK_FCC2:
260                 reg = &im_cpmux->cmx_fcr;
261                 shift = 16;
262                 break;
263         case CPM_CLK_FCC3:
264                 reg = &im_cpmux->cmx_fcr;
265                 shift = 8;
266                 break;
267         default:
268                 printk(KERN_ERR "cpm2_clock_setup: invalid clock target\n");
269                 return -EINVAL;
270         }
271
272         if (mode == CPM_CLK_RX)
273                 shift += 3;
274
275         for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
276                 if (clk_map[i][0] == target && clk_map[i][1] == clock) {
277                         bits = clk_map[i][2];
278                         break;
279                 }
280         }
281         if (i == ARRAY_SIZE(clk_map))
282             ret = -EINVAL;
283
284         bits <<= shift;
285         mask <<= shift;
286
287         out_be32(reg, (in_be32(reg) & ~mask) | bits);
288
289         cpm2_unmap(im_cpmux);
290         return ret;
291 }
292
293 int cpm2_smc_clk_setup(enum cpm_clk_target target, int clock)
294 {
295         int ret = 0;
296         int shift;
297         int i, bits = 0;
298         cpmux_t __iomem *im_cpmux;
299         u8 __iomem *reg;
300         u8 mask = 3;
301
302         u8 clk_map[][3] = {
303                 {CPM_CLK_SMC1, CPM_BRG1, 0},
304                 {CPM_CLK_SMC1, CPM_BRG7, 1},
305                 {CPM_CLK_SMC1, CPM_CLK7, 2},
306                 {CPM_CLK_SMC1, CPM_CLK9, 3},
307                 {CPM_CLK_SMC2, CPM_BRG2, 0},
308                 {CPM_CLK_SMC2, CPM_BRG8, 1},
309                 {CPM_CLK_SMC2, CPM_CLK4, 2},
310                 {CPM_CLK_SMC2, CPM_CLK15, 3},
311         };
312
313         im_cpmux = cpm2_map(im_cpmux);
314
315         switch (target) {
316         case CPM_CLK_SMC1:
317                 reg = &im_cpmux->cmx_smr;
318                 mask = 3;
319                 shift = 4;
320                 break;
321         case CPM_CLK_SMC2:
322                 reg = &im_cpmux->cmx_smr;
323                 mask = 3;
324                 shift = 0;
325                 break;
326         default:
327                 printk(KERN_ERR "cpm2_smc_clock_setup: invalid clock target\n");
328                 return -EINVAL;
329         }
330
331         for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
332                 if (clk_map[i][0] == target && clk_map[i][1] == clock) {
333                         bits = clk_map[i][2];
334                         break;
335                 }
336         }
337         if (i == ARRAY_SIZE(clk_map))
338             ret = -EINVAL;
339
340         bits <<= shift;
341         mask <<= shift;
342
343         out_8(reg, (in_8(reg) & ~mask) | bits);
344
345         cpm2_unmap(im_cpmux);
346         return ret;
347 }
348
349 #ifndef CONFIG_PPC_CPM_NEW_BINDING
350 /*
351  * dpalloc / dpfree bits.
352  */
353 static spinlock_t cpm_dpmem_lock;
354 /* 16 blocks should be enough to satisfy all requests
355  * until the memory subsystem goes up... */
356 static rh_block_t cpm_boot_dpmem_rh_block[16];
357 static rh_info_t cpm_dpmem_info;
358 static u8 __iomem *im_dprambase;
359
360 static void cpm2_dpinit(void)
361 {
362         spin_lock_init(&cpm_dpmem_lock);
363
364         /* initialize the info header */
365         rh_init(&cpm_dpmem_info, 1,
366                         sizeof(cpm_boot_dpmem_rh_block) /
367                         sizeof(cpm_boot_dpmem_rh_block[0]),
368                         cpm_boot_dpmem_rh_block);
369
370         im_dprambase = cpm2_immr;
371
372         /* Attach the usable dpmem area */
373         /* XXX: This is actually crap. CPM_DATAONLY_BASE and
374          * CPM_DATAONLY_SIZE is only a subset of the available dpram. It
375          * varies with the processor and the microcode patches activated.
376          * But the following should be at least safe.
377          */
378         rh_attach_region(&cpm_dpmem_info, CPM_DATAONLY_BASE, CPM_DATAONLY_SIZE);
379 }
380
381 /* This function returns an index into the DPRAM area.
382  */
383 unsigned long cpm_dpalloc(uint size, uint align)
384 {
385         unsigned long start;
386         unsigned long flags;
387
388         spin_lock_irqsave(&cpm_dpmem_lock, flags);
389         cpm_dpmem_info.alignment = align;
390         start = rh_alloc(&cpm_dpmem_info, size, "commproc");
391         spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
392
393         return (uint)start;
394 }
395 EXPORT_SYMBOL(cpm_dpalloc);
396
397 int cpm_dpfree(unsigned long offset)
398 {
399         int ret;
400         unsigned long flags;
401
402         spin_lock_irqsave(&cpm_dpmem_lock, flags);
403         ret = rh_free(&cpm_dpmem_info, offset);
404         spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
405
406         return ret;
407 }
408 EXPORT_SYMBOL(cpm_dpfree);
409
410 /* not sure if this is ever needed */
411 unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align)
412 {
413         unsigned long start;
414         unsigned long flags;
415
416         spin_lock_irqsave(&cpm_dpmem_lock, flags);
417         cpm_dpmem_info.alignment = align;
418         start = rh_alloc_fixed(&cpm_dpmem_info, offset, size, "commproc");
419         spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
420
421         return start;
422 }
423 EXPORT_SYMBOL(cpm_dpalloc_fixed);
424
425 void cpm_dpdump(void)
426 {
427         rh_dump(&cpm_dpmem_info);
428 }
429 EXPORT_SYMBOL(cpm_dpdump);
430
431 void *cpm_dpram_addr(unsigned long offset)
432 {
433         return (void *)(im_dprambase + offset);
434 }
435 EXPORT_SYMBOL(cpm_dpram_addr);
436 #endif /* !CONFIG_PPC_CPM_NEW_BINDING */
437
438 struct cpm2_ioports {
439         u32 dir, par, sor, odr, dat;
440         u32 res[3];
441 };
442
443 void cpm2_set_pin(int port, int pin, int flags)
444 {
445         struct cpm2_ioports __iomem *iop =
446                 (struct cpm2_ioports __iomem *)&cpm2_immr->im_ioport;
447
448         pin = 1 << (31 - pin);
449
450         if (flags & CPM_PIN_OUTPUT)
451                 setbits32(&iop[port].dir, pin);
452         else
453                 clrbits32(&iop[port].dir, pin);
454
455         if (!(flags & CPM_PIN_GPIO))
456                 setbits32(&iop[port].par, pin);
457         else
458                 clrbits32(&iop[port].par, pin);
459
460         if (flags & CPM_PIN_SECONDARY)
461                 setbits32(&iop[port].sor, pin);
462         else
463                 clrbits32(&iop[port].sor, pin);
464
465         if (flags & CPM_PIN_OPENDRAIN)
466                 setbits32(&iop[port].odr, pin);
467         else
468                 clrbits32(&iop[port].odr, pin);
469 }