2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 2006 Michael Lorenz
5 * Copyright 2008 by Nathan Whitehorn
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/module.h>
38 #include <sys/eventhandler.h>
39 #include <sys/kernel.h>
41 #include <sys/mutex.h>
42 #include <sys/clock.h>
43 #include <sys/reboot.h>
45 #include <dev/ofw/ofw_bus.h>
46 #include <dev/ofw/openfirm.h>
48 #include <machine/bus.h>
49 #include <machine/intr_machdep.h>
50 #include <machine/md_var.h>
51 #include <machine/pio.h>
52 #include <machine/resource.h>
59 #include <dev/adb/adb.h>
68 static int cuda_probe(device_t
);
69 static int cuda_attach(device_t
);
70 static int cuda_detach(device_t
);
72 static u_int
cuda_adb_send(device_t dev
, u_char command_byte
, int len
,
73 u_char
*data
, u_char poll
);
74 static u_int
cuda_adb_autopoll(device_t dev
, uint16_t mask
);
75 static u_int
cuda_poll(device_t dev
);
76 static void cuda_send_inbound(struct cuda_softc
*sc
);
77 static void cuda_send_outbound(struct cuda_softc
*sc
);
78 static void cuda_shutdown(void *xsc
, int howto
);
83 static int cuda_gettime(device_t dev
, struct timespec
*ts
);
84 static int cuda_settime(device_t dev
, struct timespec
*ts
);
86 static device_method_t cuda_methods
[] = {
87 /* Device interface */
88 DEVMETHOD(device_probe
, cuda_probe
),
89 DEVMETHOD(device_attach
, cuda_attach
),
90 DEVMETHOD(device_detach
, cuda_detach
),
91 DEVMETHOD(device_shutdown
, bus_generic_shutdown
),
92 DEVMETHOD(device_suspend
, bus_generic_suspend
),
93 DEVMETHOD(device_resume
, bus_generic_resume
),
95 /* ADB bus interface */
96 DEVMETHOD(adb_hb_send_raw_packet
, cuda_adb_send
),
97 DEVMETHOD(adb_hb_controller_poll
, cuda_poll
),
98 DEVMETHOD(adb_hb_set_autopoll_mask
, cuda_adb_autopoll
),
100 /* Clock interface */
101 DEVMETHOD(clock_gettime
, cuda_gettime
),
102 DEVMETHOD(clock_settime
, cuda_settime
),
107 static driver_t cuda_driver
= {
110 sizeof(struct cuda_softc
),
113 DRIVER_MODULE(cuda
, macio
, cuda_driver
, 0, 0);
114 DRIVER_MODULE(adb
, cuda
, adb_driver
, 0, 0);
116 static void cuda_intr(void *arg
);
117 static uint8_t cuda_read_reg(struct cuda_softc
*sc
, u_int offset
);
118 static void cuda_write_reg(struct cuda_softc
*sc
, u_int offset
, uint8_t value
);
119 static void cuda_idle(struct cuda_softc
*);
120 static void cuda_tip(struct cuda_softc
*);
121 static void cuda_clear_tip(struct cuda_softc
*);
122 static void cuda_in(struct cuda_softc
*);
123 static void cuda_out(struct cuda_softc
*);
124 static void cuda_toggle_ack(struct cuda_softc
*);
125 static void cuda_ack_off(struct cuda_softc
*);
126 static int cuda_intr_state(struct cuda_softc
*);
129 cuda_probe(device_t dev
)
131 const char *type
= ofw_bus_get_type(dev
);
133 if (strcmp(type
, "via-cuda") != 0)
136 device_set_desc(dev
, CUDA_DEVSTR
);
141 cuda_attach(device_t dev
)
143 struct cuda_softc
*sc
;
147 phandle_t node
,child
;
149 sc
= device_get_softc(dev
);
153 sc
->sc_memr
= bus_alloc_resource_any(dev
, SYS_RES_MEMORY
,
154 &sc
->sc_memrid
, RF_ACTIVE
);
156 if (sc
->sc_memr
== NULL
) {
157 device_printf(dev
, "Could not alloc mem resource!\n");
162 sc
->sc_irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &sc
->sc_irqrid
,
164 if (sc
->sc_irq
== NULL
) {
165 device_printf(dev
, "could not allocate interrupt\n");
166 bus_release_resource(dev
, SYS_RES_MEMORY
, sc
->sc_memrid
,
171 if (bus_setup_intr(dev
, sc
->sc_irq
, INTR_TYPE_MISC
| INTR_MPSAFE
172 | INTR_ENTROPY
, NULL
, cuda_intr
, dev
, &sc
->sc_ih
) != 0) {
173 device_printf(dev
, "could not setup interrupt\n");
174 bus_release_resource(dev
, SYS_RES_MEMORY
, sc
->sc_memrid
,
176 bus_release_resource(dev
, SYS_RES_IRQ
, sc
->sc_irqrid
,
181 mtx_init(&sc
->sc_mutex
,"cuda",NULL
,MTX_DEF
| MTX_RECURSE
);
187 sc
->sc_state
= CUDA_NOTREADY
;
191 STAILQ_INIT(&sc
->sc_inq
);
192 STAILQ_INIT(&sc
->sc_outq
);
193 STAILQ_INIT(&sc
->sc_freeq
);
195 for (i
= 0; i
< CUDA_MAXPACKETS
; i
++)
196 STAILQ_INSERT_TAIL(&sc
->sc_freeq
, &sc
->sc_pkts
[i
], pkt_q
);
200 reg
= cuda_read_reg(sc
, vDirB
);
201 reg
|= 0x30; /* register B bits 4 and 5: outputs */
202 cuda_write_reg(sc
, vDirB
, reg
);
204 reg
= cuda_read_reg(sc
, vDirB
);
205 reg
&= 0xf7; /* register B bit 3: input */
206 cuda_write_reg(sc
, vDirB
, reg
);
208 reg
= cuda_read_reg(sc
, vACR
);
209 reg
&= ~vSR_OUT
; /* make sure SR is set to IN */
210 cuda_write_reg(sc
, vACR
, reg
);
212 cuda_write_reg(sc
, vACR
, (cuda_read_reg(sc
, vACR
) | 0x0c) & ~0x10);
214 sc
->sc_state
= CUDA_IDLE
; /* used by all types of hardware */
216 cuda_write_reg(sc
, vIER
, 0x84); /* make sure VIA interrupts are on */
218 cuda_idle(sc
); /* reset ADB */
222 i
= cuda_read_reg(sc
, vSR
); /* clear interrupt */
223 cuda_write_reg(sc
, vIER
, 0x04); /* no interrupts while clearing */
224 cuda_idle(sc
); /* reset state to idle */
226 cuda_tip(sc
); /* signal start of frame */
232 cuda_idle(sc
); /* back to idle state */
233 i
= cuda_read_reg(sc
, vSR
); /* clear interrupt */
234 cuda_write_reg(sc
, vIER
, 0x84); /* ints ok now */
236 /* Initialize child buses (ADB) */
237 node
= ofw_bus_get_node(dev
);
239 for (child
= OF_child(node
); child
!= 0; child
= OF_peer(child
)) {
242 memset(name
, 0, sizeof(name
));
243 OF_getprop(child
, "name", name
, sizeof(name
));
246 device_printf(dev
, "CUDA child <%s>\n",name
);
248 if (strncmp(name
, "adb", 4) == 0) {
249 sc
->adb_bus
= device_add_child(dev
,"adb",DEVICE_UNIT_ANY
);
253 clock_register(dev
, 1000);
254 EVENTHANDLER_REGISTER(shutdown_final
, cuda_shutdown
, sc
,
257 bus_attach_children(dev
);
261 static int cuda_detach(device_t dev
) {
262 struct cuda_softc
*sc
;
265 error
= bus_generic_detach(dev
);
269 sc
= device_get_softc(dev
);
271 bus_teardown_intr(dev
, sc
->sc_irq
, sc
->sc_ih
);
272 bus_release_resource(dev
, SYS_RES_IRQ
, sc
->sc_irqrid
, sc
->sc_irq
);
273 bus_release_resource(dev
, SYS_RES_MEMORY
, sc
->sc_memrid
, sc
->sc_memr
);
274 mtx_destroy(&sc
->sc_mutex
);
280 cuda_read_reg(struct cuda_softc
*sc
, u_int offset
) {
281 return (bus_read_1(sc
->sc_memr
, offset
));
285 cuda_write_reg(struct cuda_softc
*sc
, u_int offset
, uint8_t value
) {
286 bus_write_1(sc
->sc_memr
, offset
, value
);
290 cuda_idle(struct cuda_softc
*sc
)
294 reg
= cuda_read_reg(sc
, vBufB
);
295 reg
|= (vPB4
| vPB5
);
296 cuda_write_reg(sc
, vBufB
, reg
);
300 cuda_tip(struct cuda_softc
*sc
)
304 reg
= cuda_read_reg(sc
, vBufB
);
306 cuda_write_reg(sc
, vBufB
, reg
);
310 cuda_clear_tip(struct cuda_softc
*sc
)
314 reg
= cuda_read_reg(sc
, vBufB
);
316 cuda_write_reg(sc
, vBufB
, reg
);
320 cuda_in(struct cuda_softc
*sc
)
324 reg
= cuda_read_reg(sc
, vACR
);
326 cuda_write_reg(sc
, vACR
, reg
);
330 cuda_out(struct cuda_softc
*sc
)
334 reg
= cuda_read_reg(sc
, vACR
);
336 cuda_write_reg(sc
, vACR
, reg
);
340 cuda_toggle_ack(struct cuda_softc
*sc
)
344 reg
= cuda_read_reg(sc
, vBufB
);
346 cuda_write_reg(sc
, vBufB
, reg
);
350 cuda_ack_off(struct cuda_softc
*sc
)
354 reg
= cuda_read_reg(sc
, vBufB
);
356 cuda_write_reg(sc
, vBufB
, reg
);
360 cuda_intr_state(struct cuda_softc
*sc
)
362 return ((cuda_read_reg(sc
, vBufB
) & vPB3
) == 0);
366 cuda_send(void *cookie
, int poll
, int length
, uint8_t *msg
)
368 struct cuda_softc
*sc
= cookie
;
369 device_t dev
= sc
->sc_dev
;
370 struct cuda_packet
*pkt
;
372 if (sc
->sc_state
== CUDA_NOTREADY
)
375 mtx_lock(&sc
->sc_mutex
);
377 pkt
= STAILQ_FIRST(&sc
->sc_freeq
);
379 mtx_unlock(&sc
->sc_mutex
);
383 pkt
->len
= length
- 1;
385 memcpy(pkt
->data
, &msg
[1], pkt
->len
);
387 STAILQ_REMOVE_HEAD(&sc
->sc_freeq
, pkt_q
);
388 STAILQ_INSERT_TAIL(&sc
->sc_outq
, pkt
, pkt_q
);
391 * If we already are sending a packet, we should bail now that this
392 * one has been added to the queue.
395 if (sc
->sc_waiting
) {
396 mtx_unlock(&sc
->sc_mutex
);
400 cuda_send_outbound(sc
);
401 mtx_unlock(&sc
->sc_mutex
);
403 if (sc
->sc_polling
|| poll
|| cold
)
410 cuda_send_outbound(struct cuda_softc
*sc
)
412 struct cuda_packet
*pkt
;
414 mtx_assert(&sc
->sc_mutex
, MA_OWNED
);
416 pkt
= STAILQ_FIRST(&sc
->sc_outq
);
420 sc
->sc_out_length
= pkt
->len
+ 1;
421 memcpy(sc
->sc_out
, &pkt
->type
, pkt
->len
+ 1);
424 STAILQ_REMOVE_HEAD(&sc
->sc_outq
, pkt_q
);
425 STAILQ_INSERT_TAIL(&sc
->sc_freeq
, pkt
, pkt_q
);
429 cuda_poll(sc
->sc_dev
);
433 if (sc
->sc_state
== CUDA_IDLE
&& !cuda_intr_state(sc
)) {
434 sc
->sc_state
= CUDA_OUT
;
436 cuda_write_reg(sc
, vSR
, sc
->sc_out
[0]);
443 cuda_send_inbound(struct cuda_softc
*sc
)
446 struct cuda_packet
*pkt
;
450 mtx_lock(&sc
->sc_mutex
);
452 while ((pkt
= STAILQ_FIRST(&sc
->sc_inq
)) != NULL
) {
453 STAILQ_REMOVE_HEAD(&sc
->sc_inq
, pkt_q
);
455 mtx_unlock(&sc
->sc_mutex
);
457 /* check if we have a handler for this message */
461 adb_receive_raw_packet(sc
->adb_bus
,
462 pkt
->data
[0],pkt
->data
[1],
463 pkt
->len
- 2,&pkt
->data
[2]);
465 adb_receive_raw_packet(sc
->adb_bus
,
466 pkt
->data
[0],pkt
->data
[1],0,NULL
);
470 mtx_lock(&sc
->sc_mutex
);
471 switch (pkt
->data
[1]) {
476 memcpy(&sc
->sc_rtc
, &pkt
->data
[2],
483 mtx_unlock(&sc
->sc_mutex
);
487 * CUDA will throw errors if we miss a race between
488 * sending and receiving packets. This is already
489 * handled when we abort packet output to handle
490 * this packet in cuda_intr(). Thus, we ignore
495 device_printf(dev
,"unknown CUDA command %d\n",
500 mtx_lock(&sc
->sc_mutex
);
502 STAILQ_INSERT_TAIL(&sc
->sc_freeq
, pkt
, pkt_q
);
505 mtx_unlock(&sc
->sc_mutex
);
509 cuda_poll(device_t dev
)
511 struct cuda_softc
*sc
= device_get_softc(dev
);
513 if (sc
->sc_state
== CUDA_IDLE
&& !cuda_intr_state(sc
) &&
525 struct cuda_softc
*sc
;
526 int ending
, process_inbound
;
530 sc
= device_get_softc(dev
);
532 mtx_lock(&sc
->sc_mutex
);
535 reg
= cuda_read_reg(sc
, vIFR
);
536 if ((reg
& vSR_INT
) != vSR_INT
) {
537 mtx_unlock(&sc
->sc_mutex
);
541 cuda_write_reg(sc
, vIFR
, 0x7f); /* Clear interrupt */
544 switch (sc
->sc_state
) {
547 * This is an unexpected packet, so grab the first (dummy)
548 * byte, set up the proper vars, and tell the chip we are
549 * starting to receive the packet by setting the TIP bit.
551 sc
->sc_in
[1] = cuda_read_reg(sc
, vSR
);
553 if (cuda_intr_state(sc
) == 0) {
554 /* must have been a fake start */
556 if (sc
->sc_waiting
) {
559 sc
->sc_state
= CUDA_OUT
;
562 cuda_write_reg(sc
, vSR
, sc
->sc_out
[1]);
573 sc
->sc_state
= CUDA_IN
;
577 sc
->sc_in
[sc
->sc_received
] = cuda_read_reg(sc
, vSR
);
580 if (sc
->sc_received
> 255) {
581 /* bitch only once */
582 if (sc
->sc_received
== 256) {
583 device_printf(dev
,"input overflow\n");
589 /* intr off means this is the last byte (end of frame) */
590 if (cuda_intr_state(sc
) == 0) {
596 if (ending
== 1) { /* end of message? */
597 struct cuda_packet
*pkt
;
599 /* reset vars and signal the end of this frame */
602 /* Queue up the packet */
603 pkt
= STAILQ_FIRST(&sc
->sc_freeq
);
605 /* If we have a free packet, process it */
607 pkt
->len
= sc
->sc_received
- 2;
608 pkt
->type
= sc
->sc_in
[1];
609 memcpy(pkt
->data
, &sc
->sc_in
[2], pkt
->len
);
611 STAILQ_REMOVE_HEAD(&sc
->sc_freeq
, pkt_q
);
612 STAILQ_INSERT_TAIL(&sc
->sc_inq
, pkt
, pkt_q
);
617 sc
->sc_state
= CUDA_IDLE
;
621 * If there is something waiting to be sent out,
622 * set everything up and send the first byte.
624 if (sc
->sc_waiting
== 1) {
625 DELAY(1500); /* required */
627 sc
->sc_state
= CUDA_OUT
;
630 * If the interrupt is on, we were too slow
631 * and the chip has already started to send
632 * something to us, so back out of the write
633 * and start a read cycle.
635 if (cuda_intr_state(sc
)) {
639 sc
->sc_state
= CUDA_IDLE
;
646 * If we got here, it's ok to start sending
647 * so load the first byte and tell the chip
651 cuda_write_reg(sc
, vSR
,
652 sc
->sc_out
[sc
->sc_sent
]);
660 cuda_read_reg(sc
, vSR
); /* reset SR-intr in IFR */
663 if (cuda_intr_state(sc
)) { /* ADB intr low during write */
664 cuda_in(sc
); /* make sure SR is set to IN */
666 sc
->sc_sent
= 0; /* must start all over */
667 sc
->sc_state
= CUDA_IDLE
; /* new state */
669 sc
->sc_waiting
= 1; /* must retry when done with
672 goto switch_start
; /* process next state right
676 if (sc
->sc_out_length
== sc
->sc_sent
) { /* check for done */
677 sc
->sc_waiting
= 0; /* done writing */
678 sc
->sc_state
= CUDA_IDLE
; /* signal bus is idle */
683 cuda_write_reg(sc
, vSR
, sc
->sc_out
[sc
->sc_sent
]);
684 cuda_toggle_ack(sc
); /* signal byte ready to
696 mtx_unlock(&sc
->sc_mutex
);
699 cuda_send_inbound(sc
);
701 mtx_lock(&sc
->sc_mutex
);
702 /* If we have another packet waiting, set it up */
703 if (!sc
->sc_waiting
&& sc
->sc_state
== CUDA_IDLE
)
704 cuda_send_outbound(sc
);
706 mtx_unlock(&sc
->sc_mutex
);
711 cuda_adb_send(device_t dev
, u_char command_byte
, int len
, u_char
*data
,
714 struct cuda_softc
*sc
= device_get_softc(dev
);
718 /* construct an ADB command packet and send it */
719 packet
[0] = CUDA_ADB
;
720 packet
[1] = command_byte
;
721 for (i
= 0; i
< len
; i
++)
722 packet
[i
+ 2] = data
[i
];
724 cuda_send(sc
, poll
, len
+ 2, packet
);
730 cuda_adb_autopoll(device_t dev
, uint16_t mask
) {
731 struct cuda_softc
*sc
= device_get_softc(dev
);
733 uint8_t cmd
[] = {CUDA_PSEUDO
, CMD_AUTOPOLL
, mask
!= 0};
735 mtx_lock(&sc
->sc_mutex
);
737 if (cmd
[2] == sc
->sc_autopoll
) {
738 mtx_unlock(&sc
->sc_mutex
);
742 sc
->sc_autopoll
= -1;
743 cuda_send(sc
, 1, 3, cmd
);
745 mtx_unlock(&sc
->sc_mutex
);
751 cuda_shutdown(void *xsc
, int howto
)
753 struct cuda_softc
*sc
= xsc
;
754 uint8_t cmd
[] = {CUDA_PSEUDO
, 0};
756 if ((howto
& RB_POWEROFF
) != 0)
757 cmd
[1] = CMD_POWEROFF
;
758 else if ((howto
& RB_HALT
) == 0)
763 cuda_poll(sc
->sc_dev
);
764 cuda_send(sc
, 1, 2, cmd
);
767 cuda_poll(sc
->sc_dev
);
770 #define DIFF19041970 2082844800
773 cuda_gettime(device_t dev
, struct timespec
*ts
)
775 struct cuda_softc
*sc
= device_get_softc(dev
);
776 uint8_t cmd
[] = {CUDA_PSEUDO
, CMD_READ_RTC
};
778 mtx_lock(&sc
->sc_mutex
);
780 cuda_send(sc
, 1, 2, cmd
);
781 if (sc
->sc_rtc
== -1)
782 mtx_sleep(&sc
->sc_rtc
, &sc
->sc_mutex
, 0, "rtc", 100);
784 ts
->tv_sec
= sc
->sc_rtc
- DIFF19041970
;
786 mtx_unlock(&sc
->sc_mutex
);
792 cuda_settime(device_t dev
, struct timespec
*ts
)
794 struct cuda_softc
*sc
= device_get_softc(dev
);
795 uint8_t cmd
[] = {CUDA_PSEUDO
, CMD_WRITE_RTC
, 0, 0, 0, 0};
798 sec
= ts
->tv_sec
+ DIFF19041970
;
799 memcpy(&cmd
[2], &sec
, sizeof(sec
));
801 mtx_lock(&sc
->sc_mutex
);
802 cuda_send(sc
, 0, 6, cmd
);
803 mtx_unlock(&sc
->sc_mutex
);