aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/syslib/ppc85xx_rio.c
diff options
context:
space:
mode:
authorMatt Porter <mporter@kernel.crashing.org>2005-11-07 04:00:19 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 10:53:47 -0500
commit2b0c28d7f8846f80a436093e906f5175d1fa8f55 (patch)
treece704dd11d562b2f5473b896153e0263e9d3906b /arch/ppc/syslib/ppc85xx_rio.c
parentfa78cc51794912b7e6ee98cd823fcc84cf79d04a (diff)
[PATCH] RapidIO support: ppc32
Adds PPC32 RIO support. Init code for the MPC85xx RIO ports and glue for the STx GP3 board to use it. Signed-off-by: Matt Porter <mporter@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc/syslib/ppc85xx_rio.c')
-rw-r--r--arch/ppc/syslib/ppc85xx_rio.c932
1 files changed, 932 insertions, 0 deletions
diff --git a/arch/ppc/syslib/ppc85xx_rio.c b/arch/ppc/syslib/ppc85xx_rio.c
new file mode 100644
index 000000000000..9d09c2715e0a
--- /dev/null
+++ b/arch/ppc/syslib/ppc85xx_rio.c
@@ -0,0 +1,932 @@
1/*
2 * MPC85xx RapidIO support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/config.h>
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/types.h>
17#include <linux/dma-mapping.h>
18#include <linux/interrupt.h>
19#include <linux/rio.h>
20#include <linux/rio_drv.h>
21
22#include <asm/io.h>
23
24#define RIO_REGS_BASE (CCSRBAR + 0xc0000)
25#define RIO_ATMU_REGS_OFFSET 0x10c00
26#define RIO_MSG_REGS_OFFSET 0x11000
27#define RIO_MAINT_WIN_SIZE 0x400000
28#define RIO_DBELL_WIN_SIZE 0x1000
29
30#define RIO_MSG_OMR_MUI 0x00000002
31#define RIO_MSG_OSR_TE 0x00000080
32#define RIO_MSG_OSR_QOI 0x00000020
33#define RIO_MSG_OSR_QFI 0x00000010
34#define RIO_MSG_OSR_MUB 0x00000004
35#define RIO_MSG_OSR_EOMI 0x00000002
36#define RIO_MSG_OSR_QEI 0x00000001
37
38#define RIO_MSG_IMR_MI 0x00000002
39#define RIO_MSG_ISR_TE 0x00000080
40#define RIO_MSG_ISR_QFI 0x00000010
41#define RIO_MSG_ISR_DIQI 0x00000001
42
43#define RIO_MSG_DESC_SIZE 32
44#define RIO_MSG_BUFFER_SIZE 4096
45#define RIO_MIN_TX_RING_SIZE 2
46#define RIO_MAX_TX_RING_SIZE 2048
47#define RIO_MIN_RX_RING_SIZE 2
48#define RIO_MAX_RX_RING_SIZE 2048
49
50#define DOORBELL_DMR_DI 0x00000002
51#define DOORBELL_DSR_TE 0x00000080
52#define DOORBELL_DSR_QFI 0x00000010
53#define DOORBELL_DSR_DIQI 0x00000001
54#define DOORBELL_TID_OFFSET 0x03
55#define DOORBELL_SID_OFFSET 0x05
56#define DOORBELL_INFO_OFFSET 0x06
57
58#define DOORBELL_MESSAGE_SIZE 0x08
59#define DBELL_SID(x) (*(u8 *)(x + DOORBELL_SID_OFFSET))
60#define DBELL_TID(x) (*(u8 *)(x + DOORBELL_TID_OFFSET))
61#define DBELL_INF(x) (*(u16 *)(x + DOORBELL_INFO_OFFSET))
62
63#define is_power_of_2(x) (((x) & ((x) - 1)) == 0)
64
65struct rio_atmu_regs {
66 u32 rowtar;
67 u32 pad1;
68 u32 rowbar;
69 u32 pad2;
70 u32 rowar;
71 u32 pad3[3];
72};
73
74struct rio_msg_regs {
75 u32 omr;
76 u32 osr;
77 u32 pad1;
78 u32 odqdpar;
79 u32 pad2;
80 u32 osar;
81 u32 odpr;
82 u32 odatr;
83 u32 odcr;
84 u32 pad3;
85 u32 odqepar;
86 u32 pad4[13];
87 u32 imr;
88 u32 isr;
89 u32 pad5;
90 u32 ifqdpar;
91 u32 pad6;
92 u32 ifqepar;
93 u32 pad7[250];
94 u32 dmr;
95 u32 dsr;
96 u32 pad8;
97 u32 dqdpar;
98 u32 pad9;
99 u32 dqepar;
100 u32 pad10[26];
101 u32 pwmr;
102 u32 pwsr;
103 u32 pad11;
104 u32 pwqbar;
105};
106
107struct rio_tx_desc {
108 u32 res1;
109 u32 saddr;
110 u32 dport;
111 u32 dattr;
112 u32 res2;
113 u32 res3;
114 u32 dwcnt;
115 u32 res4;
116};
117
118static u32 regs_win;
119static struct rio_atmu_regs *atmu_regs;
120static struct rio_atmu_regs *maint_atmu_regs;
121static struct rio_atmu_regs *dbell_atmu_regs;
122static u32 dbell_win;
123static u32 maint_win;
124static struct rio_msg_regs *msg_regs;
125
126static struct rio_dbell_ring {
127 void *virt;
128 dma_addr_t phys;
129} dbell_ring;
130
131static struct rio_msg_tx_ring {
132 void *virt;
133 dma_addr_t phys;
134 void *virt_buffer[RIO_MAX_TX_RING_SIZE];
135 dma_addr_t phys_buffer[RIO_MAX_TX_RING_SIZE];
136 int tx_slot;
137 int size;
138} msg_tx_ring;
139
140static struct rio_msg_rx_ring {
141 void *virt;
142 dma_addr_t phys;
143 void *virt_buffer[RIO_MAX_RX_RING_SIZE];
144 int rx_slot;
145 int size;
146} msg_rx_ring;
147
148/**
149 * mpc85xx_rio_doorbell_send - Send a MPC85xx doorbell message
150 * @index: ID of RapidIO interface
151 * @destid: Destination ID of target device
152 * @data: 16-bit info field of RapidIO doorbell message
153 *
154 * Sends a MPC85xx doorbell message. Returns %0 on success or
155 * %-EINVAL on failure.
156 */
157static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
158{
159 pr_debug("mpc85xx_doorbell_send: index %d destid %4.4x data %4.4x\n",
160 index, destid, data);
161 out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22);
162 out_be16((void *)(dbell_win), data);
163
164 return 0;
165}
166
167/**
168 * mpc85xx_local_config_read - Generate a MPC85xx local config space read
169 * @index: ID of RapdiIO interface
170 * @offset: Offset into configuration space
171 * @len: Length (in bytes) of the maintenance transaction
172 * @data: Value to be read into
173 *
174 * Generates a MPC85xx local configuration space read. Returns %0 on
175 * success or %-EINVAL on failure.
176 */
177static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
178{
179 pr_debug("mpc85xx_local_config_read: index %d offset %8.8x\n", index,
180 offset);
181 *data = in_be32((void *)(regs_win + offset));
182
183 return 0;
184}
185
186/**
187 * mpc85xx_local_config_write - Generate a MPC85xx local config space write
188 * @index: ID of RapdiIO interface
189 * @offset: Offset into configuration space
190 * @len: Length (in bytes) of the maintenance transaction
191 * @data: Value to be written
192 *
193 * Generates a MPC85xx local configuration space write. Returns %0 on
194 * success or %-EINVAL on failure.
195 */
196static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
197{
198 pr_debug
199 ("mpc85xx_local_config_write: index %d offset %8.8x data %8.8x\n",
200 index, offset, data);
201 out_be32((void *)(regs_win + offset), data);
202
203 return 0;
204}
205
206/**
207 * mpc85xx_rio_config_read - Generate a MPC85xx read maintenance transaction
208 * @index: ID of RapdiIO interface
209 * @destid: Destination ID of transaction
210 * @hopcount: Number of hops to target device
211 * @offset: Offset into configuration space
212 * @len: Length (in bytes) of the maintenance transaction
213 * @val: Location to be read into
214 *
215 * Generates a MPC85xx read maintenance transaction. Returns %0 on
216 * success or %-EINVAL on failure.
217 */
218static int
219mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
220 u32 * val)
221{
222 u8 *data;
223
224 pr_debug
225 ("mpc85xx_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
226 index, destid, hopcount, offset, len);
227 out_be32((void *)&maint_atmu_regs->rowtar,
228 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
229
230 data = (u8 *) maint_win + offset;
231 switch (len) {
232 case 1:
233 *val = in_8((u8 *) data);
234 break;
235 case 2:
236 *val = in_be16((u16 *) data);
237 break;
238 default:
239 *val = in_be32((u32 *) data);
240 break;
241 }
242
243 return 0;
244}
245
246/**
247 * mpc85xx_rio_config_write - Generate a MPC85xx write maintenance transaction
248 * @index: ID of RapdiIO interface
249 * @destid: Destination ID of transaction
250 * @hopcount: Number of hops to target device
251 * @offset: Offset into configuration space
252 * @len: Length (in bytes) of the maintenance transaction
253 * @val: Value to be written
254 *
255 * Generates an MPC85xx write maintenance transaction. Returns %0 on
256 * success or %-EINVAL on failure.
257 */
258static int
259mpc85xx_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
260 int len, u32 val)
261{
262 u8 *data;
263 pr_debug
264 ("mpc85xx_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
265 index, destid, hopcount, offset, len, val);
266 out_be32((void *)&maint_atmu_regs->rowtar,
267 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
268
269 data = (u8 *) maint_win + offset;
270 switch (len) {
271 case 1:
272 out_8((u8 *) data, val);
273 break;
274 case 2:
275 out_be16((u16 *) data, val);
276 break;
277 default:
278 out_be32((u32 *) data, val);
279 break;
280 }
281
282 return 0;
283}
284
285/**
286 * rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue
287 * @mport: Master port with outbound message queue
288 * @rdev: Target of outbound message
289 * @mbox: Outbound mailbox
290 * @buffer: Message to add to outbound queue
291 * @len: Length of message
292 *
293 * Adds the @buffer message to the MPC85xx outbound message queue. Returns
294 * %0 on success or %-EINVAL on failure.
295 */
296int
297rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
298 void *buffer, size_t len)
299{
300 u32 omr;
301 struct rio_tx_desc *desc =
302 (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot;
303 int ret = 0;
304
305 pr_debug
306 ("RIO: rio_hw_add_outb_message(): destid %4.4x mbox %d buffer %8.8x len %8.8x\n",
307 rdev->destid, mbox, (int)buffer, len);
308
309 if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) {
310 ret = -EINVAL;
311 goto out;
312 }
313
314 /* Copy and clear rest of buffer */
315 memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len);
316 if (len < (RIO_MAX_MSG_SIZE - 4))
317 memset((void *)((u32) msg_tx_ring.
318 virt_buffer[msg_tx_ring.tx_slot] + len), 0,
319 RIO_MAX_MSG_SIZE - len);
320
321 /* Set mbox field for message */
322 desc->dport = mbox & 0x3;
323
324 /* Enable EOMI interrupt, set priority, and set destid */
325 desc->dattr = 0x28000000 | (rdev->destid << 2);
326
327 /* Set transfer size aligned to next power of 2 (in double words) */
328 desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len);
329
330 /* Set snooping and source buffer address */
331 desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot];
332
333 /* Increment enqueue pointer */
334 omr = in_be32((void *)&msg_regs->omr);
335 out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI);
336
337 /* Go to next descriptor */
338 if (++msg_tx_ring.tx_slot == msg_tx_ring.size)
339 msg_tx_ring.tx_slot = 0;
340
341 out:
342 return ret;
343}
344
345EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
346
347/**
348 * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler
349 * @irq: Linux interrupt number
350 * @dev_instance: Pointer to interrupt-specific data
351 * @regs: Register context
352 *
353 * Handles outbound message interrupts. Executes a register outbound
354 * mailbox event handler and acks the interrupt occurence.
355 */
356static irqreturn_t
357mpc85xx_rio_tx_handler(int irq, void *dev_instance, struct pt_regs *regs)
358{
359 int osr;
360 struct rio_mport *port = (struct rio_mport *)dev_instance;
361
362 osr = in_be32((void *)&msg_regs->osr);
363
364 if (osr & RIO_MSG_OSR_TE) {
365 pr_info("RIO: outbound message transmission error\n");
366 out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE);
367 goto out;
368 }
369
370 if (osr & RIO_MSG_OSR_QOI) {
371 pr_info("RIO: outbound message queue overflow\n");
372 out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI);
373 goto out;
374 }
375
376 if (osr & RIO_MSG_OSR_EOMI) {
377 u32 dqp = in_be32((void *)&msg_regs->odqdpar);
378 int slot = (dqp - msg_tx_ring.phys) >> 5;
379 port->outb_msg[0].mcback(port, -1, slot);
380
381 /* Ack the end-of-message interrupt */
382 out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI);
383 }
384
385 out:
386 return IRQ_HANDLED;
387}
388
389/**
390 * rio_open_outb_mbox - Initialize MPC85xx outbound mailbox
391 * @mport: Master port implementing the outbound message unit
392 * @mbox: Mailbox to open
393 * @entries: Number of entries in the outbound mailbox ring
394 *
395 * Initializes buffer ring, request the outbound message interrupt,
396 * and enables the outbound message unit. Returns %0 on success and
397 * %-EINVAL or %-ENOMEM on failure.
398 */
399int rio_open_outb_mbox(struct rio_mport *mport, int mbox, int entries)
400{
401 int i, j, rc = 0;
402
403 if ((entries < RIO_MIN_TX_RING_SIZE) ||
404 (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) {
405 rc = -EINVAL;
406 goto out;
407 }
408
409 /* Initialize shadow copy ring */
410 msg_tx_ring.size = entries;
411
412 for (i = 0; i < msg_tx_ring.size; i++) {
413 if (!
414 (msg_tx_ring.virt_buffer[i] =
415 dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE,
416 &msg_tx_ring.phys_buffer[i],
417 GFP_KERNEL))) {
418 rc = -ENOMEM;
419 for (j = 0; j < msg_tx_ring.size; j++)
420 if (msg_tx_ring.virt_buffer[j])
421 dma_free_coherent(NULL,
422 RIO_MSG_BUFFER_SIZE,
423 msg_tx_ring.
424 virt_buffer[j],
425 msg_tx_ring.
426 phys_buffer[j]);
427 goto out;
428 }
429 }
430
431 /* Initialize outbound message descriptor ring */
432 if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL,
433 msg_tx_ring.size *
434 RIO_MSG_DESC_SIZE,
435 &msg_tx_ring.phys,
436 GFP_KERNEL))) {
437 rc = -ENOMEM;
438 goto out_dma;
439 }
440 memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE);
441 msg_tx_ring.tx_slot = 0;
442
443 /* Point dequeue/enqueue pointers at first entry in ring */
444 out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys);
445 out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys);
446
447 /* Configure for snooping */
448 out_be32((void *)&msg_regs->osar, 0x00000004);
449
450 /* Clear interrupt status */
451 out_be32((void *)&msg_regs->osr, 0x000000b3);
452
453 /* Hook up outbound message handler */
454 if ((rc =
455 request_irq(MPC85xx_IRQ_RIO_TX, mpc85xx_rio_tx_handler, 0,
456 "msg_tx", (void *)mport)) < 0)
457 goto out_irq;
458
459 /*
460 * Configure outbound message unit
461 * Snooping
462 * Interrupts (all enabled, except QEIE)
463 * Chaining mode
464 * Disable
465 */
466 out_be32((void *)&msg_regs->omr, 0x00100220);
467
468 /* Set number of entries */
469 out_be32((void *)&msg_regs->omr,
470 in_be32((void *)&msg_regs->omr) |
471 ((get_bitmask_order(entries) - 2) << 12));
472
473 /* Now enable the unit */
474 out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1);
475
476 out:
477 return rc;
478
479 out_irq:
480 dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
481 msg_tx_ring.virt, msg_tx_ring.phys);
482
483 out_dma:
484 for (i = 0; i < msg_tx_ring.size; i++)
485 dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
486 msg_tx_ring.virt_buffer[i],
487 msg_tx_ring.phys_buffer[i]);
488
489 return rc;
490}
491
492/**
493 * rio_close_outb_mbox - Shut down MPC85xx outbound mailbox
494 * @mport: Master port implementing the outbound message unit
495 * @mbox: Mailbox to close
496 *
497 * Disables the outbound message unit, free all buffers, and
498 * frees the outbound message interrupt.
499 */
500void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
501{
502 /* Disable inbound message unit */
503 out_be32((void *)&msg_regs->omr, 0);
504
505 /* Free ring */
506 dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
507 msg_tx_ring.virt, msg_tx_ring.phys);
508
509 /* Free interrupt */
510 free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport);
511}
512
513/**
514 * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler
515 * @irq: Linux interrupt number
516 * @dev_instance: Pointer to interrupt-specific data
517 * @regs: Register context
518 *
519 * Handles inbound message interrupts. Executes a registered inbound
520 * mailbox event handler and acks the interrupt occurence.
521 */
522static irqreturn_t
523mpc85xx_rio_rx_handler(int irq, void *dev_instance, struct pt_regs *regs)
524{
525 int isr;
526 struct rio_mport *port = (struct rio_mport *)dev_instance;
527
528 isr = in_be32((void *)&msg_regs->isr);
529
530 if (isr & RIO_MSG_ISR_TE) {
531 pr_info("RIO: inbound message reception error\n");
532 out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE);
533 goto out;
534 }
535
536 /* XXX Need to check/dispatch until queue empty */
537 if (isr & RIO_MSG_ISR_DIQI) {
538 /*
539 * We implement *only* mailbox 0, but can receive messages
540 * for any mailbox/letter to that mailbox destination. So,
541 * make the callback with an unknown/invalid mailbox number
542 * argument.
543 */
544 port->inb_msg[0].mcback(port, -1, -1);
545
546 /* Ack the queueing interrupt */
547 out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI);
548 }
549
550 out:
551 return IRQ_HANDLED;
552}
553
554/**
555 * rio_open_inb_mbox - Initialize MPC85xx inbound mailbox
556 * @mport: Master port implementing the inbound message unit
557 * @mbox: Mailbox to open
558 * @entries: Number of entries in the inbound mailbox ring
559 *
560 * Initializes buffer ring, request the inbound message interrupt,
561 * and enables the inbound message unit. Returns %0 on success
562 * and %-EINVAL or %-ENOMEM on failure.
563 */
564int rio_open_inb_mbox(struct rio_mport *mport, int mbox, int entries)
565{
566 int i, rc = 0;
567
568 if ((entries < RIO_MIN_RX_RING_SIZE) ||
569 (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) {
570 rc = -EINVAL;
571 goto out;
572 }
573
574 /* Initialize client buffer ring */
575 msg_rx_ring.size = entries;
576 msg_rx_ring.rx_slot = 0;
577 for (i = 0; i < msg_rx_ring.size; i++)
578 msg_rx_ring.virt_buffer[i] = NULL;
579
580 /* Initialize inbound message ring */
581 if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL,
582 msg_rx_ring.size *
583 RIO_MAX_MSG_SIZE,
584 &msg_rx_ring.phys,
585 GFP_KERNEL))) {
586 rc = -ENOMEM;
587 goto out;
588 }
589
590 /* Point dequeue/enqueue pointers at first entry in ring */
591 out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys);
592 out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys);
593
594 /* Clear interrupt status */
595 out_be32((void *)&msg_regs->isr, 0x00000091);
596
597 /* Hook up inbound message handler */
598 if ((rc =
599 request_irq(MPC85xx_IRQ_RIO_RX, mpc85xx_rio_rx_handler, 0,
600 "msg_rx", (void *)mport)) < 0) {
601 dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
602 msg_tx_ring.virt_buffer[i],
603 msg_tx_ring.phys_buffer[i]);
604 goto out;
605 }
606
607 /*
608 * Configure inbound message unit:
609 * Snooping
610 * 4KB max message size
611 * Unmask all interrupt sources
612 * Disable
613 */
614 out_be32((void *)&msg_regs->imr, 0x001b0060);
615
616 /* Set number of queue entries */
617 out_be32((void *)&msg_regs->imr,
618 in_be32((void *)&msg_regs->imr) |
619 ((get_bitmask_order(entries) - 2) << 12));
620
621 /* Now enable the unit */
622 out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1);
623
624 out:
625 return rc;
626}
627
628/**
629 * rio_close_inb_mbox - Shut down MPC85xx inbound mailbox
630 * @mport: Master port implementing the inbound message unit
631 * @mbox: Mailbox to close
632 *
633 * Disables the inbound message unit, free all buffers, and
634 * frees the inbound message interrupt.
635 */
636void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
637{
638 /* Disable inbound message unit */
639 out_be32((void *)&msg_regs->imr, 0);
640
641 /* Free ring */
642 dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE,
643 msg_rx_ring.virt, msg_rx_ring.phys);
644
645 /* Free interrupt */
646 free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport);
647}
648
649/**
650 * rio_hw_add_inb_buffer - Add buffer to the MPC85xx inbound message queue
651 * @mport: Master port implementing the inbound message unit
652 * @mbox: Inbound mailbox number
653 * @buf: Buffer to add to inbound queue
654 *
655 * Adds the @buf buffer to the MPC85xx inbound message queue. Returns
656 * %0 on success or %-EINVAL on failure.
657 */
658int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
659{
660 int rc = 0;
661
662 pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n",
663 msg_rx_ring.rx_slot);
664
665 if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) {
666 printk(KERN_ERR
667 "RIO: error adding inbound buffer %d, buffer exists\n",
668 msg_rx_ring.rx_slot);
669 rc = -EINVAL;
670 goto out;
671 }
672
673 msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf;
674 if (++msg_rx_ring.rx_slot == msg_rx_ring.size)
675 msg_rx_ring.rx_slot = 0;
676
677 out:
678 return rc;
679}
680
681EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer);
682
683/**
684 * rio_hw_get_inb_message - Fetch inbound message from the MPC85xx message unit
685 * @mport: Master port implementing the inbound message unit
686 * @mbox: Inbound mailbox number
687 *
688 * Gets the next available inbound message from the inbound message queue.
689 * A pointer to the message is returned on success or NULL on failure.
690 */
691void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
692{
693 u32 imr;
694 u32 phys_buf, virt_buf;
695 void *buf = NULL;
696 int buf_idx;
697
698 phys_buf = in_be32((void *)&msg_regs->ifqdpar);
699
700 /* If no more messages, then bail out */
701 if (phys_buf == in_be32((void *)&msg_regs->ifqepar))
702 goto out2;
703
704 virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys);
705 buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
706 buf = msg_rx_ring.virt_buffer[buf_idx];
707
708 if (!buf) {
709 printk(KERN_ERR
710 "RIO: inbound message copy failed, no buffers\n");
711 goto out1;
712 }
713
714 /* Copy max message size, caller is expected to allocate that big */
715 memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE);
716
717 /* Clear the available buffer */
718 msg_rx_ring.virt_buffer[buf_idx] = NULL;
719
720 out1:
721 imr = in_be32((void *)&msg_regs->imr);
722 out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI);
723
724 out2:
725 return buf;
726}
727
728EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
729
730/**
731 * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler
732 * @irq: Linux interrupt number
733 * @dev_instance: Pointer to interrupt-specific data
734 * @regs: Register context
735 *
736 * Handles doorbell interrupts. Parses a list of registered
737 * doorbell event handlers and executes a matching event handler.
738 */
739static irqreturn_t
740mpc85xx_rio_dbell_handler(int irq, void *dev_instance, struct pt_regs *regs)
741{
742 int dsr;
743 struct rio_mport *port = (struct rio_mport *)dev_instance;
744
745 dsr = in_be32((void *)&msg_regs->dsr);
746
747 if (dsr & DOORBELL_DSR_TE) {
748 pr_info("RIO: doorbell reception error\n");
749 out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE);
750 goto out;
751 }
752
753 if (dsr & DOORBELL_DSR_QFI) {
754 pr_info("RIO: doorbell queue full\n");
755 out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI);
756 goto out;
757 }
758
759 /* XXX Need to check/dispatch until queue empty */
760 if (dsr & DOORBELL_DSR_DIQI) {
761 u32 dmsg =
762 (u32) dbell_ring.virt +
763 (in_be32((void *)&msg_regs->dqdpar) & 0xfff);
764 u32 dmr;
765 struct rio_dbell *dbell;
766 int found = 0;
767
768 pr_debug
769 ("RIO: processing doorbell, sid %2.2x tid %2.2x info %4.4x\n",
770 DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
771
772 list_for_each_entry(dbell, &port->dbells, node) {
773 if ((dbell->res->start <= DBELL_INF(dmsg)) &&
774 (dbell->res->end >= DBELL_INF(dmsg))) {
775 found = 1;
776 break;
777 }
778 }
779 if (found) {
780 dbell->dinb(port, DBELL_SID(dmsg), DBELL_TID(dmsg),
781 DBELL_INF(dmsg));
782 } else {
783 pr_debug
784 ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n",
785 DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
786 }
787 dmr = in_be32((void *)&msg_regs->dmr);
788 out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI);
789 out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI);
790 }
791
792 out:
793 return IRQ_HANDLED;
794}
795
796/**
797 * mpc85xx_rio_doorbell_init - MPC85xx doorbell interface init
798 * @mport: Master port implementing the inbound doorbell unit
799 *
800 * Initializes doorbell unit hardware and inbound DMA buffer
801 * ring. Called from mpc85xx_rio_setup(). Returns %0 on success
802 * or %-ENOMEM on failure.
803 */
804static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
805{
806 int rc = 0;
807
808 /* Map outbound doorbell window immediately after maintenance window */
809 if (!(dbell_win =
810 (u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE,
811 RIO_DBELL_WIN_SIZE))) {
812 printk(KERN_ERR
813 "RIO: unable to map outbound doorbell window\n");
814 rc = -ENOMEM;
815 goto out;
816 }
817
818 /* Initialize inbound doorbells */
819 if (!(dbell_ring.virt = dma_alloc_coherent(NULL,
820 512 * DOORBELL_MESSAGE_SIZE,
821 &dbell_ring.phys,
822 GFP_KERNEL))) {
823 printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n");
824 rc = -ENOMEM;
825 iounmap((void *)dbell_win);
826 goto out;
827 }
828
829 /* Point dequeue/enqueue pointers at first entry in ring */
830 out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys);
831 out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys);
832
833 /* Clear interrupt status */
834 out_be32((void *)&msg_regs->dsr, 0x00000091);
835
836 /* Hook up doorbell handler */
837 if ((rc =
838 request_irq(MPC85xx_IRQ_RIO_BELL, mpc85xx_rio_dbell_handler, 0,
839 "dbell_rx", (void *)mport) < 0)) {
840 iounmap((void *)dbell_win);
841 dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
842 dbell_ring.virt, dbell_ring.phys);
843 printk(KERN_ERR
844 "MPC85xx RIO: unable to request inbound doorbell irq");
845 goto out;
846 }
847
848 /* Configure doorbells for snooping, 512 entries, and enable */
849 out_be32((void *)&msg_regs->dmr, 0x00108161);
850
851 out:
852 return rc;
853}
854
855static char *cmdline = NULL;
856
857static int mpc85xx_rio_get_hdid(int index)
858{
859 /* XXX Need to parse multiple entries in some format */
860 if (!cmdline)
861 return -1;
862
863 return simple_strtol(cmdline, NULL, 0);
864}
865
866static int mpc85xx_rio_get_cmdline(char *s)
867{
868 if (!s)
869 return 0;
870
871 cmdline = s;
872 return 1;
873}
874
875__setup("riohdid=", mpc85xx_rio_get_cmdline);
876
877/**
878 * mpc85xx_rio_setup - Setup MPC85xx RapidIO interface
879 * @law_start: Starting physical address of RapidIO LAW
880 * @law_size: Size of RapidIO LAW
881 *
882 * Initializes MPC85xx RapidIO hardware interface, configures
883 * master port with system-specific info, and registers the
884 * master port with the RapidIO subsystem.
885 */
886void mpc85xx_rio_setup(int law_start, int law_size)
887{
888 struct rio_ops *ops;
889 struct rio_mport *port;
890
891 ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
892 ops->lcread = mpc85xx_local_config_read;
893 ops->lcwrite = mpc85xx_local_config_write;
894 ops->cread = mpc85xx_rio_config_read;
895 ops->cwrite = mpc85xx_rio_config_write;
896 ops->dsend = mpc85xx_rio_doorbell_send;
897
898 port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL);
899 port->id = 0;
900 port->index = 0;
901 INIT_LIST_HEAD(&port->dbells);
902 port->iores.start = law_start;
903 port->iores.end = law_start + law_size;
904 port->iores.flags = IORESOURCE_MEM;
905
906 rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
907 rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
908 rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
909 strcpy(port->name, "RIO0 mport");
910
911 port->ops = ops;
912 port->host_deviceid = mpc85xx_rio_get_hdid(port->id);
913
914 rio_register_mport(port);
915
916 regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000);
917 atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET);
918 maint_atmu_regs = atmu_regs + 1;
919 dbell_atmu_regs = atmu_regs + 2;
920 msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET);
921
922 /* Configure maintenance transaction window */
923 out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000);
924 out_be32((void *)&maint_atmu_regs->rowar, 0x80077015);
925
926 maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE);
927
928 /* Configure outbound doorbell window */
929 out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400);
930 out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b);
931 mpc85xx_rio_doorbell_init(port);
932}