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
  #include <linux/init.h>
  #include <linux/delay.h>
  #include <linux/ide.h>
  #include <linux/notifier.h>
bff7832dd   Paul Gortmaker   ide/ata: Add modu...
31
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
34
35
36
  #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: ...
37
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
40
41
42
43
44
45
46
47
  
  #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
48
  #include <asm/mediabay.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49

b36ba5321   Bartlomiej Zolnierkiewicz   ide-pmac: move id...
50
  #define DRV_NAME "ide-pmac"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
53
54
55
56
57
58
59
  #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
60
61
62
63
64
65
  	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...
66
  	ide_hwif_t			*hwif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
68
69
70
71
72
73
  	/* 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
74
  } pmac_ide_hwif_t;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
217
  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
218
219
220
221
222
223
224
225
226
227
228
  /* 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: ...
229
  struct mdma_timings_t mdma_timings_33[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
232
233
234
235
236
237
238
239
240
  {
      { 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: ...
241
  struct mdma_timings_t mdma_timings_33k[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
243
244
245
246
247
248
249
250
251
252
  {
      { 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: ...
253
  struct mdma_timings_t mdma_timings_66[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  {
      { 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: ...
271
  } kl66_udma_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
273
274
275
276
277
278
279
280
281
282
283
284
  {
      {   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: ...
285
  static struct kauai_timing	kauai_pio_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286
287
288
289
290
291
292
293
294
295
296
  {
  	{ 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...
297
298
  	{ 120	, 0x04000148 },
  	{ 0	, 0 },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
  };
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
300
  static struct kauai_timing	kauai_mdma_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
302
303
304
305
306
307
308
309
310
311
312
  {
  	{ 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: ...
313
  static struct kauai_timing	kauai_udma_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314
315
316
317
318
319
320
321
322
  {
  	{ 120	, 0x000070c0 },
  	{ 90	, 0x00005d80 },
  	{ 60	, 0x00004a60 },
  	{ 45	, 0x00003a50 },
  	{ 30	, 0x00002a30 },
  	{ 20	, 0x00002921 },
  	{ 0	, 0 },
  };
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
323
  static struct kauai_timing	shasta_pio_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
325
326
327
328
329
330
331
332
333
334
  {
  	{ 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...
335
336
  	{ 120	, 0x0400010a },
  	{ 0	, 0 },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337
  };
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
338
  static struct kauai_timing	shasta_mdma_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
340
341
342
343
344
345
346
347
348
349
350
  {
  	{ 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: ...
351
  static struct kauai_timing	shasta_udma133_timings[] =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  {
  	{ 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...
372
  	BUG();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
  	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...
392
  static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393

23579a2a1   Bartlomiej Zolnierkiewicz   ide: remove IDE_*...
394
  #define PMAC_IDE_REG(x) \
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
395
  	((void __iomem *)((drive)->hwif->io_ports.data_addr + (x)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396
397
398
399
400
401
  
  /*
   * 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...
402
  static void pmac_ide_apply_timings(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
404
405
406
  	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
407

123995b97   Bartlomiej Zolnierkiewicz   ide: use 'drive->...
408
  	if (drive->dn & 1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409
410
411
412
413
414
415
416
417
418
419
  		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...
420
  static void pmac_ide_kauai_apply_timings(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
422
423
424
  	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
425

123995b97   Bartlomiej Zolnierkiewicz   ide: use 'drive->...
426
  	if (drive->dn & 1) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
428
429
430
431
432
433
434
435
436
437
438
  		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: ...
439
  static void
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
441
  pmac_ide_do_update_timings(ide_drive_t *drive)
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
442
443
444
  	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
445

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

7dd00083b   Bartlomiej Zolnierkiewicz   ide: add ide_pio_...
498
  	cycle_time = ide_pio_cycle_time(drive, pio);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
499
500
501
502
  
  	switch (pmif->kind) {
  	case controller_sh_ata6: {
  		/* 133Mhz cell */
7dd00083b   Bartlomiej Zolnierkiewicz   ide: add ide_pio_...
503
  		u32 tr = kauai_lookup_timing(shasta_pio_timings, cycle_time);
0b46ff2ea   Benjamin Herrenschmidt   ide-pmac: fix PIO...
504
  		t = (t & ~TR_133_PIOREG_PIO_MASK) | tr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
505
506
507
508
509
  		break;
  		}
  	case controller_un_ata6:
  	case controller_k2_ata6: {
  		/* 100Mhz cell */
7dd00083b   Bartlomiej Zolnierkiewicz   ide: add ide_pio_...
510
  		u32 tr = kauai_lookup_timing(kauai_pio_timings, cycle_time);
0b46ff2ea   Benjamin Herrenschmidt   ide-pmac: fix PIO...
511
  		t = (t & ~TR_100_PIOREG_PIO_MASK) | tr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512
513
514
515
  		break;
  		}
  	case controller_kl_ata4:
  		/* 66Mhz cell */
8a97206e3   Bartlomiej Zolnierkiewicz   ide-pmac: convert...
516
  		recTime = cycle_time - tim->active - tim->setup;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
517
  		recTime = max(recTime, 150U);
8a97206e3   Bartlomiej Zolnierkiewicz   ide-pmac: convert...
518
  		accessTime = tim->active;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
519
520
521
522
523
  		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...
524
525
526
  		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
527
528
529
530
  		break;
  	default: {
  		/* 33Mhz cell */
  		int ebit = 0;
8a97206e3   Bartlomiej Zolnierkiewicz   ide-pmac: convert...
531
  		recTime = cycle_time - tim->active - tim->setup;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
  		recTime = max(recTime, 150U);
8a97206e3   Bartlomiej Zolnierkiewicz   ide-pmac: convert...
533
  		accessTime = tim->active;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
535
536
537
538
539
540
541
542
543
544
  		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...
545
  		t = (t & ~TR_33_PIO_MASK) |
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
546
547
548
  				(accessTicks << TR_33_PIO_ACCESS_SHIFT) |
  				(recTicks << TR_33_PIO_RECOVERY_SHIFT);
  		if (ebit)
0b46ff2ea   Benjamin Herrenschmidt   ide-pmac: fix PIO...
549
  			t |= TR_33_PIO_E;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
550
551
552
553
554
555
556
557
558
  		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...
559
  	*timings = t;
c15d5d43e   Bartlomiej Zolnierkiewicz   ide-pmac: PIO mod...
560
  	pmac_ide_do_update_timings(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
561
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562
563
564
  /*
   * Calculate KeyLargo ATA/66 UDMA timings
   */
aacaf9bd9   Jon Loeliger   [PATCH] powerpc: ...
565
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
593
  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: ...
594
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
596
597
598
599
600
601
602
  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
603
604
605
606
607
608
609
610
611
  	*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: ...
612
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
613
614
615
616
617
618
619
620
  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
621
622
623
624
625
626
627
628
629
  	*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...
630
  static void
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
631
  set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
90f72eca3   Bartlomiej Zolnierkiewicz   ide-pmac: fix set...
632
  		 	u8 speed)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
  {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
634
  	u16 *id = drive->id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
635
636
637
638
639
640
641
642
643
644
645
  	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...
646
647
  			BUG();
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
648
  	}
90f72eca3   Bartlomiej Zolnierkiewicz   ide-pmac: fix set...
649
650
  
  	/* Check if drive provides explicit DMA cycle time */
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
651
652
  	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...
653

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
680
  	/* 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
681
682
683
684
685
686
687
688
689
690
691
692
693
694
  		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
695
696
697
698
699
700
701
  		*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
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
763
  		*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
764
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
765

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
775
776
  	timings = &pmif->timings[unit];
  	timings2 = &pmif->timings[unit+2];
085798b12   Bartlomiej Zolnierkiewicz   ide-pmac: pmac_id...
777
778
779
780
  
  	/* Copy timings to local image */
  	tl[0] = *timings;
  	tl[1] = *timings2;
4db90a145   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
781
782
783
784
785
786
787
788
789
790
791
792
  	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...
793

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
794
  	if (ret)
88b2b32ba   Bartlomiej Zolnierkiewicz   ide: move ide_con...
795
  		return;
085798b12   Bartlomiej Zolnierkiewicz   ide-pmac: pmac_id...
796
797
798
799
  
  	/* Apply timings to controller */
  	*timings = tl[0];
  	*timings2 = tl[1];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
800
  	pmac_ide_do_update_timings(drive);	
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
801
802
803
804
805
806
  }
  
  /*
   * 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: ...
807
  static void
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
836
  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...
837
838
839
840
  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
841
842
843
  /* Suspend call back, should be called after the child devices
   * have actually been suspended
   */
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
844
  static int pmac_ide_do_suspend(pmac_ide_hwif_t *pmif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
846
847
848
849
  	/* We clear the timings */
  	pmif->timings[0] = 0;
  	pmif->timings[1] = 0;
  	
616299afc   Benjamin Herrenschmidt   [PATCH] ppc32: Fi...
850
  	disable_irq(pmif->irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
851
  	/* The media bay will handle itself just fine */
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
852
  	if (on_media_bay(pmif))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
  		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...
872
  static int pmac_ide_do_resume(pmac_ide_hwif_t *pmif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
873
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
874
  	/* Hard reset & re-enable controller (do we really need to reset ? -BenH) */
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
875
  	if (!on_media_bay(pmif)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
876
877
878
879
  		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
880
881
882
883
884
885
886
  
  		/* 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...
887
888
  
  		msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
889
890
891
892
  	}
  
  	/* Sanitize drive timings */
  	sanitize_timings(pmif);
616299afc   Benjamin Herrenschmidt   [PATCH] ppc32: Fi...
893
  	enable_irq(pmif->irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
894
895
  	return 0;
  }
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
896
897
  static u8 pmac_ide_cable_detect(ide_hwif_t *hwif)
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
898
899
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
900
901
  	struct device_node *np = pmif->node;
  	const char *cable = of_get_property(np, "cable-type", NULL);
a9d5a97fa   TOMARI Hisanobu   ide-pmac: IDE cab...
902
903
  	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...
904
905
  
  	/* Get cable type from device-tree. */
a9d5a97fa   TOMARI Hisanobu   ide-pmac: IDE cab...
906
907
908
909
910
911
912
913
  	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...
914
915
916
917
918
919
920
921
922
923
924
925
  
  	/*
  	 * 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...
926
927
928
929
930
  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...
931
932
  	if (on_media_bay(pmif)) {
  		if (check_media_bay(pmif->mdev->media_bay) == MB_CD) {
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
933
  			drive->dev_flags &= ~IDE_DFLAG_NOPROBE;
07eb106f3   Bartlomiej Zolnierkiewicz   ide-pmac: add ->i...
934
935
  			return;
  		}
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
936
  		drive->dev_flags |= IDE_DFLAG_NOPROBE;
07eb106f3   Bartlomiej Zolnierkiewicz   ide-pmac: add ->i...
937
938
  	}
  }
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
939
940
941
942
  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...
943
  	.write_devctl		= pmac_write_devctl,
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
944

abb596b25   Sergei Shtylyov   ide: turn selectp...
945
  	.dev_select		= pmac_dev_select,
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
946
947
948
949
950
951
  	.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...
952
953
954
955
956
957
958
959
960
961
962
963
  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...
964
965
966
  };
  
  static const struct ide_port_ops pmac_ide_ata4_port_ops = {
07eb106f3   Bartlomiej Zolnierkiewicz   ide-pmac: add ->i...
967
  	.init_dev		= pmac_ide_init_dev,
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
968
969
  	.set_pio_mode		= pmac_ide_set_pio_mode,
  	.set_dma_mode		= pmac_ide_set_dma_mode,
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
970
  	.cable_detect		= pmac_ide_cable_detect,
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
971
972
973
  };
  
  static const struct ide_port_ops pmac_ide_port_ops = {
07eb106f3   Bartlomiej Zolnierkiewicz   ide-pmac: add ->i...
974
  	.init_dev		= pmac_ide_init_dev,
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
975
976
  	.set_pio_mode		= pmac_ide_set_pio_mode,
  	.set_dma_mode		= pmac_ide_set_dma_mode,
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
977
  };
f37afdaca   Bartlomiej Zolnierkiewicz   ide: constify str...
978
  static const struct ide_dma_ops pmac_dma_ops;
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
979

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1009
  	pmif->broken_dma = pmif->broken_dma_warn = 0;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1010
  	if (of_device_is_compatible(np, "shasta-ata")) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1011
  		pmif->kind = controller_sh_ata6;
abb596b25   Sergei Shtylyov   ide: turn selectp...
1012
1013
  		d.tp_ops = &pmac_ata6_tp_ops;
  		d.port_ops = &pmac_ide_ata4_port_ops;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1014
1015
  		d.udma_mask = ATA_UDMA6;
  	} else if (of_device_is_compatible(np, "kauai-ata")) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1016
  		pmif->kind = controller_un_ata6;
abb596b25   Sergei Shtylyov   ide: turn selectp...
1017
1018
  		d.tp_ops = &pmac_ata6_tp_ops;
  		d.port_ops = &pmac_ide_ata4_port_ops;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1019
1020
  		d.udma_mask = ATA_UDMA5;
  	} else if (of_device_is_compatible(np, "K2-UATA")) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1021
  		pmif->kind = controller_k2_ata6;
abb596b25   Sergei Shtylyov   ide: turn selectp...
1022
1023
  		d.tp_ops = &pmac_ata6_tp_ops;
  		d.port_ops = &pmac_ide_ata4_port_ops;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1024
1025
1026
  		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
1027
  			pmif->kind = controller_kl_ata4;
07a6c66da   Bartlomiej Zolnierkiewicz   ide-pmac: add ->c...
1028
  			d.port_ops = &pmac_ide_ata4_port_ops;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1029
1030
  			d.udma_mask = ATA_UDMA4;
  		} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1031
  			pmif->kind = controller_kl_ata3;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1032
  	} else if (of_device_is_compatible(np, "heathrow-ata")) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
  		pmif->kind = controller_heathrow;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1034
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1035
1036
1037
  		pmif->kind = controller_ohare;
  		pmif->broken_dma = 1;
  	}
40cd3a456   Stephen Rothwell   [POWERPC] Rename ...
1038
  	bidp = of_get_property(np, "AAPL,bus-id", NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1039
  	pmif->aapl_bus_id =  bidp ? *bidp : 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1040
1041
1042
1043
1044
  	/* 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
1045
1046
1047
  	
  	/* Make sure we have sane timings */
  	sanitize_timings(pmif);
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1048
1049
1050
  	/* 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 ...
1051
  	host = ide_host_alloc(&d, hws, 1);
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1052
1053
1054
1055
1056
  	if (host == NULL) {
  		rc = -ENOMEM;
  		goto bail;
  	}
  	hwif = pmif->hwif = host->ports[0];
9842727da   Benjamin Herrenschmidt   ide/powermac: Fix...
1057

d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1058
1059
  	if (on_media_bay(pmif)) {
  		/* Fixup bus ID for media bay */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1060
1061
1062
1063
1064
1065
1066
1067
  		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...
1068
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1069
1070
1071
1072
1073
1074
1075
   		/* 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...
1076
  	printk(KERN_INFO DRV_NAME ": Found Apple %s controller (%s), "
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1077
1078
1079
1080
  	       "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...
1081

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

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

5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1115
1116
1117
  	pmif = kzalloc(sizeof(*pmif), GFP_KERNEL);
  	if (pmif == NULL)
  		return -ENOMEM;
cc5d0189b   Benjamin Herrenschmidt   [PATCH] powerpc: ...
1118
  	if (macio_resource_count(mdev) == 0) {
939b0f1d3   Bartlomiej Zolnierkiewicz   ide-pmac: use ide...
1119
1120
  		printk(KERN_WARNING "ide-pmac: no address for %s
  ",
61c7a080a   Grant Likely   of: Always use 's...
1121
  				    mdev->ofdev.dev.of_node->full_name);
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1122
1123
  		rc = -ENXIO;
  		goto out_free_pmif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1124
1125
1126
1127
  	}
  
  	/* Request memory resource for IO ports */
  	if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) {
939b0f1d3   Bartlomiej Zolnierkiewicz   ide-pmac: use ide...
1128
  		printk(KERN_ERR "ide-pmac: can't request MMIO resource for "
61c7a080a   Grant Likely   of: Always use 's...
1129
1130
  				"%s!
  ", mdev->ofdev.dev.of_node->full_name);
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1131
1132
  		rc = -EBUSY;
  		goto out_free_pmif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1133
1134
1135
1136
1137
1138
1139
1140
  	}
  			
  	/* 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...
1141
  		printk(KERN_WARNING "ide-pmac: no intrs for device %s, using "
61c7a080a   Grant Likely   of: Always use 's...
1142
1143
  				    "13
  ", mdev->ofdev.dev.of_node->full_name);
69917c26c   Benjamin Herrenschmidt   [POWERPC] Fix oha...
1144
  		irq = irq_create_mapping(NULL, 13);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1145
1146
1147
1148
1149
  	} 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
1150
  	pmif->mdev = mdev;
61c7a080a   Grant Likely   of: Always use 's...
1151
  	pmif->node = mdev->ofdev.dev.of_node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1152
1153
1154
  	pmif->regbase = regbase;
  	pmif->irq = irq;
  	pmif->kauai_fcr = NULL;
538465747   Bartlomiej Zolnierkiewicz   ide: build-fix fo...
1155

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

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

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

b36ba5321   Bartlomiej Zolnierkiewicz   ide-pmac: move id...
1175
  	rc = pmac_ide_setup_device(pmif, &hw);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1176
1177
1178
1179
  	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...
1180
  		if (pmif->dma_regs) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1181
  			iounmap(pmif->dma_regs);
ed908fa1d   Bartlomiej Zolnierkiewicz   ide-pmac: macio r...
1182
1183
  			macio_release_resource(mdev, 1);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1184
  		macio_release_resource(mdev, 0);
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1185
  		kfree(pmif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1186
1187
1188
  	}
  
  	return rc;
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1189
1190
1191
1192
  
  out_free_pmif:
  	kfree(pmif);
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1193
1194
1195
  }
  
  static int
8b4b8a24e   David Brownell   fix broken/dubiou...
1196
  pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t mesg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1197
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1198
1199
1200
  	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
1201

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

57c802e84   Bartlomiej Zolnierkiewicz   ide: add ide_init...
1279
  	memset(&hw, 0, sizeof(hw));
5c58666fa   Bartlomiej Zolnierkiewicz   ppc/pmac: remove ...
1280
  	pmac_ide_init_ports(&hw, pmif->regbase);
57c802e84   Bartlomiej Zolnierkiewicz   ide: add ide_init...
1281
1282
  	hw.irq = pdev->irq;
  	hw.dev = &pdev->dev;
b36ba5321   Bartlomiej Zolnierkiewicz   ide-pmac: move id...
1283
  	rc = pmac_ide_setup_device(pmif, &hw);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1284
1285
1286
1287
  	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
1288
  		pci_release_regions(pdev);
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1289
  		kfree(pmif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1290
1291
1292
  	}
  
  	return rc;
5297a3e52   Bartlomiej Zolnierkiewicz   ide-pmac: dynamic...
1293
1294
1295
1296
  
  out_free_pmif:
  	kfree(pmif);
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1297
1298
1299
  }
  
  static int
8b4b8a24e   David Brownell   fix broken/dubiou...
1300
  pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1301
  {
f2ba70a22   Joe Perches   drivers/ide/pmac....
1302
  	pmac_ide_hwif_t *pmif = pci_get_drvdata(pdev);
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1303
  	int rc = 0;
8b4b8a24e   David Brownell   fix broken/dubiou...
1304
  	if (mesg.event != pdev->dev.power.power_state.event
3a2d5b700   Rafael J. Wysocki   PM: Introduce PM_...
1305
  			&& (mesg.event & PM_EVENT_SLEEP)) {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1306
  		rc = pmac_ide_do_suspend(pmif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1307
  		if (rc == 0)
8b4b8a24e   David Brownell   fix broken/dubiou...
1308
  			pdev->dev.power.power_state = mesg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1309
1310
1311
1312
1313
1314
1315
1316
  	}
  
  	return rc;
  }
  
  static int
  pmac_ide_pci_resume(struct pci_dev *pdev)
  {
f2ba70a22   Joe Perches   drivers/ide/pmac....
1317
  	pmac_ide_hwif_t *pmif = pci_get_drvdata(pdev);
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1318
  	int rc = 0;
ca078bae8   Pavel Machek   [PATCH] swsusp: s...
1319
  	if (pdev->dev.power.power_state.event != PM_EVENT_ON) {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1320
  		rc = pmac_ide_do_resume(pmif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1321
  		if (rc == 0)
829ca9a30   Pavel Machek   [PATCH] swsusp: f...
1322
  			pdev->dev.power.power_state = PMSG_ON;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1323
1324
1325
1326
  	}
  
  	return rc;
  }
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
  #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...
1344
  static struct of_device_id pmac_ide_macio_match[] = 
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1345
1346
1347
  {
  	{
  	.name 		= "IDE",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1348
1349
1350
  	},
  	{
  	.name 		= "ATA",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1351
1352
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353
  	.type		= "ide",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1354
1355
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1356
  	.type		= "ata",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1357
1358
1359
1360
1361
1362
  	},
  	{},
  };
  
  static struct macio_driver pmac_ide_macio_driver = 
  {
c2cdf6aba   Benjamin Herrenschmidt   powerpc/macio: Fi...
1363
1364
1365
1366
1367
  	.driver = {
  		.name 		= "ide-pmac",
  		.owner		= THIS_MODULE,
  		.of_match_table	= pmac_ide_macio_match,
  	},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1368
1369
1370
  	.probe		= pmac_ide_macio_attach,
  	.suspend	= pmac_ide_macio_suspend,
  	.resume		= pmac_ide_macio_resume,
d58b0c39e   Benjamin Herrenschmidt   powerpc/macio: Re...
1371
1372
1373
  #ifdef CONFIG_PMAC_MEDIABAY
  	.mediabay_event	= pmac_ide_macio_mb_event,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1374
  };
9cbcc5e3c   Bartlomiej Zolnierkiewicz   ide: use PCI_VDEV...
1375
1376
1377
1378
1379
1380
  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...
1381
  	{},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
  };
  
  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...
1392
  int __init pmac_ide_probe(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1393
  {
9e5755bce   Andrew Morton   ide: fix pmac bre...
1394
  	int error;
e8222502e   Benjamin Herrenschmidt   [PATCH] powerpc: ...
1395
  	if (!machine_is(powermac))
9e5755bce   Andrew Morton   ide: fix pmac bre...
1396
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1397
1398
  
  #ifdef CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST
9e5755bce   Andrew Morton   ide: fix pmac bre...
1399
1400
1401
1402
1403
1404
1405
1406
  	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
1407
  #else
9e5755bce   Andrew Morton   ide: fix pmac bre...
1408
1409
1410
1411
1412
1413
1414
1415
  	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: ...
1416
  #endif
9e5755bce   Andrew Morton   ide: fix pmac bre...
1417
1418
  out:
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1419
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1420
1421
1422
1423
  /*
   * 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...
1424
  static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1425
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1426
1427
1428
  	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
1429
  	struct dbdma_cmd *table;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1430
1431
  	volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
  	struct scatterlist *sg;
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
1432
1433
  	int wr = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
  	int i = cmd->sg_nents, count = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1434
1435
1436
1437
1438
1439
1440
1441
  
  	/* 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
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
  	/* 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 ...
1453
  				printk(KERN_WARNING "%s: DMA on non aligned address, "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1454
1455
1456
1457
  				       "switching to PIO on Ohare chipset
  ", drive->name);
  				pmif->broken_dma_warn = 1;
  			}
11998b316   Bartlomiej Zolnierkiewicz   ide: move ide_map...
1458
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1459
1460
1461
1462
1463
1464
1465
1466
  		}
  		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...
1467
  				return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
  			}
  			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 ...
1479
  		sg = sg_next(sg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
  		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...
1496

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1497
1498
  	return 0; /* revert to PIO for this request */
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1499
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1500
1501
1502
   * 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...
1503
  static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1504
  {
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
1505
  	ide_hwif_t *hwif = drive->hwif;
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1506
1507
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
9055ba3ee   Bartlomiej Zolnierkiewicz   pmac: remove supe...
1508
  	u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
1509
  	u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1510

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
  	/* 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: ...
1569
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1570
1571
  pmac_ide_dma_test_irq (ide_drive_t *drive)
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1572
1573
1574
  	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...
1575
  	volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1576
  	unsigned long status, timeout;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
  	/* 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
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
  
  	/* 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 ...
1611
1612
1613
  			printk(KERN_WARNING "ide%d, ide_dma_test_irq timeout flushing channel
  ",
  			       hwif->index);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1614
1615
1616
1617
1618
  			break;
  		}
  	}	
  	return 1;
  }
15ce926ad   Bartlomiej Zolnierkiewicz   ide: merge ->dma_...
1619
  static void pmac_ide_dma_host_set(ide_drive_t *drive, int on)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1620
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1621
  }
841d2a9bf   Sergei Shtylyov   ide: make void an...
1622
1623
  static void
  pmac_ide_dma_lost_irq (ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1624
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1625
1626
1627
  	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...
1628
1629
  	volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
  	unsigned long status = readl(&dma->status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1630

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1631
1632
  	printk(KERN_ERR "ide-pmac lost interrupt, dma status: %lx
  ", status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1633
  }
f37afdaca   Bartlomiej Zolnierkiewicz   ide: constify str...
1634
  static const struct ide_dma_ops pmac_dma_ops = {
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
1635
1636
  	.dma_host_set		= pmac_ide_dma_host_set,
  	.dma_setup		= pmac_ide_dma_setup,
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
1637
1638
1639
  	.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...
1640
1641
  	.dma_lost_irq		= pmac_ide_dma_lost_irq,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1642
1643
1644
1645
  /*
   * 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...
1646
1647
  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
1648
  {
7b8797acd   Bartlomiej Zolnierkiewicz   ide-pmac: store p...
1649
1650
  	pmac_ide_hwif_t *pmif =
  		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
1651
  	struct pci_dev *dev = to_pci_dev(hwif->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1652
1653
1654
  	/* We won't need pci_dev if we switch to generic consistent
  	 * DMA routines ...
  	 */
0d0719229   Bartlomiej Zolnierkiewicz   ide-pmac: use ->i...
1655
  	if (dev == NULL || pmif->dma_regs == 0)
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1656
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1657
1658
1659
1660
1661
  	/*
  	 * 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 ...
1662
  	pmif->dma_table_cpu = pci_alloc_consistent(
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
1663
  		dev,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1664
1665
1666
1667
1668
1669
  		(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...
1670
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1671
  	}
4f52a3299   Bartlomiej Zolnierkiewicz   ide-pmac: use cus...
1672
  	hwif->sg_max_nents = MAX_DCMDS;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1673
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1674
  }
ade2daf9c   Bartlomiej Zolnierkiewicz   ide: make remaini...
1675
1676
  
  module_init(pmac_ide_probe);
de9facbff   Adrian Bunk   ide/ppc/pmac.c: a...
1677
1678
  
  MODULE_LICENSE("GPL");