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

50d5676eb   Manuel Lauss   MIPS: Alchemy: ki...
39
  #include <asm/mach-au1x00/au1000.h>
26a940e21   Pete Popov   Cleaned up AMD Au...
40
  #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

d4f07ae74   Manuel Lauss   MIPS, IDE: Alchem...
46
47
48
  #ifndef IDE_REG_SHIFT
  #define IDE_REG_SHIFT 5
  #endif
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
49
50
  /* enable the burstmode in the dbdma */
  #define IDE_AU1XXX_BURSTMODE	1
26a940e21   Pete Popov   Cleaned up AMD Au...
51

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

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

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

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

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

e085b3cae   Bartlomiej Zolnierkiewicz   ide: change ->set...
107
  	switch (drive->pio_mode - XFER_PIO_0) {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
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
159
160
161
  	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...
162
  }
8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
163
  static void auide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
26a940e21   Pete Popov   Cleaned up AMD Au...
164
  {
88b2b32ba   Bartlomiej Zolnierkiewicz   ide: move ide_con...
165
  	int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
26a940e21   Pete Popov   Cleaned up AMD Au...
166

8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
167
  	switch (drive->dma_mode) {
26a940e21   Pete Popov   Cleaned up AMD Au...
168
  #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
169
170
171
172
173
174
175
176
  	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...
177
178
179
180
181
182
183
184
185
  		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...
186
187
188
189
190
191
192
193
194
  		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...
195
  		break;
26a940e21   Pete Popov   Cleaned up AMD Au...
196
  #endif
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
197
  	}
a523a1759   Bartlomiej Zolnierkiewicz   au1xxx-ide: remov...
198

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

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

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
216
217
  	/* Save for interrupt context */
  	ahwif->drive = drive;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
  	/* 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...
235
  				return 0;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
236
237
238
239
240
241
242
243
244
  			}
  
  			/* 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...
245
  				if (!au1xxx_dbdma_put_source(ahwif->tx_chan,
963accbc8   Manuel Lauss   MIPS: Alchemy: ch...
246
  					sg_phys(sg), tc, flags)) {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
247
248
  					printk(KERN_ERR "%s failed %d
  ", 
eb63963a5   Harvey Harrison   ide: replace rema...
249
  					       __func__, __LINE__);
26a940e21   Pete Popov   Cleaned up AMD Au...
250
  				}
ea071cc70   Manuel Lauss   MIPS: Alchemy: re...
251
252
  			} else  {
  				if (!au1xxx_dbdma_put_dest(ahwif->rx_chan,
963accbc8   Manuel Lauss   MIPS: Alchemy: ch...
253
  					sg_phys(sg), tc, flags)) {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
254
255
  					printk(KERN_ERR "%s failed %d
  ", 
eb63963a5   Harvey Harrison   ide: replace rema...
256
  					       __func__, __LINE__);
26a940e21   Pete Popov   Cleaned up AMD Au...
257
  				}
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
258
  			}
26a940e21   Pete Popov   Cleaned up AMD Au...
259

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

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

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

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

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

d4f07ae74   Manuel Lauss   MIPS, IDE: Alchem...
315
316
  static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize,
  				 u32 devwidth, u32 flags, u32 regbase)
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
317
318
  {
  	dev->dev_id          = dev_id;
d4f07ae74   Manuel Lauss   MIPS, IDE: Alchem...
319
  	dev->dev_physaddr    = CPHYSADDR(regbase);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
320
321
322
323
324
  	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...
325
  }
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
326
  #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
f37afdaca   Bartlomiej Zolnierkiewicz   ide: constify str...
327
  static const struct ide_dma_ops au1xxx_dma_ops = {
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
328
329
  	.dma_host_set		= auide_dma_host_set,
  	.dma_setup		= auide_dma_setup,
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
330
331
332
  	.dma_start		= auide_dma_start,
  	.dma_end		= auide_dma_end,
  	.dma_test_irq		= auide_dma_test_irq,
de23ec9ca   Bartlomiej Zolnierkiewicz   ide: make ide_dma...
333
  	.dma_lost_irq		= ide_dma_lost_irq,
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
334
  };
855286593   Bartlomiej Zolnierkiewicz   au1xxx-ide: use -...
335
336
  static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
  {
a536f326a   Bartlomiej Zolnierkiewicz   au1xxx-ide: don't...
337
  	_auide_hwif *auide = &auide_hwif;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
338
339
  	dbdev_tab_t source_dev_tab, target_dev_tab;
  	u32 dev_id, tsize, devwidth, flags;
26a940e21   Pete Popov   Cleaned up AMD Au...
340

d4f07ae74   Manuel Lauss   MIPS, IDE: Alchem...
341
  	dev_id	 = hwif->ddma_id;
26a940e21   Pete Popov   Cleaned up AMD Au...
342

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

8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
346
347
  #ifdef IDE_AU1XXX_BURSTMODE 
  	flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;
26a940e21   Pete Popov   Cleaned up AMD Au...
348
  #else
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
349
  	flags = DEV_FLAGS_SYNC;
26a940e21   Pete Popov   Cleaned up AMD Au...
350
  #endif
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
351
  	/* setup dev_tab for tx channel */
d4f07ae74   Manuel Lauss   MIPS, IDE: Alchem...
352
353
  	auide_init_dbdma_dev(&source_dev_tab, dev_id, tsize, devwidth,
  			     DEV_FLAGS_OUT | flags, auide->regbase);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
354
   	auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
d4f07ae74   Manuel Lauss   MIPS, IDE: Alchem...
355
356
  	auide_init_dbdma_dev(&source_dev_tab, dev_id, tsize, devwidth,
  			     DEV_FLAGS_IN | flags, auide->regbase);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
357
358
359
   	auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
  	
  	/* We also need to add a target device for the DMA */
d4f07ae74   Manuel Lauss   MIPS, IDE: Alchem...
360
361
  	auide_init_dbdma_dev(&target_dev_tab, (u32)DSCR_CMD0_ALWAYS, tsize,
  			     devwidth, DEV_FLAGS_ANYUSE, auide->regbase);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
  	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
  	/* setup dev_tab for tx channel */
d4f07ae74   Manuel Lauss   MIPS, IDE: Alchem...
403
404
  	auide_init_dbdma_dev(&source_dev_tab, (u32)DSCR_CMD0_ALWAYS, 8, 32,
  			     DEV_FLAGS_OUT | flags, auide->regbase);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
405
   	auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
d4f07ae74   Manuel Lauss   MIPS, IDE: Alchem...
406
407
  	auide_init_dbdma_dev(&source_dev_tab, (u32)DSCR_CMD0_ALWAYS, 8, 32,
  			     DEV_FLAGS_IN | flags, auide->regbase);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
   	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...
431
  }
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
432
  #endif
26a940e21   Pete Popov   Cleaned up AMD Au...
433

9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
434
  static void auide_setup_ports(struct ide_hw *hw, _auide_hwif *ahwif)
26a940e21   Pete Popov   Cleaned up AMD Au...
435
  {
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
436
  	int i;
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
437
  	unsigned long *ata_regs = hw->io_ports_array;
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
438
439
  
  	/* FIXME? */
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
440
  	for (i = 0; i < 8; i++)
fcbd3b4b9   Sergei Shtylyov   [MIPS] Pb1200/DBA...
441
  		*ata_regs++ = ahwif->regbase + (i << IDE_REG_SHIFT);
8f29e650b   Jordan Crouse   [PATCH] ide: AU12...
442
443
  
  	/* set the Alternative Status register */
fcbd3b4b9   Sergei Shtylyov   [MIPS] Pb1200/DBA...
444
  	*ata_regs = ahwif->regbase + (14 << IDE_REG_SHIFT);
26a940e21   Pete Popov   Cleaned up AMD Au...
445
  }
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
446
447
448
449
450
  #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...
451
  	.write_devctl		= ide_write_devctl,
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
452

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

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

4b7c7237c   H Hartley Sweeten   drivers/ide/au1xx...
520
  	ahwif->regbase = (u32)ioremap(res->start, resource_size(res));
26a940e21   Pete Popov   Cleaned up AMD Au...
521
522
523
524
  	if (ahwif->regbase == 0) {
  		ret = -ENOMEM;
  		goto out;
  	}
d4f07ae74   Manuel Lauss   MIPS, IDE: Alchem...
525
526
527
528
529
530
531
532
  	res = platform_get_resource(dev, IORESOURCE_DMA, 0);
  	if (!res) {
  		pr_debug("%s: no DDMA ID resource
  ", DRV_NAME);
  		ret = -ENODEV;
  		goto out;
  	}
  	ahwif->ddma_id = res->start;
9239b3339   Bartlomiej Zolnierkiewicz   ide: remove write...
533
534
  	memset(&hw, 0, sizeof(hw));
  	auide_setup_ports(&hw, ahwif);
aa79a2faa   Bartlomiej Zolnierkiewicz   au1xxx-ide: use i...
535
  	hw.irq = ahwif->irq;
7a192ec33   Ming Lei   platform driver: ...
536
  	hw.dev = &dev->dev;
aa79a2faa   Bartlomiej Zolnierkiewicz   au1xxx-ide: use i...
537

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

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

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

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

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

48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
558
  	ide_host_remove(host);
26a940e21   Pete Popov   Cleaned up AMD Au...
559
560
  
  	iounmap((void *)ahwif->regbase);
7a192ec33   Ming Lei   platform driver: ...
561
  	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
4b7c7237c   H Hartley Sweeten   drivers/ide/au1xx...
562
  	release_mem_region(res->start, resource_size(res));
26a940e21   Pete Popov   Cleaned up AMD Au...
563
564
565
  
  	return 0;
  }
7a192ec33   Ming Lei   platform driver: ...
566
567
568
  static struct platform_driver au1200_ide_driver = {
  	.driver = {
  		.name		= "au1200-ide",
7a192ec33   Ming Lei   platform driver: ...
569
  	},
26a940e21   Pete Popov   Cleaned up AMD Au...
570
571
572
  	.probe 		= au_ide_probe,
  	.remove		= au_ide_remove,
  };
a53dae49b   Christoph Jaeger   ide: use module_p...
573
  module_platform_driver(au1200_ide_driver);
26a940e21   Pete Popov   Cleaned up AMD Au...
574

26a940e21   Pete Popov   Cleaned up AMD Au...
575
576
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("AU1200 IDE driver");