Intel DGFX cards provides a feature Video Ram Self Refrsh(vram_sr).
vram_sr can be enabled with runtime suspend D3Cold flow and with
opportunistic S0ix system wide suspend flow as well.

vram_sr feature requires Host BIOS support, vram_sr will be
enable/disable by HOST BIOS using ACPI OpRegion.

OpRegion vram_sr is only applicable on Motherboard Down
cards.

Adding OpRegion vram_sr support in order to enable/disable
vram_sr on discrete cards.

v2:
- Added opregion->header NULL check. [Jani]
- Bundled opregion->asle NULL check to early return. [Jani]
- Use static inline for dummy declaration. [Jani]

BSpec: 53440
Cc: Jani Nikula <[email protected]>
Cc: Rodrigo Vivi <[email protected]>
Signed-off-by: Anshuman Gupta <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_opregion.c | 78 ++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_opregion.h | 17 ++++
 2 files changed, 94 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c 
b/drivers/gpu/drm/i915/display/intel_opregion.c
index 1c0c745c142d..f4a2a02c9ed3 100644
--- a/drivers/gpu/drm/i915/display/intel_opregion.c
+++ b/drivers/gpu/drm/i915/display/intel_opregion.c
@@ -55,6 +55,8 @@
 #define MBOX_ASLE_EXT          BIT(4)  /* Mailbox #5 */
 #define MBOX_BACKLIGHT         BIT(5)  /* Mailbox #2 (valid from v3.x) */
 
+#define PCON_DGFX_BIOS_SUPPORTS_VRSR                   BIT(11)
+#define PCON_DGFX_BIOS_SUPPORTS_VRSR_FIELD_VALID       BIT(12)
 #define PCON_HEADLESS_SKU      BIT(13)
 
 struct opregion_header {
@@ -132,7 +134,8 @@ struct opregion_asle {
        u64 rvda;       /* Physical (2.0) or relative from opregion (2.1+)
                         * address of raw VBT data. */
        u32 rvds;       /* Size of raw vbt data */
-       u8 rsvd[58];
+       u8 vrsr;        /* DGFX Video Ram Self Refresh */
+       u8 rsvd[57];
 } __packed;
 
 /* OpRegion mailbox #5: ASLE ext */
@@ -203,6 +206,9 @@ struct opregion_asle_ext {
 
 #define ASLE_PHED_EDID_VALID_MASK      0x3
 
+/* VRAM SR */
+#define ASLE_VRSR_ENABLE               BIT(0)
+
 /* Software System Control Interrupt (SWSCI) */
 #define SWSCI_SCIC_INDICATOR           (1 << 0)
 #define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
@@ -923,6 +929,8 @@ int intel_opregion_setup(struct drm_i915_private *dev_priv)
                opregion->header->over.minor,
                opregion->header->over.revision);
 
+       drm_dbg(&dev_priv->drm, "OpRegion PCON values 0x%x\n", 
opregion->header->pcon);
+
        mboxes = opregion->header->mboxes;
        if (mboxes & MBOX_ACPI) {
                drm_dbg(&dev_priv->drm, "Public ACPI methods supported\n");
@@ -1248,3 +1256,71 @@ void intel_opregion_unregister(struct drm_i915_private 
*i915)
        opregion->vbt = NULL;
        opregion->lid_state = NULL;
 }
+
+/**
+ * intel_opregion_vram_sr_required().
+ * @i915 i915 device priv data.
+ *
+ * It checks whether a DGFX card is Mother Board Down config depending
+ * on respective discrete platform.
+ *
+ * Returns:
+ * It returns a boolean whether opregion vram_sr support is required.
+ */
+bool
+intel_opregion_vram_sr_required(struct drm_i915_private *i915)
+{
+       return false;
+}
+
+/**
+ * intel_opregion_bios_supports_vram_sr() - get HOST BIOS vram_sr
+ * capability support.
+ * @i915: pointer to i915 device.
+ *
+ * It checks opregion pcon vram_sr fields to get HOST BIOS vram_sr
+ * capability support. It is only applocable to DGFX.
+ *
+ * Returns:
+ * true when bios supports vram_sr, or false if bios doesn't support.
+ */
+bool intel_opregion_bios_supports_vram_sr(struct drm_i915_private *i915)
+{
+       struct intel_opregion *opregion = &i915->opregion;
+
+       if (!IS_DGFX(i915))
+               return false;
+
+       if (!opregion->header)
+               return false;
+
+       if (opregion->header->pcon & PCON_DGFX_BIOS_SUPPORTS_VRSR_FIELD_VALID)
+               return opregion->header->pcon & PCON_DGFX_BIOS_SUPPORTS_VRSR;
+       else
+               return false;
+}
+
+/**
+ * intel_opregion_vram_sr() - enable/disable vram_sr.
+ * @i915: pointer to i915 device.
+ * @enable: Argument to enable/disable vram_sr.
+ *
+ * It enables/disables vram_sr in opregion ASLE MBOX, based upon that
+ * HOST BIOS will enables and disbales VRAM_SR during
+ * ACPI _PS3/_OFF and _PS/_ON glue method.
+ */
+void intel_opregion_vram_sr(struct drm_i915_private *i915, bool enable)
+{
+       struct intel_opregion *opregion = &i915->opregion;
+
+       if (!opregion->header || !opregion->asle)
+               return;
+
+       if (!intel_opregion_vram_sr_required(i915))
+               return;
+
+       if (enable)
+               opregion->asle->vrsr |= ASLE_VRSR_ENABLE;
+       else
+               opregion->asle->vrsr &= ~ASLE_VRSR_ENABLE;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_opregion.h 
b/drivers/gpu/drm/i915/display/intel_opregion.h
index 2f261f985400..55a61e8a28dc 100644
--- a/drivers/gpu/drm/i915/display/intel_opregion.h
+++ b/drivers/gpu/drm/i915/display/intel_opregion.h
@@ -75,6 +75,9 @@ int intel_opregion_notify_adapter(struct drm_i915_private 
*dev_priv,
                                  pci_power_t state);
 int intel_opregion_get_panel_type(struct drm_i915_private *dev_priv);
 struct edid *intel_opregion_get_edid(struct intel_connector *connector);
+bool intel_opregion_vram_sr_required(struct drm_i915_private *i915);
+bool intel_opregion_bios_supports_vram_sr(struct drm_i915_private *i915);
+void intel_opregion_vram_sr(struct drm_i915_private *i915, bool enable);
 
 bool intel_opregion_headless_sku(struct drm_i915_private *i915);
 
@@ -134,6 +137,20 @@ static inline bool intel_opregion_headless_sku(struct 
drm_i915_private *i915)
        return false;
 }
 
+static inline bool intel_opregion_vram_sr_required(struct drm_i915_private 
*i915)
+{
+       return false;
+}
+
+static inline bool intel_opregion_bios_supports_vram_sr(struct 
drm_i915_private *i915)
+{
+       return false;
+}
+
+static inline void intel_opregion_vram_sr(struct drm_i915_private *i915, bool 
enable)
+{
+}
+
 #endif /* CONFIG_ACPI */
 
 #endif
-- 
2.26.2

Reply via email to