gma broxton: Avoid invalid state of PWM HW counter
This implements display workaround #0854 [1]. The original descrip-
tion only mentions that the PWM might stop in a logical high state.
Which shouldn't be a problem, as long as there is a separate signal
toggling the on/off state of the backlight.
However, it turns out that with the clock gating, the PWM counter is
also not reset when the frequency divider in BLC_PWM_FREQ is updated.
This can result in a counter value out of range, effectively leaving
the PWM signal low until a 32-bit overflow at 19.2 MHz (almost 4min).
[1] https://cdrdv2-public.intel.com/685505/intel-gfx-prm-osrc-bxt-vol08-workarounds_7.pdf
May 2017, Revision 1.0
Change-Id: I38b51c5afb072fb3c7b87caca028adba557aeebf
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.sourcearcade.org/c/libgfxinit/+/539
Tested-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Thomas Heijligen <src@posteo.de>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
diff --git a/common/broxton/hw-gfx-gma-power_and_clocks.adb b/common/broxton/hw-gfx-gma-power_and_clocks.adb
index 279071a..73192ff 100644
--- a/common/broxton/hw-gfx-gma-power_and_clocks.adb
+++ b/common/broxton/hw-gfx-gma-power_and_clocks.adb
@@ -314,6 +314,24 @@
----------------------------------------------------------------------------
+ -- WA #0854
+ -- Backlight PWM may stop in the asserted state, causing backlight
+ -- to stay fully on.
+ --
+ -- It was also observed that the PWM counter is not reset on writes
+ -- to the BLC_PWM_FREQ register. This can result in a counter value
+ -- out of range, effectively leaving the PWM signal low until a 32-
+ -- bit overflow at 19.2 MHz (almost 4min).
+ procedure Apply_Workaround_0854
+ is
+ PWM1_GATING_DIS : constant := 1 * 2 ** 13;
+ PWM2_GATING_DIS : constant := 1 * 2 ** 14;
+ begin
+ Registers.Set_Mask
+ (Register => Registers.GEN9_CLKGATE_DIS_0,
+ Mask => PWM1_GATING_DIS or PWM2_GATING_DIS);
+ end Apply_Workaround_0854;
+
procedure Pre_All_Off is
begin
pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
@@ -355,6 +373,8 @@
Set_Mask (DBUF_CTL_S0, DBUF_CTL_DBUF_POWER_REQUEST);
Wait_Set_Mask (DBUF_CTL_S0, DBUF_CTL_DBUF_POWER_STATE);
+ Apply_Workaround_0854;
+
Config.Raw_Clock := Config.Default_RawClk_Freq;
end Initialize;