]> git.sur5r.net Git - u-boot/blob - arch/powerpc/cpu/mpc8260/commproc.c
ff6988108990bf03aba4e4e02d38416acdac2296
[u-boot] / arch / powerpc / cpu / mpc8260 / commproc.c
1 /*
2  * This file is based on "arch/powerpc/8260_io/commproc.c" - here is it's
3  * copyright notice:
4  *
5  * General Purpose functions for the global management of the
6  * 8260 Communication Processor Module.
7  * Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
8  * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
9  *      2.3.99 Updates
10  *
11  * In addition to the individual control of the communication
12  * channels, there are a few functions that globally affect the
13  * communication processor.
14  *
15  * Buffer descriptors must be allocated from the dual ported memory
16  * space.  The allocator for that is here.  When the communication
17  * process is reset, we reclaim the memory available.  There is
18  * currently no deallocator for this memory.
19  */
20 #include <common.h>
21 #include <asm/cpm_8260.h>
22
23 DECLARE_GLOBAL_DATA_PTR;
24
25 void
26 m8260_cpm_reset(void)
27 {
28         volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
29         volatile ulong count;
30
31         /* Reclaim the DP memory for our use.
32         */
33         gd->arch.dp_alloc_base = CPM_DATAONLY_BASE;
34         gd->arch.dp_alloc_top = gd->arch.dp_alloc_base + CPM_DATAONLY_SIZE;
35
36         /*
37          * Reset CPM
38          */
39         immr->im_cpm.cp_cpcr = CPM_CR_RST;
40         count = 0;
41         do {                    /* Spin until command processed         */
42                 __asm__ __volatile__ ("eieio");
43         } while ((immr->im_cpm.cp_cpcr & CPM_CR_FLG) && ++count < 1000000);
44 }
45
46 /* Allocate some memory from the dual ported ram.
47  * To help protocols with object alignment restrictions, we do that
48  * if they ask.
49  */
50 uint
51 m8260_cpm_dpalloc(uint size, uint align)
52 {
53         volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
54         uint    retloc;
55         uint    align_mask, off;
56         uint    savebase;
57
58         align_mask = align - 1;
59         savebase = gd->arch.dp_alloc_base;
60
61         off = gd->arch.dp_alloc_base & align_mask;
62         if (off != 0)
63                 gd->arch.dp_alloc_base += (align - off);
64
65         if ((off = size & align_mask) != 0)
66                 size += align - off;
67
68         if ((gd->arch.dp_alloc_base + size) >= gd->arch.dp_alloc_top) {
69                 gd->arch.dp_alloc_base = savebase;
70                 panic("m8260_cpm_dpalloc: ran out of dual port ram!");
71         }
72
73         retloc = gd->arch.dp_alloc_base;
74         gd->arch.dp_alloc_base += size;
75
76         memset((void *)&immr->im_dprambase[retloc], 0, size);
77
78         return(retloc);
79 }
80
81 /* We also own one page of host buffer space for the allocation of
82  * UART "fifos" and the like.
83  */
84 uint
85 m8260_cpm_hostalloc(uint size, uint align)
86 {
87         /* the host might not even have RAM yet - just use dual port RAM */
88         return (m8260_cpm_dpalloc(size, align));
89 }
90
91 /* Set a baud rate generator.  This needs lots of work.  There are
92  * eight BRGs, which can be connected to the CPM channels or output
93  * as clocks.  The BRGs are in two different block of internal
94  * memory mapped space.
95  * The baud rate clock is the system clock divided by something.
96  * It was set up long ago during the initial boot phase and is
97  * is given to us.
98  * Baud rate clocks are zero-based in the driver code (as that maps
99  * to port numbers).  Documentation uses 1-based numbering.
100  */
101 #define BRG_INT_CLK     gd->arch.brg_clk
102 #define BRG_UART_CLK    (BRG_INT_CLK / 16)
103
104 /* This function is used by UARTs, or anything else that uses a 16x
105  * oversampled clock.
106  */
107 void
108 m8260_cpm_setbrg(uint brg, uint rate)
109 {
110         volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
111         volatile uint   *bp;
112         uint cd = BRG_UART_CLK / rate;
113
114         if ((BRG_UART_CLK % rate) < (rate / 2))
115                 cd--;
116         if (brg < 4) {
117                 bp = (uint *)&immr->im_brgc1;
118         }
119         else {
120                 bp = (uint *)&immr->im_brgc5;
121                 brg -= 4;
122         }
123         bp += brg;
124         *bp = (cd << 1) | CPM_BRG_EN;
125 }
126
127 /* This function is used to set high speed synchronous baud rate
128  * clocks.
129  */
130 void
131 m8260_cpm_fastbrg(uint brg, uint rate, int div16)
132 {
133         volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
134         volatile uint   *bp;
135
136         /* This is good enough to get SMCs running.....
137         */
138         if (brg < 4) {
139                 bp = (uint *)&immr->im_brgc1;
140         }
141         else {
142                 bp = (uint *)&immr->im_brgc5;
143                 brg -= 4;
144         }
145         bp += brg;
146         *bp = (((((BRG_INT_CLK+rate-1)/rate)-1)&0xfff)<<1)|CPM_BRG_EN;
147         if (div16)
148                 *bp |= CPM_BRG_DIV16;
149 }
150
151 /* This function is used to set baud rate generators using an external
152  * clock source and 16x oversampling.
153  */
154
155 void
156 m8260_cpm_extcbrg(uint brg, uint rate, uint extclk, int pinsel)
157 {
158         volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
159         volatile uint   *bp;
160
161         if (brg < 4) {
162                 bp = (uint *)&immr->im_brgc1;
163         }
164         else {
165                 bp = (uint *)&immr->im_brgc5;
166                 brg -= 4;
167         }
168         bp += brg;
169         *bp = ((((((extclk/16)+rate-1)/rate)-1)&0xfff)<<1)|CPM_BRG_EN;
170         if (pinsel == 0)
171                 *bp |= CPM_BRG_EXTC_CLK3_9;
172         else
173                 *bp |= CPM_BRG_EXTC_CLK5_15;
174 }