示例#1
0
static int
set_timings_mdma(int intf, u32 *timings, byte speed)
{
	int cycleTime, accessTime;
	int accessTicks, recTicks;

	/* Calculate accesstime and cycle time */
	cycleTime = mdma_timings[speed & 0xf].cycleTime;
	accessTime = mdma_timings[speed & 0xf].accessTime;
	if ((pmac_ide[intf].kind == controller_ohare) && (cycleTime < 150))
		cycleTime = 150;

	/* For ata-4 controller */
	if (pmac_ide[intf].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[intf].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;
	}
	return 0;
}
示例#2
0
/* Calculate PIO timings */
static void
pmac_ide_tuneproc(ide_drive_t *drive, byte pio)
{
	ide_pio_data_t d;
	int i;
	u32 *timings;
	int accessTicks, recTicks;
	
	i = pmac_ide_find(drive);
	if (i < 0)
		return;
		
	pio = ide_get_best_pio_mode(drive, pio, 4, &d);
	accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time);
	if (drive->select.all & 0x10)
		timings = &pmac_ide[i].timings[1];
	else
		timings = &pmac_ide[i].timings[0];
	
	if (pmac_ide[i].kind == controller_kl_ata4) {
		/* The "ata-4" IDE controller of Core99 machines */
		accessTicks = SYSCLK_TICKS_UDMA(ide_pio_timings[pio].active_time * 1000);
		recTicks = SYSCLK_TICKS_UDMA(d.cycle_time * 1000) - accessTicks;

		*timings = ((*timings) & 0x1FFFFFC00) | accessTicks | (recTicks << 5);
	} else {
		/* The old "ata-3" IDE controller */
		accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time);
		if (accessTicks < 4)
			accessTicks = 4;
		recTicks = SYSCLK_TICKS(d.cycle_time) - accessTicks - 4;
		if (recTicks < 1)
			recTicks = 1;
	
		*timings = ((*timings) & 0xFFFFFF800) | accessTicks | (recTicks << 5);
	}

#ifdef IDE_PMAC_DEBUG
	printk(KERN_ERR "ide_pmac: Set PIO timing for mode %d, reg: 0x%08x\n",
		pio,  *timings);
#endif	
		
	if (drive->select.all == IN_BYTE(IDE_SELECT_REG))
		pmac_ide_selectproc(drive);
}
示例#3
0
文件: pmac.c 项目: AK101111/linux
/*
 * Calculate MDMA timings for all cells
 */
static void
set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
		 	u8 speed)
{
	u16 *id = drive->id;
	int cycleTime, accessTime = 0, recTime = 0;
	unsigned accessTicks, recTicks;
	struct mdma_timings_t* tm = NULL;
	int i;

	/* Get default cycle time for mode */
	switch(speed & 0xf) {
		case 0: cycleTime = 480; break;
		case 1: cycleTime = 150; break;
		case 2: cycleTime = 120; break;
		default:
			BUG();
			break;
	}

	/* Check if drive provides explicit DMA cycle time */
	if ((id[ATA_ID_FIELD_VALID] & 2) && id[ATA_ID_EIDE_DMA_TIME])
		cycleTime = max_t(int, id[ATA_ID_EIDE_DMA_TIME], cycleTime);

	/* OHare limits according to some old Apple sources */	
	if ((intf_type == controller_ohare) && (cycleTime < 150))
		cycleTime = 150;
	/* Get the proper timing array for this controller */
	switch(intf_type) {
	        case controller_sh_ata6:
		case controller_un_ata6:
		case controller_k2_ata6:
			break;
		case controller_kl_ata4:
			tm = mdma_timings_66;
			break;
		case controller_kl_ata3:
			tm = mdma_timings_33k;
			break;
		default:
			tm = mdma_timings_33;
			break;
	}
	if (tm != NULL) {
		/* Lookup matching access & recovery times */
		i = -1;
		for (;;) {
			if (tm[i+1].cycleTime < cycleTime)
				break;
			i++;
		}
		cycleTime = tm[i].cycleTime;
		accessTime = tm[i].accessTime;
		recTime = tm[i].recoveryTime;

#ifdef IDE_PMAC_DEBUG
		printk(KERN_ERR "%s: MDMA, cycleTime: %d, accessTime: %d, recTime: %d\n",
			drive->name, cycleTime, accessTime, recTime);
#endif
	}
	switch(intf_type) {
	case controller_sh_ata6: {
		/* 133Mhz cell */
		u32 tr = kauai_lookup_timing(shasta_mdma_timings, cycleTime);
		*timings = ((*timings) & ~TR_133_PIOREG_MDMA_MASK) | tr;
		*timings2 = (*timings2) & ~TR_133_UDMAREG_UDMA_EN;
		}
		break;
	case controller_un_ata6:
	case controller_k2_ata6: {
		/* 100Mhz cell */
		u32 tr = kauai_lookup_timing(kauai_mdma_timings, cycleTime);
		*timings = ((*timings) & ~TR_100_PIOREG_MDMA_MASK) | tr;
		*timings2 = (*timings2) & ~TR_100_UDMAREG_UDMA_EN;
		}
		break;
	case controller_kl_ata4:
		/* 66Mhz cell */
		accessTicks = SYSCLK_TICKS_66(accessTime);
		accessTicks = min(accessTicks, 0x1fU);
		accessTicks = max(accessTicks, 0x1U);
		recTicks = SYSCLK_TICKS_66(recTime);
		recTicks = min(recTicks, 0x1fU);
		recTicks = max(recTicks, 0x3U);
		/* Clear out mdma bits and disable udma */
		*timings = ((*timings) & ~(TR_66_MDMA_MASK | TR_66_UDMA_MASK)) |
			(accessTicks << TR_66_MDMA_ACCESS_SHIFT) |
			(recTicks << TR_66_MDMA_RECOVERY_SHIFT);
		break;
	case controller_kl_ata3:
		/* 33Mhz cell on KeyLargo */
		accessTicks = SYSCLK_TICKS(accessTime);
		accessTicks = max(accessTicks, 1U);
		accessTicks = min(accessTicks, 0x1fU);
		accessTime = accessTicks * IDE_SYSCLK_NS;
		recTicks = SYSCLK_TICKS(recTime);
		recTicks = max(recTicks, 1U);
		recTicks = min(recTicks, 0x1fU);
		*timings = ((*timings) & ~TR_33_MDMA_MASK) |
				(accessTicks << TR_33_MDMA_ACCESS_SHIFT) |
				(recTicks << TR_33_MDMA_RECOVERY_SHIFT);
		break;
	default: {
		/* 33Mhz cell on others */
		int halfTick = 0;
		int origAccessTime = accessTime;
		int origRecTime = recTime;
		
		accessTicks = SYSCLK_TICKS(accessTime);
		accessTicks = max(accessTicks, 1U);
		accessTicks = min(accessTicks, 0x1fU);
		accessTime = accessTicks * IDE_SYSCLK_NS;
		recTicks = SYSCLK_TICKS(recTime);
		recTicks = max(recTicks, 2U) - 1;
		recTicks = min(recTicks, 0x1fU);
		recTime = (recTicks + 1) * IDE_SYSCLK_NS;
		if ((accessTicks > 1) &&
		    ((accessTime - IDE_SYSCLK_NS/2) >= origAccessTime) &&
		    ((recTime - IDE_SYSCLK_NS/2) >= origRecTime)) {
            		halfTick = 1;
			accessTicks--;
		}
		*timings = ((*timings) & ~TR_33_MDMA_MASK) |
				(accessTicks << TR_33_MDMA_ACCESS_SHIFT) |
				(recTicks << TR_33_MDMA_RECOVERY_SHIFT);
		if (halfTick)
			*timings |= TR_33_MDMA_HALFTICK;
		}
	}
#ifdef IDE_PMAC_DEBUG
	printk(KERN_ERR "%s: Set MDMA timing for mode %d, reg: 0x%08x\n",
		drive->name, speed & 0xf,  *timings);
#endif	
}
示例#4
0
文件: pmac.c 项目: AK101111/linux
/*
 * 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);
}
示例#5
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;
}