Blame view

drivers/ide/pdc202xx_new.c 14.5 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
  /*
   *  Promise TX2/TX4/TX2000/133 IDE driver
   *
   *  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.
   *
   *  Split from:
   *  linux/drivers/ide/pdc202xx.c	Version 0.35	Mar. 30, 2002
   *  Copyright (C) 1998-2002		Andre Hedrick <andre@linux-ide.org>
35198234a   Sergei Shtylyov   pdc202xx_new: fix...
12
   *  Copyright (C) 2005-2007		MontaVista Software, Inc.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
   *  Portions Copyright (C) 1999 Promise Technology, Inc.
   *  Author: Frank Tiernan (frankt@promise.com)
   *  Released under terms of General Public License
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
19
20
  #include <linux/module.h>
  #include <linux/types.h>
  #include <linux/kernel.h>
  #include <linux/delay.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
23
24
25
  #include <linux/pci.h>
  #include <linux/init.h>
  #include <linux/ide.h>
  
  #include <asm/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
28
29
30
  
  #ifdef CONFIG_PPC_PMAC
  #include <asm/prom.h>
  #include <asm/pci-bridge.h>
  #endif
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
31
  #define DRV_NAME "pdc202xx_new"
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
32
33
34
  #undef DEBUG
  
  #ifdef DEBUG
eb63963a5   Harvey Harrison   ide: replace rema...
35
  #define DBG(fmt, args...) printk("%s: " fmt, __func__, ## args)
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
36
37
38
  #else
  #define DBG(fmt, args...)
  #endif
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
39
  static u8 max_dma_rate(struct pci_dev *pdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
  {
  	u8 mode;
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
42
  	switch(pdev->device) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  		case PCI_DEVICE_ID_PROMISE_20277:
  		case PCI_DEVICE_ID_PROMISE_20276:
  		case PCI_DEVICE_ID_PROMISE_20275:
  		case PCI_DEVICE_ID_PROMISE_20271:
  		case PCI_DEVICE_ID_PROMISE_20269:
  			mode = 4;
  			break;
  		case PCI_DEVICE_ID_PROMISE_20270:
  		case PCI_DEVICE_ID_PROMISE_20268:
  			mode = 3;
  			break;
  		default:
  			return 0;
  	}
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
57

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
  	return mode;
  }
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
60
61
62
63
64
65
66
67
  /**
   * get_indexed_reg - Get indexed register
   * @hwif: for the port address
   * @index: index of the indexed register
   */
  static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index)
  {
  	u8 value;
41051a141   Bartlomiej Zolnierkiewicz   ide: remove ->dma...
68
69
  	outb(index, hwif->dma_base + 1);
  	value = inb(hwif->dma_base + 3);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
70
71
72
73
74
75
76
77
78
79
80
81
82
  
  	DBG("index[%02X] value[%02X]
  ", index, value);
  	return value;
  }
  
  /**
   * set_indexed_reg - Set indexed register
   * @hwif: for the port address
   * @index: index of the indexed register
   */
  static void set_indexed_reg(ide_hwif_t *hwif, u8 index, u8 value)
  {
41051a141   Bartlomiej Zolnierkiewicz   ide: remove ->dma...
83
84
  	outb(index, hwif->dma_base + 1);
  	outb(value, hwif->dma_base + 3);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
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
  	DBG("index[%02X] value[%02X]
  ", index, value);
  }
  
  /*
   * ATA Timing Tables based on 133 MHz PLL output clock.
   *
   * If the PLL outputs 100 MHz clock, the ASIC hardware will set
   * the timing registers automatically when "set features" command is
   * issued to the device. However, if the PLL output clock is 133 MHz,
   * the following tables must be used.
   */
  static struct pio_timing {
  	u8 reg0c, reg0d, reg13;
  } pio_timings [] = {
  	{ 0xfb, 0x2b, 0xac },	/* PIO mode 0, IORDY off, Prefetch off */
  	{ 0x46, 0x29, 0xa4 },	/* PIO mode 1, IORDY off, Prefetch off */
  	{ 0x23, 0x26, 0x64 },	/* PIO mode 2, IORDY off, Prefetch off */
  	{ 0x27, 0x0d, 0x35 },	/* PIO mode 3, IORDY on,  Prefetch off */
  	{ 0x23, 0x09, 0x25 },	/* PIO mode 4, IORDY on,  Prefetch off */
  };
  
  static struct mwdma_timing {
  	u8 reg0e, reg0f;
  } mwdma_timings [] = {
  	{ 0xdf, 0x5f }, 	/* MWDMA mode 0 */
  	{ 0x6b, 0x27 }, 	/* MWDMA mode 1 */
  	{ 0x69, 0x25 }, 	/* MWDMA mode 2 */
  };
  
  static struct udma_timing {
  	u8 reg10, reg11, reg12;
  } udma_timings [] = {
  	{ 0x4a, 0x0f, 0xd5 },	/* UDMA mode 0 */
  	{ 0x3a, 0x0a, 0xd0 },	/* UDMA mode 1 */
  	{ 0x2a, 0x07, 0xcd },	/* UDMA mode 2 */
  	{ 0x1a, 0x05, 0xcd },	/* UDMA mode 3 */
  	{ 0x1a, 0x03, 0xcd },	/* UDMA mode 4 */
  	{ 0x1a, 0x02, 0xcb },	/* UDMA mode 5 */
  	{ 0x1a, 0x01, 0xcb },	/* UDMA mode 6 */
  };
8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
126
  static void pdcnew_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
  {
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
128
  	struct pci_dev *dev	= to_pci_dev(hwif->dev);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
129
  	u8 adj			= (drive->dn & 1) ? 0x08 : 0x00;
8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
130
  	const u8 speed		= drive->dma_mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131

47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
132
  	/*
88b2b32ba   Bartlomiej Zolnierkiewicz   ide: move ide_con...
133
134
  	 * IDE core issues SETFEATURES_XFER to the drive first (thanks to
  	 * IDE_HFLAG_POST_SET_MODE in ->host_flags).  PDC202xx hardware will
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
135
  	 * automatically set the timing registers based on 100 MHz PLL output.
88b2b32ba   Bartlomiej Zolnierkiewicz   ide: move ide_con...
136
  	 *
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
137
138
139
  	 * As we set up the PLL to output 133 MHz for UltraDMA/133 capable
  	 * chips, we must override the default register settings...
  	 */
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
140
  	if (max_dma_rate(dev) == 4) {
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
141
  		u8 mode = speed & 0x07;
4db90a145   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
142
143
144
145
146
147
148
149
150
151
152
153
  		if (speed >= XFER_UDMA_0) {
  			set_indexed_reg(hwif, 0x10 + adj,
  					udma_timings[mode].reg10);
  			set_indexed_reg(hwif, 0x11 + adj,
  					udma_timings[mode].reg11);
  			set_indexed_reg(hwif, 0x12 + adj,
  					udma_timings[mode].reg12);
  		} else {
  			set_indexed_reg(hwif, 0x0e + adj,
  					mwdma_timings[mode].reg0e);
  			set_indexed_reg(hwif, 0x0f + adj,
  					mwdma_timings[mode].reg0f);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
154
155
156
157
158
159
160
  		}
  	} else if (speed == XFER_UDMA_2) {
  		/* Set tHOLD bit to 0 if using UDMA mode 2 */
  		u8 tmp = get_indexed_reg(hwif, 0x10 + adj);
  
  		set_indexed_reg(hwif, 0x10 + adj, tmp & 0x7f);
   	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
  }
e085b3cae   Bartlomiej Zolnierkiewicz   ide: change ->set...
162
  static void pdcnew_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
  {
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
164
  	struct pci_dev *dev = to_pci_dev(hwif->dev);
ad4ba7dce   Bartlomiej Zolnierkiewicz   pdc202xx_new: mov...
165
  	u8 adj = (drive->dn & 1) ? 0x08 : 0x00;
e085b3cae   Bartlomiej Zolnierkiewicz   ide: change ->set...
166
  	const u8 pio = drive->pio_mode - XFER_PIO_0;
ad4ba7dce   Bartlomiej Zolnierkiewicz   pdc202xx_new: mov...
167

36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
168
  	if (max_dma_rate(dev) == 4) {
ad4ba7dce   Bartlomiej Zolnierkiewicz   pdc202xx_new: mov...
169
170
171
172
  		set_indexed_reg(hwif, 0x0c + adj, pio_timings[pio].reg0c);
  		set_indexed_reg(hwif, 0x0d + adj, pio_timings[pio].reg0d);
  		set_indexed_reg(hwif, 0x13 + adj, pio_timings[pio].reg13);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
  }
f454cbe8c   Bartlomiej Zolnierkiewicz   ide: ->cable_dete...
174
  static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175
  {
49521f97c   Bartlomiej Zolnierkiewicz   ide: add short ca...
176
177
178
179
  	if (get_indexed_reg(hwif, 0x0b) & 0x04)
  		return ATA_CBL_PATA40;
  	else
  		return ATA_CBL_PATA80;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180
  }
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
181

47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
182
  static void pdcnew_reset(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
184
185
186
  {
  	/*
  	 * Deleted this because it is redundant from the caller.
  	 */
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
187
188
  	printk(KERN_WARNING "pdc202xx_new: %s channel reset.
  ",
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
189
  		drive->hwif->channel ? "Secondary" : "Primary");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
  }
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
191
192
193
194
  /**
   * read_counter - Read the byte count registers
   * @dma_base: for the port address
   */
feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
195
  static long read_counter(u32 dma_base)
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
  {
  	u32  pri_dma_base = dma_base, sec_dma_base = dma_base + 0x08;
  	u8   cnt0, cnt1, cnt2, cnt3;
  	long count = 0, last;
  	int  retry = 3;
  
  	do {
  		last = count;
  
  		/* Read the current count */
  		outb(0x20, pri_dma_base + 0x01);
  		cnt0 = inb(pri_dma_base + 0x03);
  		outb(0x21, pri_dma_base + 0x01);
  		cnt1 = inb(pri_dma_base + 0x03);
  		outb(0x20, sec_dma_base + 0x01);
  		cnt2 = inb(sec_dma_base + 0x03);
  		outb(0x21, sec_dma_base + 0x01);
  		cnt3 = inb(sec_dma_base + 0x03);
  
  		count = (cnt3 << 23) | (cnt2 << 15) | (cnt1 << 8) | cnt0;
  
  		/*
  		 * The 30-bit decrementing counter is read in 4 pieces.
  		 * Incorrect value may be read when the most significant bytes
  		 * are changing...
  		 */
  	} while (retry-- && (((last ^ count) & 0x3fff8000) || last < count));
  
  	DBG("cnt0[%02X] cnt1[%02X] cnt2[%02X] cnt3[%02X]
  ",
  		  cnt0, cnt1, cnt2, cnt3);
  
  	return count;
  }
  
  /**
   * detect_pll_input_clock - Detect the PLL input clock in Hz.
   * @dma_base: for the port address
   * E.g. 16949000 on 33 MHz PCI bus, i.e. half of the PCI clock.
   */
feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
236
  static long detect_pll_input_clock(unsigned long dma_base)
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
237
  {
8006bf56e   Albert Lee   ide: pdc202xx_new...
238
  	struct timeval start_time, end_time;
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
239
  	long start_count, end_count;
8006bf56e   Albert Lee   ide: pdc202xx_new...
240
  	long pll_input, usec_elapsed;
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
241
242
243
  	u8 scr1;
  
  	start_count = read_counter(dma_base);
8006bf56e   Albert Lee   ide: pdc202xx_new...
244
  	do_gettimeofday(&start_time);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
245
246
247
248
249
250
251
252
253
254
255
256
  
  	/* Start the test mode */
  	outb(0x01, dma_base + 0x01);
  	scr1 = inb(dma_base + 0x03);
  	DBG("scr1[%02X]
  ", scr1);
  	outb(scr1 | 0x40, dma_base + 0x03);
  
  	/* Let the counter run for 10 ms. */
  	mdelay(10);
  
  	end_count = read_counter(dma_base);
8006bf56e   Albert Lee   ide: pdc202xx_new...
257
  	do_gettimeofday(&end_time);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
258
259
260
261
262
263
264
265
266
267
268
269
  
  	/* Stop the test mode */
  	outb(0x01, dma_base + 0x01);
  	scr1 = inb(dma_base + 0x03);
  	DBG("scr1[%02X]
  ", scr1);
  	outb(scr1 & ~0x40, dma_base + 0x03);
  
  	/*
  	 * Calculate the input clock in Hz
  	 * (the clock counter is 30 bit wide and counts down)
  	 */
8006bf56e   Albert Lee   ide: pdc202xx_new...
270
271
  	usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 +
  		(end_time.tv_usec - start_time.tv_usec);
56fe23d5a   Mikael Pettersson   pdc202xx_new: PLL...
272
  	pll_input = ((start_count - end_count) & 0x3fffffff) / 10 *
8006bf56e   Albert Lee   ide: pdc202xx_new...
273
  		(10000000 / usec_elapsed);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
274
275
276
277
278
279
  
  	DBG("start[%ld] end[%ld]
  ", start_count, end_count);
  
  	return pll_input;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
  #ifdef CONFIG_PPC_PMAC
feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
281
  static void apple_kiwi_init(struct pci_dev *pdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
  {
  	struct device_node *np = pci_device_to_OF_node(pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
  	u8 conf;
55b61fec2   Stephen Rothwell   [POWERPC] Rename ...
285
  	if (np == NULL || !of_device_is_compatible(np, "kiwi-root"))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286
  		return;
fc212bb1f   Bartlomiej Zolnierkiewicz   ide: use pci_dev-...
287
  	if (pdev->revision >= 0x03) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
  		/* Setup chip magic config stuff (from darwin) */
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
289
290
  		pci_read_config_byte (pdev, 0x40, &conf);
  		pci_write_config_byte(pdev, 0x40, (conf | 0x01));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
293
  }
  #endif /* CONFIG_PPC_PMAC */
2ed0ef543   Bartlomiej Zolnierkiewicz   ide: fix ->init_c...
294
  static int init_chipset_pdcnew(struct pci_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
  {
a326b02b0   Bartlomiej Zolnierkiewicz   ide: drop 'name' ...
296
  	const char *name = DRV_NAME;
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
297
298
299
300
301
  	unsigned long dma_base = pci_resource_start(dev, 4);
  	unsigned long sec_dma_base = dma_base + 0x08;
  	long pll_input, pll_output, ratio;
  	int f, r;
  	u8 pll_ctl0, pll_ctl1;
01cc643ae   Bartlomiej Zolnierkiewicz   pdc202xx_new: add...
302
303
  	if (dma_base == 0)
  		return -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
306
  #ifdef CONFIG_PPC_PMAC
  	apple_kiwi_init(dev);
  #endif
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
  	/* Calculate the required PLL output frequency */
  	switch(max_dma_rate(dev)) {
  		case 4: /* it's 133 MHz for Ultra133 chips */
  			pll_output = 133333333;
  			break;
  		case 3: /* and  100 MHz for Ultra100 chips */
  		default:
  			pll_output = 100000000;
  			break;
  	}
  
  	/*
  	 * Detect PLL input clock.
  	 * On some systems, where PCI bus is running at non-standard clock rate
  	 * (e.g. 25 or 40 MHz), we have to adjust the cycle time.
  	 * PDC20268 and newer chips employ PLL circuit to help correct timing
  	 * registers setting.
  	 */
  	pll_input = detect_pll_input_clock(dma_base);
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
326
327
328
  	printk(KERN_INFO "%s %s: PLL input clock is %ld kHz
  ",
  		name, pci_name(dev), pll_input / 1000);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
329
330
331
  
  	/* Sanity check */
  	if (unlikely(pll_input < 5000000L || pll_input > 70000000L)) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
332
333
334
  		printk(KERN_ERR "%s %s: Bad PLL input clock %ld Hz, giving up!"
  			"
  ", name, pci_name(dev), pll_input);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  		goto out;
  	}
  
  #ifdef DEBUG
  	DBG("pll_output is %ld Hz
  ", pll_output);
  
  	/* Show the current clock value of PLL control register
  	 * (maybe already configured by the BIOS)
  	 */
  	outb(0x02, sec_dma_base + 0x01);
  	pll_ctl0 = inb(sec_dma_base + 0x03);
  	outb(0x03, sec_dma_base + 0x01);
  	pll_ctl1 = inb(sec_dma_base + 0x03);
  
  	DBG("pll_ctl[%02X][%02X]
  ", pll_ctl0, pll_ctl1);
  #endif
  
  	/*
  	 * Calculate the ratio of F, R and NO
  	 * POUT = (F + 2) / (( R + 2) * NO)
  	 */
  	ratio = pll_output / (pll_input / 1000);
  	if (ratio < 8600L) { /* 8.6x */
  		/* Using NO = 0x01, R = 0x0d */
  		r = 0x0d;
  	} else if (ratio < 12900L) { /* 12.9x */
  		/* Using NO = 0x01, R = 0x08 */
  		r = 0x08;
  	} else if (ratio < 16100L) { /* 16.1x */
  		/* Using NO = 0x01, R = 0x06 */
  		r = 0x06;
  	} else if (ratio < 64000L) { /* 64x */
  		r = 0x00;
  	} else {
  		/* Invalid ratio */
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
372
373
374
  		printk(KERN_ERR "%s %s: Bad ratio %ld, giving up!
  ",
  			name, pci_name(dev), ratio);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
375
376
377
378
379
380
381
382
383
384
  		goto out;
  	}
  
  	f = (ratio * (r + 2)) / 1000 - 2;
  
  	DBG("F[%d] R[%d] ratio*1000[%ld]
  ", f, r, ratio);
  
  	if (unlikely(f < 0 || f > 127)) {
  		/* Invalid F */
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
385
386
387
  		printk(KERN_ERR "%s %s: F[%d] invalid!
  ",
  			name, pci_name(dev), f);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
  		goto out;
  	}
  
  	pll_ctl0 = (u8) f;
  	pll_ctl1 = (u8) r;
  
  	DBG("Writing pll_ctl[%02X][%02X]
  ", pll_ctl0, pll_ctl1);
  
  	outb(0x02,     sec_dma_base + 0x01);
  	outb(pll_ctl0, sec_dma_base + 0x03);
  	outb(0x03,     sec_dma_base + 0x01);
  	outb(pll_ctl1, sec_dma_base + 0x03);
  
  	/* Wait the PLL circuit to be stable */
  	mdelay(30);
  
  #ifdef DEBUG
  	/*
  	 *  Show the current clock value of PLL control register
  	 */
  	outb(0x02, sec_dma_base + 0x01);
  	pll_ctl0 = inb(sec_dma_base + 0x03);
  	outb(0x03, sec_dma_base + 0x01);
  	pll_ctl1 = inb(sec_dma_base + 0x03);
  
  	DBG("pll_ctl[%02X][%02X]
  ", pll_ctl0, pll_ctl1);
  #endif
  
   out:
2ed0ef543   Bartlomiej Zolnierkiewicz   ide: fix ->init_c...
419
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
  }
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
421
  static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
422
  {
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
423
  	struct pci_dev *dev2;
eadb6ecf7   Bartlomiej Zolnierkiewicz   pdc202xx_new: fix...
424
  	dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 1,
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
425
  						PCI_FUNC(dev->devfn)));
eadb6ecf7   Bartlomiej Zolnierkiewicz   pdc202xx_new: fix...
426

099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
427
428
429
430
431
432
  	if (dev2 &&
  	    dev2->vendor == dev->vendor &&
  	    dev2->device == dev->device) {
  
  		if (dev2->irq != dev->irq) {
  			dev2->irq = dev->irq;
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
433
  			printk(KERN_INFO DRV_NAME " %s: PCI config space "
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
434
435
  				"interrupt fixed
  ", pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
  		}
070479357   Sergei Shtylyov   pdc202xx_new: swi...
437

099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
438
  		return dev2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439
  	}
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
440
441
  
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
  }
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
443
444
445
  static const struct ide_port_ops pdcnew_port_ops = {
  	.set_pio_mode		= pdcnew_set_pio_mode,
  	.set_dma_mode		= pdcnew_set_dma_mode,
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
446
447
448
  	.resetproc		= pdcnew_reset,
  	.cable_detect		= pdcnew_cable_detect,
  };
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
449
  #define DECLARE_PDCNEW_DEV(udma) \
05d7e6cbc   Bartlomiej Zolnierkiewicz   pdc202xx_new: add...
450
  	{ \
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
451
  		.name		= DRV_NAME, \
05d7e6cbc   Bartlomiej Zolnierkiewicz   pdc202xx_new: add...
452
  		.init_chipset	= init_chipset_pdcnew, \
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
453
  		.port_ops	= &pdcnew_port_ops, \
05d7e6cbc   Bartlomiej Zolnierkiewicz   pdc202xx_new: add...
454
  		.host_flags	= IDE_HFLAG_POST_SET_MODE | \
ed67b9238   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
455
  				  IDE_HFLAG_ERROR_STOPS_FIFO | \
05d7e6cbc   Bartlomiej Zolnierkiewicz   pdc202xx_new: add...
456
457
458
459
  				  IDE_HFLAG_OFF_BOARD, \
  		.pio_mask	= ATA_PIO4, \
  		.mwdma_mask	= ATA_MWDMA2, \
  		.udma_mask	= udma, \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
  	}
05d7e6cbc   Bartlomiej Zolnierkiewicz   pdc202xx_new: add...
461

856204360   Bartlomiej Zolnierkiewicz   ide: constify str...
462
  static const struct ide_port_info pdcnew_chipsets[] __devinitdata = {
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
463
464
  	/* 0: PDC202{68,70} */		DECLARE_PDCNEW_DEV(ATA_UDMA5),
  	/* 1: PDC202{69,71,75,76,77} */	DECLARE_PDCNEW_DEV(ATA_UDMA6),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
466
467
468
469
470
471
472
473
474
475
476
477
  };
  
  /**
   *	pdc202new_init_one	-	called when a pdc202xx is found
   *	@dev: the pdc202new device
   *	@id: the matching pci id
   *
   *	Called when the PCI registration layer (or the IDE initialization)
   *	finds a device matching our IDE device tables.
   */
   
  static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
  {
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
478
  	const struct ide_port_info *d = &pdcnew_chipsets[id->driver_data];
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
479
  	struct pci_dev *bridge = dev->bus->self;
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
480

ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
481
  	if (dev->device == PCI_DEVICE_ID_PROMISE_20270 && bridge &&
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
482
483
484
485
486
487
  	    bridge->vendor == PCI_VENDOR_ID_DEC &&
  	    bridge->device == PCI_DEVICE_ID_DEC_21150) {
  		struct pci_dev *dev2;
  
  		if (PCI_SLOT(dev->devfn) & 2)
  			return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
488

099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
489
490
491
  		dev2 = pdc20270_get_dev2(dev);
  
  		if (dev2) {
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
492
  			int ret = ide_pci_init_two(dev, dev2, d, NULL);
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
493
494
495
496
497
  			if (ret < 0)
  				pci_dev_put(dev2);
  			return ret;
  		}
  	}
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
498
  	if (dev->device == PCI_DEVICE_ID_PROMISE_20276 && bridge &&
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
499
500
501
  	    bridge->vendor == PCI_VENDOR_ID_INTEL &&
  	    (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
  	     bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
502
  		printk(KERN_INFO DRV_NAME " %s: attached to I2O RAID controller,"
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
503
504
  			" skipping
  ", pci_name(dev));
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
505
506
  		return -ENODEV;
  	}
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
507
  	return ide_pci_init_one(dev, d, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
508
  }
d69c8f8c0   Bartlomiej Zolnierkiewicz   pdc202xx_new: add...
509
510
511
512
513
514
515
516
  static void __devexit pdc202new_remove(struct pci_dev *dev)
  {
  	struct ide_host *host = pci_get_drvdata(dev);
  	struct pci_dev *dev2 = host->dev[1] ? to_pci_dev(host->dev[1]) : NULL;
  
  	ide_pci_remove(dev);
  	pci_dev_put(dev2);
  }
9cbcc5e3c   Bartlomiej Zolnierkiewicz   ide: use PCI_VDEV...
517
518
519
  static const struct pci_device_id pdc202new_pci_tbl[] = {
  	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20268), 0 },
  	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20269), 1 },
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
520
521
522
523
524
  	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20270), 0 },
  	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20271), 1 },
  	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20275), 1 },
  	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20276), 1 },
  	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20277), 1 },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
525
526
527
  	{ 0, },
  };
  MODULE_DEVICE_TABLE(pci, pdc202new_pci_tbl);
a9ab09e26   Bartlomiej Zolnierkiewicz   ide: use unique n...
528
  static struct pci_driver pdc202new_pci_driver = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
529
530
531
  	.name		= "Promise_IDE",
  	.id_table	= pdc202new_pci_tbl,
  	.probe		= pdc202new_init_one,
a69999e28   Adrian Bunk   drivers/ide/pci/:...
532
  	.remove		= __devexit_p(pdc202new_remove),
feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
533
534
  	.suspend	= ide_pci_suspend,
  	.resume		= ide_pci_resume,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
535
  };
82ab1eece   Bartlomiej Zolnierkiewicz   ide: add missing ...
536
  static int __init pdc202new_ide_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537
  {
a9ab09e26   Bartlomiej Zolnierkiewicz   ide: use unique n...
538
  	return ide_pci_register_driver(&pdc202new_pci_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
  }
d69c8f8c0   Bartlomiej Zolnierkiewicz   pdc202xx_new: add...
540
541
  static void __exit pdc202new_ide_exit(void)
  {
a9ab09e26   Bartlomiej Zolnierkiewicz   ide: use unique n...
542
  	pci_unregister_driver(&pdc202new_pci_driver);
d69c8f8c0   Bartlomiej Zolnierkiewicz   pdc202xx_new: add...
543
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
544
  module_init(pdc202new_ide_init);
d69c8f8c0   Bartlomiej Zolnierkiewicz   pdc202xx_new: add...
545
  module_exit(pdc202new_ide_exit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
546
547
548
549
  
  MODULE_AUTHOR("Andre Hedrick, Frank Tiernan");
  MODULE_DESCRIPTION("PCI driver module for Promise PDC20268 and higher");
  MODULE_LICENSE("GPL");