diff options
Diffstat (limited to 'drivers/ide/legacy/buddha.c')
-rw-r--r-- | drivers/ide/legacy/buddha.c | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c new file mode 100644 index 000000000000..0391a3122878 --- /dev/null +++ b/drivers/ide/legacy/buddha.c | |||
@@ -0,0 +1,235 @@ | |||
1 | /* | ||
2 | * linux/drivers/ide/legacy/buddha.c -- Amiga Buddha, Catweasel and X-Surf IDE Driver | ||
3 | * | ||
4 | * Copyright (C) 1997, 2001 by Geert Uytterhoeven and others | ||
5 | * | ||
6 | * This driver was written based on the specifications in README.buddha and | ||
7 | * the X-Surf info from Inside_XSurf.txt available at | ||
8 | * http://www.jschoenfeld.com | ||
9 | * | ||
10 | * This file is subject to the terms and conditions of the GNU General Public | ||
11 | * License. See the file COPYING in the main directory of this archive for | ||
12 | * more details. | ||
13 | * | ||
14 | * TODO: | ||
15 | * - test it :-) | ||
16 | * - tune the timings using the speed-register | ||
17 | */ | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <linux/mm.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/blkdev.h> | ||
23 | #include <linux/hdreg.h> | ||
24 | #include <linux/zorro.h> | ||
25 | #include <linux/ide.h> | ||
26 | #include <linux/init.h> | ||
27 | |||
28 | #include <asm/amigahw.h> | ||
29 | #include <asm/amigaints.h> | ||
30 | |||
31 | |||
32 | /* | ||
33 | * The Buddha has 2 IDE interfaces, the Catweasel has 3, X-Surf has 2 | ||
34 | */ | ||
35 | |||
36 | #define BUDDHA_NUM_HWIFS 2 | ||
37 | #define CATWEASEL_NUM_HWIFS 3 | ||
38 | #define XSURF_NUM_HWIFS 2 | ||
39 | |||
40 | /* | ||
41 | * Bases of the IDE interfaces (relative to the board address) | ||
42 | */ | ||
43 | |||
44 | #define BUDDHA_BASE1 0x800 | ||
45 | #define BUDDHA_BASE2 0xa00 | ||
46 | #define BUDDHA_BASE3 0xc00 | ||
47 | |||
48 | #define XSURF_BASE1 0xb000 /* 2.5" Interface */ | ||
49 | #define XSURF_BASE2 0xd000 /* 3.5" Interface */ | ||
50 | |||
51 | static u_int buddha_bases[CATWEASEL_NUM_HWIFS] __initdata = { | ||
52 | BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3 | ||
53 | }; | ||
54 | |||
55 | static u_int xsurf_bases[XSURF_NUM_HWIFS] __initdata = { | ||
56 | XSURF_BASE1, XSURF_BASE2 | ||
57 | }; | ||
58 | |||
59 | |||
60 | /* | ||
61 | * Offsets from one of the above bases | ||
62 | */ | ||
63 | |||
64 | #define BUDDHA_DATA 0x00 | ||
65 | #define BUDDHA_ERROR 0x06 /* see err-bits */ | ||
66 | #define BUDDHA_NSECTOR 0x0a /* nr of sectors to read/write */ | ||
67 | #define BUDDHA_SECTOR 0x0e /* starting sector */ | ||
68 | #define BUDDHA_LCYL 0x12 /* starting cylinder */ | ||
69 | #define BUDDHA_HCYL 0x16 /* high byte of starting cyl */ | ||
70 | #define BUDDHA_SELECT 0x1a /* 101dhhhh , d=drive, hhhh=head */ | ||
71 | #define BUDDHA_STATUS 0x1e /* see status-bits */ | ||
72 | #define BUDDHA_CONTROL 0x11a | ||
73 | #define XSURF_CONTROL -1 /* X-Surf has no CS1* (Control/AltStat) */ | ||
74 | |||
75 | static int buddha_offsets[IDE_NR_PORTS] __initdata = { | ||
76 | BUDDHA_DATA, BUDDHA_ERROR, BUDDHA_NSECTOR, BUDDHA_SECTOR, BUDDHA_LCYL, | ||
77 | BUDDHA_HCYL, BUDDHA_SELECT, BUDDHA_STATUS, BUDDHA_CONTROL, -1 | ||
78 | }; | ||
79 | |||
80 | static int xsurf_offsets[IDE_NR_PORTS] __initdata = { | ||
81 | BUDDHA_DATA, BUDDHA_ERROR, BUDDHA_NSECTOR, BUDDHA_SECTOR, BUDDHA_LCYL, | ||
82 | BUDDHA_HCYL, BUDDHA_SELECT, BUDDHA_STATUS, XSURF_CONTROL, -1 | ||
83 | }; | ||
84 | |||
85 | /* | ||
86 | * Other registers | ||
87 | */ | ||
88 | |||
89 | #define BUDDHA_IRQ1 0xf00 /* MSB = 1, Harddisk is source of */ | ||
90 | #define BUDDHA_IRQ2 0xf40 /* interrupt */ | ||
91 | #define BUDDHA_IRQ3 0xf80 | ||
92 | |||
93 | #define XSURF_IRQ1 0x7e | ||
94 | #define XSURF_IRQ2 0x7e | ||
95 | |||
96 | static int buddha_irqports[CATWEASEL_NUM_HWIFS] __initdata = { | ||
97 | BUDDHA_IRQ1, BUDDHA_IRQ2, BUDDHA_IRQ3 | ||
98 | }; | ||
99 | |||
100 | static int xsurf_irqports[XSURF_NUM_HWIFS] __initdata = { | ||
101 | XSURF_IRQ1, XSURF_IRQ2 | ||
102 | }; | ||
103 | |||
104 | #define BUDDHA_IRQ_MR 0xfc0 /* master interrupt enable */ | ||
105 | |||
106 | |||
107 | /* | ||
108 | * Board information | ||
109 | */ | ||
110 | |||
111 | typedef enum BuddhaType_Enum { | ||
112 | BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF | ||
113 | } BuddhaType; | ||
114 | |||
115 | |||
116 | /* | ||
117 | * Check and acknowledge the interrupt status | ||
118 | */ | ||
119 | |||
120 | static int buddha_ack_intr(ide_hwif_t *hwif) | ||
121 | { | ||
122 | unsigned char ch; | ||
123 | |||
124 | ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]); | ||
125 | if (!(ch & 0x80)) | ||
126 | return 0; | ||
127 | return 1; | ||
128 | } | ||
129 | |||
130 | static int xsurf_ack_intr(ide_hwif_t *hwif) | ||
131 | { | ||
132 | unsigned char ch; | ||
133 | |||
134 | ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]); | ||
135 | /* X-Surf needs a 0 written to IRQ register to ensure ISA bit A11 stays at 0 */ | ||
136 | z_writeb(0, hwif->io_ports[IDE_IRQ_OFFSET]); | ||
137 | if (!(ch & 0x80)) | ||
138 | return 0; | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * Probe for a Buddha or Catweasel IDE interface | ||
144 | */ | ||
145 | |||
146 | void __init buddha_init(void) | ||
147 | { | ||
148 | hw_regs_t hw; | ||
149 | ide_hwif_t *hwif; | ||
150 | int i, index; | ||
151 | |||
152 | struct zorro_dev *z = NULL; | ||
153 | u_long buddha_board = 0; | ||
154 | BuddhaType type; | ||
155 | int buddha_num_hwifs; | ||
156 | |||
157 | while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { | ||
158 | unsigned long board; | ||
159 | if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { | ||
160 | buddha_num_hwifs = BUDDHA_NUM_HWIFS; | ||
161 | type=BOARD_BUDDHA; | ||
162 | } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) { | ||
163 | buddha_num_hwifs = CATWEASEL_NUM_HWIFS; | ||
164 | type=BOARD_CATWEASEL; | ||
165 | } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) { | ||
166 | buddha_num_hwifs = XSURF_NUM_HWIFS; | ||
167 | type=BOARD_XSURF; | ||
168 | } else | ||
169 | continue; | ||
170 | |||
171 | board = z->resource.start; | ||
172 | |||
173 | /* | ||
174 | * FIXME: we now have selectable mmio v/s iomio transports. | ||
175 | */ | ||
176 | |||
177 | if(type != BOARD_XSURF) { | ||
178 | if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE")) | ||
179 | continue; | ||
180 | } else { | ||
181 | if (!request_mem_region(board+XSURF_BASE1, 0x1000, "IDE")) | ||
182 | continue; | ||
183 | if (!request_mem_region(board+XSURF_BASE2, 0x1000, "IDE")) | ||
184 | goto fail_base2; | ||
185 | if (!request_mem_region(board+XSURF_IRQ1, 0x8, "IDE")) { | ||
186 | release_mem_region(board+XSURF_BASE2, 0x1000); | ||
187 | fail_base2: | ||
188 | release_mem_region(board+XSURF_BASE1, 0x1000); | ||
189 | continue; | ||
190 | } | ||
191 | } | ||
192 | buddha_board = ZTWO_VADDR(board); | ||
193 | |||
194 | /* write to BUDDHA_IRQ_MR to enable the board IRQ */ | ||
195 | /* X-Surf doesn't have this. IRQs are always on */ | ||
196 | if (type != BOARD_XSURF) | ||
197 | z_writeb(0, buddha_board+BUDDHA_IRQ_MR); | ||
198 | |||
199 | for(i=0;i<buddha_num_hwifs;i++) { | ||
200 | if(type != BOARD_XSURF) { | ||
201 | ide_setup_ports(&hw, (buddha_board+buddha_bases[i]), | ||
202 | buddha_offsets, 0, | ||
203 | (buddha_board+buddha_irqports[i]), | ||
204 | buddha_ack_intr, | ||
205 | // budda_iops, | ||
206 | IRQ_AMIGA_PORTS); | ||
207 | } else { | ||
208 | ide_setup_ports(&hw, (buddha_board+xsurf_bases[i]), | ||
209 | xsurf_offsets, 0, | ||
210 | (buddha_board+xsurf_irqports[i]), | ||
211 | xsurf_ack_intr, | ||
212 | // xsurf_iops, | ||
213 | IRQ_AMIGA_PORTS); | ||
214 | } | ||
215 | |||
216 | index = ide_register_hw(&hw, &hwif); | ||
217 | if (index != -1) { | ||
218 | hwif->mmio = 2; | ||
219 | printk("ide%d: ", index); | ||
220 | switch(type) { | ||
221 | case BOARD_BUDDHA: | ||
222 | printk("Buddha"); | ||
223 | break; | ||
224 | case BOARD_CATWEASEL: | ||
225 | printk("Catweasel"); | ||
226 | break; | ||
227 | case BOARD_XSURF: | ||
228 | printk("X-Surf"); | ||
229 | break; | ||
230 | } | ||
231 | printk(" IDE interface\n"); | ||
232 | } | ||
233 | } | ||
234 | } | ||
235 | } | ||