drm/i915/dsi: Fix state mismatch warns for horizontal timings with DSC
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / display / intel_bw.c
index 7b908e1..dcb66a3 100644 (file)
@@ -6,7 +6,7 @@
 #include <drm/drm_atomic_state_helper.h>
 
 #include "intel_bw.h"
-#include "intel_drv.h"
+#include "intel_display_types.h"
 #include "intel_sideband.h"
 
 /* Parameters for Qclk Geyserville (QGV) */
@@ -15,7 +15,7 @@ struct intel_qgv_point {
 };
 
 struct intel_qgv_info {
-       struct intel_qgv_point points[3];
+       struct intel_qgv_point points[I915_NUM_QGV_POINTS];
        u8 num_points;
        u8 num_channels;
        u8 t_bl;
@@ -35,28 +35,54 @@ static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv,
        if (ret)
                return ret;
 
-       switch (val & 0xf) {
-       case 0:
-               qi->dram_type = INTEL_DRAM_DDR4;
-               break;
-       case 1:
-               qi->dram_type = INTEL_DRAM_DDR3;
-               break;
-       case 2:
-               qi->dram_type = INTEL_DRAM_LPDDR3;
-               break;
-       case 3:
-               qi->dram_type = INTEL_DRAM_LPDDR3;
-               break;
-       default:
-               MISSING_CASE(val & 0xf);
-               break;
+       if (IS_GEN(dev_priv, 12)) {
+               switch (val & 0xf) {
+               case 0:
+                       qi->dram_type = INTEL_DRAM_DDR4;
+                       break;
+               case 3:
+                       qi->dram_type = INTEL_DRAM_LPDDR4;
+                       break;
+               case 4:
+                       qi->dram_type = INTEL_DRAM_DDR3;
+                       break;
+               case 5:
+                       qi->dram_type = INTEL_DRAM_LPDDR3;
+                       break;
+               default:
+                       MISSING_CASE(val & 0xf);
+                       break;
+               }
+       } else if (IS_GEN(dev_priv, 11)) {
+               switch (val & 0xf) {
+               case 0:
+                       qi->dram_type = INTEL_DRAM_DDR4;
+                       break;
+               case 1:
+                       qi->dram_type = INTEL_DRAM_DDR3;
+                       break;
+               case 2:
+                       qi->dram_type = INTEL_DRAM_LPDDR3;
+                       break;
+               case 3:
+                       qi->dram_type = INTEL_DRAM_LPDDR4;
+                       break;
+               default:
+                       MISSING_CASE(val & 0xf);
+                       break;
+               }
+       } else {
+               MISSING_CASE(INTEL_GEN(dev_priv));
+               qi->dram_type = INTEL_DRAM_LPDDR3; /* Conservative default */
        }
 
        qi->num_channels = (val & 0xf0) >> 4;
        qi->num_points = (val & 0xf00) >> 8;
 
-       qi->t_bl = qi->dram_type == INTEL_DRAM_DDR4 ? 4 : 8;
+       if (IS_GEN(dev_priv, 12))
+               qi->t_bl = qi->dram_type == INTEL_DRAM_DDR4 ? 4 : 16;
+       else if (IS_GEN(dev_priv, 11))
+               qi->t_bl = qi->dram_type == INTEL_DRAM_DDR4 ? 4 : 8;
 
        return 0;
 }
@@ -65,7 +91,7 @@ static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
                                         struct intel_qgv_point *sp,
                                         int point)
 {
-       u32 val = 0, val2;
+       u32 val = 0, val2 = 0;
        int ret;
 
        ret = sandybridge_pcode_read(dev_priv,
@@ -132,20 +158,25 @@ static int icl_sagv_max_dclk(const struct intel_qgv_info *qi)
 }
 
 struct intel_sa_info {
-       u8 deburst, mpagesize, deprogbwlimit, displayrtids;
+       u16 displayrtids;
+       u8 deburst, deprogbwlimit;
 };
 
 static const struct intel_sa_info icl_sa_info = {
        .deburst = 8,
-       .mpagesize = 16,
        .deprogbwlimit = 25, /* GB/s */
        .displayrtids = 128,
 };
 
-static int icl_get_bw_info(struct drm_i915_private *dev_priv)
+static const struct intel_sa_info tgl_sa_info = {
+       .deburst = 16,
+       .deprogbwlimit = 34, /* GB/s */
+       .displayrtids = 256,
+};
+
+static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa)
 {
        struct intel_qgv_info qi = {};
-       const struct intel_sa_info *sa = &icl_sa_info;
        bool is_y_tile = true; /* assume y tile may be used */
        int num_channels;
        int deinterleave;
@@ -233,24 +264,41 @@ static unsigned int icl_max_bw(struct drm_i915_private *dev_priv,
 
 void intel_bw_init_hw(struct drm_i915_private *dev_priv)
 {
-       if (IS_GEN(dev_priv, 11))
-               icl_get_bw_info(dev_priv);
+       if (!HAS_DISPLAY(dev_priv))
+               return;
+
+       if (IS_GEN(dev_priv, 12))
+               icl_get_bw_info(dev_priv, &tgl_sa_info);
+       else if (IS_GEN(dev_priv, 11))
+               icl_get_bw_info(dev_priv, &icl_sa_info);
 }
 
 static unsigned int intel_max_data_rate(struct drm_i915_private *dev_priv,
                                        int num_planes)
 {
-       if (IS_GEN(dev_priv, 11))
+       if (INTEL_GEN(dev_priv) >= 11) {
+               /*
+                * Any bw group has same amount of QGV points
+                */
+               const struct intel_bw_info *bi =
+                       &dev_priv->max_bw[0];
+               unsigned int min_bw = UINT_MAX;
+               int i;
+
                /*
                 * FIXME with SAGV disabled maybe we can assume
                 * point 1 will always be used? Seems to match
                 * the behaviour observed in the wild.
                 */
-               return min3(icl_max_bw(dev_priv, num_planes, 0),
-                           icl_max_bw(dev_priv, num_planes, 1),
-                           icl_max_bw(dev_priv, num_planes, 2));
-       else
+               for (i = 0; i < bi->num_qgv_points; i++) {
+                       unsigned int bw = icl_max_bw(dev_priv, num_planes, i);
+
+                       min_bw = min(bw, min_bw);
+               }
+               return min_bw;
+       } else {
                return UINT_MAX;
+       }
 }
 
 static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state)
@@ -264,7 +312,7 @@ static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_stat
 
 static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_state)
 {
-       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        unsigned int data_rate = 0;
        enum plane_id plane_id;
 
@@ -285,7 +333,7 @@ static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_
 void intel_bw_crtc_update(struct intel_bw_state *bw_state,
                          const struct intel_crtc_state *crtc_state)
 {
-       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
        bw_state->data_rate[crtc->pipe] =
                intel_bw_crtc_data_rate(crtc_state);
@@ -322,6 +370,20 @@ static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv,
        return data_rate;
 }
 
+static struct intel_bw_state *
+intel_atomic_get_bw_state(struct intel_atomic_state *state)
+{
+       struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+       struct drm_private_state *bw_state;
+
+       bw_state = drm_atomic_get_private_obj_state(&state->base,
+                                                   &dev_priv->bw_obj);
+       if (IS_ERR(bw_state))
+               return ERR_CAST(bw_state);
+
+       return to_intel_bw_state(bw_state);
+}
+
 int intel_bw_atomic_check(struct intel_atomic_state *state)
 {
        struct drm_i915_private *dev_priv = to_i915(state->base.dev);