2 * Core maple bus functionality
4 * Copyright (C) 2007 Adrian McMenamin
6 * Based on 2.4 code by:
8 * Copyright (C) 2000-2001 YAEGASHI Takeshi
9 * Copyright (C) 2001 M. R. Brown
10 * Copyright (C) 2001 Paul Mundt
14 * This file is subject to the terms and conditions of the GNU General Public
15 * License. See the file "COPYING" in the main directory of this archive
18 #include <linux/init.h>
19 #include <linux/kernel.h>
20 #include <linux/device.h>
21 #include <linux/module.h>
22 #include <linux/interrupt.h>
23 #include <linux/list.h>
25 #include <linux/slab.h>
26 #include <linux/maple.h>
27 #include <linux/dma-mapping.h>
28 #include <asm/cacheflush.h>
31 #include <asm/mach/dma.h>
32 #include <asm/mach/sysasic.h>
33 #include <asm/mach/maple.h>
35 MODULE_AUTHOR("Yaegshi Takeshi, Paul Mundt, M.R. Brown, Adrian McMenamin");
36 MODULE_DESCRIPTION("Maple bus driver for Dreamcast");
37 MODULE_LICENSE("GPL v2");
38 MODULE_SUPPORTED_DEVICE("{{SEGA, Dreamcast/Maple}}");
40 static void maple_dma_handler(struct work_struct
*work
);
41 static void maple_vblank_handler(struct work_struct
*work
);
43 static DECLARE_WORK(maple_dma_process
, maple_dma_handler
);
44 static DECLARE_WORK(maple_vblank_process
, maple_vblank_handler
);
46 static LIST_HEAD(maple_waitq
);
47 static LIST_HEAD(maple_sentq
);
49 static DEFINE_MUTEX(maple_list_lock
);
51 static struct maple_driver maple_dummy_driver
;
52 static struct device maple_bus
;
53 static int subdevice_map
[MAPLE_PORTS
];
54 static unsigned long *maple_sendbuf
, *maple_sendptr
, *maple_lastptr
;
55 static unsigned long maple_pnp_time
;
56 static int started
, scanning
, liststatus
;
57 static struct kmem_cache
*maple_queue_cache
;
59 struct maple_device_specify
{
65 * maple_driver_register - register a device driver
66 * automatically makes the driver bus a maple bus
67 * @drv: the driver to be registered
69 int maple_driver_register(struct device_driver
*drv
)
73 drv
->bus
= &maple_bus_type
;
74 return driver_register(drv
);
76 EXPORT_SYMBOL_GPL(maple_driver_register
);
78 /* set hardware registers to enable next round of dma */
79 static void maplebus_dma_reset(void)
81 ctrl_outl(MAPLE_MAGIC
, MAPLE_RESET
);
82 /* set trig type to 0 for software trigger, 1 for hardware (VBLANK) */
83 ctrl_outl(1, MAPLE_TRIGTYPE
);
84 ctrl_outl(MAPLE_2MBPS
| MAPLE_TIMEOUT(50000), MAPLE_SPEED
);
85 ctrl_outl(PHYSADDR(maple_sendbuf
), MAPLE_DMAADDR
);
86 ctrl_outl(1, MAPLE_ENABLE
);
90 * maple_getcond_callback - setup handling MAPLE_COMMAND_GETCOND
91 * @dev: device responding
92 * @callback: handler callback
93 * @interval: interval in jiffies between callbacks
94 * @function: the function code for the device
96 void maple_getcond_callback(struct maple_device
*dev
,
97 void (*callback
) (struct mapleq
* mq
),
98 unsigned long interval
, unsigned long function
)
100 dev
->callback
= callback
;
101 dev
->interval
= interval
;
102 dev
->function
= cpu_to_be32(function
);
105 EXPORT_SYMBOL_GPL(maple_getcond_callback
);
107 static int maple_dma_done(void)
109 return (ctrl_inl(MAPLE_STATE
) & 1) == 0;
112 static void maple_release_device(struct device
*dev
)
115 kfree(dev
->type
->name
);
121 * maple_add_packet - add a single instruction to the queue
122 * @mq: instruction to add to waiting queue
124 void maple_add_packet(struct mapleq
*mq
)
126 mutex_lock(&maple_list_lock
);
127 list_add(&mq
->list
, &maple_waitq
);
128 mutex_unlock(&maple_list_lock
);
130 EXPORT_SYMBOL_GPL(maple_add_packet
);
132 static struct mapleq
*maple_allocq(struct maple_device
*dev
)
136 mq
= kmalloc(sizeof(*mq
), GFP_KERNEL
);
141 mq
->recvbufdcsp
= kmem_cache_zalloc(maple_queue_cache
, GFP_KERNEL
);
142 mq
->recvbuf
= (void *) P2SEGADDR(mq
->recvbufdcsp
);
151 static struct maple_device
*maple_alloc_dev(int port
, int unit
)
153 struct maple_device
*dev
;
155 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
161 dev
->mq
= maple_allocq(dev
);
171 static void maple_free_dev(struct maple_device
*mdev
)
176 kmem_cache_free(maple_queue_cache
, mdev
->mq
->recvbufdcsp
);
182 /* process the command queue into a maple command block
183 * terminating command has bit 32 of first long set to 0
185 static void maple_build_block(struct mapleq
*mq
)
187 int port
, unit
, from
, to
, len
;
188 unsigned long *lsendbuf
= mq
->sendbuf
;
190 port
= mq
->dev
->port
& 3;
191 unit
= mq
->dev
->unit
;
194 to
= (port
<< 6) | (unit
> 0 ? (1 << (unit
- 1)) & 0x1f : 0x20);
196 *maple_lastptr
&= 0x7fffffff;
197 maple_lastptr
= maple_sendptr
;
199 *maple_sendptr
++ = (port
<< 16) | len
| 0x80000000;
200 *maple_sendptr
++ = PHYSADDR(mq
->recvbuf
);
202 mq
->command
| (to
<< 8) | (from
<< 16) | (len
<< 24);
205 *maple_sendptr
++ = *lsendbuf
++;
208 /* build up command queue */
209 static void maple_send(void)
213 struct mapleq
*mq
, *nmq
;
215 if (!list_empty(&maple_sentq
))
217 if (list_empty(&maple_waitq
) || !maple_dma_done())
220 maple_sendptr
= maple_lastptr
= maple_sendbuf
;
221 list_for_each_entry_safe(mq
, nmq
, &maple_waitq
, list
) {
222 maple_build_block(mq
);
223 list_move(&mq
->list
, &maple_sentq
);
224 if (maple_packets
++ > MAPLE_MAXPACKETS
)
227 if (maple_packets
> 0) {
228 for (i
= 0; i
< (1 << MAPLE_DMA_PAGES
); i
++)
229 dma_cache_sync(0, maple_sendbuf
+ i
* PAGE_SIZE
,
230 PAGE_SIZE
, DMA_BIDIRECTIONAL
);
234 static int attach_matching_maple_driver(struct device_driver
*driver
,
237 struct maple_driver
*maple_drv
;
238 struct maple_device
*mdev
;
241 maple_drv
= to_maple_driver(driver
);
242 if (mdev
->devinfo
.function
& be32_to_cpu(maple_drv
->function
)) {
243 if (maple_drv
->connect(mdev
) == 0) {
244 mdev
->driver
= maple_drv
;
251 static void maple_detach_driver(struct maple_device
*mdev
)
256 if (mdev
->driver
->disconnect
)
257 mdev
->driver
->disconnect(mdev
);
260 if (mdev
->registered
) {
261 maple_release_device(&mdev
->dev
);
262 device_unregister(&mdev
->dev
);
264 mdev
->registered
= 0;
265 maple_free_dev(mdev
);
268 /* process initial MAPLE_COMMAND_DEVINFO for each device or port */
269 static void maple_attach_driver(struct maple_device
*dev
)
274 unsigned long function
;
277 recvbuf
= dev
->mq
->recvbuf
;
278 memcpy(&dev
->devinfo
, recvbuf
+ 4, sizeof(dev
->devinfo
));
279 memcpy(dev
->product_name
, dev
->devinfo
.product_name
, 30);
280 memcpy(dev
->product_licence
, dev
->devinfo
.product_licence
, 60);
281 dev
->product_name
[30] = '\0';
282 dev
->product_licence
[60] = '\0';
284 for (p
= dev
->product_name
+ 29; dev
->product_name
<= p
; p
--)
290 for (p
= dev
->product_licence
+ 59; dev
->product_licence
<= p
; p
--)
296 function
= be32_to_cpu(dev
->devinfo
.function
);
298 if (function
> 0x200) {
299 /* Do this silently - as not a real device */
301 dev
->driver
= &maple_dummy_driver
;
302 sprintf(dev
->dev
.bus_id
, "%d:0.port", dev
->port
);
305 "Maple bus at (%d, %d): Connected function 0x%lX\n",
306 dev
->port
, dev
->unit
, function
);
309 bus_for_each_drv(&maple_bus_type
, NULL
, dev
,
310 attach_matching_maple_driver
);
313 /* Driver does not exist yet */
315 "No maple driver found for this device\n");
316 dev
->driver
= &maple_dummy_driver
;
319 sprintf(dev
->dev
.bus_id
, "%d:0%d.%lX", dev
->port
,
320 dev
->unit
, function
);
322 dev
->function
= function
;
323 dev
->dev
.bus
= &maple_bus_type
;
324 dev
->dev
.parent
= &maple_bus
;
325 dev
->dev
.release
= &maple_release_device
;
326 retval
= device_register(&dev
->dev
);
329 "Maple bus: Attempt to register device (%x, %x) failed.\n",
330 dev
->port
, dev
->unit
);
337 * if device has been registered for the given
338 * port and unit then return 1 - allows identification
339 * of which devices need to be attached or detached
341 static int detach_maple_device(struct device
*device
, void *portptr
)
343 struct maple_device_specify
*ds
;
344 struct maple_device
*mdev
;
347 mdev
= to_maple_dev(device
);
348 if (mdev
->port
== ds
->port
&& mdev
->unit
== ds
->unit
)
353 static int setup_maple_commands(struct device
*device
, void *ignored
)
355 struct maple_device
*maple_dev
= to_maple_dev(device
);
357 if ((maple_dev
->interval
> 0)
358 && time_after(jiffies
, maple_dev
->when
)) {
359 maple_dev
->when
= jiffies
+ maple_dev
->interval
;
360 maple_dev
->mq
->command
= MAPLE_COMMAND_GETCOND
;
361 maple_dev
->mq
->sendbuf
= &maple_dev
->function
;
362 maple_dev
->mq
->length
= 1;
363 maple_add_packet(maple_dev
->mq
);
366 if (time_after(jiffies
, maple_pnp_time
)) {
367 maple_dev
->mq
->command
= MAPLE_COMMAND_DEVINFO
;
368 maple_dev
->mq
->length
= 0;
369 maple_add_packet(maple_dev
->mq
);
377 /* VBLANK bottom half - implemented via workqueue */
378 static void maple_vblank_handler(struct work_struct
*work
)
380 if (!maple_dma_done())
382 if (!list_empty(&maple_sentq
))
384 ctrl_outl(0, MAPLE_ENABLE
);
386 bus_for_each_dev(&maple_bus_type
, NULL
, NULL
,
387 setup_maple_commands
);
388 if (time_after(jiffies
, maple_pnp_time
))
389 maple_pnp_time
= jiffies
+ MAPLE_PNP_INTERVAL
;
390 if (liststatus
&& list_empty(&maple_sentq
)) {
391 INIT_LIST_HEAD(&maple_sentq
);
394 maplebus_dma_reset();
397 /* handle devices added via hotplugs - placing them on queue for DEVINFO*/
398 static void maple_map_subunits(struct maple_device
*mdev
, int submask
)
400 int retval
, k
, devcheck
;
401 struct maple_device
*mdev_add
;
402 struct maple_device_specify ds
;
404 for (k
= 0; k
< 5; k
++) {
405 ds
.port
= mdev
->port
;
408 bus_for_each_dev(&maple_bus_type
, NULL
, &ds
,
409 detach_maple_device
);
411 submask
= submask
>> 1;
414 devcheck
= submask
& 0x01;
416 mdev_add
= maple_alloc_dev(mdev
->port
, k
+ 1);
419 mdev_add
->mq
->command
= MAPLE_COMMAND_DEVINFO
;
420 mdev_add
->mq
->length
= 0;
421 maple_add_packet(mdev_add
->mq
);
424 submask
= submask
>> 1;
428 /* mark a device as removed */
429 static void maple_clean_submap(struct maple_device
*mdev
)
433 killbit
= (mdev
->unit
> 0 ? (1 << (mdev
->unit
- 1)) & 0x1f : 0x20);
436 subdevice_map
[mdev
->port
] = subdevice_map
[mdev
->port
] & killbit
;
439 /* handle empty port or hotplug removal */
440 static void maple_response_none(struct maple_device
*mdev
,
443 if (mdev
->unit
!= 0) {
445 maple_clean_submap(mdev
);
447 "Maple bus device detaching at (%d, %d)\n",
448 mdev
->port
, mdev
->unit
);
449 maple_detach_driver(mdev
);
453 printk(KERN_INFO
"No maple devices attached to port %d\n",
457 maple_clean_submap(mdev
);
460 /* preprocess hotplugs or scans */
461 static void maple_response_devinfo(struct maple_device
*mdev
,
465 if ((!started
) || (scanning
== 2)) {
466 maple_attach_driver(mdev
);
469 if (mdev
->unit
== 0) {
470 submask
= recvbuf
[2] & 0x1F;
471 if (submask
^ subdevice_map
[mdev
->port
]) {
472 maple_map_subunits(mdev
, submask
);
473 subdevice_map
[mdev
->port
] = submask
;
478 /* maple dma end bottom half - implemented via workqueue */
479 static void maple_dma_handler(struct work_struct
*work
)
481 struct mapleq
*mq
, *nmq
;
482 struct maple_device
*dev
;
484 enum maple_code code
;
486 if (!maple_dma_done())
488 ctrl_outl(0, MAPLE_ENABLE
);
489 if (!list_empty(&maple_sentq
)) {
490 list_for_each_entry_safe(mq
, nmq
, &maple_sentq
, list
) {
491 recvbuf
= mq
->recvbuf
;
495 case MAPLE_RESPONSE_NONE
:
496 maple_response_none(dev
, mq
);
499 case MAPLE_RESPONSE_DEVINFO
:
500 maple_response_devinfo(dev
, recvbuf
);
503 case MAPLE_RESPONSE_DATATRF
:
508 case MAPLE_RESPONSE_FILEERR
:
509 case MAPLE_RESPONSE_AGAIN
:
510 case MAPLE_RESPONSE_BADCMD
:
511 case MAPLE_RESPONSE_BADFUNC
:
513 "Maple non-fatal error 0x%X\n",
517 case MAPLE_RESPONSE_ALLINFO
:
519 "Maple - extended device information not supported\n");
522 case MAPLE_RESPONSE_OK
:
529 INIT_LIST_HEAD(&maple_sentq
);
539 maplebus_dma_reset();
542 static irqreturn_t
maplebus_dma_interrupt(int irq
, void *dev_id
)
544 /* Load everything into the bottom half */
545 schedule_work(&maple_dma_process
);
549 static irqreturn_t
maplebus_vblank_interrupt(int irq
, void *dev_id
)
551 schedule_work(&maple_vblank_process
);
555 static struct irqaction maple_dma_irq
= {
556 .name
= "maple bus DMA handler",
557 .handler
= maplebus_dma_interrupt
,
558 .flags
= IRQF_SHARED
,
561 static struct irqaction maple_vblank_irq
= {
562 .name
= "maple bus VBLANK handler",
563 .handler
= maplebus_vblank_interrupt
,
564 .flags
= IRQF_SHARED
,
567 static int maple_set_dma_interrupt_handler(void)
569 return setup_irq(HW_EVENT_MAPLE_DMA
, &maple_dma_irq
);
572 static int maple_set_vblank_interrupt_handler(void)
574 return setup_irq(HW_EVENT_VSYNC
, &maple_vblank_irq
);
577 static int maple_get_dma_buffer(void)
580 (void *) __get_free_pages(GFP_KERNEL
| __GFP_ZERO
,
587 static int match_maple_bus_driver(struct device
*devptr
,
588 struct device_driver
*drvptr
)
590 struct maple_driver
*maple_drv
;
591 struct maple_device
*maple_dev
;
593 maple_drv
= container_of(drvptr
, struct maple_driver
, drv
);
594 maple_dev
= container_of(devptr
, struct maple_device
, dev
);
595 /* Trap empty port case */
596 if (maple_dev
->devinfo
.function
== 0xFFFFFFFF)
598 else if (maple_dev
->devinfo
.function
&
599 be32_to_cpu(maple_drv
->function
))
604 static int maple_bus_uevent(struct device
*dev
, struct kobj_uevent_env
*env
)
609 static void maple_bus_release(struct device
*dev
)
613 static struct maple_driver maple_dummy_driver
= {
615 .name
= "maple_dummy_driver",
616 .bus
= &maple_bus_type
,
620 struct bus_type maple_bus_type
= {
622 .match
= match_maple_bus_driver
,
623 .uevent
= maple_bus_uevent
,
625 EXPORT_SYMBOL_GPL(maple_bus_type
);
627 static struct device maple_bus
= {
629 .release
= maple_bus_release
,
632 static int __init
maple_bus_init(void)
635 struct maple_device
*mdev
[MAPLE_PORTS
];
636 ctrl_outl(0, MAPLE_STATE
);
638 retval
= device_register(&maple_bus
);
642 retval
= bus_register(&maple_bus_type
);
646 retval
= driver_register(&maple_dummy_driver
.drv
);
651 /* allocate memory for maple bus dma */
652 retval
= maple_get_dma_buffer();
655 "Maple bus: Failed to allocate Maple DMA buffers\n");
659 /* set up DMA interrupt handler */
660 retval
= maple_set_dma_interrupt_handler();
663 "Maple bus: Failed to grab maple DMA IRQ\n");
667 /* set up VBLANK interrupt handler */
668 retval
= maple_set_vblank_interrupt_handler();
670 printk(KERN_INFO
"Maple bus: Failed to grab VBLANK IRQ\n");
675 kmem_cache_create("maple_queue_cache", 0x400, 0,
676 SLAB_HWCACHE_ALIGN
, NULL
);
678 if (!maple_queue_cache
)
679 goto cleanup_bothirqs
;
681 /* setup maple ports */
682 for (i
= 0; i
< MAPLE_PORTS
; i
++) {
683 mdev
[i
] = maple_alloc_dev(i
, 0);
686 maple_free_dev(mdev
[i
]);
689 mdev
[i
]->registered
= 0;
690 mdev
[i
]->mq
->command
= MAPLE_COMMAND_DEVINFO
;
691 mdev
[i
]->mq
->length
= 0;
692 maple_attach_driver(mdev
[i
]);
693 maple_add_packet(mdev
[i
]->mq
);
694 subdevice_map
[i
] = 0;
697 /* setup maplebus hardware */
698 maplebus_dma_reset();
700 /* initial detection */
703 maple_pnp_time
= jiffies
;
705 printk(KERN_INFO
"Maple bus core now registered.\n");
710 kmem_cache_destroy(maple_queue_cache
);
713 free_irq(HW_EVENT_VSYNC
, 0);
716 free_irq(HW_EVENT_MAPLE_DMA
, 0);
719 free_pages((unsigned long) maple_sendbuf
, MAPLE_DMA_PAGES
);
722 driver_unregister(&maple_dummy_driver
.drv
);
725 bus_unregister(&maple_bus_type
);
728 device_unregister(&maple_bus
);
731 printk(KERN_INFO
"Maple bus registration failed\n");
734 subsys_initcall(maple_bus_init
);