Ejemplo n.º 1
0
/*
 * 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);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
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]);
}
Ejemplo n.º 7
0
/*
 * 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;
}
Ejemplo n.º 8
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);
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
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 */
	}
}
Ejemplo n.º 12
0
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;    /*                 */
	}
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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]);
}
Ejemplo n.º 16
0
/*
 * 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);
}
Ejemplo n.º 17
0
/*
 * 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);
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
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;
}