linux/arch/x86/include/asm/mca_dma.h
<<
>>
Prefs
   1#ifndef _ASM_X86_MCA_DMA_H
   2#define _ASM_X86_MCA_DMA_H
   3
   4#include <asm/io.h>
   5#include <linux/ioport.h>
   6
   7/*
   8 * Microchannel specific DMA stuff.  DMA on an MCA machine is fairly similar to
   9 *   standard PC dma, but it certainly has its quirks.  DMA register addresses
  10 *   are in a different place and there are some added functions.  Most of this
  11 *   should be pretty obvious on inspection.  Note that the user must divide
  12 *   count by 2 when using 16-bit dma; that is not handled by these functions.
  13 *
  14 * Ramen Noodles are yummy.
  15 *
  16 *  1998 Tymm Twillman <tymm@computer.org>
  17 */
  18
  19/*
  20 * Registers that are used by the DMA controller; FN is the function register
  21 *   (tell the controller what to do) and EXE is the execution register (how
  22 *   to do it)
  23 */
  24
  25#define MCA_DMA_REG_FN  0x18
  26#define MCA_DMA_REG_EXE 0x1A
  27
  28/*
  29 * Functions that the DMA controller can do
  30 */
  31
  32#define MCA_DMA_FN_SET_IO       0x00
  33#define MCA_DMA_FN_SET_ADDR     0x20
  34#define MCA_DMA_FN_GET_ADDR     0x30
  35#define MCA_DMA_FN_SET_COUNT    0x40
  36#define MCA_DMA_FN_GET_COUNT    0x50
  37#define MCA_DMA_FN_GET_STATUS   0x60
  38#define MCA_DMA_FN_SET_MODE     0x70
  39#define MCA_DMA_FN_SET_ARBUS    0x80
  40#define MCA_DMA_FN_MASK         0x90
  41#define MCA_DMA_FN_RESET_MASK   0xA0
  42#define MCA_DMA_FN_MASTER_CLEAR 0xD0
  43
  44/*
  45 * Modes (used by setting MCA_DMA_FN_MODE in the function register)
  46 *
  47 * Note that the MODE_READ is read from memory (write to device), and
  48 *   MODE_WRITE is vice-versa.
  49 */
  50
  51#define MCA_DMA_MODE_XFER  0x04  /* read by default */
  52#define MCA_DMA_MODE_READ  0x04  /* same as XFER */
  53#define MCA_DMA_MODE_WRITE 0x08  /* OR with MODE_XFER to use */
  54#define MCA_DMA_MODE_IO    0x01  /* DMA from IO register */
  55#define MCA_DMA_MODE_16    0x40  /* 16 bit xfers */
  56
  57
  58/**
  59 *      mca_enable_dma  -       channel to enable DMA on
  60 *      @dmanr: DMA channel
  61 *
  62 *      Enable the MCA bus DMA on a channel. This can be called from
  63 *      IRQ context.
  64 */
  65
  66static inline void mca_enable_dma(unsigned int dmanr)
  67{
  68        outb(MCA_DMA_FN_RESET_MASK | dmanr, MCA_DMA_REG_FN);
  69}
  70
  71/**
  72 *      mca_disble_dma  -       channel to disable DMA on
  73 *      @dmanr: DMA channel
  74 *
  75 *      Enable the MCA bus DMA on a channel. This can be called from
  76 *      IRQ context.
  77 */
  78
  79static inline void mca_disable_dma(unsigned int dmanr)
  80{
  81        outb(MCA_DMA_FN_MASK | dmanr, MCA_DMA_REG_FN);
  82}
  83
  84/**
  85 *      mca_set_dma_addr -      load a 24bit DMA address
  86 *      @dmanr: DMA channel
  87 *      @a: 24bit bus address
  88 *
  89 *      Load the address register in the DMA controller. This has a 24bit
  90 *      limitation (16Mb).
  91 */
  92
  93static inline void mca_set_dma_addr(unsigned int dmanr, unsigned int a)
  94{
  95        outb(MCA_DMA_FN_SET_ADDR | dmanr, MCA_DMA_REG_FN);
  96        outb(a & 0xff, MCA_DMA_REG_EXE);
  97        outb((a >> 8) & 0xff, MCA_DMA_REG_EXE);
  98        outb((a >> 16) & 0xff, MCA_DMA_REG_EXE);
  99}
 100
 101/**
 102 *      mca_get_dma_addr -      load a 24bit DMA address
 103 *      @dmanr: DMA channel
 104 *
 105 *      Read the address register in the DMA controller. This has a 24bit
 106 *      limitation (16Mb). The return is a bus address.
 107 */
 108
 109static inline unsigned int mca_get_dma_addr(unsigned int dmanr)
 110{
 111        unsigned int addr;
 112
 113        outb(MCA_DMA_FN_GET_ADDR | dmanr, MCA_DMA_REG_FN);
 114        addr = inb(MCA_DMA_REG_EXE);
 115        addr |= inb(MCA_DMA_REG_EXE) << 8;
 116        addr |= inb(MCA_DMA_REG_EXE) << 16;
 117
 118        return addr;
 119}
 120
 121/**
 122 *      mca_set_dma_count -     load a 16bit transfer count
 123 *      @dmanr: DMA channel
 124 *      @count: count
 125 *
 126 *      Set the DMA count for this channel. This can be up to 64Kbytes.
 127 *      Setting a count of zero will not do what you expect.
 128 */
 129
 130static inline void mca_set_dma_count(unsigned int dmanr, unsigned int count)
 131{
 132        count--;  /* transfers one more than count -- correct for this */
 133
 134        outb(MCA_DMA_FN_SET_COUNT | dmanr, MCA_DMA_REG_FN);
 135        outb(count & 0xff, MCA_DMA_REG_EXE);
 136        outb((count >> 8) & 0xff, MCA_DMA_REG_EXE);
 137}
 138
 139/**
 140 *      mca_get_dma_residue -   get the remaining bytes to transfer
 141 *      @dmanr: DMA channel
 142 *
 143 *      This function returns the number of bytes left to transfer
 144 *      on this DMA channel.
 145 */
 146
 147static inline unsigned int mca_get_dma_residue(unsigned int dmanr)
 148{
 149        unsigned short count;
 150
 151        outb(MCA_DMA_FN_GET_COUNT | dmanr, MCA_DMA_REG_FN);
 152        count = 1 + inb(MCA_DMA_REG_EXE);
 153        count += inb(MCA_DMA_REG_EXE) << 8;
 154
 155        return count;
 156}
 157
 158/**
 159 *      mca_set_dma_io -        set the port for an I/O transfer
 160 *      @dmanr: DMA channel
 161 *      @io_addr: an I/O port number
 162 *
 163 *      Unlike the ISA bus DMA controllers the DMA on MCA bus can transfer
 164 *      with an I/O port target.
 165 */
 166
 167static inline void mca_set_dma_io(unsigned int dmanr, unsigned int io_addr)
 168{
 169        /*
 170         * DMA from a port address -- set the io address
 171         */
 172
 173        outb(MCA_DMA_FN_SET_IO | dmanr, MCA_DMA_REG_FN);
 174        outb(io_addr & 0xff, MCA_DMA_REG_EXE);
 175        outb((io_addr >>  8) & 0xff, MCA_DMA_REG_EXE);
 176}
 177
 178/**
 179 *      mca_set_dma_mode -      set the DMA mode
 180 *      @dmanr: DMA channel
 181 *      @mode: mode to set
 182 *
 183 *      The DMA controller supports several modes. The mode values you can
 184 *      set are-
 185 *
 186 *      %MCA_DMA_MODE_READ when reading from the DMA device.
 187 *
 188 *      %MCA_DMA_MODE_WRITE to writing to the DMA device.
 189 *
 190 *      %MCA_DMA_MODE_IO to do DMA to or from an I/O port.
 191 *
 192 *      %MCA_DMA_MODE_16 to do 16bit transfers.
 193 */
 194
 195static inline void mca_set_dma_mode(unsigned int dmanr, unsigned int mode)
 196{
 197        outb(MCA_DMA_FN_SET_MODE | dmanr, MCA_DMA_REG_FN);
 198        outb(mode, MCA_DMA_REG_EXE);
 199}
 200
 201#endif /* _ASM_X86_MCA_DMA_H */
 202