* Re-program the timer for each loop instead of waiting for it to wrap around.

With that we will usually start right away without having to wait for the
  timer to be in the desired state, which removes roughly 116ms of spinning
  around for a normal calibration run.
* Read back the value once after programming. The delay this introduces
  accounts for the fact that the counter will only start counting down on the
  next clock cycle.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41680 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2011-05-23 13:25:44 +00:00
parent 2d62c17d26
commit 7adc7269d8

View File

@ -185,9 +185,22 @@ calibration_loop(uint8 desiredHighByte, uint8 channel, uint64& tscDelta,
double& conversionFactor, uint16& expired) double& conversionFactor, uint16& expired)
{ {
uint8 select = channel << PIT_SELECT_CHANNEL_SHIFT; uint8 select = channel << PIT_SELECT_CHANNEL_SHIFT;
uint8 channelPort = PIT_CHANNEL_PORT_BASE + channel; out8(select | PIT_ACCESS_LOW_THEN_HIGH_BYTE | PIT_MODE_RATE_GENERATOR
| PIT_BINARY_MODE, PIT_CONTROL);
// Wait for the PIT to arrive at our starting position (high byte == 0xff) // Fill in count of 0xffff, low then high byte
uint8 channelPort = PIT_CHANNEL_PORT_BASE + channel;
out8(0xff, channelPort);
out8(0xff, channelPort);
// Read the count back once to delay the start. This ensures that we've
// waited long enough for the counter to actually start counting down, as
// this only happens on the next clock cycle after reload.
in8(channelPort);
in8(channelPort);
// We're expecting the PIT to be at the starting position (high byte 0xff)
// as we just programmed it, but if it isn't we wait for it to wrap.
uint8 startLow; uint8 startLow;
uint8 startHigh; uint8 startHigh;
do { do {
@ -221,26 +234,15 @@ static void
calculate_cpu_conversion_factor() calculate_cpu_conversion_factor()
{ {
uint8 channel = 0; uint8 channel = 0;
uint8 channelPort = PIT_CHANNEL_PORT_BASE + channel;
uint8 control;
// When using channel 2, enable the input and disable the speaker. // When using channel 2, enable the input and disable the speaker.
if (channel == 2) { if (channel == 2) {
control = in8(PIT_CHANNEL_2_CONTROL); uint8 control = in8(PIT_CHANNEL_2_CONTROL);
control &= PIT_CHANNEL_2_SPEAKER_OFF_MASK; control &= PIT_CHANNEL_2_SPEAKER_OFF_MASK;
control |= PIT_CHANNEL_2_GATE_HIGH; control |= PIT_CHANNEL_2_GATE_HIGH;
out8(control, PIT_CHANNEL_2_CONTROL); out8(control, PIT_CHANNEL_2_CONTROL);
} }
uint8 select = channel << PIT_SELECT_CHANNEL_SHIFT;
control = select | PIT_ACCESS_LOW_THEN_HIGH_BYTE | PIT_MODE_RATE_GENERATOR
| PIT_BINARY_MODE;
out8(control, PIT_CONTROL);
// Fill in count of 0xffff, low then high byte
out8(0xff, channelPort);
out8(0xff, channelPort);
uint64 tscDeltaQuick, tscDeltaSlower, tscDeltaSlow; uint64 tscDeltaQuick, tscDeltaSlower, tscDeltaSlow;
double conversionFactorQuick, conversionFactorSlower, conversionFactorSlow; double conversionFactorQuick, conversionFactorSlower, conversionFactorSlow;
uint16 expired; uint16 expired;