示例#1
0
文件: hpt34x.c 项目: cilynx/dd-wrt
static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
	struct pci_dev *dev	= HWIF(drive)->pci_dev;
	u8 speed = ide_rate_filter(drive, xferspeed);
	u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0;
	u8			hi_speed, lo_speed;

	hi_speed = speed >> 4;
	lo_speed = speed & 0x0f;

	if (hi_speed & 7) {
		hi_speed = (hi_speed & 4) ? 0x01 : 0x10;
	} else {
		lo_speed <<= 5;
		lo_speed >>= 5;
	}

	pci_read_config_dword(dev, 0x44, &reg1);
	pci_read_config_dword(dev, 0x48, &reg2);
	tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
	tmp2 = ((hi_speed << drive->dn) | (reg2 & ~(0x11 << drive->dn)));
	pci_write_config_dword(dev, 0x44, tmp1);
	pci_write_config_dword(dev, 0x48, tmp2);

#if HPT343_DEBUG_DRIVE_INFO
	printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \
		" (0x%02x 0x%02x)\n",
		drive->name, ide_xfer_verbose(speed),
		drive->dn, reg1, tmp1, reg2, tmp2,
		hi_speed, lo_speed);
#endif /* HPT343_DEBUG_DRIVE_INFO */

	return(ide_config_drive_speed(drive, speed));
}
示例#2
0
static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed)
{
	ide_hwif_t *hwif	= HWIF(drive);
	unsigned long scr_port	= hwif->config_data + (drive->dn ? 0x02 : 0x00);
	u16 mode, scr		= hwif->INW(scr_port);

	speed = ide_rate_filter(tc86c001_ratemask(drive), speed);

	switch (speed) {
		case XFER_UDMA_4:	mode = 0x00c0; break;
		case XFER_UDMA_3:	mode = 0x00b0; break;
		case XFER_UDMA_2:	mode = 0x00a0; break;
		case XFER_UDMA_1:	mode = 0x0090; break;
		case XFER_UDMA_0:	mode = 0x0080; break;
		case XFER_MW_DMA_2:	mode = 0x0070; break;
		case XFER_MW_DMA_1:	mode = 0x0060; break;
		case XFER_MW_DMA_0:	mode = 0x0050; break;
		case XFER_PIO_4:	mode = 0x0400; break;
		case XFER_PIO_3:	mode = 0x0300; break;
		case XFER_PIO_2:	mode = 0x0200; break;
		case XFER_PIO_1:	mode = 0x0100; break;
		case XFER_PIO_0:
		default:		mode = 0x0000; break;
	}

	scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f;
	scr |= mode;
	outw(scr, scr_port);

	return ide_config_drive_speed(drive, speed);
}
static int aec6210_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
	ide_hwif_t *hwif	= HWIF(drive);
	struct pci_dev *dev	= hwif->pci_dev;
	u16 d_conf		= 0;
	u8 speed	= ide_rate_filter(aec62xx_ratemask(drive), xferspeed);
	u8 ultra = 0, ultra_conf = 0;
	u8 tmp0 = 0, tmp1 = 0, tmp2 = 0;
	unsigned long flags;

	local_irq_save(flags);
	pci_read_config_word(dev, 0x40|(2*drive->dn), &d_conf);
	tmp0 = pci_bus_clock_list(speed, BUSCLOCK(dev));
	SPLIT_BYTE(tmp0,tmp1,tmp2);
	MAKE_WORD(d_conf,tmp1,tmp2);
	pci_write_config_word(dev, 0x40|(2*drive->dn), d_conf);

	tmp1 = 0x00;
	tmp2 = 0x00;
	pci_read_config_byte(dev, 0x54, &ultra);
	tmp1 = ((0x00 << (2*drive->dn)) | (ultra & ~(3 << (2*drive->dn))));
	ultra_conf = pci_bus_clock_list_ultra(speed, BUSCLOCK(dev));
	tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn))));
	pci_write_config_byte(dev, 0x54, tmp2);
	local_irq_restore(flags);
	return(ide_config_drive_speed(drive, speed));
}
示例#4
0
/*
 * We only deal with PIO mode here - DMA mode 'using_dma' is not
 * initialised at the point that this function is called.
 */
static void tune_sl82c105(ide_drive_t *drive, byte pio)
{
	ide_hwif_t *hwif = HWIF(drive);
	struct pci_dev *dev = hwif->pci_dev;
	ide_pio_data_t p;
	unsigned short drv_ctrl = 0x909;
	unsigned int xfer_mode, reg;

	reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);

	pio = ide_get_best_pio_mode(drive, pio, 5, &p);

	switch (pio) {
	default:
	case 0:		xfer_mode = XFER_PIO_0;		break;
	case 1:		xfer_mode = XFER_PIO_1;		break;
	case 2:		xfer_mode = XFER_PIO_2;		break;
	case 3:		xfer_mode = XFER_PIO_3;		break;
	case 4:		xfer_mode = XFER_PIO_4;		break;
	}

	if (ide_config_drive_speed(drive, xfer_mode) == 0)
		drv_ctrl = get_timing_sl82c105(&p);

	pci_write_config_word(dev, reg, drv_ctrl);
	pci_read_config_word(dev, reg, &drv_ctrl);

	printk("%s: selected %s (%dns) (%04X)\n", drive->name,
	       ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl);
}
示例#5
0
文件: cs5520.c 项目: ivucica/linux
static int cs5520_tune_chipset(ide_drive_t *drive, u8 xferspeed)
{
	ide_hwif_t *hwif = HWIF(drive);
	struct pci_dev *pdev = hwif->pci_dev;
	u8 speed = min((u8)XFER_PIO_4, xferspeed);
	int pio = speed;
	u8 reg;
	int controller = drive->dn > 1 ? 1 : 0;
	int error;
	
	switch(speed)
	{
		case XFER_PIO_4:
		case XFER_PIO_3:
		case XFER_PIO_2:
		case XFER_PIO_1:
		case XFER_PIO_0:
			pio -= XFER_PIO_0;
			break;
		default:
			pio = 0;
			printk(KERN_ERR "cs55x0: bad ide timing.\n");
	}
	
	printk("PIO clocking = %d\n", pio);
	
	/* FIXME: if DMA = 1 do we need to set the DMA bit here ? */

	/* 8bit CAT/CRT - 8bit command timing for channel */
	pci_write_config_byte(pdev, 0x62 + controller, 
		(cs5520_pio_clocks[pio].recovery << 4) |
		(cs5520_pio_clocks[pio].assert));

	/* 0x64 - 16bit Primary, 0x68 - 16bit Secondary */

	/* FIXME: should these use address ? */
	/* Data read timing */
	pci_write_config_byte(pdev, 0x64 + 4*controller + (drive->dn&1),
		(cs5520_pio_clocks[pio].recovery << 4) |
		(cs5520_pio_clocks[pio].assert));
	/* Write command timing */
	pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1),
		(cs5520_pio_clocks[pio].recovery << 4) |
		(cs5520_pio_clocks[pio].assert));
		
	/* Set the DMA enable/disable flag */
	reg = inb(hwif->dma_base + 0x02 + 8*controller);
	reg |= 1<<((drive->dn&1)+5);
	outb(reg, hwif->dma_base + 0x02 + 8*controller);
		
	error = ide_config_drive_speed(drive, speed);
	/* ATAPI is harder so leave it for now */
	if(!error && drive->media == ide_disk)
		error = hwif->ide_dma_on(drive);

	return error;
}	
示例#6
0
文件: sgiioc4.c 项目: Mr-Aloof/wl500g
static int sgiioc4_ide_dma_check(ide_drive_t *drive)
{
	/* FIXME: check for available DMA modes */
	if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
		printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, "
				    "using PIO instead\n", drive->name);
		return -1;
	} else
		return 0;
}
示例#7
0
static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, u8 set_speed)
{
    u8 speed	= 0x00;
    u8 set_pio	= ide_get_best_pio_mode(drive, 4, 5, NULL);

    cmd64x_tuneproc(drive, set_pio);
    speed = XFER_PIO_0 + set_pio;
    if (set_speed)
        (void) ide_config_drive_speed(drive, speed);
}
示例#8
0
static int triflex_tune_chipset(ide_drive_t *drive, u8 xferspeed)
{
    ide_hwif_t *hwif = HWIF(drive);
    struct pci_dev *dev = hwif->pci_dev;
    u8 channel_offset = hwif->channel ? 0x74 : 0x70;
    u16 timing = 0;
    u32 triflex_timings = 0;
    u8 unit = (drive->select.b.unit & 0x01);
    u8 speed = ide_rate_filter(0, xferspeed);

    pci_read_config_dword(dev, channel_offset, &triflex_timings);

    switch(speed) {
    case XFER_MW_DMA_2:
        timing = 0x0103;
        break;
    case XFER_MW_DMA_1:
        timing = 0x0203;
        break;
    case XFER_MW_DMA_0:
        timing = 0x0808;
        break;
    case XFER_SW_DMA_2:
    case XFER_SW_DMA_1:
    case XFER_SW_DMA_0:
        timing = 0x0f0f;
        break;
    case XFER_PIO_4:
        timing = 0x0202;
        break;
    case XFER_PIO_3:
        timing = 0x0204;
        break;
    case XFER_PIO_2:
        timing = 0x0404;
        break;
    case XFER_PIO_1:
        timing = 0x0508;
        break;
    case XFER_PIO_0:
        timing = 0x0808;
        break;
    default:
        return -1;
    }

    triflex_timings &= ~(0xFFFF << (16 * unit));
    triflex_timings |= (timing << (16 * unit));

    pci_write_config_dword(dev, channel_offset, triflex_timings);

    return (ide_config_drive_speed(drive, speed));
}
示例#9
0
static int redwood_ide_tune_chipset (ide_drive_t *drive, byte speed)
{
	int err=0;

	redwood_ide_tune_drive(drive, redwood_ide_dma_2_pio(speed));

	if (!drive->init_speed)
		drive->init_speed = speed;
	err = ide_config_drive_speed(drive, speed);
	drive->current_speed = speed;
	return err;	
}
示例#10
0
static int
sgiioc4_ide_dma_check(ide_drive_t * drive)
{
	if (ide_config_drive_speed(drive,XFER_MW_DMA_2)!=0) {
		printk(KERN_INFO "Couldnot set %s in Multimode-2 DMA mode | Drive %s using PIO instead\n",
				drive->name, drive->name);
		drive->using_dma = 0;
	} else
		drive->using_dma = 1;

	return 0;
}
示例#11
0
static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
	ide_hwif_t *hwif	= HWIF(drive);
	struct pci_dev *dev	= hwif->pci_dev;
	u8 maslave		= hwif->channel ? 0x42 : 0x40;
	u8 speed	= ide_rate_filter(slc90e66_ratemask(drive), xferspeed);
	int sitre = 0, a_speed	= 7 << (drive->dn * 4);
	int u_speed = 0, u_flag = 1 << drive->dn;
	u16			reg4042, reg44, reg48, reg4a;

	pci_read_config_word(dev, maslave, &reg4042);
	sitre = (reg4042 & 0x4000) ? 1 : 0;
	pci_read_config_word(dev, 0x44, &reg44);
	pci_read_config_word(dev, 0x48, &reg48);
	pci_read_config_word(dev, 0x4a, &reg4a);

	switch(speed) {
#ifdef CONFIG_BLK_DEV_IDEDMA
		case XFER_UDMA_4:	u_speed = 4 << (drive->dn * 4); break;
		case XFER_UDMA_3:	u_speed = 3 << (drive->dn * 4); break;
		case XFER_UDMA_2:	u_speed = 2 << (drive->dn * 4); break;
		case XFER_UDMA_1:	u_speed = 1 << (drive->dn * 4); break;
		case XFER_UDMA_0:	u_speed = 0 << (drive->dn * 4); break;
		case XFER_MW_DMA_2:
		case XFER_MW_DMA_1:
		case XFER_SW_DMA_2:	break;
#endif /* CONFIG_BLK_DEV_IDEDMA */
		case XFER_PIO_4:
		case XFER_PIO_3:
		case XFER_PIO_2:
		case XFER_PIO_0:        break;
		default:		return -1;
	}

	if (speed >= XFER_UDMA_0) {
		if (!(reg48 & u_flag))
			pci_write_config_word(dev, 0x48, reg48|u_flag);
		/* FIXME: (reg4a & a_speed) ? */
		if ((reg4a & u_speed) != u_speed) {
			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
			pci_read_config_word(dev, 0x4a, &reg4a);
			pci_write_config_word(dev, 0x4a, reg4a|u_speed);
		}
	} else {
		if (reg48 & u_flag)
			pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
		if (reg4a & a_speed)
			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
	}

	slc90e66_tune_drive(drive, slc90e66_dma_2_pio(speed));
	return (ide_config_drive_speed(drive, speed));
}
示例#12
0
static void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed)
{
	u8 channel_timings	= siimage_taskfile_timing(HWIF(drive));
	u8 speed = 0, set_pio	= ide_get_best_pio_mode(drive, 4, 5, NULL);

	/* WARNING PIO timing mess is going to happen b/w devices, argh */
	if ((channel_timings != set_pio) && (set_pio > channel_timings))
		set_pio = channel_timings;

	siimage_tuneproc(drive, set_pio);
	speed = XFER_PIO_0 + set_pio;
	if (set_speed)
		(void) ide_config_drive_speed(drive, speed);
}
示例#13
0
static int palm_bk3710_tune_chipset(ide_drive_t *drive, u8 speed)
{
	int is_slave = drive->dn & 1;
	void __iomem *base = (void *)drive->hwif->dma_base;

	speed = ide_rate_filter(palm_bk3710_ratemask(drive), speed);
	if (speed >= XFER_UDMA_0) {
		palm_bk3710_setudmamode(base, is_slave,	speed - XFER_UDMA_0);
	} else {
		palm_bk3710_setdmamode(base, is_slave, drive->id->eide_dma_min,
				       speed);
	}
	return ide_config_drive_speed(drive, speed);
}
示例#14
0
static void palm_bk3710_tune_drive(ide_drive_t *drive, u8 pio)
{
	ide_pio_data_t piodata;
	int is_slave = drive->dn & 1;
	ide_drive_t *mate;
	void __iomem *base = (void *)drive->hwif->dma_base;

	/*
	 * Obtain the drive PIO data for tuning the Palm Chip registers
	 */
	pio  = ide_get_best_pio_mode(drive, pio, 4, &piodata);

	mate = ide_get_paired_drive(drive);
	palm_bk3710_setpiomode(base, mate, is_slave, piodata.cycle_time, pio);
	(void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
示例#15
0
static int pdcnew_new_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
	ide_hwif_t *hwif	= HWIF(drive);
	unsigned long indexreg	= hwif->dma_vendor1;
	unsigned long datareg	= hwif->dma_vendor3;
	u8 thold		= 0x10;
	u8 adj			= (drive->dn%2) ? 0x08 : 0x00;
	u8 speed		= ide_rate_filter(pdcnew_ratemask(drive), xferspeed);

	if (speed == XFER_UDMA_2) {
		hwif->OUTB((thold + adj), indexreg);
		hwif->OUTB((hwif->INB(datareg) & 0x7f), datareg);
	}

	switch (speed) {
		case XFER_UDMA_7:
			speed = XFER_UDMA_6;
		case XFER_UDMA_6:	set_ultra(0x1a, 0x01, 0xcb); break;
		case XFER_UDMA_5:	set_ultra(0x1a, 0x02, 0xcb); break;
		case XFER_UDMA_4:	set_ultra(0x1a, 0x03, 0xcd); break;
		case XFER_UDMA_3:	set_ultra(0x1a, 0x05, 0xcd); break;
		case XFER_UDMA_2:	set_ultra(0x2a, 0x07, 0xcd); break;
		case XFER_UDMA_1:	set_ultra(0x3a, 0x0a, 0xd0); break;
		case XFER_UDMA_0:	set_ultra(0x4a, 0x0f, 0xd5); break;
		case XFER_MW_DMA_2:	set_ata2(0x69, 0x25); break;
		case XFER_MW_DMA_1:	set_ata2(0x6b, 0x27); break;
		case XFER_MW_DMA_0:	set_ata2(0xdf, 0x5f); break;
		case XFER_PIO_4:	set_pio(0x23, 0x09, 0x25); break;
		case XFER_PIO_3:	set_pio(0x27, 0x0d, 0x35); break;
		case XFER_PIO_2:	set_pio(0x23, 0x26, 0x64); break;
		case XFER_PIO_1:	set_pio(0x46, 0x29, 0xa4); break;
		case XFER_PIO_0:	set_pio(0xfb, 0x2b, 0xac); break;
		default:
			;
	}

	return (ide_config_drive_speed(drive, speed));
}
static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
	ide_hwif_t *hwif	= HWIF(drive);
	struct pci_dev *dev	= hwif->pci_dev;
	u8 speed	= ide_rate_filter(aec62xx_ratemask(drive), xferspeed);
	u8 unit		= (drive->select.b.unit & 0x01);
	u8 tmp1 = 0, tmp2 = 0;
	u8 ultra = 0, drive_conf = 0, ultra_conf = 0;
	unsigned long flags;

	local_irq_save(flags);
	pci_read_config_byte(dev, 0x40|drive->dn, &drive_conf);
	drive_conf = pci_bus_clock_list(speed, BUSCLOCK(dev));
	pci_write_config_byte(dev, 0x40|drive->dn, drive_conf);

	pci_read_config_byte(dev, (0x44|hwif->channel), &ultra);
	tmp1 = ((0x00 << (4*unit)) | (ultra & ~(7 << (4*unit))));
	ultra_conf = pci_bus_clock_list_ultra(speed, BUSCLOCK(dev));
	tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit))));
	pci_write_config_byte(dev, (0x44|hwif->channel), tmp2);
	local_irq_restore(flags);
	return(ide_config_drive_speed(drive, speed));
}
示例#17
0
static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
    ide_hwif_t *hwif	= HWIF(drive);
    struct pci_dev *dev	= hwif->pci_dev;

    u8 unit			= (drive->select.b.unit & 0x01);
    u8 regU = 0, pciU	= (hwif->channel) ? UDIDETCR1 : UDIDETCR0;
    u8 regD = 0, pciD	= (hwif->channel) ? BMIDESR1 : BMIDESR0;

    u8 speed	= ide_rate_filter(cmd64x_ratemask(drive), xferspeed);

    if (speed > XFER_PIO_4) {
        (void) pci_read_config_byte(dev, pciD, &regD);
        (void) pci_read_config_byte(dev, pciU, &regU);
        regD &= ~(unit ? 0x40 : 0x20);
        regU &= ~(unit ? 0xCA : 0x35);
        (void) pci_write_config_byte(dev, pciD, regD);
        (void) pci_write_config_byte(dev, pciU, regU);
        (void) pci_read_config_byte(dev, pciD, &regD);
        (void) pci_read_config_byte(dev, pciU, &regU);
    }

    switch(speed) {
    case XFER_UDMA_5:
        regU |= (unit ? 0x0A : 0x05);
        break;
    case XFER_UDMA_4:
        regU |= (unit ? 0x4A : 0x15);
        break;
    case XFER_UDMA_3:
        regU |= (unit ? 0x8A : 0x25);
        break;
    case XFER_UDMA_2:
        regU |= (unit ? 0x42 : 0x11);
        break;
    case XFER_UDMA_1:
        regU |= (unit ? 0x82 : 0x21);
        break;
    case XFER_UDMA_0:
        regU |= (unit ? 0xC2 : 0x31);
        break;
    case XFER_MW_DMA_2:
        regD |= (unit ? 0x40 : 0x10);
        break;
    case XFER_MW_DMA_1:
        regD |= (unit ? 0x80 : 0x20);
        break;
    case XFER_MW_DMA_0:
        regD |= (unit ? 0xC0 : 0x30);
        break;
    case XFER_SW_DMA_2:
        regD |= (unit ? 0x40 : 0x10);
        break;
    case XFER_SW_DMA_1:
        regD |= (unit ? 0x80 : 0x20);
        break;
    case XFER_SW_DMA_0:
        regD |= (unit ? 0xC0 : 0x30);
        break;
    case XFER_PIO_4:
        cmd64x_tuneproc(drive, 4);
        break;
    case XFER_PIO_3:
        cmd64x_tuneproc(drive, 3);
        break;
    case XFER_PIO_2:
        cmd64x_tuneproc(drive, 2);
        break;
    case XFER_PIO_1:
        cmd64x_tuneproc(drive, 1);
        break;
    case XFER_PIO_0:
        cmd64x_tuneproc(drive, 0);
        break;

    default:
        return 1;
    }

    if (speed > XFER_PIO_4) {
        (void) pci_write_config_byte(dev, pciU, regU);
        regD |= (unit ? 0x40 : 0x20);
        (void) pci_write_config_byte(dev, pciD, regD);
    }

    return (ide_config_drive_speed(drive, speed));
}
示例#18
0
static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed)
{
	u8 ultra6[]		= { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
	u8 ultra5[]		= { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
	u16 dma[]		= { 0x2208, 0x10C2, 0x10C1 };

	ide_hwif_t *hwif	= HWIF(drive);
	u16 ultra = 0, multi	= 0;
	u8 mode = 0, unit	= drive->select.b.unit;
	u8 speed	= ide_rate_filter(siimage_ratemask(drive), xferspeed);
	u8 scsc = 0, addr_mask	= ((hwif->channel) ?
				    ((hwif->mmio) ? 0xF4 : 0x84) :
				    ((hwif->mmio) ? 0xB4 : 0x80));

	if (hwif->mmio) {
		scsc = hwif->INB(HWIFADDR(0x4A));
		mode = hwif->INB(HWIFADDR(addr_mask));
		multi = hwif->INW(SELADDR(0x08|(unit<<unit)));
		ultra = hwif->INW(SELADDR(0x0C|(unit<<unit)));
	} else {
		pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
		pci_read_config_byte(hwif->pci_dev, addr_mask, &mode);
		pci_read_config_word(hwif->pci_dev,
				SELREG(0x08|(unit<<unit)), &multi);
		pci_read_config_word(hwif->pci_dev,
				SELREG(0x0C|(unit<<unit)), &ultra);
	}

	mode &= ~((unit) ? 0x30 : 0x03);
	ultra &= ~0x3F;
	scsc = ((scsc & 0x30) == 0x00) ? 0 : 1;

	scsc = (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) ? 1 : scsc;

	switch(speed) {
		case XFER_PIO_4:
		case XFER_PIO_3:
		case XFER_PIO_2:
		case XFER_PIO_1:
		case XFER_PIO_0:
			siimage_tuneproc(drive, (speed - XFER_PIO_0));
			mode |= ((unit) ? 0x10 : 0x01);
			break;
		case XFER_MW_DMA_2:
		case XFER_MW_DMA_1:
		case XFER_MW_DMA_0:
			multi = dma[speed - XFER_MW_DMA_0];
			mode |= ((unit) ? 0x20 : 0x02);
			config_siimage_chipset_for_pio(drive, 0);
			break;
		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:
			multi = dma[2];
			ultra |= ((scsc) ? (ultra6[speed - XFER_UDMA_0]) :
					   (ultra5[speed - XFER_UDMA_0]));
			mode |= ((unit) ? 0x30 : 0x03);
			config_siimage_chipset_for_pio(drive, 0);
			break;
		default:
			return 1;
	}

	if (hwif->mmio) {
		hwif->OUTB(mode, HWIFADDR(addr_mask));
		hwif->OUTW(multi, SELADDR(0x08|(unit<<unit)));
		hwif->OUTW(ultra, SELADDR(0x0C|(unit<<unit)));
	} else {
		pci_write_config_byte(hwif->pci_dev, addr_mask, mode);
		pci_write_config_word(hwif->pci_dev,
				SELREG(0x08|(unit<<unit)), multi);
		pci_write_config_word(hwif->pci_dev,
				SELREG(0x0C|(unit<<unit)), ultra);
	}

	return (ide_config_drive_speed(drive, speed));
}
示例#19
0
static int pdc202xx_tune_chipset (ide_drive_t *drive, byte speed)
{
	ide_hwif_t *hwif	= HWIF(drive);
	struct pci_dev *dev	= hwif->pci_dev;

	unsigned int		drive_conf;
	int			err;
	byte			drive_pci, AP, BP, CP, DP;
	byte			TA = 0, TB = 0, TC = 0;

	switch (drive->dn) {
		case 0: drive_pci = 0x60; break;
		case 1: drive_pci = 0x64; break;
		case 2: drive_pci = 0x68; break;
		case 3: drive_pci = 0x6c; break;
		default: return -1;
	}

	if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0))	return -1;

	pci_read_config_dword(dev, drive_pci, &drive_conf);
	pci_read_config_byte(dev, (drive_pci), &AP);
	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
	pci_read_config_byte(dev, (drive_pci)|0x03, &DP);

#ifdef CONFIG_BLK_DEV_IDEDMA
	if (speed >= XFER_SW_DMA_0) {
		if ((BP & 0xF0) && (CP & 0x0F)) {
			/* clear DMA modes of upper 842 bits of B Register */
			/* clear PIO forced mode upper 1 bit of B Register */
			pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0xF0);
			pci_read_config_byte(dev, (drive_pci)|0x01, &BP);

			/* clear DMA modes of lower 8421 bits of C Register */
			pci_write_config_byte(dev, (drive_pci)|0x02, CP & ~0x0F);
			pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
		}
	} else {
#else
	{
#endif /* CONFIG_BLK_DEV_IDEDMA */
		if ((AP & 0x0F) || (BP & 0x07)) {
			/* clear PIO modes of lower 8421 bits of A Register */
			pci_write_config_byte(dev, (drive_pci), AP & ~0x0F);
			pci_read_config_byte(dev, (drive_pci), &AP);

			/* clear PIO modes of lower 421 bits of B Register */
			pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0x07);
			pci_read_config_byte(dev, (drive_pci)|0x01, &BP);

			pci_read_config_byte(dev, (drive_pci), &AP);
			pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
		}
	}

	pci_read_config_byte(dev, (drive_pci), &AP);
	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);

	switch(speed) {
#ifdef CONFIG_BLK_DEV_IDEDMA
		case XFER_UDMA_5:
		case XFER_UDMA_4:	TB = 0x20; TC = 0x01; break;	/* speed 8 == UDMA mode 4 */
		case XFER_UDMA_3:	TB = 0x40; TC = 0x02; break;	/* speed 7 == UDMA mode 3 */
		case XFER_UDMA_2:	TB = 0x20; TC = 0x01; break;	/* speed 6 == UDMA mode 2 */
		case XFER_UDMA_1:	TB = 0x40; TC = 0x02; break;	/* speed 5 == UDMA mode 1 */
		case XFER_UDMA_0:	TB = 0x60; TC = 0x03; break;	/* speed 4 == UDMA mode 0 */
		case XFER_MW_DMA_2:	TB = 0x60; TC = 0x03; break;	/* speed 4 == MDMA mode 2 */
		case XFER_MW_DMA_1:	TB = 0x60; TC = 0x04; break;	/* speed 3 == MDMA mode 1 */
		case XFER_MW_DMA_0:	TB = 0x60; TC = 0x05; break;	/* speed 2 == MDMA mode 0 */
		case XFER_SW_DMA_2:	TB = 0x60; TC = 0x05; break;	/* speed 0 == SDMA mode 2 */
		case XFER_SW_DMA_1:	TB = 0x80; TC = 0x06; break;	/* speed 1 == SDMA mode 1 */
		case XFER_SW_DMA_0:	TB = 0xC0; TC = 0x0B; break;	/* speed 0 == SDMA mode 0 */
#endif /* CONFIG_BLK_DEV_IDEDMA */
		case XFER_PIO_4:	TA = 0x01; TB = 0x04; break;
		case XFER_PIO_3:	TA = 0x02; TB = 0x06; break;
		case XFER_PIO_2:	TA = 0x03; TB = 0x08; break;
		case XFER_PIO_1:	TA = 0x05; TB = 0x0C; break;
		case XFER_PIO_0:
		default:		TA = 0x09; TB = 0x13; break;
	}

#ifdef CONFIG_BLK_DEV_IDEDMA
        if (speed >= XFER_SW_DMA_0) {
		pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
		pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC);
	} else {
#else
	{
#endif /* CONFIG_BLK_DEV_IDEDMA */
		pci_write_config_byte(dev, (drive_pci), AP|TA);
		pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
	}

#if PDC202XX_DECODE_REGISTER_INFO
	pci_read_config_byte(dev, (drive_pci), &AP);
	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
	pci_read_config_byte(dev, (drive_pci)|0x03, &DP);

	decode_registers(REG_A, AP);
	decode_registers(REG_B, BP);
	decode_registers(REG_C, CP);
	decode_registers(REG_D, DP);
#endif /* PDC202XX_DECODE_REGISTER_INFO */

	err = ide_config_drive_speed(drive, speed);

#if PDC202XX_DEBUG_DRIVE_INFO
	printk("%s: %s drive%d 0x%08x ",
		drive->name, ide_xfer_verbose(speed),
		drive->dn, drive_conf);
		pci_read_config_dword(dev, drive_pci, &drive_conf);
	printk("0x%08x\n", drive_conf);
#endif /* PDC202XX_DEBUG_DRIVE_INFO */
	return err;
}

/*   0    1    2    3    4    5    6   7   8
 * 960, 480, 390, 300, 240, 180, 120, 90, 60
 *           180, 150, 120,  90,  60
 * DMA_Speed
 * 180, 120,  90,  90,  90,  60,  30
 *  11,   5,   4,   3,   2,   1,   0
 */
static int config_chipset_for_pio (ide_drive_t *drive, byte pio)
{
	byte speed = 0x00;

	pio = (pio == 5) ? 4 : pio;
	speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL);
        
	return ((int) pdc202xx_tune_chipset(drive, speed));
}

static void pdc202xx_tune_drive (ide_drive_t *drive, byte pio)
{
	(void) config_chipset_for_pio(drive, pio);
}
示例#20
0
static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
	ide_hwif_t *hwif	= HWIF(drive);
	struct pci_dev *dev	= hwif->pci_dev;
	u8 maslave		= hwif->channel ? 0x42 : 0x40;
	u8 speed		= ide_rate_filter(piix_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;
	int			sitre;
	u16			reg4042, reg4a;
	u8			reg48, reg54, reg55;

	pci_read_config_word(dev, maslave, &reg4042);
	sitre = (reg4042 & 0x4000) ? 1 : 0;
	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_4:
		case XFER_UDMA_2:	u_speed = 2 << (drive->dn * 4); break;
		case XFER_UDMA_5:
		case XFER_UDMA_3:
		case XFER_UDMA_1:	u_speed = 1 << (drive->dn * 4); break;
		case XFER_UDMA_0:	u_speed = 0 << (drive->dn * 4); break;
		case XFER_MW_DMA_2:
		case XFER_MW_DMA_1:
		case XFER_SW_DMA_2:	break;
		case XFER_PIO_4:
		case XFER_PIO_3:
		case XFER_PIO_2:
		case XFER_PIO_0:	break;
		default:		return -1;
	}

	if (speed >= XFER_UDMA_0) {
		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);
		if (speed > XFER_UDMA_2) {
			if (!(reg54 & v_flag))
				pci_write_config_byte(dev, 0x54, reg54 | v_flag);
		} else
			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
	} else {
		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);
	}

	piix_tune_drive(drive, piix_dma_2_pio(speed));
	return (ide_config_drive_speed(drive, speed));
}
示例#21
0
static void slc90e66_tune_drive (ide_drive_t *drive, u8 pio)
{
	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
	slc90e66_tune_pio(drive, pio);
	(void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
示例#22
0
static int ps2_ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
	ide_hwif_t *hwif = HWIF(drive);
	struct ps2_dmatable *t = (struct ps2_dmatable *)hwif->dmatable;
	struct ata_dma_request *req = &t->ata_dma_request;
	int ret;

#if !defined(GATHER_WRITE_DATA)
	ps2sif_dmadata_t *sdd;
	int cnt, i;
#endif /* !GATHER_WRITE_DATA */

	DPRINT("ps2_ide_dmaproc: %s\n", procfunc[func]);
	switch (func) {
	case ide_dma_off:
		printk("%s: DMA disabled\n", drive->name);
	case ide_dma_off_quietly:
	case ide_dma_on:
		drive->using_dma = (func == ide_dma_on);
		return 0;
	case ide_dma_check:
		/* only ide-disk DMA works... */
		drive->using_dma = hwif->autodma && drive->media == ide_disk;

		/* TODO: always UltraDMA mode 4 */
		if (drive->using_dma) {
			int ide_config_drive_speed (ide_drive_t *drive, byte speed);
			ide_config_drive_speed(drive, XFER_UDMA_4);
		}
		return 0;

	case ide_dma_read:
#ifdef NO_DMA_READ
		return 1;
#endif
		if (drive->media != ide_disk)
			return 0;
		if (!ps2_ide_build_dmatable(0, drive))
			return 1;	/* try PIO instead of DMA */
		req->command = WIN_READDMA;
		req->devctrl = drive->ctl;
		drive->waiting_for_dma = 1;
		ide_set_handler(drive, &ide_dma_intr, WAIT_CMD);

		/* set nIEN for disable ATA interrupt */
		/* (ATA interrupt is enabled in RPC handler) */
		OUT_BYTE(drive->ctl|2, hwif->io_ports[IDE_CONTROL_OFFSET]);

		flush_cache_all();
		do {
			ret = ps2sif_callrpc(&t->cd_ata, SIFNUM_DmaRead,
					     SIF_RPCM_NOWAIT, (void *)req,
					     sizeof(int) * 4 + sizeof(ps2sif_dmadata_t) * req->count,
					     NULL, 0, NULL, NULL);
			switch (ret) {
			case 0:
				break;
			case -SIF_RPCE_SENDP:
				break;
			default:
				/* restore nIEN */
				OUT_BYTE(drive->ctl, hwif->io_ports[IDE_CONTROL_OFFSET]);

				printk("ps2_ide_dmaproc(read): callrpc failed, result=%d\n", ret);
				drive->waiting_for_dma = 0;
				return 1;
			}
		} while (ret < 0);
		return 0;

	case ide_dma_write:
#ifdef NO_DMA_WRITE
		return 1;
#endif
		if (drive->media != ide_disk)
			return 0;
		if (!ps2_ide_build_dmatable(1, drive))
			return 1;	/* try PIO instead of DMA */
		req->command = WIN_WRITEDMA;
		drive->waiting_for_dma = 1;
		ide_set_handler(drive, &ide_dma_intr, WAIT_CMD);

		flush_cache_all();
#if !defined(GATHER_WRITE_DATA)
		sdd = req->sdd;
		for (cnt = 0; cnt < req->count; cnt++) {
			while (ps2sif_setdma(sdd, 1) == 0) {
				i = 0x010000;
				while (i--)
					;
			}
			sdd++;
		}
#else	/* GATHER_WRITE_DATA */
		req->sdd[0].data = t->dma_buffer;
		req->sdd[0].addr = t->ata_iop_buffer;
		req->sdd[0].size = req->size;
		req->sdd[0].mode = 0;
		while (ps2sif_setdma(req->sdd, 1) == 0) {
			i = 0x010000;
			while (i--)
				;
		}
#endif
		do {
			ret = ps2sif_callrpc(&t->cd_ata, SIFNUM_DmaWrite,
					     SIF_RPCM_NOWAIT, (void *)req,
					     sizeof(int) * 4,
					     NULL, 0, NULL, NULL);
			switch (ret) {
			case 0:
				break;
			case -SIF_RPCE_SENDP:
				break;
			default:
				printk("ps2_ide_dmaproc(write): callrpc failed, result=%d\n", ret);
				drive->waiting_for_dma = 0;
				return 1;
			}
		} while (ret < 0);
		return 0;

	case ide_dma_begin:
		/* TODO */
		return 0;
	case ide_dma_end: /* returns 1 on error, 0 otherwise */
		/* disable DMA transfer */
		*SPD_R_XFR_CTRL = 0;
		*SPD_R_IF_CTRL = *SPD_R_IF_CTRL & ~IFC_DMA_EN;
		/* force break DMA */
		if (!(*SPD_R_INTR_STAT & 0x0001)) {
			unsigned char if_ctrl;
			if_ctrl = *SPD_R_IF_CTRL;
			*SPD_R_IF_CTRL = IFC_ATA_RST;
			udelay(100);
			*SPD_R_IF_CTRL = if_ctrl;
			do {
				ret = ps2sif_callrpc(&t->cd_ata_end, 0, SIF_RPCM_NOWAIT, NULL, 0, NULL, 0, NULL, NULL);
				switch (ret) {
				case 0:
					break;
				case -SIF_RPCE_SENDP:
					break;
				default:
					printk("ps2_ide_dmaproc(end): callrpc failed, result=%d\n", ret);
					break;
				}
			} while (ret == -SIF_RPCE_SENDP);
		}
		drive->waiting_for_dma = 0;
		return 0;
	case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
		return (*SPD_R_INTR_STAT & 0x0001) ? 1 : 0;

	default:
		printk("ps2_ide_dmaproc: unsupported func: %d\n", func);
		return 1;
	}
}
示例#23
0
文件: jmicron.c 项目: cilynx/dd-wrt
static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed)
{
	u8 speed = ide_rate_filter(drive, xferspeed);

	return ide_config_drive_speed(drive, speed);
}
示例#24
0
static int cs5530_set_xfer_mode (ide_drive_t *drive, u8 mode)
{
	printk(KERN_DEBUG "%s: cs5530_set_xfer_mode(%s)\n",
		drive->name, ide_xfer_verbose(mode));
	return (ide_config_drive_speed(drive, mode));
}
示例#25
0
文件: jmicron.c 项目: cilynx/dd-wrt
static void jmicron_tuneproc(ide_drive_t *drive, u8 pio)
{
	pio = ide_get_best_pio_mode(drive, pio, 5);
	ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
示例#26
0
static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
{
	ide_startstop_t startstop;

	BUG_ON(!blk_rq_started(rq));

#ifdef DEBUG
	printk("%s: start_request: current=0x%08lx\n",
		drive->hwif->name, (unsigned long) rq);
#endif

	/* bail early if we've exceeded max_failures */
	if (drive->max_failures && (drive->failures > drive->max_failures)) {
		rq->cmd_flags |= REQ_FAILED;
		goto kill_rq;
	}

	if (blk_pm_request(rq))
		ide_check_pm_state(drive, rq);

	SELECT_DRIVE(drive);
	if (ide_wait_stat(&startstop, drive, drive->ready_stat,
			  ATA_BUSY | ATA_DRQ, WAIT_READY)) {
		printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
		return startstop;
	}
	if (!drive->special.all) {
		struct ide_driver *drv;

		/*
		 * We reset the drive so we need to issue a SETFEATURES.
		 * Do it _after_ do_special() restored device parameters.
		 */
		if (drive->current_speed == 0xff)
			ide_config_drive_speed(drive, drive->desired_speed);

		if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
			return execute_drive_cmd(drive, rq);
		else if (blk_pm_request(rq)) {
			struct request_pm_state *pm = rq->data;
#ifdef DEBUG_PM
			printk("%s: start_power_step(step: %d)\n",
				drive->name, pm->pm_step);
#endif
			startstop = ide_start_power_step(drive, rq);
			if (startstop == ide_stopped &&
			    pm->pm_step == IDE_PM_COMPLETED)
				ide_complete_pm_request(drive, rq);
			return startstop;
		} else if (!rq->rq_disk && blk_special_request(rq))
			/*
			 * TODO: Once all ULDs have been modified to
			 * check for specific op codes rather than
			 * blindly accepting any special request, the
			 * check for ->rq_disk above may be replaced
			 * by a more suitable mechanism or even
			 * dropped entirely.
			 */
			return ide_special_rq(drive, rq);

		drv = *(struct ide_driver **)rq->rq_disk->private_data;

		return drv->do_request(drive, rq, rq->sector);
	}
	return do_special(drive);
kill_rq:
	ide_kill_rq(drive, rq);
	return ide_stopped;
}
示例#27
0
static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed)
{
	u8 ultra6[]		= { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
	u8 ultra5[]		= { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
	u16 dma[]		= { 0x2208, 0x10C2, 0x10C1 };

	ide_hwif_t *hwif	= HWIF(drive);
	u16 ultra = 0, multi	= 0;
	u8 mode = 0, unit	= drive->select.b.unit;
	u8 speed		= ide_rate_filter(siimage_ratemask(drive), xferspeed);
	unsigned long base	= (unsigned long)hwif->hwif_data;
	u8 scsc = 0, addr_mask	= ((hwif->channel) ?
				    ((hwif->mmio) ? 0xF4 : 0x84) :
				    ((hwif->mmio) ? 0xB4 : 0x80));
				    
	unsigned long ma	= siimage_seldev(drive, 0x08);
	unsigned long ua	= siimage_seldev(drive, 0x0C);

	if (hwif->mmio) {
		scsc = hwif->INB(base + 0x4A);
		mode = hwif->INB(base + addr_mask);
		multi = hwif->INW(ma);
		ultra = hwif->INW(ua);
	} else {
		pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
		pci_read_config_byte(hwif->pci_dev, addr_mask, &mode);
		pci_read_config_word(hwif->pci_dev, ma, &multi);
		pci_read_config_word(hwif->pci_dev, ua, &ultra);
	}

	mode &= ~((unit) ? 0x30 : 0x03);
	ultra &= ~0x3F;
	scsc = ((scsc & 0x30) == 0x00) ? 0 : 1;

	scsc = is_sata(hwif) ? 1 : scsc;

	switch(speed) {
		case XFER_PIO_4:
		case XFER_PIO_3:
		case XFER_PIO_2:
		case XFER_PIO_1:
		case XFER_PIO_0:
			siimage_tuneproc(drive, (speed - XFER_PIO_0));
			mode |= ((unit) ? 0x10 : 0x01);
			break;
		case XFER_MW_DMA_2:
		case XFER_MW_DMA_1:
		case XFER_MW_DMA_0:
			multi = dma[speed - XFER_MW_DMA_0];
			mode |= ((unit) ? 0x20 : 0x02);
			config_siimage_chipset_for_pio(drive, 0);
			break;
		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:
			multi = dma[2];
			ultra |= ((scsc) ? (ultra6[speed - XFER_UDMA_0]) :
					   (ultra5[speed - XFER_UDMA_0]));
			mode |= ((unit) ? 0x30 : 0x03);
			config_siimage_chipset_for_pio(drive, 0);
			break;
		default:
			return 1;
	}

	if (hwif->mmio) {
		hwif->OUTB(mode, base + addr_mask);
		hwif->OUTW(multi, ma);
		hwif->OUTW(ultra, ua);
	} else {
		pci_write_config_byte(hwif->pci_dev, addr_mask, mode);
		pci_write_config_word(hwif->pci_dev, ma, multi);
		pci_write_config_word(hwif->pci_dev, ua, ultra);
	}
	return (ide_config_drive_speed(drive, speed));
}
示例#28
0
static int pdcnew_tune_chipset(ide_drive_t *drive, u8 speed)
{
	ide_hwif_t *hwif	= HWIF(drive);
	u8 adj			= (drive->dn & 1) ? 0x08 : 0x00;
	int			err;

	speed = ide_rate_filter(pdcnew_ratemask(drive), speed);

	/*
	 * Issue SETFEATURES_XFER to the drive first. PDC202xx hardware will
	 * automatically set the timing registers based on 100 MHz PLL output.
	 */
 	err = ide_config_drive_speed(drive, speed);

	/*
	 * As we set up the PLL to output 133 MHz for UltraDMA/133 capable
	 * chips, we must override the default register settings...
	 */
	if (max_dma_rate(hwif->pci_dev) == 4) {
		u8 mode = speed & 0x07;

		switch (speed) {
			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:
				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);
				break;

			case XFER_MW_DMA_2:
			case XFER_MW_DMA_1:
			case XFER_MW_DMA_0:
				set_indexed_reg(hwif, 0x0e + adj,
						mwdma_timings[mode].reg0e);
				set_indexed_reg(hwif, 0x0f + adj,
						mwdma_timings[mode].reg0f);
				break;
			case XFER_PIO_4:
			case XFER_PIO_3:
			case XFER_PIO_2:
			case XFER_PIO_1:
			case XFER_PIO_0:
				set_indexed_reg(hwif, 0x0c + adj,
						pio_timings[mode].reg0c);
				set_indexed_reg(hwif, 0x0d + adj,
						pio_timings[mode].reg0d);
				set_indexed_reg(hwif, 0x13 + adj,
						pio_timings[mode].reg13);
				break;
			default:
				printk(KERN_ERR "pdc202xx_new: "
				       "Unknown speed %d ignored\n", speed);
		}
	} 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);
 	}

	return err;
}
示例#29
0
文件: it8213.c 项目: cilynx/dd-wrt
static void it8213_tuneproc(ide_drive_t *drive, u8 pio)
{
	pio = ide_get_best_pio_mode(drive, pio, 4);
	it8213_tune_pio(drive, pio);
	ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}