Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  linux/arch/arm/kernel/dma-isa.c
0004  *
0005  *  Copyright (C) 1999-2000 Russell King
0006  *
0007  *  ISA DMA primitives
0008  *  Taken from various sources, including:
0009  *   linux/include/asm/dma.h: Defines for using and allocating dma channels.
0010  *     Written by Hennus Bergman, 1992.
0011  *     High DMA channel support & info by Hannu Savolainen and John Boyd,
0012  *     Nov. 1992.
0013  *   arch/arm/kernel/dma-ebsa285.c
0014  *   Copyright (C) 1998 Phil Blundell
0015  */
0016 #include <linux/ioport.h>
0017 #include <linux/init.h>
0018 #include <linux/dma-mapping.h>
0019 #include <linux/io.h>
0020 
0021 #include <asm/dma.h>
0022 #include <asm/mach/dma.h>
0023 
0024 #define ISA_DMA_MASK        0
0025 #define ISA_DMA_MODE        1
0026 #define ISA_DMA_CLRFF       2
0027 #define ISA_DMA_PGHI        3
0028 #define ISA_DMA_PGLO        4
0029 #define ISA_DMA_ADDR        5
0030 #define ISA_DMA_COUNT       6
0031 
0032 static unsigned int isa_dma_port[8][7] = {
0033     /* MASK   MODE   CLRFF  PAGE_HI PAGE_LO ADDR COUNT */
0034     {  0x0a,  0x0b,  0x0c,  0x487,  0x087,  0x00, 0x01 },
0035     {  0x0a,  0x0b,  0x0c,  0x483,  0x083,  0x02, 0x03 },
0036     {  0x0a,  0x0b,  0x0c,  0x481,  0x081,  0x04, 0x05 },
0037     {  0x0a,  0x0b,  0x0c,  0x482,  0x082,  0x06, 0x07 },
0038     {  0xd4,  0xd6,  0xd8,  0x000,  0x000,  0xc0, 0xc2 },
0039     {  0xd4,  0xd6,  0xd8,  0x48b,  0x08b,  0xc4, 0xc6 },
0040     {  0xd4,  0xd6,  0xd8,  0x489,  0x089,  0xc8, 0xca },
0041     {  0xd4,  0xd6,  0xd8,  0x48a,  0x08a,  0xcc, 0xce }
0042 };
0043 
0044 static int isa_get_dma_residue(unsigned int chan, dma_t *dma)
0045 {
0046     unsigned int io_port = isa_dma_port[chan][ISA_DMA_COUNT];
0047     int count;
0048 
0049     count = 1 + inb(io_port);
0050     count |= inb(io_port) << 8;
0051 
0052     return chan < 4 ? count : (count << 1);
0053 }
0054 
0055 static struct device isa_dma_dev = {
0056     .init_name      = "fallback device",
0057     .coherent_dma_mask  = ~(dma_addr_t)0,
0058     .dma_mask       = &isa_dma_dev.coherent_dma_mask,
0059 };
0060 
0061 static void isa_enable_dma(unsigned int chan, dma_t *dma)
0062 {
0063     if (dma->invalid) {
0064         unsigned long address, length;
0065         unsigned int mode;
0066         enum dma_data_direction direction;
0067 
0068         mode = (chan & 3) | dma->dma_mode;
0069         switch (dma->dma_mode & DMA_MODE_MASK) {
0070         case DMA_MODE_READ:
0071             direction = DMA_FROM_DEVICE;
0072             break;
0073 
0074         case DMA_MODE_WRITE:
0075             direction = DMA_TO_DEVICE;
0076             break;
0077 
0078         case DMA_MODE_CASCADE:
0079             direction = DMA_BIDIRECTIONAL;
0080             break;
0081 
0082         default:
0083             direction = DMA_NONE;
0084             break;
0085         }
0086 
0087         if (!dma->sg) {
0088             /*
0089              * Cope with ISA-style drivers which expect cache
0090              * coherence.
0091              */
0092             dma->sg = &dma->buf;
0093             dma->sgcount = 1;
0094             dma->buf.length = dma->count;
0095             dma->buf.dma_address = dma_map_single(&isa_dma_dev,
0096                 dma->addr, dma->count,
0097                 direction);
0098         }
0099 
0100         address = dma->buf.dma_address;
0101         length  = dma->buf.length - 1;
0102 
0103         outb(address >> 16, isa_dma_port[chan][ISA_DMA_PGLO]);
0104         outb(address >> 24, isa_dma_port[chan][ISA_DMA_PGHI]);
0105 
0106         if (chan >= 4) {
0107             address >>= 1;
0108             length >>= 1;
0109         }
0110 
0111         outb(0, isa_dma_port[chan][ISA_DMA_CLRFF]);
0112 
0113         outb(address, isa_dma_port[chan][ISA_DMA_ADDR]);
0114         outb(address >> 8, isa_dma_port[chan][ISA_DMA_ADDR]);
0115 
0116         outb(length, isa_dma_port[chan][ISA_DMA_COUNT]);
0117         outb(length >> 8, isa_dma_port[chan][ISA_DMA_COUNT]);
0118 
0119         outb(mode, isa_dma_port[chan][ISA_DMA_MODE]);
0120         dma->invalid = 0;
0121     }
0122     outb(chan & 3, isa_dma_port[chan][ISA_DMA_MASK]);
0123 }
0124 
0125 static void isa_disable_dma(unsigned int chan, dma_t *dma)
0126 {
0127     outb(chan | 4, isa_dma_port[chan][ISA_DMA_MASK]);
0128 }
0129 
0130 static struct dma_ops isa_dma_ops = {
0131     .type       = "ISA",
0132     .enable     = isa_enable_dma,
0133     .disable    = isa_disable_dma,
0134     .residue    = isa_get_dma_residue,
0135 };
0136 
0137 static struct resource dma_resources[] = { {
0138     .name   = "dma1",
0139     .start  = 0x0000,
0140     .end    = 0x000f
0141 }, {
0142     .name   = "dma low page",
0143     .start  = 0x0080,
0144     .end    = 0x008f
0145 }, {
0146     .name   = "dma2",
0147     .start  = 0x00c0,
0148     .end    = 0x00df
0149 }, {
0150     .name   = "dma high page",
0151     .start  = 0x0480,
0152     .end    = 0x048f
0153 } };
0154 
0155 static dma_t isa_dma[8];
0156 
0157 /*
0158  * ISA DMA always starts at channel 0
0159  */
0160 void __init isa_init_dma(void)
0161 {
0162     /*
0163      * Try to autodetect presence of an ISA DMA controller.
0164      * We do some minimal initialisation, and check that
0165      * channel 0's DMA address registers are writeable.
0166      */
0167     outb(0xff, 0x0d);
0168     outb(0xff, 0xda);
0169 
0170     /*
0171      * Write high and low address, and then read them back
0172      * in the same order.
0173      */
0174     outb(0x55, 0x00);
0175     outb(0xaa, 0x00);
0176 
0177     if (inb(0) == 0x55 && inb(0) == 0xaa) {
0178         unsigned int chan, i;
0179 
0180         for (chan = 0; chan < 8; chan++) {
0181             isa_dma[chan].d_ops = &isa_dma_ops;
0182             isa_disable_dma(chan, NULL);
0183         }
0184 
0185         outb(0x40, 0x0b);
0186         outb(0x41, 0x0b);
0187         outb(0x42, 0x0b);
0188         outb(0x43, 0x0b);
0189 
0190         outb(0xc0, 0xd6);
0191         outb(0x41, 0xd6);
0192         outb(0x42, 0xd6);
0193         outb(0x43, 0xd6);
0194 
0195         outb(0, 0xd4);
0196 
0197         outb(0x10, 0x08);
0198         outb(0x10, 0xd0);
0199 
0200         /*
0201          * Is this correct?  According to my documentation, it
0202          * doesn't appear to be.  It should be:
0203          *  outb(0x3f, 0x40b); outb(0x3f, 0x4d6);
0204          */
0205         outb(0x30, 0x40b);
0206         outb(0x31, 0x40b);
0207         outb(0x32, 0x40b);
0208         outb(0x33, 0x40b);
0209         outb(0x31, 0x4d6);
0210         outb(0x32, 0x4d6);
0211         outb(0x33, 0x4d6);
0212 
0213         for (i = 0; i < ARRAY_SIZE(dma_resources); i++)
0214             request_resource(&ioport_resource, dma_resources + i);
0215 
0216         for (chan = 0; chan < 8; chan++) {
0217             int ret = isa_dma_add(chan, &isa_dma[chan]);
0218             if (ret)
0219                 pr_err("ISADMA%u: unable to register: %d\n",
0220                        chan, ret);
0221         }
0222 
0223         request_dma(DMA_ISA_CASCADE, "cascade");
0224     }
0225 }