Blame view

drivers/ide/via82cxxx.c 14.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
   * VIA IDE driver for Linux. Supported southbridges:
   *
   *   vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
   *   vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a,
a7dec1e0d   Alan Cox   [PATCH] Missing P...
6
   *   vt8235, vt8237, vt8237a
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
   *
   * Copyright (c) 2000-2002 Vojtech Pavlik
42036c85a   Bartlomiej Zolnierkiewicz   via82cxxx: vx855 ...
9
   * Copyright (c) 2007-2010 Bartlomiej Zolnierkiewicz
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
12
13
14
15
16
   *
   * Based on the work of:
   *	Michel Aubry
   *	Jeff Garzik
   *	Andre Hedrick
   *
   * Documentation:
25985edce   Lucas De Marchi   Fix common misspe...
17
   *	Obsolete device documentation publicly available from via.com.tw
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
21
22
23
24
25
   *	Current device documentation available under NDA only
   */
  
  /*
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 as published by
   * the Free Software Foundation.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
  #include <linux/module.h>
  #include <linux/kernel.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
28
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
30
31
  #include <linux/pci.h>
  #include <linux/init.h>
  #include <linux/ide.h>
bdab00b73   Bartlomiej Zolnierkiewicz   via82cxxx: backpo...
32
  #include <linux/dmi.h>
74a9d5f1d   Sascha Hauer   [PATCH] Remove in...
33
  #ifdef CONFIG_PPC_CHRP
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
  #include <asm/processor.h>
  #endif
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
36
  #define DRV_NAME "via82cxxx"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
38
39
40
41
42
43
44
45
46
  #define VIA_IDE_ENABLE		0x40
  #define VIA_IDE_CONFIG		0x41
  #define VIA_FIFO_CONFIG		0x43
  #define VIA_MISC_1		0x44
  #define VIA_MISC_2		0x45
  #define VIA_MISC_3		0x46
  #define VIA_DRIVE_TIMING	0x48
  #define VIA_8BIT_TIMING		0x4e
  #define VIA_ADDRESS_SETUP	0x4c
  #define VIA_UDMA_TIMING		0x50
75b1d9753   Bartlomiej Zolnierkiewicz   ide: convert ide_...
47
48
49
50
51
52
  #define VIA_BAD_PREQ		0x01 /* Crashes if PREQ# till DDACK# set */
  #define VIA_BAD_CLK66		0x02 /* 66 MHz clock doesn't work correctly */
  #define VIA_SET_FIFO		0x04 /* Needs to have FIFO split set */
  #define VIA_NO_UNMASK		0x08 /* Doesn't work with IRQ unmasking on */
  #define VIA_BAD_ID		0x10 /* Has wrong vendor ID (0x1107) */
  #define VIA_BAD_AST		0x20 /* Don't touch Address Setup Timing */
a13e4865f   Bartlomiej Zolnierkiewicz   via82cxxx: fix SA...
53
  #define VIA_SATA_PATA		0x80 /* SATA/PATA combined configuration */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54

42036c85a   Bartlomiej Zolnierkiewicz   via82cxxx: vx855 ...
55
56
57
  enum {
  	VIA_IDFLAG_SINGLE = (1 << 1), /* single channel controller */
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
60
61
62
63
64
65
66
  /*
   * VIA SouthBridge chips.
   */
  
  static struct via_isa_bridge {
  	char *name;
  	u16 id;
  	u8 rev_min;
  	u8 rev_max;
75b1d9753   Bartlomiej Zolnierkiewicz   ide: convert ide_...
67
68
  	u8 udma_mask;
  	u8 flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
  } via_isa_bridges[] = {
a13e4865f   Bartlomiej Zolnierkiewicz   via82cxxx: fix SA...
70
71
72
  	{ "vx855",	PCI_DEVICE_ID_VIA_VX855,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
  	{ "vx800",	PCI_DEVICE_ID_VIA_VX800,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
  	{ "cx700",	PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
5b6c82ea0   Bartlomiej Zolnierkiewicz   via82cxxx: add su...
73
  	{ "vt8261",	PCI_DEVICE_ID_VIA_8261,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
75b1d9753   Bartlomiej Zolnierkiewicz   ide: convert ide_...
74
75
  	{ "vt8237s",	PCI_DEVICE_ID_VIA_8237S,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
  	{ "vt6410",	PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
2a800b7bd   Yann Dirson   via82cxxx: fix ty...
76
  	{ "vt6415",	PCI_DEVICE_ID_VIA_6415,     0x00, 0xff, ATA_UDMA6, VIA_BAD_AST },
75b1d9753   Bartlomiej Zolnierkiewicz   ide: convert ide_...
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
  	{ "vt8251",	PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
  	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
  	{ "vt8237a",	PCI_DEVICE_ID_VIA_8237A,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
  	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
  	{ "vt8233a",	PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
  	{ "vt8233c",	PCI_DEVICE_ID_VIA_8233C_0,  0x00, 0x2f, ATA_UDMA5, },
  	{ "vt8233",	PCI_DEVICE_ID_VIA_8233_0,   0x00, 0x2f, ATA_UDMA5, },
  	{ "vt8231",	PCI_DEVICE_ID_VIA_8231,     0x00, 0x2f, ATA_UDMA5, },
  	{ "vt82c686b",	PCI_DEVICE_ID_VIA_82C686,   0x40, 0x4f, ATA_UDMA5, },
  	{ "vt82c686a",	PCI_DEVICE_ID_VIA_82C686,   0x10, 0x2f, ATA_UDMA4, },
  	{ "vt82c686",	PCI_DEVICE_ID_VIA_82C686,   0x00, 0x0f, ATA_UDMA2, VIA_BAD_CLK66 },
  	{ "vt82c596b",	PCI_DEVICE_ID_VIA_82C596,   0x10, 0x2f, ATA_UDMA4, },
  	{ "vt82c596a",	PCI_DEVICE_ID_VIA_82C596,   0x00, 0x0f, ATA_UDMA2, VIA_BAD_CLK66 },
  	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, ATA_UDMA2, VIA_SET_FIFO },
  	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, ATA_UDMA2, VIA_SET_FIFO | VIA_BAD_PREQ },
  	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, ATA_UDMA2, VIA_SET_FIFO },
  	{ "vt82c586a",	PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, ATA_UDMA2, VIA_SET_FIFO },
  	{ "vt82c586",	PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f,      0x00, VIA_SET_FIFO },
  	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f,      0x00, VIA_SET_FIFO | VIA_NO_UNMASK },
  	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f,      0x00, VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
5b6c82ea0   Bartlomiej Zolnierkiewicz   via82cxxx: add su...
97
  	{ "vtxxxx",	PCI_DEVICE_ID_VIA_ANON,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
98
99
  	{ NULL }
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
  static unsigned int via_clock;
75b1d9753   Bartlomiej Zolnierkiewicz   ide: convert ide_...
101
  static char *via_dma[] = { "16", "25", "33", "44", "66", "100", "133" };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102

7462cbff7   Daniel Drake   [PATCH] via82cxxx...
103
104
105
106
107
  struct via82cxxx_dev
  {
  	struct via_isa_bridge *via_config;
  	unsigned int via_80w;
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
110
111
112
113
114
115
  /**
   *	via_set_speed			-	write timing registers
   *	@dev: PCI device
   *	@dn: device
   *	@timing: IDE timing data to use
   *
   *	via_set_speed writes timing values to the chipset registers
   */
7462cbff7   Daniel Drake   [PATCH] via82cxxx...
116
  static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
  {
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
118
  	struct pci_dev *dev = to_pci_dev(hwif->dev);
ee77325b0   Bartlomiej Zolnierkiewicz   via82cxxx: conver...
119
120
  	struct ide_host *host = pci_get_drvdata(dev);
  	struct via82cxxx_dev *vdev = host->host_priv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
  	u8 t;
7462cbff7   Daniel Drake   [PATCH] via82cxxx...
122
  	if (~vdev->via_config->flags & VIA_BAD_AST) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
  		pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
d6cddd3ca   Harvey Harrison   ide: eliminate FI...
124
  		t = (t & ~(3 << ((3 - dn) << 1))) | ((clamp_val(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
126
127
128
  		pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t);
  	}
  
  	pci_write_config_byte(dev, VIA_8BIT_TIMING + (1 - (dn >> 1)),
d6cddd3ca   Harvey Harrison   ide: eliminate FI...
129
  		((clamp_val(timing->act8b, 1, 16) - 1) << 4) | (clamp_val(timing->rec8b, 1, 16) - 1));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
131
  
  	pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
d6cddd3ca   Harvey Harrison   ide: eliminate FI...
132
  		((clamp_val(timing->active, 1, 16) - 1) << 4) | (clamp_val(timing->recover, 1, 16) - 1));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133

75b1d9753   Bartlomiej Zolnierkiewicz   ide: convert ide_...
134
  	switch (vdev->via_config->udma_mask) {
d6cddd3ca   Harvey Harrison   ide: eliminate FI...
135
136
137
138
  	case ATA_UDMA2: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 5) - 2)) : 0x03; break;
  	case ATA_UDMA4: t = timing->udma ? (0xe8 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x0f; break;
  	case ATA_UDMA5: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
  	case ATA_UDMA6: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
  	}
68d0a0361   Bartlomiej Zolnierkiewicz   via82cxxx: fix UD...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
  	/* Set UDMA unless device is not UDMA capable */
  	if (vdev->via_config->udma_mask) {
  		u8 udma_etc;
  
  		pci_read_config_byte(dev, VIA_UDMA_TIMING + 3 - dn, &udma_etc);
  
  		/* clear transfer mode bit */
  		udma_etc &= ~0x20;
  
  		if (timing->udma) {
  			/* preserve 80-wire cable detection bit */
  			udma_etc &= 0x10;
  			udma_etc |= t;
  		}
  
  		pci_write_config_byte(dev, VIA_UDMA_TIMING + 3 - dn, udma_etc);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
158
159
160
  }
  
  /**
   *	via_set_drive		-	configure transfer mode
8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
161
   *	@hwif: port
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
   *	@drive: Drive to set up
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
   *
88b2b32ba   Bartlomiej Zolnierkiewicz   ide: move ide_con...
164
165
   *	via_set_drive() computes timing values configures the chipset to
   *	a desired transfer mode.  It also can be called by upper layers.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
   */
8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
167
  static void via_set_drive(ide_hwif_t *hwif, ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
  {
7e59ea21a   Bartlomiej Zolnierkiewicz   ide: check drive-...
169
  	ide_drive_t *peer = ide_get_pair_dev(drive);
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
170
  	struct pci_dev *dev = to_pci_dev(hwif->dev);
ee77325b0   Bartlomiej Zolnierkiewicz   via82cxxx: conver...
171
172
  	struct ide_host *host = pci_get_drvdata(dev);
  	struct via82cxxx_dev *vdev = host->host_priv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
174
  	struct ide_timing t, p;
  	unsigned int T, UT;
8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
175
  	const u8 speed = drive->dma_mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
  	T = 1000000000 / via_clock;
75b1d9753   Bartlomiej Zolnierkiewicz   ide: convert ide_...
178
179
180
181
182
183
  	switch (vdev->via_config->udma_mask) {
  	case ATA_UDMA2: UT = T;   break;
  	case ATA_UDMA4: UT = T/2; break;
  	case ATA_UDMA5: UT = T/3; break;
  	case ATA_UDMA6: UT = T/4; break;
  	default:	UT = T;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
185
186
  	}
  
  	ide_timing_compute(drive, speed, &t, T, UT);
7e59ea21a   Bartlomiej Zolnierkiewicz   ide: check drive-...
187
  	if (peer) {
f0e5f62d9   Bartlomiej Zolnierkiewicz   via82cxxx: use ->...
188
  		ide_timing_compute(peer, peer->pio_mode, &p, T, UT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
190
  		ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
  	}
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
191
  	via_set_speed(hwif, drive->dn, &t);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
  }
  
  /**
88b2b32ba   Bartlomiej Zolnierkiewicz   ide: move ide_con...
195
   *	via_set_pio_mode	-	set host controller for PIO mode
e085b3cae   Bartlomiej Zolnierkiewicz   ide: change ->set...
196
   *	@hwif: port
26bcb879c   Bartlomiej Zolnierkiewicz   ide: add ide_set{...
197
   *	@drive: drive
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
199
200
   *
   *	A callback from the upper layers for PIO-only tuning.
   */
e085b3cae   Bartlomiej Zolnierkiewicz   ide: change ->set...
201
  static void via_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
  {
8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
203
204
  	drive->dma_mode = drive->pio_mode;
  	via_set_drive(hwif, drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205
  }
7462cbff7   Daniel Drake   [PATCH] via82cxxx...
206
207
208
  static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
  {
  	struct via_isa_bridge *via_config;
7462cbff7   Daniel Drake   [PATCH] via82cxxx...
209

5b6c82ea0   Bartlomiej Zolnierkiewicz   via82cxxx: add su...
210
211
  	for (via_config = via_isa_bridges;
  	     via_config->id != PCI_DEVICE_ID_VIA_ANON; via_config++)
652aa1629   Alan Cox   [PATCH] IDE: more...
212
  		if ((*isa = pci_get_device(PCI_VENDOR_ID_VIA +
7462cbff7   Daniel Drake   [PATCH] via82cxxx...
213
214
  			!!(via_config->flags & VIA_BAD_ID),
  			via_config->id, NULL))) {
44c10138f   Auke Kok   PCI: Change all d...
215
216
  			if ((*isa)->revision >= via_config->rev_min &&
  			    (*isa)->revision <= via_config->rev_max)
7462cbff7   Daniel Drake   [PATCH] via82cxxx...
217
  				break;
652aa1629   Alan Cox   [PATCH] IDE: more...
218
  			pci_dev_put(*isa);
7462cbff7   Daniel Drake   [PATCH] via82cxxx...
219
220
221
  		}
  
  	return via_config;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
  }
cd36beec0   Bartlomiej Zolnierkiewicz   [PATCH] via82cxxx...
223
224
225
  /*
   * Check and handle 80-wire cable presence
   */
feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
226
  static void via_cable_detect(struct via82cxxx_dev *vdev, u32 u)
cd36beec0   Bartlomiej Zolnierkiewicz   [PATCH] via82cxxx...
227
228
  {
  	int i;
75b1d9753   Bartlomiej Zolnierkiewicz   ide: convert ide_...
229
230
  	switch (vdev->via_config->udma_mask) {
  		case ATA_UDMA4:
cd36beec0   Bartlomiej Zolnierkiewicz   [PATCH] via82cxxx...
231
232
233
234
235
236
237
238
239
240
241
  			for (i = 24; i >= 0; i -= 8)
  				if (((u >> (i & 16)) & 8) &&
  				    ((u >> i) & 0x20) &&
  				     (((u >> i) & 7) < 2)) {
  					/*
  					 * 2x PCI clock and
  					 * UDMA w/ < 3T/cycle
  					 */
  					vdev->via_80w |= (1 << (1 - (i >> 4)));
  				}
  			break;
75b1d9753   Bartlomiej Zolnierkiewicz   ide: convert ide_...
242
  		case ATA_UDMA5:
cd36beec0   Bartlomiej Zolnierkiewicz   [PATCH] via82cxxx...
243
244
245
246
247
248
249
250
251
252
  			for (i = 24; i >= 0; i -= 8)
  				if (((u >> i) & 0x10) ||
  				    (((u >> i) & 0x20) &&
  				     (((u >> i) & 7) < 4))) {
  					/* BIOS 80-wire bit or
  					 * UDMA w/ < 60ns/cycle
  					 */
  					vdev->via_80w |= (1 << (1 - (i >> 4)));
  				}
  			break;
75b1d9753   Bartlomiej Zolnierkiewicz   ide: convert ide_...
253
  		case ATA_UDMA6:
cd36beec0   Bartlomiej Zolnierkiewicz   [PATCH] via82cxxx...
254
255
256
257
258
259
260
261
262
263
264
265
  			for (i = 24; i >= 0; i -= 8)
  				if (((u >> i) & 0x10) ||
  				    (((u >> i) & 0x20) &&
  				     (((u >> i) & 7) < 6))) {
  					/* BIOS 80-wire bit or
  					 * UDMA w/ < 60ns/cycle
  					 */
  					vdev->via_80w |= (1 << (1 - (i >> 4)));
  				}
  			break;
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
267
268
  /**
   *	init_chipset_via82cxxx	-	initialization handler
   *	@dev: PCI device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
270
271
272
   *
   *	The initialization callback. Here we determine the IDE chip type
   *	and initialize its drive independent registers.
   */
2ed0ef543   Bartlomiej Zolnierkiewicz   ide: fix ->init_c...
273
  static int init_chipset_via82cxxx(struct pci_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274
  {
ee77325b0   Bartlomiej Zolnierkiewicz   via82cxxx: conver...
275
276
  	struct ide_host *host = pci_get_drvdata(dev);
  	struct via82cxxx_dev *vdev = host->host_priv;
37525bebc   Bartlomiej Zolnierkiewicz   via82cxxx: cleanu...
277
  	struct via_isa_bridge *via_config = vdev->via_config;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278
  	u8 t, v;
cd36beec0   Bartlomiej Zolnierkiewicz   [PATCH] via82cxxx...
279
  	u32 u;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
  	/*
cd36beec0   Bartlomiej Zolnierkiewicz   [PATCH] via82cxxx...
281
  	 * Detect cable and configure Clk66
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
  	 */
cd36beec0   Bartlomiej Zolnierkiewicz   [PATCH] via82cxxx...
283
284
285
  	pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
  
  	via_cable_detect(vdev, u);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286

75b1d9753   Bartlomiej Zolnierkiewicz   ide: convert ide_...
287
  	if (via_config->udma_mask == ATA_UDMA4) {
7462cbff7   Daniel Drake   [PATCH] via82cxxx...
288
  		/* Enable Clk66 */
7462cbff7   Daniel Drake   [PATCH] via82cxxx...
289
290
  		pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
  	} else if (via_config->flags & VIA_BAD_CLK66) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
  		/* Would cause trouble on 596a and 686 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  		pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008);
  	}
  
  	/*
  	 * Check whether interfaces are enabled.
  	 */
  
  	pci_read_config_byte(dev, VIA_IDE_ENABLE, &v);
  
  	/*
  	 * Set up FIFO sizes and thresholds.
  	 */
  
  	pci_read_config_byte(dev, VIA_FIFO_CONFIG, &t);
  
  	/* Disable PREQ# till DDACK# */
  	if (via_config->flags & VIA_BAD_PREQ) {
  		/* Would crash on 586b rev 41 */
  		t &= 0x7f;
  	}
  
  	/* Fix FIFO split between channels */
  	if (via_config->flags & VIA_SET_FIFO) {
  		t &= (t & 0x9f);
  		switch (v & 3) {
  			case 2: t |= 0x00; break;	/* 16 on primary */
  			case 1: t |= 0x60; break;	/* 16 on secondary */
  			case 3: t |= 0x20; break;	/* 8 pri 8 sec */
  		}
  	}
  
  	pci_write_config_byte(dev, VIA_FIFO_CONFIG, t);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
325
  	return 0;
  }
bdab00b73   Bartlomiej Zolnierkiewicz   via82cxxx: backpo...
326
327
328
  /*
   *	Cable special cases
   */
1855256c4   Jeff Garzik   drivers/firmware:...
329
  static const struct dmi_system_id cable_dmi_table[] = {
bdab00b73   Bartlomiej Zolnierkiewicz   via82cxxx: backpo...
330
331
332
333
334
335
336
337
338
  	{
  		.ident = "Acer Ferrari 3400",
  		.matches = {
  			DMI_MATCH(DMI_BOARD_VENDOR, "Acer,Inc."),
  			DMI_MATCH(DMI_BOARD_NAME, "Ferrari 3400"),
  		},
  	},
  	{ }
  };
58e47bb17   Bartlomiej Zolnierkiewicz   via82cxxx: add Ar...
339
  static int via_cable_override(struct pci_dev *pdev)
bdab00b73   Bartlomiej Zolnierkiewicz   via82cxxx: backpo...
340
341
342
343
  {
  	/* Systems by DMI */
  	if (dmi_check_system(cable_dmi_table))
  		return 1;
58e47bb17   Bartlomiej Zolnierkiewicz   via82cxxx: add Ar...
344
345
346
347
348
  
  	/* Arima W730-K8/Targa Visionary 811/... */
  	if (pdev->subsystem_vendor == 0x161F &&
  	    pdev->subsystem_device == 0x2032)
  		return 1;
bdab00b73   Bartlomiej Zolnierkiewicz   via82cxxx: backpo...
349
350
  	return 0;
  }
f454cbe8c   Bartlomiej Zolnierkiewicz   ide: ->cable_dete...
351
  static u8 via82cxxx_cable_detect(ide_hwif_t *hwif)
bdab00b73   Bartlomiej Zolnierkiewicz   via82cxxx: backpo...
352
  {
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
353
  	struct pci_dev *pdev = to_pci_dev(hwif->dev);
ee77325b0   Bartlomiej Zolnierkiewicz   via82cxxx: conver...
354
355
  	struct ide_host *host = pci_get_drvdata(pdev);
  	struct via82cxxx_dev *vdev = host->host_priv;
bdab00b73   Bartlomiej Zolnierkiewicz   via82cxxx: backpo...
356

58e47bb17   Bartlomiej Zolnierkiewicz   via82cxxx: add Ar...
357
  	if (via_cable_override(pdev))
bdab00b73   Bartlomiej Zolnierkiewicz   via82cxxx: backpo...
358
  		return ATA_CBL_PATA40_SHORT;
a13e4865f   Bartlomiej Zolnierkiewicz   via82cxxx: fix SA...
359
360
  	if ((vdev->via_config->flags & VIA_SATA_PATA) && hwif->channel == 0)
  		return ATA_CBL_SATA;
bdab00b73   Bartlomiej Zolnierkiewicz   via82cxxx: backpo...
361
362
363
364
365
  	if ((vdev->via_80w >> hwif->channel) & 1)
  		return ATA_CBL_PATA80;
  	else
  		return ATA_CBL_PATA40;
  }
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
366
367
368
369
370
  static const struct ide_port_ops via_port_ops = {
  	.set_pio_mode		= via_set_pio_mode,
  	.set_dma_mode		= via_set_drive,
  	.cable_detect		= via82cxxx_cable_detect,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
371

fe31edc8a   Greg Kroah-Hartman   Drivers: ide: rem...
372
  static const struct ide_port_info via82cxxx_chipset = {
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
373
  	.name		= DRV_NAME,
6157332ed   Bartlomiej Zolnierkiewicz   via82cxxx: keep l...
374
  	.init_chipset	= init_chipset_via82cxxx,
6157332ed   Bartlomiej Zolnierkiewicz   via82cxxx: keep l...
375
  	.enablebits	= { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
376
  	.port_ops	= &via_port_ops,
6157332ed   Bartlomiej Zolnierkiewicz   via82cxxx: keep l...
377
  	.host_flags	= IDE_HFLAG_PIO_NO_BLACKLIST |
6157332ed   Bartlomiej Zolnierkiewicz   via82cxxx: keep l...
378
  			  IDE_HFLAG_POST_SET_MODE |
5e71d9c5a   Bartlomiej Zolnierkiewicz   ide: IDE_HFLAG_BO...
379
  			  IDE_HFLAG_IO_32BIT,
6157332ed   Bartlomiej Zolnierkiewicz   via82cxxx: keep l...
380
381
382
  	.pio_mask	= ATA_PIO5,
  	.swdma_mask	= ATA_SWDMA2,
  	.mwdma_mask	= ATA_MWDMA2,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
  };
fe31edc8a   Greg Kroah-Hartman   Drivers: ide: rem...
384
  static int via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
  {
23a1b2a78   Alan Cox   [PATCH] via82cxxx...
386
387
  	struct pci_dev *isa = NULL;
  	struct via_isa_bridge *via_config;
ee77325b0   Bartlomiej Zolnierkiewicz   via82cxxx: conver...
388
389
  	struct via82cxxx_dev *vdev;
  	int rc;
6157332ed   Bartlomiej Zolnierkiewicz   via82cxxx: keep l...
390
  	u8 idx = id->driver_data;
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
391
  	struct ide_port_info d;
6157332ed   Bartlomiej Zolnierkiewicz   via82cxxx: keep l...
392
393
  
  	d = via82cxxx_chipset;
8acf28c09   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
394

23a1b2a78   Alan Cox   [PATCH] via82cxxx...
395
396
397
398
  	/*
  	 * Find the ISA bridge and check we know what it is.
  	 */
  	via_config = via_config_find(&isa);
8acf28c09   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
399

37525bebc   Bartlomiej Zolnierkiewicz   via82cxxx: cleanu...
400
401
402
  	/*
  	 * Print the boot message.
  	 */
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
403
404
  	printk(KERN_INFO DRV_NAME " %s: VIA %s (rev %02x) IDE %sDMA%s
  ",
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
405
  		pci_name(dev), via_config->name, isa->revision,
37525bebc   Bartlomiej Zolnierkiewicz   via82cxxx: cleanu...
406
407
  		via_config->udma_mask ? "U" : "MW",
  		via_dma[via_config->udma_mask ?
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
408
  			(fls(via_config->udma_mask) - 1) : 0]);
37525bebc   Bartlomiej Zolnierkiewicz   via82cxxx: cleanu...
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
  
  	pci_dev_put(isa);
  
  	/*
  	 * Determine system bus clock.
  	 */
  	via_clock = (ide_pci_clk ? ide_pci_clk : 33) * 1000;
  
  	switch (via_clock) {
  	case 33000: via_clock = 33333; break;
  	case 37000: via_clock = 37500; break;
  	case 41000: via_clock = 41666; break;
  	}
  
  	if (via_clock < 20000 || via_clock > 50000) {
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
424
  		printk(KERN_WARNING DRV_NAME ": User given PCI clock speed "
37525bebc   Bartlomiej Zolnierkiewicz   via82cxxx: cleanu...
425
426
  			"impossible (%d), using 33 MHz instead.
  ", via_clock);
37525bebc   Bartlomiej Zolnierkiewicz   via82cxxx: cleanu...
427
428
  		via_clock = 33333;
  	}
42036c85a   Bartlomiej Zolnierkiewicz   via82cxxx: vx855 ...
429
  	if (idx == 1)
6157332ed   Bartlomiej Zolnierkiewicz   via82cxxx: keep l...
430
  		d.enablebits[1].reg = d.enablebits[0].reg = 0;
42036c85a   Bartlomiej Zolnierkiewicz   via82cxxx: vx855 ...
431
432
433
434
435
  	else
  		d.host_flags |= IDE_HFLAG_NO_AUTODMA;
  
  	if (idx == VIA_IDFLAG_SINGLE)
  		d.host_flags |= IDE_HFLAG_SINGLE;
6157332ed   Bartlomiej Zolnierkiewicz   via82cxxx: keep l...
436
437
438
  
  	if ((via_config->flags & VIA_NO_UNMASK) == 0)
  		d.host_flags |= IDE_HFLAG_UNMASK_IRQS;
caea7602f   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
439

6157332ed   Bartlomiej Zolnierkiewicz   via82cxxx: keep l...
440
  	d.udma_mask = via_config->udma_mask;
8acf28c09   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
441

ee77325b0   Bartlomiej Zolnierkiewicz   via82cxxx: conver...
442
443
  	vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
  	if (!vdev) {
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
444
445
446
  		printk(KERN_ERR DRV_NAME " %s: out of memory :(
  ",
  			pci_name(dev));
ee77325b0   Bartlomiej Zolnierkiewicz   via82cxxx: conver...
447
448
  		return -ENOMEM;
  	}
37525bebc   Bartlomiej Zolnierkiewicz   via82cxxx: cleanu...
449
  	vdev->via_config = via_config;
ee77325b0   Bartlomiej Zolnierkiewicz   via82cxxx: conver...
450
451
452
453
454
  	rc = ide_pci_init_one(dev, &d, vdev);
  	if (rc)
  		kfree(vdev);
  
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455
  }
fe31edc8a   Greg Kroah-Hartman   Drivers: ide: rem...
456
  static void via_remove(struct pci_dev *dev)
585f67e73   Bartlomiej Zolnierkiewicz   via82cxxx: add ->...
457
458
459
460
461
462
463
  {
  	struct ide_host *host = pci_get_drvdata(dev);
  	struct via82cxxx_dev *vdev = host->host_priv;
  
  	ide_pci_remove(dev);
  	kfree(vdev);
  }
9cbcc5e3c   Bartlomiej Zolnierkiewicz   ide: use PCI_VDEV...
464
465
466
  static const struct pci_device_id via_pci_tbl[] = {
  	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1),  0 },
  	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1),  0 },
84f7e451e   Andrew Smith   via82cxxx: add ne...
467
  	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_CX700_IDE), 0 },
42036c85a   Bartlomiej Zolnierkiewicz   via82cxxx: vx855 ...
468
  	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_VX855_IDE), VIA_IDFLAG_SINGLE },
9cbcc5e3c   Bartlomiej Zolnierkiewicz   ide: use PCI_VDEV...
469
  	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410),      1 },
a354ae874   Bartlomiej Zolnierkiewicz   via82cxxx: add su...
470
  	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6415),      1 },
9cbcc5e3c   Bartlomiej Zolnierkiewicz   ide: use PCI_VDEV...
471
  	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
473
474
  	{ 0, },
  };
  MODULE_DEVICE_TABLE(pci, via_pci_tbl);
a9ab09e26   Bartlomiej Zolnierkiewicz   ide: use unique n...
475
  static struct pci_driver via_pci_driver = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
476
477
478
  	.name 		= "VIA_IDE",
  	.id_table 	= via_pci_tbl,
  	.probe 		= via_init_one,
fe31edc8a   Greg Kroah-Hartman   Drivers: ide: rem...
479
  	.remove		= via_remove,
feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
480
481
  	.suspend	= ide_pci_suspend,
  	.resume		= ide_pci_resume,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
482
  };
82ab1eece   Bartlomiej Zolnierkiewicz   ide: add missing ...
483
  static int __init via_ide_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
  {
a9ab09e26   Bartlomiej Zolnierkiewicz   ide: use unique n...
485
  	return ide_pci_register_driver(&via_pci_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
486
  }
585f67e73   Bartlomiej Zolnierkiewicz   via82cxxx: add ->...
487
488
  static void __exit via_ide_exit(void)
  {
a9ab09e26   Bartlomiej Zolnierkiewicz   ide: use unique n...
489
  	pci_unregister_driver(&via_pci_driver);
585f67e73   Bartlomiej Zolnierkiewicz   via82cxxx: add ->...
490
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
  module_init(via_ide_init);
585f67e73   Bartlomiej Zolnierkiewicz   via82cxxx: add ->...
492
  module_exit(via_ide_exit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493

42036c85a   Bartlomiej Zolnierkiewicz   via82cxxx: vx855 ...
494
  MODULE_AUTHOR("Vojtech Pavlik, Bartlomiej Zolnierkiewicz, Michel Aubry, Jeff Garzik, Andre Hedrick");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
496
  MODULE_DESCRIPTION("PCI driver module for VIA IDE");
  MODULE_LICENSE("GPL");