it8213.c 8.4 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * ITE 8213 IDE driver
 *
 * Copyright (C) 2006 Jack Lee
 * Copyright (C) 2006 Alan Cox
 * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
 */

J
Jack Lee 已提交
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/init.h>

#include <asm/io.h>

/*
 *	it8213_ratemask	-	Compute available modes
 *	@drive: IDE drive
 *
 *	Compute the available speeds for the devices on the interface. This
25
 *	is all modes to ATA133 clipped by drive cable setup.
J
Jack Lee 已提交
26 27 28 29 30 31
 */

static u8 it8213_ratemask (ide_drive_t *drive)
{
	u8 mode	= 4;
	if (!eighty_ninty_three(drive))
32
		mode = min_t(u8, mode, 1);
J
Jack Lee 已提交
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
	return mode;
}

/**
 *	it8213_dma_2_pio		-	return the PIO mode matching DMA
 *	@xfer_rate: transfer speed
 *
 *	Returns the nearest equivalent PIO timing for the PIO or DMA
 *	mode requested by the controller.
 */

static u8 it8213_dma_2_pio (u8 xfer_rate) {
	switch(xfer_rate) {
		case XFER_UDMA_6:
		case XFER_UDMA_5:
		case XFER_UDMA_4:
		case XFER_UDMA_3:
		case XFER_UDMA_2:
		case XFER_UDMA_1:
		case XFER_UDMA_0:
		case XFER_MW_DMA_2:
		case XFER_PIO_4:
			return 4;
		case XFER_MW_DMA_1:
		case XFER_PIO_3:
			return 3;
		case XFER_SW_DMA_2:
		case XFER_PIO_2:
			return 2;
		case XFER_MW_DMA_0:
		case XFER_SW_DMA_1:
		case XFER_SW_DMA_0:
		case XFER_PIO_1:
		case XFER_PIO_0:
		case XFER_PIO_SLOW:
		default:
			return 0;
	}
}

/*
 *	it8213_tuneproc	-	tune a drive
 *	@drive: drive to tune
76
 *	@pio: desired PIO mode
J
Jack Lee 已提交
77
 *
78
 *	Set the interface PIO mode.
J
Jack Lee 已提交
79 80
 */

81
static void it8213_tuneproc (ide_drive_t *drive, u8 pio)
J
Jack Lee 已提交
82 83 84
{
	ide_hwif_t *hwif	= HWIF(drive);
	struct pci_dev *dev	= hwif->pci_dev;
85
	int is_slave		= drive->dn & 1;
J
Jack Lee 已提交
86 87 88 89 90
	int master_port		= 0x40;
	int slave_port		= 0x44;
	unsigned long flags;
	u16 master_data;
	u8 slave_data;
91 92
	static DEFINE_SPINLOCK(tune_lock);
	int control = 0;
J
Jack Lee 已提交
93

94 95 96 97 98 99
	static const u8 timings[][2]= {
					{ 0, 0 },
					{ 0, 0 },
					{ 1, 0 },
					{ 2, 1 },
					{ 2, 3 }, };
J
Jack Lee 已提交
100

101
	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
J
Jack Lee 已提交
102 103 104

	spin_lock_irqsave(&tune_lock, flags);
	pci_read_config_word(dev, master_port, &master_data);
105 106 107 108 109 110 111

	if (pio > 1)
		control |= 1;	/* Programmable timing on */
	if (drive->media != ide_disk)
		control |= 4;	/* ATAPI */
	if (pio > 2)
		control |= 2;	/* IORDY */
J
Jack Lee 已提交
112
	if (is_slave) {
113 114
		master_data |=  0x4000;
		master_data &= ~0x0070;
J
Jack Lee 已提交
115
		if (pio > 1)
116
			master_data = master_data | (control << 4);
J
Jack Lee 已提交
117 118
		pci_read_config_byte(dev, slave_port, &slave_data);
		slave_data = slave_data & 0xf0;
119
		slave_data = slave_data | (timings[pio][0] << 2) | timings[pio][1];
J
Jack Lee 已提交
120
	} else {
121
		master_data &= ~0x3307;
J
Jack Lee 已提交
122
		if (pio > 1)
123
			master_data = master_data | control;
J
Jack Lee 已提交
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
		master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8);
	}
	pci_write_config_word(dev, master_port, master_data);
	if (is_slave)
		pci_write_config_byte(dev, slave_port, slave_data);
	spin_unlock_irqrestore(&tune_lock, flags);
}

/**
 *	it8213_tune_chipset	-	set controller timings
 *	@drive: Drive to set up
 *	@xferspeed: speed we want to achieve
 *
 *	Tune the ITE chipset for the desired mode. If we can't achieve
 *	the desired mode then tune for a lower one, but ultimately
 *	make the thing work.
 */

142
static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed)
J
Jack Lee 已提交
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
{

	ide_hwif_t *hwif	= HWIF(drive);
	struct pci_dev *dev	= hwif->pci_dev;
	u8 maslave		= 0x40;
	u8 speed		= ide_rate_filter(it8213_ratemask(drive), xferspeed);
	int a_speed		= 3 << (drive->dn * 4);
	int u_flag		= 1 << drive->dn;
	int v_flag		= 0x01 << drive->dn;
	int w_flag		= 0x10 << drive->dn;
	int u_speed		= 0;
	u16			reg4042, reg4a;
	u8			reg48, reg54, reg55;

	pci_read_config_word(dev, maslave, &reg4042);
	pci_read_config_byte(dev, 0x48, &reg48);
	pci_read_config_word(dev, 0x4a, &reg4a);
	pci_read_config_byte(dev, 0x54, &reg54);
	pci_read_config_byte(dev, 0x55, &reg55);

	switch(speed) {
		case XFER_UDMA_6:
		case XFER_UDMA_4:
166
		case XFER_UDMA_2:	u_speed = 2 << (drive->dn * 4); break;
J
Jack Lee 已提交
167 168
		case XFER_UDMA_5:
		case XFER_UDMA_3:
169 170
		case XFER_UDMA_1:	u_speed = 1 << (drive->dn * 4); break;
		case XFER_UDMA_0:	u_speed = 0 << (drive->dn * 4); break;
J
Jack Lee 已提交
171 172 173
			break;
		case XFER_MW_DMA_2:
		case XFER_MW_DMA_1:
174
		case XFER_SW_DMA_2:
J
Jack Lee 已提交
175 176 177 178 179 180 181 182 183 184 185
			break;
		case XFER_PIO_4:
		case XFER_PIO_3:
		case XFER_PIO_2:
		case XFER_PIO_1:
		case XFER_PIO_0:
			break;
		default:
			return -1;
	}

186
	if (speed >= XFER_UDMA_0) {
J
Jack Lee 已提交
187 188 189 190 191 192 193 194 195 196
		if (!(reg48 & u_flag))
			pci_write_config_byte(dev, 0x48, reg48 | u_flag);
		if (speed >= XFER_UDMA_5) {
			pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
		} else {
			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
		}

		if ((reg4a & a_speed) != u_speed)
			pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
197
		if (speed > XFER_UDMA_2) {
J
Jack Lee 已提交
198 199 200 201
			if (!(reg54 & v_flag))
				pci_write_config_byte(dev, 0x54, reg54 | v_flag);
		} else
			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
202
	} else {
J
Jack Lee 已提交
203 204 205 206 207 208 209 210
		if (reg48 & u_flag)
			pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
		if (reg4a & a_speed)
			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
		if (reg54 & v_flag)
			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
		if (reg55 & w_flag)
			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
211
	}
J
Jack Lee 已提交
212 213
	it8213_tuneproc(drive, it8213_dma_2_pio(speed));
	return ide_config_drive_speed(drive, speed);
214
}
J
Jack Lee 已提交
215 216 217 218 219 220 221 222 223 224

/*
 *	config_chipset_for_dma	-	configure for DMA
 *	@drive: drive to configure
 *
 *	Called by the IDE layer when it wants the timings set up.
 */

static int config_chipset_for_dma (ide_drive_t *drive)
{
225 226
	u8 speed = ide_dma_speed(drive, it8213_ratemask(drive));

J
Jack Lee 已提交
227
	if (!speed)
228 229
		return 0;

J
Jack Lee 已提交
230
	it8213_tune_chipset(drive, speed);
231

J
Jack Lee 已提交
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
	return ide_dma_enable(drive);
}

/**
 *	it8213_configure_drive_for_dma	-	set up for DMA transfers
 *	@drive: drive we are going to set up
 *
 *	Set up the drive for DMA, tune the controller and drive as
 *	required. If the drive isn't suitable for DMA or we hit
 *	other problems then we will drop down to PIO and set up
 *	PIO appropriately
 */

static int it8213_config_drive_for_dma (ide_drive_t *drive)
{
247
	u8 pio;
248

249 250
	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
		return 0;
J
Jack Lee 已提交
251

252 253
	pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
	it8213_tune_chipset(drive, XFER_PIO_0 + pio);
J
Jack Lee 已提交
254

255
	return -1;
J
Jack Lee 已提交
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
}

/**
 *	init_hwif_it8213	-	set up hwif structs
 *	@hwif: interface to set up
 *
 *	We do the basic set up of the interface structure. The IT8212
 *	requires several custom handlers so we override the default
 *	ide DMA handlers appropriately
 */

static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
{
	u8 reg42h = 0, ata66 = 0;

	hwif->speedproc = &it8213_tune_chipset;
	hwif->tuneproc	= &it8213_tuneproc;

	hwif->autodma = 0;

	hwif->drives[0].autotune = 1;
	hwif->drives[1].autotune = 1;

	if (!hwif->dma_base)
280 281
		return;

J
Jack Lee 已提交
282 283
	hwif->atapi_dma = 1;
	hwif->ultra_mask = 0x7f;
284 285
	hwif->mwdma_mask = 0x06;
	hwif->swdma_mask = 0x04;
J
Jack Lee 已提交
286 287

	pci_read_config_byte(hwif->pci_dev, 0x42, &reg42h);
288
	ata66 = (reg42h & 0x02) ? 0 : 1;
J
Jack Lee 已提交
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310

	hwif->ide_dma_check = &it8213_config_drive_for_dma;
	if (!(hwif->udma_four))
		hwif->udma_four = ata66;

	/*
	 *	The BIOS often doesn't set up DMA on this controller
	 *	so we always do it.
	 */
	if (!noautodma)
		hwif->autodma = 1;

	hwif->drives[0].autodma = hwif->autodma;
	hwif->drives[1].autodma = hwif->autodma;
}


#define DECLARE_ITE_DEV(name_str)			\
	{						\
		.name		= name_str,		\
		.init_hwif	= init_hwif_it8213,	\
		.channels	= 1,			\
311
		.autodma	= AUTODMA,		\
J
Jack Lee 已提交
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
		.enablebits	= {{0x41,0x80,0x80}}, \
		.bootable	= ON_BOARD,		\
	}

static ide_pci_device_t it8213_chipsets[] __devinitdata = {
	/* 0 */ DECLARE_ITE_DEV("IT8213"),
};


/**
 *	it8213_init_one	-	pci layer discovery entry
 *	@dev: PCI device
 *	@id: ident table entry
 *
 *	Called by the PCI code when it finds an ITE8213 controller. As
 *	this device follows the standard interfaces we can use the
 *	standard helper functions to do almost all the work for us.
 */

static int __devinit it8213_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
	ide_setup_pci_device(dev, &it8213_chipsets[id->driver_data]);
	return 0;
}


static struct pci_device_id it8213_pci_tbl[] = {
339
	{ PCI_VENDOR_ID_ITE, 0x8213, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
J
Jack Lee 已提交
340 341 342 343 344 345 346 347 348 349 350 351 352
	{ 0, },
};

MODULE_DEVICE_TABLE(pci, it8213_pci_tbl);

static struct pci_driver driver = {
	.name		= "ITE8213_IDE",
	.id_table	= it8213_pci_tbl,
	.probe		= it8213_init_one,
};

static int __init it8213_ide_init(void)
{
353 354
	return ide_pci_register_driver(&driver);
}
J
Jack Lee 已提交
355 356 357

module_init(it8213_ide_init);

358
MODULE_AUTHOR("Jack Lee, Alan Cox");
J
Jack Lee 已提交
359 360
MODULE_DESCRIPTION("PCI driver module for the ITE 8213");
MODULE_LICENSE("GPL");