summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/dma-arc.c
blob: 53ef12b1c5866a551adad93f9a3438ddac7e65c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
 * arch/arm/kernel/dma-arc.c
 *
 * Copyright (C) 1998-1999 Dave Gilbert / Russell King
 *
 * DMA functions specific to Archimedes architecture
 */
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/init.h>

#include <asm/dma.h>
#include <asm/io.h>
#include <asm/hardware.h>

#include "dma.h"

#define DEBUG

int arch_request_dma(dmach_t channel, dma_t *dma, const char * dev_id)
{
  printk("arch_request_dma channel=%d F0=%d F1=%d\n",channel,DMA_VIRTUAL_FLOPPY0,DMA_VIRTUAL_FLOPPY1);
	if (channel == DMA_VIRTUAL_FLOPPY0 ||
	    channel == DMA_VIRTUAL_FLOPPY1)
		return 0;
	else
		return -EINVAL;
}

void arch_free_dma(dmach_t channel, dma_t *dma)
{
}

void arch_enable_dma(dmach_t channel, dma_t *dma)
{
  printk("arch_enable_dma channel=%d F0=%d F1=%d\n",channel,DMA_VIRTUAL_FLOPPY0,DMA_VIRTUAL_FLOPPY1);
	switch (channel) {
#ifdef CONFIG_BLK_DEV_FD1772
	case DMA_VIRTUAL_FLOPPY0: { /* Data DMA */
		switch (dma->dma_mode) {
		case DMA_MODE_READ: /* read */
    	    	{
			extern unsigned char fdc1772_dma_read, fdc1772_dma_read_end;
			extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
			unsigned long flags;
#ifdef DEBUG
			printk("enable_dma fdc1772 data read\n");
#endif
			save_flags(flags);
			cliIF();
			
			memcpy ((void *)0x1c, (void *)&fdc1772_dma_read,
				&fdc1772_dma_read_end - &fdc1772_dma_read);
			fdc1772_setupdma(dma->buf.length, __bus_to_virt(dma->buf.address)); /* Sets data pointer up */
			enable_irq (64);
			restore_flags(flags);
		}
		break;

		case DMA_MODE_WRITE: /* write */
	        {
			extern unsigned char fdc1772_dma_write, fdc1772_dma_write_end;
			extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
			unsigned long flags;

#ifdef DEBUG
			printk("enable_dma fdc1772 data write\n");
#endif
			save_flags(flags);
			cliIF();
			memcpy ((void *)0x1c, (void *)&fdc1772_dma_write,
				&fdc1772_dma_write_end - &fdc1772_dma_write);
			fdc1772_setupdma(dma->buf.length, __bus_to_virt(dma->buf.address)); /* Sets data pointer up */
			enable_irq (64);

			restore_flags(flags);
		}
		break;
    		default:
			printk ("enable_dma: dma%d not initialised\n", channel);
			return;
		}
	}
	break;

	case DMA_VIRTUAL_FLOPPY1: { /* Command end FIQ - actually just sets a flag */
		/* Need to build a branch at the FIQ address */
		extern void fdc1772_comendhandler(void);
		unsigned long flags;

		/*printk("enable_dma fdc1772 command end FIQ\n");*/
		save_flags(flags);
		cliIF();
	
		*((unsigned int *)0x1c)=0xea000000 | (((unsigned int)fdc1772_comendhandler-(0x1c+8))/4); /* B fdc1772_comendhandler */

		restore_flags(flags);
	}
	break;
#endif
	}
}

int arch_get_dma_residue(dmach_t channel, dma_t *dma)
{
  switch (channel) {
#ifdef CONFIG_BLK_DEV_FD1772
    case DMA_VIRTUAL_FLOPPY0: { /* Data DMA */
        extern unsigned int fdc1772_bytestogo;

        /* 10/1/1999 DAG - I presume its the number of bytes left? */
        return fdc1772_bytestogo;
      };
      break;

    case DMA_VIRTUAL_FLOPPY1: { /* Command completed */
        /* 10/1/1999 DAG - Presume whether there is an outstanding command? */
        extern unsigned int fdc1772_fdc_int_done;

        return (fdc1772_fdc_int_done==0)?1:0; /* Explicit! If the int done is 0 then 1 int to go */
      };
      break;

#endif

    default:
      printk("dma-arc.c:arch_get_dma_residue called with unknown/unconfigured DMA channel\n");
      return 0;
  };
}

void arch_disable_dma(dmach_t channel, dma_t *dma)
{
	if (channel != DMA_VIRTUAL_FLOPPY0 &&
	    channel != DMA_VIRTUAL_FLOPPY1)
		printk("arch_disable_dma: invalid channel %d\n", channel);
	else
		disable_irq(dma->dma_irq);
}

int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle_ns)
{
	return 0;
}

void __init arch_dma_init(dma_t *dma)
{
	dma[DMA_VIRTUAL_FLOPPY0].dma_irq = 64;
	dma[DMA_VIRTUAL_FLOPPY1].dma_irq = 65;
}