hpt366.c 34.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
/*
 * linux/drivers/ide/hpt366.c		Version 0.33	April 17, 2002
 *
 * Copyright (C) 1999-2002		Andre Hedrick <andre@linux-ide.org>
 * Portions Copyright (C) 2001	        Sun Microsystems, Inc.
 *
 * Thanks to HighPoint Technologies for their assistance, and hardware.
 * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his
 * donation of an ABit BP6 mainboard, processor, and memory acellerated
 * development and support.
 *
 * Note that final HPT370 support was done by force extraction of GPL.
 *
 * - add function for getting/setting power status of drive
 * - the HPT370's state machine can get confused. reset it before each dma 
 *   xfer to prevent that from happening.
 * - reset state engine whenever we get an error.
 * - check for busmaster state at end of dma. 
 * - use new highpoint timings.
 * - detect bus speed using highpoint register.
 * - use pll if we don't have a clock table. added a 66MHz table that's
 *   just 2x the 33MHz table.
 * - removed turnaround. NOTE: we never want to switch between pll and
 *   pci clocks as the chip can glitch in those cases. the highpoint
 *   approved workaround slows everything down too much to be useful. in
 *   addition, we would have to serialize access to each chip.
 * 	Adrian Sun <a.sun@sun.com>
 *
 * add drive timings for 66MHz PCI bus,
 * fix ATA Cable signal detection, fix incorrect /proc info
 * add /proc display for per-drive PIO/DMA/UDMA mode and
 * per-channel ATA-33/66 Cable detect.
 * 	Duncan Laurie <void@sun.com>
 *
 * fixup /proc output for multiple controllers
 *	Tim Hockin <thockin@sun.com>
 *
 * On hpt366: 
 * Reset the hpt366 on error, reset on dma
 * Fix disabling Fast Interrupt hpt366.
 * 	Mike Waychison <crlf@sun.com>
 */


#include <linux/config.h>
#include <linux/types.h>
47
#include <linux/module.h>
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>

#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ide.h>

#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/irq.h>

#include "ide_modes.h"
Jens Axboe's avatar
Jens Axboe committed
66
#include "hpt366.h"
67 68 69 70 71 72 73 74 75 76

#if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
#endif  /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */

static unsigned int hpt_revision(struct pci_dev *dev);
static unsigned int hpt_minimum_revision(struct pci_dev *dev, int revision);

#if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
Jens Axboe's avatar
Jens Axboe committed
77 78 79 80

static u8 hpt366_proc = 0;
static struct pci_dev *hpt_devs[HPT366_MAX_DEVS];
static int n_hpt_devs;
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count)
{
	char *p	= buffer;
	char *chipset_nums[] = {"366", "366",  "368",
				"370", "370A", "372",
				"302", "371",  "374" };
	int i;

	p += sprintf(p, "\n                             "
		"HighPoint HPT366/368/370/372/374\n");
	for (i = 0; i < n_hpt_devs; i++) {
		struct pci_dev *dev = hpt_devs[i];
		unsigned long iobase = dev->resource[4].start;
		u32 class_rev = hpt_revision(dev);
		u8 c0, c1;

		p += sprintf(p, "\nController: %d\n", i);
		p += sprintf(p, "Chipset: HPT%s\n", chipset_nums[class_rev]);
		p += sprintf(p, "--------------- Primary Channel "
				"--------------- Secondary Channel "
				"--------------\n");

		/* get the bus master status registers */
Jens Axboe's avatar
Jens Axboe committed
105 106
		c0 = inb(iobase + 0x2);
		c1 = inb(iobase + 0xa);
107 108 109 110 111 112 113
		p += sprintf(p, "Enabled:        %s"
				"                             %s\n",
			(c0 & 0x80) ? "no" : "yes",
			(c1 & 0x80) ? "no" : "yes");

		if (hpt_minimum_revision(dev, 3)) {
			u8 cbl;
Jens Axboe's avatar
Jens Axboe committed
114 115 116 117
			cbl = inb(iobase + 0x7b);
			outb(cbl | 1, iobase + 0x7b);
			outb(cbl & ~1, iobase + 0x7b);
			cbl = inb(iobase + 0x7a);
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
			p += sprintf(p, "Cable:          ATA-%d"
					"                          ATA-%d\n",
				(cbl & 0x02) ? 33 : 66,
				(cbl & 0x01) ? 33 : 66);
			p += sprintf(p, "\n");
		}

		p += sprintf(p, "--------------- drive0 --------- drive1 "
				"------- drive0 ---------- drive1 -------\n");
		p += sprintf(p, "DMA capable:    %s              %s" 
				"            %s               %s\n",
			(c0 & 0x20) ? "yes" : "no ", 
			(c0 & 0x40) ? "yes" : "no ",
			(c1 & 0x20) ? "yes" : "no ", 
			(c1 & 0x40) ? "yes" : "no ");

		{
			u8 c2, c3;
			/* older revs don't have these registers mapped 
			 * into io space */
			pci_read_config_byte(dev, 0x43, &c0);
			pci_read_config_byte(dev, 0x47, &c1);
			pci_read_config_byte(dev, 0x4b, &c2);
			pci_read_config_byte(dev, 0x4f, &c3);

			p += sprintf(p, "Mode:           %s             %s"
					"           %s              %s\n",
				(c0 & 0x10) ? "UDMA" : (c0 & 0x20) ? "DMA " : 
					(c0 & 0x80) ? "PIO " : "off ",
				(c1 & 0x10) ? "UDMA" : (c1 & 0x20) ? "DMA " :
					(c1 & 0x80) ? "PIO " : "off ",
				(c2 & 0x10) ? "UDMA" : (c2 & 0x20) ? "DMA " :
					(c2 & 0x80) ? "PIO " : "off ",
				(c3 & 0x10) ? "UDMA" : (c3 & 0x20) ? "DMA " :
					(c3 & 0x80) ? "PIO " : "off ");
		}
	}
	p += sprintf(p, "\n");
	
	return p-buffer;/* => must be less than 4k! */
}
#endif  /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */

Jens Axboe's avatar
Jens Axboe committed
161
static u32 hpt_revision (struct pci_dev *dev)
162
{
Jens Axboe's avatar
Jens Axboe committed
163
	u32 class_rev;
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
	class_rev &= 0xff;

	switch(dev->device) {
		case PCI_DEVICE_ID_TTI_HPT374:
			class_rev = PCI_DEVICE_ID_TTI_HPT374; break;
		case PCI_DEVICE_ID_TTI_HPT371:
			class_rev = PCI_DEVICE_ID_TTI_HPT371; break;
		case PCI_DEVICE_ID_TTI_HPT302:
			class_rev = PCI_DEVICE_ID_TTI_HPT302; break;
		case PCI_DEVICE_ID_TTI_HPT372:
			class_rev = PCI_DEVICE_ID_TTI_HPT372; break;
		default:
			break;
	}
	return class_rev;
}

Jens Axboe's avatar
Jens Axboe committed
182
static u32 hpt_minimum_revision (struct pci_dev *dev, int revision)
183 184 185 186 187 188 189 190
{
	unsigned int class_rev = hpt_revision(dev);
	revision--;
	return ((int) (class_rev > revision) ? 1 : 0);
}

static int check_in_drive_lists(ide_drive_t *drive, const char **list);

Jens Axboe's avatar
Jens Axboe committed
191
static u8 hpt3xx_ratemask (ide_drive_t *drive)
192
{
Jens Axboe's avatar
Jens Axboe committed
193 194
	struct pci_dev *dev	= HWIF(drive)->pci_dev;
	u8 mode			= 0;
195 196

	if (hpt_minimum_revision(dev, 8)) {		/* HPT374 */
Jens Axboe's avatar
Jens Axboe committed
197
		mode = (HPT374_ALLOW_ATA133_6) ? 4 : 3;
198
	} else if (hpt_minimum_revision(dev, 7)) {	/* HPT371 */
Jens Axboe's avatar
Jens Axboe committed
199
		mode = (HPT371_ALLOW_ATA133_6) ? 4 : 3;
200
	} else if (hpt_minimum_revision(dev, 6)) {	/* HPT302 */
Jens Axboe's avatar
Jens Axboe committed
201
		mode = (HPT302_ALLOW_ATA133_6) ? 4 : 3;
202
	} else if (hpt_minimum_revision(dev, 5)) {	/* HPT372 */
Jens Axboe's avatar
Jens Axboe committed
203
		mode = (HPT372_ALLOW_ATA133_6) ? 4 : 3;
204
	} else if (hpt_minimum_revision(dev, 4)) {	/* HPT370A */
Jens Axboe's avatar
Jens Axboe committed
205
		mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2;
206
	} else if (hpt_minimum_revision(dev, 3)) {	/* HPT370 */
Jens Axboe's avatar
Jens Axboe committed
207 208 209 210
		mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2;
		mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : mode;
	} else {				/* HPT366 and HPT368 */
		mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : 2;
211
	}
Jens Axboe's avatar
Jens Axboe committed
212 213 214
	if (!eighty_ninty_three(drive) && (mode))
		mode = min(mode, (u8)1);
	return mode;
215 216
}

Jens Axboe's avatar
Jens Axboe committed
217
static u8 hpt3xx_ratefilter (ide_drive_t *drive, u8 speed)
218 219 220
{
#ifdef CONFIG_BLK_DEV_IDEDMA
	struct pci_dev *dev	= HWIF(drive)->pci_dev;
Jens Axboe's avatar
Jens Axboe committed
221
	u8 mode			= hpt3xx_ratemask(drive);
222 223

	if (drive->media != ide_disk)
Jens Axboe's avatar
Jens Axboe committed
224
		return min(speed, (u8)XFER_PIO_4);
225 226 227

	switch(mode) {
		case 0x04:
Jens Axboe's avatar
Jens Axboe committed
228
			speed = min(speed, (u8)XFER_UDMA_6);
229 230
			break;
		case 0x03:
Jens Axboe's avatar
Jens Axboe committed
231
			speed = min(speed, (u8)XFER_UDMA_5);
232 233 234
			if (hpt_minimum_revision(dev, 5))
				break;
			if (check_in_drive_lists(drive, bad_ata100_5))
Jens Axboe's avatar
Jens Axboe committed
235
				speed = min(speed, (u8)XFER_UDMA_4);
236 237
			break;
		case 0x02:
Jens Axboe's avatar
Jens Axboe committed
238
			speed = min(speed, (u8)XFER_UDMA_4);
239 240 241 242 243 244 245
	/*
	 * CHECK ME, Does this need to be set to 5 ??
	 */
			if (hpt_minimum_revision(dev, 3))
				break;
			if ((check_in_drive_lists(drive, bad_ata66_4)) ||
			    (!(HPT366_ALLOW_ATA66_4)))
Jens Axboe's avatar
Jens Axboe committed
246
				speed = min(speed, (u8)XFER_UDMA_3);
247 248
			if ((check_in_drive_lists(drive, bad_ata66_3)) ||
			    (!(HPT366_ALLOW_ATA66_3)))
Jens Axboe's avatar
Jens Axboe committed
249
				speed = min(speed, (u8)XFER_UDMA_2);
250 251
			break;
		case 0x01:
Jens Axboe's avatar
Jens Axboe committed
252
			speed = min(speed, (u8)XFER_UDMA_2);
253 254 255 256 257 258
	/*
	 * CHECK ME, Does this need to be set to 5 ??
	 */
			if (hpt_minimum_revision(dev, 3))
				break;
			if (check_in_drive_lists(drive, bad_ata33))
Jens Axboe's avatar
Jens Axboe committed
259
				speed = min(speed, (u8)XFER_MW_DMA_2);
260 261
			break;
		case 0x00:
Jens Axboe's avatar
Jens Axboe committed
262 263
		default:
			speed = min(speed, (u8)XFER_MW_DMA_2);
264 265
			break;
	}
Jens Axboe's avatar
Jens Axboe committed
266
	return speed;
267
#else
Jens Axboe's avatar
Jens Axboe committed
268
	return min(speed, (u8)XFER_PIO_4);
269 270 271 272 273 274 275 276
#endif /* CONFIG_BLK_DEV_IDEDMA */
}

static int check_in_drive_lists (ide_drive_t *drive, const char **list)
{
	struct hd_driveid *id = drive->id;

	if (quirk_drives == list) {
Jens Axboe's avatar
Jens Axboe committed
277 278
		while (*list)
			if (strstr(id->model, *list++))
279 280
				return 1;
	} else {
Jens Axboe's avatar
Jens Axboe committed
281 282
		while (*list)
			if (!strcmp(*list++,id->model))
283 284 285 286 287
				return 1;
	}
	return 0;
}

Jens Axboe's avatar
Jens Axboe committed
288
static unsigned int pci_bus_clock_list (u8 speed, struct chipset_bus_clock_list_entry * chipset_table)
289 290
{
	for ( ; chipset_table->xfer_speed ; chipset_table++)
Jens Axboe's avatar
Jens Axboe committed
291
		if (chipset_table->xfer_speed == speed)
292 293 294 295
			return chipset_table->chipset_settings;
	return chipset_table->chipset_settings;
}

Jens Axboe's avatar
Jens Axboe committed
296
static void hpt366_tune_chipset (ide_drive_t *drive, u8 xferspeed)
297 298
{
	struct pci_dev *dev	= HWIF(drive)->pci_dev;
Jens Axboe's avatar
Jens Axboe committed
299 300 301 302 303 304
	u8 speed		= hpt3xx_ratefilter(drive, xferspeed);
//	u8 speed	= ide_rate_filter(hpt3xx_ratemask(drive), xferspeed);
	u8 regtime		= (drive->select.b.unit & 0x01) ? 0x44 : 0x40;
	u8 regfast		= (HWIF(drive)->channel) ? 0x55 : 0x51;
	u8 drive_fast		= 0;
	u32 reg1 = 0, reg2	= 0;
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334

	/*
	 * Disable the "fast interrupt" prediction.
	 */
	pci_read_config_byte(dev, regfast, &drive_fast);
#if 0
	if (drive_fast & 0x02)
		pci_write_config_byte(dev, regfast, drive_fast & ~0x20);
#else
	if (drive_fast & 0x80)
		pci_write_config_byte(dev, regfast, drive_fast & ~0x80);
#endif

	reg2 = pci_bus_clock_list(speed,
		(struct chipset_bus_clock_list_entry *) dev->driver_data);
	/*
	 * Disable on-chip PIO FIFO/buffer
	 *  (to avoid problems handling I/O errors later)
	 */
	pci_read_config_dword(dev, regtime, &reg1);
	if (speed >= XFER_MW_DMA_0) {
		reg2 = (reg2 & ~0xc0000000) | (reg1 & 0xc0000000);
	} else {
		reg2 = (reg2 & ~0x30070000) | (reg1 & 0x30070000);
	}	
	reg2 &= ~0x80000000;

	pci_write_config_dword(dev, regtime, reg2);
}

Jens Axboe's avatar
Jens Axboe committed
335
static void hpt368_tune_chipset (ide_drive_t *drive, u8 speed)
336 337 338 339
{
	hpt366_tune_chipset(drive, speed);
}

Jens Axboe's avatar
Jens Axboe committed
340
static void hpt370_tune_chipset (ide_drive_t *drive, u8 xferspeed)
341
{
Jens Axboe's avatar
Jens Axboe committed
342 343 344 345 346 347 348 349
	struct pci_dev *dev = HWIF(drive)->pci_dev;
	u8 speed	= hpt3xx_ratefilter(drive, xferspeed);
//	u8 speed	= ide_rate_filter(hpt3xx_ratemask(drive), xferspeed);
	u8 regfast	= (HWIF(drive)->channel) ? 0x55 : 0x51;
	u8 drive_pci	= 0x40 + (drive->dn * 4);
	u8 new_fast	= 0, drive_fast = 0;
	u32 list_conf	= 0, drive_conf = 0;
	u32 conf_mask	= (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000;
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383

	/*
	 * Disable the "fast interrupt" prediction.
	 * don't holdoff on interrupts. (== 0x01 despite what the docs say) 
	 */
	pci_read_config_byte(dev, regfast, &drive_fast);
	new_fast = drive_fast;
	if (new_fast & 0x02)
		new_fast &= ~0x02;

#ifdef HPT_DELAY_INTERRUPT
	if (new_fast & 0x01)
		new_fast &= ~0x01;
#else
	if ((new_fast & 0x01) == 0)
		new_fast |= 0x01;
#endif
	if (new_fast != drive_fast)
		pci_write_config_byte(dev, regfast, new_fast);

	list_conf = pci_bus_clock_list(speed, 
				       (struct chipset_bus_clock_list_entry *)
				       dev->driver_data);

	pci_read_config_dword(dev, drive_pci, &drive_conf);
	list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask);
	
	if (speed < XFER_MW_DMA_0) {
		list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
	}

	pci_write_config_dword(dev, drive_pci, list_conf);
}

Jens Axboe's avatar
Jens Axboe committed
384
static void hpt372_tune_chipset (ide_drive_t *drive, u8 xferspeed)
385 386
{
	struct pci_dev *dev	= HWIF(drive)->pci_dev;
Jens Axboe's avatar
Jens Axboe committed
387 388 389 390 391 392
	u8 speed	= hpt3xx_ratefilter(drive, xferspeed);
//	u8 speed	= ide_rate_filter(hpt3xx_ratemask(drive), xferspeed);
	u8 regfast	= (HWIF(drive)->channel) ? 0x55 : 0x51;
	u8 drive_fast	= 0, drive_pci = 0x40 + (drive->dn * 4);
	u32 list_conf	= 0, drive_conf = 0;
	u32 conf_mask	= (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000;
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411

	/*
	 * Disable the "fast interrupt" prediction.
	 * don't holdoff on interrupts. (== 0x01 despite what the docs say)
	 */
	pci_read_config_byte(dev, regfast, &drive_fast);
	drive_fast &= ~0x07;
	pci_write_config_byte(dev, regfast, drive_fast);
					
	list_conf = pci_bus_clock_list(speed,
			(struct chipset_bus_clock_list_entry *)
					dev->driver_data);
	pci_read_config_dword(dev, drive_pci, &drive_conf);
	list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask);
	if (speed < XFER_MW_DMA_0)
		list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
	pci_write_config_dword(dev, drive_pci, list_conf);
}

Jens Axboe's avatar
Jens Axboe committed
412
static void hpt374_tune_chipset (ide_drive_t *drive, u8 speed)
413 414 415 416
{
	hpt372_tune_chipset(drive, speed);
}

Jens Axboe's avatar
Jens Axboe committed
417
static int hpt3xx_tune_chipset (ide_drive_t *drive, u8 speed)
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
{
	struct pci_dev *dev	= HWIF(drive)->pci_dev;

	if (hpt_minimum_revision(dev, 8))
		hpt374_tune_chipset(drive, speed);
#if 0
	else if (hpt_minimum_revision(dev, 7))
		hpt371_tune_chipset(drive, speed);
	else if (hpt_minimum_revision(dev, 6))
		hpt302_tune_chipset(drive, speed);
#endif
	else if (hpt_minimum_revision(dev, 5))
		hpt372_tune_chipset(drive, speed);
	else if (hpt_minimum_revision(dev, 3))
		hpt370_tune_chipset(drive, speed);
	else if (hpt_minimum_revision(dev, 2))
		hpt368_tune_chipset(drive, speed);
	else
                hpt366_tune_chipset(drive, speed);

	return ((int) ide_config_drive_speed(drive, speed));
}

Jens Axboe's avatar
Jens Axboe committed
441
static void hpt3xx_tune_drive (ide_drive_t *drive, u8 pio)
442 443
{
	pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
Jens Axboe's avatar
Jens Axboe committed
444
	(void) hpt3xx_tune_chipset(drive, (XFER_PIO_0 + pio));
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
}

#ifdef CONFIG_BLK_DEV_IDEDMA
/*
 * This allows the configuration of ide_pci chipset registers
 * for cards that learn about the drive's UDMA, DMA, PIO capabilities
 * after the drive is reported by the OS.  Initally for designed for
 * HPT366 UDMA chipset by HighPoint|Triones Technologies, Inc.
 *
 * check_in_drive_lists(drive, bad_ata66_4)
 * check_in_drive_lists(drive, bad_ata66_3)
 * check_in_drive_lists(drive, bad_ata33)
 *
 */
static int config_chipset_for_dma (ide_drive_t *drive)
{
Jens Axboe's avatar
Jens Axboe committed
461
	u8 speed = ide_dma_speed(drive, hpt3xx_ratemask(drive));
462

Jens Axboe's avatar
Jens Axboe committed
463 464
	if (!(speed))
		return 0;
465 466

	(void) hpt3xx_tune_chipset(drive, speed);
Jens Axboe's avatar
Jens Axboe committed
467
	return ide_dma_enable(drive);
468 469
}

Jens Axboe's avatar
Jens Axboe committed
470
static int hpt3xx_quirkproc (ide_drive_t *drive)
471 472 473 474
{
	return ((int) check_in_drive_lists(drive, quirk_drives));
}

Jens Axboe's avatar
Jens Axboe committed
475
static void hpt3xx_intrproc (ide_drive_t *drive)
476
{
Jens Axboe's avatar
Jens Axboe committed
477 478
	ide_hwif_t *hwif = HWIF(drive);

479 480 481
	if (drive->quirk_list)
		return;
	/* drives in the quirk_list may not like intr setups/cleanups */
Jens Axboe's avatar
Jens Axboe committed
482
	hwif->OUTB(drive->ctl|2, IDE_CONTROL_REG);
483 484
}

Jens Axboe's avatar
Jens Axboe committed
485
static void hpt3xx_maskproc (ide_drive_t *drive, int mask)
486 487 488 489 490
{
	struct pci_dev *dev = HWIF(drive)->pci_dev;

	if (drive->quirk_list) {
		if (hpt_minimum_revision(dev,3)) {
Jens Axboe's avatar
Jens Axboe committed
491
			u8 reg5a = 0;
492 493 494 495 496 497 498 499 500 501 502 503
			pci_read_config_byte(dev, 0x5a, &reg5a);
			if (((reg5a & 0x10) >> 4) != mask)
				pci_write_config_byte(dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10));
		} else {
			if (mask) {
				disable_irq(HWIF(drive)->irq);
			} else {
				enable_irq(HWIF(drive)->irq);
			}
		}
	} else {
		if (IDE_CONTROL_REG)
Jens Axboe's avatar
Jens Axboe committed
504 505 506
			HWIF(drive)->OUTB(mask ? (drive->ctl | 2) :
						 (drive->ctl & ~2),
						 IDE_CONTROL_REG);
507 508 509
	}
}

Jens Axboe's avatar
Jens Axboe committed
510
static int hpt366_config_drive_xfer_rate (ide_drive_t *drive)
511
{
Jens Axboe's avatar
Jens Axboe committed
512 513
	ide_hwif_t *hwif	= HWIF(drive);
	struct hd_driveid *id	= drive->id;
514 515 516

	drive->init_speed = 0;

Jens Axboe's avatar
Jens Axboe committed
517
	if (id && (id->capability & 1) && drive->autodma) {
518
		/* Consult the list of known "bad" drives */
Jens Axboe's avatar
Jens Axboe committed
519
		if (hwif->ide_dma_bad_drive(drive))
520 521
			goto fast_ata_pio;
		if (id->field_valid & 4) {
Jens Axboe's avatar
Jens Axboe committed
522
			if (id->dma_ultra & hwif->ultra_mask) {
523
				/* Force if Capable UltraDMA */
Jens Axboe's avatar
Jens Axboe committed
524 525
				int dma = config_chipset_for_dma(drive);
				if ((id->field_valid & 2) && !dma)
526 527 528 529
					goto try_dma_modes;
			}
		} else if (id->field_valid & 2) {
try_dma_modes:
Jens Axboe's avatar
Jens Axboe committed
530
			if (id->dma_mword & hwif->mwdma_mask) {
531
				/* Force if Capable regular DMA modes */
Jens Axboe's avatar
Jens Axboe committed
532
				if (!config_chipset_for_dma(drive))
533 534
					goto no_dma_set;
			}
Jens Axboe's avatar
Jens Axboe committed
535 536
		} else if (hwif->ide_dma_good_drive(drive) &&
			   (id->eide_dma_time < 150)) {
537
			/* Consult the list of known "good" drives */
Jens Axboe's avatar
Jens Axboe committed
538
			if (!config_chipset_for_dma(drive))
539 540 541 542 543 544 545 546
				goto no_dma_set;
		} else {
			goto fast_ata_pio;
		}
	} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
		hpt3xx_tune_drive(drive, 5);
Jens Axboe's avatar
Jens Axboe committed
547
		return hwif->ide_dma_off_quietly(drive);
548
	}
Jens Axboe's avatar
Jens Axboe committed
549
	return hwif->ide_dma_on(drive);
550 551 552 553 554 555
}

/*
 * This is specific to the HPT366 UDMA bios chipset
 * by HighPoint|Triones Technologies, Inc.
 */
Jens Axboe's avatar
Jens Axboe committed
556
static int hpt366_ide_dma_lostirq (ide_drive_t *drive)
557 558
{
	struct pci_dev *dev	= HWIF(drive)->pci_dev;
Jens Axboe's avatar
Jens Axboe committed
559 560 561 562 563 564 565 566 567
	u8 reg50h = 0, reg52h = 0, reg5ah = 0;

	pci_read_config_byte(dev, 0x50, &reg50h);
	pci_read_config_byte(dev, 0x52, &reg52h);
	pci_read_config_byte(dev, 0x5a, &reg5ah);
	printk("%s: (%s)  reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n",
		drive->name, __FUNCTION__, reg50h, reg52h, reg5ah);
	if (reg5ah & 0x10)
		pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10);
568
#if 0
Jens Axboe's avatar
Jens Axboe committed
569 570 571 572 573 574 575
	/* how about we flush and reset, mmmkay? */
	pci_write_config_byte(dev, 0x51, 0x1F);
	/* fall through to a reset */
	case ide_dma_begin:
	case ide_dma_end:
	/* reset the chips state over and over.. */
	pci_write_config_byte(dev, 0x51, 0x13);
576
#endif
Jens Axboe's avatar
Jens Axboe committed
577
	return __ide_dma_lostirq(drive);
578 579
}

Jens Axboe's avatar
Jens Axboe committed
580
static void hpt370_clear_engine (ide_drive_t *drive)
581
{
Jens Axboe's avatar
Jens Axboe committed
582 583 584 585
	u8 regstate = HWIF(drive)->channel ? 0x54 : 0x50;
	pci_write_config_byte(HWIF(drive)->pci_dev, regstate, 0x37);
	udelay(10);
}
586

Jens Axboe's avatar
Jens Axboe committed
587 588
static int hpt370_ide_dma_begin (ide_drive_t *drive)
{
589
#ifdef HPT_RESET_STATE_ENGINE
Jens Axboe's avatar
Jens Axboe committed
590
	hpt370_clear_engine(drive);
591
#endif
Jens Axboe's avatar
Jens Axboe committed
592 593
	return __ide_dma_begin(drive);
}
594

Jens Axboe's avatar
Jens Axboe committed
595 596 597 598 599 600 601 602 603
static int hpt370_ide_dma_end (ide_drive_t *drive)
{
	ide_hwif_t *hwif	= HWIF(drive);
	u8 dma_stat		= hwif->INB(hwif->dma_status);

	if (dma_stat & 0x01) {
		/* wait a little */
		udelay(20);
		dma_stat = hwif->INB(hwif->dma_status);
604
	}
Jens Axboe's avatar
Jens Axboe committed
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
	if ((dma_stat & 0x01) != 0) 
		/* fallthrough */
		(void) HWIF(drive)->ide_dma_timeout(drive);

	return __ide_dma_end(drive);
}

static void hpt370_lostirq_timeout (ide_drive_t *drive)
{
	ide_hwif_t *hwif	= HWIF(drive);
	u8 bfifo = 0, reginfo	= hwif->channel ? 0x56 : 0x52;
	u8 dma_stat = 0, dma_cmd = 0;

	pci_read_config_byte(HWIF(drive)->pci_dev, reginfo, &bfifo);
	printk("%s: %d bytes in FIFO\n", drive->name, bfifo);
	hpt370_clear_engine(drive);
	/* get dma command mode */
	dma_cmd = hwif->INB(hwif->dma_command);
	/* stop dma */
	hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command);
	dma_stat = hwif->INB(hwif->dma_status);
	/* clear errors */
	hwif->OUTB(dma_stat | 0x6, hwif->dma_status);
628 629
}

Jens Axboe's avatar
Jens Axboe committed
630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
static int hpt370_ide_dma_timeout (ide_drive_t *drive)
{
	hpt370_lostirq_timeout(drive);
	hpt370_clear_engine(drive);
	return __ide_dma_timeout(drive);
}

static int hpt370_ide_dma_lostirq (ide_drive_t *drive)
{
	hpt370_lostirq_timeout(drive);
	hpt370_clear_engine(drive);
	return __ide_dma_lostirq(drive);
}

static int hpt374_ide_dma_end (ide_drive_t *drive)
645 646 647
{
	struct pci_dev *dev	= HWIF(drive)->pci_dev;
	ide_hwif_t *hwif	= HWIF(drive);
Jens Axboe's avatar
Jens Axboe committed
648 649 650 651 652 653 654 655
	u8 msc_stat = 0, mscreg	= hwif->channel ? 0x54 : 0x50;
	u8 bwsr_stat = 0, bwsr_mask = hwif->channel ? 0x02 : 0x01;

	pci_read_config_byte(dev, 0x6a, &bwsr_stat);
	pci_read_config_byte(dev, mscreg, &msc_stat);
	if ((bwsr_stat & bwsr_mask) == bwsr_mask)
		pci_write_config_byte(dev, mscreg, msc_stat|0x30);
	return __ide_dma_end(drive);
656 657 658 659 660 661 662 663
}
#endif /* CONFIG_BLK_DEV_IDEDMA */

/*
 * Since SUN Cobalt is attempting to do this operation, I should disclose
 * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date
 * HOTSWAP ATA Infrastructure.
 */
Jens Axboe's avatar
Jens Axboe committed
664 665

static void hpt3xx_reset (ide_drive_t *drive)
666 667
{
#if 0
Jens Axboe's avatar
Jens Axboe committed
668 669 670
	u32 high_16	= pci_resource_start(HWIF(drive)->pci_dev, 4);
	u8 reset	= (HWIF(drive)->channel) ? 0x80 : 0x40;
	u8 reg59h	= 0;
671 672 673 674 675 676 677 678 679 680 681

	pci_read_config_byte(HWIF(drive)->pci_dev, 0x59, &reg59h);
	pci_write_config_byte(HWIF(drive)->pci_dev, 0x59, reg59h|reset);
	pci_write_config_byte(HWIF(drive)->pci_dev, 0x59, reg59h);
#endif
}

static int hpt3xx_tristate (ide_drive_t * drive, int state)
{
	ide_hwif_t *hwif	= HWIF(drive);
	struct pci_dev *dev	= hwif->pci_dev;
Jens Axboe's avatar
Jens Axboe committed
682 683
	u8 reg59h = 0, reset	= (hwif->channel) ? 0x80 : 0x40;
	u8 regXXh = 0, state_reg= (hwif->channel) ? 0x57 : 0x53;
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717

	if (!hwif)
		return -EINVAL;

//	hwif->bus_state = state;

	pci_read_config_byte(dev, 0x59, &reg59h);
	pci_read_config_byte(dev, state_reg, &regXXh);

	if (state) {
		(void) ide_do_reset(drive);
		pci_write_config_byte(dev, state_reg, regXXh|0x80);
		pci_write_config_byte(dev, 0x59, reg59h|reset);
	} else {
		pci_write_config_byte(dev, 0x59, reg59h & ~(reset));
		pci_write_config_byte(dev, state_reg, regXXh & ~(0x80));
		(void) ide_do_reset(drive);
	}
	return 0;
}

/* 
 * set/get power state for a drive.
 * turning the power off does the following things:
 *   1) soft-reset the drive
 *   2) tri-states the ide bus
 *
 * when we turn things back on, we need to re-initialize things.
 */
#define TRISTATE_BIT  0x8000
static int hpt370_busproc(ide_drive_t * drive, int state)
{
	ide_hwif_t *hwif	= HWIF(drive);
	struct pci_dev *dev	= hwif->pci_dev;
Jens Axboe's avatar
Jens Axboe committed
718
	u8 tristate = 0, resetmask = 0, bus_reg = 0;
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 764 765 766 767 768 769 770 771 772 773
	u16 tri_reg;

	if (!hwif)
		return -EINVAL;

	hwif->bus_state = state;

	if (hwif->channel) { 
		/* secondary channel */
		tristate = 0x56;
		resetmask = 0x80; 
	} else { 
		/* primary channel */
		tristate = 0x52;
		resetmask = 0x40;
	}

	/* grab status */
	pci_read_config_word(dev, tristate, &tri_reg);
	pci_read_config_byte(dev, 0x59, &bus_reg);

	/* set the state. we don't set it if we don't need to do so.
	 * make sure that the drive knows that it has failed if it's off */
	switch (state) {
	case BUSSTATE_ON:
		hwif->drives[0].failures = 0;
		hwif->drives[1].failures = 0;
		if ((bus_reg & resetmask) == 0)
			return 0;
		tri_reg &= ~TRISTATE_BIT;
		bus_reg &= ~resetmask;
		break;
	case BUSSTATE_OFF:
		hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
		hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
		if ((tri_reg & TRISTATE_BIT) == 0 && (bus_reg & resetmask))
			return 0;
		tri_reg &= ~TRISTATE_BIT;
		bus_reg |= resetmask;
		break;
	case BUSSTATE_TRISTATE:
		hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
		hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
		if ((tri_reg & TRISTATE_BIT) && (bus_reg & resetmask))
			return 0;
		tri_reg |= TRISTATE_BIT;
		bus_reg |= resetmask;
		break;
	}
	pci_write_config_byte(dev, 0x59, bus_reg);
	pci_write_config_word(dev, tristate, tri_reg);

	return 0;
}

Jens Axboe's avatar
Jens Axboe committed
774
static int __init init_hpt37x(struct pci_dev *dev)
775 776 777 778
{
	int adjust, i;
	u16 freq;
	u32 pll;
Jens Axboe's avatar
Jens Axboe committed
779
	u8 reg5bh;
780 781

#if 1
Jens Axboe's avatar
Jens Axboe committed
782
	u8 reg5ah = 0;
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802
	pci_read_config_byte(dev, 0x5a, &reg5ah);
	/* interrupt force enable */
	pci_write_config_byte(dev, 0x5a, (reg5ah & ~0x10));
#endif

	/*
	 * default to pci clock. make sure MA15/16 are set to output
	 * to prevent drives having problems with 40-pin cables.
	 */
	pci_write_config_byte(dev, 0x5b, 0x23);

	/*
	 * set up the PLL. we need to adjust it so that it's stable. 
	 * freq = Tpll * 192 / Tpci
	 */
	pci_read_config_word(dev, 0x78, &freq);
	freq &= 0x1FF;
	if (freq < 0x9c) {
		pll = F_LOW_PCI_33;
		if (hpt_minimum_revision(dev,8))
Jens Axboe's avatar
Jens Axboe committed
803
			pci_set_drvdata(dev, (void *) thirty_three_base_hpt374);
804
		else if (hpt_minimum_revision(dev,5))
Jens Axboe's avatar
Jens Axboe committed
805
			pci_set_drvdata(dev, (void *) thirty_three_base_hpt372);
806
		else if (hpt_minimum_revision(dev,4))
Jens Axboe's avatar
Jens Axboe committed
807
			pci_set_drvdata(dev, (void *) thirty_three_base_hpt370a);
808
		else
Jens Axboe's avatar
Jens Axboe committed
809
			pci_set_drvdata(dev, (void *) thirty_three_base_hpt370);
810 811 812 813 814 815
		printk("HPT37X: using 33MHz PCI clock\n");
	} else if (freq < 0xb0) {
		pll = F_LOW_PCI_40;
	} else if (freq < 0xc8) {
		pll = F_LOW_PCI_50;
		if (hpt_minimum_revision(dev,8))
Jens Axboe's avatar
Jens Axboe committed
816
			return -EOPNOTSUPP;
817
		else if (hpt_minimum_revision(dev,5))
Jens Axboe's avatar
Jens Axboe committed
818
			pci_set_drvdata(dev, (void *) fifty_base_hpt372);
819
		else if (hpt_minimum_revision(dev,4))
Jens Axboe's avatar
Jens Axboe committed
820
			pci_set_drvdata(dev, (void *) fifty_base_hpt370a);
821
		else
Jens Axboe's avatar
Jens Axboe committed
822
			pci_set_drvdata(dev, (void *) fifty_base_hpt370a);
823 824 825 826
		printk("HPT37X: using 50MHz PCI clock\n");
	} else {
		pll = F_LOW_PCI_66;
		if (hpt_minimum_revision(dev,8))
Jens Axboe's avatar
Jens Axboe committed
827
			return -EOPNOTSUPP;
828
		else if (hpt_minimum_revision(dev,5))
Jens Axboe's avatar
Jens Axboe committed
829
			pci_set_drvdata(dev, (void *) sixty_six_base_hpt372);
830
		else if (hpt_minimum_revision(dev,4))
Jens Axboe's avatar
Jens Axboe committed
831
			pci_set_drvdata(dev, (void *) sixty_six_base_hpt370a);
832
		else
Jens Axboe's avatar
Jens Axboe committed
833
			pci_set_drvdata(dev, (void *) sixty_six_base_hpt370);
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
		printk("HPT37X: using 66MHz PCI clock\n");
	}
	
	/*
	 * only try the pll if we don't have a table for the clock
	 * speed that we're running at. NOTE: the internal PLL will
	 * result in slow reads when using a 33MHz PCI clock. we also
	 * don't like to use the PLL because it will cause glitches
	 * on PRST/SRST when the HPT state engine gets reset.
	 */
	if (dev->driver_data) 
		goto init_hpt37X_done;
	
	/*
	 * adjust PLL based upon PCI clock, enable it, and wait for
	 * stabilization.
	 */
	adjust = 0;
	freq = (pll < F_LOW_PCI_50) ? 2 : 4;
	while (adjust++ < 6) {
		pci_write_config_dword(dev, 0x5c, (freq + pll) << 16 |
				       pll | 0x100);

		/* wait for clock stabilization */
		for (i = 0; i < 0x50000; i++) {
			pci_read_config_byte(dev, 0x5b, &reg5bh);
			if (reg5bh & 0x80) {
				/* spin looking for the clock to destabilize */
				for (i = 0; i < 0x1000; ++i) {
					pci_read_config_byte(dev, 0x5b, 
							     &reg5bh);
					if ((reg5bh & 0x80) == 0)
						goto pll_recal;
				}
				pci_read_config_dword(dev, 0x5c, &pll);
				pci_write_config_dword(dev, 0x5c, 
						       pll & ~0x100);
				pci_write_config_byte(dev, 0x5b, 0x21);
				if (hpt_minimum_revision(dev,8))
Jens Axboe's avatar
Jens Axboe committed
873
					return -EOPNOTSUPP;
874
				else if (hpt_minimum_revision(dev,5))
Jens Axboe's avatar
Jens Axboe committed
875
					pci_set_drvdata(dev, (void *) fifty_base_hpt372);
876
				else if (hpt_minimum_revision(dev,4))
Jens Axboe's avatar
Jens Axboe committed
877
					pci_set_drvdata(dev, (void *) fifty_base_hpt370a);
878
				else
Jens Axboe's avatar
Jens Axboe committed
879
					pci_set_drvdata(dev, (void *) fifty_base_hpt370a);
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895
				printk("HPT37X: using 50MHz internal PLL\n");
				goto init_hpt37X_done;
			}
		}
pll_recal:
		if (adjust & 1)
			pll -= (adjust >> 1);
		else
			pll += (adjust >> 1);
	} 

init_hpt37X_done:
	/* reset state engine */
	pci_write_config_byte(dev, 0x50, 0x37); 
	pci_write_config_byte(dev, 0x54, 0x37); 
	udelay(100);
Jens Axboe's avatar
Jens Axboe committed
896
	return 0;
897 898
}

Jens Axboe's avatar
Jens Axboe committed
899
static int __init init_hpt366 (struct pci_dev *dev)
900
{
Jens Axboe's avatar
Jens Axboe committed
901 902
	u32 reg1	= 0;
	u8 drive_fast	= 0;
903 904 905 906 907 908 909 910 911 912 913 914

	/*
	 * Disable the "fast interrupt" prediction.
	 */
	pci_read_config_byte(dev, 0x51, &drive_fast);
	if (drive_fast & 0x80)
		pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);
	pci_read_config_dword(dev, 0x40, &reg1);
									
	/* detect bus speed by looking at control reg timing: */
	switch((reg1 >> 8) & 7) {
		case 5:
Jens Axboe's avatar
Jens Axboe committed
915
			pci_set_drvdata(dev, (void *) forty_base_hpt366);
916 917
			break;
		case 9:
Jens Axboe's avatar
Jens Axboe committed
918
			pci_set_drvdata(dev, (void *) twenty_five_base_hpt366);
919 920 921
			break;
		case 7:
		default:
Jens Axboe's avatar
Jens Axboe committed
922
			pci_set_drvdata(dev, (void *) thirty_three_base_hpt366);
923 924 925 926
			break;
	}

	if (!dev->driver_data)
Jens Axboe's avatar
Jens Axboe committed
927 928 929 930 931
	{
		printk(KERN_ERR "hpt366: unknown bus timing.\n");
		return -EOPNOTSUPP;
	}
	return 0;
932 933
}

Jens Axboe's avatar
Jens Axboe committed
934
static unsigned int __init init_chipset_hpt366 (struct pci_dev *dev, const char *name)
935
{
Jens Axboe's avatar
Jens Axboe committed
936 937
	int ret = 0;
	u8 test = 0;
938 939

	if (dev->resource[PCI_ROM_RESOURCE].start)
Jens Axboe's avatar
Jens Axboe committed
940 941
		pci_write_config_byte(dev, PCI_ROM_ADDRESS,
			dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
942 943 944

	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &test);
	if (test != (L1_CACHE_BYTES / 4))
Jens Axboe's avatar
Jens Axboe committed
945 946
		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
			(L1_CACHE_BYTES / 4));
947 948 949 950 951 952 953 954 955 956 957 958 959 960

	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &test);
	if (test != 0x78)
		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);

	pci_read_config_byte(dev, PCI_MIN_GNT, &test);
	if (test != 0x08)
		pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);

	pci_read_config_byte(dev, PCI_MAX_LAT, &test);
	if (test != 0x08)
		pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);

	if (hpt_minimum_revision(dev, 3)) {
Jens Axboe's avatar
Jens Axboe committed
961
		ret = init_hpt37x(dev);
962
	} else {
Jens Axboe's avatar
Jens Axboe committed
963
		ret =init_hpt366(dev);
964
	}
Jens Axboe's avatar
Jens Axboe committed
965 966
	if (ret)
		return ret;
967 968
	
#if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
Jens Axboe's avatar
Jens Axboe committed
969 970
	hpt_devs[n_hpt_devs++] = dev;

971 972
	if (!hpt366_proc) {
		hpt366_proc = 1;
Jens Axboe's avatar
Jens Axboe committed
973
		ide_pci_register_host_proc(&hpt366_procs[0]);
974 975 976 977 978 979
	}
#endif /* DISPLAY_HPT366_TIMINGS && CONFIG_PROC_FS */

	return dev->irq;
}

Jens Axboe's avatar
Jens Axboe committed
980
static void __init init_hwif_hpt366 (ide_hwif_t *hwif)
981
{
Jens Axboe's avatar
Jens Axboe committed
982 983 984 985 986 987 988 989
	struct pci_dev *dev		= hwif->pci_dev;
	u8 ata66 = 0, regmask		= (hwif->channel) ? 0x01 : 0x02;

	hwif->tuneproc			= &hpt3xx_tune_drive;
	hwif->speedproc			= &hpt3xx_tune_chipset;
	hwif->quirkproc			= &hpt3xx_quirkproc;
	hwif->intrproc			= &hpt3xx_intrproc;
	hwif->maskproc			= &hpt3xx_maskproc;
990 991

	pci_read_config_byte(hwif->pci_dev, 0x5a, &ata66);
Jens Axboe's avatar
Jens Axboe committed
992

993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
#ifdef DEBUG
	printk("HPT366: reg5ah=0x%02x ATA-%s Cable Port%d\n",
		ata66, (ata66 & regmask) ? "33" : "66",
		PCI_FUNC(hwif->pci_dev->devfn));
#endif /* DEBUG */

#ifdef HPT_SERIALIZE_IO
	/* serialize access to this device */
	if (hwif->mate)
		hwif->serialized = hwif->mate->serialized = 1;
#endif

	if (hpt_minimum_revision(dev,3)) {
Jens Axboe's avatar
Jens Axboe committed
1006
		u8 reg5ah = 0;
1007 1008 1009 1010 1011 1012 1013 1014
			pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10);
		/*
		 * set up ioctl for power status.
		 * note: power affects both
		 * drives on each channel
		 */
		hwif->resetproc	= &hpt3xx_reset;
		hwif->busproc	= &hpt370_busproc;
Jens Axboe's avatar
Jens Axboe committed
1015
//		hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
1016 1017 1018 1019 1020 1021 1022 1023
	} else if (hpt_minimum_revision(dev,2)) {
		hwif->resetproc	= &hpt3xx_reset;
		hwif->busproc	= &hpt3xx_tristate;
	} else {
		hwif->resetproc = &hpt3xx_reset;
		hwif->busproc   = &hpt3xx_tristate;
	}

Jens Axboe's avatar
Jens Axboe committed
1024 1025 1026
	if (!hwif->dma_base) {
		hwif->drives[0].autotune = 1;
		hwif->drives[1].autotune = 1;
1027
		return;
Jens Axboe's avatar
Jens Axboe committed
1028 1029 1030 1031
	}

	hwif->ultra_mask = 0x7f;
	hwif->mwdma_mask = 0x07;
1032 1033

#ifdef CONFIG_BLK_DEV_IDEDMA
Jens Axboe's avatar
Jens Axboe committed
1034 1035 1036 1037
	if (!(hwif->udma_four))
		hwif->udma_four = ((ata66 & regmask) ? 0 : 1);
	hwif->ide_dma_check = &hpt366_config_drive_xfer_rate;

1038
	if (hpt_minimum_revision(dev,8))
Jens Axboe's avatar
Jens Axboe committed
1039
		hwif->ide_dma_end = &hpt374_ide_dma_end;
1040
	else if (hpt_minimum_revision(dev,5))
Jens Axboe's avatar
Jens Axboe committed
1041 1042 1043 1044 1045 1046 1047 1048
		hwif->ide_dma_end = &hpt374_ide_dma_end;
	else if (hpt_minimum_revision(dev,3)) {
		hwif->ide_dma_begin = &hpt370_ide_dma_begin;
		hwif->ide_dma_end = &hpt370_ide_dma_end;
		hwif->ide_dma_timeout = &hpt370_ide_dma_timeout;
		hwif->ide_dma_lostirq = &hpt370_ide_dma_lostirq;
	} else if (hpt_minimum_revision(dev,2))
		hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq;
1049
	else
Jens Axboe's avatar
Jens Axboe committed
1050
		hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq;
1051 1052 1053

	if (!noautodma)
		hwif->autodma = 1;
Jens Axboe's avatar
Jens Axboe committed
1054 1055
	hwif->drives[0].autodma = hwif->autodma;
	hwif->drives[1].autodma = hwif->autodma;
1056 1057 1058
#endif /* CONFIG_BLK_DEV_IDEDMA */
}

Jens Axboe's avatar
Jens Axboe committed
1059
static void __init init_dma_hpt366 (ide_hwif_t *hwif, unsigned long dmabase)
1060
{
Jens Axboe's avatar
Jens Axboe committed
1061 1062 1063 1064
	u8 masterdma	= 0, slavedma = 0;
	u8 dma_new	= 0, dma_old = 0;
	u8 primary	= hwif->channel ? 0x4b : 0x43;
	u8 secondary	= hwif->channel ? 0x4f : 0x47;
1065 1066
	unsigned long flags;

Jens Axboe's avatar
Jens Axboe committed
1067 1068 1069 1070 1071
	if (!dmabase)
		return;

	dma_old = hwif->INB(dmabase+2);

1072 1073 1074 1075 1076 1077 1078 1079
	local_irq_save(flags);

	dma_new = dma_old;
	pci_read_config_byte(hwif->pci_dev, primary, &masterdma);
	pci_read_config_byte(hwif->pci_dev, secondary, &slavedma);

	if (masterdma & 0x30)	dma_new |= 0x20;
	if (slavedma & 0x30)	dma_new |= 0x40;
Jens Axboe's avatar
Jens Axboe committed
1080 1081
	if (dma_new != dma_old)
		hwif->OUTB(dma_new, dmabase+2);
1082 1083 1084 1085 1086 1087

	local_irq_restore(flags);

	ide_setup_dma(hwif, dmabase, 8);
}

Jens Axboe's avatar
Jens Axboe committed
1088 1089
extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
extern void ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, ide_pci_device_t *);
1090

Jens Axboe's avatar
Jens Axboe committed
1091
static void __init init_setup_hpt374 (struct pci_dev *dev, ide_pci_device_t *d)
1092
{
Jens Axboe's avatar
Jens Axboe committed
1093
	struct pci_dev *findev = NULL;
1094 1095 1096 1097 1098 1099 1100 1101 1102

	if (PCI_FUNC(dev->devfn) & 1)
		return;

	pci_for_each_dev(findev) {
		if ((findev->vendor == dev->vendor) &&
		    (findev->device == dev->device) &&
		    ((findev->devfn - dev->devfn) == 1) &&
		    (PCI_FUNC(findev->devfn) & 1)) {
Jens Axboe's avatar
Jens Axboe committed
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
			u8 irq = 0, irq2 = 0;
			pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
			pci_read_config_byte(findev, PCI_INTERRUPT_LINE, &irq2);
			if (irq != irq2) {
				pci_write_config_byte(findev,
						PCI_INTERRUPT_LINE, irq);
				findev->irq = dev->irq;
				printk("%s: pci-config space interrupt "
					"fixed.\n", d->name);
			}
			ide_setup_pci_devices(dev, findev, d);
			return;
1115 1116 1117
		}
	}
	ide_setup_pci_device(dev, d);
Jens Axboe's avatar
Jens Axboe committed
1118
}
1119

Jens Axboe's avatar
Jens Axboe committed
1120 1121 1122
static void __init init_setup_hpt37x (struct pci_dev *dev, ide_pci_device_t *d)
{
	ide_setup_pci_device(dev, d);
1123 1124
}

Jens Axboe's avatar
Jens Axboe committed
1125
static void __init init_setup_hpt366 (struct pci_dev *dev, ide_pci_device_t *d)
1126
{
Jens Axboe's avatar
Jens Axboe committed
1127 1128
	struct pci_dev *findev = NULL;
	u8 pin1 = 0, pin2 = 0;
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143
	unsigned int class_rev;
	char *chipset_names[] = {"HPT366", "HPT366",  "HPT368",
				 "HPT370", "HPT370A", "HPT372"};

	if (PCI_FUNC(dev->devfn) & 1)
		return;

	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
	class_rev &= 0xff;

	strcpy(d->name, chipset_names[class_rev]);

	switch(class_rev) {
		case 5:
		case 4:
Jens Axboe's avatar
Jens Axboe committed
1144
		case 3: ide_setup_pci_device(dev, d);
1145 1146 1147 1148
			return;
		default:	break;
	}

Jens Axboe's avatar
Jens Axboe committed
1149 1150
	d->channels = 1;

1151 1152 1153 1154 1155 1156
	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1);
	pci_for_each_dev(findev) {
		if ((findev->vendor == dev->vendor) &&
		    (findev->device == dev->device) &&
		    ((findev->devfn - dev->devfn) == 1) &&
		    (PCI_FUNC(findev->devfn) & 1)) {
Jens Axboe's avatar
Jens Axboe committed
1157 1158
			pci_read_config_byte(findev, PCI_INTERRUPT_PIN, &pin2);
			if ((pin1 != pin2) && (dev->irq == findev->irq)) {
1159 1160 1161 1162 1163
				d->bootable = ON_BOARD;
				printk("%s: onboard version of chipset, "
					"pin1=%d pin2=%d\n", d->name,
					pin1, pin2);
			}
Jens Axboe's avatar
Jens Axboe committed
1164 1165
			ide_setup_pci_devices(dev, findev, d);
			return;
1166 1167 1168
		}
	}
	ide_setup_pci_device(dev, d);
Jens Axboe's avatar
Jens Axboe committed
1169 1170 1171
}


1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183
/**
 *	hpt366_init_one	-	called when an HPT366 is found
 *	@dev: the hpt366 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 hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
	ide_pci_device_t *d = &hpt366_chipsets[id->driver_data];
Jens Axboe's avatar
Jens Axboe committed
1184

1185 1186 1187
	if (dev->device != d->device)
		BUG();
	d->init_setup(dev, d);
Jens Axboe's avatar
Jens Axboe committed
1188
	return 0;
1189 1190
}

1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
/**
 *	hpt366_remove_one	-	called when an HPT366 is unplugged
 *	@dev: the device that was removed
 *
 *	Disconnect a HPT366 device that has been unplugged either by hotplug
 *	or by a more civilized notification scheme. Not yet supported.
 */
 
static void hpt366_remove_one(struct pci_dev *dev)
{
	panic("HPT366 removal not yet supported");
}

static struct pci_device_id hpt366_pci_tbl[] __devinitdata = {
	{ PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
	{ PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
	{ PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
	{ PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
Jens Axboe's avatar
Jens Axboe committed
1209
	{ PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT374, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237
	{ 0, },
};

static struct pci_driver driver = {
	name:		"HPT366 IDE",
	id_table:	hpt366_pci_tbl,
	probe:		hpt366_init_one,
	remove:		__devexit_p(hpt366_remove_one),
};

static int hpt366_ide_init(void)
{
	return ide_pci_register_driver(&driver);
}

static void hpt366_ide_exit(void)
{
	ide_pci_unregister_driver(&driver);
}

module_init(hpt366_ide_init);
module_exit(hpt366_ide_exit);

MODULE_AUTHOR("Andre Hedrick");
MODULE_DESCRIPTION("PCI driver module for Highpoint HPT366 IDE");
MODULE_LICENSE("GPL");

EXPORT_NO_SYMBOLS;