Pull bugzilla-9194 into release branch
[pandora-kernel.git] / arch / powerpc / sysdev / cpm2_common.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 /* Set a baud rate generator.  This needs lots of work.  There are
86  * eight BRGs, which can be connected to the CPM channels or output
87  * as clocks.  The BRGs are in two different block of internal
88  * memory mapped space.
89  * The baud rate clock is the system clock divided by something.
90  * It was set up long ago during the initial boot phase and is
91  * is given to us.
92  * Baud rate clocks are zero-based in the driver code (as that maps
93  * to port numbers).  Documentation uses 1-based numbering.
94  */
95 #define BRG_INT_CLK     (get_brgfreq())
96 #define BRG_UART_CLK    (BRG_INT_CLK/16)
97
98 /* This function is used by UARTS, or anything else that uses a 16x
99  * oversampled clock.
100  */
101 void
102 cpm_setbrg(uint brg, uint rate)
103 {
104         u32 __iomem *bp;
105
106         /* This is good enough to get SMCs running.....
107         */
108         if (brg < 4) {
109                 bp = cpm2_map_size(im_brgc1, 16);
110         } else {
111                 bp = cpm2_map_size(im_brgc5, 16);
112                 brg -= 4;
113         }
114         bp += brg;
115         out_be32(bp, (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN);
116
117         cpm2_unmap(bp);
118 }
119
120 /* This function is used to set high speed synchronous baud rate
121  * clocks.
122  */
123 void
124 cpm2_fastbrg(uint brg, uint rate, int div16)
125 {
126         u32 __iomem *bp;
127         u32 val;
128
129         if (brg < 4) {
130                 bp = cpm2_map_size(im_brgc1, 16);
131         }
132         else {
133                 bp = cpm2_map_size(im_brgc5, 16);
134                 brg -= 4;
135         }
136         bp += brg;
137         val = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN;
138         if (div16)
139                 val |= CPM_BRG_DIV16;
140
141         out_be32(bp, val);
142         cpm2_unmap(bp);
143 }
144
145 int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
146 {
147         int ret = 0;
148         int shift;
149         int i, bits = 0;
150         cpmux_t __iomem *im_cpmux;
151         u32 __iomem *reg;
152         u32 mask = 7;
153
154         u8 clk_map[][3] = {
155                 {CPM_CLK_FCC1, CPM_BRG5, 0},
156                 {CPM_CLK_FCC1, CPM_BRG6, 1},
157                 {CPM_CLK_FCC1, CPM_BRG7, 2},
158                 {CPM_CLK_FCC1, CPM_BRG8, 3},
159                 {CPM_CLK_FCC1, CPM_CLK9, 4},
160                 {CPM_CLK_FCC1, CPM_CLK10, 5},
161                 {CPM_CLK_FCC1, CPM_CLK11, 6},
162                 {CPM_CLK_FCC1, CPM_CLK12, 7},
163                 {CPM_CLK_FCC2, CPM_BRG5, 0},
164                 {CPM_CLK_FCC2, CPM_BRG6, 1},
165                 {CPM_CLK_FCC2, CPM_BRG7, 2},
166                 {CPM_CLK_FCC2, CPM_BRG8, 3},
167                 {CPM_CLK_FCC2, CPM_CLK13, 4},
168                 {CPM_CLK_FCC2, CPM_CLK14, 5},
169                 {CPM_CLK_FCC2, CPM_CLK15, 6},
170                 {CPM_CLK_FCC2, CPM_CLK16, 7},
171                 {CPM_CLK_FCC3, CPM_BRG5, 0},
172                 {CPM_CLK_FCC3, CPM_BRG6, 1},
173                 {CPM_CLK_FCC3, CPM_BRG7, 2},
174                 {CPM_CLK_FCC3, CPM_BRG8, 3},
175                 {CPM_CLK_FCC3, CPM_CLK13, 4},
176                 {CPM_CLK_FCC3, CPM_CLK14, 5},
177                 {CPM_CLK_FCC3, CPM_CLK15, 6},
178                 {CPM_CLK_FCC3, CPM_CLK16, 7},
179                 {CPM_CLK_SCC1, CPM_BRG1, 0},
180                 {CPM_CLK_SCC1, CPM_BRG2, 1},
181                 {CPM_CLK_SCC1, CPM_BRG3, 2},
182                 {CPM_CLK_SCC1, CPM_BRG4, 3},
183                 {CPM_CLK_SCC1, CPM_CLK11, 4},
184                 {CPM_CLK_SCC1, CPM_CLK12, 5},
185                 {CPM_CLK_SCC1, CPM_CLK3, 6},
186                 {CPM_CLK_SCC1, CPM_CLK4, 7},
187                 {CPM_CLK_SCC2, CPM_BRG1, 0},
188                 {CPM_CLK_SCC2, CPM_BRG2, 1},
189                 {CPM_CLK_SCC2, CPM_BRG3, 2},
190                 {CPM_CLK_SCC2, CPM_BRG4, 3},
191                 {CPM_CLK_SCC2, CPM_CLK11, 4},
192                 {CPM_CLK_SCC2, CPM_CLK12, 5},
193                 {CPM_CLK_SCC2, CPM_CLK3, 6},
194                 {CPM_CLK_SCC2, CPM_CLK4, 7},
195                 {CPM_CLK_SCC3, CPM_BRG1, 0},
196                 {CPM_CLK_SCC3, CPM_BRG2, 1},
197                 {CPM_CLK_SCC3, CPM_BRG3, 2},
198                 {CPM_CLK_SCC3, CPM_BRG4, 3},
199                 {CPM_CLK_SCC3, CPM_CLK5, 4},
200                 {CPM_CLK_SCC3, CPM_CLK6, 5},
201                 {CPM_CLK_SCC3, CPM_CLK7, 6},
202                 {CPM_CLK_SCC3, CPM_CLK8, 7},
203                 {CPM_CLK_SCC4, CPM_BRG1, 0},
204                 {CPM_CLK_SCC4, CPM_BRG2, 1},
205                 {CPM_CLK_SCC4, CPM_BRG3, 2},
206                 {CPM_CLK_SCC4, CPM_BRG4, 3},
207                 {CPM_CLK_SCC4, CPM_CLK5, 4},
208                 {CPM_CLK_SCC4, CPM_CLK6, 5},
209                 {CPM_CLK_SCC4, CPM_CLK7, 6},
210                 {CPM_CLK_SCC4, CPM_CLK8, 7},
211         };
212
213         im_cpmux = cpm2_map(im_cpmux);
214
215         switch (target) {
216         case CPM_CLK_SCC1:
217                 reg = &im_cpmux->cmx_scr;
218                 shift = 24;
219         case CPM_CLK_SCC2:
220                 reg = &im_cpmux->cmx_scr;
221                 shift = 16;
222                 break;
223         case CPM_CLK_SCC3:
224                 reg = &im_cpmux->cmx_scr;
225                 shift = 8;
226                 break;
227         case CPM_CLK_SCC4:
228                 reg = &im_cpmux->cmx_scr;
229                 shift = 0;
230                 break;
231         case CPM_CLK_FCC1:
232                 reg = &im_cpmux->cmx_fcr;
233                 shift = 24;
234                 break;
235         case CPM_CLK_FCC2:
236                 reg = &im_cpmux->cmx_fcr;
237                 shift = 16;
238                 break;
239         case CPM_CLK_FCC3:
240                 reg = &im_cpmux->cmx_fcr;
241                 shift = 8;
242                 break;
243         default:
244                 printk(KERN_ERR "cpm2_clock_setup: invalid clock target\n");
245                 return -EINVAL;
246         }
247
248         if (mode == CPM_CLK_RX)
249                 shift += 3;
250
251         for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
252                 if (clk_map[i][0] == target && clk_map[i][1] == clock) {
253                         bits = clk_map[i][2];
254                         break;
255                 }
256         }
257         if (i == ARRAY_SIZE(clk_map))
258             ret = -EINVAL;
259
260         bits <<= shift;
261         mask <<= shift;
262
263         out_be32(reg, (in_be32(reg) & ~mask) | bits);
264
265         cpm2_unmap(im_cpmux);
266         return ret;
267 }
268
269 int cpm2_smc_clk_setup(enum cpm_clk_target target, int clock)
270 {
271         int ret = 0;
272         int shift;
273         int i, bits = 0;
274         cpmux_t __iomem *im_cpmux;
275         u8 __iomem *reg;
276         u8 mask = 3;
277
278         u8 clk_map[][3] = {
279                 {CPM_CLK_SMC1, CPM_BRG1, 0},
280                 {CPM_CLK_SMC1, CPM_BRG7, 1},
281                 {CPM_CLK_SMC1, CPM_CLK7, 2},
282                 {CPM_CLK_SMC1, CPM_CLK9, 3},
283                 {CPM_CLK_SMC2, CPM_BRG2, 0},
284                 {CPM_CLK_SMC2, CPM_BRG8, 1},
285                 {CPM_CLK_SMC2, CPM_CLK4, 2},
286                 {CPM_CLK_SMC2, CPM_CLK15, 3},
287         };
288
289         im_cpmux = cpm2_map(im_cpmux);
290
291         switch (target) {
292         case CPM_CLK_SMC1:
293                 reg = &im_cpmux->cmx_smr;
294                 mask = 3;
295                 shift = 4;
296                 break;
297         case CPM_CLK_SMC2:
298                 reg = &im_cpmux->cmx_smr;
299                 mask = 3;
300                 shift = 0;
301                 break;
302         default:
303                 printk(KERN_ERR "cpm2_smc_clock_setup: invalid clock target\n");
304                 return -EINVAL;
305         }
306
307         for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
308                 if (clk_map[i][0] == target && clk_map[i][1] == clock) {
309                         bits = clk_map[i][2];
310                         break;
311                 }
312         }
313         if (i == ARRAY_SIZE(clk_map))
314             ret = -EINVAL;
315
316         bits <<= shift;
317         mask <<= shift;
318
319         out_8(reg, (in_8(reg) & ~mask) | bits);
320
321         cpm2_unmap(im_cpmux);
322         return ret;
323 }
324
325 #ifndef CONFIG_PPC_CPM_NEW_BINDING
326 /*
327  * dpalloc / dpfree bits.
328  */
329 static spinlock_t cpm_dpmem_lock;
330 /* 16 blocks should be enough to satisfy all requests
331  * until the memory subsystem goes up... */
332 static rh_block_t cpm_boot_dpmem_rh_block[16];
333 static rh_info_t cpm_dpmem_info;
334 static u8 __iomem *im_dprambase;
335
336 static void cpm2_dpinit(void)
337 {
338         spin_lock_init(&cpm_dpmem_lock);
339
340         /* initialize the info header */
341         rh_init(&cpm_dpmem_info, 1,
342                         sizeof(cpm_boot_dpmem_rh_block) /
343                         sizeof(cpm_boot_dpmem_rh_block[0]),
344                         cpm_boot_dpmem_rh_block);
345
346         im_dprambase = cpm2_immr;
347
348         /* Attach the usable dpmem area */
349         /* XXX: This is actually crap. CPM_DATAONLY_BASE and
350          * CPM_DATAONLY_SIZE is only a subset of the available dpram. It
351          * varies with the processor and the microcode patches activated.
352          * But the following should be at least safe.
353          */
354         rh_attach_region(&cpm_dpmem_info, CPM_DATAONLY_BASE, CPM_DATAONLY_SIZE);
355 }
356
357 /* This function returns an index into the DPRAM area.
358  */
359 unsigned long cpm_dpalloc(uint size, uint align)
360 {
361         unsigned long start;
362         unsigned long flags;
363
364         spin_lock_irqsave(&cpm_dpmem_lock, flags);
365         cpm_dpmem_info.alignment = align;
366         start = rh_alloc(&cpm_dpmem_info, size, "commproc");
367         spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
368
369         return (uint)start;
370 }
371 EXPORT_SYMBOL(cpm_dpalloc);
372
373 int cpm_dpfree(unsigned long offset)
374 {
375         int ret;
376         unsigned long flags;
377
378         spin_lock_irqsave(&cpm_dpmem_lock, flags);
379         ret = rh_free(&cpm_dpmem_info, offset);
380         spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
381
382         return ret;
383 }
384 EXPORT_SYMBOL(cpm_dpfree);
385
386 /* not sure if this is ever needed */
387 unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align)
388 {
389         unsigned long start;
390         unsigned long flags;
391
392         spin_lock_irqsave(&cpm_dpmem_lock, flags);
393         cpm_dpmem_info.alignment = align;
394         start = rh_alloc_fixed(&cpm_dpmem_info, offset, size, "commproc");
395         spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
396
397         return start;
398 }
399 EXPORT_SYMBOL(cpm_dpalloc_fixed);
400
401 void cpm_dpdump(void)
402 {
403         rh_dump(&cpm_dpmem_info);
404 }
405 EXPORT_SYMBOL(cpm_dpdump);
406
407 void *cpm_dpram_addr(unsigned long offset)
408 {
409         return (void *)(im_dprambase + offset);
410 }
411 EXPORT_SYMBOL(cpm_dpram_addr);
412 #endif /* !CONFIG_PPC_CPM_NEW_BINDING */
413
414 struct cpm2_ioports {
415         u32 dir, par, sor, odr, dat;
416         u32 res[3];
417 };
418
419 void cpm2_set_pin(int port, int pin, int flags)
420 {
421         struct cpm2_ioports __iomem *iop =
422                 (struct cpm2_ioports __iomem *)&cpm2_immr->im_ioport;
423
424         pin = 1 << (31 - pin);
425
426         if (flags & CPM_PIN_OUTPUT)
427                 setbits32(&iop[port].dir, pin);
428         else
429                 clrbits32(&iop[port].dir, pin);
430
431         if (!(flags & CPM_PIN_GPIO))
432                 setbits32(&iop[port].par, pin);
433         else
434                 clrbits32(&iop[port].par, pin);
435
436         if (flags & CPM_PIN_SECONDARY)
437                 setbits32(&iop[port].sor, pin);
438         else
439                 clrbits32(&iop[port].sor, pin);
440
441         if (flags & CPM_PIN_OPENDRAIN)
442                 setbits32(&iop[port].odr, pin);
443         else
444                 clrbits32(&iop[port].odr, pin);
445 }