Blame view

drivers/ide/pmac.c 45.8 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
   * Support for IDE interfaces on PowerMacs.
58f189fcc   Bartlomiej Zolnierkiewicz   ide: delete filen...
3
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
5
6
7
   * These IDE interfaces are memory-mapped and have a DBDMA channel
   * for doing DMA.
   *
   *  Copyright (C) 1998-2003 Paul Mackerras & Ben. Herrenschmidt
8a97206e3   Bartlomiej Zolnierkiewicz   ide-pmac: convert...
8
   *  Copyright (C) 2007-2008 Bartlomiej Zolnierkiewicz
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   *
   *  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.
   *
   * Some code taken from drivers/ide/ide-dma.c:
   *
   *  Copyright (c) 1995-1998  Mark Lord
   *
   * TODO: - Use pre-calculated (kauai) timing tables all the time and
   * get rid of the "rounded" tables used previously, so we have the
   * same table format for all controllers and can then just have one
   * big table
   * 
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
  #include <linux/types.h>
  #include <linux/kernel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
30
31
32
33
34
35
  #include <linux/init.h>
  #include <linux/delay.h>
  #include <linux/ide.h>
  #include <linux/notifier.h>
  #include <linux/reboot.h>
  #include <linux/pci.h>
  #include <linux/adb.h>
  #include <linux/pmu.h>
  #include <linux/scatterlist.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
36
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
38
39
40
41
42
43
44
45
46
  
  #include <asm/prom.h>
  #include <asm/io.h>
  #include <asm/dbdma.h>
  #include <asm/ide.h>
  #include <asm/pci-bridge.h>
  #include <asm/machdep.h>
  #include <asm/pmac_feature.h>
  #include <asm/sections.h>
  #include <asm/irq.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47
  #include <asm/mediabay.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48

b36ba5321   Bartlomiej Zolnierkiewicz   ide-pmac: move id...
49
  #define DRV_NAME "ide-pmac"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
53
54
55
56
57
58
  #undef IDE_PMAC_DEBUG
  
  #define DMA_WAIT_TIMEOUT	50
  
  typedef struct pmac_ide_hwif {
  	unsigned long			regbase;
  	int				irq;
  	int				kind;
  	int				aapl_bus_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
63
64
  	unsigned			broken_dma : 1;
  	unsigned			broken_dma_warn : 1;
  	struct device_node*		node;
  	struct macio_dev		*mdev;
  	u32				timings[4];
  	volatile u32 __iomem *		*kauai_fcr;
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
65
  	ide_hwif_t			*hwif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
68
69
70
71
72
  	/* Those fields are duplicating what is in hwif. We currently
  	 * can't use the hwif ones because of some assumptions that are
  	 * beeing done by the generic code about the kind of dma controller
  	 * and format of the dma table. This will have to be fixed though.
  	 */
  	volatile struct dbdma_regs __iomem *	dma_regs;
  	struct dbdma_cmd*		dma_table_cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  } pmac_ide_hwif_t;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
  enum {
  	controller_ohare,	/* OHare based */
  	controller_heathrow,	/* Heathrow/Paddington */
  	controller_kl_ata3,	/* KeyLargo ATA-3 */
  	controller_kl_ata4,	/* KeyLargo ATA-4 */
  	controller_un_ata6,	/* UniNorth2 ATA-6 */
  	controller_k2_ata6,	/* K2 ATA-6 */
  	controller_sh_ata6,	/* Shasta ATA-6 */
  };
  
  static const char* model_name[] = {
  	"OHare ATA",		/* OHare based */
  	"Heathrow ATA",		/* Heathrow/Paddington */
  	"KeyLargo ATA-3",	/* KeyLargo ATA-3 (MDMA only) */
  	"KeyLargo ATA-4",	/* KeyLargo ATA-4 (UDMA/66) */
  	"UniNorth ATA-6",	/* UniNorth2 ATA-6 (UDMA/100) */
  	"K2 ATA-6",		/* K2 ATA-6 (UDMA/100) */
  	"Shasta ATA-6",		/* Shasta ATA-6 (UDMA/133) */
  };
  
  /*
   * Extra registers, both 32-bit little-endian
   */
  #define IDE_TIMING_CONFIG	0x200
  #define IDE_INTERRUPT		0x300
  
  /* Kauai (U2) ATA has different register setup */
  #define IDE_KAUAI_PIO_CONFIG	0x200
  #define IDE_KAUAI_ULTRA_CONFIG	0x210
  #define IDE_KAUAI_POLL_CONFIG	0x220
  
  /*
   * Timing configuration register definitions
   */
  
  /* Number of IDE_SYSCLK_NS ticks, argument is in nanoseconds */
  #define SYSCLK_TICKS(t)		(((t) + IDE_SYSCLK_NS - 1) / IDE_SYSCLK_NS)
  #define SYSCLK_TICKS_66(t)	(((t) + IDE_SYSCLK_66_NS - 1) / IDE_SYSCLK_66_NS)
  #define IDE_SYSCLK_NS		30	/* 33Mhz cell */
  #define IDE_SYSCLK_66_NS	15	/* 66Mhz cell */
  
  /* 133Mhz cell, found in shasta.
   * See comments about 100 Mhz Uninorth 2...
   * Note that PIO_MASK and MDMA_MASK seem to overlap
   */
  #define TR_133_PIOREG_PIO_MASK		0xff000fff
  #define TR_133_PIOREG_MDMA_MASK		0x00fff800
  #define TR_133_UDMAREG_UDMA_MASK	0x0003ffff
  #define TR_133_UDMAREG_UDMA_EN		0x00000001
  
  /* 100Mhz cell, found in Uninorth 2. I don't have much infos about
   * this one yet, it appears as a pci device (106b/0033) on uninorth
   * internal PCI bus and it's clock is controlled like gem or fw. It
   * appears to be an evolution of keylargo ATA4 with a timing register
   * extended to 2 32bits registers and a similar DBDMA channel. Other
   * registers seem to exist but I can't tell much about them.
   * 
   * So far, I'm using pre-calculated tables for this extracted from
   * the values used by the MacOS X driver.
   * 
   * The "PIO" register controls PIO and MDMA timings, the "ULTRA"
   * register controls the UDMA timings. At least, it seems bit 0
   * of this one enables UDMA vs. MDMA, and bits 4..7 are the
   * cycle time in units of 10ns. Bits 8..15 are used by I don't
   * know their meaning yet
   */
  #define TR_100_PIOREG_PIO_MASK		0xff000fff
  #define TR_100_PIOREG_MDMA_MASK		0x00fff000
  #define TR_100_UDMAREG_UDMA_MASK	0x0000ffff
  #define TR_100_UDMAREG_UDMA_EN		0x00000001
  
  
  /* 66Mhz cell, found in KeyLargo. Can do ultra mode 0 to 2 on
   * 40 connector cable and to 4 on 80 connector one.
   * Clock unit is 15ns (66Mhz)
   * 
   * 3 Values can be programmed:
   *  - Write data setup, which appears to match the cycle time. They
   *    also call it DIOW setup.
   *  - Ready to pause time (from spec)
   *  - Address setup. That one is weird. I don't see where exactly
   *    it fits in UDMA cycles, I got it's name from an obscure piece
   *    of commented out code in Darwin. They leave it to 0, we do as
   *    well, despite a comment that would lead to think it has a
   *    min value of 45ns.
   * Apple also add 60ns to the write data setup (or cycle time ?) on
   * reads.
   */
  #define TR_66_UDMA_MASK			0xfff00000
  #define TR_66_UDMA_EN			0x00100000 /* Enable Ultra mode for DMA */
  #define TR_66_UDMA_ADDRSETUP_MASK	0xe0000000 /* Address setup */
  #define TR_66_UDMA_ADDRSETUP_SHIFT	29
  #define TR_66_UDMA_RDY2PAUS_MASK	0x1e000000 /* Ready 2 pause time */
  #define TR_66_UDMA_RDY2PAUS_SHIFT	25
  #define TR_66_UDMA_WRDATASETUP_MASK	0x01e00000 /* Write data setup time */
  #define TR_66_UDMA_WRDATASETUP_SHIFT	21
  #define TR_66_MDMA_MASK			0x000ffc00
  #define TR_66_MDMA_RECOVERY_MASK	0x000f8000
  #define TR_66_MDMA_RECOVERY_SHIFT	15
  #define TR_66_MDMA_ACCESS_MASK		0x00007c00
  #define TR_66_MDMA_ACCESS_SHIFT		10
  #define TR_66_PIO_MASK			0x000003ff
  #define TR_66_PIO_RECOVERY_MASK		0x000003e0
  #define TR_66_PIO_RECOVERY_SHIFT	5
  #define TR_66_PIO_ACCESS_MASK		0x0000001f
  #define TR_66_PIO_ACCESS_SHIFT		0
  
  /* 33Mhz cell, found in OHare, Heathrow (& Paddington) and KeyLargo
   * Can do pio & mdma modes, clock unit is 30ns (33Mhz)
   * 
   * The access time and recovery time can be programmed. Some older
   * Darwin code base limit OHare to 150ns cycle time. I decided to do
   * the same here fore safety against broken old hardware ;)
   * The HalfTick bit, when set, adds half a clock (15ns) to the access
   * time and removes one from recovery. It's not supported on KeyLargo
   * implementation afaik. The E bit appears to be set for PIO mode 0 and
   * is used to reach long timings used in this mode.
   */
  #define TR_33_MDMA_MASK			0x003ff800
  #define TR_33_MDMA_RECOVERY_MASK	0x001f0000
  #define TR_33_MDMA_RECOVERY_SHIFT	16
  #define TR_33_MDMA_ACCESS_MASK		0x0000f800
  #define TR_33_MDMA_ACCESS_SHIFT		11
  #define TR_33_MDMA_HALFTICK		0x00200000
  #define TR_33_PIO_MASK			0x000007ff
  #define TR_33_PIO_E			0x00000400
  #define TR_33_PIO_RECOVERY_MASK		0x000003e0
  #define TR_33_PIO_RECOVERY_SHIFT	5
  #define TR_33_PIO_ACCESS_MASK		0x0000001f
  #define TR_33_PIO_ACCESS_SHIFT		0
  
  /*
   * Interrupt register definitions
   */
  #define IDE_INTR_DMA			0x80000000
  #define IDE_INTR_DEVICE			0x40000000
  
  /*
   * FCR Register on Kauai. Not sure what bit 0x4 is  ...
   */
  #define KAUAI_FCR_UATA_MAGIC		0x00000004
  #define KAUAI_FCR_UATA_RESET_N		0x00000002
  #define KAUAI_FCR_UATA_ENABLE		0x00000001
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
218
219
220
221
222
223
224
225
226
227
  /* Rounded Multiword DMA timings
   * 
   * I gave up finding a generic formula for all controller
   * types and instead, built tables based on timing values
   * used by Apple in Darwin's implementation.
   */
  struct mdma_timings_t {
  	int	accessTime;
  	int	recoveryTime;
  	int	cycleTime;
  };
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
228
  struct mdma_timings_t mdma_timings_33[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
230
231
232
233
234
235
236
237
238
239
  {
      { 240, 240, 480 },
      { 180, 180, 360 },
      { 135, 135, 270 },
      { 120, 120, 240 },
      { 105, 105, 210 },
      {  90,  90, 180 },
      {  75,  75, 150 },
      {  75,  45, 120 },
      {   0,   0,   0 }
  };
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
240
  struct mdma_timings_t mdma_timings_33k[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
242
243
244
245
246
247
248
249
250
251
  {
      { 240, 240, 480 },
      { 180, 180, 360 },
      { 150, 150, 300 },
      { 120, 120, 240 },
      {  90, 120, 210 },
      {  90,  90, 180 },
      {  90,  60, 150 },
      {  90,  30, 120 },
      {   0,   0,   0 }
  };
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
252
  struct mdma_timings_t mdma_timings_66[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
  {
      { 240, 240, 480 },
      { 180, 180, 360 },
      { 135, 135, 270 },
      { 120, 120, 240 },
      { 105, 105, 210 },
      {  90,  90, 180 },
      {  90,  75, 165 },
      {  75,  45, 120 },
      {   0,   0,   0 }
  };
  
  /* KeyLargo ATA-4 Ultra DMA timings (rounded) */
  struct {
  	int	addrSetup; /* ??? */
  	int	rdy2pause;
  	int	wrDataSetup;
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
270
  } kl66_udma_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
272
273
274
275
276
277
278
279
280
281
282
283
  {
      {   0, 180,  120 },	/* Mode 0 */
      {   0, 150,  90 },	/*      1 */
      {   0, 120,  60 },	/*      2 */
      {   0, 90,   45 },	/*      3 */
      {   0, 90,   30 }	/*      4 */
  };
  
  /* UniNorth 2 ATA/100 timings */
  struct kauai_timing {
  	int	cycle_time;
  	u32	timing_reg;
  };
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
284
  static struct kauai_timing	kauai_pio_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
287
288
289
290
291
292
293
294
295
  {
  	{ 930	, 0x08000fff },
  	{ 600	, 0x08000a92 },
  	{ 383	, 0x0800060f },
  	{ 360	, 0x08000492 },
  	{ 330	, 0x0800048f },
  	{ 300	, 0x080003cf },
  	{ 270	, 0x080003cc },
  	{ 240	, 0x0800038b },
  	{ 239	, 0x0800030c },
  	{ 180	, 0x05000249 },
c15d5d43e   Bartlomiej Zolnierkiewicz   ide-pmac: PIO mod...
296
297
  	{ 120	, 0x04000148 },
  	{ 0	, 0 },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
  };
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
299
  static struct kauai_timing	kauai_mdma_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
301
302
303
304
305
306
307
308
309
310
311
  {
  	{ 1260	, 0x00fff000 },
  	{ 480	, 0x00618000 },
  	{ 360	, 0x00492000 },
  	{ 270	, 0x0038e000 },
  	{ 240	, 0x0030c000 },
  	{ 210	, 0x002cb000 },
  	{ 180	, 0x00249000 },
  	{ 150	, 0x00209000 },
  	{ 120	, 0x00148000 },
  	{ 0	, 0 },
  };
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
312
  static struct kauai_timing	kauai_udma_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313
314
315
316
317
318
319
320
321
  {
  	{ 120	, 0x000070c0 },
  	{ 90	, 0x00005d80 },
  	{ 60	, 0x00004a60 },
  	{ 45	, 0x00003a50 },
  	{ 30	, 0x00002a30 },
  	{ 20	, 0x00002921 },
  	{ 0	, 0 },
  };
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
322
  static struct kauai_timing	shasta_pio_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
324
325
326
327
328
329
330
331
332
333
  {
  	{ 930	, 0x08000fff },
  	{ 600	, 0x0A000c97 },
  	{ 383	, 0x07000712 },
  	{ 360	, 0x040003cd },
  	{ 330	, 0x040003cd },
  	{ 300	, 0x040003cd },
  	{ 270	, 0x040003cd },
  	{ 240	, 0x040003cd },
  	{ 239	, 0x040003cd },
  	{ 180	, 0x0400028b },
c15d5d43e   Bartlomiej Zolnierkiewicz   ide-pmac: PIO mod...
334
335
  	{ 120	, 0x0400010a },
  	{ 0	, 0 },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
  };
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
337
  static struct kauai_timing	shasta_mdma_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
339
340
341
342
343
344
345
346
347
348
349
  {
  	{ 1260	, 0x00fff000 },
  	{ 480	, 0x00820800 },
  	{ 360	, 0x00820800 },
  	{ 270	, 0x00820800 },
  	{ 240	, 0x00820800 },
  	{ 210	, 0x00820800 },
  	{ 180	, 0x00820800 },
  	{ 150	, 0x0028b000 },
  	{ 120	, 0x001ca000 },
  	{ 0	, 0 },
  };
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
350
  static struct kauai_timing	shasta_udma133_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
  {
  	{ 120   , 0x00035901, },
  	{ 90    , 0x000348b1, },
  	{ 60    , 0x00033881, },
  	{ 45    , 0x00033861, },
  	{ 30    , 0x00033841, },
  	{ 20    , 0x00033031, },
  	{ 15    , 0x00033021, },
  	{ 0	, 0 },
  };
  
  
  static inline u32
  kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
  {
  	int i;
  	
  	for (i=0; table[i].cycle_time; i++)
  		if (cycle_time > table[i+1].cycle_time)
  			return table[i].timing_reg;
90a87ea48   Bartlomiej Zolnierkiewicz   ide-pmac: don't c...
371
  	BUG();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
  	return 0;
  }
  
  /* allow up to 256 DBDMA commands per xfer */
  #define MAX_DCMDS		256
  
  /* 
   * Wait 1s for disk to answer on IDE bus after a hard reset
   * of the device (via GPIO/FCR).
   * 
   * Some devices seem to "pollute" the bus even after dropping
   * the BSY bit (typically some combo drives slave on the UDMA
   * bus) after a hard reset. Since we hard reset all drives on
   * KeyLargo ATA66, we have to keep that delay around. I may end
   * up not hard resetting anymore on these and keep the delay only
   * for older interfaces instead (we have to reset when coming
   * from MacOS...) --BenH. 
   */
  #define IDE_WAKEUP_DELAY	(1*HZ)
0d0719229   Bartlomiej Zolnierkiewicz   ide-pmac: use ->i...
391
  static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
392

23579a2a1   Bartlomiej Zolnierkiewicz   ide: remove IDE_*...
393
  #define PMAC_IDE_REG(x) \
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
394
  	((void __iomem *)((drive)->hwif->io_ports.data_addr + (x)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
396
397
398
399
400
  
  /*
   * Apply the timings of the proper unit (master/slave) to the shared
   * timing register when selecting that unit. This version is for
   * ASICs with a single timing register
   */
abb596b25   Sergei Shtylyov   ide: turn selectp...
401
  static void pmac_ide_apply_timings(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
403
404
405
  	ide_hwif_t *hwif = drive->hwif;
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406

123995b97   Bartlomiej Zolnierkiewicz   ide: use 'drive->...
407
  	if (drive->dn & 1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
409
410
411
412
413
414
415
416
417
418
  		writel(pmif->timings[1], PMAC_IDE_REG(IDE_TIMING_CONFIG));
  	else
  		writel(pmif->timings[0], PMAC_IDE_REG(IDE_TIMING_CONFIG));
  	(void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
  }
  
  /*
   * Apply the timings of the proper unit (master/slave) to the shared
   * timing register when selecting that unit. This version is for
   * ASICs with a dual timing register (Kauai)
   */
abb596b25   Sergei Shtylyov   ide: turn selectp...
419
  static void pmac_ide_kauai_apply_timings(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
421
422
423
  	ide_hwif_t *hwif = drive->hwif;
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424

123995b97   Bartlomiej Zolnierkiewicz   ide: use 'drive->...
425
  	if (drive->dn & 1) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
427
428
429
430
431
432
433
434
435
436
437
  		writel(pmif->timings[1], PMAC_IDE_REG(IDE_KAUAI_PIO_CONFIG));
  		writel(pmif->timings[3], PMAC_IDE_REG(IDE_KAUAI_ULTRA_CONFIG));
  	} else {
  		writel(pmif->timings[0], PMAC_IDE_REG(IDE_KAUAI_PIO_CONFIG));
  		writel(pmif->timings[2], PMAC_IDE_REG(IDE_KAUAI_ULTRA_CONFIG));
  	}
  	(void)readl(PMAC_IDE_REG(IDE_KAUAI_PIO_CONFIG));
  }
  
  /*
   * Force an update of controller timing values for a given drive
   */
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
438
  static void
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439
440
  pmac_ide_do_update_timings(ide_drive_t *drive)
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
441
442
443
  	ide_hwif_t *hwif = drive->hwif;
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445
446
447
  	if (pmif->kind == controller_sh_ata6 ||
  	    pmif->kind == controller_un_ata6 ||
  	    pmif->kind == controller_k2_ata6)
abb596b25   Sergei Shtylyov   ide: turn selectp...
448
  		pmac_ide_kauai_apply_timings(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449
  	else
abb596b25   Sergei Shtylyov   ide: turn selectp...
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
  		pmac_ide_apply_timings(drive);
  }
  
  static void pmac_dev_select(ide_drive_t *drive)
  {
  	pmac_ide_apply_timings(drive);
  
  	writeb(drive->select | ATA_DEVICE_OBS,
  	       (void __iomem *)drive->hwif->io_ports.device_addr);
  }
  
  static void pmac_kauai_dev_select(ide_drive_t *drive)
  {
  	pmac_ide_kauai_apply_timings(drive);
  
  	writeb(drive->select | ATA_DEVICE_OBS,
  	       (void __iomem *)drive->hwif->io_ports.device_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
467
  }
c6dfa867b   Bartlomiej Zolnierkiewicz   ide: add ->exec_c...
468
469
470
471
472
473
  static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd)
  {
  	writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
  	(void)readl((void __iomem *)(hwif->io_ports.data_addr
  				     + IDE_TIMING_CONFIG));
  }
ecf3a31d2   Sergei Shtylyov   ide: turn set_irq...
474
  static void pmac_write_devctl(ide_hwif_t *hwif, u8 ctl)
6e6afb3b7   Bartlomiej Zolnierkiewicz   ide: add ->set_ir...
475
  {
6e6afb3b7   Bartlomiej Zolnierkiewicz   ide: add ->set_ir...
476
477
478
479
  	writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
  	(void)readl((void __iomem *)(hwif->io_ports.data_addr
  				     + IDE_TIMING_CONFIG));
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481
482
   * Old tuning functions (called on hdparm -p), sets up drive PIO timings
   */
e085b3cae   Bartlomiej Zolnierkiewicz   ide: change ->set...
483
  static void pmac_ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
485
486
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
e085b3cae   Bartlomiej Zolnierkiewicz   ide: change ->set...
487
  	const u8 pio = drive->pio_mode - XFER_PIO_0;
8a97206e3   Bartlomiej Zolnierkiewicz   ide-pmac: convert...
488
  	struct ide_timing *tim = ide_timing_find_mode(XFER_PIO_0 + pio);
0b46ff2ea   Benjamin Herrenschmidt   ide-pmac: fix PIO...
489
  	u32 *timings, t;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
490
491
  	unsigned accessTicks, recTicks;
  	unsigned accessTime, recTime;
7dd00083b   Bartlomiej Zolnierkiewicz   ide: add ide_pio_...
492
  	unsigned int cycle_time;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493
  	/* which drive is it ? */
123995b97   Bartlomiej Zolnierkiewicz   ide: use 'drive->...
494
  	timings = &pmif->timings[drive->dn & 1];
0b46ff2ea   Benjamin Herrenschmidt   ide-pmac: fix PIO...
495
  	t = *timings;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
496

7dd00083b   Bartlomiej Zolnierkiewicz   ide: add ide_pio_...
497
  	cycle_time = ide_pio_cycle_time(drive, pio);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498
499
500
501
  
  	switch (pmif->kind) {
  	case controller_sh_ata6: {
  		/* 133Mhz cell */
7dd00083b   Bartlomiej Zolnierkiewicz   ide: add ide_pio_...
502
  		u32 tr = kauai_lookup_timing(shasta_pio_timings, cycle_time);
0b46ff2ea   Benjamin Herrenschmidt   ide-pmac: fix PIO...
503
  		t = (t & ~TR_133_PIOREG_PIO_MASK) | tr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504
505
506
507
508
  		break;
  		}
  	case controller_un_ata6:
  	case controller_k2_ata6: {
  		/* 100Mhz cell */
7dd00083b   Bartlomiej Zolnierkiewicz   ide: add ide_pio_...
509
  		u32 tr = kauai_lookup_timing(kauai_pio_timings, cycle_time);
0b46ff2ea   Benjamin Herrenschmidt   ide-pmac: fix PIO...
510
  		t = (t & ~TR_100_PIOREG_PIO_MASK) | tr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511
512
513
514
  		break;
  		}
  	case controller_kl_ata4:
  		/* 66Mhz cell */
8a97206e3   Bartlomiej Zolnierkiewicz   ide-pmac: convert...
515
  		recTime = cycle_time - tim->active - tim->setup;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
  		recTime = max(recTime, 150U);
8a97206e3   Bartlomiej Zolnierkiewicz   ide-pmac: convert...
517
  		accessTime = tim->active;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
518
519
520
521
522
  		accessTime = max(accessTime, 150U);
  		accessTicks = SYSCLK_TICKS_66(accessTime);
  		accessTicks = min(accessTicks, 0x1fU);
  		recTicks = SYSCLK_TICKS_66(recTime);
  		recTicks = min(recTicks, 0x1fU);
0b46ff2ea   Benjamin Herrenschmidt   ide-pmac: fix PIO...
523
524
525
  		t = (t & ~TR_66_PIO_MASK) |
  			(accessTicks << TR_66_PIO_ACCESS_SHIFT) |
  			(recTicks << TR_66_PIO_RECOVERY_SHIFT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
527
528
529
  		break;
  	default: {
  		/* 33Mhz cell */
  		int ebit = 0;
8a97206e3   Bartlomiej Zolnierkiewicz   ide-pmac: convert...
530
  		recTime = cycle_time - tim->active - tim->setup;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
  		recTime = max(recTime, 150U);
8a97206e3   Bartlomiej Zolnierkiewicz   ide-pmac: convert...
532
  		accessTime = tim->active;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
533
534
535
536
537
538
539
540
541
542
543
  		accessTime = max(accessTime, 150U);
  		accessTicks = SYSCLK_TICKS(accessTime);
  		accessTicks = min(accessTicks, 0x1fU);
  		accessTicks = max(accessTicks, 4U);
  		recTicks = SYSCLK_TICKS(recTime);
  		recTicks = min(recTicks, 0x1fU);
  		recTicks = max(recTicks, 5U) - 4;
  		if (recTicks > 9) {
  			recTicks--; /* guess, but it's only for PIO0, so... */
  			ebit = 1;
  		}
0b46ff2ea   Benjamin Herrenschmidt   ide-pmac: fix PIO...
544
  		t = (t & ~TR_33_PIO_MASK) |
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
545
546
547
  				(accessTicks << TR_33_PIO_ACCESS_SHIFT) |
  				(recTicks << TR_33_PIO_RECOVERY_SHIFT);
  		if (ebit)
0b46ff2ea   Benjamin Herrenschmidt   ide-pmac: fix PIO...
548
  			t |= TR_33_PIO_E;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
549
550
551
552
553
554
555
556
557
  		break;
  		}
  	}
  
  #ifdef IDE_PMAC_DEBUG
  	printk(KERN_ERR "%s: Set PIO timing for mode %d, reg: 0x%08x
  ",
  		drive->name, pio,  *timings);
  #endif	
0b46ff2ea   Benjamin Herrenschmidt   ide-pmac: fix PIO...
558
  	*timings = t;
c15d5d43e   Bartlomiej Zolnierkiewicz   ide-pmac: PIO mod...
559
  	pmac_ide_do_update_timings(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
560
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
561
562
563
  /*
   * Calculate KeyLargo ATA/66 UDMA timings
   */
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
564
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
  set_timings_udma_ata4(u32 *timings, u8 speed)
  {
  	unsigned rdyToPauseTicks, wrDataSetupTicks, addrTicks;
  
  	if (speed > XFER_UDMA_4)
  		return 1;
  
  	rdyToPauseTicks = SYSCLK_TICKS_66(kl66_udma_timings[speed & 0xf].rdy2pause);
  	wrDataSetupTicks = SYSCLK_TICKS_66(kl66_udma_timings[speed & 0xf].wrDataSetup);
  	addrTicks = SYSCLK_TICKS_66(kl66_udma_timings[speed & 0xf].addrSetup);
  
  	*timings = ((*timings) & ~(TR_66_UDMA_MASK | TR_66_MDMA_MASK)) |
  			(wrDataSetupTicks << TR_66_UDMA_WRDATASETUP_SHIFT) | 
  			(rdyToPauseTicks << TR_66_UDMA_RDY2PAUS_SHIFT) |
  			(addrTicks <<TR_66_UDMA_ADDRSETUP_SHIFT) |
  			TR_66_UDMA_EN;
  #ifdef IDE_PMAC_DEBUG
  	printk(KERN_ERR "ide_pmac: Set UDMA timing for mode %d, reg: 0x%08x
  ",
  		speed & 0xf,  *timings);
  #endif	
  
  	return 0;
  }
  
  /*
   * Calculate Kauai ATA/100 UDMA timings
   */
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
593
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594
595
596
597
598
599
600
601
  set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed)
  {
  	struct ide_timing *t = ide_timing_find_mode(speed);
  	u32 tr;
  
  	if (speed > XFER_UDMA_5 || t == NULL)
  		return 1;
  	tr = kauai_lookup_timing(kauai_udma_timings, (int)t->udma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
602
603
604
605
606
607
608
609
610
  	*ultra_timings = ((*ultra_timings) & ~TR_100_UDMAREG_UDMA_MASK) | tr;
  	*ultra_timings = (*ultra_timings) | TR_100_UDMAREG_UDMA_EN;
  
  	return 0;
  }
  
  /*
   * Calculate Shasta ATA/133 UDMA timings
   */
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
611
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
612
613
614
615
616
617
618
619
  set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed)
  {
  	struct ide_timing *t = ide_timing_find_mode(speed);
  	u32 tr;
  
  	if (speed > XFER_UDMA_6 || t == NULL)
  		return 1;
  	tr = kauai_lookup_timing(shasta_udma133_timings, (int)t->udma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
620
621
622
623
624
625
626
627
628
  	*ultra_timings = ((*ultra_timings) & ~TR_133_UDMAREG_UDMA_MASK) | tr;
  	*ultra_timings = (*ultra_timings) | TR_133_UDMAREG_UDMA_EN;
  
  	return 0;
  }
  
  /*
   * Calculate MDMA timings for all cells
   */
90f72eca3   Bartlomiej Zolnierkiewicz   ide-pmac: fix set...
629
  static void
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
630
  set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
90f72eca3   Bartlomiej Zolnierkiewicz   ide-pmac: fix set...
631
  		 	u8 speed)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
632
  {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
633
  	u16 *id = drive->id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
634
635
636
637
638
639
640
641
642
643
644
  	int cycleTime, accessTime = 0, recTime = 0;
  	unsigned accessTicks, recTicks;
  	struct mdma_timings_t* tm = NULL;
  	int i;
  
  	/* Get default cycle time for mode */
  	switch(speed & 0xf) {
  		case 0: cycleTime = 480; break;
  		case 1: cycleTime = 150; break;
  		case 2: cycleTime = 120; break;
  		default:
90f72eca3   Bartlomiej Zolnierkiewicz   ide-pmac: fix set...
645
646
  			BUG();
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
647
  	}
90f72eca3   Bartlomiej Zolnierkiewicz   ide-pmac: fix set...
648
649
  
  	/* Check if drive provides explicit DMA cycle time */
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
650
651
  	if ((id[ATA_ID_FIELD_VALID] & 2) && id[ATA_ID_EIDE_DMA_TIME])
  		cycleTime = max_t(int, id[ATA_ID_EIDE_DMA_TIME], cycleTime);
90f72eca3   Bartlomiej Zolnierkiewicz   ide-pmac: fix set...
652

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
  	/* OHare limits according to some old Apple sources */	
  	if ((intf_type == controller_ohare) && (cycleTime < 150))
  		cycleTime = 150;
  	/* Get the proper timing array for this controller */
  	switch(intf_type) {
  	        case controller_sh_ata6:
  		case controller_un_ata6:
  		case controller_k2_ata6:
  			break;
  		case controller_kl_ata4:
  			tm = mdma_timings_66;
  			break;
  		case controller_kl_ata3:
  			tm = mdma_timings_33k;
  			break;
  		default:
  			tm = mdma_timings_33;
  			break;
  	}
  	if (tm != NULL) {
  		/* Lookup matching access & recovery times */
  		i = -1;
  		for (;;) {
  			if (tm[i+1].cycleTime < cycleTime)
  				break;
  			i++;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
680
681
682
683
684
685
686
687
688
689
690
691
692
693
  		cycleTime = tm[i].cycleTime;
  		accessTime = tm[i].accessTime;
  		recTime = tm[i].recoveryTime;
  
  #ifdef IDE_PMAC_DEBUG
  		printk(KERN_ERR "%s: MDMA, cycleTime: %d, accessTime: %d, recTime: %d
  ",
  			drive->name, cycleTime, accessTime, recTime);
  #endif
  	}
  	switch(intf_type) {
  	case controller_sh_ata6: {
  		/* 133Mhz cell */
  		u32 tr = kauai_lookup_timing(shasta_mdma_timings, cycleTime);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
694
695
696
697
698
699
700
  		*timings = ((*timings) & ~TR_133_PIOREG_MDMA_MASK) | tr;
  		*timings2 = (*timings2) & ~TR_133_UDMAREG_UDMA_EN;
  		}
  	case controller_un_ata6:
  	case controller_k2_ata6: {
  		/* 100Mhz cell */
  		u32 tr = kauai_lookup_timing(kauai_mdma_timings, cycleTime);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
  		*timings = ((*timings) & ~TR_100_PIOREG_MDMA_MASK) | tr;
  		*timings2 = (*timings2) & ~TR_100_UDMAREG_UDMA_EN;
  		}
  		break;
  	case controller_kl_ata4:
  		/* 66Mhz cell */
  		accessTicks = SYSCLK_TICKS_66(accessTime);
  		accessTicks = min(accessTicks, 0x1fU);
  		accessTicks = max(accessTicks, 0x1U);
  		recTicks = SYSCLK_TICKS_66(recTime);
  		recTicks = min(recTicks, 0x1fU);
  		recTicks = max(recTicks, 0x3U);
  		/* Clear out mdma bits and disable udma */
  		*timings = ((*timings) & ~(TR_66_MDMA_MASK | TR_66_UDMA_MASK)) |
  			(accessTicks << TR_66_MDMA_ACCESS_SHIFT) |
  			(recTicks << TR_66_MDMA_RECOVERY_SHIFT);
  		break;
  	case controller_kl_ata3:
  		/* 33Mhz cell on KeyLargo */
  		accessTicks = SYSCLK_TICKS(accessTime);
  		accessTicks = max(accessTicks, 1U);
  		accessTicks = min(accessTicks, 0x1fU);
  		accessTime = accessTicks * IDE_SYSCLK_NS;
  		recTicks = SYSCLK_TICKS(recTime);
  		recTicks = max(recTicks, 1U);
  		recTicks = min(recTicks, 0x1fU);
  		*timings = ((*timings) & ~TR_33_MDMA_MASK) |
  				(accessTicks << TR_33_MDMA_ACCESS_SHIFT) |
  				(recTicks << TR_33_MDMA_RECOVERY_SHIFT);
  		break;
  	default: {
  		/* 33Mhz cell on others */
  		int halfTick = 0;
  		int origAccessTime = accessTime;
  		int origRecTime = recTime;
  		
  		accessTicks = SYSCLK_TICKS(accessTime);
  		accessTicks = max(accessTicks, 1U);
  		accessTicks = min(accessTicks, 0x1fU);
  		accessTime = accessTicks * IDE_SYSCLK_NS;
  		recTicks = SYSCLK_TICKS(recTime);
  		recTicks = max(recTicks, 2U) - 1;
  		recTicks = min(recTicks, 0x1fU);
  		recTime = (recTicks + 1) * IDE_SYSCLK_NS;
  		if ((accessTicks > 1) &&
  		    ((accessTime - IDE_SYSCLK_NS/2) >= origAccessTime) &&
  		    ((recTime - IDE_SYSCLK_NS/2) >= origRecTime)) {
              		halfTick = 1;
  			accessTicks--;
  		}
  		*timings = ((*timings) & ~TR_33_MDMA_MASK) |
  				(accessTicks << TR_33_MDMA_ACCESS_SHIFT) |
  				(recTicks << TR_33_MDMA_RECOVERY_SHIFT);
  		if (halfTick)
  			*timings |= TR_33_MDMA_HALFTICK;
  		}
  	}
  #ifdef IDE_PMAC_DEBUG
  	printk(KERN_ERR "%s: Set MDMA timing for mode %d, reg: 0x%08x
  ",
  		drive->name, speed & 0xf,  *timings);
  #endif	
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
763
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
764

8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
765
  static void pmac_ide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
766
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
767
768
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
769
  	int ret = 0;
085798b12   Bartlomiej Zolnierkiewicz   ide-pmac: pmac_id...
770
  	u32 *timings, *timings2, tl[2];
123995b97   Bartlomiej Zolnierkiewicz   ide: use 'drive->...
771
  	u8 unit = drive->dn & 1;
8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
772
  	const u8 speed = drive->dma_mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
773

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
774
775
  	timings = &pmif->timings[unit];
  	timings2 = &pmif->timings[unit+2];
085798b12   Bartlomiej Zolnierkiewicz   ide-pmac: pmac_id...
776
777
778
779
  
  	/* Copy timings to local image */
  	tl[0] = *timings;
  	tl[1] = *timings2;
4db90a145   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
780
781
782
783
784
785
786
787
788
789
790
791
  	if (speed >= XFER_UDMA_0) {
  		if (pmif->kind == controller_kl_ata4)
  			ret = set_timings_udma_ata4(&tl[0], speed);
  		else if (pmif->kind == controller_un_ata6
  			 || pmif->kind == controller_k2_ata6)
  			ret = set_timings_udma_ata6(&tl[0], &tl[1], speed);
  		else if (pmif->kind == controller_sh_ata6)
  			ret = set_timings_udma_shasta(&tl[0], &tl[1], speed);
  		else
  			ret = -1;
  	} else
  		set_timings_mdma(drive, pmif->kind, &tl[0], &tl[1], speed);
538465747   Bartlomiej Zolnierkiewicz   ide: build-fix fo...
792

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
793
  	if (ret)
88b2b32ba   Bartlomiej Zolnierkiewicz   ide: move ide_con...
794
  		return;
085798b12   Bartlomiej Zolnierkiewicz   ide-pmac: pmac_id...
795
796
797
798
  
  	/* Apply timings to controller */
  	*timings = tl[0];
  	*timings2 = tl[1];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
799
  	pmac_ide_do_update_timings(drive);	
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
800
801
802
803
804
805
  }
  
  /*
   * Blast some well known "safe" values to the timing registers at init or
   * wakeup from sleep time, before we do real calculation
   */
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
806
  static void
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
  sanitize_timings(pmac_ide_hwif_t *pmif)
  {
  	unsigned int value, value2 = 0;
  	
  	switch(pmif->kind) {
  		case controller_sh_ata6:
  			value = 0x0a820c97;
  			value2 = 0x00033031;
  			break;
  		case controller_un_ata6:
  		case controller_k2_ata6:
  			value = 0x08618a92;
  			value2 = 0x00002921;
  			break;
  		case controller_kl_ata4:
  			value = 0x0008438c;
  			break;
  		case controller_kl_ata3:
  			value = 0x00084526;
  			break;
  		case controller_heathrow:
  		case controller_ohare:
  		default:
  			value = 0x00074526;
  			break;
  	}
  	pmif->timings[0] = pmif->timings[1] = value;
  	pmif->timings[2] = pmif->timings[3] = value2;
  }
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
836
837
838
839
  static int on_media_bay(pmac_ide_hwif_t *pmif)
  {
  	return pmif->mdev && pmif->mdev->media_bay != NULL;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
840
841
842
  /* Suspend call back, should be called after the child devices
   * have actually been suspended
   */
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
843
  static int pmac_ide_do_suspend(pmac_ide_hwif_t *pmif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
844
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845
846
847
848
  	/* We clear the timings */
  	pmif->timings[0] = 0;
  	pmif->timings[1] = 0;
  	
616299afc   Benjamin Herrenschmidt   [PATCH] ppc32: Fi...
849
  	disable_irq(pmif->irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
850
  	/* The media bay will handle itself just fine */
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
851
  	if (on_media_bay(pmif))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
  		return 0;
  	
  	/* Kauai has bus control FCRs directly here */
  	if (pmif->kauai_fcr) {
  		u32 fcr = readl(pmif->kauai_fcr);
  		fcr &= ~(KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE);
  		writel(fcr, pmif->kauai_fcr);
  	}
  
  	/* Disable the bus on older machines and the cell on kauai */
  	ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id,
  			    0);
  
  	return 0;
  }
  
  /* Resume call back, should be called before the child devices
   * are resumed
   */
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
871
  static int pmac_ide_do_resume(pmac_ide_hwif_t *pmif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
873
  	/* Hard reset & re-enable controller (do we really need to reset ? -BenH) */
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
874
  	if (!on_media_bay(pmif)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
875
876
877
878
  		ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 1);
  		ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1);
  		msleep(10);
  		ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879
880
881
882
883
884
885
  
  		/* Kauai has it different */
  		if (pmif->kauai_fcr) {
  			u32 fcr = readl(pmif->kauai_fcr);
  			fcr |= KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE;
  			writel(fcr, pmif->kauai_fcr);
  		}
616299afc   Benjamin Herrenschmidt   [PATCH] ppc32: Fi...
886
887
  
  		msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
888
889
890
891
  	}
  
  	/* Sanitize drive timings */
  	sanitize_timings(pmif);
616299afc   Benjamin Herrenschmidt   [PATCH] ppc32: Fi...
892
  	enable_irq(pmif->irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
893
894
  	return 0;
  }
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
895
896
  static u8 pmac_ide_cable_detect(ide_hwif_t *hwif)
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
897
898
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
899
900
  	struct device_node *np = pmif->node;
  	const char *cable = of_get_property(np, "cable-type", NULL);
a9d5a97fa   TOMARI Hisanobu   ide-pmac: IDE cab...
901
902
  	struct device_node *root = of_find_node_by_path("/");
  	const char *model = of_get_property(root, "model", NULL);
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
903
904
  
  	/* Get cable type from device-tree. */
a9d5a97fa   TOMARI Hisanobu   ide-pmac: IDE cab...
905
906
907
908
909
910
911
912
  	if (cable && !strncmp(cable, "80-", 3)) {
  		/* Some drives fail to detect 80c cable in PowerBook */
  		/* These machine use proprietary short IDE cable anyway */
  		if (!strncmp(model, "PowerBook", 9))
  			return ATA_CBL_PATA40_SHORT;
  		else
  			return ATA_CBL_PATA80;
  	}
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
913
914
915
916
917
918
919
920
921
922
923
924
  
  	/*
  	 * G5's seem to have incorrect cable type in device-tree.
  	 * Let's assume they have a 80 conductor cable, this seem
  	 * to be always the case unless the user mucked around.
  	 */
  	if (of_device_is_compatible(np, "K2-UATA") ||
  	    of_device_is_compatible(np, "shasta-ata"))
  		return ATA_CBL_PATA80;
  
  	return ATA_CBL_PATA40;
  }
07eb106f3   Bartlomiej Zolnierkiewicz   ide-pmac: add ->i...
925
926
927
928
929
  static void pmac_ide_init_dev(ide_drive_t *drive)
  {
  	ide_hwif_t *hwif = drive->hwif;
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
930
931
  	if (on_media_bay(pmif)) {
  		if (check_media_bay(pmif->mdev->media_bay) == MB_CD) {
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
932
  			drive->dev_flags &= ~IDE_DFLAG_NOPROBE;
07eb106f3   Bartlomiej Zolnierkiewicz   ide-pmac: add ->i...
933
934
  			return;
  		}
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
935
  		drive->dev_flags |= IDE_DFLAG_NOPROBE;
07eb106f3   Bartlomiej Zolnierkiewicz   ide-pmac: add ->i...
936
937
  	}
  }
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
938
939
940
941
  static const struct ide_tp_ops pmac_tp_ops = {
  	.exec_command		= pmac_exec_command,
  	.read_status		= ide_read_status,
  	.read_altstatus		= ide_read_altstatus,
ecf3a31d2   Sergei Shtylyov   ide: turn set_irq...
942
  	.write_devctl		= pmac_write_devctl,
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
943

abb596b25   Sergei Shtylyov   ide: turn selectp...
944
  	.dev_select		= pmac_dev_select,
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
945
946
947
948
949
950
  	.tf_load		= ide_tf_load,
  	.tf_read		= ide_tf_read,
  
  	.input_data		= ide_input_data,
  	.output_data		= ide_output_data,
  };
abb596b25   Sergei Shtylyov   ide: turn selectp...
951
952
953
954
955
956
957
958
959
960
961
962
  static const struct ide_tp_ops pmac_ata6_tp_ops = {
  	.exec_command		= pmac_exec_command,
  	.read_status		= ide_read_status,
  	.read_altstatus		= ide_read_altstatus,
  	.write_devctl		= pmac_write_devctl,
  
  	.dev_select		= pmac_kauai_dev_select,
  	.tf_load		= ide_tf_load,
  	.tf_read		= ide_tf_read,
  
  	.input_data		= ide_input_data,
  	.output_data		= ide_output_data,
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
963
964
965
  };
  
  static const struct ide_port_ops pmac_ide_ata4_port_ops = {
07eb106f3   Bartlomiej Zolnierkiewicz   ide-pmac: add ->i...
966
  	.init_dev		= pmac_ide_init_dev,
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
967
968
  	.set_pio_mode		= pmac_ide_set_pio_mode,
  	.set_dma_mode		= pmac_ide_set_dma_mode,
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
969
  	.cable_detect		= pmac_ide_cable_detect,
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
970
971
972
  };
  
  static const struct ide_port_ops pmac_ide_port_ops = {
07eb106f3   Bartlomiej Zolnierkiewicz   ide-pmac: add ->i...
973
  	.init_dev		= pmac_ide_init_dev,
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
974
975
  	.set_pio_mode		= pmac_ide_set_pio_mode,
  	.set_dma_mode		= pmac_ide_set_dma_mode,
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
976
  };
f37afdaca   Bartlomiej Zolnierkiewicz   ide: constify str...
977
  static const struct ide_dma_ops pmac_dma_ops;
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
978

c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
979
  static const struct ide_port_info pmac_port_info = {
b36ba5321   Bartlomiej Zolnierkiewicz   ide-pmac: move id...
980
  	.name			= DRV_NAME,
0d0719229   Bartlomiej Zolnierkiewicz   ide-pmac: use ->i...
981
  	.init_dma		= pmac_ide_init_dma,
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
982
  	.chipset		= ide_pmac,
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
983
984
  	.tp_ops			= &pmac_tp_ops,
  	.port_ops		= &pmac_ide_port_ops,
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
985
  	.dma_ops		= &pmac_dma_ops,
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
986
  	.host_flags		= IDE_HFLAG_SET_PIO_MODE_KEEP_DMA |
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
987
  				  IDE_HFLAG_POST_SET_MODE |
c5dd43ec6   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
988
  				  IDE_HFLAG_MMIO |
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
989
990
991
992
  				  IDE_HFLAG_UNMASK_IRQS,
  	.pio_mask		= ATA_PIO4,
  	.mwdma_mask		= ATA_MWDMA2,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
993
994
  /*
   * Setup, register & probe an IDE channel driven by this driver, this is
5b16464ac   Bartlomiej Zolnierkiewicz   ide-pmac: remove ...
995
   * called by one of the 2 probe functions (macio or PCI).
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
996
   */
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
997
998
  static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif,
  					   struct ide_hw *hw)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
999
1000
  {
  	struct device_node *np = pmif->node;
018a3d1db   Jeremy Kerr   [POWERPC] powerma...
1001
  	const int *bidp;
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1002
  	struct ide_host *host;
b36ba5321   Bartlomiej Zolnierkiewicz   ide-pmac: move id...
1003
  	ide_hwif_t *hwif;
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
1004
  	struct ide_hw *hws[] = { hw };
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1005
  	struct ide_port_info d = pmac_port_info;
6f904d015   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1006
  	int rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1007

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1008
  	pmif->broken_dma = pmif->broken_dma_warn = 0;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1009
  	if (of_device_is_compatible(np, "shasta-ata")) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1010
  		pmif->kind = controller_sh_ata6;
abb596b25   Sergei Shtylyov   ide: turn selectp...
1011
1012
  		d.tp_ops = &pmac_ata6_tp_ops;
  		d.port_ops = &pmac_ide_ata4_port_ops;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1013
1014
  		d.udma_mask = ATA_UDMA6;
  	} else if (of_device_is_compatible(np, "kauai-ata")) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1015
  		pmif->kind = controller_un_ata6;
abb596b25   Sergei Shtylyov   ide: turn selectp...
1016
1017
  		d.tp_ops = &pmac_ata6_tp_ops;
  		d.port_ops = &pmac_ide_ata4_port_ops;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1018
1019
  		d.udma_mask = ATA_UDMA5;
  	} else if (of_device_is_compatible(np, "K2-UATA")) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1020
  		pmif->kind = controller_k2_ata6;
abb596b25   Sergei Shtylyov   ide: turn selectp...
1021
1022
  		d.tp_ops = &pmac_ata6_tp_ops;
  		d.port_ops = &pmac_ide_ata4_port_ops;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1023
1024
1025
  		d.udma_mask = ATA_UDMA5;
  	} else if (of_device_is_compatible(np, "keylargo-ata")) {
  		if (strcmp(np->name, "ata-4") == 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1026
  			pmif->kind = controller_kl_ata4;
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
1027
  			d.port_ops = &pmac_ide_ata4_port_ops;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1028
1029
  			d.udma_mask = ATA_UDMA4;
  		} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1030
  			pmif->kind = controller_kl_ata3;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1031
  	} else if (of_device_is_compatible(np, "heathrow-ata")) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1032
  		pmif->kind = controller_heathrow;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1033
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1034
1035
1036
  		pmif->kind = controller_ohare;
  		pmif->broken_dma = 1;
  	}
40cd3a456   Stephen Rothwell   [POWERPC] Rename ...
1037
  	bidp = of_get_property(np, "AAPL,bus-id", NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1038
  	pmif->aapl_bus_id =  bidp ? *bidp : 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1039
1040
1041
1042
1043
  	/* On Kauai-type controllers, we make sure the FCR is correct */
  	if (pmif->kauai_fcr)
  		writel(KAUAI_FCR_UATA_MAGIC |
  		       KAUAI_FCR_UATA_RESET_N |
  		       KAUAI_FCR_UATA_ENABLE, pmif->kauai_fcr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1044
1045
1046
  	
  	/* Make sure we have sane timings */
  	sanitize_timings(pmif);
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1047
1048
1049
  	/* If we are on a media bay, wait for it to settle and lock it */
  	if (pmif->mdev)
  		lock_media_bay(pmif->mdev->media_bay);
dca398305   Bartlomiej Zolnierkiewicz   ide: pass number ...
1050
  	host = ide_host_alloc(&d, hws, 1);
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1051
1052
1053
1054
1055
  	if (host == NULL) {
  		rc = -ENOMEM;
  		goto bail;
  	}
  	hwif = pmif->hwif = host->ports[0];
9842727da   Benjamin Herrenschmidt   ide/powermac: Fix...
1056

d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1057
1058
  	if (on_media_bay(pmif)) {
  		/* Fixup bus ID for media bay */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1059
1060
1061
1062
1063
1064
1065
1066
  		if (!bidp)
  			pmif->aapl_bus_id = 1;
  	} else if (pmif->kind == controller_ohare) {
  		/* The code below is having trouble on some ohare machines
  		 * (timing related ?). Until I can put my hand on one of these
  		 * units, I keep the old way
  		 */
  		ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, 0, 1);
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1067
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1068
1069
1070
1071
1072
1073
1074
   		/* This is necessary to enable IDE when net-booting */
  		ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1);
  		ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1);
  		msleep(10);
  		ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 0);
  		msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY));
  	}
b36ba5321   Bartlomiej Zolnierkiewicz   ide-pmac: move id...
1075
  	printk(KERN_INFO DRV_NAME ": Found Apple %s controller (%s), "
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1076
1077
1078
1079
  	       "bus ID %d%s, irq %d
  ", model_name[pmif->kind],
  	       pmif->mdev ? "macio" : "PCI", pmif->aapl_bus_id,
  	       on_media_bay(pmif) ? " (mediabay)" : "", hw->irq);
b36ba5321   Bartlomiej Zolnierkiewicz   ide-pmac: move id...
1080

9842727da   Benjamin Herrenschmidt   ide/powermac: Fix...
1081
  	rc = ide_host_register(host, &d, hws);
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1082
1083
  	if (rc)
  		pmif->hwif = NULL;
5cbf79cdb   Bartlomiej Zolnierkiewicz   ide: add ide_proc...
1084

d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1085
1086
1087
1088
1089
1090
1091
  	if (pmif->mdev)
  		unlock_media_bay(pmif->mdev->media_bay);
  
   bail:
  	if (rc && host)
  		ide_host_free(host);
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1092
  }
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
1093
  static void __devinit pmac_ide_init_ports(struct ide_hw *hw, unsigned long base)
5c58666fa   Bartlomiej Zolnierkiewicz   ppc/pmac: remove ...
1094
1095
1096
1097
  {
  	int i;
  
  	for (i = 0; i < 8; ++i)
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
1098
1099
1100
  		hw->io_ports_array[i] = base + i * 0x10;
  
  	hw->io_ports.ctl_addr = base + 0x160;
5c58666fa   Bartlomiej Zolnierkiewicz   ppc/pmac: remove ...
1101
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1102
1103
1104
1105
  /*
   * Attach to a macio probed interface
   */
  static int __devinit
5e6557722   Jeff Mahoney   [PATCH] openfirmw...
1106
  pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1107
1108
1109
  {
  	void __iomem *base;
  	unsigned long regbase;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1110
  	pmac_ide_hwif_t *pmif;
939b0f1d3   Bartlomiej Zolnierkiewicz   ide-pmac: use ide...
1111
  	int irq, rc;
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
1112
  	struct ide_hw hw;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1113

5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1114
1115
1116
  	pmif = kzalloc(sizeof(*pmif), GFP_KERNEL);
  	if (pmif == NULL)
  		return -ENOMEM;
cc5d0189b   Benjamin Herrenschmidt   [PATCH] powerpc: ...
1117
  	if (macio_resource_count(mdev) == 0) {
939b0f1d3   Bartlomiej Zolnierkiewicz   ide-pmac: use ide...
1118
1119
  		printk(KERN_WARNING "ide-pmac: no address for %s
  ",
61c7a080a   Grant Likely   of: Always use 's...
1120
  				    mdev->ofdev.dev.of_node->full_name);
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1121
1122
  		rc = -ENXIO;
  		goto out_free_pmif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1123
1124
1125
1126
  	}
  
  	/* Request memory resource for IO ports */
  	if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) {
939b0f1d3   Bartlomiej Zolnierkiewicz   ide-pmac: use ide...
1127
  		printk(KERN_ERR "ide-pmac: can't request MMIO resource for "
61c7a080a   Grant Likely   of: Always use 's...
1128
1129
  				"%s!
  ", mdev->ofdev.dev.of_node->full_name);
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1130
1131
  		rc = -EBUSY;
  		goto out_free_pmif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1132
1133
1134
1135
1136
1137
1138
1139
  	}
  			
  	/* XXX This is bogus. Should be fixed in the registry by checking
  	 * the kind of host interrupt controller, a bit like gatwick
  	 * fixes in irq.c. That works well enough for the single case
  	 * where that happens though...
  	 */
  	if (macio_irq_count(mdev) == 0) {
939b0f1d3   Bartlomiej Zolnierkiewicz   ide-pmac: use ide...
1140
  		printk(KERN_WARNING "ide-pmac: no intrs for device %s, using "
61c7a080a   Grant Likely   of: Always use 's...
1141
1142
  				    "13
  ", mdev->ofdev.dev.of_node->full_name);
69917c26c   Benjamin Herrenschmidt   [POWERPC] Fix oha...
1143
  		irq = irq_create_mapping(NULL, 13);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1144
1145
1146
1147
1148
  	} else
  		irq = macio_irq(mdev, 0);
  
  	base = ioremap(macio_resource_start(mdev, 0), 0x400);
  	regbase = (unsigned long) base;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1149
  	pmif->mdev = mdev;
61c7a080a   Grant Likely   of: Always use 's...
1150
  	pmif->node = mdev->ofdev.dev.of_node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1151
1152
1153
  	pmif->regbase = regbase;
  	pmif->irq = irq;
  	pmif->kauai_fcr = NULL;
538465747   Bartlomiej Zolnierkiewicz   ide: build-fix fo...
1154

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1155
1156
  	if (macio_resource_count(mdev) >= 2) {
  		if (macio_request_resource(mdev, 1, "ide-pmac (dma)"))
939b0f1d3   Bartlomiej Zolnierkiewicz   ide-pmac: use ide...
1157
1158
1159
  			printk(KERN_WARNING "ide-pmac: can't request DMA "
  					    "resource for %s!
  ",
61c7a080a   Grant Likely   of: Always use 's...
1160
  					    mdev->ofdev.dev.of_node->full_name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1161
1162
1163
1164
  		else
  			pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000);
  	} else
  		pmif->dma_regs = NULL;
538465747   Bartlomiej Zolnierkiewicz   ide: build-fix fo...
1165

7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1166
  	dev_set_drvdata(&mdev->ofdev.dev, pmif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1167

57c802e84   Bartlomiej Zolnierkiewicz   ide: add ide_init...
1168
  	memset(&hw, 0, sizeof(hw));
5c58666fa   Bartlomiej Zolnierkiewicz   ppc/pmac: remove ...
1169
  	pmac_ide_init_ports(&hw, pmif->regbase);
57c802e84   Bartlomiej Zolnierkiewicz   ide: add ide_init...
1170
  	hw.irq = irq;
c56c5648a   Bartlomiej Zolnierkiewicz   ide: set hwif->de...
1171
1172
  	hw.dev = &mdev->bus->pdev->dev;
  	hw.parent = &mdev->ofdev.dev;
57c802e84   Bartlomiej Zolnierkiewicz   ide: add ide_init...
1173

b36ba5321   Bartlomiej Zolnierkiewicz   ide-pmac: move id...
1174
  	rc = pmac_ide_setup_device(pmif, &hw);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1175
1176
1177
1178
  	if (rc != 0) {
  		/* The inteface is released to the common IDE layer */
  		dev_set_drvdata(&mdev->ofdev.dev, NULL);
  		iounmap(base);
ed908fa1d   Bartlomiej Zolnierkiewicz   ide-pmac: macio r...
1179
  		if (pmif->dma_regs) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1180
  			iounmap(pmif->dma_regs);
ed908fa1d   Bartlomiej Zolnierkiewicz   ide-pmac: macio r...
1181
1182
  			macio_release_resource(mdev, 1);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1183
  		macio_release_resource(mdev, 0);
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1184
  		kfree(pmif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1185
1186
1187
  	}
  
  	return rc;
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1188
1189
1190
1191
  
  out_free_pmif:
  	kfree(pmif);
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1192
1193
1194
  }
  
  static int
8b4b8a24e   David Brownell   fix broken/dubiou...
1195
  pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t mesg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1196
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1197
1198
1199
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
  	int rc = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1200

8b4b8a24e   David Brownell   fix broken/dubiou...
1201
  	if (mesg.event != mdev->ofdev.dev.power.power_state.event
3a2d5b700   Rafael J. Wysocki   PM: Introduce PM_...
1202
  			&& (mesg.event & PM_EVENT_SLEEP)) {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1203
  		rc = pmac_ide_do_suspend(pmif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1204
  		if (rc == 0)
8b4b8a24e   David Brownell   fix broken/dubiou...
1205
  			mdev->ofdev.dev.power.power_state = mesg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1206
1207
1208
1209
1210
1211
1212
1213
  	}
  
  	return rc;
  }
  
  static int
  pmac_ide_macio_resume(struct macio_dev *mdev)
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1214
1215
1216
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
  	int rc = 0;
ca078bae8   Pavel Machek   [PATCH] swsusp: s...
1217
  	if (mdev->ofdev.dev.power.power_state.event != PM_EVENT_ON) {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1218
  		rc = pmac_ide_do_resume(pmif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1219
  		if (rc == 0)
829ca9a30   Pavel Machek   [PATCH] swsusp: f...
1220
  			mdev->ofdev.dev.power.power_state = PMSG_ON;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
  	}
  
  	return rc;
  }
  
  /*
   * Attach to a PCI probed interface
   */
  static int __devinit
  pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1232
1233
1234
1235
  	struct device_node *np;
  	pmac_ide_hwif_t *pmif;
  	void __iomem *base;
  	unsigned long rbase, rlen;
939b0f1d3   Bartlomiej Zolnierkiewicz   ide-pmac: use ide...
1236
  	int rc;
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
1237
  	struct ide_hw hw;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1238
1239
1240
1241
1242
1243
1244
  
  	np = pci_device_to_OF_node(pdev);
  	if (np == NULL) {
  		printk(KERN_ERR "ide-pmac: cannot find MacIO node for Kauai ATA interface
  ");
  		return -ENODEV;
  	}
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1245
1246
1247
1248
  
  	pmif = kzalloc(sizeof(*pmif), GFP_KERNEL);
  	if (pmif == NULL)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1249
  	if (pci_enable_device(pdev)) {
939b0f1d3   Bartlomiej Zolnierkiewicz   ide-pmac: use ide...
1250
1251
1252
  		printk(KERN_WARNING "ide-pmac: Can't enable PCI device for "
  				    "%s
  ", np->full_name);
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1253
1254
  		rc = -ENXIO;
  		goto out_free_pmif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1255
1256
1257
1258
  	}
  	pci_set_master(pdev);
  			
  	if (pci_request_regions(pdev, "Kauai ATA")) {
939b0f1d3   Bartlomiej Zolnierkiewicz   ide-pmac: use ide...
1259
1260
1261
  		printk(KERN_ERR "ide-pmac: Cannot obtain PCI resources for "
  				"%s
  ", np->full_name);
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1262
1263
  		rc = -ENXIO;
  		goto out_free_pmif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1264
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1265
1266
1267
1268
1269
1270
1271
1272
  	pmif->mdev = NULL;
  	pmif->node = np;
  
  	rbase = pci_resource_start(pdev, 0);
  	rlen = pci_resource_len(pdev, 0);
  
  	base = ioremap(rbase, rlen);
  	pmif->regbase = (unsigned long) base + 0x2000;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1273
  	pmif->dma_regs = base + 0x1000;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1274
1275
  	pmif->kauai_fcr = base;
  	pmif->irq = pdev->irq;
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1276
  	pci_set_drvdata(pdev, pmif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1277

57c802e84   Bartlomiej Zolnierkiewicz   ide: add ide_init...
1278
  	memset(&hw, 0, sizeof(hw));
5c58666fa   Bartlomiej Zolnierkiewicz   ppc/pmac: remove ...
1279
  	pmac_ide_init_ports(&hw, pmif->regbase);
57c802e84   Bartlomiej Zolnierkiewicz   ide: add ide_init...
1280
1281
  	hw.irq = pdev->irq;
  	hw.dev = &pdev->dev;
b36ba5321   Bartlomiej Zolnierkiewicz   ide-pmac: move id...
1282
  	rc = pmac_ide_setup_device(pmif, &hw);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1283
1284
1285
1286
  	if (rc != 0) {
  		/* The inteface is released to the common IDE layer */
  		pci_set_drvdata(pdev, NULL);
  		iounmap(base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1287
  		pci_release_regions(pdev);
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1288
  		kfree(pmif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1289
1290
1291
  	}
  
  	return rc;
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1292
1293
1294
1295
  
  out_free_pmif:
  	kfree(pmif);
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1296
1297
1298
  }
  
  static int
8b4b8a24e   David Brownell   fix broken/dubiou...
1299
  pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1300
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1301
1302
  	pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)pci_get_drvdata(pdev);
  	int rc = 0;
8b4b8a24e   David Brownell   fix broken/dubiou...
1303
  	if (mesg.event != pdev->dev.power.power_state.event
3a2d5b700   Rafael J. Wysocki   PM: Introduce PM_...
1304
  			&& (mesg.event & PM_EVENT_SLEEP)) {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1305
  		rc = pmac_ide_do_suspend(pmif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1306
  		if (rc == 0)
8b4b8a24e   David Brownell   fix broken/dubiou...
1307
  			pdev->dev.power.power_state = mesg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1308
1309
1310
1311
1312
1313
1314
1315
  	}
  
  	return rc;
  }
  
  static int
  pmac_ide_pci_resume(struct pci_dev *pdev)
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1316
1317
  	pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)pci_get_drvdata(pdev);
  	int rc = 0;
ca078bae8   Pavel Machek   [PATCH] swsusp: s...
1318
  	if (pdev->dev.power.power_state.event != PM_EVENT_ON) {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1319
  		rc = pmac_ide_do_resume(pmif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1320
  		if (rc == 0)
829ca9a30   Pavel Machek   [PATCH] swsusp: f...
1321
  			pdev->dev.power.power_state = PMSG_ON;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1322
1323
1324
1325
  	}
  
  	return rc;
  }
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
  #ifdef CONFIG_PMAC_MEDIABAY
  static void pmac_ide_macio_mb_event(struct macio_dev* mdev, int mb_state)
  {
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
  
  	switch(mb_state) {
  	case MB_CD:
  		if (!pmif->hwif->present)
  			ide_port_scan(pmif->hwif);
  		break;
  	default:
  		if (pmif->hwif->present)
  			ide_port_unregister_devices(pmif->hwif);
  	}
  }
  #endif /* CONFIG_PMAC_MEDIABAY */
5e6557722   Jeff Mahoney   [PATCH] openfirmw...
1343
  static struct of_device_id pmac_ide_macio_match[] = 
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1344
1345
1346
  {
  	{
  	.name 		= "IDE",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1347
1348
1349
  	},
  	{
  	.name 		= "ATA",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1350
1351
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1352
  	.type		= "ide",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353
1354
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1355
  	.type		= "ata",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1356
1357
1358
1359
1360
1361
  	},
  	{},
  };
  
  static struct macio_driver pmac_ide_macio_driver = 
  {
c2cdf6aba   Benjamin Herrenschmidt   powerpc/macio: Fi...
1362
1363
1364
1365
1366
  	.driver = {
  		.name 		= "ide-pmac",
  		.owner		= THIS_MODULE,
  		.of_match_table	= pmac_ide_macio_match,
  	},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1367
1368
1369
  	.probe		= pmac_ide_macio_attach,
  	.suspend	= pmac_ide_macio_suspend,
  	.resume		= pmac_ide_macio_resume,
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1370
1371
1372
  #ifdef CONFIG_PMAC_MEDIABAY
  	.mediabay_event	= pmac_ide_macio_mb_event,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1373
  };
9cbcc5e3c   Bartlomiej Zolnierkiewicz   ide: use PCI_VDEV...
1374
1375
1376
1377
1378
1379
  static const struct pci_device_id pmac_ide_pci_match[] = {
  	{ PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA),	0 },
  	{ PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100),	0 },
  	{ PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100),	0 },
  	{ PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_SH_ATA),	0 },
  	{ PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA),	0 },
71e4eda8c   Benjamin Herrenschmidt   Fix non-terminate...
1380
  	{},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
  };
  
  static struct pci_driver pmac_ide_pci_driver = {
  	.name		= "ide-pmac",
  	.id_table	= pmac_ide_pci_match,
  	.probe		= pmac_ide_pci_attach,
  	.suspend	= pmac_ide_pci_suspend,
  	.resume		= pmac_ide_pci_resume,
  };
  MODULE_DEVICE_TABLE(pci, pmac_ide_pci_match);
9e5755bce   Andrew Morton   ide: fix pmac bre...
1391
  int __init pmac_ide_probe(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1392
  {
9e5755bce   Andrew Morton   ide: fix pmac bre...
1393
  	int error;
e8222502e   Benjamin Herrenschmidt   [PATCH] powerpc: ...
1394
  	if (!machine_is(powermac))
9e5755bce   Andrew Morton   ide: fix pmac bre...
1395
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1396
1397
  
  #ifdef CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST
9e5755bce   Andrew Morton   ide: fix pmac bre...
1398
1399
1400
1401
1402
1403
1404
1405
  	error = pci_register_driver(&pmac_ide_pci_driver);
  	if (error)
  		goto out;
  	error = macio_register_driver(&pmac_ide_macio_driver);
  	if (error) {
  		pci_unregister_driver(&pmac_ide_pci_driver);
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1406
  #else
9e5755bce   Andrew Morton   ide: fix pmac bre...
1407
1408
1409
1410
1411
1412
1413
1414
  	error = macio_register_driver(&pmac_ide_macio_driver);
  	if (error)
  		goto out;
  	error = pci_register_driver(&pmac_ide_pci_driver);
  	if (error) {
  		macio_unregister_driver(&pmac_ide_macio_driver);
  		goto out;
  	}
1beb6a7d6   Benjamin Herrenschmidt   [PATCH] powerpc: ...
1415
  #endif
9e5755bce   Andrew Morton   ide: fix pmac bre...
1416
1417
  out:
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1418
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1419
1420
1421
1422
  /*
   * pmac_ide_build_dmatable builds the DBDMA command list
   * for a transfer and sets the DBDMA channel to point to it.
   */
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
1423
  static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1424
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1425
1426
1427
  	ide_hwif_t *hwif = drive->hwif;
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1428
  	struct dbdma_cmd *table;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1429
1430
  	volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
  	struct scatterlist *sg;
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
1431
1432
  	int wr = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
  	int i = cmd->sg_nents, count = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1433
1434
1435
1436
1437
1438
1439
1440
  
  	/* DMA table is already aligned */
  	table = (struct dbdma_cmd *) pmif->dma_table_cpu;
  
  	/* Make sure DMA controller is stopped (necessary ?) */
  	writel((RUN|PAUSE|FLUSH|WAKE|DEAD) << 16, &dma->control);
  	while (readl(&dma->status) & RUN)
  		udelay(1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
  	/* Build DBDMA commands list */
  	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);
  
  		if (pmif->broken_dma && cur_addr & (L1_CACHE_BYTES - 1)) {
  			if (pmif->broken_dma_warn == 0) {
aca38a515   Joe Perches   drivers/ide: Add ...
1452
  				printk(KERN_WARNING "%s: DMA on non aligned address, "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1453
1454
1455
1456
  				       "switching to PIO on Ohare chipset
  ", drive->name);
  				pmif->broken_dma_warn = 1;
  			}
11998b316   Bartlomiej Zolnierkiewicz   ide: move ide_map...
1457
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1458
1459
1460
1461
1462
1463
1464
1465
  		}
  		while (cur_len) {
  			unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
  
  			if (count++ >= MAX_DCMDS) {
  				printk(KERN_WARNING "%s: DMA table too small
  ",
  				       drive->name);
11998b316   Bartlomiej Zolnierkiewicz   ide: move ide_map...
1466
  				return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
  			}
  			st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE);
  			st_le16(&table->req_count, tc);
  			st_le32(&table->phy_addr, cur_addr);
  			table->cmd_dep = 0;
  			table->xfer_status = 0;
  			table->res_count = 0;
  			cur_addr += tc;
  			cur_len -= tc;
  			++table;
  		}
55c16a700   Jens Axboe   IDE: sg chaining ...
1478
  		sg = sg_next(sg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
  		i--;
  	}
  
  	/* convert the last command to an input/output last command */
  	if (count) {
  		st_le16(&table[-1].command, wr? OUTPUT_LAST: INPUT_LAST);
  		/* add the stop command to the end of the list */
  		memset(table, 0, sizeof(struct dbdma_cmd));
  		st_le16(&table->command, DBDMA_STOP);
  		mb();
  		writel(hwif->dmatable_dma, &dma->cmdptr);
  		return 1;
  	}
  
  	printk(KERN_DEBUG "%s: empty DMA table?
  ", drive->name);
f6fb786d6   Bartlomiej Zolnierkiewicz   ide: use ide_dest...
1495

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1496
1497
  	return 0; /* revert to PIO for this request */
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1498
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1499
1500
1501
   * Prepare a DMA transfer. We build the DMA table, adjust the timings for
   * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
   */
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
1502
  static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1503
  {
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
1504
  	ide_hwif_t *hwif = drive->hwif;
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1505
1506
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
9055ba3ee   Bartlomiej Zolnierkiewicz   pmac: remove supe...
1507
  	u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
1508
  	u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1509

11998b316   Bartlomiej Zolnierkiewicz   ide: move ide_map...
1510
  	if (pmac_ide_build_dmatable(drive, cmd) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1511
  		return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1512
1513
1514
  
  	/* Apple adds 60ns to wrDataSetup on reads */
  	if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
1515
  		writel(pmif->timings[unit] + (write ? 0 : 0x00800000UL),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1516
1517
1518
  			PMAC_IDE_REG(IDE_TIMING_CONFIG));
  		(void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1519
1520
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1521
1522
1523
1524
  /*
   * Kick the DMA controller into life after the DMA command has been issued
   * to the drive.
   */
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
1525
  static void
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1526
1527
  pmac_ide_dma_start(ide_drive_t *drive)
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1528
1529
1530
  	ide_hwif_t *hwif = drive->hwif;
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
  	volatile struct dbdma_regs __iomem *dma;
  
  	dma = pmif->dma_regs;
  
  	writel((RUN << 16) | RUN, &dma->control);
  	/* Make sure it gets to the controller right now */
  	(void)readl(&dma->control);
  }
  
  /*
   * After a DMA transfer, make sure the controller is stopped
   */
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
1543
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1544
1545
  pmac_ide_dma_end (ide_drive_t *drive)
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1546
1547
1548
  	ide_hwif_t *hwif = drive->hwif;
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
9055ba3ee   Bartlomiej Zolnierkiewicz   pmac: remove supe...
1549
  	volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1550
  	u32 dstat;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1551

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1552
1553
  	dstat = readl(&dma->status);
  	writel(((RUN|WAKE|DEAD) << 16), &dma->control);
f5e0b5ecb   Bartlomiej Zolnierkiewicz   pmac: remove need...
1554

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
  	/* verify good dma status. we don't check for ACTIVE beeing 0. We should...
  	 * in theory, but with ATAPI decices doing buffer underruns, that would
  	 * cause us to disable DMA, which isn't what we want
  	 */
  	return (dstat & (RUN|DEAD)) != RUN;
  }
  
  /*
   * Check out that the interrupt we got was for us. We can't always know this
   * for sure with those Apple interfaces (well, we could on the recent ones but
   * that's not implemented yet), on the other hand, we don't have shared interrupts
   * so it's not really a problem
   */
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
1568
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1569
1570
  pmac_ide_dma_test_irq (ide_drive_t *drive)
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1571
1572
1573
  	ide_hwif_t *hwif = drive->hwif;
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
9055ba3ee   Bartlomiej Zolnierkiewicz   pmac: remove supe...
1574
  	volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1575
  	unsigned long status, timeout;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
  	/* We have to things to deal with here:
  	 * 
  	 * - The dbdma won't stop if the command was started
  	 * but completed with an error without transferring all
  	 * datas. This happens when bad blocks are met during
  	 * a multi-block transfer.
  	 * 
  	 * - The dbdma fifo hasn't yet finished flushing to
  	 * to system memory when the disk interrupt occurs.
  	 * 
  	 */
  
  	/* If ACTIVE is cleared, the STOP command have passed and
  	 * transfer is complete.
  	 */
  	status = readl(&dma->status);
  	if (!(status & ACTIVE))
  		return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
  
  	/* If dbdma didn't execute the STOP command yet, the
  	 * active bit is still set. We consider that we aren't
  	 * sharing interrupts (which is hopefully the case with
  	 * those controllers) and so we just try to flush the
  	 * channel for pending data in the fifo
  	 */
  	udelay(1);
  	writel((FLUSH << 16) | FLUSH, &dma->control);
  	timeout = 0;
  	for (;;) {
  		udelay(1);
  		status = readl(&dma->status);
  		if ((status & FLUSH) == 0)
  			break;
  		if (++timeout > 100) {
b1681c56f   Joe Perches   drivers/ide: Fix ...
1610
1611
1612
  			printk(KERN_WARNING "ide%d, ide_dma_test_irq timeout flushing channel
  ",
  			       hwif->index);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1613
1614
1615
1616
1617
  			break;
  		}
  	}	
  	return 1;
  }
15ce926ad   Bartlomiej Zolnierkiewicz   ide: merge ->dma_...
1618
  static void pmac_ide_dma_host_set(ide_drive_t *drive, int on)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1619
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1620
  }
841d2a9bf   Sergei Shtylyov   ide: make void an...
1621
1622
  static void
  pmac_ide_dma_lost_irq (ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1623
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1624
1625
1626
  	ide_hwif_t *hwif = drive->hwif;
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
9055ba3ee   Bartlomiej Zolnierkiewicz   pmac: remove supe...
1627
1628
  	volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
  	unsigned long status = readl(&dma->status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1629

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1630
1631
  	printk(KERN_ERR "ide-pmac lost interrupt, dma status: %lx
  ", status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1632
  }
f37afdaca   Bartlomiej Zolnierkiewicz   ide: constify str...
1633
  static const struct ide_dma_ops pmac_dma_ops = {
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
1634
1635
  	.dma_host_set		= pmac_ide_dma_host_set,
  	.dma_setup		= pmac_ide_dma_setup,
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
1636
1637
1638
  	.dma_start		= pmac_ide_dma_start,
  	.dma_end		= pmac_ide_dma_end,
  	.dma_test_irq		= pmac_ide_dma_test_irq,
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
1639
1640
  	.dma_lost_irq		= pmac_ide_dma_lost_irq,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1641
1642
1643
1644
  /*
   * Allocate the data structures needed for using DMA with an interface
   * and fill the proper list of functions pointers
   */
0d0719229   Bartlomiej Zolnierkiewicz   ide-pmac: use ->i...
1645
1646
  static int __devinit pmac_ide_init_dma(ide_hwif_t *hwif,
  				       const struct ide_port_info *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1647
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1648
1649
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
1650
  	struct pci_dev *dev = to_pci_dev(hwif->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1651
1652
1653
  	/* We won't need pci_dev if we switch to generic consistent
  	 * DMA routines ...
  	 */
0d0719229   Bartlomiej Zolnierkiewicz   ide-pmac: use ->i...
1654
  	if (dev == NULL || pmif->dma_regs == 0)
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1655
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1656
1657
1658
1659
1660
  	/*
  	 * Allocate space for the DBDMA commands.
  	 * The +2 is +1 for the stop command and +1 to allow for
  	 * aligning the start address to a multiple of 16 bytes.
  	 */
d5f840bf7   Jack Stone   ide: Remove void ...
1661
  	pmif->dma_table_cpu = pci_alloc_consistent(
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
1662
  		dev,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1663
1664
1665
1666
1667
1668
  		(MAX_DCMDS + 2) * sizeof(struct dbdma_cmd),
  		&hwif->dmatable_dma);
  	if (pmif->dma_table_cpu == NULL) {
  		printk(KERN_ERR "%s: unable to allocate DMA command list
  ",
  		       hwif->name);
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1669
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1670
  	}
4f52a3299   Bartlomiej Zolnierkiewicz   ide-pmac: use cus...
1671
  	hwif->sg_max_nents = MAX_DCMDS;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1672
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1673
  }
ade2daf9c   Bartlomiej Zolnierkiewicz   ide: make remaini...
1674
1675
  
  module_init(pmac_ide_probe);
de9facbff   Adrian Bunk   ide/ppc/pmac.c: a...
1676
1677
  
  MODULE_LICENSE("GPL");