Home | History | Annotate | Line # | Download | only in dev
      1 /*	$NetBSD: dbdma.c,v 1.12 2016/07/15 21:08:27 macallan Exp $	*/
      2 
      3 /*
      4  * Copyright 1991-1998 by Open Software Foundation, Inc.
      5  *              All Rights Reserved
      6  *
      7  * Permission to use, copy, modify, and distribute this software and
      8  * its documentation for any purpose and without fee is hereby granted,
      9  * provided that the above copyright notice appears in all copies and
     10  * that both the copyright notice and this permission notice appear in
     11  * supporting documentation.
     12  *
     13  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
     14  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     15  * FOR A PARTICULAR PURPOSE.
     16  *
     17  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
     18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
     19  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
     20  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
     21  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     22  *
     23  */
     24 
     25 #include <sys/cdefs.h>
     26 __KERNEL_RCSID(0, "$NetBSD: dbdma.c,v 1.12 2016/07/15 21:08:27 macallan Exp $");
     27 
     28 #include <sys/param.h>
     29 #include <sys/kmem.h>
     30 #include <sys/systm.h>
     31 
     32 #include <prop/proplib.h>
     33 
     34 #include <uvm/uvm_extern.h>
     35 
     36 #include <machine/autoconf.h>
     37 #include <machine/pio.h>
     38 #include <macppc/dev/dbdma.h>
     39 
     40 dbdma_command_t	*dbdma_alloc_commands = NULL;
     41 
     42 void
     43 dbdma_start(dbdma_regmap_t *dmap, dbdma_command_t *commands)
     44 {
     45 	unsigned long addr = vtophys((vaddr_t)commands);
     46 
     47 	if (addr & 0xf)
     48 		panic("dbdma_start command structure not 16-byte aligned %08x %08x", (uint32_t)commands, (uint32_t)addr);
     49 
     50 	dmap->d_intselect = 0xff;  /* Endian magic - clear out interrupts */
     51 	DBDMA_ST4_ENDIAN(&dmap->d_control,
     52 			 DBDMA_CLEAR_CNTRL( (DBDMA_CNTRL_ACTIVE	|
     53 					     DBDMA_CNTRL_DEAD	|
     54 					     DBDMA_CNTRL_WAKE	|
     55 					     DBDMA_CNTRL_FLUSH	|
     56 					     DBDMA_CNTRL_PAUSE	|
     57 					     DBDMA_CNTRL_RUN      )));
     58 
     59 	while (DBDMA_LD4_ENDIAN(&dmap->d_status) & DBDMA_CNTRL_ACTIVE)
     60 		;
     61 
     62 	dmap->d_cmdptrhi = 0;	/* 64-bit not yet */
     63 	DBDMA_ST4_ENDIAN(&dmap->d_cmdptrlo, addr);
     64 
     65 	DBDMA_ST4_ENDIAN(&dmap->d_control, DBDMA_SET_CNTRL(DBDMA_CNTRL_RUN));
     66 }
     67 
     68 void
     69 dbdma_stop(dbdma_regmap_t *dmap)
     70 {
     71 	out32rb(&dmap->d_control, DBDMA_CLEAR_CNTRL(DBDMA_CNTRL_RUN) |
     72 			  DBDMA_SET_CNTRL(DBDMA_CNTRL_FLUSH));
     73 
     74 	while (in32rb(&dmap->d_status) &
     75 		(DBDMA_CNTRL_ACTIVE|DBDMA_CNTRL_FLUSH));
     76 }
     77 
     78 void
     79 dbdma_flush(dbdma_regmap_t *dmap)
     80 {
     81 	out32rb(&dmap->d_control, DBDMA_SET_CNTRL(DBDMA_CNTRL_FLUSH));
     82 
     83 	while (in32rb(&dmap->d_status) & (DBDMA_CNTRL_FLUSH));
     84 }
     85 
     86 void
     87 dbdma_reset(dbdma_regmap_t *dmap)
     88 {
     89 	out32rb(&dmap->d_control,
     90 			 DBDMA_CLEAR_CNTRL( (DBDMA_CNTRL_ACTIVE	|
     91 					     DBDMA_CNTRL_DEAD	|
     92 					     DBDMA_CNTRL_WAKE	|
     93 					     DBDMA_CNTRL_FLUSH	|
     94 					     DBDMA_CNTRL_PAUSE	|
     95 					     DBDMA_CNTRL_RUN      )));
     96 
     97 	while (in32rb(&dmap->d_status) & DBDMA_CNTRL_RUN);
     98 }
     99 
    100 void
    101 dbdma_continue(dbdma_regmap_t *dmap)
    102 {
    103 	out32rb(&dmap->d_control,
    104 		DBDMA_SET_CNTRL(DBDMA_CNTRL_RUN | DBDMA_CNTRL_WAKE) |
    105 		DBDMA_CLEAR_CNTRL(DBDMA_CNTRL_PAUSE | DBDMA_CNTRL_DEAD));
    106 }
    107 
    108 void
    109 dbdma_pause(dbdma_regmap_t *dmap)
    110 {
    111 	DBDMA_ST4_ENDIAN(&dmap->d_control,DBDMA_SET_CNTRL(DBDMA_CNTRL_PAUSE));
    112 
    113 	while (DBDMA_LD4_ENDIAN(&dmap->d_status) & DBDMA_CNTRL_ACTIVE)
    114 		;
    115 }
    116 
    117 dbdma_command_t	*
    118 dbdma_alloc(int size, void **fp)
    119 {
    120 	u_int buf;
    121 
    122 	buf = (u_int)kmem_alloc(size + 0x0f, KM_SLEEP);
    123 	if (fp != NULL) {
    124 	 *fp = (void *)buf;
    125         }
    126 	buf = (buf + 0x0f) & ~0x0f;
    127 
    128 	return (dbdma_command_t *)buf;
    129 }
    130 
    131 void
    132 dbdma_free(void *ptr, int size)
    133 {
    134 	kmem_free(ptr, size + 0x0f);
    135 }
    136