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