/* * Set PIO mode for the specified drive. * This function computes timing parameters * and sets controller registers accordingly. */ static void ali14xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { int driveNum; int time1, time2; u8 param1, param2, param3, param4; unsigned long flags; int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; const u8 pio = drive->pio_mode - XFER_PIO_0; struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); /* calculate timing, according to PIO mode */ time1 = ide_pio_cycle_time(drive, pio); time2 = t->active; param3 = param1 = (time2 * bus_speed + 999) / 1000; param4 = param2 = (time1 * bus_speed + 999) / 1000 - param1; if (pio < 3) { param3 += 8; param4 += 8; } printk(KERN_DEBUG "%s: PIO mode%d, t1=%dns, t2=%dns, cycles = %d+%d, %d+%d\n", drive->name, pio, time1, time2, param1, param2, param3, param4); /* stuff timing parameters into controller registers */ driveNum = (drive->hwif->index << 1) + (drive->dn & 1); spin_lock_irqsave(&ali14xx_lock, flags); outb_p(regOn, basePort); outReg(param1, regTab[driveNum].reg1); outReg(param2, regTab[driveNum].reg2); outReg(param3, regTab[driveNum].reg3); outReg(param4, regTab[driveNum].reg4); outb_p(regOff, basePort); spin_unlock_irqrestore(&ali14xx_lock, flags); }
static void palm_bk3710_setdmamode(void __iomem *base, unsigned int dev, unsigned short min_cycle, unsigned int mode) { u8 td, tkw, t0; u32 val32; u16 val16; struct ide_timing *t; int cycletime; t = ide_timing_find_mode(mode); cycletime = max_t(int, t->cycle, min_cycle); /* DMA Data Setup */ t0 = DIV_ROUND_UP(cycletime, ideclk_period); td = DIV_ROUND_UP(t->active, ideclk_period); tkw = t0 - td - 1; td -= 1; val32 = readl(base + BK3710_DMASTB) & (0xFF << (dev ? 0 : 8)); val32 |= (td << (dev ? 8 : 0)); writel(val32, base + BK3710_DMASTB); val32 = readl(base + BK3710_DMARCVR) & (0xFF << (dev ? 0 : 8)); val32 |= (tkw << (dev ? 8 : 0)); writel(val32, base + BK3710_DMARCVR); /* Disable UDMA for Device */ val16 = readw(base + BK3710_UDMACTL) & ~(1 << dev); writew(val16, base + BK3710_UDMACTL); }
static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate, unsigned int dev, unsigned int cycletime, unsigned int mode) { u8 t2, t2i, t0; u32 val32; struct ide_timing *t; /* PIO Data Setup */ t0 = (cycletime + ideclk_period - 1) / ideclk_period; t2 = (ide_timing_find_mode(XFER_PIO_0 + mode)->active + ideclk_period - 1) / ideclk_period; t2i = t0 - t2 - 1; t2 -= 1; val32 = readl(base + BK3710_DATSTB) & (0xFF << (dev ? 0 : 8)); val32 |= (t2 << (dev ? 8 : 0)); writel(val32, base + BK3710_DATSTB); val32 = readl(base + BK3710_DATRCVR) & (0xFF << (dev ? 0 : 8)); val32 |= (t2i << (dev ? 8 : 0)); writel(val32, base + BK3710_DATRCVR); if (mate && mate->present) { u8 mode2 = ide_get_best_pio_mode(mate, 255, 4, NULL); if (mode2 < mode) mode = mode2; } /* TASKFILE Setup */ t = ide_timing_find_mode(XFER_PIO_0 + mode); t0 = (t->cyc8b + ideclk_period - 1) / ideclk_period; t2 = (t->act8b + ideclk_period - 1) / ideclk_period; t2i = t0 - t2 - 1; t2 -= 1; val32 = readl(base + BK3710_REGSTB) & (0xFF << (dev ? 0 : 8)); val32 |= (t2 << (dev ? 8 : 0)); writel(val32, base + BK3710_REGSTB); val32 = readl(base + BK3710_REGRCVR) & (0xFF << (dev ? 0 : 8)); val32 |= (t2i << (dev ? 8 : 0)); writel(val32, base + BK3710_REGRCVR); }
static void cmd640_set_mode(ide_drive_t *drive, unsigned int index, u8 pio_mode, unsigned int cycle_time) { struct ide_timing *t; int setup_time, active_time, recovery_time, clock_time; u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count; int bus_speed; if (cmd640_vlb) bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; else bus_speed = ide_pci_clk ? ide_pci_clk : 33; if (pio_mode > 5) pio_mode = 5; t = ide_timing_find_mode(XFER_PIO_0 + pio_mode); setup_time = t->setup; active_time = t->active; recovery_time = cycle_time - (setup_time + active_time); clock_time = 1000 / bus_speed; cycle_count = DIV_ROUND_UP(cycle_time, clock_time); setup_count = DIV_ROUND_UP(setup_time, clock_time); active_count = DIV_ROUND_UP(active_time, clock_time); if (active_count < 2) active_count = 2; recovery_count = DIV_ROUND_UP(recovery_time, clock_time); recovery_count2 = cycle_count - (setup_count + active_count); if (recovery_count2 > recovery_count) recovery_count = recovery_count2; if (recovery_count < 2) recovery_count = 2; if (recovery_count > 17) { active_count += recovery_count - 17; recovery_count = 17; } if (active_count > 16) active_count = 16; if (cmd640_chip_version > 1) recovery_count -= 1; if (recovery_count > 16) recovery_count = 16; setup_counts[index] = setup_count; active_counts[index] = active_count; recovery_counts[index] = recovery_count; program_drive_counts(drive, index); }
int ide_timing_compute(ide_drive_t *drive, u8 speed, struct ide_timing *t, int T, int UT) { u16 *id = drive->id; struct ide_timing *s, p; s = ide_timing_find_mode(speed); if (s == NULL) return -EINVAL; *t = *s; if (id[ATA_ID_FIELD_VALID] & 2) { memset(&p, 0, sizeof(p)); if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO]; else if ((speed <= XFER_PIO_4) || (speed == XFER_PIO_5 && !ata_id_is_cfa(id))) p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY]; else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) p.cycle = id[ATA_ID_EIDE_DMA_MIN]; ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B); } ide_timing_quantize(t, t, T, UT); if (speed >= XFER_SW_DMA_0) { u8 pio = ide_get_best_pio_mode(drive, 255, 5); ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT); ide_timing_merge(&p, t, t, IDE_TIMING_ALL); } if (t->act8b + t->rec8b < t->cyc8b) { t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2; t->rec8b = t->cyc8b - t->act8b; } if (t->active + t->recover < t->cycle) { t->active += (t->cycle - (t->active + t->recover)) / 2; t->recover = t->cycle - t->active; } return 0; }
/* * 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]); }
/* * Calculate Shasta ATA/133 UDMA timings */ static int set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed) { struct ide_timing *t = ide_timing_find_mode(speed); u32 tr; if (speed > XFER_UDMA_6 || t == NULL) return 1; tr = kauai_lookup_timing(shasta_udma133_timings, (int)t->udma); *ultra_timings = ((*ultra_timings) & ~TR_133_UDMAREG_UDMA_MASK) | tr; *ultra_timings = (*ultra_timings) | TR_133_UDMAREG_UDMA_EN; return 0; }
static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); int s_time = t->setup, a_time = t->active, c_time = t->cycle; u8 s_clc, a_clc, r_clc; unsigned long flags; int bus_speed = ide_pci_clk ? ide_pci_clk : 33; int port = hwif->channel ? 0x5c : 0x58; int portFIFO = hwif->channel ? 0x55 : 0x54; u8 cd_dma_fifo = 0, unit = drive->dn & 1; if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8) s_clc = 0; if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8) a_clc = 0; if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) { r_clc = 1; } else { if (r_clc >= 16) r_clc = 0; } local_irq_save(flags); /* * PIO mode => ATA FIFO on, ATAPI FIFO off */ pci_read_config_byte(dev, portFIFO, &cd_dma_fifo); if (drive->media==ide_disk) { if (unit) { pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0x0F) | 0x50); } else { pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0xF0) | 0x05); } } else { if (unit) { pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0x0F); } else { pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0xF0); } } pci_write_config_byte(dev, port, s_clc); pci_write_config_byte(dev, port + unit + 2, (a_clc << 4) | r_clc); local_irq_restore(flags); }
static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) { struct ide_timing *timing; u8 chipselect = drive->hwif->select_data; int use_iordy = 0; pdbg("chipselect %u pio %u\n", chipselect, pio); timing = ide_timing_find_mode(XFER_PIO_0 + pio); BUG_ON(!timing); if (ide_pio_need_iordy(drive, pio)) use_iordy = 1; apply_timings(chipselect, pio, timing, use_iordy); }
static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate, unsigned int dev, unsigned int cycletime, unsigned int mode) { u8 t2, t2i, t0; u32 val32; struct ide_timing *t; t = ide_timing_find_mode(XFER_PIO_0 + mode); /* PIO Data Setup */ t0 = DIV_ROUND_UP(cycletime, ideclk_period); t2 = DIV_ROUND_UP(t->active, ideclk_period); t2i = t0 - t2 - 1; t2 -= 1; val32 = readl(base + BK3710_DATSTB) & (0xFF << (dev ? 0 : 8)); val32 |= (t2 << (dev ? 8 : 0)); writel(val32, base + BK3710_DATSTB); val32 = readl(base + BK3710_DATRCVR) & (0xFF << (dev ? 0 : 8)); val32 |= (t2i << (dev ? 8 : 0)); writel(val32, base + BK3710_DATRCVR); if (mate) { u8 mode2 = mate->pio_mode - XFER_PIO_0; if (mode2 < mode) mode = mode2; } /* TASKFILE Setup */ t0 = DIV_ROUND_UP(t->cyc8b, ideclk_period); t2 = DIV_ROUND_UP(t->act8b, ideclk_period); t2i = t0 - t2 - 1; t2 -= 1; val32 = readl(base + BK3710_REGSTB) & (0xFF << (dev ? 0 : 8)); val32 |= (t2 << (dev ? 8 : 0)); writel(val32, base + BK3710_REGSTB); val32 = readl(base + BK3710_REGRCVR) & (0xFF << (dev ? 0 : 8)); val32 |= (t2i << (dev ? 8 : 0)); writel(val32, base + BK3710_REGRCVR); }
static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio) { int active_time, recovery_time; int active_cycles, recovery_cycles; int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; if (pio) { unsigned int cycle_time; struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); cycle_time = ide_pio_cycle_time(drive, pio); /* * Just like opti621.c we try to calculate the * actual cycle time for recovery and activity * according system bus speed. */ active_time = t->active; recovery_time = cycle_time - active_time - t->setup; /* * Cycle times should be Vesa bus cycles */ active_cycles = (active_time * bus_speed + 999) / 1000; recovery_cycles = (recovery_time * bus_speed + 999) / 1000; /* * Upper and lower limits */ if (active_cycles < 2) active_cycles = 2; if (recovery_cycles < 2) recovery_cycles = 2; if (active_cycles > 15) active_cycles = 15; if (recovery_cycles > 15) recovery_cycles = 0; /* 0==16 */ #ifdef DEBUG printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n", drive->name, pio, recovery_cycles, recovery_time, active_cycles, active_time); #endif return (u8)((recovery_cycles << 4) | active_cycles); } else { #ifdef DEBUG printk("ht6560b: drive %s setting pio=0\n", drive->name); #endif return HT_TIMING_DEFAULT; /* default setting */ } }
static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio) { int active_time, recovery_time; int active_cycles, recovery_cycles; int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; if (pio) { unsigned int cycle_time; struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); cycle_time = ide_pio_cycle_time(drive, pio); /* */ active_time = t->active; recovery_time = cycle_time - active_time - t->setup; /* */ active_cycles = (active_time * bus_speed + 999) / 1000; recovery_cycles = (recovery_time * bus_speed + 999) / 1000; /* */ if (active_cycles < 2) active_cycles = 2; if (recovery_cycles < 2) recovery_cycles = 2; if (active_cycles > 15) active_cycles = 15; if (recovery_cycles > 15) recovery_cycles = 0; /* */ #ifdef DEBUG printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n", drive->name, pio, recovery_cycles, recovery_time, active_cycles, active_time); #endif return (u8)((recovery_cycles << 4) | active_cycles); } else { #ifdef DEBUG printk("ht6560b: drive %s setting pio=0\n", drive->name); #endif return HT_TIMING_DEFAULT; /* */ } }
u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio) { u16 *id = drive->id; struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); u16 cycle = 0; if (id[ATA_ID_FIELD_VALID] & 2) { if (ata_id_has_iordy(drive->id)) cycle = id[ATA_ID_EIDE_PIO_IORDY]; else cycle = id[ATA_ID_EIDE_PIO]; /* conservative "downgrade" for all pre-ATA2 drives */ if (pio < 3 && cycle < t->cycle) cycle = 0; /* use standard timing */ } return cycle ? cycle : t->cycle; }
u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio) { u16 *id = drive->id; struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); u16 cycle = 0; if (id[ATA_ID_FIELD_VALID] & 2) { if (ata_id_has_iordy(drive->id)) cycle = id[ATA_ID_EIDE_PIO_IORDY]; else cycle = id[ATA_ID_EIDE_PIO]; if (pio < 3 && cycle < t->cycle) cycle = 0; if (pio > 4 && ata_id_is_cfa(id)) cycle = 0; } return cycle ? cycle : t->cycle; }
static void tx4938ide_tune_ebusc(unsigned int ebus_ch, unsigned int gbus_clock, u8 pio) { struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); u64 cr = __raw_readq(&tx4938_ebuscptr->cr[ebus_ch]); unsigned int sp = (cr >> 4) & 3; unsigned int clock = gbus_clock / (4 - sp); unsigned int cycle = 1000000000 / clock; unsigned int shwt; int wt; /* Minimum DIOx- active time */ wt = DIV_ROUND_UP(t->act8b, cycle) - 2; /* IORDY setup time: 35ns */ wt = max_t(int, wt, DIV_ROUND_UP(35, cycle)); /* actual wait-cycle is max(wt & ~1, 1) */ if (wt > 2 && (wt & 1)) wt++; wt &= ~1; /* Address-valid to DIOR/DIOW setup */ shwt = DIV_ROUND_UP(t->setup, cycle); /* -DIOx recovery time (SHWT * 4) and cycle time requirement */ while ((shwt * 4 + wt + (wt ? 2 : 3)) * cycle < t->cycle) shwt++; if (shwt > 7) { pr_warning("tx4938ide: SHWT violation (%d)\n", shwt); shwt = 7; } pr_debug("tx4938ide: ebus %d, bus cycle %dns, WT %d, SHWT %d\n", ebus_ch, cycle, wt, shwt); __raw_writeq((cr & ~0x3f007ull) | (wt << 12) | shwt, &tx4938_ebuscptr->cr[ebus_ch]); }
/* * Set a specific pio_mode for a drive */ static void cmd640_set_mode(ide_drive_t *drive, unsigned int index, u8 pio_mode, unsigned int cycle_time) { struct ide_timing *t; int setup_time, active_time, recovery_time, clock_time; u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count; int bus_speed; if (cmd640_vlb) bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; else bus_speed = ide_pci_clk ? ide_pci_clk : 33; if (pio_mode > 5) pio_mode = 5; t = ide_timing_find_mode(XFER_PIO_0 + pio_mode); setup_time = t->setup; active_time = t->active; recovery_time = cycle_time - (setup_time + active_time); clock_time = 1000 / bus_speed; cycle_count = DIV_ROUND_UP(cycle_time, clock_time); setup_count = DIV_ROUND_UP(setup_time, clock_time); active_count = DIV_ROUND_UP(active_time, clock_time); if (active_count < 2) active_count = 2; /* minimum allowed by cmd640 */ recovery_count = DIV_ROUND_UP(recovery_time, clock_time); recovery_count2 = cycle_count - (setup_count + active_count); if (recovery_count2 > recovery_count) recovery_count = recovery_count2; if (recovery_count < 2) recovery_count = 2; /* minimum allowed by cmd640 */ if (recovery_count > 17) { active_count += recovery_count - 17; recovery_count = 17; } if (active_count > 16) active_count = 16; /* maximum allowed by cmd640 */ if (cmd640_chip_version > 1) recovery_count -= 1; /* cmd640b uses (count + 1)*/ if (recovery_count > 16) recovery_count = 16; /* maximum allowed by cmd640 */ setup_counts[index] = setup_count; active_counts[index] = active_count; recovery_counts[index] = recovery_count; /* * In a perfect world, we might set the drive pio mode here * (using WIN_SETFEATURE) before continuing. * * But we do not, because: * 1) this is the wrong place to do it (proper is do_special() in ide.c) * 2) in practice this is rarely, if ever, necessary */ program_drive_counts(drive, index); }
/* * Old tuning functions (called on hdparm -p), sets up drive PIO timings */ static void pmac_ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent); const u8 pio = drive->pio_mode - XFER_PIO_0; struct ide_timing *tim = ide_timing_find_mode(XFER_PIO_0 + pio); u32 *timings, t; unsigned accessTicks, recTicks; unsigned accessTime, recTime; unsigned int cycle_time; /* which drive is it ? */ timings = &pmif->timings[drive->dn & 1]; t = *timings; cycle_time = ide_pio_cycle_time(drive, pio); switch (pmif->kind) { case controller_sh_ata6: { /* 133Mhz cell */ u32 tr = kauai_lookup_timing(shasta_pio_timings, cycle_time); t = (t & ~TR_133_PIOREG_PIO_MASK) | tr; break; } case controller_un_ata6: case controller_k2_ata6: { /* 100Mhz cell */ u32 tr = kauai_lookup_timing(kauai_pio_timings, cycle_time); t = (t & ~TR_100_PIOREG_PIO_MASK) | tr; break; } case controller_kl_ata4: /* 66Mhz cell */ recTime = cycle_time - tim->active - tim->setup; recTime = max(recTime, 150U); accessTime = tim->active; accessTime = max(accessTime, 150U); accessTicks = SYSCLK_TICKS_66(accessTime); accessTicks = min(accessTicks, 0x1fU); recTicks = SYSCLK_TICKS_66(recTime); recTicks = min(recTicks, 0x1fU); t = (t & ~TR_66_PIO_MASK) | (accessTicks << TR_66_PIO_ACCESS_SHIFT) | (recTicks << TR_66_PIO_RECOVERY_SHIFT); break; default: { /* 33Mhz cell */ int ebit = 0; recTime = cycle_time - tim->active - tim->setup; recTime = max(recTime, 150U); accessTime = tim->active; accessTime = max(accessTime, 150U); accessTicks = SYSCLK_TICKS(accessTime); accessTicks = min(accessTicks, 0x1fU); accessTicks = max(accessTicks, 4U); recTicks = SYSCLK_TICKS(recTime); recTicks = min(recTicks, 0x1fU); recTicks = max(recTicks, 5U) - 4; if (recTicks > 9) { recTicks--; /* guess, but it's only for PIO0, so... */ ebit = 1; } t = (t & ~TR_33_PIO_MASK) | (accessTicks << TR_33_PIO_ACCESS_SHIFT) | (recTicks << TR_33_PIO_RECOVERY_SHIFT); if (ebit) t |= TR_33_PIO_E; break; } } #ifdef IDE_PMAC_DEBUG printk(KERN_ERR "%s: Set PIO timing for mode %d, reg: 0x%08x\n", drive->name, pio, *timings); #endif *timings = t; pmac_ide_do_update_timings(drive); }
static int __init at91_ide_probe(struct platform_device *pdev) { int ret; struct ide_hw hw, *hws[] = { &hw }; struct ide_host *host; struct resource *res; unsigned long tf_base = 0, ctl_base = 0; struct at91_cf_data *board = pdev->dev.platform_data; if (!board) return -ENODEV; if (board->det_pin && at91_get_gpio_value(board->det_pin) != 0) { perr("no device detected\n"); return -ENODEV; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { perr("can't get memory resource\n"); return -ENODEV; } if (!devm_request_mem_region(&pdev->dev, res->start + TASK_FILE, REGS_SIZE, "ide") || !devm_request_mem_region(&pdev->dev, res->start + ALT_MODE, REGS_SIZE, "alt")) { perr("memory resources in use\n"); return -EBUSY; } pdbg("chipselect %u irq %u res %08lx\n", board->chipselect, board->irq_pin, (unsigned long) res->start); tf_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + TASK_FILE, REGS_SIZE); ctl_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + ALT_MODE, REGS_SIZE); if (!tf_base || !ctl_base) { perr("can't map memory regions\n"); return -EBUSY; } memset(&hw, 0, sizeof(hw)); if (board->flags & AT91_IDE_SWAP_A0_A2) { hw.io_ports.data_addr = tf_base + 0; hw.io_ports.error_addr = tf_base + 4; hw.io_ports.nsect_addr = tf_base + 2; hw.io_ports.lbal_addr = tf_base + 6; hw.io_ports.lbam_addr = tf_base + 1; hw.io_ports.lbah_addr = tf_base + 5; hw.io_ports.device_addr = tf_base + 3; hw.io_ports.command_addr = tf_base + 7; hw.io_ports.ctl_addr = ctl_base + 3; } else ide_std_init_ports(&hw, tf_base, ctl_base + 6); hw.irq = board->irq_pin; hw.dev = &pdev->dev; host = ide_host_alloc(&at91_ide_port_info, hws, 1); if (!host) { perr("failed to allocate ide host\n"); return -ENOMEM; } /* setup Static Memory Controller - PIO 0 as default */ apply_timings(board->chipselect, 0, ide_timing_find_mode(XFER_PIO_0), 0); /* with GPIO interrupt we have to do quirks in handler */ if (board->irq_pin >= PIN_BASE) host->irq_handler = at91_irq_handler; host->ports[0]->select_data = board->chipselect; ret = ide_host_register(host, &at91_ide_port_info, hws); if (ret) { perr("failed to register ide host\n"); goto err_free_host; } platform_set_drvdata(pdev, host); return 0; err_free_host: ide_host_free(host); return ret; }
int ide_timing_compute(ide_drive_t *drive, u8 speed, struct ide_timing *t, int T, int UT) { u16 *id = drive->id; struct ide_timing *s, p; /* * Find the mode. */ s = ide_timing_find_mode(speed); if (s == NULL) return -EINVAL; /* * Copy the timing from the table. */ *t = *s; /* * If the drive is an EIDE drive, it can tell us it needs extended * PIO/MWDMA cycle timing. */ if (id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */ memset(&p, 0, sizeof(p)); if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO]; else if (speed <= XFER_PIO_5) p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY]; else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) p.cycle = id[ATA_ID_EIDE_DMA_MIN]; ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B); } /* * Convert the timing to bus clock counts. */ ide_timing_quantize(t, t, T, UT); /* * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, * S.M.A.R.T and some other commands. We have to ensure that the * DMA cycle timing is slower/equal than the fastest PIO timing. */ if (speed >= XFER_SW_DMA_0) { u8 pio = ide_get_best_pio_mode(drive, 255, 5); ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT); ide_timing_merge(&p, t, t, IDE_TIMING_ALL); } /* * Lengthen active & recovery time so that cycle time is correct. */ if (t->act8b + t->rec8b < t->cyc8b) { t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2; t->rec8b = t->cyc8b - t->act8b; } if (t->active + t->recover < t->cycle) { t->active += (t->cycle - (t->active + t->recover)) / 2; t->recover = t->cycle - t->active; } return 0; }