Re: [Intel-gfx] [PATCH] drm/i915: add plumbing for SWSCI

2013-08-29 Thread Paulo Zanoni
2013/8/29 Jani Nikula :
> On Thu, 29 Aug 2013, Paulo Zanoni  wrote:
>> Hi
>>
>> 2013/8/28 Jani Nikula :
>>> SWSCI is a driver to bios call interface.
>>>
>>> This checks for SWSCI availability and bios requested callbacks, and
>>> filters out any calls that shouldn't happen. This way the callers don't
>>> need to do the checks all over the place.
>>>
>>> v2: silence some checkpatch nagging
>>>
>>> v3: set PCI_SWSCI bit 0 to trigger interrupt (Mengdong Lin)
>>>
>>> v4: remove an extra #define (Jesse)
>>>
>>> v5: spec says s/w is responsible for clearing PCI_SWSCI bit 0 too
>>>
>>> Signed-off-by: Jani Nikula 
>>> ---
>>>  drivers/gpu/drm/i915/i915_drv.h   |1 +
>>>  drivers/gpu/drm/i915/intel_opregion.c |  133 
>>> -
>>>  2 files changed, 131 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h 
>>> b/drivers/gpu/drm/i915/i915_drv.h
>>> index 84b95b1..adc2f46 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>> @@ -225,6 +225,7 @@ struct intel_opregion {
>>> struct opregion_header __iomem *header;
>>> struct opregion_acpi __iomem *acpi;
>>> struct opregion_swsci __iomem *swsci;
>>> +   u32 swsci_requested_callbacks;
>>> struct opregion_asle __iomem *asle;
>>> void __iomem *vbt;
>>> u32 __iomem *lid_state;
>>> diff --git a/drivers/gpu/drm/i915/intel_opregion.c 
>>> b/drivers/gpu/drm/i915/intel_opregion.c
>>> index cfb8fb6..233cc7f 100644
>>> --- a/drivers/gpu/drm/i915/intel_opregion.c
>>> +++ b/drivers/gpu/drm/i915/intel_opregion.c
>>> @@ -36,8 +36,11 @@
>>>  #include "i915_drv.h"
>>>  #include "intel_drv.h"
>>>
>>> -#define PCI_ASLE 0xe4
>>> -#define PCI_ASLS 0xfc
>>> +#define PCI_ASLE   0xe4
>>> +#define PCI_ASLS   0xfc
>>> +#define PCI_SWSCI  0xe8
>>> +#define PCI_SWSCI_SCISEL   (1 << 15)
>>> +#define PCI_SWSCI_GSSCIE   (1 << 0)
>>>
>>>  #define OPREGION_HEADER_OFFSET 0
>>>  #define OPREGION_ACPI_OFFSET   0x100
>>> @@ -151,6 +154,48 @@ struct opregion_asle {
>>>
>>>  #define ASLE_CBLV_VALID (1<<31)
>>>
>>> +/* Software System Control Interrupt (SWSCI) */
>>> +#define SWSCI_SCIC_INDICATOR   (1 << 0)
>>> +#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
>>> +#define SWSCI_SCIC_MAIN_FUNCTION_MASK  (0xf << 1)
>>> +#define SWSCI_SCIC_SUB_FUNCTION_SHIFT  8
>>> +#define SWSCI_SCIC_SUB_FUNCTION_MASK   (0x7f << 8)
>>
>> Shouldn't this be (0xff << 8) since it's bits 15:8 ?
>
> In my spec, section 4.1.1: "Function codes are broken down into two
> parts the main function code (SCIC bits [4:1]) and the sub-function code
> (SCIC bits [14:8])."

In the same spec, section 3.3.1, table 3-35 says it's 15:8 :(
We're both right and wrong...


>
>>> +#define SWSCI_SCIC_EXIT_STATUS_SHIFT   5
>>> +#define SWSCI_SCIC_EXIT_STATUS_MASK(7 << 5)
>>> +#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
>>> +
>>> +#define SWSCI_FUNCTION_CODE(main, sub) \
>>> +   ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
>>> +(sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
>>> +
>>> +/* SWSCI: Get BIOS Data (GBDA) */
>>> +#define SWSCI_GBDA 4
>>> +#define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
>>> +#define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
>>> +#define SWSCI_GBDA_BOOT_DISPLAY_PREF   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
>>> +#define SWSCI_GBDA_PANEL_DETAILS   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
>>> +#define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
>>
>> The newer spec says "reserved" here. But let's leave your definition
>> until they assign it again to something else :) (same thing for the
>> other TV bit below)
>
> Okay. :)
>
>>> +#define SWSCI_GBDA_INTERNAL_GRAPHICS   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
>>> +#define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
>>> +
>>> +/* SWSCI: System BIOS Callbacks (SBCB) */
>>> +#define SWSCI_SBCB 6
>>> +#define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
>>> +#define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
>>> +#define SWSCI_SBCB_PRE_HIRES_SET_MODE  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
>>> +#define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
>>> +#define SWSCI_SBCB_DISPLAY_SWITCH  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
>>> +#define SWSCI_SBCB_SET_TV_FORMAT   SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
>>> +#define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
>>> +#define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
>>> +#define SWSCI_SBCB_SET_BOOT_DISPLAYSWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
>>> +#define SWSCI_SBCB_SET_INTERNAL_GFXSWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
>>> +#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS
>>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
>>> +#define SWSCI_SBCB_SUSPEND_RESUME  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
>>> +#define 

Re: [Intel-gfx] [PATCH] drm/i915: add plumbing for SWSCI

2013-08-29 Thread Jani Nikula
On Thu, 29 Aug 2013, Paulo Zanoni  wrote:
> Hi
>
> 2013/8/28 Jani Nikula :
>> SWSCI is a driver to bios call interface.
>>
>> This checks for SWSCI availability and bios requested callbacks, and
>> filters out any calls that shouldn't happen. This way the callers don't
>> need to do the checks all over the place.
>>
>> v2: silence some checkpatch nagging
>>
>> v3: set PCI_SWSCI bit 0 to trigger interrupt (Mengdong Lin)
>>
>> v4: remove an extra #define (Jesse)
>>
>> v5: spec says s/w is responsible for clearing PCI_SWSCI bit 0 too
>>
>> Signed-off-by: Jani Nikula 
>> ---
>>  drivers/gpu/drm/i915/i915_drv.h   |1 +
>>  drivers/gpu/drm/i915/intel_opregion.c |  133 
>> -
>>  2 files changed, 131 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h 
>> b/drivers/gpu/drm/i915/i915_drv.h
>> index 84b95b1..adc2f46 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -225,6 +225,7 @@ struct intel_opregion {
>> struct opregion_header __iomem *header;
>> struct opregion_acpi __iomem *acpi;
>> struct opregion_swsci __iomem *swsci;
>> +   u32 swsci_requested_callbacks;
>> struct opregion_asle __iomem *asle;
>> void __iomem *vbt;
>> u32 __iomem *lid_state;
>> diff --git a/drivers/gpu/drm/i915/intel_opregion.c 
>> b/drivers/gpu/drm/i915/intel_opregion.c
>> index cfb8fb6..233cc7f 100644
>> --- a/drivers/gpu/drm/i915/intel_opregion.c
>> +++ b/drivers/gpu/drm/i915/intel_opregion.c
>> @@ -36,8 +36,11 @@
>>  #include "i915_drv.h"
>>  #include "intel_drv.h"
>>
>> -#define PCI_ASLE 0xe4
>> -#define PCI_ASLS 0xfc
>> +#define PCI_ASLE   0xe4
>> +#define PCI_ASLS   0xfc
>> +#define PCI_SWSCI  0xe8
>> +#define PCI_SWSCI_SCISEL   (1 << 15)
>> +#define PCI_SWSCI_GSSCIE   (1 << 0)
>>
>>  #define OPREGION_HEADER_OFFSET 0
>>  #define OPREGION_ACPI_OFFSET   0x100
>> @@ -151,6 +154,48 @@ struct opregion_asle {
>>
>>  #define ASLE_CBLV_VALID (1<<31)
>>
>> +/* Software System Control Interrupt (SWSCI) */
>> +#define SWSCI_SCIC_INDICATOR   (1 << 0)
>> +#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
>> +#define SWSCI_SCIC_MAIN_FUNCTION_MASK  (0xf << 1)
>> +#define SWSCI_SCIC_SUB_FUNCTION_SHIFT  8
>> +#define SWSCI_SCIC_SUB_FUNCTION_MASK   (0x7f << 8)
>
> Shouldn't this be (0xff << 8) since it's bits 15:8 ?

In my spec, section 4.1.1: "Function codes are broken down into two
parts the main function code (SCIC bits [4:1]) and the sub-function code
(SCIC bits [14:8])."

>> +#define SWSCI_SCIC_EXIT_STATUS_SHIFT   5
>> +#define SWSCI_SCIC_EXIT_STATUS_MASK(7 << 5)
>> +#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
>> +
>> +#define SWSCI_FUNCTION_CODE(main, sub) \
>> +   ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
>> +(sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
>> +
>> +/* SWSCI: Get BIOS Data (GBDA) */
>> +#define SWSCI_GBDA 4
>> +#define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
>> +#define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
>> +#define SWSCI_GBDA_BOOT_DISPLAY_PREF   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
>> +#define SWSCI_GBDA_PANEL_DETAILS   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
>> +#define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
>
> The newer spec says "reserved" here. But let's leave your definition
> until they assign it again to something else :) (same thing for the
> other TV bit below)

Okay. :)

>> +#define SWSCI_GBDA_INTERNAL_GRAPHICS   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
>> +#define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
>> +
>> +/* SWSCI: System BIOS Callbacks (SBCB) */
>> +#define SWSCI_SBCB 6
>> +#define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
>> +#define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
>> +#define SWSCI_SBCB_PRE_HIRES_SET_MODE  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
>> +#define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
>> +#define SWSCI_SBCB_DISPLAY_SWITCH  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
>> +#define SWSCI_SBCB_SET_TV_FORMAT   SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
>> +#define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
>> +#define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
>> +#define SWSCI_SBCB_SET_BOOT_DISPLAYSWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
>> +#define SWSCI_SBCB_SET_INTERNAL_GFXSWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
>> +#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
>> +#define SWSCI_SBCB_SUSPEND_RESUME  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
>> +#define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
>> +#define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
>> +#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
>>

Re: [Intel-gfx] [PATCH] drm/i915: add plumbing for SWSCI

2013-08-29 Thread Paulo Zanoni
2013/8/29 Paulo Zanoni :
> Hi
>
> 2013/8/28 Jani Nikula :
>> SWSCI is a driver to bios call interface.
>>
>> This checks for SWSCI availability and bios requested callbacks, and
>> filters out any calls that shouldn't happen. This way the callers don't
>> need to do the checks all over the place.
>>
>> v2: silence some checkpatch nagging
>>
>> v3: set PCI_SWSCI bit 0 to trigger interrupt (Mengdong Lin)
>>
>> v4: remove an extra #define (Jesse)
>>
>> v5: spec says s/w is responsible for clearing PCI_SWSCI bit 0 too
>>
>> Signed-off-by: Jani Nikula 
>> ---
>>  drivers/gpu/drm/i915/i915_drv.h   |1 +
>>  drivers/gpu/drm/i915/intel_opregion.c |  133 
>> -
>>  2 files changed, 131 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h 
>> b/drivers/gpu/drm/i915/i915_drv.h
>> index 84b95b1..adc2f46 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -225,6 +225,7 @@ struct intel_opregion {
>> struct opregion_header __iomem *header;
>> struct opregion_acpi __iomem *acpi;
>> struct opregion_swsci __iomem *swsci;
>> +   u32 swsci_requested_callbacks;
>> struct opregion_asle __iomem *asle;
>> void __iomem *vbt;
>> u32 __iomem *lid_state;
>> diff --git a/drivers/gpu/drm/i915/intel_opregion.c 
>> b/drivers/gpu/drm/i915/intel_opregion.c
>> index cfb8fb6..233cc7f 100644
>> --- a/drivers/gpu/drm/i915/intel_opregion.c
>> +++ b/drivers/gpu/drm/i915/intel_opregion.c
>> @@ -36,8 +36,11 @@
>>  #include "i915_drv.h"
>>  #include "intel_drv.h"
>>
>> -#define PCI_ASLE 0xe4
>> -#define PCI_ASLS 0xfc
>> +#define PCI_ASLE   0xe4
>> +#define PCI_ASLS   0xfc
>> +#define PCI_SWSCI  0xe8
>> +#define PCI_SWSCI_SCISEL   (1 << 15)
>> +#define PCI_SWSCI_GSSCIE   (1 << 0)
>>
>>  #define OPREGION_HEADER_OFFSET 0
>>  #define OPREGION_ACPI_OFFSET   0x100
>> @@ -151,6 +154,48 @@ struct opregion_asle {
>>
>>  #define ASLE_CBLV_VALID (1<<31)
>>
>> +/* Software System Control Interrupt (SWSCI) */
>> +#define SWSCI_SCIC_INDICATOR   (1 << 0)
>> +#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
>> +#define SWSCI_SCIC_MAIN_FUNCTION_MASK  (0xf << 1)
>> +#define SWSCI_SCIC_SUB_FUNCTION_SHIFT  8
>> +#define SWSCI_SCIC_SUB_FUNCTION_MASK   (0x7f << 8)
>
> Shouldn't this be (0xff << 8) since it's bits 15:8 ?
>
>
>> +#define SWSCI_SCIC_EXIT_STATUS_SHIFT   5
>> +#define SWSCI_SCIC_EXIT_STATUS_MASK(7 << 5)
>> +#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
>> +
>> +#define SWSCI_FUNCTION_CODE(main, sub) \
>> +   ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
>> +(sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
>> +
>> +/* SWSCI: Get BIOS Data (GBDA) */
>> +#define SWSCI_GBDA 4
>> +#define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
>> +#define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
>> +#define SWSCI_GBDA_BOOT_DISPLAY_PREF   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
>> +#define SWSCI_GBDA_PANEL_DETAILS   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
>> +#define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
>
> The newer spec says "reserved" here. But let's leave your definition
> until they assign it again to something else :) (same thing for the
> other TV bit below)
>
>
>> +#define SWSCI_GBDA_INTERNAL_GRAPHICS   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
>> +#define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
>> +
>> +/* SWSCI: System BIOS Callbacks (SBCB) */
>> +#define SWSCI_SBCB 6
>> +#define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
>> +#define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
>> +#define SWSCI_SBCB_PRE_HIRES_SET_MODE  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
>> +#define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
>> +#define SWSCI_SBCB_DISPLAY_SWITCH  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
>> +#define SWSCI_SBCB_SET_TV_FORMAT   SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
>> +#define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
>> +#define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
>> +#define SWSCI_SBCB_SET_BOOT_DISPLAYSWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
>> +#define SWSCI_SBCB_SET_INTERNAL_GFXSWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
>> +#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
>> +#define SWSCI_SBCB_SUSPEND_RESUME  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
>> +#define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
>> +#define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
>> +#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO
>> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
>> +
>>  #define ACPI_OTHER_OUTPUT (0<<8)
>>  #define ACPI_VGA_OUTPUT (1<<8)
>>  #define ACPI_TV_OUTPUT (2<<8)
>> @@ -158,6 +203,84 @@ struct opregion_asle {
>>  #define ACPI_LVDS_OUTPUT

Re: [Intel-gfx] [PATCH] drm/i915: add plumbing for SWSCI

2013-08-29 Thread Paulo Zanoni
Hi

2013/8/28 Jani Nikula :
> SWSCI is a driver to bios call interface.
>
> This checks for SWSCI availability and bios requested callbacks, and
> filters out any calls that shouldn't happen. This way the callers don't
> need to do the checks all over the place.
>
> v2: silence some checkpatch nagging
>
> v3: set PCI_SWSCI bit 0 to trigger interrupt (Mengdong Lin)
>
> v4: remove an extra #define (Jesse)
>
> v5: spec says s/w is responsible for clearing PCI_SWSCI bit 0 too
>
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/i915/i915_drv.h   |1 +
>  drivers/gpu/drm/i915/intel_opregion.c |  133 
> -
>  2 files changed, 131 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 84b95b1..adc2f46 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -225,6 +225,7 @@ struct intel_opregion {
> struct opregion_header __iomem *header;
> struct opregion_acpi __iomem *acpi;
> struct opregion_swsci __iomem *swsci;
> +   u32 swsci_requested_callbacks;
> struct opregion_asle __iomem *asle;
> void __iomem *vbt;
> u32 __iomem *lid_state;
> diff --git a/drivers/gpu/drm/i915/intel_opregion.c 
> b/drivers/gpu/drm/i915/intel_opregion.c
> index cfb8fb6..233cc7f 100644
> --- a/drivers/gpu/drm/i915/intel_opregion.c
> +++ b/drivers/gpu/drm/i915/intel_opregion.c
> @@ -36,8 +36,11 @@
>  #include "i915_drv.h"
>  #include "intel_drv.h"
>
> -#define PCI_ASLE 0xe4
> -#define PCI_ASLS 0xfc
> +#define PCI_ASLE   0xe4
> +#define PCI_ASLS   0xfc
> +#define PCI_SWSCI  0xe8
> +#define PCI_SWSCI_SCISEL   (1 << 15)
> +#define PCI_SWSCI_GSSCIE   (1 << 0)
>
>  #define OPREGION_HEADER_OFFSET 0
>  #define OPREGION_ACPI_OFFSET   0x100
> @@ -151,6 +154,48 @@ struct opregion_asle {
>
>  #define ASLE_CBLV_VALID (1<<31)
>
> +/* Software System Control Interrupt (SWSCI) */
> +#define SWSCI_SCIC_INDICATOR   (1 << 0)
> +#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
> +#define SWSCI_SCIC_MAIN_FUNCTION_MASK  (0xf << 1)
> +#define SWSCI_SCIC_SUB_FUNCTION_SHIFT  8
> +#define SWSCI_SCIC_SUB_FUNCTION_MASK   (0x7f << 8)

Shouldn't this be (0xff << 8) since it's bits 15:8 ?


> +#define SWSCI_SCIC_EXIT_STATUS_SHIFT   5
> +#define SWSCI_SCIC_EXIT_STATUS_MASK(7 << 5)
> +#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
> +
> +#define SWSCI_FUNCTION_CODE(main, sub) \
> +   ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
> +(sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
> +
> +/* SWSCI: Get BIOS Data (GBDA) */
> +#define SWSCI_GBDA 4
> +#define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
> +#define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
> +#define SWSCI_GBDA_BOOT_DISPLAY_PREF   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
> +#define SWSCI_GBDA_PANEL_DETAILS   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
> +#define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)

The newer spec says "reserved" here. But let's leave your definition
until they assign it again to something else :) (same thing for the
other TV bit below)


> +#define SWSCI_GBDA_INTERNAL_GRAPHICS   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
> +#define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
> +
> +/* SWSCI: System BIOS Callbacks (SBCB) */
> +#define SWSCI_SBCB 6
> +#define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
> +#define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
> +#define SWSCI_SBCB_PRE_HIRES_SET_MODE  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
> +#define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
> +#define SWSCI_SBCB_DISPLAY_SWITCH  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
> +#define SWSCI_SBCB_SET_TV_FORMAT   SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
> +#define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
> +#define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
> +#define SWSCI_SBCB_SET_BOOT_DISPLAYSWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
> +#define SWSCI_SBCB_SET_INTERNAL_GFXSWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
> +#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
> +#define SWSCI_SBCB_SUSPEND_RESUME  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
> +#define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
> +#define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
> +#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO
> SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
> +
>  #define ACPI_OTHER_OUTPUT (0<<8)
>  #define ACPI_VGA_OUTPUT (1<<8)
>  #define ACPI_TV_OUTPUT (2<<8)
> @@ -158,6 +203,84 @@ struct opregion_asle {
>  #define ACPI_LVDS_OUTPUT (4<<8)
>
>  #ifdef CONFIG_ACPI
> +static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 
> *parm_out)
> +{
> +   struct drm_i915_priv

[Intel-gfx] [PATCH] drm/i915: add plumbing for SWSCI

2013-08-28 Thread Jani Nikula
SWSCI is a driver to bios call interface.

This checks for SWSCI availability and bios requested callbacks, and
filters out any calls that shouldn't happen. This way the callers don't
need to do the checks all over the place.

v2: silence some checkpatch nagging

v3: set PCI_SWSCI bit 0 to trigger interrupt (Mengdong Lin)

v4: remove an extra #define (Jesse)

v5: spec says s/w is responsible for clearing PCI_SWSCI bit 0 too

Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/i915_drv.h   |1 +
 drivers/gpu/drm/i915/intel_opregion.c |  133 -
 2 files changed, 131 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 84b95b1..adc2f46 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -225,6 +225,7 @@ struct intel_opregion {
struct opregion_header __iomem *header;
struct opregion_acpi __iomem *acpi;
struct opregion_swsci __iomem *swsci;
+   u32 swsci_requested_callbacks;
struct opregion_asle __iomem *asle;
void __iomem *vbt;
u32 __iomem *lid_state;
diff --git a/drivers/gpu/drm/i915/intel_opregion.c 
b/drivers/gpu/drm/i915/intel_opregion.c
index cfb8fb6..233cc7f 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -36,8 +36,11 @@
 #include "i915_drv.h"
 #include "intel_drv.h"
 
-#define PCI_ASLE 0xe4
-#define PCI_ASLS 0xfc
+#define PCI_ASLE   0xe4
+#define PCI_ASLS   0xfc
+#define PCI_SWSCI  0xe8
+#define PCI_SWSCI_SCISEL   (1 << 15)
+#define PCI_SWSCI_GSSCIE   (1 << 0)
 
 #define OPREGION_HEADER_OFFSET 0
 #define OPREGION_ACPI_OFFSET   0x100
@@ -151,6 +154,48 @@ struct opregion_asle {
 
 #define ASLE_CBLV_VALID (1<<31)
 
+/* Software System Control Interrupt (SWSCI) */
+#define SWSCI_SCIC_INDICATOR   (1 << 0)
+#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
+#define SWSCI_SCIC_MAIN_FUNCTION_MASK  (0xf << 1)
+#define SWSCI_SCIC_SUB_FUNCTION_SHIFT  8
+#define SWSCI_SCIC_SUB_FUNCTION_MASK   (0x7f << 8)
+#define SWSCI_SCIC_EXIT_STATUS_SHIFT   5
+#define SWSCI_SCIC_EXIT_STATUS_MASK(7 << 5)
+#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
+
+#define SWSCI_FUNCTION_CODE(main, sub) \
+   ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
+(sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
+
+/* SWSCI: Get BIOS Data (GBDA) */
+#define SWSCI_GBDA 4
+#define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
+#define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
+#define SWSCI_GBDA_BOOT_DISPLAY_PREF   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
+#define SWSCI_GBDA_PANEL_DETAILS   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
+#define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
+#define SWSCI_GBDA_INTERNAL_GRAPHICS   SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
+#define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
+
+/* SWSCI: System BIOS Callbacks (SBCB) */
+#define SWSCI_SBCB 6
+#define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
+#define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
+#define SWSCI_SBCB_PRE_HIRES_SET_MODE  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
+#define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
+#define SWSCI_SBCB_DISPLAY_SWITCH  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
+#define SWSCI_SBCB_SET_TV_FORMAT   SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
+#define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
+#define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
+#define SWSCI_SBCB_SET_BOOT_DISPLAYSWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
+#define SWSCI_SBCB_SET_INTERNAL_GFXSWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
+#define SWSCI_SBCB_POST_HIRES_TO_DOS_FSSWSCI_FUNCTION_CODE(SWSCI_SBCB, 
16)
+#define SWSCI_SBCB_SUSPEND_RESUME  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
+#define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
+#define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
+#define SWSCI_SBCB_ENABLE_DISABLE_AUDIOSWSCI_FUNCTION_CODE(SWSCI_SBCB, 
21)
+
 #define ACPI_OTHER_OUTPUT (0<<8)
 #define ACPI_VGA_OUTPUT (1<<8)
 #define ACPI_TV_OUTPUT (2<<8)
@@ -158,6 +203,84 @@ struct opregion_asle {
 #define ACPI_LVDS_OUTPUT (4<<8)
 
 #ifdef CONFIG_ACPI
+static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
+{
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct opregion_swsci __iomem *swsci = dev_priv->opregion.swsci;
+   u32 main_function, sub_function, scic;
+   u16 pci_swsci;
+
+   if (!swsci)
+   return 0;
+
+   main_function = (function & SWSCI_SCIC_MAIN_FUNCTION_MASK) >>
+   SWSCI_SCIC_MAIN_FUNCTION_SHIFT;
+   sub_function = (function & SWSCI_SCIC_SUB_FUNCTION_MASK) >>
+   SWSCI_SCIC_SUB_FUNCTIO