Blame view

drivers/ide/pdc202xx_new.c 14.4 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
  #include <linux/pci.h>
  #include <linux/init.h>
  #include <linux/ide.h>
353b39d1b   Amitoj Kaur Chawla   ide: pdc202xx_new...
24
  #include <linux/ktime.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
  
  #include <asm/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
  
  #ifdef CONFIG_PPC_PMAC
  #include <asm/prom.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
  #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
  {
353b39d1b   Amitoj Kaur Chawla   ide: pdc202xx_new...
238
  	ktime_t 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);
353b39d1b   Amitoj Kaur Chawla   ide: pdc202xx_new...
244
  	start_time = ktime_get();
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);
353b39d1b   Amitoj Kaur Chawla   ide: pdc202xx_new...
257
  	end_time = ktime_get();
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)
  	 */
353b39d1b   Amitoj Kaur Chawla   ide: pdc202xx_new...
270
  	usec_elapsed = ktime_us_delta(end_time, start_time);
56fe23d5a   Mikael Pettersson   pdc202xx_new: PLL...
271
  	pll_input = ((start_count - end_count) & 0x3fffffff) / 10 *
8006bf56e   Albert Lee   ide: pdc202xx_new...
272
  		(10000000 / usec_elapsed);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
273
274
275
276
277
278
  
  	DBG("start[%ld] end[%ld]
  ", start_count, end_count);
  
  	return pll_input;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
  #ifdef CONFIG_PPC_PMAC
feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
280
  static void apple_kiwi_init(struct pci_dev *pdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281
282
  {
  	struct device_node *np = pci_device_to_OF_node(pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
283
  	u8 conf;
55b61fec2   Stephen Rothwell   [POWERPC] Rename ...
284
  	if (np == NULL || !of_device_is_compatible(np, "kiwi-root"))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
  		return;
fc212bb1f   Bartlomiej Zolnierkiewicz   ide: use pci_dev-...
286
  	if (pdev->revision >= 0x03) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
  		/* Setup chip magic config stuff (from darwin) */
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
288
289
  		pci_read_config_byte (pdev, 0x40, &conf);
  		pci_write_config_byte(pdev, 0x40, (conf | 0x01));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
292
  }
  #endif /* CONFIG_PPC_PMAC */
2ed0ef543   Bartlomiej Zolnierkiewicz   ide: fix ->init_c...
293
  static int init_chipset_pdcnew(struct pci_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
  {
a326b02b0   Bartlomiej Zolnierkiewicz   ide: drop 'name' ...
295
  	const char *name = DRV_NAME;
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
296
297
298
299
300
  	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...
301
302
  	if (dma_base == 0)
  		return -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
304
305
  #ifdef CONFIG_PPC_PMAC
  	apple_kiwi_init(dev);
  #endif
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  	/* 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 ...
325
326
327
  	printk(KERN_INFO "%s %s: PLL input clock is %ld kHz
  ",
  		name, pci_name(dev), pll_input / 1000);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
328
329
330
  
  	/* Sanity check */
  	if (unlikely(pll_input < 5000000L || pll_input > 70000000L)) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
331
332
333
  		printk(KERN_ERR "%s %s: Bad PLL input clock %ld Hz, giving up!"
  			"
  ", name, pci_name(dev), pll_input);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
334
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
  		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 ...
371
372
373
  		printk(KERN_ERR "%s %s: Bad ratio %ld, giving up!
  ",
  			name, pci_name(dev), ratio);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
374
375
376
377
378
379
380
381
382
383
  		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 ...
384
385
386
  		printk(KERN_ERR "%s %s: F[%d] invalid!
  ",
  			name, pci_name(dev), f);
47694bb86   Sergei Shtylyov   [PATCH] pdc202xx_...
387
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
  		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...
418
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
419
  }
fe31edc8a   Greg Kroah-Hartman   Drivers: ide: rem...
420
  static struct pci_dev *pdc20270_get_dev2(struct pci_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421
  {
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
422
  	struct pci_dev *dev2;
eadb6ecf7   Bartlomiej Zolnierkiewicz   pdc202xx_new: fix...
423
  	dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 1,
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
424
  						PCI_FUNC(dev->devfn)));
eadb6ecf7   Bartlomiej Zolnierkiewicz   pdc202xx_new: fix...
425

099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
426
427
428
429
430
431
  	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...
432
  			printk(KERN_INFO DRV_NAME " %s: PCI config space "
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
433
434
  				"interrupt fixed
  ", pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
  		}
070479357   Sergei Shtylyov   pdc202xx_new: swi...
436

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

fe31edc8a   Greg Kroah-Hartman   Drivers: ide: rem...
461
  static const struct ide_port_info pdcnew_chipsets[] = {
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
462
463
  	/* 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
464
465
466
467
468
469
470
471
472
473
474
  };
  
  /**
   *	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.
   */
   
fe31edc8a   Greg Kroah-Hartman   Drivers: ide: rem...
475
  static int pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
476
  {
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
477
  	const struct ide_port_info *d = &pdcnew_chipsets[id->driver_data];
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
478
  	struct pci_dev *bridge = dev->bus->self;
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
479

ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
480
  	if (dev->device == PCI_DEVICE_ID_PROMISE_20270 && bridge &&
099b1f42a   Bartlomiej Zolnierkiewicz   pdc202xx_new: rem...
481
482
483
484
485
486
  	    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
487

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