static void program_drive_counts(ide_drive_t *drive, unsigned int index) { unsigned long flags; u8 setup_count = setup_counts[index]; u8 active_count = active_counts[index]; u8 recovery_count = recovery_counts[index]; if (index > 1) { ide_drive_t *peer = ide_get_pair_dev(drive); unsigned int mate = index ^ 1; if (peer) { if (setup_count < setup_counts[mate]) setup_count = setup_counts[mate]; if (active_count < active_counts[mate]) active_count = active_counts[mate]; if (recovery_count < recovery_counts[mate]) recovery_count = recovery_counts[mate]; } } switch (setup_count) { case 4: setup_count = 0x00; break; case 3: setup_count = 0x80; break; case 1: case 2: setup_count = 0x40; break; default: setup_count = 0xc0; } spin_lock_irqsave(&cmd640_lock, flags); setup_count |= __get_cmd640_reg(arttim_regs[index]) & 0x3f; __put_cmd640_reg(arttim_regs[index], setup_count); __put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count)); spin_unlock_irqrestore(&cmd640_lock, flags); }
int generic_ide_suspend(struct device *dev, pm_message_t mesg) { ide_drive_t *drive = dev_get_drvdata(dev); ide_drive_t *pair = ide_get_pair_dev(drive); ide_hwif_t *hwif = drive->hwif; struct request *rq; struct request_pm_state rqpm; int ret; if (ide_port_acpi(hwif)) { /* call ACPI _GTM only once */ if ((drive->dn & 1) == 0 || pair == NULL) ide_acpi_get_timing(hwif); } memset(&rqpm, 0, sizeof(rqpm)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_SUSPEND; rq->special = &rqpm; rqpm.pm_step = IDE_PM_START_SUSPEND; if (mesg.event == PM_EVENT_PRETHAW) mesg.event = PM_EVENT_FREEZE; rqpm.pm_state = mesg.event; ret = blk_execute_rq(drive->queue, NULL, rq, 0); blk_put_request(rq); if (ret == 0 && ide_port_acpi(hwif)) { /* call ACPI _PS3 only after both devices are suspended */ if ((drive->dn & 1) || pair == NULL) ide_acpi_set_state(hwif, 0); } return ret; }
/* * This routine writes the prepared setup/active/recovery counts * for a drive into the cmd640 chipset registers to active them. */ static void program_drive_counts(ide_drive_t *drive, unsigned int index) { unsigned long flags; u8 setup_count = setup_counts[index]; u8 active_count = active_counts[index]; u8 recovery_count = recovery_counts[index]; /* * Set up address setup count and drive read/write timing registers. * Primary interface has individual count/timing registers for * each drive. Secondary interface has one common set of registers, * so we merge the timings, using the slowest value for each timing. */ if (index > 1) { ide_drive_t *peer = ide_get_pair_dev(drive); unsigned int mate = index ^ 1; if (peer) { if (setup_count < setup_counts[mate]) setup_count = setup_counts[mate]; if (active_count < active_counts[mate]) active_count = active_counts[mate]; if (recovery_count < recovery_counts[mate]) recovery_count = recovery_counts[mate]; } } /* * Convert setup_count to internal chipset representation */ switch (setup_count) { case 4: setup_count = 0x00; break; case 3: setup_count = 0x80; break; case 1: case 2: setup_count = 0x40; break; default: setup_count = 0xc0; /* case 5 */ } /* * Now that everything is ready, program the new timings */ spin_lock_irqsave(&cmd640_lock, flags); /* * Program the address_setup clocks into ARTTIM reg, * and then the active/recovery counts into the DRWTIM reg * (this converts counts of 16 into counts of zero -- okay). */ setup_count |= __get_cmd640_reg(arttim_regs[index]) & 0x3f; __put_cmd640_reg(arttim_regs[index], setup_count); __put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count)); spin_unlock_irqrestore(&cmd640_lock, flags); }
static void cmd64x_program_timings(ide_drive_t *drive, u8 mode) { ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(drive->hwif->dev); int bus_speed = ide_pci_clk ? ide_pci_clk : 33; const unsigned long T = 1000000 / bus_speed; static const u8 recovery_values[] = {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}; static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; static const u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM2, DRWTIM3}; struct ide_timing t; u8 arttim = 0; ide_timing_compute(drive, mode, &t, T, 0); if (t.recover > 16) { t.active += t.recover - 16; t.recover = 16; } if (t.active > 16) t.active = 16; t.recover = recovery_values[t.recover]; t.active &= 0x0f; pci_write_config_byte(dev, drwtim_regs[drive->dn], (t.active << 4) | t.recover); if (hwif->channel) { ide_drive_t *pair = ide_get_pair_dev(drive); if (pair) { struct ide_timing tp; ide_timing_compute(pair, pair->pio_mode, &tp, T, 0); ide_timing_merge(&t, &tp, &t, IDE_TIMING_SETUP); if (pair->dma_mode) { ide_timing_compute(pair, pair->dma_mode, &tp, T, 0); ide_timing_merge(&tp, &t, &t, IDE_TIMING_SETUP); } } } if (t.setup > 5) t.setup = 5; (void) pci_read_config_byte (dev, arttim_regs[drive->dn], &arttim); if (hwif->channel) arttim &= ~ARTTIM23_INTR_CH1; arttim &= ~0xc0; arttim |= setup_values[t.setup]; (void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim); }
static void tx4938ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { struct tx4938ide_platform_info *pdata = hwif->dev->platform_data; u8 safe = drive->pio_mode - XFER_PIO_0; ide_drive_t *pair; pair = ide_get_pair_dev(drive); if (pair) safe = min(safe, pair->pio_mode - XFER_PIO_0); tx4938ide_tune_ebusc(pdata->ebus_ch, pdata->gbus_clock, safe); }
static void tx4938ide_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = drive->hwif; struct tx4938ide_platform_info *pdata = hwif->dev->platform_data; u8 safe = pio; ide_drive_t *pair; pair = ide_get_pair_dev(drive); if (pair) safe = min(safe, ide_get_best_pio_mode(pair, 255, 5)); tx4938ide_tune_ebusc(pdata->ebus_ch, pdata->gbus_clock, safe); }
/* * This routine writes into the chipset registers * PIO setup/active/recovery timings. */ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); unsigned long setup_count; unsigned int cycle_time; u8 arttim = 0; static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; cycle_time = ide_pio_cycle_time(drive, pio); program_cycle_times(drive, cycle_time, t->active); setup_count = quantize_timing(t->setup, 1000 / (ide_pci_clk ? ide_pci_clk : 33)); /* * The primary channel has individual address setup timing registers * for each drive and the hardware selects the slowest timing itself. * The secondary channel has one common register and we have to select * the slowest address setup timing ourselves. */ if (hwif->channel) { ide_drive_t *pair = ide_get_pair_dev(drive); ide_set_drivedata(drive, (void *)setup_count); if (pair) setup_count = max_t(u8, setup_count, (unsigned long)ide_get_drivedata(pair)); } if (setup_count > 5) /* shouldn't actually happen... */ setup_count = 5; cmdprintk("Final address setup count: %d\n", setup_count); /* * Program the address setup clocks into the ARTTIM registers. * Avoid clearing the secondary channel's interrupt bit. */ (void) pci_read_config_byte (dev, arttim_regs[drive->dn], &arttim); if (hwif->channel) arttim &= ~ARTTIM23_INTR_CH1; arttim &= ~0xc0; arttim |= setup_values[setup_count]; (void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim); cmdprintk("Write 0x%02x to reg 0x%x\n", arttim, arttim_regs[drive->dn]); }
static void sil_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { static const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 }; static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; struct pci_dev *dev = to_pci_dev(hwif->dev); ide_drive_t *pair = ide_get_pair_dev(drive); u32 speedt = 0; u16 speedp = 0; unsigned long addr = siimage_seldev(drive, 0x04); unsigned long tfaddr = siimage_selreg(hwif, 0x02); unsigned long base = (unsigned long)hwif->hwif_data; const u8 pio = drive->pio_mode - XFER_PIO_0; u8 tf_pio = pio; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; u8 addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84) : (mmio ? 0xB4 : 0x80); u8 mode = 0; u8 unit = drive->dn & 1; if (pair) { u8 pair_pio = pair->pio_mode - XFER_PIO_0; if (pair_pio < tf_pio) tf_pio = pair_pio; } speedp = data_speed[pio]; speedt = tf_speed[tf_pio]; sil_iowrite16(dev, speedp, addr); sil_iowrite16(dev, speedt, tfaddr); speedp = sil_ioread16(dev, tfaddr - 2); speedp &= ~0x200; mode = sil_ioread8(dev, base + addr_mask); mode &= ~(unit ? 0x30 : 0x03); if (ide_pio_need_iordy(drive, pio)) { speedp |= 0x200; mode |= unit ? 0x10 : 0x01; } sil_iowrite16(dev, speedp, tfaddr - 2); sil_iowrite8(dev, mode, base + addr_mask); }
static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio) { unsigned int cycle_time; 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 */ cycle_time = ide_pio_cycle_time(drive, pio); mate = ide_get_pair_dev(drive); palm_bk3710_setpiomode(base, mate, is_slave, cycle_time, pio); }
int generic_ide_resume(struct device *dev) { ide_drive_t *drive = dev_get_drvdata(dev); ide_drive_t *pair = ide_get_pair_dev(drive); ide_hwif_t *hwif = drive->hwif; struct request *rq; struct request_pm_state rqpm; int err; if (ide_port_acpi(hwif)) { /* call ACPI _PS0 / _STM only once */ if ((drive->dn & 1) == 0 || pair == NULL) { ide_acpi_set_state(hwif, 1); ide_acpi_push_timing(hwif); } ide_acpi_exec_tfs(drive); } memset(&rqpm, 0, sizeof(rqpm)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_RESUME; rq->cmd_flags |= REQ_PREEMPT; rq->special = &rqpm; rqpm.pm_step = IDE_PM_START_RESUME; rqpm.pm_state = PM_EVENT_ON; err = blk_execute_rq(drive->queue, NULL, rq, 1); blk_put_request(rq); if (err == 0 && dev->driver) { struct ide_driver *drv = to_ide_driver(dev->driver); if (drv->resume) drv->resume(drive); } return err; }
static void opti621_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { ide_drive_t *pair = ide_get_pair_dev(drive); unsigned long flags; unsigned long mode = drive->pio_mode, pair_mode; const u8 pio = mode - XFER_PIO_0; u8 tim, misc, addr_pio = pio, clk; static const u8 addr_timings[2][5] = { { 0x20, 0x10, 0x00, 0x00, 0x00 }, { 0x10, 0x10, 0x00, 0x00, 0x00 }, }; static const u8 data_rec_timings[2][5] = { { 0x5b, 0x45, 0x32, 0x21, 0x20 }, { 0x48, 0x34, 0x21, 0x10, 0x10 } }; ide_set_drivedata(drive, (void *)mode); if (pair) { pair_mode = (unsigned long)ide_get_drivedata(pair); if (pair_mode && pair_mode < mode) addr_pio = pair_mode - XFER_PIO_0; } spin_lock_irqsave(&opti621_lock, flags); reg_base = hwif->io_ports.data_addr; outb(0xc0, reg_base + CNTRL_REG); outb(0xff, reg_base + 5); (void)inb(reg_base + CNTRL_REG); read_reg(CNTRL_REG); clk = read_reg(STRAP_REG) & 1; printk(KERN_INFO "%s: CLK = %d MHz\n", hwif->name, clk ? 25 : 33); tim = data_rec_timings[clk][pio]; misc = addr_timings[clk][addr_pio]; write_reg(drive->dn & 1, MISC_REG); write_reg(tim, READ_REG); write_reg(tim, WRITE_REG); write_reg(0x85, CNTRL_REG); write_reg(misc, MISC_REG); spin_unlock_irqrestore(&opti621_lock, flags); }
static void cmd64x_program_timings(ide_drive_t *drive, u8 mode) { ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(drive->hwif->dev); int bus_speed = ide_pci_clk ? ide_pci_clk : 33; const unsigned long T = 1000000 / bus_speed; static const u8 recovery_values[] = {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}; static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; static const u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM2, DRWTIM3}; struct ide_timing t; u8 arttim = 0; ide_timing_compute(drive, mode, &t, T, 0); /* * In case we've got too long recovery phase, try to lengthen * the active phase */ if (t.recover > 16) { t.active += t.recover - 16; t.recover = 16; } if (t.active > 16) /* shouldn't actually happen... */ t.active = 16; /* * Convert values to internal chipset representation */ t.recover = recovery_values[t.recover]; t.active &= 0x0f; /* Program the active/recovery counts into the DRWTIM register */ pci_write_config_byte(dev, drwtim_regs[drive->dn], (t.active << 4) | t.recover); /* * The primary channel has individual address setup timing registers * for each drive and the hardware selects the slowest timing itself. * The secondary channel has one common register and we have to select * the slowest address setup timing ourselves. */ if (hwif->channel) { ide_drive_t *pair = ide_get_pair_dev(drive); if (pair) { struct ide_timing tp; ide_timing_compute(pair, pair->pio_mode, &tp, T, 0); ide_timing_merge(&t, &tp, &t, IDE_TIMING_SETUP); if (pair->dma_mode) { ide_timing_compute(pair, pair->dma_mode, &tp, T, 0); ide_timing_merge(&tp, &t, &t, IDE_TIMING_SETUP); } } } if (t.setup > 5) /* shouldn't actually happen... */ t.setup = 5; /* * Program the address setup clocks into the ARTTIM registers. * Avoid clearing the secondary channel's interrupt bit. */ (void) pci_read_config_byte (dev, arttim_regs[drive->dn], &arttim); if (hwif->channel) arttim &= ~ARTTIM23_INTR_CH1; arttim &= ~0xc0; arttim |= setup_values[t.setup]; (void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim); }
static void opti621_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { ide_drive_t *pair = ide_get_pair_dev(drive); unsigned long flags; unsigned long mode = drive->pio_mode, pair_mode; const u8 pio = mode - XFER_PIO_0; u8 tim, misc, addr_pio = pio, clk; /* DRDY is default 2 (by OPTi Databook) */ static const u8 addr_timings[2][5] = { { 0x20, 0x10, 0x00, 0x00, 0x00 }, /* 33 MHz */ { 0x10, 0x10, 0x00, 0x00, 0x00 }, /* 25 MHz */ }; static const u8 data_rec_timings[2][5] = { { 0x5b, 0x45, 0x32, 0x21, 0x20 }, /* 33 MHz */ { 0x48, 0x34, 0x21, 0x10, 0x10 } /* 25 MHz */ }; ide_set_drivedata(drive, (void *)mode); if (pair) { pair_mode = (unsigned long)ide_get_drivedata(pair); if (pair_mode && pair_mode < mode) addr_pio = pair_mode - XFER_PIO_0; } spin_lock_irqsave(&opti621_lock, flags); reg_base = hwif->io_ports.data_addr; /* allow Register-B */ outb(0xc0, reg_base + CNTRL_REG); /* hmm, setupvic.exe does this ;-) */ outb(0xff, reg_base + 5); /* if reads 0xff, adapter not exist? */ (void)inb(reg_base + CNTRL_REG); /* if reads 0xc0, no interface exist? */ read_reg(CNTRL_REG); /* check CLK speed */ clk = read_reg(STRAP_REG) & 1; printk(KERN_INFO "%s: CLK = %d MHz\n", hwif->name, clk ? 25 : 33); tim = data_rec_timings[clk][pio]; misc = addr_timings[clk][addr_pio]; /* select Index-0/1 for Register-A/B */ write_reg(drive->dn & 1, MISC_REG); /* set read cycle timings */ write_reg(tim, READ_REG); /* set write cycle timings */ write_reg(tim, WRITE_REG); /* use Register-A for drive 0 */ /* use Register-B for drive 1 */ write_reg(0x85, CNTRL_REG); /* set address setup, DRDY timings, */ /* and read prefetch for both drives */ write_reg(misc, MISC_REG); spin_unlock_irqrestore(&opti621_lock, flags); }