Blame view

drivers/ide/au1xxx-ide.c 15 KB
26a940e21   Pete Popov   Cleaned up AMD Au...
1
  /*
26a940e21   Pete Popov   Cleaned up AMD Au...
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
   * BRIEF MODULE DESCRIPTION
   * AMD Alchemy Au1xxx IDE interface routines over the Static Bus
   *
   * Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions
   *
   * This program is free software; you can redistribute it and/or modify it under
   * the terms of the GNU General Public License as published by the Free Software
   * Foundation; either version 2 of the License, or (at your option) any later
   * version.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   * POSSIBILITY OF SUCH DAMAGE.
   *
   * You should have received a copy of the GNU General Public License along with
   * this program; if not, write to the Free Software Foundation, Inc.,
   * 675 Mass Ave, Cambridge, MA 02139, USA.
   *
   * Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE
   *       Interface and Linux Device Driver" Application Note.
   */
26a940e21   Pete Popov   Cleaned up AMD Au...
30
31
32
33
  #include <linux/types.h>
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/delay.h>
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
34
  #include <linux/platform_device.h>
26a940e21   Pete Popov   Cleaned up AMD Au...
35
36
  #include <linux/init.h>
  #include <linux/ide.h>
fabd3a223   Sergei Shtylyov   Au1200: IDE drive...
37
  #include <linux/scatterlist.h>
26a940e21   Pete Popov   Cleaned up AMD Au...
38

26a940e21   Pete Popov   Cleaned up AMD Au...
39
40
  #include <asm/mach-au1x00/au1xxx.h>
  #include <asm/mach-au1x00/au1xxx_dbdma.h>
26a940e21   Pete Popov   Cleaned up AMD Au...
41
42
43
  #include <asm/mach-au1x00/au1xxx_ide.h>
  
  #define DRV_NAME	"au1200-ide"
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
44
  #define DRV_AUTHOR	"Enrico Walther <enrico.walther@amd.com> / Pete Popov <ppopov@embeddedalley.com>"
26a940e21   Pete Popov   Cleaned up AMD Au...
45

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
46
47
  /* enable the burstmode in the dbdma */
  #define IDE_AU1XXX_BURSTMODE	1
26a940e21   Pete Popov   Cleaned up AMD Au...
48

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
49
  static _auide_hwif auide_hwif;
26a940e21   Pete Popov   Cleaned up AMD Au...
50

26a940e21   Pete Popov   Cleaned up AMD Au...
51
  #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
985232e38   Sergei Shtylyov   au1xxx-ide: auide...
52
  static inline void auide_insw(unsigned long port, void *addr, u32 count)
26a940e21   Pete Popov   Cleaned up AMD Au...
53
  {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
54
55
56
  	_auide_hwif *ahwif = &auide_hwif;
  	chan_tab_t *ctp;
  	au1x_ddma_desc_t *dp;
26a940e21   Pete Popov   Cleaned up AMD Au...
57

963accbc8   Manuel Lauss   MIPS: Alchemy: ch...
58
  	if (!au1xxx_dbdma_put_dest(ahwif->rx_chan, virt_to_phys(addr),
ea071cc70   Manuel Lauss   MIPS: Alchemy: re...
59
  				   count << 1, DDMA_FLAGS_NOIE)) {
eb63963a5   Harvey Harrison   ide: replace rema...
60
61
  		printk(KERN_ERR "%s failed %d
  ", __func__, __LINE__);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
62
63
64
65
66
67
68
  		return;
  	}
  	ctp = *((chan_tab_t **)ahwif->rx_chan);
  	dp = ctp->cur_ptr;
  	while (dp->dscr_cmd0 & DSCR_CMD0_V)
  		;
  	ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
26a940e21   Pete Popov   Cleaned up AMD Au...
69
  }
985232e38   Sergei Shtylyov   au1xxx-ide: auide...
70
  static inline void auide_outsw(unsigned long port, void *addr, u32 count)
26a940e21   Pete Popov   Cleaned up AMD Au...
71
  {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
72
73
74
  	_auide_hwif *ahwif = &auide_hwif;
  	chan_tab_t *ctp;
  	au1x_ddma_desc_t *dp;
26a940e21   Pete Popov   Cleaned up AMD Au...
75

963accbc8   Manuel Lauss   MIPS: Alchemy: ch...
76
  	if (!au1xxx_dbdma_put_source(ahwif->tx_chan, virt_to_phys(addr),
ea071cc70   Manuel Lauss   MIPS: Alchemy: re...
77
  				     count << 1, DDMA_FLAGS_NOIE)) {
eb63963a5   Harvey Harrison   ide: replace rema...
78
79
  		printk(KERN_ERR "%s failed %d
  ", __func__, __LINE__);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
80
81
82
83
84
85
86
  		return;
  	}
  	ctp = *((chan_tab_t **)ahwif->tx_chan);
  	dp = ctp->cur_ptr;
  	while (dp->dscr_cmd0 & DSCR_CMD0_V)
  		;
  	ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
26a940e21   Pete Popov   Cleaned up AMD Au...
87
  }
adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
88
  static void au1xxx_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
70f91e0d1   Bartlomiej Zolnierkiewicz   au1xxx-ide: add -...
89
90
91
92
  			      void *buf, unsigned int len)
  {
  	auide_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
  }
adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
93
  static void au1xxx_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
70f91e0d1   Bartlomiej Zolnierkiewicz   au1xxx-ide: add -...
94
95
96
97
  			       void *buf, unsigned int len)
  {
  	auide_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
  }
26a940e21   Pete Popov   Cleaned up AMD Au...
98
  #endif
26a940e21   Pete Popov   Cleaned up AMD Au...
99

e085b3cae   Bartlomiej Zolnierkiewicz   ide: change ->set...
100
  static void au1xxx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
26a940e21   Pete Popov   Cleaned up AMD Au...
101
  {
88b2b32ba   Bartlomiej Zolnierkiewicz   ide: move ide_con...
102
  	int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
103

e085b3cae   Bartlomiej Zolnierkiewicz   ide: change ->set...
104
  	switch (drive->pio_mode - XFER_PIO_0) {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
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
151
152
153
154
155
156
157
158
  	case 0:
  		mem_sttime = SBC_IDE_TIMING(PIO0);
  
  		/* set configuration for RCS2# */
  		mem_stcfg |= TS_MASK;
  		mem_stcfg &= ~TCSOE_MASK;
  		mem_stcfg &= ~TOECS_MASK;
  		mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
  		break;
  
  	case 1:
  		mem_sttime = SBC_IDE_TIMING(PIO1);
  
  		/* set configuration for RCS2# */
  		mem_stcfg |= TS_MASK;
  		mem_stcfg &= ~TCSOE_MASK;
  		mem_stcfg &= ~TOECS_MASK;
  		mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS;
  		break;
  
  	case 2:
  		mem_sttime = SBC_IDE_TIMING(PIO2);
  
  		/* set configuration for RCS2# */
  		mem_stcfg &= ~TS_MASK;
  		mem_stcfg &= ~TCSOE_MASK;
  		mem_stcfg &= ~TOECS_MASK;
  		mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS;
  		break;
  
  	case 3:
  		mem_sttime = SBC_IDE_TIMING(PIO3);
  
  		/* set configuration for RCS2# */
  		mem_stcfg &= ~TS_MASK;
  		mem_stcfg &= ~TCSOE_MASK;
  		mem_stcfg &= ~TOECS_MASK;
  		mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS;
  
  		break;
  
  	case 4:
  		mem_sttime = SBC_IDE_TIMING(PIO4);
  
  		/* set configuration for RCS2# */
  		mem_stcfg &= ~TS_MASK;
  		mem_stcfg &= ~TCSOE_MASK;
  		mem_stcfg &= ~TOECS_MASK;
  		mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS;
  		break;
  	}
  
  	au_writel(mem_sttime,MEM_STTIME2);
  	au_writel(mem_stcfg,MEM_STCFG2);
26a940e21   Pete Popov   Cleaned up AMD Au...
159
  }
8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
160
  static void auide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
26a940e21   Pete Popov   Cleaned up AMD Au...
161
  {
88b2b32ba   Bartlomiej Zolnierkiewicz   ide: move ide_con...
162
  	int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
26a940e21   Pete Popov   Cleaned up AMD Au...
163

8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
164
  	switch (drive->dma_mode) {
26a940e21   Pete Popov   Cleaned up AMD Au...
165
  #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
166
167
168
169
170
171
172
173
  	case XFER_MW_DMA_2:
  		mem_sttime = SBC_IDE_TIMING(MDMA2);
  
  		/* set configuration for RCS2# */
  		mem_stcfg &= ~TS_MASK;
  		mem_stcfg &= ~TCSOE_MASK;
  		mem_stcfg &= ~TOECS_MASK;
  		mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
174
175
176
177
178
179
180
181
182
  		break;
  	case XFER_MW_DMA_1:
  		mem_sttime = SBC_IDE_TIMING(MDMA1);
  
  		/* set configuration for RCS2# */
  		mem_stcfg &= ~TS_MASK;
  		mem_stcfg &= ~TCSOE_MASK;
  		mem_stcfg &= ~TOECS_MASK;
  		mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
183
184
185
186
187
188
189
190
191
  		break;
  	case XFER_MW_DMA_0:
  		mem_sttime = SBC_IDE_TIMING(MDMA0);
  
  		/* set configuration for RCS2# */
  		mem_stcfg |= TS_MASK;
  		mem_stcfg &= ~TCSOE_MASK;
  		mem_stcfg &= ~TOECS_MASK;
  		mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
192
  		break;
26a940e21   Pete Popov   Cleaned up AMD Au...
193
  #endif
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
194
  	}
a523a1759   Bartlomiej Zolnierkiewicz   au1xxx-ide: remov...
195

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
196
197
  	au_writel(mem_sttime,MEM_STTIME2);
  	au_writel(mem_stcfg,MEM_STCFG2);
26a940e21   Pete Popov   Cleaned up AMD Au...
198
199
200
201
202
  }
  
  /*
   * Multi-Word DMA + DbDMA functions
   */
26a940e21   Pete Popov   Cleaned up AMD Au...
203

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
204
  #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
205
  static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
26a940e21   Pete Popov   Cleaned up AMD Au...
206
  {
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
207
  	ide_hwif_t *hwif = drive->hwif;
a536f326a   Bartlomiej Zolnierkiewicz   au1xxx-ide: don't...
208
  	_auide_hwif *ahwif = &auide_hwif;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
209
  	struct scatterlist *sg;
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
210
211
  	int i = cmd->sg_nents, count = 0;
  	int iswrite = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
212

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
213
214
  	/* Save for interrupt context */
  	ahwif->drive = drive;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
  	/* fill the descriptors */
  	sg = hwif->sg_table;
  	while (i && sg_dma_len(sg)) {
  		u32 cur_addr;
  		u32 cur_len;
  
  		cur_addr = sg_dma_address(sg);
  		cur_len = sg_dma_len(sg);
  
  		while (cur_len) {
  			u32 flags = DDMA_FLAGS_NOIE;
  			unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
  
  			if (++count >= PRD_ENTRIES) {
  				printk(KERN_WARNING "%s: DMA table too small
  ",
  				       drive->name);
11998b316   Bartlomiej Zolnierkiewicz   ide: move ide_map...
232
  				return 0;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
233
234
235
236
237
238
239
240
241
  			}
  
  			/* Lets enable intr for the last descriptor only */
  			if (1==i)
  				flags = DDMA_FLAGS_IE;
  			else
  				flags = DDMA_FLAGS_NOIE;
  
  			if (iswrite) {
ea071cc70   Manuel Lauss   MIPS: Alchemy: re...
242
  				if (!au1xxx_dbdma_put_source(ahwif->tx_chan,
963accbc8   Manuel Lauss   MIPS: Alchemy: ch...
243
  					sg_phys(sg), tc, flags)) {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
244
245
  					printk(KERN_ERR "%s failed %d
  ", 
eb63963a5   Harvey Harrison   ide: replace rema...
246
  					       __func__, __LINE__);
26a940e21   Pete Popov   Cleaned up AMD Au...
247
  				}
ea071cc70   Manuel Lauss   MIPS: Alchemy: re...
248
249
  			} else  {
  				if (!au1xxx_dbdma_put_dest(ahwif->rx_chan,
963accbc8   Manuel Lauss   MIPS: Alchemy: ch...
250
  					sg_phys(sg), tc, flags)) {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
251
252
  					printk(KERN_ERR "%s failed %d
  ", 
eb63963a5   Harvey Harrison   ide: replace rema...
253
  					       __func__, __LINE__);
26a940e21   Pete Popov   Cleaned up AMD Au...
254
  				}
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
255
  			}
26a940e21   Pete Popov   Cleaned up AMD Au...
256

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
257
258
259
  			cur_addr += tc;
  			cur_len -= tc;
  		}
55c16a700   Jens Axboe   IDE: sg chaining ...
260
  		sg = sg_next(sg);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
261
262
  		i--;
  	}
26a940e21   Pete Popov   Cleaned up AMD Au...
263

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
264
265
  	if (count)
  		return 1;
26a940e21   Pete Popov   Cleaned up AMD Au...
266

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
267
  	return 0; /* revert to PIO for this request */
26a940e21   Pete Popov   Cleaned up AMD Au...
268
269
270
271
  }
  
  static int auide_dma_end(ide_drive_t *drive)
  {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
272
  	return 0;
26a940e21   Pete Popov   Cleaned up AMD Au...
273
274
275
276
  }
  
  static void auide_dma_start(ide_drive_t *drive )
  {
26a940e21   Pete Popov   Cleaned up AMD Au...
277
  }
26a940e21   Pete Popov   Cleaned up AMD Au...
278

229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
279
  static int auide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
b65fac32c   Bartlomiej Zolnierkiewicz   ide: merge ide_hw...
280
  {
11998b316   Bartlomiej Zolnierkiewicz   ide: move ide_map...
281
  	if (auide_build_dmatable(drive, cmd) == 0)
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
282
  		return 1;
26a940e21   Pete Popov   Cleaned up AMD Au...
283

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
284
  	return 0;
26a940e21   Pete Popov   Cleaned up AMD Au...
285
  }
26a940e21   Pete Popov   Cleaned up AMD Au...
286
  static int auide_dma_test_irq(ide_drive_t *drive)
c67c216d8   Bartlomiej Zolnierkiewicz   ide: remove super...
287
  {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
288
289
  	/* If dbdma didn't execute the STOP command yet, the
  	 * active bit is still set
26a940e21   Pete Popov   Cleaned up AMD Au...
290
  	 */
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
291
292
  	drive->waiting_for_dma++;
  	if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
b1681c56f   Joe Perches   drivers/ide: Fix ...
293
294
295
  		printk(KERN_WARNING "%s: timeout waiting for ddma to complete
  ",
  		       drive->name);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
296
297
298
299
  		return 1;
  	}
  	udelay(10);
  	return 0;
26a940e21   Pete Popov   Cleaned up AMD Au...
300
  }
15ce926ad   Bartlomiej Zolnierkiewicz   ide: merge ->dma_...
301
  static void auide_dma_host_set(ide_drive_t *drive, int on)
26a940e21   Pete Popov   Cleaned up AMD Au...
302
  {
26a940e21   Pete Popov   Cleaned up AMD Au...
303
  }
53e62d3aa   Ralf Baechle   [PATCH] Alchemy: ...
304
  static void auide_ddma_tx_callback(int irq, void *param)
26a940e21   Pete Popov   Cleaned up AMD Au...
305
  {
26a940e21   Pete Popov   Cleaned up AMD Au...
306
  }
53e62d3aa   Ralf Baechle   [PATCH] Alchemy: ...
307
  static void auide_ddma_rx_callback(int irq, void *param)
26a940e21   Pete Popov   Cleaned up AMD Au...
308
  {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
309
  }
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
310
  #endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
26a940e21   Pete Popov   Cleaned up AMD Au...
311

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
312
313
314
  static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags)
  {
  	dev->dev_id          = dev_id;
fcbd3b4b9   Sergei Shtylyov   [MIPS] Pb1200/DBA...
315
  	dev->dev_physaddr    = (u32)IDE_PHYS_ADDR;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
316
317
318
319
320
  	dev->dev_intlevel    = 0;
  	dev->dev_intpolarity = 0;
  	dev->dev_tsize       = tsize;
  	dev->dev_devwidth    = devwidth;
  	dev->dev_flags       = flags;
26a940e21   Pete Popov   Cleaned up AMD Au...
321
  }
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
322
  #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
f37afdaca   Bartlomiej Zolnierkiewicz   ide: constify str...
323
  static const struct ide_dma_ops au1xxx_dma_ops = {
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
324
325
  	.dma_host_set		= auide_dma_host_set,
  	.dma_setup		= auide_dma_setup,
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
326
327
328
  	.dma_start		= auide_dma_start,
  	.dma_end		= auide_dma_end,
  	.dma_test_irq		= auide_dma_test_irq,
de23ec9ca   Bartlomiej Zolnierkiewicz   ide: make ide_dma...
329
  	.dma_lost_irq		= ide_dma_lost_irq,
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
330
  };
855286593   Bartlomiej Zolnierkiewicz   au1xxx-ide: use -...
331
332
  static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
  {
a536f326a   Bartlomiej Zolnierkiewicz   au1xxx-ide: don't...
333
  	_auide_hwif *auide = &auide_hwif;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
334
335
  	dbdev_tab_t source_dev_tab, target_dev_tab;
  	u32 dev_id, tsize, devwidth, flags;
26a940e21   Pete Popov   Cleaned up AMD Au...
336

fcbd3b4b9   Sergei Shtylyov   [MIPS] Pb1200/DBA...
337
  	dev_id	 = IDE_DDMA_REQ;
26a940e21   Pete Popov   Cleaned up AMD Au...
338

f629b38be   Bartlomiej Zolnierkiewicz   au1xxx-ide: fix M...
339
340
  	tsize    =  8; /*  1 */
  	devwidth = 32; /* 16 */
26a940e21   Pete Popov   Cleaned up AMD Au...
341

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
342
343
  #ifdef IDE_AU1XXX_BURSTMODE 
  	flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;
26a940e21   Pete Popov   Cleaned up AMD Au...
344
  #else
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
345
  	flags = DEV_FLAGS_SYNC;
26a940e21   Pete Popov   Cleaned up AMD Au...
346
  #endif
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
  	/* setup dev_tab for tx channel */
  	auide_init_dbdma_dev( &source_dev_tab,
  			      dev_id,
  			      tsize, devwidth, DEV_FLAGS_OUT | flags);
   	auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
  
  	auide_init_dbdma_dev( &source_dev_tab,
  			      dev_id,
  			      tsize, devwidth, DEV_FLAGS_IN | flags);
   	auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
  	
  	/* We also need to add a target device for the DMA */
  	auide_init_dbdma_dev( &target_dev_tab,
  			      (u32)DSCR_CMD0_ALWAYS,
  			      tsize, devwidth, DEV_FLAGS_ANYUSE);
  	auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab);	
   
  	/* Get a channel for TX */
  	auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id,
  						 auide->tx_dev_id,
  						 auide_ddma_tx_callback,
  						 (void*)auide);
   
  	/* Get a channel for RX */
  	auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
  						 auide->target_dev_id,
  						 auide_ddma_rx_callback,
  						 (void*)auide);
  
  	auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
  							     NUM_DESCRIPTORS);
  	auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
  							     NUM_DESCRIPTORS);
2bbd57cad   Bartlomiej Zolnierkiewicz   ide: switch to DM...
380
381
382
  
  	/* FIXME: check return value */
  	(void)ide_allocate_dma_engine(hwif);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
383
384
385
386
387
388
  	
  	au1xxx_dbdma_start( auide->tx_chan );
  	au1xxx_dbdma_start( auide->rx_chan );
   
  	return 0;
  } 
26a940e21   Pete Popov   Cleaned up AMD Au...
389
  #else
855286593   Bartlomiej Zolnierkiewicz   au1xxx-ide: use -...
390
  static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
391
  {
a536f326a   Bartlomiej Zolnierkiewicz   au1xxx-ide: don't...
392
  	_auide_hwif *auide = &auide_hwif;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
393
394
  	dbdev_tab_t source_dev_tab;
  	int flags;
26a940e21   Pete Popov   Cleaned up AMD Au...
395

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
396
397
398
399
  #ifdef IDE_AU1XXX_BURSTMODE 
  	flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;
  #else
  	flags = DEV_FLAGS_SYNC;
26a940e21   Pete Popov   Cleaned up AMD Au...
400
  #endif
26a940e21   Pete Popov   Cleaned up AMD Au...
401

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
  	/* setup dev_tab for tx channel */
  	auide_init_dbdma_dev( &source_dev_tab,
  			      (u32)DSCR_CMD0_ALWAYS,
  			      8, 32, DEV_FLAGS_OUT | flags);
   	auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
  
  	auide_init_dbdma_dev( &source_dev_tab,
  			      (u32)DSCR_CMD0_ALWAYS,
  			      8, 32, DEV_FLAGS_IN | flags);
   	auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
  	
  	/* Get a channel for TX */
  	auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
  						 auide->tx_dev_id,
  						 NULL,
  						 (void*)auide);
   
  	/* Get a channel for RX */
  	auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
  						 DSCR_CMD0_ALWAYS,
  						 NULL,
  						 (void*)auide);
   
  	auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
  							     NUM_DESCRIPTORS);
  	auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
  							     NUM_DESCRIPTORS);
   
  	au1xxx_dbdma_start( auide->tx_chan );
  	au1xxx_dbdma_start( auide->rx_chan );
   	
  	return 0;
26a940e21   Pete Popov   Cleaned up AMD Au...
434
  }
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
435
  #endif
26a940e21   Pete Popov   Cleaned up AMD Au...
436

9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
437
  static void auide_setup_ports(struct ide_hw *hw, _auide_hwif *ahwif)
26a940e21   Pete Popov   Cleaned up AMD Au...
438
  {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
439
  	int i;
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
440
  	unsigned long *ata_regs = hw->io_ports_array;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
441
442
  
  	/* FIXME? */
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
443
  	for (i = 0; i < 8; i++)
fcbd3b4b9   Sergei Shtylyov   [MIPS] Pb1200/DBA...
444
  		*ata_regs++ = ahwif->regbase + (i << IDE_REG_SHIFT);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
445
446
  
  	/* set the Alternative Status register */
fcbd3b4b9   Sergei Shtylyov   [MIPS] Pb1200/DBA...
447
  	*ata_regs = ahwif->regbase + (14 << IDE_REG_SHIFT);
26a940e21   Pete Popov   Cleaned up AMD Au...
448
  }
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
449
450
451
452
453
  #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
  static const struct ide_tp_ops au1xxx_tp_ops = {
  	.exec_command		= ide_exec_command,
  	.read_status		= ide_read_status,
  	.read_altstatus		= ide_read_altstatus,
ecf3a31d2   Sergei Shtylyov   ide: turn set_irq...
454
  	.write_devctl		= ide_write_devctl,
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
455

abb596b25   Sergei Shtylyov   ide: turn selectp...
456
  	.dev_select		= ide_dev_select,
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
457
458
459
460
461
462
463
  	.tf_load		= ide_tf_load,
  	.tf_read		= ide_tf_read,
  
  	.input_data		= au1xxx_input_data,
  	.output_data		= au1xxx_output_data,
  };
  #endif
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
464
465
466
  static const struct ide_port_ops au1xxx_port_ops = {
  	.set_pio_mode		= au1xxx_set_pio_mode,
  	.set_dma_mode		= auide_set_dma_mode,
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
467
  };
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
468
  static const struct ide_port_info au1xxx_port_info = {
855286593   Bartlomiej Zolnierkiewicz   au1xxx-ide: use -...
469
  	.init_dma		= auide_ddma_init,
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
470
471
472
  #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
  	.tp_ops			= &au1xxx_tp_ops,
  #endif
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
473
  	.port_ops		= &au1xxx_port_ops,
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
474
475
476
  #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
  	.dma_ops		= &au1xxx_dma_ops,
  #endif
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
477
  	.host_flags		= IDE_HFLAG_POST_SET_MODE |
807b90d0b   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
478
  				  IDE_HFLAG_NO_IO_32BIT |
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
479
480
481
482
483
  				  IDE_HFLAG_UNMASK_IRQS,
  	.pio_mask		= ATA_PIO4,
  #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
  	.mwdma_mask		= ATA_MWDMA2,
  #endif
29e52cf79   Bartlomiej Zolnierkiewicz   ide: remove chips...
484
  	.chipset		= ide_au1xxx,
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
485
  };
7a192ec33   Ming Lei   platform driver: ...
486
  static int au_ide_probe(struct platform_device *dev)
26a940e21   Pete Popov   Cleaned up AMD Au...
487
  {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
488
  	_auide_hwif *ahwif = &auide_hwif;
26a940e21   Pete Popov   Cleaned up AMD Au...
489
  	struct resource *res;
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
490
  	struct ide_host *host;
26a940e21   Pete Popov   Cleaned up AMD Au...
491
  	int ret = 0;
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
492
  	struct ide_hw hw, *hws[] = { &hw };
26a940e21   Pete Popov   Cleaned up AMD Au...
493
494
  
  #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
495
  	char *mode = "MWDMA2";
26a940e21   Pete Popov   Cleaned up AMD Au...
496
  #elif defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
497
  	char *mode = "PIO+DDMA(offload)";
26a940e21   Pete Popov   Cleaned up AMD Au...
498
  #endif
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
499
  	memset(&auide_hwif, 0, sizeof(_auide_hwif));
7a192ec33   Ming Lei   platform driver: ...
500
  	ahwif->irq = platform_get_irq(dev, 0);
26a940e21   Pete Popov   Cleaned up AMD Au...
501

7a192ec33   Ming Lei   platform driver: ...
502
  	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
26a940e21   Pete Popov   Cleaned up AMD Au...
503
504
  
  	if (res == NULL) {
7a192ec33   Ming Lei   platform driver: ...
505
506
  		pr_debug("%s %d: no base address
  ", DRV_NAME, dev->id);
26a940e21   Pete Popov   Cleaned up AMD Au...
507
  		ret = -ENODEV;
489447380   David Vrabel   [PATCH] handle er...
508
509
510
  		goto out;
  	}
  	if (ahwif->irq < 0) {
7a192ec33   Ming Lei   platform driver: ...
511
512
  		pr_debug("%s %d: no IRQ
  ", DRV_NAME, dev->id);
489447380   David Vrabel   [PATCH] handle er...
513
  		ret = -ENODEV;
26a940e21   Pete Popov   Cleaned up AMD Au...
514
515
  		goto out;
  	}
4b7c7237c   H Hartley Sweeten   drivers/ide/au1xx...
516
  	if (!request_mem_region(res->start, resource_size(res), dev->name)) {
26a940e21   Pete Popov   Cleaned up AMD Au...
517
518
  		pr_debug("%s: request_mem_region failed
  ", DRV_NAME);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
519
  		ret =  -EBUSY;
26a940e21   Pete Popov   Cleaned up AMD Au...
520
  		goto out;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
521
  	}
26a940e21   Pete Popov   Cleaned up AMD Au...
522

4b7c7237c   H Hartley Sweeten   drivers/ide/au1xx...
523
  	ahwif->regbase = (u32)ioremap(res->start, resource_size(res));
26a940e21   Pete Popov   Cleaned up AMD Au...
524
525
526
527
  	if (ahwif->regbase == 0) {
  		ret = -ENOMEM;
  		goto out;
  	}
9239b3339   Bartlomiej Zolnierkiewicz   ide: remove write...
528
529
  	memset(&hw, 0, sizeof(hw));
  	auide_setup_ports(&hw, ahwif);
aa79a2faa   Bartlomiej Zolnierkiewicz   au1xxx-ide: use i...
530
  	hw.irq = ahwif->irq;
7a192ec33   Ming Lei   platform driver: ...
531
  	hw.dev = &dev->dev;
aa79a2faa   Bartlomiej Zolnierkiewicz   au1xxx-ide: use i...
532

dca398305   Bartlomiej Zolnierkiewicz   ide: pass number ...
533
  	ret = ide_host_add(&au1xxx_port_info, hws, 1, &host);
6f904d015   Bartlomiej Zolnierkiewicz   ide: add ide_host...
534
  	if (ret)
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
535
  		goto out;
5cbf79cdb   Bartlomiej Zolnierkiewicz   ide: add ide_proc...
536

48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
537
  	auide_hwif.hwif = host->ports[0];
5cbf79cdb   Bartlomiej Zolnierkiewicz   ide: add ide_proc...
538

7a192ec33   Ming Lei   platform driver: ...
539
  	platform_set_drvdata(dev, host);
26a940e21   Pete Popov   Cleaned up AMD Au...
540

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
541
542
  	printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s
  ", mode );
26a940e21   Pete Popov   Cleaned up AMD Au...
543

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
544
545
   out:
  	return ret;
26a940e21   Pete Popov   Cleaned up AMD Au...
546
  }
7a192ec33   Ming Lei   platform driver: ...
547
  static int au_ide_remove(struct platform_device *dev)
26a940e21   Pete Popov   Cleaned up AMD Au...
548
  {
26a940e21   Pete Popov   Cleaned up AMD Au...
549
  	struct resource *res;
7a192ec33   Ming Lei   platform driver: ...
550
  	struct ide_host *host = platform_get_drvdata(dev);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
551
  	_auide_hwif *ahwif = &auide_hwif;
26a940e21   Pete Popov   Cleaned up AMD Au...
552

48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
553
  	ide_host_remove(host);
26a940e21   Pete Popov   Cleaned up AMD Au...
554
555
  
  	iounmap((void *)ahwif->regbase);
7a192ec33   Ming Lei   platform driver: ...
556
  	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
4b7c7237c   H Hartley Sweeten   drivers/ide/au1xx...
557
  	release_mem_region(res->start, resource_size(res));
26a940e21   Pete Popov   Cleaned up AMD Au...
558
559
560
  
  	return 0;
  }
7a192ec33   Ming Lei   platform driver: ...
561
562
563
564
565
  static struct platform_driver au1200_ide_driver = {
  	.driver = {
  		.name		= "au1200-ide",
  		.owner		= THIS_MODULE,
  	},
26a940e21   Pete Popov   Cleaned up AMD Au...
566
567
568
569
570
571
  	.probe 		= au_ide_probe,
  	.remove		= au_ide_remove,
  };
  
  static int __init au_ide_init(void)
  {
7a192ec33   Ming Lei   platform driver: ...
572
  	return platform_driver_register(&au1200_ide_driver);
26a940e21   Pete Popov   Cleaned up AMD Au...
573
  }
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
574
  static void __exit au_ide_exit(void)
26a940e21   Pete Popov   Cleaned up AMD Au...
575
  {
7a192ec33   Ming Lei   platform driver: ...
576
  	platform_driver_unregister(&au1200_ide_driver);
26a940e21   Pete Popov   Cleaned up AMD Au...
577
  }
26a940e21   Pete Popov   Cleaned up AMD Au...
578
579
580
581
582
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("AU1200 IDE driver");
  
  module_init(au_ide_init);
  module_exit(au_ide_exit);