drm/i915: Parse VBT PSR block.
authorRodrigo Vivi <rodrigo.vivi@intel.com>
Fri, 14 Nov 2014 16:52:30 +0000 (08:52 -0800)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 3 Dec 2014 08:35:05 +0000 (09:35 +0100)
PSR (aka SRD) block is defined at VBT and currently being used.
Mainly/At-least to configure the amount of idle_frames require to get
back to PSR Entry.

Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_bios.h

index bb1892d..c7f00a4 100644 (file)
@@ -1306,6 +1306,13 @@ enum drrs_support_type {
        SEAMLESS_DRRS_SUPPORT = 2
 };
 
+enum psr_lines_to_wait {
+       PSR_0_LINES_TO_WAIT = 0,
+       PSR_1_LINE_TO_WAIT,
+       PSR_4_LINES_TO_WAIT,
+       PSR_8_LINES_TO_WAIT
+};
+
 struct intel_vbt_data {
        struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
        struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
@@ -1334,6 +1341,15 @@ struct intel_vbt_data {
        int edp_bpp;
        struct edp_power_seq edp_pps;
 
+       struct {
+               bool full_link;
+               bool require_aux_wakeup;
+               int idle_frames;
+               enum psr_lines_to_wait lines_to_wait;
+               int tp1_wakeup_time;
+               int tp2_tp3_wakeup_time;
+       } psr;
+
        struct {
                u16 pwm_freq_hz;
                bool present;
index a4bd90f..3f17825 100644 (file)
@@ -664,6 +664,50 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
        }
 }
 
+static void
+parse_psr(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
+{
+       struct bdb_psr *psr;
+       struct psr_table *psr_table;
+
+       psr = find_section(bdb, BDB_PSR);
+       if (!psr) {
+               DRM_DEBUG_KMS("No PSR BDB found.\n");
+               return;
+       }
+
+       psr_table = &psr->psr_table[panel_type];
+
+       dev_priv->vbt.psr.full_link = psr_table->full_link;
+       dev_priv->vbt.psr.require_aux_wakeup = psr_table->require_aux_to_wakeup;
+
+       /* Allowed VBT values goes from 0 to 15 */
+       dev_priv->vbt.psr.idle_frames = psr_table->idle_frames < 0 ? 0 :
+               psr_table->idle_frames > 15 ? 15 : psr_table->idle_frames;
+
+       switch (psr_table->lines_to_wait) {
+       case 0:
+               dev_priv->vbt.psr.lines_to_wait = PSR_0_LINES_TO_WAIT;
+               break;
+       case 1:
+               dev_priv->vbt.psr.lines_to_wait = PSR_1_LINE_TO_WAIT;
+               break;
+       case 2:
+               dev_priv->vbt.psr.lines_to_wait = PSR_4_LINES_TO_WAIT;
+               break;
+       case 3:
+               dev_priv->vbt.psr.lines_to_wait = PSR_8_LINES_TO_WAIT;
+               break;
+       default:
+               DRM_DEBUG_KMS("VBT has unknown PSR lines to wait %u\n",
+                             psr_table->lines_to_wait);
+               break;
+       }
+
+       dev_priv->vbt.psr.tp1_wakeup_time = psr_table->tp1_wakeup_time;
+       dev_priv->vbt.psr.tp2_tp3_wakeup_time = psr_table->tp2_tp3_wakeup_time;
+}
+
 static u8 *goto_next_sequence(u8 *data, int *size)
 {
        u16 len;
@@ -1241,6 +1285,7 @@ intel_parse_bios(struct drm_device *dev)
        parse_device_mapping(dev_priv, bdb);
        parse_driver_features(dev_priv, bdb);
        parse_edp(dev_priv, bdb);
+       parse_psr(dev_priv, bdb);
        parse_mipi(dev_priv, bdb);
        parse_ddi_ports(dev_priv, bdb);
 
index 7603765..de01167 100644 (file)
@@ -80,7 +80,7 @@ struct vbios_data {
 #define BDB_EXT_MMIO_REGS        6
 #define BDB_SWF_IO               7
 #define BDB_SWF_MMIO             8
-#define BDB_DOT_CLOCK_TABLE      9
+#define BDB_PSR                          9
 #define BDB_MODE_REMOVAL_TABLE  10
 #define BDB_CHILD_DEVICE_TABLE  11
 #define BDB_DRIVER_FEATURES     12
@@ -556,6 +556,26 @@ struct bdb_edp {
        u16 edp_t3_optimization;
 } __packed;
 
+struct psr_table {
+       /* Feature bits */
+       u8 full_link:1;
+       u8 require_aux_to_wakeup:1;
+       u8 feature_bits_rsvd:6;
+
+       /* Wait times */
+       u8 idle_frames:4;
+       u8 lines_to_wait:3;
+       u8 wait_times_rsvd:1;
+
+       /* TP wake up time in multiple of 100 */
+       u16 tp1_wakeup_time;
+       u16 tp2_tp3_wakeup_time;
+} __packed;
+
+struct bdb_psr {
+       struct psr_table psr_table[16];
+} __packed;
+
 void intel_setup_bios(struct drm_device *dev);
 int intel_parse_bios(struct drm_device *dev);