diff options
-rw-r--r-- | arch/powerpc/Kconfig | 12 | ||||
-rw-r--r-- | arch/powerpc/sysdev/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/Kconfig | 30 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/Makefile | 8 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe.c | 353 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe_ic.c | 555 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe_ic.h | 106 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe_io.c | 226 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/ucc.c | 251 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/ucc_fast.c | 396 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/ucc_slow.c | 404 | ||||
-rw-r--r-- | include/asm-powerpc/immap_qe.h | 477 | ||||
-rw-r--r-- | include/asm-powerpc/qe.h | 457 | ||||
-rw-r--r-- | include/asm-powerpc/qe_ic.h | 64 | ||||
-rw-r--r-- | include/asm-powerpc/ucc.h | 84 | ||||
-rw-r--r-- | include/asm-powerpc/ucc_fast.h | 243 | ||||
-rw-r--r-- | include/asm-powerpc/ucc_slow.h | 289 | ||||
-rw-r--r-- | include/linux/fsl_devices.h | 65 |
18 files changed, 4007 insertions, 14 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index b29adaa97348..2587468eec43 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -351,6 +351,16 @@ config APUS | |||
351 | <http://linux-apus.sourceforge.net/>. | 351 | <http://linux-apus.sourceforge.net/>. |
352 | endchoice | 352 | endchoice |
353 | 353 | ||
354 | config QUICC_ENGINE | ||
355 | bool | ||
356 | depends on PPC_MPC836x || PPC_MPC832x | ||
357 | default y | ||
358 | help | ||
359 | The QUICC Engine (QE) is a new generation of communications | ||
360 | coprocessors on Freescale embedded CPUs (akin to CPM in older chips). | ||
361 | Selecting this option means that you wish to build a kernel | ||
362 | for a machine with a QE coprocessor. | ||
363 | |||
354 | config PPC_PSERIES | 364 | config PPC_PSERIES |
355 | depends on PPC_MULTIPLATFORM && PPC64 | 365 | depends on PPC_MULTIPLATFORM && PPC64 |
356 | bool "IBM pSeries & new (POWER5-based) iSeries" | 366 | bool "IBM pSeries & new (POWER5-based) iSeries" |
@@ -1059,6 +1069,8 @@ source "fs/Kconfig" | |||
1059 | 1069 | ||
1060 | # XXX source "arch/ppc/8260_io/Kconfig" | 1070 | # XXX source "arch/ppc/8260_io/Kconfig" |
1061 | 1071 | ||
1072 | source "arch/powerpc/sysdev/qe_lib/Kconfig" | ||
1073 | |||
1062 | source "arch/powerpc/platforms/iseries/Kconfig" | 1074 | source "arch/powerpc/platforms/iseries/Kconfig" |
1063 | 1075 | ||
1064 | source "lib/Kconfig" | 1076 | source "lib/Kconfig" |
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index f15f4d78aee9..91f052d8cce0 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -12,6 +12,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o | |||
12 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o | 12 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o |
13 | obj-$(CONFIG_PPC_TODC) += todc.o | 13 | obj-$(CONFIG_PPC_TODC) += todc.o |
14 | obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o | 14 | obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o |
15 | obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ | ||
15 | 16 | ||
16 | ifeq ($(CONFIG_PPC_MERGE),y) | 17 | ifeq ($(CONFIG_PPC_MERGE),y) |
17 | obj-$(CONFIG_PPC_I8259) += i8259.o | 18 | obj-$(CONFIG_PPC_I8259) += i8259.o |
diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig new file mode 100644 index 000000000000..a725e80befa8 --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/Kconfig | |||
@@ -0,0 +1,30 @@ | |||
1 | # | ||
2 | # QE Communication options | ||
3 | # | ||
4 | |||
5 | menu "QE Options" | ||
6 | depends on QUICC_ENGINE | ||
7 | |||
8 | config UCC_SLOW | ||
9 | bool "UCC Slow Protocols Support" | ||
10 | default n | ||
11 | select UCC | ||
12 | help | ||
13 | This option provides qe_lib support to UCC slow | ||
14 | protocols: UART, BISYNC, QMC | ||
15 | |||
16 | config UCC_FAST | ||
17 | bool "UCC Fast Protocols Support" | ||
18 | default n | ||
19 | select UCC | ||
20 | select UCC_SLOW | ||
21 | help | ||
22 | This option provides qe_lib support to UCC fast | ||
23 | protocols: HDLC, Ethernet, ATM, transparent | ||
24 | |||
25 | config UCC | ||
26 | bool | ||
27 | default y if UCC_FAST || UCC_SLOW | ||
28 | |||
29 | endmenu | ||
30 | |||
diff --git a/arch/powerpc/sysdev/qe_lib/Makefile b/arch/powerpc/sysdev/qe_lib/Makefile new file mode 100644 index 000000000000..874fe1a5b1cf --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for the linux ppc-specific parts of QE | ||
3 | # | ||
4 | obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_ic.o qe_io.o | ||
5 | |||
6 | obj-$(CONFIG_UCC) += ucc.o | ||
7 | obj-$(CONFIG_UCC_SLOW) += ucc_slow.o | ||
8 | obj-$(CONFIG_UCC_FAST) += ucc_fast.o | ||
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c new file mode 100644 index 000000000000..2bae632d3ad7 --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
@@ -0,0 +1,353 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. | ||
3 | * | ||
4 | * Authors: Shlomi Gridish <gridish@freescale.com> | ||
5 | * Li Yang <leoli@freescale.com> | ||
6 | * Based on cpm2_common.c from Dan Malek (dmalek@jlc.net) | ||
7 | * | ||
8 | * Description: | ||
9 | * General Purpose functions for the global management of the | ||
10 | * QUICC Engine (QE). | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License as published by the | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | */ | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/param.h> | ||
21 | #include <linux/string.h> | ||
22 | #include <linux/mm.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/bootmem.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/ioport.h> | ||
28 | #include <asm/irq.h> | ||
29 | #include <asm/page.h> | ||
30 | #include <asm/pgtable.h> | ||
31 | #include <asm/immap_qe.h> | ||
32 | #include <asm/qe.h> | ||
33 | #include <asm/prom.h> | ||
34 | #include <asm/rheap.h> | ||
35 | |||
36 | static void qe_snums_init(void); | ||
37 | static void qe_muram_init(void); | ||
38 | static int qe_sdma_init(void); | ||
39 | |||
40 | static DEFINE_SPINLOCK(qe_lock); | ||
41 | |||
42 | /* QE snum state */ | ||
43 | enum qe_snum_state { | ||
44 | QE_SNUM_STATE_USED, | ||
45 | QE_SNUM_STATE_FREE | ||
46 | }; | ||
47 | |||
48 | /* QE snum */ | ||
49 | struct qe_snum { | ||
50 | u8 num; | ||
51 | enum qe_snum_state state; | ||
52 | }; | ||
53 | |||
54 | /* We allocate this here because it is used almost exclusively for | ||
55 | * the communication processor devices. | ||
56 | */ | ||
57 | struct qe_immap *qe_immr = NULL; | ||
58 | EXPORT_SYMBOL(qe_immr); | ||
59 | |||
60 | static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */ | ||
61 | |||
62 | static phys_addr_t qebase = -1; | ||
63 | |||
64 | phys_addr_t get_qe_base(void) | ||
65 | { | ||
66 | struct device_node *qe; | ||
67 | |||
68 | if (qebase != -1) | ||
69 | return qebase; | ||
70 | |||
71 | qe = of_find_node_by_type(NULL, "qe"); | ||
72 | if (qe) { | ||
73 | unsigned int size; | ||
74 | const void *prop = get_property(qe, "reg", &size); | ||
75 | qebase = of_translate_address(qe, prop); | ||
76 | of_node_put(qe); | ||
77 | }; | ||
78 | |||
79 | return qebase; | ||
80 | } | ||
81 | |||
82 | EXPORT_SYMBOL(get_qe_base); | ||
83 | |||
84 | void qe_reset(void) | ||
85 | { | ||
86 | if (qe_immr == NULL) | ||
87 | qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE); | ||
88 | |||
89 | qe_snums_init(); | ||
90 | |||
91 | qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID, | ||
92 | QE_CR_PROTOCOL_UNSPECIFIED, 0); | ||
93 | |||
94 | /* Reclaim the MURAM memory for our use. */ | ||
95 | qe_muram_init(); | ||
96 | |||
97 | if (qe_sdma_init()) | ||
98 | panic("sdma init failed!"); | ||
99 | } | ||
100 | |||
101 | int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) | ||
102 | { | ||
103 | unsigned long flags; | ||
104 | u8 mcn_shift = 0, dev_shift = 0; | ||
105 | |||
106 | spin_lock_irqsave(&qe_lock, flags); | ||
107 | if (cmd == QE_RESET) { | ||
108 | out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG)); | ||
109 | } else { | ||
110 | if (cmd == QE_ASSIGN_PAGE) { | ||
111 | /* Here device is the SNUM, not sub-block */ | ||
112 | dev_shift = QE_CR_SNUM_SHIFT; | ||
113 | } else if (cmd == QE_ASSIGN_RISC) { | ||
114 | /* Here device is the SNUM, and mcnProtocol is | ||
115 | * e_QeCmdRiscAssignment value */ | ||
116 | dev_shift = QE_CR_SNUM_SHIFT; | ||
117 | mcn_shift = QE_CR_MCN_RISC_ASSIGN_SHIFT; | ||
118 | } else { | ||
119 | if (device == QE_CR_SUBBLOCK_USB) | ||
120 | mcn_shift = QE_CR_MCN_USB_SHIFT; | ||
121 | else | ||
122 | mcn_shift = QE_CR_MCN_NORMAL_SHIFT; | ||
123 | } | ||
124 | |||
125 | out_be32(&qe_immr->cp.cecdr, | ||
126 | immrbar_virt_to_phys((void *)cmd_input)); | ||
127 | out_be32(&qe_immr->cp.cecr, | ||
128 | (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32) | ||
129 | mcn_protocol << mcn_shift)); | ||
130 | } | ||
131 | |||
132 | /* wait for the QE_CR_FLG to clear */ | ||
133 | while(in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) | ||
134 | cpu_relax(); | ||
135 | spin_unlock_irqrestore(&qe_lock, flags); | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | EXPORT_SYMBOL(qe_issue_cmd); | ||
140 | |||
141 | /* Set a baud rate generator. This needs lots of work. There are | ||
142 | * 16 BRGs, which can be connected to the QE channels or output | ||
143 | * as clocks. The BRGs are in two different block of internal | ||
144 | * memory mapped space. | ||
145 | * The baud rate clock is the system clock divided by something. | ||
146 | * It was set up long ago during the initial boot phase and is | ||
147 | * is given to us. | ||
148 | * Baud rate clocks are zero-based in the driver code (as that maps | ||
149 | * to port numbers). Documentation uses 1-based numbering. | ||
150 | */ | ||
151 | static unsigned int brg_clk = 0; | ||
152 | |||
153 | unsigned int get_brg_clk(void) | ||
154 | { | ||
155 | struct device_node *qe; | ||
156 | if (brg_clk) | ||
157 | return brg_clk; | ||
158 | |||
159 | qe = of_find_node_by_type(NULL, "qe"); | ||
160 | if (qe) { | ||
161 | unsigned int size; | ||
162 | const u32 *prop = get_property(qe, "brg-frequency", &size); | ||
163 | brg_clk = *prop; | ||
164 | of_node_put(qe); | ||
165 | }; | ||
166 | return brg_clk; | ||
167 | } | ||
168 | |||
169 | /* This function is used by UARTS, or anything else that uses a 16x | ||
170 | * oversampled clock. | ||
171 | */ | ||
172 | void qe_setbrg(u32 brg, u32 rate) | ||
173 | { | ||
174 | volatile u32 *bp; | ||
175 | u32 divisor, tempval; | ||
176 | int div16 = 0; | ||
177 | |||
178 | bp = &qe_immr->brg.brgc1; | ||
179 | bp += brg; | ||
180 | |||
181 | divisor = (get_brg_clk() / rate); | ||
182 | if (divisor > QE_BRGC_DIVISOR_MAX + 1) { | ||
183 | div16 = 1; | ||
184 | divisor /= 16; | ||
185 | } | ||
186 | |||
187 | tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE; | ||
188 | if (div16) | ||
189 | tempval |= QE_BRGC_DIV16; | ||
190 | |||
191 | out_be32(bp, tempval); | ||
192 | } | ||
193 | |||
194 | /* Initialize SNUMs (thread serial numbers) according to | ||
195 | * QE Module Control chapter, SNUM table | ||
196 | */ | ||
197 | static void qe_snums_init(void) | ||
198 | { | ||
199 | int i; | ||
200 | static const u8 snum_init[] = { | ||
201 | 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, | ||
202 | 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89, | ||
203 | 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9, | ||
204 | 0xD8, 0xD9, 0xE8, 0xE9, | ||
205 | }; | ||
206 | |||
207 | for (i = 0; i < QE_NUM_OF_SNUM; i++) { | ||
208 | snums[i].num = snum_init[i]; | ||
209 | snums[i].state = QE_SNUM_STATE_FREE; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | int qe_get_snum(void) | ||
214 | { | ||
215 | unsigned long flags; | ||
216 | int snum = -EBUSY; | ||
217 | int i; | ||
218 | |||
219 | spin_lock_irqsave(&qe_lock, flags); | ||
220 | for (i = 0; i < QE_NUM_OF_SNUM; i++) { | ||
221 | if (snums[i].state == QE_SNUM_STATE_FREE) { | ||
222 | snums[i].state = QE_SNUM_STATE_USED; | ||
223 | snum = snums[i].num; | ||
224 | break; | ||
225 | } | ||
226 | } | ||
227 | spin_unlock_irqrestore(&qe_lock, flags); | ||
228 | |||
229 | return snum; | ||
230 | } | ||
231 | EXPORT_SYMBOL(qe_get_snum); | ||
232 | |||
233 | void qe_put_snum(u8 snum) | ||
234 | { | ||
235 | int i; | ||
236 | |||
237 | for (i = 0; i < QE_NUM_OF_SNUM; i++) { | ||
238 | if (snums[i].num == snum) { | ||
239 | snums[i].state = QE_SNUM_STATE_FREE; | ||
240 | break; | ||
241 | } | ||
242 | } | ||
243 | } | ||
244 | EXPORT_SYMBOL(qe_put_snum); | ||
245 | |||
246 | static int qe_sdma_init(void) | ||
247 | { | ||
248 | struct sdma *sdma = &qe_immr->sdma; | ||
249 | u32 sdma_buf_offset; | ||
250 | |||
251 | if (!sdma) | ||
252 | return -ENODEV; | ||
253 | |||
254 | /* allocate 2 internal temporary buffers (512 bytes size each) for | ||
255 | * the SDMA */ | ||
256 | sdma_buf_offset = qe_muram_alloc(512 * 2, 64); | ||
257 | if (IS_MURAM_ERR(sdma_buf_offset)) | ||
258 | return -ENOMEM; | ||
259 | |||
260 | out_be32(&sdma->sdebcr, sdma_buf_offset & QE_SDEBCR_BA_MASK); | ||
261 | out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK | (0x1 >> | ||
262 | QE_SDMR_CEN_SHIFT))); | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * muram_alloc / muram_free bits. | ||
269 | */ | ||
270 | static DEFINE_SPINLOCK(qe_muram_lock); | ||
271 | |||
272 | /* 16 blocks should be enough to satisfy all requests | ||
273 | * until the memory subsystem goes up... */ | ||
274 | static rh_block_t qe_boot_muram_rh_block[16]; | ||
275 | static rh_info_t qe_muram_info; | ||
276 | |||
277 | static void qe_muram_init(void) | ||
278 | { | ||
279 | struct device_node *np; | ||
280 | u32 address; | ||
281 | u64 size; | ||
282 | unsigned int flags; | ||
283 | |||
284 | /* initialize the info header */ | ||
285 | rh_init(&qe_muram_info, 1, | ||
286 | sizeof(qe_boot_muram_rh_block) / | ||
287 | sizeof(qe_boot_muram_rh_block[0]), qe_boot_muram_rh_block); | ||
288 | |||
289 | /* Attach the usable muram area */ | ||
290 | /* XXX: This is a subset of the available muram. It | ||
291 | * varies with the processor and the microcode patches activated. | ||
292 | */ | ||
293 | if ((np = of_find_node_by_name(NULL, "data-only")) != NULL) { | ||
294 | address = *of_get_address(np, 0, &size, &flags); | ||
295 | of_node_put(np); | ||
296 | rh_attach_region(&qe_muram_info, | ||
297 | (void *)address, (int)size); | ||
298 | } | ||
299 | } | ||
300 | |||
301 | /* This function returns an index into the MURAM area. | ||
302 | */ | ||
303 | u32 qe_muram_alloc(u32 size, u32 align) | ||
304 | { | ||
305 | void *start; | ||
306 | unsigned long flags; | ||
307 | |||
308 | spin_lock_irqsave(&qe_muram_lock, flags); | ||
309 | start = rh_alloc_align(&qe_muram_info, size, align, "QE"); | ||
310 | spin_unlock_irqrestore(&qe_muram_lock, flags); | ||
311 | |||
312 | return (u32) start; | ||
313 | } | ||
314 | EXPORT_SYMBOL(qe_muram_alloc); | ||
315 | |||
316 | int qe_muram_free(u32 offset) | ||
317 | { | ||
318 | int ret; | ||
319 | unsigned long flags; | ||
320 | |||
321 | spin_lock_irqsave(&qe_muram_lock, flags); | ||
322 | ret = rh_free(&qe_muram_info, (void *)offset); | ||
323 | spin_unlock_irqrestore(&qe_muram_lock, flags); | ||
324 | |||
325 | return ret; | ||
326 | } | ||
327 | EXPORT_SYMBOL(qe_muram_free); | ||
328 | |||
329 | /* not sure if this is ever needed */ | ||
330 | u32 qe_muram_alloc_fixed(u32 offset, u32 size) | ||
331 | { | ||
332 | void *start; | ||
333 | unsigned long flags; | ||
334 | |||
335 | spin_lock_irqsave(&qe_muram_lock, flags); | ||
336 | start = rh_alloc_fixed(&qe_muram_info, (void *)offset, size, "commproc"); | ||
337 | spin_unlock_irqrestore(&qe_muram_lock, flags); | ||
338 | |||
339 | return (u32) start; | ||
340 | } | ||
341 | EXPORT_SYMBOL(qe_muram_alloc_fixed); | ||
342 | |||
343 | void qe_muram_dump(void) | ||
344 | { | ||
345 | rh_dump(&qe_muram_info); | ||
346 | } | ||
347 | EXPORT_SYMBOL(qe_muram_dump); | ||
348 | |||
349 | void *qe_muram_addr(u32 offset) | ||
350 | { | ||
351 | return (void *)&qe_immr->muram[offset]; | ||
352 | } | ||
353 | EXPORT_SYMBOL(qe_muram_addr); | ||
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c new file mode 100644 index 000000000000..c229d07d4957 --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c | |||
@@ -0,0 +1,555 @@ | |||
1 | /* | ||
2 | * arch/powerpc/sysdev/qe_lib/qe_ic.c | ||
3 | * | ||
4 | * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. | ||
5 | * | ||
6 | * Author: Li Yang <leoli@freescale.com> | ||
7 | * Based on code from Shlomi Gridish <gridish@freescale.com> | ||
8 | * | ||
9 | * QUICC ENGINE Interrupt Controller | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/reboot.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/stddef.h> | ||
23 | #include <linux/sched.h> | ||
24 | #include <linux/signal.h> | ||
25 | #include <linux/sysdev.h> | ||
26 | #include <linux/device.h> | ||
27 | #include <linux/bootmem.h> | ||
28 | #include <linux/spinlock.h> | ||
29 | #include <asm/irq.h> | ||
30 | #include <asm/io.h> | ||
31 | #include <asm/prom.h> | ||
32 | #include <asm/qe_ic.h> | ||
33 | |||
34 | #include "qe_ic.h" | ||
35 | |||
36 | static DEFINE_SPINLOCK(qe_ic_lock); | ||
37 | |||
38 | static struct qe_ic_info qe_ic_info[] = { | ||
39 | [1] = { | ||
40 | .mask = 0x00008000, | ||
41 | .mask_reg = QEIC_CIMR, | ||
42 | .pri_code = 0, | ||
43 | .pri_reg = QEIC_CIPWCC, | ||
44 | }, | ||
45 | [2] = { | ||
46 | .mask = 0x00004000, | ||
47 | .mask_reg = QEIC_CIMR, | ||
48 | .pri_code = 1, | ||
49 | .pri_reg = QEIC_CIPWCC, | ||
50 | }, | ||
51 | [3] = { | ||
52 | .mask = 0x00002000, | ||
53 | .mask_reg = QEIC_CIMR, | ||
54 | .pri_code = 2, | ||
55 | .pri_reg = QEIC_CIPWCC, | ||
56 | }, | ||
57 | [10] = { | ||
58 | .mask = 0x00000040, | ||
59 | .mask_reg = QEIC_CIMR, | ||
60 | .pri_code = 1, | ||
61 | .pri_reg = QEIC_CIPZCC, | ||
62 | }, | ||
63 | [11] = { | ||
64 | .mask = 0x00000020, | ||
65 | .mask_reg = QEIC_CIMR, | ||
66 | .pri_code = 2, | ||
67 | .pri_reg = QEIC_CIPZCC, | ||
68 | }, | ||
69 | [12] = { | ||
70 | .mask = 0x00000010, | ||
71 | .mask_reg = QEIC_CIMR, | ||
72 | .pri_code = 3, | ||
73 | .pri_reg = QEIC_CIPZCC, | ||
74 | }, | ||
75 | [13] = { | ||
76 | .mask = 0x00000008, | ||
77 | .mask_reg = QEIC_CIMR, | ||
78 | .pri_code = 4, | ||
79 | .pri_reg = QEIC_CIPZCC, | ||
80 | }, | ||
81 | [14] = { | ||
82 | .mask = 0x00000004, | ||
83 | .mask_reg = QEIC_CIMR, | ||
84 | .pri_code = 5, | ||
85 | .pri_reg = QEIC_CIPZCC, | ||
86 | }, | ||
87 | [15] = { | ||
88 | .mask = 0x00000002, | ||
89 | .mask_reg = QEIC_CIMR, | ||
90 | .pri_code = 6, | ||
91 | .pri_reg = QEIC_CIPZCC, | ||
92 | }, | ||
93 | [20] = { | ||
94 | .mask = 0x10000000, | ||
95 | .mask_reg = QEIC_CRIMR, | ||
96 | .pri_code = 3, | ||
97 | .pri_reg = QEIC_CIPRTA, | ||
98 | }, | ||
99 | [25] = { | ||
100 | .mask = 0x00800000, | ||
101 | .mask_reg = QEIC_CRIMR, | ||
102 | .pri_code = 0, | ||
103 | .pri_reg = QEIC_CIPRTB, | ||
104 | }, | ||
105 | [26] = { | ||
106 | .mask = 0x00400000, | ||
107 | .mask_reg = QEIC_CRIMR, | ||
108 | .pri_code = 1, | ||
109 | .pri_reg = QEIC_CIPRTB, | ||
110 | }, | ||
111 | [27] = { | ||
112 | .mask = 0x00200000, | ||
113 | .mask_reg = QEIC_CRIMR, | ||
114 | .pri_code = 2, | ||
115 | .pri_reg = QEIC_CIPRTB, | ||
116 | }, | ||
117 | [28] = { | ||
118 | .mask = 0x00100000, | ||
119 | .mask_reg = QEIC_CRIMR, | ||
120 | .pri_code = 3, | ||
121 | .pri_reg = QEIC_CIPRTB, | ||
122 | }, | ||
123 | [32] = { | ||
124 | .mask = 0x80000000, | ||
125 | .mask_reg = QEIC_CIMR, | ||
126 | .pri_code = 0, | ||
127 | .pri_reg = QEIC_CIPXCC, | ||
128 | }, | ||
129 | [33] = { | ||
130 | .mask = 0x40000000, | ||
131 | .mask_reg = QEIC_CIMR, | ||
132 | .pri_code = 1, | ||
133 | .pri_reg = QEIC_CIPXCC, | ||
134 | }, | ||
135 | [34] = { | ||
136 | .mask = 0x20000000, | ||
137 | .mask_reg = QEIC_CIMR, | ||
138 | .pri_code = 2, | ||
139 | .pri_reg = QEIC_CIPXCC, | ||
140 | }, | ||
141 | [35] = { | ||
142 | .mask = 0x10000000, | ||
143 | .mask_reg = QEIC_CIMR, | ||
144 | .pri_code = 3, | ||
145 | .pri_reg = QEIC_CIPXCC, | ||
146 | }, | ||
147 | [36] = { | ||
148 | .mask = 0x08000000, | ||
149 | .mask_reg = QEIC_CIMR, | ||
150 | .pri_code = 4, | ||
151 | .pri_reg = QEIC_CIPXCC, | ||
152 | }, | ||
153 | [40] = { | ||
154 | .mask = 0x00800000, | ||
155 | .mask_reg = QEIC_CIMR, | ||
156 | .pri_code = 0, | ||
157 | .pri_reg = QEIC_CIPYCC, | ||
158 | }, | ||
159 | [41] = { | ||
160 | .mask = 0x00400000, | ||
161 | .mask_reg = QEIC_CIMR, | ||
162 | .pri_code = 1, | ||
163 | .pri_reg = QEIC_CIPYCC, | ||
164 | }, | ||
165 | [42] = { | ||
166 | .mask = 0x00200000, | ||
167 | .mask_reg = QEIC_CIMR, | ||
168 | .pri_code = 2, | ||
169 | .pri_reg = QEIC_CIPYCC, | ||
170 | }, | ||
171 | [43] = { | ||
172 | .mask = 0x00100000, | ||
173 | .mask_reg = QEIC_CIMR, | ||
174 | .pri_code = 3, | ||
175 | .pri_reg = QEIC_CIPYCC, | ||
176 | }, | ||
177 | }; | ||
178 | |||
179 | static inline u32 qe_ic_read(volatile __be32 __iomem * base, unsigned int reg) | ||
180 | { | ||
181 | return in_be32(base + (reg >> 2)); | ||
182 | } | ||
183 | |||
184 | static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg, | ||
185 | u32 value) | ||
186 | { | ||
187 | out_be32(base + (reg >> 2), value); | ||
188 | } | ||
189 | |||
190 | static inline struct qe_ic *qe_ic_from_irq(unsigned int virq) | ||
191 | { | ||
192 | return irq_desc[virq].chip_data; | ||
193 | } | ||
194 | |||
195 | #define virq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) | ||
196 | |||
197 | static void qe_ic_unmask_irq(unsigned int virq) | ||
198 | { | ||
199 | struct qe_ic *qe_ic = qe_ic_from_irq(virq); | ||
200 | unsigned int src = virq_to_hw(virq); | ||
201 | unsigned long flags; | ||
202 | u32 temp; | ||
203 | |||
204 | spin_lock_irqsave(&qe_ic_lock, flags); | ||
205 | |||
206 | temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg); | ||
207 | qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg, | ||
208 | temp | qe_ic_info[src].mask); | ||
209 | |||
210 | spin_unlock_irqrestore(&qe_ic_lock, flags); | ||
211 | } | ||
212 | |||
213 | static void qe_ic_mask_irq(unsigned int virq) | ||
214 | { | ||
215 | struct qe_ic *qe_ic = qe_ic_from_irq(virq); | ||
216 | unsigned int src = virq_to_hw(virq); | ||
217 | unsigned long flags; | ||
218 | u32 temp; | ||
219 | |||
220 | spin_lock_irqsave(&qe_ic_lock, flags); | ||
221 | |||
222 | temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg); | ||
223 | qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg, | ||
224 | temp & ~qe_ic_info[src].mask); | ||
225 | |||
226 | spin_unlock_irqrestore(&qe_ic_lock, flags); | ||
227 | } | ||
228 | |||
229 | static void qe_ic_mask_irq_and_ack(unsigned int virq) | ||
230 | { | ||
231 | struct qe_ic *qe_ic = qe_ic_from_irq(virq); | ||
232 | unsigned int src = virq_to_hw(virq); | ||
233 | unsigned long flags; | ||
234 | u32 temp; | ||
235 | |||
236 | spin_lock_irqsave(&qe_ic_lock, flags); | ||
237 | |||
238 | temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg); | ||
239 | qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg, | ||
240 | temp & ~qe_ic_info[src].mask); | ||
241 | |||
242 | /* There is nothing to do for ack here, ack is handled in ISR */ | ||
243 | |||
244 | spin_unlock_irqrestore(&qe_ic_lock, flags); | ||
245 | } | ||
246 | |||
247 | static struct irq_chip qe_ic_irq_chip = { | ||
248 | .typename = " QEIC ", | ||
249 | .unmask = qe_ic_unmask_irq, | ||
250 | .mask = qe_ic_mask_irq, | ||
251 | .mask_ack = qe_ic_mask_irq_and_ack, | ||
252 | }; | ||
253 | |||
254 | static int qe_ic_host_match(struct irq_host *h, struct device_node *node) | ||
255 | { | ||
256 | struct qe_ic *qe_ic = h->host_data; | ||
257 | |||
258 | /* Exact match, unless qe_ic node is NULL */ | ||
259 | return qe_ic->of_node == NULL || qe_ic->of_node == node; | ||
260 | } | ||
261 | |||
262 | static int qe_ic_host_map(struct irq_host *h, unsigned int virq, | ||
263 | irq_hw_number_t hw) | ||
264 | { | ||
265 | struct qe_ic *qe_ic = h->host_data; | ||
266 | struct irq_chip *chip; | ||
267 | |||
268 | if (qe_ic_info[hw].mask == 0) { | ||
269 | printk(KERN_ERR "Can't map reserved IRQ \n"); | ||
270 | return -EINVAL; | ||
271 | } | ||
272 | /* Default chip */ | ||
273 | chip = &qe_ic->hc_irq; | ||
274 | |||
275 | set_irq_chip_data(virq, qe_ic); | ||
276 | get_irq_desc(virq)->status |= IRQ_LEVEL; | ||
277 | |||
278 | set_irq_chip_and_handler(virq, chip, handle_level_irq); | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct, | ||
284 | u32 * intspec, unsigned int intsize, | ||
285 | irq_hw_number_t * out_hwirq, | ||
286 | unsigned int *out_flags) | ||
287 | { | ||
288 | *out_hwirq = intspec[0]; | ||
289 | if (intsize > 1) | ||
290 | *out_flags = intspec[1]; | ||
291 | else | ||
292 | *out_flags = IRQ_TYPE_NONE; | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static struct irq_host_ops qe_ic_host_ops = { | ||
297 | .match = qe_ic_host_match, | ||
298 | .map = qe_ic_host_map, | ||
299 | .xlate = qe_ic_host_xlate, | ||
300 | }; | ||
301 | |||
302 | /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ | ||
303 | unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic, struct pt_regs *regs) | ||
304 | { | ||
305 | int irq; | ||
306 | |||
307 | BUG_ON(qe_ic == NULL); | ||
308 | |||
309 | /* get the interrupt source vector. */ | ||
310 | irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26; | ||
311 | |||
312 | if (irq == 0) | ||
313 | return NO_IRQ; | ||
314 | |||
315 | return irq_linear_revmap(qe_ic->irqhost, irq); | ||
316 | } | ||
317 | |||
318 | /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ | ||
319 | unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic, struct pt_regs *regs) | ||
320 | { | ||
321 | int irq; | ||
322 | |||
323 | BUG_ON(qe_ic == NULL); | ||
324 | |||
325 | /* get the interrupt source vector. */ | ||
326 | irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26; | ||
327 | |||
328 | if (irq == 0) | ||
329 | return NO_IRQ; | ||
330 | |||
331 | return irq_linear_revmap(qe_ic->irqhost, irq); | ||
332 | } | ||
333 | |||
334 | /* FIXME: We mask all the QE Low interrupts while handling. We should | ||
335 | * let other interrupt come in, but BAD interrupts are generated */ | ||
336 | void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc, | ||
337 | struct pt_regs *regs) | ||
338 | { | ||
339 | struct qe_ic *qe_ic = desc->handler_data; | ||
340 | struct irq_chip *chip = irq_desc[irq].chip; | ||
341 | |||
342 | unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic, regs); | ||
343 | |||
344 | chip->mask_ack(irq); | ||
345 | if (cascade_irq != NO_IRQ) | ||
346 | generic_handle_irq(cascade_irq, regs); | ||
347 | chip->unmask(irq); | ||
348 | } | ||
349 | |||
350 | /* FIXME: We mask all the QE High interrupts while handling. We should | ||
351 | * let other interrupt come in, but BAD interrupts are generated */ | ||
352 | void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc, | ||
353 | struct pt_regs *regs) | ||
354 | { | ||
355 | struct qe_ic *qe_ic = desc->handler_data; | ||
356 | struct irq_chip *chip = irq_desc[irq].chip; | ||
357 | |||
358 | unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic, regs); | ||
359 | |||
360 | chip->mask_ack(irq); | ||
361 | if (cascade_irq != NO_IRQ) | ||
362 | generic_handle_irq(cascade_irq, regs); | ||
363 | chip->unmask(irq); | ||
364 | } | ||
365 | |||
366 | void __init qe_ic_init(struct device_node *node, unsigned int flags) | ||
367 | { | ||
368 | struct qe_ic *qe_ic; | ||
369 | struct resource res; | ||
370 | u32 temp = 0, ret, high_active = 0; | ||
371 | |||
372 | qe_ic = alloc_bootmem(sizeof(struct qe_ic)); | ||
373 | if (qe_ic == NULL) | ||
374 | return; | ||
375 | |||
376 | memset(qe_ic, 0, sizeof(struct qe_ic)); | ||
377 | qe_ic->of_node = node ? of_node_get(node) : NULL; | ||
378 | |||
379 | qe_ic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, | ||
380 | NR_QE_IC_INTS, &qe_ic_host_ops, 0); | ||
381 | if (qe_ic->irqhost == NULL) { | ||
382 | of_node_put(node); | ||
383 | return; | ||
384 | } | ||
385 | |||
386 | ret = of_address_to_resource(node, 0, &res); | ||
387 | if (ret) | ||
388 | return; | ||
389 | |||
390 | qe_ic->regs = ioremap(res.start, res.end - res.start + 1); | ||
391 | |||
392 | qe_ic->irqhost->host_data = qe_ic; | ||
393 | qe_ic->hc_irq = qe_ic_irq_chip; | ||
394 | |||
395 | qe_ic->virq_high = irq_of_parse_and_map(node, 0); | ||
396 | qe_ic->virq_low = irq_of_parse_and_map(node, 1); | ||
397 | |||
398 | if (qe_ic->virq_low == NO_IRQ) { | ||
399 | printk(KERN_ERR "Failed to map QE_IC low IRQ\n"); | ||
400 | return; | ||
401 | } | ||
402 | |||
403 | /* default priority scheme is grouped. If spread mode is */ | ||
404 | /* required, configure cicr accordingly. */ | ||
405 | if (flags & QE_IC_SPREADMODE_GRP_W) | ||
406 | temp |= CICR_GWCC; | ||
407 | if (flags & QE_IC_SPREADMODE_GRP_X) | ||
408 | temp |= CICR_GXCC; | ||
409 | if (flags & QE_IC_SPREADMODE_GRP_Y) | ||
410 | temp |= CICR_GYCC; | ||
411 | if (flags & QE_IC_SPREADMODE_GRP_Z) | ||
412 | temp |= CICR_GZCC; | ||
413 | if (flags & QE_IC_SPREADMODE_GRP_RISCA) | ||
414 | temp |= CICR_GRTA; | ||
415 | if (flags & QE_IC_SPREADMODE_GRP_RISCB) | ||
416 | temp |= CICR_GRTB; | ||
417 | |||
418 | /* choose destination signal for highest priority interrupt */ | ||
419 | if (flags & QE_IC_HIGH_SIGNAL) { | ||
420 | temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT); | ||
421 | high_active = 1; | ||
422 | } | ||
423 | |||
424 | qe_ic_write(qe_ic->regs, QEIC_CICR, temp); | ||
425 | |||
426 | set_irq_data(qe_ic->virq_low, qe_ic); | ||
427 | set_irq_chained_handler(qe_ic->virq_low, qe_ic_cascade_low); | ||
428 | |||
429 | if (qe_ic->virq_high != NO_IRQ) { | ||
430 | set_irq_data(qe_ic->virq_high, qe_ic); | ||
431 | set_irq_chained_handler(qe_ic->virq_high, qe_ic_cascade_high); | ||
432 | } | ||
433 | |||
434 | printk("QEIC (%d IRQ sources) at %p\n", NR_QE_IC_INTS, qe_ic->regs); | ||
435 | } | ||
436 | |||
437 | void qe_ic_set_highest_priority(unsigned int virq, int high) | ||
438 | { | ||
439 | struct qe_ic *qe_ic = qe_ic_from_irq(virq); | ||
440 | unsigned int src = virq_to_hw(virq); | ||
441 | u32 temp = 0; | ||
442 | |||
443 | temp = qe_ic_read(qe_ic->regs, QEIC_CICR); | ||
444 | |||
445 | temp &= ~CICR_HP_MASK; | ||
446 | temp |= src << CICR_HP_SHIFT; | ||
447 | |||
448 | temp &= ~CICR_HPIT_MASK; | ||
449 | temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT; | ||
450 | |||
451 | qe_ic_write(qe_ic->regs, QEIC_CICR, temp); | ||
452 | } | ||
453 | |||
454 | /* Set Priority level within its group, from 1 to 8 */ | ||
455 | int qe_ic_set_priority(unsigned int virq, unsigned int priority) | ||
456 | { | ||
457 | struct qe_ic *qe_ic = qe_ic_from_irq(virq); | ||
458 | unsigned int src = virq_to_hw(virq); | ||
459 | u32 temp; | ||
460 | |||
461 | if (priority > 8 || priority == 0) | ||
462 | return -EINVAL; | ||
463 | if (src > 127) | ||
464 | return -EINVAL; | ||
465 | if (qe_ic_info[src].pri_reg == 0) | ||
466 | return -EINVAL; | ||
467 | |||
468 | temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg); | ||
469 | |||
470 | if (priority < 4) { | ||
471 | temp &= ~(0x7 << (32 - priority * 3)); | ||
472 | temp |= qe_ic_info[src].pri_code << (32 - priority * 3); | ||
473 | } else { | ||
474 | temp &= ~(0x7 << (24 - priority * 3)); | ||
475 | temp |= qe_ic_info[src].pri_code << (24 - priority * 3); | ||
476 | } | ||
477 | |||
478 | qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp); | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | /* Set a QE priority to use high irq, only priority 1~2 can use high irq */ | ||
484 | int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high) | ||
485 | { | ||
486 | struct qe_ic *qe_ic = qe_ic_from_irq(virq); | ||
487 | unsigned int src = virq_to_hw(virq); | ||
488 | u32 temp, control_reg = QEIC_CICNR, shift = 0; | ||
489 | |||
490 | if (priority > 2 || priority == 0) | ||
491 | return -EINVAL; | ||
492 | |||
493 | switch (qe_ic_info[src].pri_reg) { | ||
494 | case QEIC_CIPZCC: | ||
495 | shift = CICNR_ZCC1T_SHIFT; | ||
496 | break; | ||
497 | case QEIC_CIPWCC: | ||
498 | shift = CICNR_WCC1T_SHIFT; | ||
499 | break; | ||
500 | case QEIC_CIPYCC: | ||
501 | shift = CICNR_YCC1T_SHIFT; | ||
502 | break; | ||
503 | case QEIC_CIPXCC: | ||
504 | shift = CICNR_XCC1T_SHIFT; | ||
505 | break; | ||
506 | case QEIC_CIPRTA: | ||
507 | shift = CRICR_RTA1T_SHIFT; | ||
508 | control_reg = QEIC_CRICR; | ||
509 | break; | ||
510 | case QEIC_CIPRTB: | ||
511 | shift = CRICR_RTB1T_SHIFT; | ||
512 | control_reg = QEIC_CRICR; | ||
513 | break; | ||
514 | default: | ||
515 | return -EINVAL; | ||
516 | } | ||
517 | |||
518 | shift += (2 - priority) * 2; | ||
519 | temp = qe_ic_read(qe_ic->regs, control_reg); | ||
520 | temp &= ~(SIGNAL_MASK << shift); | ||
521 | temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift; | ||
522 | qe_ic_write(qe_ic->regs, control_reg, temp); | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static struct sysdev_class qe_ic_sysclass = { | ||
528 | set_kset_name("qe_ic"), | ||
529 | }; | ||
530 | |||
531 | static struct sys_device device_qe_ic = { | ||
532 | .id = 0, | ||
533 | .cls = &qe_ic_sysclass, | ||
534 | }; | ||
535 | |||
536 | static int __init init_qe_ic_sysfs(void) | ||
537 | { | ||
538 | int rc; | ||
539 | |||
540 | printk(KERN_DEBUG "Registering qe_ic with sysfs...\n"); | ||
541 | |||
542 | rc = sysdev_class_register(&qe_ic_sysclass); | ||
543 | if (rc) { | ||
544 | printk(KERN_ERR "Failed registering qe_ic sys class\n"); | ||
545 | return -ENODEV; | ||
546 | } | ||
547 | rc = sysdev_register(&device_qe_ic); | ||
548 | if (rc) { | ||
549 | printk(KERN_ERR "Failed registering qe_ic sys device\n"); | ||
550 | return -ENODEV; | ||
551 | } | ||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | subsys_initcall(init_qe_ic_sysfs); | ||
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h new file mode 100644 index 000000000000..9a631adb189d --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.h | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * arch/powerpc/sysdev/qe_lib/qe_ic.h | ||
3 | * | ||
4 | * QUICC ENGINE Interrupt Controller Header | ||
5 | * | ||
6 | * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. | ||
7 | * | ||
8 | * Author: Li Yang <leoli@freescale.com> | ||
9 | * Based on code from Shlomi Gridish <gridish@freescale.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | */ | ||
16 | #ifndef _POWERPC_SYSDEV_QE_IC_H | ||
17 | #define _POWERPC_SYSDEV_QE_IC_H | ||
18 | |||
19 | #include <asm/qe_ic.h> | ||
20 | |||
21 | #define NR_QE_IC_INTS 64 | ||
22 | |||
23 | /* QE IC registers offset */ | ||
24 | #define QEIC_CICR 0x00 | ||
25 | #define QEIC_CIVEC 0x04 | ||
26 | #define QEIC_CRIPNR 0x08 | ||
27 | #define QEIC_CIPNR 0x0c | ||
28 | #define QEIC_CIPXCC 0x10 | ||
29 | #define QEIC_CIPYCC 0x14 | ||
30 | #define QEIC_CIPWCC 0x18 | ||
31 | #define QEIC_CIPZCC 0x1c | ||
32 | #define QEIC_CIMR 0x20 | ||
33 | #define QEIC_CRIMR 0x24 | ||
34 | #define QEIC_CICNR 0x28 | ||
35 | #define QEIC_CIPRTA 0x30 | ||
36 | #define QEIC_CIPRTB 0x34 | ||
37 | #define QEIC_CRICR 0x3c | ||
38 | #define QEIC_CHIVEC 0x60 | ||
39 | |||
40 | /* Interrupt priority registers */ | ||
41 | #define CIPCC_SHIFT_PRI0 29 | ||
42 | #define CIPCC_SHIFT_PRI1 26 | ||
43 | #define CIPCC_SHIFT_PRI2 23 | ||
44 | #define CIPCC_SHIFT_PRI3 20 | ||
45 | #define CIPCC_SHIFT_PRI4 13 | ||
46 | #define CIPCC_SHIFT_PRI5 10 | ||
47 | #define CIPCC_SHIFT_PRI6 7 | ||
48 | #define CIPCC_SHIFT_PRI7 4 | ||
49 | |||
50 | /* CICR priority modes */ | ||
51 | #define CICR_GWCC 0x00040000 | ||
52 | #define CICR_GXCC 0x00020000 | ||
53 | #define CICR_GYCC 0x00010000 | ||
54 | #define CICR_GZCC 0x00080000 | ||
55 | #define CICR_GRTA 0x00200000 | ||
56 | #define CICR_GRTB 0x00400000 | ||
57 | #define CICR_HPIT_SHIFT 8 | ||
58 | #define CICR_HPIT_MASK 0x00000300 | ||
59 | #define CICR_HP_SHIFT 24 | ||
60 | #define CICR_HP_MASK 0x3f000000 | ||
61 | |||
62 | /* CICNR */ | ||
63 | #define CICNR_WCC1T_SHIFT 20 | ||
64 | #define CICNR_ZCC1T_SHIFT 28 | ||
65 | #define CICNR_YCC1T_SHIFT 12 | ||
66 | #define CICNR_XCC1T_SHIFT 4 | ||
67 | |||
68 | /* CRICR */ | ||
69 | #define CRICR_RTA1T_SHIFT 20 | ||
70 | #define CRICR_RTB1T_SHIFT 28 | ||
71 | |||
72 | /* Signal indicator */ | ||
73 | #define SIGNAL_MASK 3 | ||
74 | #define SIGNAL_HIGH 2 | ||
75 | #define SIGNAL_LOW 0 | ||
76 | |||
77 | struct qe_ic { | ||
78 | /* Control registers offset */ | ||
79 | volatile u32 __iomem *regs; | ||
80 | |||
81 | /* The remapper for this QEIC */ | ||
82 | struct irq_host *irqhost; | ||
83 | |||
84 | /* The "linux" controller struct */ | ||
85 | struct irq_chip hc_irq; | ||
86 | |||
87 | /* The device node of the interrupt controller */ | ||
88 | struct device_node *of_node; | ||
89 | |||
90 | /* VIRQ numbers of QE high/low irqs */ | ||
91 | unsigned int virq_high; | ||
92 | unsigned int virq_low; | ||
93 | }; | ||
94 | |||
95 | /* | ||
96 | * QE interrupt controller internal structure | ||
97 | */ | ||
98 | struct qe_ic_info { | ||
99 | u32 mask; /* location of this source at the QIMR register. */ | ||
100 | u32 mask_reg; /* Mask register offset */ | ||
101 | u8 pri_code; /* for grouped interrupts sources - the interrupt | ||
102 | code as appears at the group priority register */ | ||
103 | u32 pri_reg; /* Group priority register offset */ | ||
104 | }; | ||
105 | |||
106 | #endif /* _POWERPC_SYSDEV_QE_IC_H */ | ||
diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c new file mode 100644 index 000000000000..aea435970389 --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/qe_io.c | |||
@@ -0,0 +1,226 @@ | |||
1 | /* | ||
2 | * arch/powerpc/sysdev/qe_lib/qe_io.c | ||
3 | * | ||
4 | * QE Parallel I/O ports configuration routines | ||
5 | * | ||
6 | * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. | ||
7 | * | ||
8 | * Author: Li Yang <LeoLi@freescale.com> | ||
9 | * Based on code from Shlomi Gridish <gridish@freescale.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | */ | ||
16 | |||
17 | #include <linux/config.h> | ||
18 | #include <linux/stddef.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/ioport.h> | ||
24 | |||
25 | #include <asm/io.h> | ||
26 | #include <asm/prom.h> | ||
27 | #include <sysdev/fsl_soc.h> | ||
28 | |||
29 | #undef DEBUG | ||
30 | |||
31 | #define NUM_OF_PINS 32 | ||
32 | |||
33 | struct port_regs { | ||
34 | __be32 cpodr; /* Open drain register */ | ||
35 | __be32 cpdata; /* Data register */ | ||
36 | __be32 cpdir1; /* Direction register */ | ||
37 | __be32 cpdir2; /* Direction register */ | ||
38 | __be32 cppar1; /* Pin assignment register */ | ||
39 | __be32 cppar2; /* Pin assignment register */ | ||
40 | }; | ||
41 | |||
42 | static struct port_regs *par_io = NULL; | ||
43 | static int num_par_io_ports = 0; | ||
44 | |||
45 | int par_io_init(struct device_node *np) | ||
46 | { | ||
47 | struct resource res; | ||
48 | int ret; | ||
49 | const u32 *num_ports; | ||
50 | |||
51 | /* Map Parallel I/O ports registers */ | ||
52 | ret = of_address_to_resource(np, 0, &res); | ||
53 | if (ret) | ||
54 | return ret; | ||
55 | par_io = ioremap(res.start, res.end - res.start + 1); | ||
56 | |||
57 | num_ports = get_property(np, "num-ports", NULL); | ||
58 | if (num_ports) | ||
59 | num_par_io_ports = *num_ports; | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain, | ||
65 | int assignment, int has_irq) | ||
66 | { | ||
67 | u32 pin_mask1bit, pin_mask2bits, new_mask2bits, tmp_val; | ||
68 | |||
69 | if (!par_io) | ||
70 | return -1; | ||
71 | |||
72 | /* calculate pin location for single and 2 bits information */ | ||
73 | pin_mask1bit = (u32) (1 << (NUM_OF_PINS - (pin + 1))); | ||
74 | |||
75 | /* Set open drain, if required */ | ||
76 | tmp_val = in_be32(&par_io[port].cpodr); | ||
77 | if (open_drain) | ||
78 | out_be32(&par_io[port].cpodr, pin_mask1bit | tmp_val); | ||
79 | else | ||
80 | out_be32(&par_io[port].cpodr, ~pin_mask1bit & tmp_val); | ||
81 | |||
82 | /* define direction */ | ||
83 | tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ? | ||
84 | in_be32(&par_io[port].cpdir2) : | ||
85 | in_be32(&par_io[port].cpdir1); | ||
86 | |||
87 | /* get all bits mask for 2 bit per port */ | ||
88 | pin_mask2bits = (u32) (0x3 << (NUM_OF_PINS - | ||
89 | (pin % (NUM_OF_PINS / 2) + 1) * 2)); | ||
90 | |||
91 | /* Get the final mask we need for the right definition */ | ||
92 | new_mask2bits = (u32) (dir << (NUM_OF_PINS - | ||
93 | (pin % (NUM_OF_PINS / 2) + 1) * 2)); | ||
94 | |||
95 | /* clear and set 2 bits mask */ | ||
96 | if (pin > (NUM_OF_PINS / 2) - 1) { | ||
97 | out_be32(&par_io[port].cpdir2, | ||
98 | ~pin_mask2bits & tmp_val); | ||
99 | tmp_val &= ~pin_mask2bits; | ||
100 | out_be32(&par_io[port].cpdir2, new_mask2bits | tmp_val); | ||
101 | } else { | ||
102 | out_be32(&par_io[port].cpdir1, | ||
103 | ~pin_mask2bits & tmp_val); | ||
104 | tmp_val &= ~pin_mask2bits; | ||
105 | out_be32(&par_io[port].cpdir1, new_mask2bits | tmp_val); | ||
106 | } | ||
107 | /* define pin assignment */ | ||
108 | tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ? | ||
109 | in_be32(&par_io[port].cppar2) : | ||
110 | in_be32(&par_io[port].cppar1); | ||
111 | |||
112 | new_mask2bits = (u32) (assignment << (NUM_OF_PINS - | ||
113 | (pin % (NUM_OF_PINS / 2) + 1) * 2)); | ||
114 | /* clear and set 2 bits mask */ | ||
115 | if (pin > (NUM_OF_PINS / 2) - 1) { | ||
116 | out_be32(&par_io[port].cppar2, | ||
117 | ~pin_mask2bits & tmp_val); | ||
118 | tmp_val &= ~pin_mask2bits; | ||
119 | out_be32(&par_io[port].cppar2, new_mask2bits | tmp_val); | ||
120 | } else { | ||
121 | out_be32(&par_io[port].cppar1, | ||
122 | ~pin_mask2bits & tmp_val); | ||
123 | tmp_val &= ~pin_mask2bits; | ||
124 | out_be32(&par_io[port].cppar1, new_mask2bits | tmp_val); | ||
125 | } | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | EXPORT_SYMBOL(par_io_config_pin); | ||
130 | |||
131 | int par_io_data_set(u8 port, u8 pin, u8 val) | ||
132 | { | ||
133 | u32 pin_mask, tmp_val; | ||
134 | |||
135 | if (port >= num_par_io_ports) | ||
136 | return -EINVAL; | ||
137 | if (pin >= NUM_OF_PINS) | ||
138 | return -EINVAL; | ||
139 | /* calculate pin location */ | ||
140 | pin_mask = (u32) (1 << (NUM_OF_PINS - 1 - pin)); | ||
141 | |||
142 | tmp_val = in_be32(&par_io[port].cpdata); | ||
143 | |||
144 | if (val == 0) /* clear */ | ||
145 | out_be32(&par_io[port].cpdata, ~pin_mask & tmp_val); | ||
146 | else /* set */ | ||
147 | out_be32(&par_io[port].cpdata, pin_mask | tmp_val); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | EXPORT_SYMBOL(par_io_data_set); | ||
152 | |||
153 | int par_io_of_config(struct device_node *np) | ||
154 | { | ||
155 | struct device_node *pio; | ||
156 | const phandle *ph; | ||
157 | int pio_map_len; | ||
158 | const unsigned int *pio_map; | ||
159 | |||
160 | if (par_io == NULL) { | ||
161 | printk(KERN_ERR "par_io not initialized \n"); | ||
162 | return -1; | ||
163 | } | ||
164 | |||
165 | ph = get_property(np, "pio-handle", NULL); | ||
166 | if (ph == 0) { | ||
167 | printk(KERN_ERR "pio-handle not available \n"); | ||
168 | return -1; | ||
169 | } | ||
170 | |||
171 | pio = of_find_node_by_phandle(*ph); | ||
172 | |||
173 | pio_map = get_property(pio, "pio-map", &pio_map_len); | ||
174 | if (pio_map == NULL) { | ||
175 | printk(KERN_ERR "pio-map is not set! \n"); | ||
176 | return -1; | ||
177 | } | ||
178 | pio_map_len /= sizeof(unsigned int); | ||
179 | if ((pio_map_len % 6) != 0) { | ||
180 | printk(KERN_ERR "pio-map format wrong! \n"); | ||
181 | return -1; | ||
182 | } | ||
183 | |||
184 | while (pio_map_len > 0) { | ||
185 | par_io_config_pin((u8) pio_map[0], (u8) pio_map[1], | ||
186 | (int) pio_map[2], (int) pio_map[3], | ||
187 | (int) pio_map[4], (int) pio_map[5]); | ||
188 | pio_map += 6; | ||
189 | pio_map_len -= 6; | ||
190 | } | ||
191 | of_node_put(pio); | ||
192 | return 0; | ||
193 | } | ||
194 | EXPORT_SYMBOL(par_io_of_config); | ||
195 | |||
196 | #ifdef DEBUG | ||
197 | static void dump_par_io(void) | ||
198 | { | ||
199 | int i; | ||
200 | |||
201 | printk(KERN_INFO "PAR IO registars:\n"); | ||
202 | printk(KERN_INFO "Base address: 0x%08x\n", (u32) par_io); | ||
203 | for (i = 0; i < num_par_io_ports; i++) { | ||
204 | printk(KERN_INFO "cpodr[%d] : addr - 0x%08x, val - 0x%08x\n", | ||
205 | i, (u32) & par_io[i].cpodr, | ||
206 | in_be32(&par_io[i].cpodr)); | ||
207 | printk(KERN_INFO "cpdata[%d]: addr - 0x%08x, val - 0x%08x\n", | ||
208 | i, (u32) & par_io[i].cpdata, | ||
209 | in_be32(&par_io[i].cpdata)); | ||
210 | printk(KERN_INFO "cpdir1[%d]: addr - 0x%08x, val - 0x%08x\n", | ||
211 | i, (u32) & par_io[i].cpdir1, | ||
212 | in_be32(&par_io[i].cpdir1)); | ||
213 | printk(KERN_INFO "cpdir2[%d]: addr - 0x%08x, val - 0x%08x\n", | ||
214 | i, (u32) & par_io[i].cpdir2, | ||
215 | in_be32(&par_io[i].cpdir2)); | ||
216 | printk(KERN_INFO "cppar1[%d]: addr - 0x%08x, val - 0x%08x\n", | ||
217 | i, (u32) & par_io[i].cppar1, | ||
218 | in_be32(&par_io[i].cppar1)); | ||
219 | printk(KERN_INFO "cppar2[%d]: addr - 0x%08x, val - 0x%08x\n", | ||
220 | i, (u32) & par_io[i].cppar2, | ||
221 | in_be32(&par_io[i].cppar2)); | ||
222 | } | ||
223 | |||
224 | } | ||
225 | EXPORT_SYMBOL(dump_par_io); | ||
226 | #endif /* DEBUG */ | ||
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c new file mode 100644 index 000000000000..916c9e5df57f --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/ucc.c | |||
@@ -0,0 +1,251 @@ | |||
1 | /* | ||
2 | * arch/powerpc/sysdev/qe_lib/ucc.c | ||
3 | * | ||
4 | * QE UCC API Set - UCC specific routines implementations. | ||
5 | * | ||
6 | * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. | ||
7 | * | ||
8 | * Authors: Shlomi Gridish <gridish@freescale.com> | ||
9 | * Li Yang <leoli@freescale.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | */ | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/stddef.h> | ||
21 | |||
22 | #include <asm/irq.h> | ||
23 | #include <asm/io.h> | ||
24 | #include <asm/immap_qe.h> | ||
25 | #include <asm/qe.h> | ||
26 | #include <asm/ucc.h> | ||
27 | |||
28 | static DEFINE_SPINLOCK(ucc_lock); | ||
29 | |||
30 | int ucc_set_qe_mux_mii_mng(int ucc_num) | ||
31 | { | ||
32 | unsigned long flags; | ||
33 | |||
34 | spin_lock_irqsave(&ucc_lock, flags); | ||
35 | out_be32(&qe_immr->qmx.cmxgcr, | ||
36 | ((in_be32(&qe_immr->qmx.cmxgcr) & | ||
37 | ~QE_CMXGCR_MII_ENET_MNG) | | ||
38 | (ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT))); | ||
39 | spin_unlock_irqrestore(&ucc_lock, flags); | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | int ucc_set_type(int ucc_num, struct ucc_common *regs, | ||
45 | enum ucc_speed_type speed) | ||
46 | { | ||
47 | u8 guemr = 0; | ||
48 | |||
49 | /* check if the UCC number is in range. */ | ||
50 | if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0)) | ||
51 | return -EINVAL; | ||
52 | |||
53 | guemr = regs->guemr; | ||
54 | guemr &= ~(UCC_GUEMR_MODE_MASK_RX | UCC_GUEMR_MODE_MASK_TX); | ||
55 | switch (speed) { | ||
56 | case UCC_SPEED_TYPE_SLOW: | ||
57 | guemr |= (UCC_GUEMR_MODE_SLOW_RX | UCC_GUEMR_MODE_SLOW_TX); | ||
58 | break; | ||
59 | case UCC_SPEED_TYPE_FAST: | ||
60 | guemr |= (UCC_GUEMR_MODE_FAST_RX | UCC_GUEMR_MODE_FAST_TX); | ||
61 | break; | ||
62 | default: | ||
63 | return -EINVAL; | ||
64 | } | ||
65 | regs->guemr = guemr; | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | int ucc_init_guemr(struct ucc_common *regs) | ||
71 | { | ||
72 | u8 guemr = 0; | ||
73 | |||
74 | if (!regs) | ||
75 | return -EINVAL; | ||
76 | |||
77 | /* Set bit 3 (which is reserved in the GUEMR register) to 1 */ | ||
78 | guemr = UCC_GUEMR_SET_RESERVED3; | ||
79 | |||
80 | regs->guemr = guemr; | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static void get_cmxucr_reg(int ucc_num, volatile u32 ** p_cmxucr, u8 * reg_num, | ||
86 | u8 * shift) | ||
87 | { | ||
88 | switch (ucc_num) { | ||
89 | case 0: *p_cmxucr = &(qe_immr->qmx.cmxucr1); | ||
90 | *reg_num = 1; | ||
91 | *shift = 16; | ||
92 | break; | ||
93 | case 2: *p_cmxucr = &(qe_immr->qmx.cmxucr1); | ||
94 | *reg_num = 1; | ||
95 | *shift = 0; | ||
96 | break; | ||
97 | case 4: *p_cmxucr = &(qe_immr->qmx.cmxucr2); | ||
98 | *reg_num = 2; | ||
99 | *shift = 16; | ||
100 | break; | ||
101 | case 6: *p_cmxucr = &(qe_immr->qmx.cmxucr2); | ||
102 | *reg_num = 2; | ||
103 | *shift = 0; | ||
104 | break; | ||
105 | case 1: *p_cmxucr = &(qe_immr->qmx.cmxucr3); | ||
106 | *reg_num = 3; | ||
107 | *shift = 16; | ||
108 | break; | ||
109 | case 3: *p_cmxucr = &(qe_immr->qmx.cmxucr3); | ||
110 | *reg_num = 3; | ||
111 | *shift = 0; | ||
112 | break; | ||
113 | case 5: *p_cmxucr = &(qe_immr->qmx.cmxucr4); | ||
114 | *reg_num = 4; | ||
115 | *shift = 16; | ||
116 | break; | ||
117 | case 7: *p_cmxucr = &(qe_immr->qmx.cmxucr4); | ||
118 | *reg_num = 4; | ||
119 | *shift = 0; | ||
120 | break; | ||
121 | default: | ||
122 | break; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | int ucc_mux_set_grant_tsa_bkpt(int ucc_num, int set, u32 mask) | ||
127 | { | ||
128 | volatile u32 *p_cmxucr; | ||
129 | u8 reg_num; | ||
130 | u8 shift; | ||
131 | |||
132 | /* check if the UCC number is in range. */ | ||
133 | if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0)) | ||
134 | return -EINVAL; | ||
135 | |||
136 | get_cmxucr_reg(ucc_num, &p_cmxucr, ®_num, &shift); | ||
137 | |||
138 | if (set) | ||
139 | out_be32(p_cmxucr, in_be32(p_cmxucr) | (mask << shift)); | ||
140 | else | ||
141 | out_be32(p_cmxucr, in_be32(p_cmxucr) & ~(mask << shift)); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode) | ||
147 | { | ||
148 | volatile u32 *p_cmxucr; | ||
149 | u8 reg_num; | ||
150 | u8 shift; | ||
151 | u32 clock_bits; | ||
152 | u32 clock_mask; | ||
153 | int source = -1; | ||
154 | |||
155 | /* check if the UCC number is in range. */ | ||
156 | if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0)) | ||
157 | return -EINVAL; | ||
158 | |||
159 | if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX))) { | ||
160 | printk(KERN_ERR | ||
161 | "ucc_set_qe_mux_rxtx: bad comm mode type passed."); | ||
162 | return -EINVAL; | ||
163 | } | ||
164 | |||
165 | get_cmxucr_reg(ucc_num, &p_cmxucr, ®_num, &shift); | ||
166 | |||
167 | switch (reg_num) { | ||
168 | case 1: | ||
169 | switch (clock) { | ||
170 | case QE_BRG1: source = 1; break; | ||
171 | case QE_BRG2: source = 2; break; | ||
172 | case QE_BRG7: source = 3; break; | ||
173 | case QE_BRG8: source = 4; break; | ||
174 | case QE_CLK9: source = 5; break; | ||
175 | case QE_CLK10: source = 6; break; | ||
176 | case QE_CLK11: source = 7; break; | ||
177 | case QE_CLK12: source = 8; break; | ||
178 | case QE_CLK15: source = 9; break; | ||
179 | case QE_CLK16: source = 10; break; | ||
180 | default: source = -1; break; | ||
181 | } | ||
182 | break; | ||
183 | case 2: | ||
184 | switch (clock) { | ||
185 | case QE_BRG5: source = 1; break; | ||
186 | case QE_BRG6: source = 2; break; | ||
187 | case QE_BRG7: source = 3; break; | ||
188 | case QE_BRG8: source = 4; break; | ||
189 | case QE_CLK13: source = 5; break; | ||
190 | case QE_CLK14: source = 6; break; | ||
191 | case QE_CLK19: source = 7; break; | ||
192 | case QE_CLK20: source = 8; break; | ||
193 | case QE_CLK15: source = 9; break; | ||
194 | case QE_CLK16: source = 10; break; | ||
195 | default: source = -1; break; | ||
196 | } | ||
197 | break; | ||
198 | case 3: | ||
199 | switch (clock) { | ||
200 | case QE_BRG9: source = 1; break; | ||
201 | case QE_BRG10: source = 2; break; | ||
202 | case QE_BRG15: source = 3; break; | ||
203 | case QE_BRG16: source = 4; break; | ||
204 | case QE_CLK3: source = 5; break; | ||
205 | case QE_CLK4: source = 6; break; | ||
206 | case QE_CLK17: source = 7; break; | ||
207 | case QE_CLK18: source = 8; break; | ||
208 | case QE_CLK7: source = 9; break; | ||
209 | case QE_CLK8: source = 10; break; | ||
210 | default: source = -1; break; | ||
211 | } | ||
212 | break; | ||
213 | case 4: | ||
214 | switch (clock) { | ||
215 | case QE_BRG13: source = 1; break; | ||
216 | case QE_BRG14: source = 2; break; | ||
217 | case QE_BRG15: source = 3; break; | ||
218 | case QE_BRG16: source = 4; break; | ||
219 | case QE_CLK5: source = 5; break; | ||
220 | case QE_CLK6: source = 6; break; | ||
221 | case QE_CLK21: source = 7; break; | ||
222 | case QE_CLK22: source = 8; break; | ||
223 | case QE_CLK7: source = 9; break; | ||
224 | case QE_CLK8: source = 10; break; | ||
225 | default: source = -1; break; | ||
226 | } | ||
227 | break; | ||
228 | default: | ||
229 | source = -1; | ||
230 | break; | ||
231 | } | ||
232 | |||
233 | if (source == -1) { | ||
234 | printk(KERN_ERR | ||
235 | "ucc_set_qe_mux_rxtx: Bad combination of clock and UCC."); | ||
236 | return -ENOENT; | ||
237 | } | ||
238 | |||
239 | clock_bits = (u32) source; | ||
240 | clock_mask = QE_CMXUCR_TX_CLK_SRC_MASK; | ||
241 | if (mode == COMM_DIR_RX) { | ||
242 | clock_bits <<= 4; /* Rx field is 4 bits to left of Tx field */ | ||
243 | clock_mask <<= 4; /* Rx field is 4 bits to left of Tx field */ | ||
244 | } | ||
245 | clock_bits <<= shift; | ||
246 | clock_mask <<= shift; | ||
247 | |||
248 | out_be32(p_cmxucr, (in_be32(p_cmxucr) & ~clock_mask) | clock_bits); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c new file mode 100644 index 000000000000..c2be7348fcbd --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c | |||
@@ -0,0 +1,396 @@ | |||
1 | /* | ||
2 | * arch/powerpc/sysdev/qe_lib/ucc_fast.c | ||
3 | * | ||
4 | * QE UCC Fast API Set - UCC Fast specific routines implementations. | ||
5 | * | ||
6 | * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. | ||
7 | * | ||
8 | * Authors: Shlomi Gridish <gridish@freescale.com> | ||
9 | * Li Yang <leoli@freescale.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | */ | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/stddef.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | |||
23 | #include <asm/io.h> | ||
24 | #include <asm/immap_qe.h> | ||
25 | #include <asm/qe.h> | ||
26 | |||
27 | #include <asm/ucc.h> | ||
28 | #include <asm/ucc_fast.h> | ||
29 | |||
30 | #define uccf_printk(level, format, arg...) \ | ||
31 | printk(level format "\n", ## arg) | ||
32 | |||
33 | #define uccf_dbg(format, arg...) \ | ||
34 | uccf_printk(KERN_DEBUG , format , ## arg) | ||
35 | #define uccf_err(format, arg...) \ | ||
36 | uccf_printk(KERN_ERR , format , ## arg) | ||
37 | #define uccf_info(format, arg...) \ | ||
38 | uccf_printk(KERN_INFO , format , ## arg) | ||
39 | #define uccf_warn(format, arg...) \ | ||
40 | uccf_printk(KERN_WARNING , format , ## arg) | ||
41 | |||
42 | #ifdef UCCF_VERBOSE_DEBUG | ||
43 | #define uccf_vdbg uccf_dbg | ||
44 | #else | ||
45 | #define uccf_vdbg(fmt, args...) do { } while (0) | ||
46 | #endif /* UCCF_VERBOSE_DEBUG */ | ||
47 | |||
48 | void ucc_fast_dump_regs(struct ucc_fast_private * uccf) | ||
49 | { | ||
50 | uccf_info("UCC%d Fast registers:", uccf->uf_info->ucc_num); | ||
51 | uccf_info("Base address: 0x%08x", (u32) uccf->uf_regs); | ||
52 | |||
53 | uccf_info("gumr : addr - 0x%08x, val - 0x%08x", | ||
54 | (u32) & uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr)); | ||
55 | uccf_info("upsmr : addr - 0x%08x, val - 0x%08x", | ||
56 | (u32) & uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr)); | ||
57 | uccf_info("utodr : addr - 0x%08x, val - 0x%04x", | ||
58 | (u32) & uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr)); | ||
59 | uccf_info("udsr : addr - 0x%08x, val - 0x%04x", | ||
60 | (u32) & uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr)); | ||
61 | uccf_info("ucce : addr - 0x%08x, val - 0x%08x", | ||
62 | (u32) & uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce)); | ||
63 | uccf_info("uccm : addr - 0x%08x, val - 0x%08x", | ||
64 | (u32) & uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm)); | ||
65 | uccf_info("uccs : addr - 0x%08x, val - 0x%02x", | ||
66 | (u32) & uccf->uf_regs->uccs, uccf->uf_regs->uccs); | ||
67 | uccf_info("urfb : addr - 0x%08x, val - 0x%08x", | ||
68 | (u32) & uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb)); | ||
69 | uccf_info("urfs : addr - 0x%08x, val - 0x%04x", | ||
70 | (u32) & uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs)); | ||
71 | uccf_info("urfet : addr - 0x%08x, val - 0x%04x", | ||
72 | (u32) & uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet)); | ||
73 | uccf_info("urfset: addr - 0x%08x, val - 0x%04x", | ||
74 | (u32) & uccf->uf_regs->urfset, | ||
75 | in_be16(&uccf->uf_regs->urfset)); | ||
76 | uccf_info("utfb : addr - 0x%08x, val - 0x%08x", | ||
77 | (u32) & uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb)); | ||
78 | uccf_info("utfs : addr - 0x%08x, val - 0x%04x", | ||
79 | (u32) & uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs)); | ||
80 | uccf_info("utfet : addr - 0x%08x, val - 0x%04x", | ||
81 | (u32) & uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet)); | ||
82 | uccf_info("utftt : addr - 0x%08x, val - 0x%04x", | ||
83 | (u32) & uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt)); | ||
84 | uccf_info("utpt : addr - 0x%08x, val - 0x%04x", | ||
85 | (u32) & uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt)); | ||
86 | uccf_info("urtry : addr - 0x%08x, val - 0x%08x", | ||
87 | (u32) & uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry)); | ||
88 | uccf_info("guemr : addr - 0x%08x, val - 0x%02x", | ||
89 | (u32) & uccf->uf_regs->guemr, uccf->uf_regs->guemr); | ||
90 | } | ||
91 | |||
92 | u32 ucc_fast_get_qe_cr_subblock(int uccf_num) | ||
93 | { | ||
94 | switch (uccf_num) { | ||
95 | case 0: return QE_CR_SUBBLOCK_UCCFAST1; | ||
96 | case 1: return QE_CR_SUBBLOCK_UCCFAST2; | ||
97 | case 2: return QE_CR_SUBBLOCK_UCCFAST3; | ||
98 | case 3: return QE_CR_SUBBLOCK_UCCFAST4; | ||
99 | case 4: return QE_CR_SUBBLOCK_UCCFAST5; | ||
100 | case 5: return QE_CR_SUBBLOCK_UCCFAST6; | ||
101 | case 6: return QE_CR_SUBBLOCK_UCCFAST7; | ||
102 | case 7: return QE_CR_SUBBLOCK_UCCFAST8; | ||
103 | default: return QE_CR_SUBBLOCK_INVALID; | ||
104 | } | ||
105 | } | ||
106 | |||
107 | void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf) | ||
108 | { | ||
109 | out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD); | ||
110 | } | ||
111 | |||
112 | void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode) | ||
113 | { | ||
114 | struct ucc_fast *uf_regs; | ||
115 | u32 gumr; | ||
116 | |||
117 | uf_regs = uccf->uf_regs; | ||
118 | |||
119 | /* Enable reception and/or transmission on this UCC. */ | ||
120 | gumr = in_be32(&uf_regs->gumr); | ||
121 | if (mode & COMM_DIR_TX) { | ||
122 | gumr |= UCC_FAST_GUMR_ENT; | ||
123 | uccf->enabled_tx = 1; | ||
124 | } | ||
125 | if (mode & COMM_DIR_RX) { | ||
126 | gumr |= UCC_FAST_GUMR_ENR; | ||
127 | uccf->enabled_rx = 1; | ||
128 | } | ||
129 | out_be32(&uf_regs->gumr, gumr); | ||
130 | } | ||
131 | |||
132 | void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode) | ||
133 | { | ||
134 | struct ucc_fast *uf_regs; | ||
135 | u32 gumr; | ||
136 | |||
137 | uf_regs = uccf->uf_regs; | ||
138 | |||
139 | /* Disable reception and/or transmission on this UCC. */ | ||
140 | gumr = in_be32(&uf_regs->gumr); | ||
141 | if (mode & COMM_DIR_TX) { | ||
142 | gumr &= ~UCC_FAST_GUMR_ENT; | ||
143 | uccf->enabled_tx = 0; | ||
144 | } | ||
145 | if (mode & COMM_DIR_RX) { | ||
146 | gumr &= ~UCC_FAST_GUMR_ENR; | ||
147 | uccf->enabled_rx = 0; | ||
148 | } | ||
149 | out_be32(&uf_regs->gumr, gumr); | ||
150 | } | ||
151 | |||
152 | int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret) | ||
153 | { | ||
154 | struct ucc_fast_private *uccf; | ||
155 | struct ucc_fast *uf_regs; | ||
156 | u32 gumr = 0; | ||
157 | int ret; | ||
158 | |||
159 | uccf_vdbg("%s: IN", __FUNCTION__); | ||
160 | |||
161 | if (!uf_info) | ||
162 | return -EINVAL; | ||
163 | |||
164 | /* check if the UCC port number is in range. */ | ||
165 | if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) { | ||
166 | uccf_err("ucc_fast_init: Illagal UCC number!"); | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | |||
170 | /* Check that 'max_rx_buf_length' is properly aligned (4). */ | ||
171 | if (uf_info->max_rx_buf_length & (UCC_FAST_MRBLR_ALIGNMENT - 1)) { | ||
172 | uccf_err("ucc_fast_init: max_rx_buf_length not aligned."); | ||
173 | return -EINVAL; | ||
174 | } | ||
175 | |||
176 | /* Validate Virtual Fifo register values */ | ||
177 | if (uf_info->urfs < UCC_FAST_URFS_MIN_VAL) { | ||
178 | uccf_err | ||
179 | ("ucc_fast_init: Virtual Fifo register urfs too small."); | ||
180 | return -EINVAL; | ||
181 | } | ||
182 | |||
183 | if (uf_info->urfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { | ||
184 | uccf_err | ||
185 | ("ucc_fast_init: Virtual Fifo register urfs not aligned."); | ||
186 | return -EINVAL; | ||
187 | } | ||
188 | |||
189 | if (uf_info->urfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { | ||
190 | uccf_err | ||
191 | ("ucc_fast_init: Virtual Fifo register urfet not aligned."); | ||
192 | return -EINVAL; | ||
193 | } | ||
194 | |||
195 | if (uf_info->urfset & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { | ||
196 | uccf_err | ||
197 | ("ucc_fast_init: Virtual Fifo register urfset not aligned."); | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | |||
201 | if (uf_info->utfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { | ||
202 | uccf_err | ||
203 | ("ucc_fast_init: Virtual Fifo register utfs not aligned."); | ||
204 | return -EINVAL; | ||
205 | } | ||
206 | |||
207 | if (uf_info->utfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { | ||
208 | uccf_err | ||
209 | ("ucc_fast_init: Virtual Fifo register utfet not aligned."); | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | |||
213 | if (uf_info->utftt & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { | ||
214 | uccf_err | ||
215 | ("ucc_fast_init: Virtual Fifo register utftt not aligned."); | ||
216 | return -EINVAL; | ||
217 | } | ||
218 | |||
219 | uccf = (struct ucc_fast_private *) | ||
220 | kmalloc(sizeof(struct ucc_fast_private), GFP_KERNEL); | ||
221 | if (!uccf) { | ||
222 | uccf_err | ||
223 | ("ucc_fast_init: No memory for UCC slow data structure!"); | ||
224 | return -ENOMEM; | ||
225 | } | ||
226 | memset(uccf, 0, sizeof(struct ucc_fast_private)); | ||
227 | |||
228 | /* Fill fast UCC structure */ | ||
229 | uccf->uf_info = uf_info; | ||
230 | /* Set the PHY base address */ | ||
231 | uccf->uf_regs = | ||
232 | (struct ucc_fast *) ioremap(uf_info->regs, sizeof(struct ucc_fast)); | ||
233 | if (uccf->uf_regs == NULL) { | ||
234 | uccf_err | ||
235 | ("ucc_fast_init: No memory map for UCC slow controller!"); | ||
236 | return -ENOMEM; | ||
237 | } | ||
238 | |||
239 | uccf->enabled_tx = 0; | ||
240 | uccf->enabled_rx = 0; | ||
241 | uccf->stopped_tx = 0; | ||
242 | uccf->stopped_rx = 0; | ||
243 | uf_regs = uccf->uf_regs; | ||
244 | uccf->p_ucce = (u32 *) & (uf_regs->ucce); | ||
245 | uccf->p_uccm = (u32 *) & (uf_regs->uccm); | ||
246 | #ifdef STATISTICS | ||
247 | uccf->tx_frames = 0; | ||
248 | uccf->rx_frames = 0; | ||
249 | uccf->rx_discarded = 0; | ||
250 | #endif /* STATISTICS */ | ||
251 | |||
252 | /* Init Guemr register */ | ||
253 | if ((ret = ucc_init_guemr((struct ucc_common *) (uf_regs)))) { | ||
254 | uccf_err("ucc_fast_init: Could not init the guemr register."); | ||
255 | ucc_fast_free(uccf); | ||
256 | return ret; | ||
257 | } | ||
258 | |||
259 | /* Set UCC to fast type */ | ||
260 | if ((ret = ucc_set_type(uf_info->ucc_num, | ||
261 | (struct ucc_common *) (uf_regs), | ||
262 | UCC_SPEED_TYPE_FAST))) { | ||
263 | uccf_err("ucc_fast_init: Could not set type to fast."); | ||
264 | ucc_fast_free(uccf); | ||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | uccf->mrblr = uf_info->max_rx_buf_length; | ||
269 | |||
270 | /* Set GUMR */ | ||
271 | /* For more details see the hardware spec. */ | ||
272 | /* gumr starts as zero. */ | ||
273 | if (uf_info->tci) | ||
274 | gumr |= UCC_FAST_GUMR_TCI; | ||
275 | gumr |= uf_info->ttx_trx; | ||
276 | if (uf_info->cdp) | ||
277 | gumr |= UCC_FAST_GUMR_CDP; | ||
278 | if (uf_info->ctsp) | ||
279 | gumr |= UCC_FAST_GUMR_CTSP; | ||
280 | if (uf_info->cds) | ||
281 | gumr |= UCC_FAST_GUMR_CDS; | ||
282 | if (uf_info->ctss) | ||
283 | gumr |= UCC_FAST_GUMR_CTSS; | ||
284 | if (uf_info->txsy) | ||
285 | gumr |= UCC_FAST_GUMR_TXSY; | ||
286 | if (uf_info->rsyn) | ||
287 | gumr |= UCC_FAST_GUMR_RSYN; | ||
288 | gumr |= uf_info->synl; | ||
289 | if (uf_info->rtsm) | ||
290 | gumr |= UCC_FAST_GUMR_RTSM; | ||
291 | gumr |= uf_info->renc; | ||
292 | if (uf_info->revd) | ||
293 | gumr |= UCC_FAST_GUMR_REVD; | ||
294 | gumr |= uf_info->tenc; | ||
295 | gumr |= uf_info->tcrc; | ||
296 | gumr |= uf_info->mode; | ||
297 | out_be32(&uf_regs->gumr, gumr); | ||
298 | |||
299 | /* Allocate memory for Tx Virtual Fifo */ | ||
300 | uccf->ucc_fast_tx_virtual_fifo_base_offset = | ||
301 | qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT); | ||
302 | if (IS_MURAM_ERR(uccf->ucc_fast_tx_virtual_fifo_base_offset)) { | ||
303 | uccf_err | ||
304 | ("ucc_fast_init: Can not allocate MURAM memory for " | ||
305 | "struct ucc_fastx_virtual_fifo_base_offset."); | ||
306 | uccf->ucc_fast_tx_virtual_fifo_base_offset = 0; | ||
307 | ucc_fast_free(uccf); | ||
308 | return -ENOMEM; | ||
309 | } | ||
310 | |||
311 | /* Allocate memory for Rx Virtual Fifo */ | ||
312 | uccf->ucc_fast_rx_virtual_fifo_base_offset = | ||
313 | qe_muram_alloc(uf_info->urfs + | ||
314 | (u32) | ||
315 | UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR, | ||
316 | UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT); | ||
317 | if (IS_MURAM_ERR(uccf->ucc_fast_rx_virtual_fifo_base_offset)) { | ||
318 | uccf_err | ||
319 | ("ucc_fast_init: Can not allocate MURAM memory for " | ||
320 | "ucc_fast_rx_virtual_fifo_base_offset."); | ||
321 | uccf->ucc_fast_rx_virtual_fifo_base_offset = 0; | ||
322 | ucc_fast_free(uccf); | ||
323 | return -ENOMEM; | ||
324 | } | ||
325 | |||
326 | /* Set Virtual Fifo registers */ | ||
327 | out_be16(&uf_regs->urfs, uf_info->urfs); | ||
328 | out_be16(&uf_regs->urfet, uf_info->urfet); | ||
329 | out_be16(&uf_regs->urfset, uf_info->urfset); | ||
330 | out_be16(&uf_regs->utfs, uf_info->utfs); | ||
331 | out_be16(&uf_regs->utfet, uf_info->utfet); | ||
332 | out_be16(&uf_regs->utftt, uf_info->utftt); | ||
333 | /* utfb, urfb are offsets from MURAM base */ | ||
334 | out_be32(&uf_regs->utfb, uccf->ucc_fast_tx_virtual_fifo_base_offset); | ||
335 | out_be32(&uf_regs->urfb, uccf->ucc_fast_rx_virtual_fifo_base_offset); | ||
336 | |||
337 | /* Mux clocking */ | ||
338 | /* Grant Support */ | ||
339 | ucc_set_qe_mux_grant(uf_info->ucc_num, uf_info->grant_support); | ||
340 | /* Breakpoint Support */ | ||
341 | ucc_set_qe_mux_bkpt(uf_info->ucc_num, uf_info->brkpt_support); | ||
342 | /* Set Tsa or NMSI mode. */ | ||
343 | ucc_set_qe_mux_tsa(uf_info->ucc_num, uf_info->tsa); | ||
344 | /* If NMSI (not Tsa), set Tx and Rx clock. */ | ||
345 | if (!uf_info->tsa) { | ||
346 | /* Rx clock routing */ | ||
347 | if (uf_info->rx_clock != QE_CLK_NONE) { | ||
348 | if (ucc_set_qe_mux_rxtx | ||
349 | (uf_info->ucc_num, uf_info->rx_clock, | ||
350 | COMM_DIR_RX)) { | ||
351 | uccf_err | ||
352 | ("ucc_fast_init: Illegal value for parameter 'RxClock'."); | ||
353 | ucc_fast_free(uccf); | ||
354 | return -EINVAL; | ||
355 | } | ||
356 | } | ||
357 | /* Tx clock routing */ | ||
358 | if (uf_info->tx_clock != QE_CLK_NONE) { | ||
359 | if (ucc_set_qe_mux_rxtx | ||
360 | (uf_info->ucc_num, uf_info->tx_clock, | ||
361 | COMM_DIR_TX)) { | ||
362 | uccf_err | ||
363 | ("ucc_fast_init: Illegal value for parameter 'TxClock'."); | ||
364 | ucc_fast_free(uccf); | ||
365 | return -EINVAL; | ||
366 | } | ||
367 | } | ||
368 | } | ||
369 | |||
370 | /* Set interrupt mask register at UCC level. */ | ||
371 | out_be32(&uf_regs->uccm, uf_info->uccm_mask); | ||
372 | |||
373 | /* First, clear anything pending at UCC level, | ||
374 | * otherwise, old garbage may come through | ||
375 | * as soon as the dam is opened | ||
376 | * Writing '1' clears | ||
377 | */ | ||
378 | out_be32(&uf_regs->ucce, 0xffffffff); | ||
379 | |||
380 | *uccf_ret = uccf; | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | void ucc_fast_free(struct ucc_fast_private * uccf) | ||
385 | { | ||
386 | if (!uccf) | ||
387 | return; | ||
388 | |||
389 | if (uccf->ucc_fast_tx_virtual_fifo_base_offset) | ||
390 | qe_muram_free(uccf->ucc_fast_tx_virtual_fifo_base_offset); | ||
391 | |||
392 | if (uccf->ucc_fast_rx_virtual_fifo_base_offset) | ||
393 | qe_muram_free(uccf->ucc_fast_rx_virtual_fifo_base_offset); | ||
394 | |||
395 | kfree(uccf); | ||
396 | } | ||
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c new file mode 100644 index 000000000000..1fb88ef7cf06 --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c | |||
@@ -0,0 +1,404 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. | ||
3 | * | ||
4 | * Authors: Shlomi Gridish <gridish@freescale.com> | ||
5 | * Li Yang <leoli@freescale.com> | ||
6 | * | ||
7 | * Description: | ||
8 | * QE UCC Slow API Set - UCC Slow specific routines implementations. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/stddef.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | |||
22 | #include <asm/irq.h> | ||
23 | #include <asm/io.h> | ||
24 | #include <asm/immap_qe.h> | ||
25 | #include <asm/qe.h> | ||
26 | |||
27 | #include <asm/ucc.h> | ||
28 | #include <asm/ucc_slow.h> | ||
29 | |||
30 | #define uccs_printk(level, format, arg...) \ | ||
31 | printk(level format "\n", ## arg) | ||
32 | |||
33 | #define uccs_dbg(format, arg...) \ | ||
34 | uccs_printk(KERN_DEBUG , format , ## arg) | ||
35 | #define uccs_err(format, arg...) \ | ||
36 | uccs_printk(KERN_ERR , format , ## arg) | ||
37 | #define uccs_info(format, arg...) \ | ||
38 | uccs_printk(KERN_INFO , format , ## arg) | ||
39 | #define uccs_warn(format, arg...) \ | ||
40 | uccs_printk(KERN_WARNING , format , ## arg) | ||
41 | |||
42 | #ifdef UCCS_VERBOSE_DEBUG | ||
43 | #define uccs_vdbg uccs_dbg | ||
44 | #else | ||
45 | #define uccs_vdbg(fmt, args...) do { } while (0) | ||
46 | #endif /* UCCS_VERBOSE_DEBUG */ | ||
47 | |||
48 | u32 ucc_slow_get_qe_cr_subblock(int uccs_num) | ||
49 | { | ||
50 | switch (uccs_num) { | ||
51 | case 0: return QE_CR_SUBBLOCK_UCCSLOW1; | ||
52 | case 1: return QE_CR_SUBBLOCK_UCCSLOW2; | ||
53 | case 2: return QE_CR_SUBBLOCK_UCCSLOW3; | ||
54 | case 3: return QE_CR_SUBBLOCK_UCCSLOW4; | ||
55 | case 4: return QE_CR_SUBBLOCK_UCCSLOW5; | ||
56 | case 5: return QE_CR_SUBBLOCK_UCCSLOW6; | ||
57 | case 6: return QE_CR_SUBBLOCK_UCCSLOW7; | ||
58 | case 7: return QE_CR_SUBBLOCK_UCCSLOW8; | ||
59 | default: return QE_CR_SUBBLOCK_INVALID; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | void ucc_slow_poll_transmitter_now(struct ucc_slow_private * uccs) | ||
64 | { | ||
65 | out_be16(&uccs->us_regs->utodr, UCC_SLOW_TOD); | ||
66 | } | ||
67 | |||
68 | void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs) | ||
69 | { | ||
70 | struct ucc_slow_info *us_info = uccs->us_info; | ||
71 | u32 id; | ||
72 | |||
73 | id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num); | ||
74 | qe_issue_cmd(QE_GRACEFUL_STOP_TX, id, | ||
75 | QE_CR_PROTOCOL_UNSPECIFIED, 0); | ||
76 | } | ||
77 | |||
78 | void ucc_slow_stop_tx(struct ucc_slow_private * uccs) | ||
79 | { | ||
80 | struct ucc_slow_info *us_info = uccs->us_info; | ||
81 | u32 id; | ||
82 | |||
83 | id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num); | ||
84 | qe_issue_cmd(QE_STOP_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0); | ||
85 | } | ||
86 | |||
87 | void ucc_slow_restart_tx(struct ucc_slow_private * uccs) | ||
88 | { | ||
89 | struct ucc_slow_info *us_info = uccs->us_info; | ||
90 | u32 id; | ||
91 | |||
92 | id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num); | ||
93 | qe_issue_cmd(QE_RESTART_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0); | ||
94 | } | ||
95 | |||
96 | void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode) | ||
97 | { | ||
98 | struct ucc_slow *us_regs; | ||
99 | u32 gumr_l; | ||
100 | |||
101 | us_regs = uccs->us_regs; | ||
102 | |||
103 | /* Enable reception and/or transmission on this UCC. */ | ||
104 | gumr_l = in_be32(&us_regs->gumr_l); | ||
105 | if (mode & COMM_DIR_TX) { | ||
106 | gumr_l |= UCC_SLOW_GUMR_L_ENT; | ||
107 | uccs->enabled_tx = 1; | ||
108 | } | ||
109 | if (mode & COMM_DIR_RX) { | ||
110 | gumr_l |= UCC_SLOW_GUMR_L_ENR; | ||
111 | uccs->enabled_rx = 1; | ||
112 | } | ||
113 | out_be32(&us_regs->gumr_l, gumr_l); | ||
114 | } | ||
115 | |||
116 | void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode) | ||
117 | { | ||
118 | struct ucc_slow *us_regs; | ||
119 | u32 gumr_l; | ||
120 | |||
121 | us_regs = uccs->us_regs; | ||
122 | |||
123 | /* Disable reception and/or transmission on this UCC. */ | ||
124 | gumr_l = in_be32(&us_regs->gumr_l); | ||
125 | if (mode & COMM_DIR_TX) { | ||
126 | gumr_l &= ~UCC_SLOW_GUMR_L_ENT; | ||
127 | uccs->enabled_tx = 0; | ||
128 | } | ||
129 | if (mode & COMM_DIR_RX) { | ||
130 | gumr_l &= ~UCC_SLOW_GUMR_L_ENR; | ||
131 | uccs->enabled_rx = 0; | ||
132 | } | ||
133 | out_be32(&us_regs->gumr_l, gumr_l); | ||
134 | } | ||
135 | |||
136 | int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret) | ||
137 | { | ||
138 | u32 i; | ||
139 | struct ucc_slow *us_regs; | ||
140 | u32 gumr; | ||
141 | u8 function_code = 0; | ||
142 | u8 *bd; | ||
143 | struct ucc_slow_private *uccs; | ||
144 | u32 id; | ||
145 | u32 command; | ||
146 | int ret; | ||
147 | |||
148 | uccs_vdbg("%s: IN", __FUNCTION__); | ||
149 | |||
150 | if (!us_info) | ||
151 | return -EINVAL; | ||
152 | |||
153 | /* check if the UCC port number is in range. */ | ||
154 | if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) { | ||
155 | uccs_err("ucc_slow_init: Illagal UCC number!"); | ||
156 | return -EINVAL; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Set mrblr | ||
161 | * Check that 'max_rx_buf_length' is properly aligned (4), unless | ||
162 | * rfw is 1, meaning that QE accepts one byte at a time, unlike normal | ||
163 | * case when QE accepts 32 bits at a time. | ||
164 | */ | ||
165 | if ((!us_info->rfw) && | ||
166 | (us_info->max_rx_buf_length & (UCC_SLOW_MRBLR_ALIGNMENT - 1))) { | ||
167 | uccs_err("max_rx_buf_length not aligned."); | ||
168 | return -EINVAL; | ||
169 | } | ||
170 | |||
171 | uccs = (struct ucc_slow_private *) | ||
172 | kmalloc(sizeof(struct ucc_slow_private), GFP_KERNEL); | ||
173 | if (!uccs) { | ||
174 | uccs_err | ||
175 | ("ucc_slow_init: No memory for UCC slow data structure!"); | ||
176 | return -ENOMEM; | ||
177 | } | ||
178 | memset(uccs, 0, sizeof(struct ucc_slow_private)); | ||
179 | |||
180 | /* Fill slow UCC structure */ | ||
181 | uccs->us_info = us_info; | ||
182 | uccs->saved_uccm = 0; | ||
183 | uccs->p_rx_frame = 0; | ||
184 | uccs->us_regs = us_info->us_regs; | ||
185 | us_regs = uccs->us_regs; | ||
186 | uccs->p_ucce = (u16 *) & (us_regs->ucce); | ||
187 | uccs->p_uccm = (u16 *) & (us_regs->uccm); | ||
188 | #ifdef STATISTICS | ||
189 | uccs->rx_frames = 0; | ||
190 | uccs->tx_frames = 0; | ||
191 | uccs->rx_discarded = 0; | ||
192 | #endif /* STATISTICS */ | ||
193 | |||
194 | /* Get PRAM base */ | ||
195 | uccs->us_pram_offset = qe_muram_alloc(UCC_SLOW_PRAM_SIZE, | ||
196 | ALIGNMENT_OF_UCC_SLOW_PRAM); | ||
197 | if (IS_MURAM_ERR(uccs->us_pram_offset)) { | ||
198 | uccs_err | ||
199 | ("ucc_slow_init: Can not allocate MURAM memory " | ||
200 | "for Slow UCC."); | ||
201 | ucc_slow_free(uccs); | ||
202 | return -ENOMEM; | ||
203 | } | ||
204 | id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num); | ||
205 | qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, id, QE_CR_PROTOCOL_UNSPECIFIED, | ||
206 | (u32) uccs->us_pram_offset); | ||
207 | |||
208 | uccs->us_pram = qe_muram_addr(uccs->us_pram_offset); | ||
209 | |||
210 | /* Init Guemr register */ | ||
211 | if ((ret = ucc_init_guemr((struct ucc_common *) (us_info->us_regs)))) { | ||
212 | uccs_err("ucc_slow_init: Could not init the guemr register."); | ||
213 | ucc_slow_free(uccs); | ||
214 | return ret; | ||
215 | } | ||
216 | |||
217 | /* Set UCC to slow type */ | ||
218 | if ((ret = ucc_set_type(us_info->ucc_num, | ||
219 | (struct ucc_common *) (us_info->us_regs), | ||
220 | UCC_SPEED_TYPE_SLOW))) { | ||
221 | uccs_err("ucc_slow_init: Could not init the guemr register."); | ||
222 | ucc_slow_free(uccs); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | out_be16(&uccs->us_pram->mrblr, us_info->max_rx_buf_length); | ||
227 | |||
228 | INIT_LIST_HEAD(&uccs->confQ); | ||
229 | |||
230 | /* Allocate BDs. */ | ||
231 | uccs->rx_base_offset = | ||
232 | qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd), | ||
233 | QE_ALIGNMENT_OF_BD); | ||
234 | if (IS_MURAM_ERR(uccs->rx_base_offset)) { | ||
235 | uccs_err("ucc_slow_init: No memory for Rx BD's."); | ||
236 | uccs->rx_base_offset = 0; | ||
237 | ucc_slow_free(uccs); | ||
238 | return -ENOMEM; | ||
239 | } | ||
240 | |||
241 | uccs->tx_base_offset = | ||
242 | qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd), | ||
243 | QE_ALIGNMENT_OF_BD); | ||
244 | if (IS_MURAM_ERR(uccs->tx_base_offset)) { | ||
245 | uccs_err("ucc_slow_init: No memory for Tx BD's."); | ||
246 | uccs->tx_base_offset = 0; | ||
247 | ucc_slow_free(uccs); | ||
248 | return -ENOMEM; | ||
249 | } | ||
250 | |||
251 | /* Init Tx bds */ | ||
252 | bd = uccs->confBd = uccs->tx_bd = qe_muram_addr(uccs->tx_base_offset); | ||
253 | for (i = 0; i < us_info->tx_bd_ring_len; i++) { | ||
254 | /* clear bd buffer */ | ||
255 | out_be32(&(((struct qe_bd *)bd)->buf), 0); | ||
256 | /* set bd status and length */ | ||
257 | out_be32((u32*)bd, 0); | ||
258 | bd += sizeof(struct qe_bd); | ||
259 | } | ||
260 | bd -= sizeof(struct qe_bd); | ||
261 | /* set bd status and length */ | ||
262 | out_be32((u32*)bd, T_W); /* for last BD set Wrap bit */ | ||
263 | |||
264 | /* Init Rx bds */ | ||
265 | bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset); | ||
266 | for (i = 0; i < us_info->rx_bd_ring_len; i++) { | ||
267 | /* set bd status and length */ | ||
268 | out_be32((u32*)bd, 0); | ||
269 | /* clear bd buffer */ | ||
270 | out_be32(&(((struct qe_bd *)bd)->buf), 0); | ||
271 | bd += sizeof(struct qe_bd); | ||
272 | } | ||
273 | bd -= sizeof(struct qe_bd); | ||
274 | /* set bd status and length */ | ||
275 | out_be32((u32*)bd, R_W); /* for last BD set Wrap bit */ | ||
276 | |||
277 | /* Set GUMR (For more details see the hardware spec.). */ | ||
278 | /* gumr_h */ | ||
279 | gumr = 0; | ||
280 | gumr |= us_info->tcrc; | ||
281 | if (us_info->cdp) | ||
282 | gumr |= UCC_SLOW_GUMR_H_CDP; | ||
283 | if (us_info->ctsp) | ||
284 | gumr |= UCC_SLOW_GUMR_H_CTSP; | ||
285 | if (us_info->cds) | ||
286 | gumr |= UCC_SLOW_GUMR_H_CDS; | ||
287 | if (us_info->ctss) | ||
288 | gumr |= UCC_SLOW_GUMR_H_CTSS; | ||
289 | if (us_info->tfl) | ||
290 | gumr |= UCC_SLOW_GUMR_H_TFL; | ||
291 | if (us_info->rfw) | ||
292 | gumr |= UCC_SLOW_GUMR_H_RFW; | ||
293 | if (us_info->txsy) | ||
294 | gumr |= UCC_SLOW_GUMR_H_TXSY; | ||
295 | if (us_info->rtsm) | ||
296 | gumr |= UCC_SLOW_GUMR_H_RTSM; | ||
297 | out_be32(&us_regs->gumr_h, gumr); | ||
298 | |||
299 | /* gumr_l */ | ||
300 | gumr = 0; | ||
301 | if (us_info->tci) | ||
302 | gumr |= UCC_SLOW_GUMR_L_TCI; | ||
303 | if (us_info->rinv) | ||
304 | gumr |= UCC_SLOW_GUMR_L_RINV; | ||
305 | if (us_info->tinv) | ||
306 | gumr |= UCC_SLOW_GUMR_L_TINV; | ||
307 | if (us_info->tend) | ||
308 | gumr |= UCC_SLOW_GUMR_L_TEND; | ||
309 | gumr |= us_info->tdcr; | ||
310 | gumr |= us_info->rdcr; | ||
311 | gumr |= us_info->tenc; | ||
312 | gumr |= us_info->renc; | ||
313 | gumr |= us_info->diag; | ||
314 | gumr |= us_info->mode; | ||
315 | out_be32(&us_regs->gumr_l, gumr); | ||
316 | |||
317 | /* Function code registers */ | ||
318 | /* function_code has initial value 0 */ | ||
319 | |||
320 | /* if the data is in cachable memory, the 'global' */ | ||
321 | /* in the function code should be set. */ | ||
322 | function_code |= us_info->data_mem_part; | ||
323 | function_code |= QE_BMR_BYTE_ORDER_BO_MOT; /* Required for QE */ | ||
324 | uccs->us_pram->tfcr = function_code; | ||
325 | uccs->us_pram->rfcr = function_code; | ||
326 | |||
327 | /* rbase, tbase are offsets from MURAM base */ | ||
328 | out_be16(&uccs->us_pram->rbase, uccs->us_pram_offset); | ||
329 | out_be16(&uccs->us_pram->tbase, uccs->us_pram_offset); | ||
330 | |||
331 | /* Mux clocking */ | ||
332 | /* Grant Support */ | ||
333 | ucc_set_qe_mux_grant(us_info->ucc_num, us_info->grant_support); | ||
334 | /* Breakpoint Support */ | ||
335 | ucc_set_qe_mux_bkpt(us_info->ucc_num, us_info->brkpt_support); | ||
336 | /* Set Tsa or NMSI mode. */ | ||
337 | ucc_set_qe_mux_tsa(us_info->ucc_num, us_info->tsa); | ||
338 | /* If NMSI (not Tsa), set Tx and Rx clock. */ | ||
339 | if (!us_info->tsa) { | ||
340 | /* Rx clock routing */ | ||
341 | if (ucc_set_qe_mux_rxtx | ||
342 | (us_info->ucc_num, us_info->rx_clock, COMM_DIR_RX)) { | ||
343 | uccs_err | ||
344 | ("ucc_slow_init: Illegal value for parameter" | ||
345 | " 'RxClock'."); | ||
346 | ucc_slow_free(uccs); | ||
347 | return -EINVAL; | ||
348 | } | ||
349 | /* Tx clock routing */ | ||
350 | if (ucc_set_qe_mux_rxtx(us_info->ucc_num, | ||
351 | us_info->tx_clock, COMM_DIR_TX)) { | ||
352 | uccs_err | ||
353 | ("ucc_slow_init: Illegal value for parameter " | ||
354 | "'TxClock'."); | ||
355 | ucc_slow_free(uccs); | ||
356 | return -EINVAL; | ||
357 | } | ||
358 | } | ||
359 | |||
360 | /* | ||
361 | * INTERRUPTS | ||
362 | */ | ||
363 | /* Set interrupt mask register at UCC level. */ | ||
364 | out_be16(&us_regs->uccm, us_info->uccm_mask); | ||
365 | |||
366 | /* First, clear anything pending at UCC level, */ | ||
367 | /* otherwise, old garbage may come through */ | ||
368 | /* as soon as the dam is opened. */ | ||
369 | |||
370 | /* Writing '1' clears */ | ||
371 | out_be16(&us_regs->ucce, 0xffff); | ||
372 | |||
373 | /* Issue QE Init command */ | ||
374 | if (us_info->init_tx && us_info->init_rx) | ||
375 | command = QE_INIT_TX_RX; | ||
376 | else if (us_info->init_tx) | ||
377 | command = QE_INIT_TX; | ||
378 | else | ||
379 | command = QE_INIT_RX; /* We know at least one is TRUE */ | ||
380 | id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num); | ||
381 | qe_issue_cmd(command, id, QE_CR_PROTOCOL_UNSPECIFIED, 0); | ||
382 | |||
383 | *uccs_ret = uccs; | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | void ucc_slow_free(struct ucc_slow_private * uccs) | ||
388 | { | ||
389 | if (!uccs) | ||
390 | return; | ||
391 | |||
392 | if (uccs->rx_base_offset) | ||
393 | qe_muram_free(uccs->rx_base_offset); | ||
394 | |||
395 | if (uccs->tx_base_offset) | ||
396 | qe_muram_free(uccs->tx_base_offset); | ||
397 | |||
398 | if (uccs->us_pram) { | ||
399 | qe_muram_free(uccs->us_pram_offset); | ||
400 | uccs->us_pram = NULL; | ||
401 | } | ||
402 | |||
403 | kfree(uccs); | ||
404 | } | ||
diff --git a/include/asm-powerpc/immap_qe.h b/include/asm-powerpc/immap_qe.h new file mode 100644 index 000000000000..ce12f85fff9b --- /dev/null +++ b/include/asm-powerpc/immap_qe.h | |||
@@ -0,0 +1,477 @@ | |||
1 | /* | ||
2 | * include/asm-powerpc/immap_qe.h | ||
3 | * | ||
4 | * QUICC Engine (QE) Internal Memory Map. | ||
5 | * The Internal Memory Map for devices with QE on them. This | ||
6 | * is the superset of all QE devices (8360, etc.). | ||
7 | |||
8 | * Copyright (C) 2006. Freescale Semicondutor, Inc. All rights reserved. | ||
9 | * | ||
10 | * Authors: Shlomi Gridish <gridish@freescale.com> | ||
11 | * Li Yang <leoli@freescale.com> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms of the GNU General Public License as published by the | ||
15 | * Free Software Foundation; either version 2 of the License, or (at your | ||
16 | * option) any later version. | ||
17 | */ | ||
18 | #ifndef _ASM_POWERPC_IMMAP_QE_H | ||
19 | #define _ASM_POWERPC_IMMAP_QE_H | ||
20 | #ifdef __KERNEL__ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | |||
24 | #define QE_IMMAP_SIZE (1024 * 1024) /* 1MB from 1MB+IMMR */ | ||
25 | |||
26 | /* QE I-RAM */ | ||
27 | struct qe_iram { | ||
28 | __be32 iadd; /* I-RAM Address Register */ | ||
29 | __be32 idata; /* I-RAM Data Register */ | ||
30 | u8 res0[0x78]; | ||
31 | } __attribute__ ((packed)); | ||
32 | |||
33 | /* QE Interrupt Controller */ | ||
34 | struct qe_ic_regs { | ||
35 | __be32 qicr; | ||
36 | __be32 qivec; | ||
37 | __be32 qripnr; | ||
38 | __be32 qipnr; | ||
39 | __be32 qipxcc; | ||
40 | __be32 qipycc; | ||
41 | __be32 qipwcc; | ||
42 | __be32 qipzcc; | ||
43 | __be32 qimr; | ||
44 | __be32 qrimr; | ||
45 | __be32 qicnr; | ||
46 | u8 res0[0x4]; | ||
47 | __be32 qiprta; | ||
48 | __be32 qiprtb; | ||
49 | u8 res1[0x4]; | ||
50 | __be32 qricr; | ||
51 | u8 res2[0x20]; | ||
52 | __be32 qhivec; | ||
53 | u8 res3[0x1C]; | ||
54 | } __attribute__ ((packed)); | ||
55 | |||
56 | /* Communications Processor */ | ||
57 | struct cp_qe { | ||
58 | __be32 cecr; /* QE command register */ | ||
59 | __be32 ceccr; /* QE controller configuration register */ | ||
60 | __be32 cecdr; /* QE command data register */ | ||
61 | u8 res0[0xA]; | ||
62 | __be16 ceter; /* QE timer event register */ | ||
63 | u8 res1[0x2]; | ||
64 | __be16 cetmr; /* QE timers mask register */ | ||
65 | __be32 cetscr; /* QE time-stamp timer control register */ | ||
66 | __be32 cetsr1; /* QE time-stamp register 1 */ | ||
67 | __be32 cetsr2; /* QE time-stamp register 2 */ | ||
68 | u8 res2[0x8]; | ||
69 | __be32 cevter; /* QE virtual tasks event register */ | ||
70 | __be32 cevtmr; /* QE virtual tasks mask register */ | ||
71 | __be16 cercr; /* QE RAM control register */ | ||
72 | u8 res3[0x2]; | ||
73 | u8 res4[0x24]; | ||
74 | __be16 ceexe1; /* QE external request 1 event register */ | ||
75 | u8 res5[0x2]; | ||
76 | __be16 ceexm1; /* QE external request 1 mask register */ | ||
77 | u8 res6[0x2]; | ||
78 | __be16 ceexe2; /* QE external request 2 event register */ | ||
79 | u8 res7[0x2]; | ||
80 | __be16 ceexm2; /* QE external request 2 mask register */ | ||
81 | u8 res8[0x2]; | ||
82 | __be16 ceexe3; /* QE external request 3 event register */ | ||
83 | u8 res9[0x2]; | ||
84 | __be16 ceexm3; /* QE external request 3 mask register */ | ||
85 | u8 res10[0x2]; | ||
86 | __be16 ceexe4; /* QE external request 4 event register */ | ||
87 | u8 res11[0x2]; | ||
88 | __be16 ceexm4; /* QE external request 4 mask register */ | ||
89 | u8 res12[0x2]; | ||
90 | u8 res13[0x280]; | ||
91 | } __attribute__ ((packed)); | ||
92 | |||
93 | /* QE Multiplexer */ | ||
94 | struct qe_mux { | ||
95 | __be32 cmxgcr; /* CMX general clock route register */ | ||
96 | __be32 cmxsi1cr_l; /* CMX SI1 clock route low register */ | ||
97 | __be32 cmxsi1cr_h; /* CMX SI1 clock route high register */ | ||
98 | __be32 cmxsi1syr; /* CMX SI1 SYNC route register */ | ||
99 | __be32 cmxucr1; /* CMX UCC1, UCC3 clock route register */ | ||
100 | __be32 cmxucr2; /* CMX UCC5, UCC7 clock route register */ | ||
101 | __be32 cmxucr3; /* CMX UCC2, UCC4 clock route register */ | ||
102 | __be32 cmxucr4; /* CMX UCC6, UCC8 clock route register */ | ||
103 | __be32 cmxupcr; /* CMX UPC clock route register */ | ||
104 | u8 res0[0x1C]; | ||
105 | } __attribute__ ((packed)); | ||
106 | |||
107 | /* QE Timers */ | ||
108 | struct qe_timers { | ||
109 | u8 gtcfr1; /* Timer 1 and Timer 2 global config register*/ | ||
110 | u8 res0[0x3]; | ||
111 | u8 gtcfr2; /* Timer 3 and timer 4 global config register*/ | ||
112 | u8 res1[0xB]; | ||
113 | __be16 gtmdr1; /* Timer 1 mode register */ | ||
114 | __be16 gtmdr2; /* Timer 2 mode register */ | ||
115 | __be16 gtrfr1; /* Timer 1 reference register */ | ||
116 | __be16 gtrfr2; /* Timer 2 reference register */ | ||
117 | __be16 gtcpr1; /* Timer 1 capture register */ | ||
118 | __be16 gtcpr2; /* Timer 2 capture register */ | ||
119 | __be16 gtcnr1; /* Timer 1 counter */ | ||
120 | __be16 gtcnr2; /* Timer 2 counter */ | ||
121 | __be16 gtmdr3; /* Timer 3 mode register */ | ||
122 | __be16 gtmdr4; /* Timer 4 mode register */ | ||
123 | __be16 gtrfr3; /* Timer 3 reference register */ | ||
124 | __be16 gtrfr4; /* Timer 4 reference register */ | ||
125 | __be16 gtcpr3; /* Timer 3 capture register */ | ||
126 | __be16 gtcpr4; /* Timer 4 capture register */ | ||
127 | __be16 gtcnr3; /* Timer 3 counter */ | ||
128 | __be16 gtcnr4; /* Timer 4 counter */ | ||
129 | __be16 gtevr1; /* Timer 1 event register */ | ||
130 | __be16 gtevr2; /* Timer 2 event register */ | ||
131 | __be16 gtevr3; /* Timer 3 event register */ | ||
132 | __be16 gtevr4; /* Timer 4 event register */ | ||
133 | __be16 gtps; /* Timer 1 prescale register */ | ||
134 | u8 res2[0x46]; | ||
135 | } __attribute__ ((packed)); | ||
136 | |||
137 | /* BRG */ | ||
138 | struct qe_brg { | ||
139 | __be32 brgc1; /* BRG1 configuration register */ | ||
140 | __be32 brgc2; /* BRG2 configuration register */ | ||
141 | __be32 brgc3; /* BRG3 configuration register */ | ||
142 | __be32 brgc4; /* BRG4 configuration register */ | ||
143 | __be32 brgc5; /* BRG5 configuration register */ | ||
144 | __be32 brgc6; /* BRG6 configuration register */ | ||
145 | __be32 brgc7; /* BRG7 configuration register */ | ||
146 | __be32 brgc8; /* BRG8 configuration register */ | ||
147 | __be32 brgc9; /* BRG9 configuration register */ | ||
148 | __be32 brgc10; /* BRG10 configuration register */ | ||
149 | __be32 brgc11; /* BRG11 configuration register */ | ||
150 | __be32 brgc12; /* BRG12 configuration register */ | ||
151 | __be32 brgc13; /* BRG13 configuration register */ | ||
152 | __be32 brgc14; /* BRG14 configuration register */ | ||
153 | __be32 brgc15; /* BRG15 configuration register */ | ||
154 | __be32 brgc16; /* BRG16 configuration register */ | ||
155 | u8 res0[0x40]; | ||
156 | } __attribute__ ((packed)); | ||
157 | |||
158 | /* SPI */ | ||
159 | struct spi { | ||
160 | u8 res0[0x20]; | ||
161 | __be32 spmode; /* SPI mode register */ | ||
162 | u8 res1[0x2]; | ||
163 | u8 spie; /* SPI event register */ | ||
164 | u8 res2[0x1]; | ||
165 | u8 res3[0x2]; | ||
166 | u8 spim; /* SPI mask register */ | ||
167 | u8 res4[0x1]; | ||
168 | u8 res5[0x1]; | ||
169 | u8 spcom; /* SPI command register */ | ||
170 | u8 res6[0x2]; | ||
171 | __be32 spitd; /* SPI transmit data register (cpu mode) */ | ||
172 | __be32 spird; /* SPI receive data register (cpu mode) */ | ||
173 | u8 res7[0x8]; | ||
174 | } __attribute__ ((packed)); | ||
175 | |||
176 | /* SI */ | ||
177 | struct si1 { | ||
178 | __be16 siamr1; /* SI1 TDMA mode register */ | ||
179 | __be16 sibmr1; /* SI1 TDMB mode register */ | ||
180 | __be16 sicmr1; /* SI1 TDMC mode register */ | ||
181 | __be16 sidmr1; /* SI1 TDMD mode register */ | ||
182 | u8 siglmr1_h; /* SI1 global mode register high */ | ||
183 | u8 res0[0x1]; | ||
184 | u8 sicmdr1_h; /* SI1 command register high */ | ||
185 | u8 res2[0x1]; | ||
186 | u8 sistr1_h; /* SI1 status register high */ | ||
187 | u8 res3[0x1]; | ||
188 | __be16 sirsr1_h; /* SI1 RAM shadow address register high */ | ||
189 | u8 sitarc1; /* SI1 RAM counter Tx TDMA */ | ||
190 | u8 sitbrc1; /* SI1 RAM counter Tx TDMB */ | ||
191 | u8 sitcrc1; /* SI1 RAM counter Tx TDMC */ | ||
192 | u8 sitdrc1; /* SI1 RAM counter Tx TDMD */ | ||
193 | u8 sirarc1; /* SI1 RAM counter Rx TDMA */ | ||
194 | u8 sirbrc1; /* SI1 RAM counter Rx TDMB */ | ||
195 | u8 sircrc1; /* SI1 RAM counter Rx TDMC */ | ||
196 | u8 sirdrc1; /* SI1 RAM counter Rx TDMD */ | ||
197 | u8 res4[0x8]; | ||
198 | __be16 siemr1; /* SI1 TDME mode register 16 bits */ | ||
199 | __be16 sifmr1; /* SI1 TDMF mode register 16 bits */ | ||
200 | __be16 sigmr1; /* SI1 TDMG mode register 16 bits */ | ||
201 | __be16 sihmr1; /* SI1 TDMH mode register 16 bits */ | ||
202 | u8 siglmg1_l; /* SI1 global mode register low 8 bits */ | ||
203 | u8 res5[0x1]; | ||
204 | u8 sicmdr1_l; /* SI1 command register low 8 bits */ | ||
205 | u8 res6[0x1]; | ||
206 | u8 sistr1_l; /* SI1 status register low 8 bits */ | ||
207 | u8 res7[0x1]; | ||
208 | __be16 sirsr1_l; /* SI1 RAM shadow address register low 16 bits*/ | ||
209 | u8 siterc1; /* SI1 RAM counter Tx TDME 8 bits */ | ||
210 | u8 sitfrc1; /* SI1 RAM counter Tx TDMF 8 bits */ | ||
211 | u8 sitgrc1; /* SI1 RAM counter Tx TDMG 8 bits */ | ||
212 | u8 sithrc1; /* SI1 RAM counter Tx TDMH 8 bits */ | ||
213 | u8 sirerc1; /* SI1 RAM counter Rx TDME 8 bits */ | ||
214 | u8 sirfrc1; /* SI1 RAM counter Rx TDMF 8 bits */ | ||
215 | u8 sirgrc1; /* SI1 RAM counter Rx TDMG 8 bits */ | ||
216 | u8 sirhrc1; /* SI1 RAM counter Rx TDMH 8 bits */ | ||
217 | u8 res8[0x8]; | ||
218 | __be32 siml1; /* SI1 multiframe limit register */ | ||
219 | u8 siedm1; /* SI1 extended diagnostic mode register */ | ||
220 | u8 res9[0xBB]; | ||
221 | } __attribute__ ((packed)); | ||
222 | |||
223 | /* SI Routing Tables */ | ||
224 | struct sir { | ||
225 | u8 tx[0x400]; | ||
226 | u8 rx[0x400]; | ||
227 | u8 res0[0x800]; | ||
228 | } __attribute__ ((packed)); | ||
229 | |||
230 | /* USB Controller */ | ||
231 | struct usb_ctlr { | ||
232 | u8 usb_usmod; | ||
233 | u8 usb_usadr; | ||
234 | u8 usb_uscom; | ||
235 | u8 res1[1]; | ||
236 | __be16 usb_usep1; | ||
237 | __be16 usb_usep2; | ||
238 | __be16 usb_usep3; | ||
239 | __be16 usb_usep4; | ||
240 | u8 res2[4]; | ||
241 | __be16 usb_usber; | ||
242 | u8 res3[2]; | ||
243 | __be16 usb_usbmr; | ||
244 | u8 res4[1]; | ||
245 | u8 usb_usbs; | ||
246 | __be16 usb_ussft; | ||
247 | u8 res5[2]; | ||
248 | __be16 usb_usfrn; | ||
249 | u8 res6[0x22]; | ||
250 | } __attribute__ ((packed)); | ||
251 | |||
252 | /* MCC */ | ||
253 | struct mcc { | ||
254 | __be32 mcce; /* MCC event register */ | ||
255 | __be32 mccm; /* MCC mask register */ | ||
256 | __be32 mccf; /* MCC configuration register */ | ||
257 | __be32 merl; /* MCC emergency request level register */ | ||
258 | u8 res0[0xF0]; | ||
259 | } __attribute__ ((packed)); | ||
260 | |||
261 | /* QE UCC Slow */ | ||
262 | struct ucc_slow { | ||
263 | __be32 gumr_l; /* UCCx general mode register (low) */ | ||
264 | __be32 gumr_h; /* UCCx general mode register (high) */ | ||
265 | __be16 upsmr; /* UCCx protocol-specific mode register */ | ||
266 | u8 res0[0x2]; | ||
267 | __be16 utodr; /* UCCx transmit on demand register */ | ||
268 | __be16 udsr; /* UCCx data synchronization register */ | ||
269 | __be16 ucce; /* UCCx event register */ | ||
270 | u8 res1[0x2]; | ||
271 | __be16 uccm; /* UCCx mask register */ | ||
272 | u8 res2[0x1]; | ||
273 | u8 uccs; /* UCCx status register */ | ||
274 | u8 res3[0x24]; | ||
275 | __be16 utpt; | ||
276 | u8 guemr; /* UCC general extended mode register */ | ||
277 | u8 res4[0x200 - 0x091]; | ||
278 | } __attribute__ ((packed)); | ||
279 | |||
280 | /* QE UCC Fast */ | ||
281 | struct ucc_fast { | ||
282 | __be32 gumr; /* UCCx general mode register */ | ||
283 | __be32 upsmr; /* UCCx protocol-specific mode register */ | ||
284 | __be16 utodr; /* UCCx transmit on demand register */ | ||
285 | u8 res0[0x2]; | ||
286 | __be16 udsr; /* UCCx data synchronization register */ | ||
287 | u8 res1[0x2]; | ||
288 | __be32 ucce; /* UCCx event register */ | ||
289 | __be32 uccm; /* UCCx mask register */ | ||
290 | u8 uccs; /* UCCx status register */ | ||
291 | u8 res2[0x7]; | ||
292 | __be32 urfb; /* UCC receive FIFO base */ | ||
293 | __be16 urfs; /* UCC receive FIFO size */ | ||
294 | u8 res3[0x2]; | ||
295 | __be16 urfet; /* UCC receive FIFO emergency threshold */ | ||
296 | __be16 urfset; /* UCC receive FIFO special emergency | ||
297 | threshold */ | ||
298 | __be32 utfb; /* UCC transmit FIFO base */ | ||
299 | __be16 utfs; /* UCC transmit FIFO size */ | ||
300 | u8 res4[0x2]; | ||
301 | __be16 utfet; /* UCC transmit FIFO emergency threshold */ | ||
302 | u8 res5[0x2]; | ||
303 | __be16 utftt; /* UCC transmit FIFO transmit threshold */ | ||
304 | u8 res6[0x2]; | ||
305 | __be16 utpt; /* UCC transmit polling timer */ | ||
306 | u8 res7[0x2]; | ||
307 | __be32 urtry; /* UCC retry counter register */ | ||
308 | u8 res8[0x4C]; | ||
309 | u8 guemr; /* UCC general extended mode register */ | ||
310 | u8 res9[0x100 - 0x091]; | ||
311 | } __attribute__ ((packed)); | ||
312 | |||
313 | /* QE UCC */ | ||
314 | struct ucc_common { | ||
315 | u8 res1[0x90]; | ||
316 | u8 guemr; | ||
317 | u8 res2[0x200 - 0x091]; | ||
318 | } __attribute__ ((packed)); | ||
319 | |||
320 | struct ucc { | ||
321 | union { | ||
322 | struct ucc_slow slow; | ||
323 | struct ucc_fast fast; | ||
324 | struct ucc_common common; | ||
325 | }; | ||
326 | } __attribute__ ((packed)); | ||
327 | |||
328 | /* MultiPHY UTOPIA POS Controllers (UPC) */ | ||
329 | struct upc { | ||
330 | __be32 upgcr; /* UTOPIA/POS general configuration register */ | ||
331 | __be32 uplpa; /* UTOPIA/POS last PHY address */ | ||
332 | __be32 uphec; /* ATM HEC register */ | ||
333 | __be32 upuc; /* UTOPIA/POS UCC configuration */ | ||
334 | __be32 updc1; /* UTOPIA/POS device 1 configuration */ | ||
335 | __be32 updc2; /* UTOPIA/POS device 2 configuration */ | ||
336 | __be32 updc3; /* UTOPIA/POS device 3 configuration */ | ||
337 | __be32 updc4; /* UTOPIA/POS device 4 configuration */ | ||
338 | __be32 upstpa; /* UTOPIA/POS STPA threshold */ | ||
339 | u8 res0[0xC]; | ||
340 | __be32 updrs1_h; /* UTOPIA/POS device 1 rate select */ | ||
341 | __be32 updrs1_l; /* UTOPIA/POS device 1 rate select */ | ||
342 | __be32 updrs2_h; /* UTOPIA/POS device 2 rate select */ | ||
343 | __be32 updrs2_l; /* UTOPIA/POS device 2 rate select */ | ||
344 | __be32 updrs3_h; /* UTOPIA/POS device 3 rate select */ | ||
345 | __be32 updrs3_l; /* UTOPIA/POS device 3 rate select */ | ||
346 | __be32 updrs4_h; /* UTOPIA/POS device 4 rate select */ | ||
347 | __be32 updrs4_l; /* UTOPIA/POS device 4 rate select */ | ||
348 | __be32 updrp1; /* UTOPIA/POS device 1 receive priority low */ | ||
349 | __be32 updrp2; /* UTOPIA/POS device 2 receive priority low */ | ||
350 | __be32 updrp3; /* UTOPIA/POS device 3 receive priority low */ | ||
351 | __be32 updrp4; /* UTOPIA/POS device 4 receive priority low */ | ||
352 | __be32 upde1; /* UTOPIA/POS device 1 event */ | ||
353 | __be32 upde2; /* UTOPIA/POS device 2 event */ | ||
354 | __be32 upde3; /* UTOPIA/POS device 3 event */ | ||
355 | __be32 upde4; /* UTOPIA/POS device 4 event */ | ||
356 | __be16 uprp1; | ||
357 | __be16 uprp2; | ||
358 | __be16 uprp3; | ||
359 | __be16 uprp4; | ||
360 | u8 res1[0x8]; | ||
361 | __be16 uptirr1_0; /* Device 1 transmit internal rate 0 */ | ||
362 | __be16 uptirr1_1; /* Device 1 transmit internal rate 1 */ | ||
363 | __be16 uptirr1_2; /* Device 1 transmit internal rate 2 */ | ||
364 | __be16 uptirr1_3; /* Device 1 transmit internal rate 3 */ | ||
365 | __be16 uptirr2_0; /* Device 2 transmit internal rate 0 */ | ||
366 | __be16 uptirr2_1; /* Device 2 transmit internal rate 1 */ | ||
367 | __be16 uptirr2_2; /* Device 2 transmit internal rate 2 */ | ||
368 | __be16 uptirr2_3; /* Device 2 transmit internal rate 3 */ | ||
369 | __be16 uptirr3_0; /* Device 3 transmit internal rate 0 */ | ||
370 | __be16 uptirr3_1; /* Device 3 transmit internal rate 1 */ | ||
371 | __be16 uptirr3_2; /* Device 3 transmit internal rate 2 */ | ||
372 | __be16 uptirr3_3; /* Device 3 transmit internal rate 3 */ | ||
373 | __be16 uptirr4_0; /* Device 4 transmit internal rate 0 */ | ||
374 | __be16 uptirr4_1; /* Device 4 transmit internal rate 1 */ | ||
375 | __be16 uptirr4_2; /* Device 4 transmit internal rate 2 */ | ||
376 | __be16 uptirr4_3; /* Device 4 transmit internal rate 3 */ | ||
377 | __be32 uper1; /* Device 1 port enable register */ | ||
378 | __be32 uper2; /* Device 2 port enable register */ | ||
379 | __be32 uper3; /* Device 3 port enable register */ | ||
380 | __be32 uper4; /* Device 4 port enable register */ | ||
381 | u8 res2[0x150]; | ||
382 | } __attribute__ ((packed)); | ||
383 | |||
384 | /* SDMA */ | ||
385 | struct sdma { | ||
386 | __be32 sdsr; /* Serial DMA status register */ | ||
387 | __be32 sdmr; /* Serial DMA mode register */ | ||
388 | __be32 sdtr1; /* SDMA system bus threshold register */ | ||
389 | __be32 sdtr2; /* SDMA secondary bus threshold register */ | ||
390 | __be32 sdhy1; /* SDMA system bus hysteresis register */ | ||
391 | __be32 sdhy2; /* SDMA secondary bus hysteresis register */ | ||
392 | __be32 sdta1; /* SDMA system bus address register */ | ||
393 | __be32 sdta2; /* SDMA secondary bus address register */ | ||
394 | __be32 sdtm1; /* SDMA system bus MSNUM register */ | ||
395 | __be32 sdtm2; /* SDMA secondary bus MSNUM register */ | ||
396 | u8 res0[0x10]; | ||
397 | __be32 sdaqr; /* SDMA address bus qualify register */ | ||
398 | __be32 sdaqmr; /* SDMA address bus qualify mask register */ | ||
399 | u8 res1[0x4]; | ||
400 | __be32 sdebcr; /* SDMA CAM entries base register */ | ||
401 | u8 res2[0x38]; | ||
402 | } __attribute__ ((packed)); | ||
403 | |||
404 | /* Debug Space */ | ||
405 | struct dbg { | ||
406 | __be32 bpdcr; /* Breakpoint debug command register */ | ||
407 | __be32 bpdsr; /* Breakpoint debug status register */ | ||
408 | __be32 bpdmr; /* Breakpoint debug mask register */ | ||
409 | __be32 bprmrr0; /* Breakpoint request mode risc register 0 */ | ||
410 | __be32 bprmrr1; /* Breakpoint request mode risc register 1 */ | ||
411 | u8 res0[0x8]; | ||
412 | __be32 bprmtr0; /* Breakpoint request mode trb register 0 */ | ||
413 | __be32 bprmtr1; /* Breakpoint request mode trb register 1 */ | ||
414 | u8 res1[0x8]; | ||
415 | __be32 bprmir; /* Breakpoint request mode immediate register */ | ||
416 | __be32 bprmsr; /* Breakpoint request mode serial register */ | ||
417 | __be32 bpemr; /* Breakpoint exit mode register */ | ||
418 | u8 res2[0x48]; | ||
419 | } __attribute__ ((packed)); | ||
420 | |||
421 | /* RISC Special Registers (Trap and Breakpoint) */ | ||
422 | struct rsp { | ||
423 | u8 fixme[0x100]; | ||
424 | } __attribute__ ((packed)); | ||
425 | |||
426 | struct qe_immap { | ||
427 | struct qe_iram iram; /* I-RAM */ | ||
428 | struct qe_ic_regs ic; /* Interrupt Controller */ | ||
429 | struct cp_qe cp; /* Communications Processor */ | ||
430 | struct qe_mux qmx; /* QE Multiplexer */ | ||
431 | struct qe_timers qet; /* QE Timers */ | ||
432 | struct spi spi[0x2]; /* spi */ | ||
433 | struct mcc mcc; /* mcc */ | ||
434 | struct qe_brg brg; /* brg */ | ||
435 | struct usb_ctlr usb; /* USB */ | ||
436 | struct si1 si1; /* SI */ | ||
437 | u8 res11[0x800]; | ||
438 | struct sir sir; /* SI Routing Tables */ | ||
439 | struct ucc ucc1; /* ucc1 */ | ||
440 | struct ucc ucc3; /* ucc3 */ | ||
441 | struct ucc ucc5; /* ucc5 */ | ||
442 | struct ucc ucc7; /* ucc7 */ | ||
443 | u8 res12[0x600]; | ||
444 | struct upc upc1; /* MultiPHY UTOPIA POS Ctrlr 1*/ | ||
445 | struct ucc ucc2; /* ucc2 */ | ||
446 | struct ucc ucc4; /* ucc4 */ | ||
447 | struct ucc ucc6; /* ucc6 */ | ||
448 | struct ucc ucc8; /* ucc8 */ | ||
449 | u8 res13[0x600]; | ||
450 | struct upc upc2; /* MultiPHY UTOPIA POS Ctrlr 2*/ | ||
451 | struct sdma sdma; /* SDMA */ | ||
452 | struct dbg dbg; /* Debug Space */ | ||
453 | struct rsp rsp[0x2]; /* RISC Special Registers | ||
454 | (Trap and Breakpoint) */ | ||
455 | u8 res14[0x300]; | ||
456 | u8 res15[0x3A00]; | ||
457 | u8 res16[0x8000]; /* 0x108000 - 0x110000 */ | ||
458 | u8 muram[0xC000]; /* 0x110000 - 0x11C000 | ||
459 | Multi-user RAM */ | ||
460 | u8 res17[0x24000]; /* 0x11C000 - 0x140000 */ | ||
461 | u8 res18[0xC0000]; /* 0x140000 - 0x200000 */ | ||
462 | } __attribute__ ((packed)); | ||
463 | |||
464 | extern struct qe_immap *qe_immr; | ||
465 | extern phys_addr_t get_qe_base(void); | ||
466 | |||
467 | static inline unsigned long immrbar_virt_to_phys(volatile void * address) | ||
468 | { | ||
469 | if ( ((u32)address >= (u32)qe_immr) && | ||
470 | ((u32)address < ((u32)qe_immr + QE_IMMAP_SIZE)) ) | ||
471 | return (unsigned long)(address - (u32)qe_immr + | ||
472 | (u32)get_qe_base()); | ||
473 | return (unsigned long)virt_to_phys(address); | ||
474 | } | ||
475 | |||
476 | #endif /* __KERNEL__ */ | ||
477 | #endif /* _ASM_POWERPC_IMMAP_QE_H */ | ||
diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h new file mode 100644 index 000000000000..a62168ec535f --- /dev/null +++ b/include/asm-powerpc/qe.h | |||
@@ -0,0 +1,457 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. | ||
3 | * | ||
4 | * Authors: Shlomi Gridish <gridish@freescale.com> | ||
5 | * Li Yang <leoli@freescale.com> | ||
6 | * | ||
7 | * Description: | ||
8 | * QUICC Engine (QE) external definitions and structure. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | #ifndef _ASM_POWERPC_QE_H | ||
16 | #define _ASM_POWERPC_QE_H | ||
17 | #ifdef __KERNEL__ | ||
18 | |||
19 | #include <asm/immap_qe.h> | ||
20 | |||
21 | #define QE_NUM_OF_SNUM 28 | ||
22 | #define QE_NUM_OF_BRGS 16 | ||
23 | #define QE_NUM_OF_PORTS 1024 | ||
24 | |||
25 | /* Memory partitions | ||
26 | */ | ||
27 | #define MEM_PART_SYSTEM 0 | ||
28 | #define MEM_PART_SECONDARY 1 | ||
29 | #define MEM_PART_MURAM 2 | ||
30 | |||
31 | /* Export QE common operations */ | ||
32 | extern void qe_reset(void); | ||
33 | extern int par_io_init(struct device_node *np); | ||
34 | extern int par_io_of_config(struct device_node *np); | ||
35 | |||
36 | /* QE internal API */ | ||
37 | int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input); | ||
38 | void qe_setbrg(u32 brg, u32 rate); | ||
39 | int qe_get_snum(void); | ||
40 | void qe_put_snum(u8 snum); | ||
41 | u32 qe_muram_alloc(u32 size, u32 align); | ||
42 | int qe_muram_free(u32 offset); | ||
43 | u32 qe_muram_alloc_fixed(u32 offset, u32 size); | ||
44 | void qe_muram_dump(void); | ||
45 | void *qe_muram_addr(u32 offset); | ||
46 | |||
47 | /* Buffer descriptors */ | ||
48 | struct qe_bd { | ||
49 | u16 status; | ||
50 | u16 length; | ||
51 | u32 buf; | ||
52 | } __attribute__ ((packed)); | ||
53 | |||
54 | #define BD_STATUS_MASK 0xffff0000 | ||
55 | #define BD_LENGTH_MASK 0x0000ffff | ||
56 | |||
57 | /* Alignment */ | ||
58 | #define QE_INTR_TABLE_ALIGN 16 /* ??? */ | ||
59 | #define QE_ALIGNMENT_OF_BD 8 | ||
60 | #define QE_ALIGNMENT_OF_PRAM 64 | ||
61 | |||
62 | /* RISC allocation */ | ||
63 | enum qe_risc_allocation { | ||
64 | QE_RISC_ALLOCATION_RISC1 = 1, /* RISC 1 */ | ||
65 | QE_RISC_ALLOCATION_RISC2 = 2, /* RISC 2 */ | ||
66 | QE_RISC_ALLOCATION_RISC1_AND_RISC2 = 3 /* Dynamically choose | ||
67 | RISC 1 or RISC 2 */ | ||
68 | }; | ||
69 | |||
70 | /* QE extended filtering Table Lookup Key Size */ | ||
71 | enum qe_fltr_tbl_lookup_key_size { | ||
72 | QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES | ||
73 | = 0x3f, /* LookupKey parsed by the Generate LookupKey | ||
74 | CMD is truncated to 8 bytes */ | ||
75 | QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES | ||
76 | = 0x5f, /* LookupKey parsed by the Generate LookupKey | ||
77 | CMD is truncated to 16 bytes */ | ||
78 | }; | ||
79 | |||
80 | /* QE FLTR extended filtering Largest External Table Lookup Key Size */ | ||
81 | enum qe_fltr_largest_external_tbl_lookup_key_size { | ||
82 | QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE | ||
83 | = 0x0,/* not used */ | ||
84 | QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES | ||
85 | = QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES, /* 8 bytes */ | ||
86 | QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES | ||
87 | = QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES, /* 16 bytes */ | ||
88 | }; | ||
89 | |||
90 | /* structure representing QE parameter RAM */ | ||
91 | struct qe_timer_tables { | ||
92 | u16 tm_base; /* QE timer table base adr */ | ||
93 | u16 tm_ptr; /* QE timer table pointer */ | ||
94 | u16 r_tmr; /* QE timer mode register */ | ||
95 | u16 r_tmv; /* QE timer valid register */ | ||
96 | u32 tm_cmd; /* QE timer cmd register */ | ||
97 | u32 tm_cnt; /* QE timer internal cnt */ | ||
98 | } __attribute__ ((packed)); | ||
99 | |||
100 | #define QE_FLTR_TAD_SIZE 8 | ||
101 | |||
102 | /* QE extended filtering Termination Action Descriptor (TAD) */ | ||
103 | struct qe_fltr_tad { | ||
104 | u8 serialized[QE_FLTR_TAD_SIZE]; | ||
105 | } __attribute__ ((packed)); | ||
106 | |||
107 | /* Communication Direction */ | ||
108 | enum comm_dir { | ||
109 | COMM_DIR_NONE = 0, | ||
110 | COMM_DIR_RX = 1, | ||
111 | COMM_DIR_TX = 2, | ||
112 | COMM_DIR_RX_AND_TX = 3 | ||
113 | }; | ||
114 | |||
115 | /* Clocks and BRGs */ | ||
116 | enum qe_clock { | ||
117 | QE_CLK_NONE = 0, | ||
118 | QE_BRG1, /* Baud Rate Generator 1 */ | ||
119 | QE_BRG2, /* Baud Rate Generator 2 */ | ||
120 | QE_BRG3, /* Baud Rate Generator 3 */ | ||
121 | QE_BRG4, /* Baud Rate Generator 4 */ | ||
122 | QE_BRG5, /* Baud Rate Generator 5 */ | ||
123 | QE_BRG6, /* Baud Rate Generator 6 */ | ||
124 | QE_BRG7, /* Baud Rate Generator 7 */ | ||
125 | QE_BRG8, /* Baud Rate Generator 8 */ | ||
126 | QE_BRG9, /* Baud Rate Generator 9 */ | ||
127 | QE_BRG10, /* Baud Rate Generator 10 */ | ||
128 | QE_BRG11, /* Baud Rate Generator 11 */ | ||
129 | QE_BRG12, /* Baud Rate Generator 12 */ | ||
130 | QE_BRG13, /* Baud Rate Generator 13 */ | ||
131 | QE_BRG14, /* Baud Rate Generator 14 */ | ||
132 | QE_BRG15, /* Baud Rate Generator 15 */ | ||
133 | QE_BRG16, /* Baud Rate Generator 16 */ | ||
134 | QE_CLK1, /* Clock 1 */ | ||
135 | QE_CLK2, /* Clock 2 */ | ||
136 | QE_CLK3, /* Clock 3 */ | ||
137 | QE_CLK4, /* Clock 4 */ | ||
138 | QE_CLK5, /* Clock 5 */ | ||
139 | QE_CLK6, /* Clock 6 */ | ||
140 | QE_CLK7, /* Clock 7 */ | ||
141 | QE_CLK8, /* Clock 8 */ | ||
142 | QE_CLK9, /* Clock 9 */ | ||
143 | QE_CLK10, /* Clock 10 */ | ||
144 | QE_CLK11, /* Clock 11 */ | ||
145 | QE_CLK12, /* Clock 12 */ | ||
146 | QE_CLK13, /* Clock 13 */ | ||
147 | QE_CLK14, /* Clock 14 */ | ||
148 | QE_CLK15, /* Clock 15 */ | ||
149 | QE_CLK16, /* Clock 16 */ | ||
150 | QE_CLK17, /* Clock 17 */ | ||
151 | QE_CLK18, /* Clock 18 */ | ||
152 | QE_CLK19, /* Clock 19 */ | ||
153 | QE_CLK20, /* Clock 20 */ | ||
154 | QE_CLK21, /* Clock 21 */ | ||
155 | QE_CLK22, /* Clock 22 */ | ||
156 | QE_CLK23, /* Clock 23 */ | ||
157 | QE_CLK24, /* Clock 24 */ | ||
158 | QE_CLK_DUMMY, | ||
159 | }; | ||
160 | |||
161 | /* QE CMXUCR Registers. | ||
162 | * There are two UCCs represented in each of the four CMXUCR registers. | ||
163 | * These values are for the UCC in the LSBs | ||
164 | */ | ||
165 | #define QE_CMXUCR_MII_ENET_MNG 0x00007000 | ||
166 | #define QE_CMXUCR_MII_ENET_MNG_SHIFT 12 | ||
167 | #define QE_CMXUCR_GRANT 0x00008000 | ||
168 | #define QE_CMXUCR_TSA 0x00004000 | ||
169 | #define QE_CMXUCR_BKPT 0x00000100 | ||
170 | #define QE_CMXUCR_TX_CLK_SRC_MASK 0x0000000F | ||
171 | |||
172 | /* QE CMXGCR Registers. | ||
173 | */ | ||
174 | #define QE_CMXGCR_MII_ENET_MNG 0x00007000 | ||
175 | #define QE_CMXGCR_MII_ENET_MNG_SHIFT 12 | ||
176 | #define QE_CMXGCR_USBCS 0x0000000f | ||
177 | |||
178 | /* QE CECR Commands. | ||
179 | */ | ||
180 | #define QE_CR_FLG 0x00010000 | ||
181 | #define QE_RESET 0x80000000 | ||
182 | #define QE_INIT_TX_RX 0x00000000 | ||
183 | #define QE_INIT_RX 0x00000001 | ||
184 | #define QE_INIT_TX 0x00000002 | ||
185 | #define QE_ENTER_HUNT_MODE 0x00000003 | ||
186 | #define QE_STOP_TX 0x00000004 | ||
187 | #define QE_GRACEFUL_STOP_TX 0x00000005 | ||
188 | #define QE_RESTART_TX 0x00000006 | ||
189 | #define QE_CLOSE_RX_BD 0x00000007 | ||
190 | #define QE_SWITCH_COMMAND 0x00000007 | ||
191 | #define QE_SET_GROUP_ADDRESS 0x00000008 | ||
192 | #define QE_START_IDMA 0x00000009 | ||
193 | #define QE_MCC_STOP_RX 0x00000009 | ||
194 | #define QE_ATM_TRANSMIT 0x0000000a | ||
195 | #define QE_HPAC_CLEAR_ALL 0x0000000b | ||
196 | #define QE_GRACEFUL_STOP_RX 0x0000001a | ||
197 | #define QE_RESTART_RX 0x0000001b | ||
198 | #define QE_HPAC_SET_PRIORITY 0x0000010b | ||
199 | #define QE_HPAC_STOP_TX 0x0000020b | ||
200 | #define QE_HPAC_STOP_RX 0x0000030b | ||
201 | #define QE_HPAC_GRACEFUL_STOP_TX 0x0000040b | ||
202 | #define QE_HPAC_GRACEFUL_STOP_RX 0x0000050b | ||
203 | #define QE_HPAC_START_TX 0x0000060b | ||
204 | #define QE_HPAC_START_RX 0x0000070b | ||
205 | #define QE_USB_STOP_TX 0x0000000a | ||
206 | #define QE_USB_RESTART_TX 0x0000000b | ||
207 | #define QE_QMC_STOP_TX 0x0000000c | ||
208 | #define QE_QMC_STOP_RX 0x0000000d | ||
209 | #define QE_SS7_SU_FIL_RESET 0x0000000e | ||
210 | /* jonathbr added from here down for 83xx */ | ||
211 | #define QE_RESET_BCS 0x0000000a | ||
212 | #define QE_MCC_INIT_TX_RX_16 0x00000003 | ||
213 | #define QE_MCC_STOP_TX 0x00000004 | ||
214 | #define QE_MCC_INIT_TX_1 0x00000005 | ||
215 | #define QE_MCC_INIT_RX_1 0x00000006 | ||
216 | #define QE_MCC_RESET 0x00000007 | ||
217 | #define QE_SET_TIMER 0x00000008 | ||
218 | #define QE_RANDOM_NUMBER 0x0000000c | ||
219 | #define QE_ATM_MULTI_THREAD_INIT 0x00000011 | ||
220 | #define QE_ASSIGN_PAGE 0x00000012 | ||
221 | #define QE_ADD_REMOVE_HASH_ENTRY 0x00000013 | ||
222 | #define QE_START_FLOW_CONTROL 0x00000014 | ||
223 | #define QE_STOP_FLOW_CONTROL 0x00000015 | ||
224 | #define QE_ASSIGN_PAGE_TO_DEVICE 0x00000016 | ||
225 | |||
226 | #define QE_ASSIGN_RISC 0x00000010 | ||
227 | #define QE_CR_MCN_NORMAL_SHIFT 6 | ||
228 | #define QE_CR_MCN_USB_SHIFT 4 | ||
229 | #define QE_CR_MCN_RISC_ASSIGN_SHIFT 8 | ||
230 | #define QE_CR_SNUM_SHIFT 17 | ||
231 | |||
232 | /* QE CECR Sub Block - sub block of QE command. | ||
233 | */ | ||
234 | #define QE_CR_SUBBLOCK_INVALID 0x00000000 | ||
235 | #define QE_CR_SUBBLOCK_USB 0x03200000 | ||
236 | #define QE_CR_SUBBLOCK_UCCFAST1 0x02000000 | ||
237 | #define QE_CR_SUBBLOCK_UCCFAST2 0x02200000 | ||
238 | #define QE_CR_SUBBLOCK_UCCFAST3 0x02400000 | ||
239 | #define QE_CR_SUBBLOCK_UCCFAST4 0x02600000 | ||
240 | #define QE_CR_SUBBLOCK_UCCFAST5 0x02800000 | ||
241 | #define QE_CR_SUBBLOCK_UCCFAST6 0x02a00000 | ||
242 | #define QE_CR_SUBBLOCK_UCCFAST7 0x02c00000 | ||
243 | #define QE_CR_SUBBLOCK_UCCFAST8 0x02e00000 | ||
244 | #define QE_CR_SUBBLOCK_UCCSLOW1 0x00000000 | ||
245 | #define QE_CR_SUBBLOCK_UCCSLOW2 0x00200000 | ||
246 | #define QE_CR_SUBBLOCK_UCCSLOW3 0x00400000 | ||
247 | #define QE_CR_SUBBLOCK_UCCSLOW4 0x00600000 | ||
248 | #define QE_CR_SUBBLOCK_UCCSLOW5 0x00800000 | ||
249 | #define QE_CR_SUBBLOCK_UCCSLOW6 0x00a00000 | ||
250 | #define QE_CR_SUBBLOCK_UCCSLOW7 0x00c00000 | ||
251 | #define QE_CR_SUBBLOCK_UCCSLOW8 0x00e00000 | ||
252 | #define QE_CR_SUBBLOCK_MCC1 0x03800000 | ||
253 | #define QE_CR_SUBBLOCK_MCC2 0x03a00000 | ||
254 | #define QE_CR_SUBBLOCK_MCC3 0x03000000 | ||
255 | #define QE_CR_SUBBLOCK_IDMA1 0x02800000 | ||
256 | #define QE_CR_SUBBLOCK_IDMA2 0x02a00000 | ||
257 | #define QE_CR_SUBBLOCK_IDMA3 0x02c00000 | ||
258 | #define QE_CR_SUBBLOCK_IDMA4 0x02e00000 | ||
259 | #define QE_CR_SUBBLOCK_HPAC 0x01e00000 | ||
260 | #define QE_CR_SUBBLOCK_SPI1 0x01400000 | ||
261 | #define QE_CR_SUBBLOCK_SPI2 0x01600000 | ||
262 | #define QE_CR_SUBBLOCK_RAND 0x01c00000 | ||
263 | #define QE_CR_SUBBLOCK_TIMER 0x01e00000 | ||
264 | #define QE_CR_SUBBLOCK_GENERAL 0x03c00000 | ||
265 | |||
266 | /* QE CECR Protocol - For non-MCC, specifies mode for QE CECR command */ | ||
267 | #define QE_CR_PROTOCOL_UNSPECIFIED 0x00 /* For all other protocols */ | ||
268 | #define QE_CR_PROTOCOL_HDLC_TRANSPARENT 0x00 | ||
269 | #define QE_CR_PROTOCOL_ATM_POS 0x0A | ||
270 | #define QE_CR_PROTOCOL_ETHERNET 0x0C | ||
271 | #define QE_CR_PROTOCOL_L2_SWITCH 0x0D | ||
272 | |||
273 | /* BMR byte order */ | ||
274 | #define QE_BMR_BYTE_ORDER_BO_PPC 0x08 /* powerpc little endian */ | ||
275 | #define QE_BMR_BYTE_ORDER_BO_MOT 0x10 /* motorola big endian */ | ||
276 | #define QE_BMR_BYTE_ORDER_BO_MAX 0x18 | ||
277 | |||
278 | /* BRG configuration register */ | ||
279 | #define QE_BRGC_ENABLE 0x00010000 | ||
280 | #define QE_BRGC_DIVISOR_SHIFT 1 | ||
281 | #define QE_BRGC_DIVISOR_MAX 0xFFF | ||
282 | #define QE_BRGC_DIV16 1 | ||
283 | |||
284 | /* QE Timers registers */ | ||
285 | #define QE_GTCFR1_PCAS 0x80 | ||
286 | #define QE_GTCFR1_STP2 0x20 | ||
287 | #define QE_GTCFR1_RST2 0x10 | ||
288 | #define QE_GTCFR1_GM2 0x08 | ||
289 | #define QE_GTCFR1_GM1 0x04 | ||
290 | #define QE_GTCFR1_STP1 0x02 | ||
291 | #define QE_GTCFR1_RST1 0x01 | ||
292 | |||
293 | /* SDMA registers */ | ||
294 | #define QE_SDSR_BER1 0x02000000 | ||
295 | #define QE_SDSR_BER2 0x01000000 | ||
296 | |||
297 | #define QE_SDMR_GLB_1_MSK 0x80000000 | ||
298 | #define QE_SDMR_ADR_SEL 0x20000000 | ||
299 | #define QE_SDMR_BER1_MSK 0x02000000 | ||
300 | #define QE_SDMR_BER2_MSK 0x01000000 | ||
301 | #define QE_SDMR_EB1_MSK 0x00800000 | ||
302 | #define QE_SDMR_ER1_MSK 0x00080000 | ||
303 | #define QE_SDMR_ER2_MSK 0x00040000 | ||
304 | #define QE_SDMR_CEN_MASK 0x0000E000 | ||
305 | #define QE_SDMR_SBER_1 0x00000200 | ||
306 | #define QE_SDMR_SBER_2 0x00000200 | ||
307 | #define QE_SDMR_EB1_PR_MASK 0x000000C0 | ||
308 | #define QE_SDMR_ER1_PR 0x00000008 | ||
309 | |||
310 | #define QE_SDMR_CEN_SHIFT 13 | ||
311 | #define QE_SDMR_EB1_PR_SHIFT 6 | ||
312 | |||
313 | #define QE_SDTM_MSNUM_SHIFT 24 | ||
314 | |||
315 | #define QE_SDEBCR_BA_MASK 0x01FFFFFF | ||
316 | |||
317 | /* UPC */ | ||
318 | #define UPGCR_PROTOCOL 0x80000000 /* protocol ul2 or pl2 */ | ||
319 | #define UPGCR_TMS 0x40000000 /* Transmit master/slave mode */ | ||
320 | #define UPGCR_RMS 0x20000000 /* Receive master/slave mode */ | ||
321 | #define UPGCR_ADDR 0x10000000 /* Master MPHY Addr multiplexing */ | ||
322 | #define UPGCR_DIAG 0x01000000 /* Diagnostic mode */ | ||
323 | |||
324 | /* UCC */ | ||
325 | #define UCC_GUEMR_MODE_MASK_RX 0x02 | ||
326 | #define UCC_GUEMR_MODE_MASK_TX 0x01 | ||
327 | #define UCC_GUEMR_MODE_FAST_RX 0x02 | ||
328 | #define UCC_GUEMR_MODE_FAST_TX 0x01 | ||
329 | #define UCC_GUEMR_MODE_SLOW_RX 0x00 | ||
330 | #define UCC_GUEMR_MODE_SLOW_TX 0x00 | ||
331 | #define UCC_GUEMR_SET_RESERVED3 0x10 /* Bit 3 in the guemr is reserved but | ||
332 | must be set 1 */ | ||
333 | |||
334 | /* structure representing UCC SLOW parameter RAM */ | ||
335 | struct ucc_slow_pram { | ||
336 | u16 rbase; /* RX BD base address */ | ||
337 | u16 tbase; /* TX BD base address */ | ||
338 | u8 rfcr; /* Rx function code */ | ||
339 | u8 tfcr; /* Tx function code */ | ||
340 | u16 mrblr; /* Rx buffer length */ | ||
341 | u32 rstate; /* Rx internal state */ | ||
342 | u32 rptr; /* Rx internal data pointer */ | ||
343 | u16 rbptr; /* rb BD Pointer */ | ||
344 | u16 rcount; /* Rx internal byte count */ | ||
345 | u32 rtemp; /* Rx temp */ | ||
346 | u32 tstate; /* Tx internal state */ | ||
347 | u32 tptr; /* Tx internal data pointer */ | ||
348 | u16 tbptr; /* Tx BD pointer */ | ||
349 | u16 tcount; /* Tx byte count */ | ||
350 | u32 ttemp; /* Tx temp */ | ||
351 | u32 rcrc; /* temp receive CRC */ | ||
352 | u32 tcrc; /* temp transmit CRC */ | ||
353 | } __attribute__ ((packed)); | ||
354 | |||
355 | /* General UCC SLOW Mode Register (GUMRH & GUMRL) */ | ||
356 | #define UCC_SLOW_GUMR_H_CRC16 0x00004000 | ||
357 | #define UCC_SLOW_GUMR_H_CRC16CCITT 0x00000000 | ||
358 | #define UCC_SLOW_GUMR_H_CRC32CCITT 0x00008000 | ||
359 | #define UCC_SLOW_GUMR_H_REVD 0x00002000 | ||
360 | #define UCC_SLOW_GUMR_H_TRX 0x00001000 | ||
361 | #define UCC_SLOW_GUMR_H_TTX 0x00000800 | ||
362 | #define UCC_SLOW_GUMR_H_CDP 0x00000400 | ||
363 | #define UCC_SLOW_GUMR_H_CTSP 0x00000200 | ||
364 | #define UCC_SLOW_GUMR_H_CDS 0x00000100 | ||
365 | #define UCC_SLOW_GUMR_H_CTSS 0x00000080 | ||
366 | #define UCC_SLOW_GUMR_H_TFL 0x00000040 | ||
367 | #define UCC_SLOW_GUMR_H_RFW 0x00000020 | ||
368 | #define UCC_SLOW_GUMR_H_TXSY 0x00000010 | ||
369 | #define UCC_SLOW_GUMR_H_4SYNC 0x00000004 | ||
370 | #define UCC_SLOW_GUMR_H_8SYNC 0x00000008 | ||
371 | #define UCC_SLOW_GUMR_H_16SYNC 0x0000000c | ||
372 | #define UCC_SLOW_GUMR_H_RTSM 0x00000002 | ||
373 | #define UCC_SLOW_GUMR_H_RSYN 0x00000001 | ||
374 | |||
375 | #define UCC_SLOW_GUMR_L_TCI 0x10000000 | ||
376 | #define UCC_SLOW_GUMR_L_RINV 0x02000000 | ||
377 | #define UCC_SLOW_GUMR_L_TINV 0x01000000 | ||
378 | #define UCC_SLOW_GUMR_L_TEND 0x00020000 | ||
379 | #define UCC_SLOW_GUMR_L_ENR 0x00000020 | ||
380 | #define UCC_SLOW_GUMR_L_ENT 0x00000010 | ||
381 | |||
382 | /* General UCC FAST Mode Register */ | ||
383 | #define UCC_FAST_GUMR_TCI 0x20000000 | ||
384 | #define UCC_FAST_GUMR_TRX 0x10000000 | ||
385 | #define UCC_FAST_GUMR_TTX 0x08000000 | ||
386 | #define UCC_FAST_GUMR_CDP 0x04000000 | ||
387 | #define UCC_FAST_GUMR_CTSP 0x02000000 | ||
388 | #define UCC_FAST_GUMR_CDS 0x01000000 | ||
389 | #define UCC_FAST_GUMR_CTSS 0x00800000 | ||
390 | #define UCC_FAST_GUMR_TXSY 0x00020000 | ||
391 | #define UCC_FAST_GUMR_RSYN 0x00010000 | ||
392 | #define UCC_FAST_GUMR_RTSM 0x00002000 | ||
393 | #define UCC_FAST_GUMR_REVD 0x00000400 | ||
394 | #define UCC_FAST_GUMR_ENR 0x00000020 | ||
395 | #define UCC_FAST_GUMR_ENT 0x00000010 | ||
396 | |||
397 | /* Slow UCC Event Register (UCCE) */ | ||
398 | #define UCC_SLOW_UCCE_GLR 0x1000 | ||
399 | #define UCC_SLOW_UCCE_GLT 0x0800 | ||
400 | #define UCC_SLOW_UCCE_DCC 0x0400 | ||
401 | #define UCC_SLOW_UCCE_FLG 0x0200 | ||
402 | #define UCC_SLOW_UCCE_AB 0x0200 | ||
403 | #define UCC_SLOW_UCCE_IDLE 0x0100 | ||
404 | #define UCC_SLOW_UCCE_GRA 0x0080 | ||
405 | #define UCC_SLOW_UCCE_TXE 0x0010 | ||
406 | #define UCC_SLOW_UCCE_RXF 0x0008 | ||
407 | #define UCC_SLOW_UCCE_CCR 0x0008 | ||
408 | #define UCC_SLOW_UCCE_RCH 0x0008 | ||
409 | #define UCC_SLOW_UCCE_BSY 0x0004 | ||
410 | #define UCC_SLOW_UCCE_TXB 0x0002 | ||
411 | #define UCC_SLOW_UCCE_TX 0x0002 | ||
412 | #define UCC_SLOW_UCCE_RX 0x0001 | ||
413 | #define UCC_SLOW_UCCE_GOV 0x0001 | ||
414 | #define UCC_SLOW_UCCE_GUN 0x0002 | ||
415 | #define UCC_SLOW_UCCE_GINT 0x0004 | ||
416 | #define UCC_SLOW_UCCE_IQOV 0x0008 | ||
417 | |||
418 | #define UCC_SLOW_UCCE_HDLC_SET (UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \ | ||
419 | UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_TXB | UCC_SLOW_UCCE_RXF | \ | ||
420 | UCC_SLOW_UCCE_DCC | UCC_SLOW_UCCE_GLT | UCC_SLOW_UCCE_GLR) | ||
421 | #define UCC_SLOW_UCCE_ENET_SET (UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \ | ||
422 | UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_TXB | UCC_SLOW_UCCE_RXF) | ||
423 | #define UCC_SLOW_UCCE_TRANS_SET (UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \ | ||
424 | UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_TX | UCC_SLOW_UCCE_RX | \ | ||
425 | UCC_SLOW_UCCE_DCC | UCC_SLOW_UCCE_GLT | UCC_SLOW_UCCE_GLR) | ||
426 | #define UCC_SLOW_UCCE_UART_SET (UCC_SLOW_UCCE_BSY | UCC_SLOW_UCCE_GRA | \ | ||
427 | UCC_SLOW_UCCE_TXB | UCC_SLOW_UCCE_TX | UCC_SLOW_UCCE_RX | \ | ||
428 | UCC_SLOW_UCCE_GLT | UCC_SLOW_UCCE_GLR) | ||
429 | #define UCC_SLOW_UCCE_QMC_SET (UCC_SLOW_UCCE_IQOV | UCC_SLOW_UCCE_GINT | \ | ||
430 | UCC_SLOW_UCCE_GUN | UCC_SLOW_UCCE_GOV) | ||
431 | |||
432 | #define UCC_SLOW_UCCE_OTHER (UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \ | ||
433 | UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_DCC | UCC_SLOW_UCCE_GLT | \ | ||
434 | UCC_SLOW_UCCE_GLR) | ||
435 | |||
436 | #define UCC_SLOW_INTR_TX UCC_SLOW_UCCE_TXB | ||
437 | #define UCC_SLOW_INTR_RX (UCC_SLOW_UCCE_RXF | UCC_SLOW_UCCE_RX) | ||
438 | #define UCC_SLOW_INTR (UCC_SLOW_INTR_TX | UCC_SLOW_INTR_RX) | ||
439 | |||
440 | /* UCC Transmit On Demand Register (UTODR) */ | ||
441 | #define UCC_SLOW_TOD 0x8000 | ||
442 | #define UCC_FAST_TOD 0x8000 | ||
443 | |||
444 | /* Function code masks */ | ||
445 | #define FC_GBL 0x20 | ||
446 | #define FC_DTB_LCL 0x02 | ||
447 | #define UCC_FAST_FUNCTION_CODE_GBL 0x20 | ||
448 | #define UCC_FAST_FUNCTION_CODE_DTB_LCL 0x02 | ||
449 | #define UCC_FAST_FUNCTION_CODE_BDB_LCL 0x01 | ||
450 | |||
451 | static inline long IS_MURAM_ERR(const u32 offset) | ||
452 | { | ||
453 | return offset > (u32) - 1000L; | ||
454 | } | ||
455 | |||
456 | #endif /* __KERNEL__ */ | ||
457 | #endif /* _ASM_POWERPC_QE_H */ | ||
diff --git a/include/asm-powerpc/qe_ic.h b/include/asm-powerpc/qe_ic.h new file mode 100644 index 000000000000..e386fb7e44b0 --- /dev/null +++ b/include/asm-powerpc/qe_ic.h | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * include/asm-powerpc/qe_ic.h | ||
3 | * | ||
4 | * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. | ||
5 | * | ||
6 | * Authors: Shlomi Gridish <gridish@freescale.com> | ||
7 | * Li Yang <leoli@freescale.com> | ||
8 | * | ||
9 | * Description: | ||
10 | * QE IC external definitions and structure. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License as published by the | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | */ | ||
17 | #ifndef _ASM_POWERPC_QE_IC_H | ||
18 | #define _ASM_POWERPC_QE_IC_H | ||
19 | |||
20 | #include <linux/irq.h> | ||
21 | |||
22 | #define NUM_OF_QE_IC_GROUPS 6 | ||
23 | |||
24 | /* Flags when we init the QE IC */ | ||
25 | #define QE_IC_SPREADMODE_GRP_W 0x00000001 | ||
26 | #define QE_IC_SPREADMODE_GRP_X 0x00000002 | ||
27 | #define QE_IC_SPREADMODE_GRP_Y 0x00000004 | ||
28 | #define QE_IC_SPREADMODE_GRP_Z 0x00000008 | ||
29 | #define QE_IC_SPREADMODE_GRP_RISCA 0x00000010 | ||
30 | #define QE_IC_SPREADMODE_GRP_RISCB 0x00000020 | ||
31 | |||
32 | #define QE_IC_LOW_SIGNAL 0x00000100 | ||
33 | #define QE_IC_HIGH_SIGNAL 0x00000200 | ||
34 | |||
35 | #define QE_IC_GRP_W_PRI0_DEST_SIGNAL_HIGH 0x00001000 | ||
36 | #define QE_IC_GRP_W_PRI1_DEST_SIGNAL_HIGH 0x00002000 | ||
37 | #define QE_IC_GRP_X_PRI0_DEST_SIGNAL_HIGH 0x00004000 | ||
38 | #define QE_IC_GRP_X_PRI1_DEST_SIGNAL_HIGH 0x00008000 | ||
39 | #define QE_IC_GRP_Y_PRI0_DEST_SIGNAL_HIGH 0x00010000 | ||
40 | #define QE_IC_GRP_Y_PRI1_DEST_SIGNAL_HIGH 0x00020000 | ||
41 | #define QE_IC_GRP_Z_PRI0_DEST_SIGNAL_HIGH 0x00040000 | ||
42 | #define QE_IC_GRP_Z_PRI1_DEST_SIGNAL_HIGH 0x00080000 | ||
43 | #define QE_IC_GRP_RISCA_PRI0_DEST_SIGNAL_HIGH 0x00100000 | ||
44 | #define QE_IC_GRP_RISCA_PRI1_DEST_SIGNAL_HIGH 0x00200000 | ||
45 | #define QE_IC_GRP_RISCB_PRI0_DEST_SIGNAL_HIGH 0x00400000 | ||
46 | #define QE_IC_GRP_RISCB_PRI1_DEST_SIGNAL_HIGH 0x00800000 | ||
47 | #define QE_IC_GRP_W_DEST_SIGNAL_SHIFT (12) | ||
48 | |||
49 | /* QE interrupt sources groups */ | ||
50 | enum qe_ic_grp_id { | ||
51 | QE_IC_GRP_W = 0, /* QE interrupt controller group W */ | ||
52 | QE_IC_GRP_X, /* QE interrupt controller group X */ | ||
53 | QE_IC_GRP_Y, /* QE interrupt controller group Y */ | ||
54 | QE_IC_GRP_Z, /* QE interrupt controller group Z */ | ||
55 | QE_IC_GRP_RISCA, /* QE interrupt controller RISC group A */ | ||
56 | QE_IC_GRP_RISCB /* QE interrupt controller RISC group B */ | ||
57 | }; | ||
58 | |||
59 | void qe_ic_init(struct device_node *node, unsigned int flags); | ||
60 | void qe_ic_set_highest_priority(unsigned int virq, int high); | ||
61 | int qe_ic_set_priority(unsigned int virq, unsigned int priority); | ||
62 | int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high); | ||
63 | |||
64 | #endif /* _ASM_POWERPC_QE_IC_H */ | ||
diff --git a/include/asm-powerpc/ucc.h b/include/asm-powerpc/ucc.h new file mode 100644 index 000000000000..afe3076bdc03 --- /dev/null +++ b/include/asm-powerpc/ucc.h | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. | ||
3 | * | ||
4 | * Authors: Shlomi Gridish <gridish@freescale.com> | ||
5 | * Li Yang <leoli@freescale.com> | ||
6 | * | ||
7 | * Description: | ||
8 | * Internal header file for UCC unit routines. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | #ifndef __UCC_H__ | ||
16 | #define __UCC_H__ | ||
17 | |||
18 | #include <asm/immap_qe.h> | ||
19 | #include <asm/qe.h> | ||
20 | |||
21 | #define STATISTICS | ||
22 | |||
23 | #define UCC_MAX_NUM 8 | ||
24 | |||
25 | /* Slow or fast type for UCCs. | ||
26 | */ | ||
27 | enum ucc_speed_type { | ||
28 | UCC_SPEED_TYPE_FAST, UCC_SPEED_TYPE_SLOW | ||
29 | }; | ||
30 | |||
31 | /* Initial UCCs Parameter RAM address relative to: MEM_MAP_BASE (IMMR). | ||
32 | */ | ||
33 | enum ucc_pram_initial_offset { | ||
34 | UCC_PRAM_OFFSET_UCC1 = 0x8400, | ||
35 | UCC_PRAM_OFFSET_UCC2 = 0x8500, | ||
36 | UCC_PRAM_OFFSET_UCC3 = 0x8600, | ||
37 | UCC_PRAM_OFFSET_UCC4 = 0x9000, | ||
38 | UCC_PRAM_OFFSET_UCC5 = 0x8000, | ||
39 | UCC_PRAM_OFFSET_UCC6 = 0x8100, | ||
40 | UCC_PRAM_OFFSET_UCC7 = 0x8200, | ||
41 | UCC_PRAM_OFFSET_UCC8 = 0x8300 | ||
42 | }; | ||
43 | |||
44 | /* ucc_set_type | ||
45 | * Sets UCC to slow or fast mode. | ||
46 | * | ||
47 | * ucc_num - (In) number of UCC (0-7). | ||
48 | * regs - (In) pointer to registers base for the UCC. | ||
49 | * speed - (In) slow or fast mode for UCC. | ||
50 | */ | ||
51 | int ucc_set_type(int ucc_num, struct ucc_common *regs, | ||
52 | enum ucc_speed_type speed); | ||
53 | |||
54 | /* ucc_init_guemr | ||
55 | * Init the Guemr register. | ||
56 | * | ||
57 | * regs - (In) pointer to registers base for the UCC. | ||
58 | */ | ||
59 | int ucc_init_guemr(struct ucc_common *regs); | ||
60 | |||
61 | int ucc_set_qe_mux_mii_mng(int ucc_num); | ||
62 | |||
63 | int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode); | ||
64 | |||
65 | int ucc_mux_set_grant_tsa_bkpt(int ucc_num, int set, u32 mask); | ||
66 | |||
67 | /* QE MUX clock routing for UCC | ||
68 | */ | ||
69 | static inline int ucc_set_qe_mux_grant(int ucc_num, int set) | ||
70 | { | ||
71 | return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_GRANT); | ||
72 | } | ||
73 | |||
74 | static inline int ucc_set_qe_mux_tsa(int ucc_num, int set) | ||
75 | { | ||
76 | return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_TSA); | ||
77 | } | ||
78 | |||
79 | static inline int ucc_set_qe_mux_bkpt(int ucc_num, int set) | ||
80 | { | ||
81 | return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_BKPT); | ||
82 | } | ||
83 | |||
84 | #endif /* __UCC_H__ */ | ||
diff --git a/include/asm-powerpc/ucc_fast.h b/include/asm-powerpc/ucc_fast.h new file mode 100644 index 000000000000..39d1c90fd2ca --- /dev/null +++ b/include/asm-powerpc/ucc_fast.h | |||
@@ -0,0 +1,243 @@ | |||
1 | /* | ||
2 | * include/asm-powerpc/ucc_fast.h | ||
3 | * | ||
4 | * Internal header file for UCC FAST unit routines. | ||
5 | * | ||
6 | * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. | ||
7 | * | ||
8 | * Authors: Shlomi Gridish <gridish@freescale.com> | ||
9 | * Li Yang <leoli@freescale.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | */ | ||
16 | #ifndef __UCC_FAST_H__ | ||
17 | #define __UCC_FAST_H__ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | |||
21 | #include <asm/immap_qe.h> | ||
22 | #include <asm/qe.h> | ||
23 | |||
24 | #include "ucc.h" | ||
25 | |||
26 | /* Receive BD's status */ | ||
27 | #define R_E 0x80000000 /* buffer empty */ | ||
28 | #define R_W 0x20000000 /* wrap bit */ | ||
29 | #define R_I 0x10000000 /* interrupt on reception */ | ||
30 | #define R_L 0x08000000 /* last */ | ||
31 | #define R_F 0x04000000 /* first */ | ||
32 | |||
33 | /* transmit BD's status */ | ||
34 | #define T_R 0x80000000 /* ready bit */ | ||
35 | #define T_W 0x20000000 /* wrap bit */ | ||
36 | #define T_I 0x10000000 /* interrupt on completion */ | ||
37 | #define T_L 0x08000000 /* last */ | ||
38 | |||
39 | /* Rx Data buffer must be 4 bytes aligned in most cases */ | ||
40 | #define UCC_FAST_RX_ALIGN 4 | ||
41 | #define UCC_FAST_MRBLR_ALIGNMENT 4 | ||
42 | #define UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT 8 | ||
43 | |||
44 | /* Sizes */ | ||
45 | #define UCC_FAST_URFS_MIN_VAL 0x88 | ||
46 | #define UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR 8 | ||
47 | |||
48 | /* ucc_fast_channel_protocol_mode - UCC FAST mode */ | ||
49 | enum ucc_fast_channel_protocol_mode { | ||
50 | UCC_FAST_PROTOCOL_MODE_HDLC = 0x00000000, | ||
51 | UCC_FAST_PROTOCOL_MODE_RESERVED01 = 0x00000001, | ||
52 | UCC_FAST_PROTOCOL_MODE_RESERVED_QMC = 0x00000002, | ||
53 | UCC_FAST_PROTOCOL_MODE_RESERVED02 = 0x00000003, | ||
54 | UCC_FAST_PROTOCOL_MODE_RESERVED_UART = 0x00000004, | ||
55 | UCC_FAST_PROTOCOL_MODE_RESERVED03 = 0x00000005, | ||
56 | UCC_FAST_PROTOCOL_MODE_RESERVED_EX_MAC_1 = 0x00000006, | ||
57 | UCC_FAST_PROTOCOL_MODE_RESERVED_EX_MAC_2 = 0x00000007, | ||
58 | UCC_FAST_PROTOCOL_MODE_RESERVED_BISYNC = 0x00000008, | ||
59 | UCC_FAST_PROTOCOL_MODE_RESERVED04 = 0x00000009, | ||
60 | UCC_FAST_PROTOCOL_MODE_ATM = 0x0000000A, | ||
61 | UCC_FAST_PROTOCOL_MODE_RESERVED05 = 0x0000000B, | ||
62 | UCC_FAST_PROTOCOL_MODE_ETHERNET = 0x0000000C, | ||
63 | UCC_FAST_PROTOCOL_MODE_RESERVED06 = 0x0000000D, | ||
64 | UCC_FAST_PROTOCOL_MODE_POS = 0x0000000E, | ||
65 | UCC_FAST_PROTOCOL_MODE_RESERVED07 = 0x0000000F | ||
66 | }; | ||
67 | |||
68 | /* ucc_fast_transparent_txrx - UCC Fast Transparent TX & RX */ | ||
69 | enum ucc_fast_transparent_txrx { | ||
70 | UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL = 0x00000000, | ||
71 | UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_TRANSPARENT = 0x18000000 | ||
72 | }; | ||
73 | |||
74 | /* UCC fast diagnostic mode */ | ||
75 | enum ucc_fast_diag_mode { | ||
76 | UCC_FAST_DIAGNOSTIC_NORMAL = 0x0, | ||
77 | UCC_FAST_DIAGNOSTIC_LOCAL_LOOP_BACK = 0x40000000, | ||
78 | UCC_FAST_DIAGNOSTIC_AUTO_ECHO = 0x80000000, | ||
79 | UCC_FAST_DIAGNOSTIC_LOOP_BACK_AND_ECHO = 0xC0000000 | ||
80 | }; | ||
81 | |||
82 | /* UCC fast Sync length (transparent mode only) */ | ||
83 | enum ucc_fast_sync_len { | ||
84 | UCC_FAST_SYNC_LEN_NOT_USED = 0x0, | ||
85 | UCC_FAST_SYNC_LEN_AUTOMATIC = 0x00004000, | ||
86 | UCC_FAST_SYNC_LEN_8_BIT = 0x00008000, | ||
87 | UCC_FAST_SYNC_LEN_16_BIT = 0x0000C000 | ||
88 | }; | ||
89 | |||
90 | /* UCC fast RTS mode */ | ||
91 | enum ucc_fast_ready_to_send { | ||
92 | UCC_FAST_SEND_IDLES_BETWEEN_FRAMES = 0x00000000, | ||
93 | UCC_FAST_SEND_FLAGS_BETWEEN_FRAMES = 0x00002000 | ||
94 | }; | ||
95 | |||
96 | /* UCC fast receiver decoding mode */ | ||
97 | enum ucc_fast_rx_decoding_method { | ||
98 | UCC_FAST_RX_ENCODING_NRZ = 0x00000000, | ||
99 | UCC_FAST_RX_ENCODING_NRZI = 0x00000800, | ||
100 | UCC_FAST_RX_ENCODING_RESERVED0 = 0x00001000, | ||
101 | UCC_FAST_RX_ENCODING_RESERVED1 = 0x00001800 | ||
102 | }; | ||
103 | |||
104 | /* UCC fast transmitter encoding mode */ | ||
105 | enum ucc_fast_tx_encoding_method { | ||
106 | UCC_FAST_TX_ENCODING_NRZ = 0x00000000, | ||
107 | UCC_FAST_TX_ENCODING_NRZI = 0x00000100, | ||
108 | UCC_FAST_TX_ENCODING_RESERVED0 = 0x00000200, | ||
109 | UCC_FAST_TX_ENCODING_RESERVED1 = 0x00000300 | ||
110 | }; | ||
111 | |||
112 | /* UCC fast CRC length */ | ||
113 | enum ucc_fast_transparent_tcrc { | ||
114 | UCC_FAST_16_BIT_CRC = 0x00000000, | ||
115 | UCC_FAST_CRC_RESERVED0 = 0x00000040, | ||
116 | UCC_FAST_32_BIT_CRC = 0x00000080, | ||
117 | UCC_FAST_CRC_RESERVED1 = 0x000000C0 | ||
118 | }; | ||
119 | |||
120 | /* Fast UCC initialization structure */ | ||
121 | struct ucc_fast_info { | ||
122 | int ucc_num; | ||
123 | enum qe_clock rx_clock; | ||
124 | enum qe_clock tx_clock; | ||
125 | u32 regs; | ||
126 | int irq; | ||
127 | u32 uccm_mask; | ||
128 | int bd_mem_part; | ||
129 | int brkpt_support; | ||
130 | int grant_support; | ||
131 | int tsa; | ||
132 | int cdp; | ||
133 | int cds; | ||
134 | int ctsp; | ||
135 | int ctss; | ||
136 | int tci; | ||
137 | int txsy; | ||
138 | int rtsm; | ||
139 | int revd; | ||
140 | int rsyn; | ||
141 | u16 max_rx_buf_length; | ||
142 | u16 urfs; | ||
143 | u16 urfet; | ||
144 | u16 urfset; | ||
145 | u16 utfs; | ||
146 | u16 utfet; | ||
147 | u16 utftt; | ||
148 | u16 ufpt; | ||
149 | enum ucc_fast_channel_protocol_mode mode; | ||
150 | enum ucc_fast_transparent_txrx ttx_trx; | ||
151 | enum ucc_fast_tx_encoding_method tenc; | ||
152 | enum ucc_fast_rx_decoding_method renc; | ||
153 | enum ucc_fast_transparent_tcrc tcrc; | ||
154 | enum ucc_fast_sync_len synl; | ||
155 | }; | ||
156 | |||
157 | struct ucc_fast_private { | ||
158 | struct ucc_fast_info *uf_info; | ||
159 | struct ucc_fast *uf_regs; /* a pointer to memory map of UCC regs. */ | ||
160 | u32 *p_ucce; /* a pointer to the event register in memory. */ | ||
161 | u32 *p_uccm; /* a pointer to the mask register in memory. */ | ||
162 | int enabled_tx; /* Whether channel is enabled for Tx (ENT) */ | ||
163 | int enabled_rx; /* Whether channel is enabled for Rx (ENR) */ | ||
164 | int stopped_tx; /* Whether channel has been stopped for Tx | ||
165 | (STOP_TX, etc.) */ | ||
166 | int stopped_rx; /* Whether channel has been stopped for Rx */ | ||
167 | u32 ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of Tx | ||
168 | virtual fifo */ | ||
169 | u32 ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of Rx | ||
170 | virtual fifo */ | ||
171 | #ifdef STATISTICS | ||
172 | u32 tx_frames; /* Transmitted frames counter. */ | ||
173 | u32 rx_frames; /* Received frames counter (only frames | ||
174 | passed to application). */ | ||
175 | u32 tx_discarded; /* Discarded tx frames counter (frames that | ||
176 | were discarded by the driver due to errors). | ||
177 | */ | ||
178 | u32 rx_discarded; /* Discarded rx frames counter (frames that | ||
179 | were discarded by the driver due to errors). | ||
180 | */ | ||
181 | #endif /* STATISTICS */ | ||
182 | u16 mrblr; /* maximum receive buffer length */ | ||
183 | }; | ||
184 | |||
185 | /* ucc_fast_init | ||
186 | * Initializes Fast UCC according to user provided parameters. | ||
187 | * | ||
188 | * uf_info - (In) pointer to the fast UCC info structure. | ||
189 | * uccf_ret - (Out) pointer to the fast UCC structure. | ||
190 | */ | ||
191 | int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret); | ||
192 | |||
193 | /* ucc_fast_free | ||
194 | * Frees all resources for fast UCC. | ||
195 | * | ||
196 | * uccf - (In) pointer to the fast UCC structure. | ||
197 | */ | ||
198 | void ucc_fast_free(struct ucc_fast_private * uccf); | ||
199 | |||
200 | /* ucc_fast_enable | ||
201 | * Enables a fast UCC port. | ||
202 | * This routine enables Tx and/or Rx through the General UCC Mode Register. | ||
203 | * | ||
204 | * uccf - (In) pointer to the fast UCC structure. | ||
205 | * mode - (In) TX, RX, or both. | ||
206 | */ | ||
207 | void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode); | ||
208 | |||
209 | /* ucc_fast_disable | ||
210 | * Disables a fast UCC port. | ||
211 | * This routine disables Tx and/or Rx through the General UCC Mode Register. | ||
212 | * | ||
213 | * uccf - (In) pointer to the fast UCC structure. | ||
214 | * mode - (In) TX, RX, or both. | ||
215 | */ | ||
216 | void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode); | ||
217 | |||
218 | /* ucc_fast_irq | ||
219 | * Handles interrupts on fast UCC. | ||
220 | * Called from the general interrupt routine to handle interrupts on fast UCC. | ||
221 | * | ||
222 | * uccf - (In) pointer to the fast UCC structure. | ||
223 | */ | ||
224 | void ucc_fast_irq(struct ucc_fast_private * uccf); | ||
225 | |||
226 | /* ucc_fast_transmit_on_demand | ||
227 | * Immediately forces a poll of the transmitter for data to be sent. | ||
228 | * Typically, the hardware performs a periodic poll for data that the | ||
229 | * transmit routine has set up to be transmitted. In cases where | ||
230 | * this polling cycle is not soon enough, this optional routine can | ||
231 | * be invoked to force a poll right away, instead. Proper use for | ||
232 | * each transmission for which this functionality is desired is to | ||
233 | * call the transmit routine and then this routine right after. | ||
234 | * | ||
235 | * uccf - (In) pointer to the fast UCC structure. | ||
236 | */ | ||
237 | void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf); | ||
238 | |||
239 | u32 ucc_fast_get_qe_cr_subblock(int uccf_num); | ||
240 | |||
241 | void ucc_fast_dump_regs(struct ucc_fast_private * uccf); | ||
242 | |||
243 | #endif /* __UCC_FAST_H__ */ | ||
diff --git a/include/asm-powerpc/ucc_slow.h b/include/asm-powerpc/ucc_slow.h new file mode 100644 index 000000000000..ca93bc99237e --- /dev/null +++ b/include/asm-powerpc/ucc_slow.h | |||
@@ -0,0 +1,289 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. | ||
3 | * | ||
4 | * Authors: Shlomi Gridish <gridish@freescale.com> | ||
5 | * Li Yang <leoli@freescale.com> | ||
6 | * | ||
7 | * Description: | ||
8 | * Internal header file for UCC SLOW unit routines. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | #ifndef __UCC_SLOW_H__ | ||
16 | #define __UCC_SLOW_H__ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | |||
20 | #include <asm/immap_qe.h> | ||
21 | #include <asm/qe.h> | ||
22 | |||
23 | #include "ucc.h" | ||
24 | |||
25 | /* transmit BD's status */ | ||
26 | #define T_R 0x80000000 /* ready bit */ | ||
27 | #define T_PAD 0x40000000 /* add pads to short frames */ | ||
28 | #define T_W 0x20000000 /* wrap bit */ | ||
29 | #define T_I 0x10000000 /* interrupt on completion */ | ||
30 | #define T_L 0x08000000 /* last */ | ||
31 | |||
32 | #define T_A 0x04000000 /* Address - the data transmitted as address | ||
33 | chars */ | ||
34 | #define T_TC 0x04000000 /* transmit CRC */ | ||
35 | #define T_CM 0x02000000 /* continuous mode */ | ||
36 | #define T_DEF 0x02000000 /* collision on previous attempt to transmit */ | ||
37 | #define T_P 0x01000000 /* Preamble - send Preamble sequence before | ||
38 | data */ | ||
39 | #define T_HB 0x01000000 /* heartbeat */ | ||
40 | #define T_NS 0x00800000 /* No Stop */ | ||
41 | #define T_LC 0x00800000 /* late collision */ | ||
42 | #define T_RL 0x00400000 /* retransmission limit */ | ||
43 | #define T_UN 0x00020000 /* underrun */ | ||
44 | #define T_CT 0x00010000 /* CTS lost */ | ||
45 | #define T_CSL 0x00010000 /* carrier sense lost */ | ||
46 | #define T_RC 0x003c0000 /* retry count */ | ||
47 | |||
48 | /* Receive BD's status */ | ||
49 | #define R_E 0x80000000 /* buffer empty */ | ||
50 | #define R_W 0x20000000 /* wrap bit */ | ||
51 | #define R_I 0x10000000 /* interrupt on reception */ | ||
52 | #define R_L 0x08000000 /* last */ | ||
53 | #define R_C 0x08000000 /* the last byte in this buffer is a cntl | ||
54 | char */ | ||
55 | #define R_F 0x04000000 /* first */ | ||
56 | #define R_A 0x04000000 /* the first byte in this buffer is address | ||
57 | byte */ | ||
58 | #define R_CM 0x02000000 /* continuous mode */ | ||
59 | #define R_ID 0x01000000 /* buffer close on reception of idles */ | ||
60 | #define R_M 0x01000000 /* Frame received because of promiscuous | ||
61 | mode */ | ||
62 | #define R_AM 0x00800000 /* Address match */ | ||
63 | #define R_DE 0x00800000 /* Address match */ | ||
64 | #define R_LG 0x00200000 /* Break received */ | ||
65 | #define R_BR 0x00200000 /* Frame length violation */ | ||
66 | #define R_NO 0x00100000 /* Rx Non Octet Aligned Packet */ | ||
67 | #define R_FR 0x00100000 /* Framing Error (no stop bit) character | ||
68 | received */ | ||
69 | #define R_PR 0x00080000 /* Parity Error character received */ | ||
70 | #define R_AB 0x00080000 /* Frame Aborted */ | ||
71 | #define R_SH 0x00080000 /* frame is too short */ | ||
72 | #define R_CR 0x00040000 /* CRC Error */ | ||
73 | #define R_OV 0x00020000 /* Overrun */ | ||
74 | #define R_CD 0x00010000 /* CD lost */ | ||
75 | #define R_CL 0x00010000 /* this frame is closed because of a | ||
76 | collision */ | ||
77 | |||
78 | /* Rx Data buffer must be 4 bytes aligned in most cases.*/ | ||
79 | #define UCC_SLOW_RX_ALIGN 4 | ||
80 | #define UCC_SLOW_MRBLR_ALIGNMENT 4 | ||
81 | #define UCC_SLOW_PRAM_SIZE 0x100 | ||
82 | #define ALIGNMENT_OF_UCC_SLOW_PRAM 64 | ||
83 | |||
84 | /* UCC Slow Channel Protocol Mode */ | ||
85 | enum ucc_slow_channel_protocol_mode { | ||
86 | UCC_SLOW_CHANNEL_PROTOCOL_MODE_QMC = 0x00000002, | ||
87 | UCC_SLOW_CHANNEL_PROTOCOL_MODE_UART = 0x00000004, | ||
88 | UCC_SLOW_CHANNEL_PROTOCOL_MODE_BISYNC = 0x00000008, | ||
89 | }; | ||
90 | |||
91 | /* UCC Slow Transparent Transmit CRC (TCRC) */ | ||
92 | enum ucc_slow_transparent_tcrc { | ||
93 | /* 16-bit CCITT CRC (HDLC). (X16 + X12 + X5 + 1) */ | ||
94 | UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC16 = 0x00000000, | ||
95 | /* CRC16 (BISYNC). (X16 + X15 + X2 + 1) */ | ||
96 | UCC_SLOW_TRANSPARENT_TCRC_CRC16 = 0x00004000, | ||
97 | /* 32-bit CCITT CRC (Ethernet and HDLC) */ | ||
98 | UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC32 = 0x00008000, | ||
99 | }; | ||
100 | |||
101 | /* UCC Slow oversampling rate for transmitter (TDCR) */ | ||
102 | enum ucc_slow_tx_oversampling_rate { | ||
103 | /* 1x clock mode */ | ||
104 | UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_1 = 0x00000000, | ||
105 | /* 8x clock mode */ | ||
106 | UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_8 = 0x00010000, | ||
107 | /* 16x clock mode */ | ||
108 | UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_16 = 0x00020000, | ||
109 | /* 32x clock mode */ | ||
110 | UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_32 = 0x00030000, | ||
111 | }; | ||
112 | |||
113 | /* UCC Slow Oversampling rate for receiver (RDCR) | ||
114 | */ | ||
115 | enum ucc_slow_rx_oversampling_rate { | ||
116 | /* 1x clock mode */ | ||
117 | UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_1 = 0x00000000, | ||
118 | /* 8x clock mode */ | ||
119 | UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_8 = 0x00004000, | ||
120 | /* 16x clock mode */ | ||
121 | UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_16 = 0x00008000, | ||
122 | /* 32x clock mode */ | ||
123 | UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_32 = 0x0000c000, | ||
124 | }; | ||
125 | |||
126 | /* UCC Slow Transmitter encoding method (TENC) | ||
127 | */ | ||
128 | enum ucc_slow_tx_encoding_method { | ||
129 | UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZ = 0x00000000, | ||
130 | UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZI = 0x00000100 | ||
131 | }; | ||
132 | |||
133 | /* UCC Slow Receiver decoding method (RENC) | ||
134 | */ | ||
135 | enum ucc_slow_rx_decoding_method { | ||
136 | UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZ = 0x00000000, | ||
137 | UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZI = 0x00000800 | ||
138 | }; | ||
139 | |||
140 | /* UCC Slow Diagnostic mode (DIAG) | ||
141 | */ | ||
142 | enum ucc_slow_diag_mode { | ||
143 | UCC_SLOW_DIAG_MODE_NORMAL = 0x00000000, | ||
144 | UCC_SLOW_DIAG_MODE_LOOPBACK = 0x00000040, | ||
145 | UCC_SLOW_DIAG_MODE_ECHO = 0x00000080, | ||
146 | UCC_SLOW_DIAG_MODE_LOOPBACK_ECHO = 0x000000c0 | ||
147 | }; | ||
148 | |||
149 | struct ucc_slow_info { | ||
150 | int ucc_num; | ||
151 | enum qe_clock rx_clock; | ||
152 | enum qe_clock tx_clock; | ||
153 | struct ucc_slow *us_regs; | ||
154 | int irq; | ||
155 | u16 uccm_mask; | ||
156 | int data_mem_part; | ||
157 | int init_tx; | ||
158 | int init_rx; | ||
159 | u32 tx_bd_ring_len; | ||
160 | u32 rx_bd_ring_len; | ||
161 | int rx_interrupts; | ||
162 | int brkpt_support; | ||
163 | int grant_support; | ||
164 | int tsa; | ||
165 | int cdp; | ||
166 | int cds; | ||
167 | int ctsp; | ||
168 | int ctss; | ||
169 | int rinv; | ||
170 | int tinv; | ||
171 | int rtsm; | ||
172 | int rfw; | ||
173 | int tci; | ||
174 | int tend; | ||
175 | int tfl; | ||
176 | int txsy; | ||
177 | u16 max_rx_buf_length; | ||
178 | enum ucc_slow_transparent_tcrc tcrc; | ||
179 | enum ucc_slow_channel_protocol_mode mode; | ||
180 | enum ucc_slow_diag_mode diag; | ||
181 | enum ucc_slow_tx_oversampling_rate tdcr; | ||
182 | enum ucc_slow_rx_oversampling_rate rdcr; | ||
183 | enum ucc_slow_tx_encoding_method tenc; | ||
184 | enum ucc_slow_rx_decoding_method renc; | ||
185 | }; | ||
186 | |||
187 | struct ucc_slow_private { | ||
188 | struct ucc_slow_info *us_info; | ||
189 | struct ucc_slow *us_regs; /* a pointer to memory map of UCC regs */ | ||
190 | struct ucc_slow_pram *us_pram; /* a pointer to the parameter RAM */ | ||
191 | u32 us_pram_offset; | ||
192 | int enabled_tx; /* Whether channel is enabled for Tx (ENT) */ | ||
193 | int enabled_rx; /* Whether channel is enabled for Rx (ENR) */ | ||
194 | int stopped_tx; /* Whether channel has been stopped for Tx | ||
195 | (STOP_TX, etc.) */ | ||
196 | int stopped_rx; /* Whether channel has been stopped for Rx */ | ||
197 | struct list_head confQ; /* frames passed to chip waiting for tx */ | ||
198 | u32 first_tx_bd_mask; /* mask is used in Tx routine to save status | ||
199 | and length for first BD in a frame */ | ||
200 | u32 tx_base_offset; /* first BD in Tx BD table offset (In MURAM) */ | ||
201 | u32 rx_base_offset; /* first BD in Rx BD table offset (In MURAM) */ | ||
202 | u8 *confBd; /* next BD for confirm after Tx */ | ||
203 | u8 *tx_bd; /* next BD for new Tx request */ | ||
204 | u8 *rx_bd; /* next BD to collect after Rx */ | ||
205 | void *p_rx_frame; /* accumulating receive frame */ | ||
206 | u16 *p_ucce; /* a pointer to the event register in memory. | ||
207 | */ | ||
208 | u16 *p_uccm; /* a pointer to the mask register in memory */ | ||
209 | u16 saved_uccm; /* a saved mask for the RX Interrupt bits */ | ||
210 | #ifdef STATISTICS | ||
211 | u32 tx_frames; /* Transmitted frames counters */ | ||
212 | u32 rx_frames; /* Received frames counters (only frames | ||
213 | passed to application) */ | ||
214 | u32 rx_discarded; /* Discarded frames counters (frames that | ||
215 | were discarded by the driver due to | ||
216 | errors) */ | ||
217 | #endif /* STATISTICS */ | ||
218 | }; | ||
219 | |||
220 | /* ucc_slow_init | ||
221 | * Initializes Slow UCC according to provided parameters. | ||
222 | * | ||
223 | * us_info - (In) pointer to the slow UCC info structure. | ||
224 | * uccs_ret - (Out) pointer to the slow UCC structure. | ||
225 | */ | ||
226 | int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret); | ||
227 | |||
228 | /* ucc_slow_free | ||
229 | * Frees all resources for slow UCC. | ||
230 | * | ||
231 | * uccs - (In) pointer to the slow UCC structure. | ||
232 | */ | ||
233 | void ucc_slow_free(struct ucc_slow_private * uccs); | ||
234 | |||
235 | /* ucc_slow_enable | ||
236 | * Enables a fast UCC port. | ||
237 | * This routine enables Tx and/or Rx through the General UCC Mode Register. | ||
238 | * | ||
239 | * uccs - (In) pointer to the slow UCC structure. | ||
240 | * mode - (In) TX, RX, or both. | ||
241 | */ | ||
242 | void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode); | ||
243 | |||
244 | /* ucc_slow_disable | ||
245 | * Disables a fast UCC port. | ||
246 | * This routine disables Tx and/or Rx through the General UCC Mode Register. | ||
247 | * | ||
248 | * uccs - (In) pointer to the slow UCC structure. | ||
249 | * mode - (In) TX, RX, or both. | ||
250 | */ | ||
251 | void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode); | ||
252 | |||
253 | /* ucc_slow_poll_transmitter_now | ||
254 | * Immediately forces a poll of the transmitter for data to be sent. | ||
255 | * Typically, the hardware performs a periodic poll for data that the | ||
256 | * transmit routine has set up to be transmitted. In cases where | ||
257 | * this polling cycle is not soon enough, this optional routine can | ||
258 | * be invoked to force a poll right away, instead. Proper use for | ||
259 | * each transmission for which this functionality is desired is to | ||
260 | * call the transmit routine and then this routine right after. | ||
261 | * | ||
262 | * uccs - (In) pointer to the slow UCC structure. | ||
263 | */ | ||
264 | void ucc_slow_poll_transmitter_now(struct ucc_slow_private * uccs); | ||
265 | |||
266 | /* ucc_slow_graceful_stop_tx | ||
267 | * Smoothly stops transmission on a specified slow UCC. | ||
268 | * | ||
269 | * uccs - (In) pointer to the slow UCC structure. | ||
270 | */ | ||
271 | void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs); | ||
272 | |||
273 | /* ucc_slow_stop_tx | ||
274 | * Stops transmission on a specified slow UCC. | ||
275 | * | ||
276 | * uccs - (In) pointer to the slow UCC structure. | ||
277 | */ | ||
278 | void ucc_slow_stop_tx(struct ucc_slow_private * uccs); | ||
279 | |||
280 | /* ucc_slow_restart_x | ||
281 | * Restarts transmitting on a specified slow UCC. | ||
282 | * | ||
283 | * uccs - (In) pointer to the slow UCC structure. | ||
284 | */ | ||
285 | void ucc_slow_restart_x(struct ucc_slow_private * uccs); | ||
286 | |||
287 | u32 ucc_slow_get_qe_cr_subblock(int uccs_num); | ||
288 | |||
289 | #endif /* __UCC_SLOW_H__ */ | ||
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index 16fbe59edeb1..3da29e2d524a 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h | |||
@@ -46,18 +46,17 @@ | |||
46 | 46 | ||
47 | struct gianfar_platform_data { | 47 | struct gianfar_platform_data { |
48 | /* device specific information */ | 48 | /* device specific information */ |
49 | u32 device_flags; | 49 | u32 device_flags; |
50 | |||
51 | /* board specific information */ | 50 | /* board specific information */ |
52 | u32 board_flags; | 51 | u32 board_flags; |
53 | u32 bus_id; | 52 | u32 bus_id; |
54 | u32 phy_id; | 53 | u32 phy_id; |
55 | u8 mac_addr[6]; | 54 | u8 mac_addr[6]; |
56 | }; | 55 | }; |
57 | 56 | ||
58 | struct gianfar_mdio_data { | 57 | struct gianfar_mdio_data { |
59 | /* board specific information */ | 58 | /* board specific information */ |
60 | int irq[32]; | 59 | int irq[32]; |
61 | }; | 60 | }; |
62 | 61 | ||
63 | /* Flags related to gianfar device features */ | 62 | /* Flags related to gianfar device features */ |
@@ -76,14 +75,13 @@ struct gianfar_mdio_data { | |||
76 | 75 | ||
77 | struct fsl_i2c_platform_data { | 76 | struct fsl_i2c_platform_data { |
78 | /* device specific information */ | 77 | /* device specific information */ |
79 | u32 device_flags; | 78 | u32 device_flags; |
80 | }; | 79 | }; |
81 | 80 | ||
82 | /* Flags related to I2C device features */ | 81 | /* Flags related to I2C device features */ |
83 | #define FSL_I2C_DEV_SEPARATE_DFSRR 0x00000001 | 82 | #define FSL_I2C_DEV_SEPARATE_DFSRR 0x00000001 |
84 | #define FSL_I2C_DEV_CLOCK_5200 0x00000002 | 83 | #define FSL_I2C_DEV_CLOCK_5200 0x00000002 |
85 | 84 | ||
86 | |||
87 | enum fsl_usb2_operating_modes { | 85 | enum fsl_usb2_operating_modes { |
88 | FSL_USB2_MPH_HOST, | 86 | FSL_USB2_MPH_HOST, |
89 | FSL_USB2_DR_HOST, | 87 | FSL_USB2_DR_HOST, |
@@ -101,9 +99,9 @@ enum fsl_usb2_phy_modes { | |||
101 | 99 | ||
102 | struct fsl_usb2_platform_data { | 100 | struct fsl_usb2_platform_data { |
103 | /* board specific information */ | 101 | /* board specific information */ |
104 | enum fsl_usb2_operating_modes operating_mode; | 102 | enum fsl_usb2_operating_modes operating_mode; |
105 | enum fsl_usb2_phy_modes phy_mode; | 103 | enum fsl_usb2_phy_modes phy_mode; |
106 | unsigned int port_enables; | 104 | unsigned int port_enables; |
107 | }; | 105 | }; |
108 | 106 | ||
109 | /* Flags in fsl_usb2_mph_platform_data */ | 107 | /* Flags in fsl_usb2_mph_platform_data */ |
@@ -121,5 +119,44 @@ struct fsl_spi_platform_data { | |||
121 | u32 sysclk; | 119 | u32 sysclk; |
122 | }; | 120 | }; |
123 | 121 | ||
124 | #endif /* _FSL_DEVICE_H_ */ | 122 | /* Ethernet interface (phy management and speed) |
125 | #endif /* __KERNEL__ */ | 123 | */ |
124 | enum enet_interface { | ||
125 | ENET_10_MII, /* 10 Base T, MII interface */ | ||
126 | ENET_10_RMII, /* 10 Base T, RMII interface */ | ||
127 | ENET_10_RGMII, /* 10 Base T, RGMII interface */ | ||
128 | ENET_100_MII, /* 100 Base T, MII interface */ | ||
129 | ENET_100_RMII, /* 100 Base T, RMII interface */ | ||
130 | ENET_100_RGMII, /* 100 Base T, RGMII interface */ | ||
131 | ENET_1000_GMII, /* 1000 Base T, GMII interface */ | ||
132 | ENET_1000_RGMII, /* 1000 Base T, RGMII interface */ | ||
133 | ENET_1000_TBI, /* 1000 Base T, TBI interface */ | ||
134 | ENET_1000_RTBI /* 1000 Base T, RTBI interface */ | ||
135 | }; | ||
136 | |||
137 | struct ucc_geth_platform_data { | ||
138 | /* device specific information */ | ||
139 | u32 device_flags; | ||
140 | u32 phy_reg_addr; | ||
141 | |||
142 | /* board specific information */ | ||
143 | u32 board_flags; | ||
144 | u8 rx_clock; | ||
145 | u8 tx_clock; | ||
146 | u32 phy_id; | ||
147 | enum enet_interface phy_interface; | ||
148 | u32 phy_interrupt; | ||
149 | u8 mac_addr[6]; | ||
150 | }; | ||
151 | |||
152 | /* Flags related to UCC Gigabit Ethernet device features */ | ||
153 | #define FSL_UGETH_DEV_HAS_GIGABIT 0x00000001 | ||
154 | #define FSL_UGETH_DEV_HAS_COALESCE 0x00000002 | ||
155 | #define FSL_UGETH_DEV_HAS_RMON 0x00000004 | ||
156 | |||
157 | /* Flags in ucc_geth_platform_data */ | ||
158 | #define FSL_UGETH_BRD_HAS_PHY_INTR 0x00000001 | ||
159 | /* if not set use a timer */ | ||
160 | |||
161 | #endif /* _FSL_DEVICE_H_ */ | ||
162 | #endif /* __KERNEL__ */ | ||