From 71d757484353e83d47c5a5751c6ea756faf653ee Mon Sep 17 00:00:00 2001 From: Olivier Martin Date: Mon, 20 Feb 2012 16:11:16 +0000 Subject: [PATCH 2/7] SamsungPlatformPkg/TimerDxe: Do not overwrite Timers 2/3 settings Signed-off-by: Olivier Martin --- SamsungPlatformPkg/ExynosPkg/TimerDxe/TimerDxe.c | 64 ++++++++++++---------- 1 files changed, 34 insertions(+), 30 deletions(-) diff --git a/SamsungPlatformPkg/ExynosPkg/TimerDxe/TimerDxe.c b/SamsungPlatformPkg/ExynosPkg/TimerDxe/TimerDxe.c index ea24534..2b2e8f1 100755 --- a/SamsungPlatformPkg/ExynosPkg/TimerDxe/TimerDxe.c +++ b/SamsungPlatformPkg/ExynosPkg/TimerDxe/TimerDxe.c @@ -70,7 +70,7 @@ TimerInterruptHandler ( UINT32 PWMTimerBase; EFI_STATUS Status; - PWMTimerBase=PcdGet32(PcdPWMTimerBase); + PWMTimerBase = PcdGet32(PcdPWMTimerBase); // // DXE core uses this callback for the EFI timer tick. The DXE core uses locks // that raise to TPL_HIGH and then restore back to current level. Thus we need @@ -80,34 +80,35 @@ TimerInterruptHandler ( // clear the interrupt IntStatus = MmioRead32 (PWMTimerBase + PWM_TINT_CSTAT_OFFSET); + if(IntStatus & TIMER_STATUS_MASK(TIMER_0)){ MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET),(IntStatus | TIMER_STATUS_MASK(TIMER_0))); - Status = RETURN_SUCCESS; + Status = RETURN_SUCCESS; DEBUG ((EFI_D_INFO, "\nTimer 0 ISR\n")); } if(IntStatus & TIMER_STATUS_MASK(TIMER_1)){ MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET),(IntStatus | TIMER_STATUS_MASK(TIMER_1))); - Status = RETURN_SUCCESS; + Status = RETURN_SUCCESS; DEBUG ((EFI_D_INFO, "\nTimer 1 ISR\n")); } if(IntStatus & TIMER_STATUS_MASK(TIMER_2)){ MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET),(IntStatus | TIMER_STATUS_MASK(TIMER_2))); - Status = RETURN_SUCCESS; + Status = RETURN_SUCCESS; DEBUG ((EFI_D_INFO, "\nTimer 2 ISR\n")); } if(IntStatus & TIMER_STATUS_MASK(TIMER_3)){ MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET),(IntStatus | TIMER_STATUS_MASK(TIMER_3))); - Status = RETURN_SUCCESS; + Status = RETURN_SUCCESS; DEBUG ((EFI_D_INFO, "\nTimer 3 ISR\n")); } if(IntStatus & TIMER_STATUS_MASK(TIMER_4)){ MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET),(IntStatus | TIMER_STATUS_MASK(TIMER_4))); - Status = RETURN_SUCCESS; + Status = RETURN_SUCCESS; DEBUG ((EFI_D_INFO, "\nTimer 4 ISR\n")); } if(EFI_ERROR(Status)){ - Status = RETURN_UNSUPPORTED; - ASSERT_EFI_ERROR(FALSE); + Status = RETURN_UNSUPPORTED; + ASSERT_EFI_ERROR(FALSE); } // signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers gInterrupt->EndOfInterrupt (gInterrupt, Source); @@ -227,41 +228,43 @@ TimerDriverSetTimerPeriod ( UINT32 PWMTimerBase; DEBUG ((EFI_D_INFO, "\nSetTimer called\n")); - PWMTimerBase=PcdGet32(PcdPWMTimerBase); + PWMTimerBase = PcdGet32(PcdPWMTimerBase); // Stop PWM timer 0 rwVal = MmioRead32 (PWMTimerBase + PWM_TCON_OFFSET); - MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET),STOP_TIMER_VAL(TIMER_0)); + MmioAnd32 ((PWMTimerBase + PWM_TCON_OFFSET), ~1); if (TimerPeriod == 0) { // leave timer disabled from above, and... rwVal = MmioRead32 (PWMTimerBase + PWM_TINT_CSTAT_OFFSET); MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET),(rwVal & ~TIMER_INTR_MASK(TIMER_0))); // disable timer 0/1 interrupt for a TimerPeriod of 0 - Status = gInterrupt->DisableInterruptSource (gInterrupt, gVector); + Status = gInterrupt->DisableInterruptSource (gInterrupt, gVector); } else { - // Convert TimerPeriod into 1MHz clock counts (us units = 100ns units / 10) - TimerTicks = DivU64x32 (TimerPeriod, 10); - // if it's larger than 32-bits, pin to highest value - if (TimerTicks > 0xffffffff) { - TimerTicks = 0xffffffff; - } - - // PWM Timer 0 used by Period counter with Auto re-load mode - MmioWrite32 ((PWMTimerBase + PWM_TCNTB0_OFFSET), TimerTicks); - // Set and Clear PWM Manually update for Timer 0 - rwVal = MmioRead32 (PWMTimerBase + PWM_TCON_OFFSET); - MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), rwVal | UPDATE_COUNT_BUF_MASK(TIMER_0)); - MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), rwVal & ~UPDATE_COUNT_BUF_MASK(TIMER_0)); - - // Set Auto re-load and start Timer + // Convert TimerPeriod into 1MHz clock counts (us units = 100ns units / 10) + TimerTicks = DivU64x32 (TimerPeriod, 10); + // if it's larger than 32-bits, pin to highest value + if (TimerTicks > 0xffffffff) { + TimerTicks = 0xffffffff; + } + + // PWM Timer 0 used by Period counter with Auto re-load mode + MmioWrite32 ((PWMTimerBase + PWM_TCNTB0_OFFSET), TimerTicks); + // Set and Clear PWM Manually update for Timer 0 + rwVal = MmioRead32 (PWMTimerBase + PWM_TCON_OFFSET); + MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), rwVal | UPDATE_COUNT_BUF_MASK(TIMER_0)); + MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), rwVal & ~UPDATE_COUNT_BUF_MASK(TIMER_0)); + + // Set Auto re-load and start Timer MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), rwVal | RELOAD_AND_START(TIMER_0)); - //PWM Timer0 INT enable + Status = gInterrupt->EnableInterruptSource (gInterrupt, gVector); + + // PWM Timer0 INT enable rwVal = MmioRead32 (PWMTimerBase + PWM_TINT_CSTAT_OFFSET); MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET), rwVal | TIMER_INTR_MASK(TIMER_0) ); Status = gInterrupt->EnableInterruptSource (gInterrupt, gVector); - } + } // Save the new timer period mTimerPeriod = TimerPeriod; @@ -390,7 +393,9 @@ TimerInitialize ( UINT32 Tmp; UINT32 PWMTimerBase; - PWMTimerBase=PcdGet32(PcdPWMTimerBase); + gVector = PWM_TIMER0_INTERRUPT_NUM; + PWMTimerBase = PcdGet32(PcdPWMTimerBase); + // Find the interrupt controller protocol. ASSERT if not found. Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt); ASSERT_EFI_ERROR (Status); @@ -407,7 +412,6 @@ TimerInitialize ( ASSERT_EFI_ERROR (Status); // Install interrupt handler - gVector = PWM_TIMER0_INTERRUPT_NUM; Status = gInterrupt->RegisterInterruptSource (gInterrupt, gVector, TimerInterruptHandler); ASSERT_EFI_ERROR (Status); -- 1.7.0.4