1/*++
2
3Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
4
5  This program and the accompanying materials are licensed and made available under
6  the terms and conditions of the BSD License that accompanies this distribution.
7  The full text of the license may be found at
8  http://opensource.org/licenses/bsd-license.php.
9
10  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13
14
15Module Name:
16
17  IgdOMOBF.ASL
18
19Abstract:
20
21  IGD OpRegion/Software SCI Reference Code for the Baytrail Family.
22  This file contains ASL code with the purpose of handling events
23  i.e. hotkeys and other system interrupts.
24
25--*/
26
27
28// Notes:
29// 1. The following routines are to be called from the appropriate event
30//    handlers.
31// 2. This code cannot comprehend the exact implementation in the OEM's BIOS.
32//    Therefore, an OEM must call these methods from the existing event
33//    handler infrastructure.  Details on when/why to call each method is
34//    included in the method header under the "usage" section.
35
36
37/************************************************************************;
38;* ACPI Notification Methods
39;************************************************************************/
40
41
42/************************************************************************;
43;*
44;* Name:        PDRD
45;*
46;* Description: Check if the graphics driver is ready to process
47;*              notifications and video extensions.
48;*
49;* Usage:       This method is to be called prior to performing any
50;*              notifications or handling video extensions.
51;*              Ex: If (PDRD()) {Return (FAIL)}
52;*
53;* Input:       None
54;*
55;* Output:      None
56;*
57;* References:  DRDY (Driver ready status), ASLP (Driver recommended
58;*              sleep timeout value).
59;*
60;************************************************************************/
61
62Method(PDRD)
63{
64  If(LNot(DRDY))
65  {
66
67    // Sleep for ASLP milliseconds if the driver is not ready.
68
69    Sleep(ASLP)
70  }
71
72  // If DRDY is clear, the driver is not ready.  If the return value is
73  // !=0, do not perform any notifications or video extension handling.
74
75  Return(LNot(DRDY))
76}
77
78
79/************************************************************************;
80;*
81;* Name:        PSTS
82;*
83;* Description: Check if the graphics driver has completed the previous
84;*              "notify" command.
85;*
86;* Usage:       This method is called before every "notify" command.  A
87;*              "notify" should only be set if the driver has completed the
88;*              previous command.  Else, ignore the event and exit the parent
89;*              method.
90;*              Ex: If (PSTS()) {Return (FAIL)}
91;*
92;* Input:       None
93;*
94;* Output:      None
95;*
96;* References:  CSTS (Notification status), ASLP (Driver recommended sleep
97;*              timeout value).
98;*
99;************************************************************************/
100
101Method(PSTS)
102{
103  If(LGreater(CSTS, 2))
104  {
105    // Sleep for ASLP milliseconds if the status is not "success,
106    // failure, or pending"
107    //
108    Sleep(ASLP)
109  }
110
111  Return(LEqual(CSTS, 3))         // Return True if still Dispatched
112}
113
114
115/************************************************************************;
116;*
117;* Name:        GNOT
118;*
119;* Description: Call the appropriate methods to query the graphics driver
120;*              status.  If all methods return success, do a notification of
121;*              the graphics device.
122;*
123;* Usage:       This method is to be called when a graphics device
124;*              notification is required (display switch hotkey, etc).
125;*
126;* Input:       Arg0 = Current event type:
127;*                      1 = display switch
128;*                      2 = lid
129;*                      3 = dock
130;*              Arg1 = Notification type:
131;*                      0 = Re-enumeration
132;*                      0x80 = Display switch
133;*
134;* Output:      Returns 0 = success, 1 = failure
135;*
136;* References:  PDRD and PSTS methods.  OSYS (OS version)
137;*
138;************************************************************************/
139
140Method(GNOT, 2)
141{
142  // Check for 1. Driver loaded, 2. Driver ready.
143  // If any of these cases is not met, skip this event and return failure.
144  //
145  If(PDRD())
146  {
147    Return(0x1)             // Return failure if driver not loaded.
148  }
149
150  Store(Arg0, CEVT)               // Set up the current event value
151  Store(3, CSTS)                  // CSTS=BIOS dispatched an event
152
153  If(LAnd(LEqual(CHPD, 0), LEqual(Arg1, 0)))      // Do not re-enum if driver supports hotplug
154  {
155    If(LOr(LGreater(OSYS, 2000), LLess(OSYS, 2006)))
156    {
157      //
158      // WINXP requires that the entire PCI Bridge be re-enumerated.
159      //
160      Notify(\_SB.PCI0, Arg1)
161    }
162    Else
163    {
164      //
165      // Re-enumerate the Graphics Device for non-XP operating systems.
166      //
167      Notify(\_SB.PCI0.GFX0, Arg1)
168    }
169  }
170
171  Notify(\_SB.PCI0.GFX0,0x80)
172
173
174  Return(0x0)                     // Return success
175}
176
177
178/************************************************************************;
179;*
180;* Name:        GHDS
181;*
182;* Description: Handle a hotkey display switching event (performs a
183;*              Notify(GFX0, 0).
184;*
185;* Usage:       This method must be called when a hotkey event occurs and the
186;*              purpose of that hotkey is to do a display switch.
187;*
188;* Input:       Arg0 = Toggle table number.
189;*
190;* Output:      Returns 0 = success, 1 = failure.
191;*              CEVT and TIDX are indirect outputs.
192;*
193;* References:  TIDX, GNOT
194;*
195;************************************************************************/
196
197Method(GHDS, 1)
198{
199  Store(Arg0, TIDX)               // Store the table number
200
201  // Call GNOT for CEVT = 1 = hotkey, notify value = 0
202
203  Return(GNOT(1, 0))              // Return stats from GNOT
204}
205
206
207/************************************************************************;
208;*
209;* Name:        GLID
210;*
211;* Description: Handle a lid event (performs the Notify(GFX0, 0), but not the
212;*              lid notify).
213;*
214;* Usage:       This method must be called when a lid event occurs.  A
215;*              Notify(LID0, 0x80) must follow the call to this method.
216;*
217;* Input:       Arg0 = Lid state:
218;*                      0 = All closed
219;*                      1 = internal LFP lid open
220;*                      2 = external lid open
221;*                      3 = both external and internal open
222;*
223;* Output:      Returns 0=success, 1=failure.
224;*              CLID and CEVT are indirect outputs.
225;*
226;* References:  CLID, GNOT
227;*
228;************************************************************************/
229
230Method(GLID, 1)
231{
232  Store(Arg0, CLID)               // Store the current lid state
233
234  // Call GNOT for CEVT=2=Lid, notify value = 0
235
236  Return(GNOT(2, 0))              // Return stats from GNOT
237}
238
239
240/************************************************************************;
241;*
242;* Name:        GDCK
243;*
244;* Description: Handle a docking event by updating the current docking status
245;*              and doing a notification.
246;*
247;* Usage:       This method must be called when a docking event occurs.
248;*
249;* Input:       Arg0 = Docking state:
250;*                      0 = Undocked
251;*                      1 = Docked
252;*
253;* Output:      Returns 0=success, 1=failure.
254;*              CDCK and CEVT are indirect outputs.
255;*
256;* References:  CDCK, GNOT
257;*
258;************************************************************************/
259
260Method(GDCK, 1)
261{
262  Store(Arg0, CDCK)               // Store the current dock state
263
264  // Call GNOT for CEVT=4=Dock, notify value = 0
265
266  Return(GNOT(4, 0))              // Return stats from GNOT
267}
268
269
270/************************************************************************;
271;* ASLE Interrupt Methods
272;************************************************************************/
273
274
275/************************************************************************;
276;*
277;* Name:        PARD
278;*
279;* Description: Check if the driver is ready to handle ASLE interrupts
280;*              generate by the system BIOS.
281;*
282;* Usage:       This method must be called before generating each ASLE
283;*              interrupt.
284;*
285;* Input:       None
286;*
287;* Output:      Returns 0 = success, 1 = failure.
288;*
289;* References:  ARDY (Driver readiness), ASLP (Driver recommended sleep
290;*              timeout value)
291;*
292;************************************************************************/
293
294Method(PARD)
295{
296  If(LNot(ARDY))
297  {
298
299    // Sleep for ASLP milliseconds if the driver is not ready.
300
301    Sleep(ASLP)
302  }
303
304  // If ARDY is clear, the driver is not ready.  If the return value is
305  // !=0, do not generate the ASLE interrupt.
306
307  Return(LNot(ARDY))
308}
309
310
311/************************************************************************;
312;*
313;* Name:        AINT
314;*
315;* Description: Call the appropriate methods to generate an ASLE interrupt.
316;*              This process includes ensuring the graphics driver is ready
317;*              to process the interrupt, ensuring the driver supports the
318;*              interrupt of interest, and passing information about the event
319;*              to the graphics driver.
320;*
321;* Usage:       This method must called to generate an ASLE interrupt.
322;*
323;* Input:       Arg0 = ASLE command function code:
324;*                      0 = Set ALS illuminance
325;*                      1 = Set backlight brightness
326;*                      2 = Do Panel Fitting
327;*              Arg1 = If Arg0 = 0, current ALS reading:
328;*                      0 = Reading below sensor range
329;*                      1-0xFFFE = Current sensor reading
330;*                      0xFFFF = Reading above sensor range
331;*              Arg1 = If Arg0 = 1, requested backlight percentage
332;*
333;* Output:      Returns 0 = success, 1 = failure
334;*
335;* References:  PARD method.
336;*
337;************************************************************************/
338
339Method(AINT, 2)
340{
341
342  // Return failure if the requested feature is not supported by the
343  // driver.
344
345  If(LNot(And(TCHE, ShiftLeft(1, Arg0))))
346  {
347    Return(0x1)
348  }
349
350  // Return failure if the driver is not ready to handle an ASLE
351  // interrupt.
352
353  If(PARD())
354  {
355    Return(0x1)
356  }
357
358  // Evaluate the first argument (Panel fitting, backlight brightness, or ALS).
359
360  If(LEqual(Arg0, 2))             // Arg0 = 2, so request a panel fitting mode change.
361  {
362    If(CPFM)                                        // If current mode field is non-zero use it.
363    {
364      And(CPFM, 0x0F, Local0)                 // Create variables without reserved
365      And(EPFM, 0x0F, Local1)                 // or valid bits.
366
367      If(LEqual(Local0, 1))                   // If current mode is centered,
368      {
369        If(And(Local1, 6))              // and if stretched is enabled,
370        {
371          Store(6, PFIT)          // request stretched.
372        }
373        Else                            // Otherwise,
374        {
375          If(And(Local1, 8))      // if aspect ratio is enabled,
376          {
377            Store(8, PFIT)  // request aspect ratio.
378          }
379          Else                    // Only centered mode is enabled
380          {
381            Store(1, PFIT)  // so request centered. (No change.)
382          }
383        }
384      }
385      If(LEqual(Local0, 6))                   // If current mode is stretched,
386      {
387        If(And(Local1, 8))              // and if aspect ratio is enabled,
388        {
389          Store(8, PFIT)          // request aspect ratio.
390        }
391        Else                            // Otherwise,
392        {
393          If(And(Local1, 1))      // if centered is enabled,
394          {
395            Store(1, PFIT)  // request centered.
396          }
397          Else                    // Only stretched mode is enabled
398          {
399            Store(6, PFIT)  // so request stretched. (No change.)
400          }
401        }
402      }
403      If(LEqual(Local0, 8))                   // If current mode is aspect ratio,
404      {
405        If(And(Local1, 1))              // and if centered is enabled,
406        {
407          Store(1, PFIT)          // request centered.
408        }
409        Else                            // Otherwise,
410        {
411          If(And(Local1, 6))      // if stretched is enabled,
412          {
413            Store(6, PFIT)  // request stretched.
414          }
415          Else                    // Only aspect ratio mode is enabled
416          {
417            Store(8, PFIT)  // so request aspect ratio. (No change.)
418          }
419        }
420      }
421    }
422
423    // The following code for panel fitting (within the Else condition) is retained for backward compatiblity.
424
425    Else                            // If CFPM field is zero use PFIT and toggle the
426    {
427      Xor(PFIT,7,PFIT)        // mode setting between stretched and centered only.
428    }
429
430    Or(PFIT,0x80000000,PFIT)        // Set the valid bit for all cases.
431
432    Store(4, ASLC)                  // Store "Panel fitting event" to ASLC[31:1]
433  }
434  Else
435  {
436    If(LEqual(Arg0, 1))             // Arg0=1, so set the backlight brightness.
437    {
438      Store(Divide(Multiply(Arg1, 255), 100), BCLP) // Convert from percent to 0-255.
439
440      Or(BCLP, 0x80000000, BCLP)      // Set the valid bit.
441
442      Store(2, ASLC)                  // Store "Backlight control event" to ASLC[31:1]
443    }
444    Else
445    {
446      If(LEqual(Arg0, 0))             // Arg0=0, so set the ALS illuminace
447      {
448        Store(Arg1, ALSI)
449
450        Store(1, ASLC)          // Store "ALS event" to ASLC[31:1]
451      }
452      Else
453      {
454        Return(0x1) // Unsupported function
455      }
456    }
457  }
458
459  Store(0x01, ASLE)               // Generate ASLE interrupt
460  Return(0x0)                     // Return success
461}
462
463
464/************************************************************************;
465;*
466;* Name:        SCIP
467;*
468;* Description: Checks the presence of the OpRegion and SCI
469;*
470;* Usage:       This method is called before other OpRegion methods. The
471;*              former "GSMI True/False is not always valid.  This method
472;*              checks if the OpRegion Version is non-zero and if non-zero,
473;*              (present and readable) then checks the GSMI flag.
474;*
475;* Input:       None
476;*
477;* Output:      Boolean True = SCI present.
478;*
479;* References:  None
480;*
481;************************************************************************/
482
483Method(SCIP)
484{
485  If(LNotEqual(OVER,0))           // If OpRegion Version not 0.
486  {
487    Return(LNot(GSMI))      // Return True if SCI.
488  }
489
490  Return(0)                       // Else Return False.
491}
492