Ejemplo n.º 1
0
/* Calculate Ultra DMA timings */
static int
pmac_ide_udma_enable(ide_drive_t *drive, int idx)
{
	byte bits = drive->id->dma_ultra & 0x1f;
	byte feature = udma_bits_to_command(bits);
	int cycleTime, accessTime;
	int rdyToPauseTicks, cycleTicks;
	u32 *timings;
	
	/* Set feature on drive */
    	printk("%s: Enabling Ultra DMA %d\n", drive->name, feature & 0xf);
	if (pmac_ide_do_setfeature(drive, feature)) {
		printk("%s: Failed !\n", drive->name);
		return 0;
	}

	/* which drive is it ? */
	if (drive->select.all & 0x10)
		timings = &pmac_ide[idx].timings[1];
	else
		timings = &pmac_ide[idx].timings[0];
	

	cycleTime = udma_timings[feature & 0xf].cycleTime;
	accessTime = udma_timings[feature & 0xf].accessTime;

	rdyToPauseTicks = SYSCLK_TICKS_UDMA(accessTime * 1000);
	cycleTicks = SYSCLK_TICKS_UDMA(cycleTime * 1000);
	
	*timings = ((*timings) & 0xe00fffff) |
			((cycleTicks << 1) | (rdyToPauseTicks << 5) | 1) << 20;
	return 1;
}
Ejemplo n.º 2
0
/* You may notice we don't use this function on normal operation,
 * our, normal mdma function is supposed to be more precise
 */
static int
pmac_ide_tune_chipset (ide_drive_t *drive, byte speed)
{
	int intf		= pmac_ide_find(drive);
	int unit		= (drive->select.all & 0x10) ? 1:0;
	int ret			= 0;
	u32 *timings;

	if (intf < 0)
		return 1;
		
	timings = &pmac_ide[intf].timings[unit];
	
	switch(speed) {
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
		case XFER_UDMA_4:
		case XFER_UDMA_3:
		case XFER_UDMA_2:
		case XFER_UDMA_1:
		case XFER_UDMA_0:
			ret = set_timings_udma(intf, timings, speed);
			break;
		case XFER_MW_DMA_2:
		case XFER_MW_DMA_1:
		case XFER_MW_DMA_0:
		case XFER_SW_DMA_2:
		case XFER_SW_DMA_1:
		case XFER_SW_DMA_0:
			ret = set_timings_mdma(intf, timings, speed);
			break;
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
		case XFER_PIO_4:
		case XFER_PIO_3:
		case XFER_PIO_2:
		case XFER_PIO_1:
		case XFER_PIO_0:
			pmac_ide_tuneproc(drive, speed & 0x07);
			break;
		default:
			ret = 1;
	}
	if (ret)
		return ret;

	ret = pmac_ide_do_setfeature(drive, speed);
	if (ret)
		return ret;
		
	pmac_ide_selectproc(drive);	
	drive->current_speed = speed;

	return 0;
}
Ejemplo n.º 3
0
/* Calculate MultiWord DMA timings */
static int
pmac_ide_mdma_enable(ide_drive_t *drive, int idx)
{
	byte bits = drive->id->dma_mword & 0x07;
	byte feature = dma_bits_to_command(bits);
	u32 *timings;
	int cycleTime, accessTime;
	int accessTicks, recTicks;
	struct hd_driveid *id = drive->id;
	int ret;

	/* Set feature on drive */
    	printk(KERN_INFO "%s: Enabling MultiWord DMA %d\n", drive->name, feature & 0xf);
	ret = pmac_ide_do_setfeature(drive, feature);
	if (ret) {
	    	printk(KERN_WARNING "%s: Failed !\n", drive->name);
	    	return 0;
	}

	if (!drive->init_speed)
		drive->init_speed = feature;
	
	/* which drive is it ? */
	if (drive->select.all & 0x10)
		timings = &pmac_ide[idx].timings[1];
	else
		timings = &pmac_ide[idx].timings[0];

	/* Calculate accesstime and cycle time */
	cycleTime = mdma_timings[feature & 0xf].cycleTime;
	accessTime = mdma_timings[feature & 0xf].accessTime;
	if ((id->field_valid & 2) && (id->eide_dma_time))
		cycleTime = id->eide_dma_time;
	if ((pmac_ide[idx].kind == controller_ohare) && (cycleTime < 150))
		cycleTime = 150;

	/* For ata-4 controller */
	if (pmac_ide[idx].kind == controller_kl_ata4) {
		accessTicks = SYSCLK_TICKS_UDMA(accessTime * 1000);
		recTicks = SYSCLK_TICKS_UDMA(cycleTime * 1000) - accessTicks;
		*timings = ((*timings) & 0xffe003ff) |
			(accessTicks | (recTicks << 5)) << 10;
	} else {
		int halfTick = 0;
		int origAccessTime = accessTime;
		int origCycleTime = cycleTime;
		
		accessTicks = SYSCLK_TICKS(accessTime);
		if (accessTicks < 1)
			accessTicks = 1;
		accessTime = accessTicks * IDE_SYSCLK_NS;
		recTicks = SYSCLK_TICKS(cycleTime - accessTime) - 1;
		if (recTicks < 1)
			recTicks = 1;
		cycleTime = (recTicks + 1 + accessTicks) * IDE_SYSCLK_NS;

		/* KeyLargo ata-3 don't support the half-tick stuff */
		if ((pmac_ide[idx].kind != controller_kl_ata3) &&
			(accessTicks > 1) &&
			((accessTime - IDE_SYSCLK_NS/2) >= origAccessTime) &&
			((cycleTime - IDE_SYSCLK_NS) >= origCycleTime)) {
            			halfTick    = 1;
				accessTicks--;
		}
		*timings = ((*timings) & 0x7FF) |
			(accessTicks | (recTicks << 5) | (halfTick << 10)) << 11;
	}
#ifdef IDE_PMAC_DEBUG
	printk(KERN_INFO "ide_pmac: Set MDMA timing for mode %d, reg: 0x%08x\n",
		feature & 0xf, *timings);
#endif
	drive->current_speed = feature;	
	return 1;
}