IOReturn AppleKiwiATA::selectIOTimerValue( IOATADevConfig* configRequest, UInt32 unitNumber) { // This particular chip snoops the SetFeatures command, so we just snag what the // driver tells us as info, but don't set the chip in anyway. busTimings[unitNumber].ataPIOSpeedMode = configRequest->getPIOMode(); busTimings[unitNumber].ataPIOCycleTime = configRequest->getPIOCycleTime(); busTimings[unitNumber].ataMultiDMASpeed = configRequest->getDMAMode(); busTimings[unitNumber].ataMultiCycleTime = configRequest->getDMACycleTime(); busTimings[unitNumber].ataUltraDMASpeedMode = configRequest->getUltraMode(); IOLog("AppleKiwiATA: PIO Mode %d UDMA mode %d \n", bitSigToNumeric(busTimings[unitNumber].ataPIOSpeedMode), bitSigToNumeric(busTimings[unitNumber].ataUltraDMASpeedMode) ); // stuff the values back into the request structure and return result return getConfig( configRequest, unitNumber); }
void AppleKiwiATA::selectIOTiming( ataUnitID unit ) { // this chip snoops the SetFeatures command and we don't need to do anything // unless it is running with the PLL at 133mhz in the case of the 271. In // that event, we have to override the snoop mode because the chip's internals // don't set the correct mode unless the pll is running at 100 mhz. if(mode6Capable) { UInt32 bTiming = kPartBTiming33LE; switch(bitSigToNumeric(busTimings[unit].ataUltraDMASpeedMode) ) { case 2: bTiming = kPartBTiming33LE; break; case 4: bTiming = kPartBTiming66LE; break; case 5: bTiming = kPartBTiming100LE; break; case 6: bTiming = kPartBTiming133LE; break; default: IOLog("AppleKiwiATA: error setting timing registers\n"); break; } //set the registers if( unit == 0) { *timingAReg0 = kPartATimingLE; *timingBReg0 = bTiming; } else { *timingAReg1 = kPartATimingLE; *timingBReg1 = bTiming; } OSSynchronizeIO(); } return; }
IOReturn OHareATA::selectIOTimerValue( IOATADevConfig* configRequest, UInt32 unitNumber) { // table of default cycle times to use when a device requests a mode // by number, but doesn't include a cycle time. static const UInt16 MinPIOCycle[kATAMaxPIOMode + 1] = { 600, // Mode 0 383, // Mode 1 240, // Mode 2 180, // Mode 3 120 // Mode 4 }; static const UInt16 MinMultiDMACycle[kATAMaxMultiDMAMode + 1] = { 480, // Mode 0 150, // Mode 1 120 // Mode 2 }; // table of PIO cycle times and the corresponding binary numbers // that the config register needs to make that timing. static const UInt32 PIOCycleValue[kOHarePIOCycleEntries] = { 0x00000400, // Hardware maximum (2070 ns = 'E' + 1110 rec + 960 acc) 0x00000526, // Minimum PIO mode 0 (600 ns = 'E' + 420 rec + 180 acc) 0x00000085, // Minimum PIO mode 1 (390 ns = 240 rec + 150 acc) 0x00000046, // Derated PIO Mode 2/3/4 (360 ns = 180 rec + 180 acc) 0x00000045, // Derated PIO Mode 2/3/4 (330 ns = 180 rec + 150 acc) 0x00000025, // Derated PIO Mode 2/3/4 (300 ns = 150 rec + 150 acc) 0x00000025, // Derated PIO mode 2/3/4 (300 ns = 150 rec + 150 acc) 0x00000025, // Minimum PIO mode 2 (300 ns = 150 rec + 150 acc) 0x00000025, // Derated PIO Mode 3/4 (300 ns = 150 rec + 150 acc) 0x00000025, // Minimum PIO mode 3 (300 ns = 150 rec + 150 acc) 0x00000025 // Minimum PIO mode 4 (300 ns = 150 rec + 150 acc) }; static const UInt16 PIOCycleTime[ kOHarePIOCycleEntries ]= { 2070, // Hardware maximum (0) 600, // Minimum PIO mode 0 (1) 383, // Minimum PIO mode 1 (2) 360, // Derated PIO Mode 2/3/4 (3) 330, // Derated PIO Mode 2/3/4 (4) 300, // Derated PIO Mode 2/3/4 (5) 270, // Derated PIO mode 2/3/4 (6) 240, // Minimum PIO mode 2 (7) 239, // Derated PIO Mode 3/4 (8) 180, // Minimum PIO mode 3 (9) 120, // Minimum PIO mode 4 (10) }; // table of DMA cycle times and the corresponding binary value to reach that number. static const UInt32 MultiDMACycleValue[kOHareMultiDMACycleEntries] = { 0x00000000, // Hardware maximum (1950= 990rec+960acc) 0x00074000, // Minimum Multi mode 0 (480= 240rec+240acc) 0x00053000, // Derated mode 1 or 2 (360= 180rec+180acc) 0x00242000, // Derated mode 1 or 2 (270=H+135rec+135acc) 0x00032000, // Derated mode 1 or 2 (240= 120rec+120acc) 0x00231800, // Derated mode 1 or 2 (210=H+105rec+105acc) 0x00021800, // Derated mode 1 or 2 (180= 90rec+90acc) 0x00221000, // Minimum Multi mode 1 (150=H+75rec+75acc) 0x00211000 // Minimum Multi mode 2 (120=H+45rec+75acc)(rd) (150=H+75rec+75acc)(wr) }; static const UInt16 MultiDMACycleTime[kOHareMultiDMACycleEntries] = { 1950, // Hardware maximum (0) 480, // Minimum Multi mode 0 (1) 360, // Derated mode 1 or 2 (2) 270, // Derated mode 1 or 2 (3) 240, // Derated mode 1 or 2 (4) 210, // Derated mode 1 or 2 (5) 180, // Derated mode 1 or 2 (6) 150, // Minimum Multi mode 1 (7) 120 // Minimum Multi mode 2 (8) }; UInt32 pioConfigBits = PIOCycleValue[0]; // the theory is simple, just examine the requested mode and cycle time, find the // entry in the table which is closest, but NOT faster than the requested cycle time. // convert the bit maps into numbers UInt32 pioModeNumber = bitSigToNumeric( configRequest->getPIOMode()); // check for out of range values. if( pioModeNumber > kATAMaxPIOMode ) { DLOG("OHareATA pio mode out of range\n"); return kATAModeNotSupported; } // use a default cycle time if the device didn't report a time // to use. UInt32 pioCycleTime = configRequest->getPIOCycleTime(); if( pioCycleTime < MinPIOCycle[ pioModeNumber ] ) { pioCycleTime = MinPIOCycle[ pioModeNumber ]; } // loop until a the hardware cycle time is longer than the // or equal to the requested cycle time for( int i = kOHarePIOCycleEntries - 1; i >= 0; i--) { if( pioCycleTime <= PIOCycleTime[ i ] ) { // found the fastest time which is not greater than // the requested time. pioConfigBits = PIOCycleValue[i]; break; } } // now do the same for DMA modes. UInt32 dmaConfigBits = MultiDMACycleValue[0]; UInt32 dmaModeNumber = bitSigToNumeric( configRequest->getDMAMode() ); // if the device requested no DMA mode, then just set the timer to mode 0 if( dmaModeNumber > kATAMaxMultiDMAMode ) { dmaModeNumber = 0; } UInt32 dmaCycleTime = configRequest->getDMACycleTime(); if( dmaCycleTime < MinMultiDMACycle[ dmaModeNumber ] ) { dmaCycleTime = MinMultiDMACycle[ dmaModeNumber ]; } // loop until a the hardware cycle time is longer than the // or equal to the requested cycle time for( int i = kOHareMultiDMACycleEntries - 1; i >= 0; i--) { if( dmaCycleTime <= MultiDMACycleTime[ i ] ) { // found the fastest time which is not greater than // the requested time. dmaConfigBits = MultiDMACycleValue[i]; break; } } // now combine the bits forming the configuration and put them // into the timing structure along with the mode and cycle time busTimings[unitNumber].cycleRegValue = dmaConfigBits | pioConfigBits; busTimings[unitNumber].ataPIOSpeedMode = configRequest->getPIOMode(); busTimings[unitNumber].ataPIOCycleTime = pioCycleTime; busTimings[unitNumber].ataMultiDMASpeed = configRequest->getDMAMode(); busTimings[unitNumber].ataMultiCycleTime = dmaCycleTime; DLOG("OHareATA PIO mode %x at %ld ns selected for device: %x\n", (int)pioModeNumber, pioCycleTime, (int)unitNumber); DLOG("OHareATA DMA mode %x at %ld ns selected for device: %x\n", (int)dmaModeNumber, dmaCycleTime, (int)unitNumber); // stuff the values back into the request structure and return result return getConfig( configRequest, unitNumber); }