summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_drv.h
diff options
context:
space:
mode:
authorMahesh Kumar <mahesh1.kumar@intel.com>2016-12-01 21:19:37 +0530
committerPaulo Zanoni <paulo.r.zanoni@intel.com>2016-12-07 16:30:34 -0200
commitb95320bdf2d891011da9c5ec85dcb114483856a6 (patch)
tree2578f72c9c83314a2fc9fc4fdcb319dfcfef82fe /drivers/gpu/drm/i915/i915_drv.h
parent4b7b2331885a1ab348178f3faf9dc6a4dccae01a (diff)
downloadlwn-b95320bdf2d891011da9c5ec85dcb114483856a6.tar.gz
lwn-b95320bdf2d891011da9c5ec85dcb114483856a6.zip
drm/i915/skl+: change WM calc to fixed point 16.16
This patch changes Watermak calculation to fixed point calculation. Problem with current calculation is during plane_blocks_per_line calculation we divide intermediate blocks with min_scanlines and takes floor of the result because of integer operation. hence we end-up assigning less blocks than required. Which leads to flickers. Changes since V1: - Add fixed point data type as per Paulo's review Changes since V2: - use fixed_point instead of fp_16_16 Changes since V3: - rebase Changes since V4 (from Paulo): - My original renaming suggestion was misunderstood, so implement it - Simplify fixed_16_16_to_u32 implementation - Fix indentation Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Mahesh Kumar <mahesh1.kumar@intel.com> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20161201154940.24446-6-mahesh1.kumar@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/i915_drv.h')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h84
1 files changed, 84 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4eea9255dc53..b9138cd75a39 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -119,6 +119,90 @@ bool __i915_inject_load_failure(const char *func, int line);
#define i915_inject_load_failure() \
__i915_inject_load_failure(__func__, __LINE__)
+typedef struct {
+ uint32_t val;
+} uint_fixed_16_16_t;
+
+#define FP_16_16_MAX ({ \
+ uint_fixed_16_16_t fp; \
+ fp.val = UINT_MAX; \
+ fp; \
+})
+
+static inline uint_fixed_16_16_t u32_to_fixed_16_16(uint32_t val)
+{
+ uint_fixed_16_16_t fp;
+
+ WARN_ON(val >> 16);
+
+ fp.val = val << 16;
+ return fp;
+}
+
+static inline uint32_t fixed_16_16_to_u32_round_up(uint_fixed_16_16_t fp)
+{
+ return DIV_ROUND_UP(fp.val, 1 << 16);
+}
+
+static inline uint32_t fixed_16_16_to_u32(uint_fixed_16_16_t fp)
+{
+ return fp.val >> 16;
+}
+
+static inline uint_fixed_16_16_t min_fixed_16_16(uint_fixed_16_16_t min1,
+ uint_fixed_16_16_t min2)
+{
+ uint_fixed_16_16_t min;
+
+ min.val = min(min1.val, min2.val);
+ return min;
+}
+
+static inline uint_fixed_16_16_t max_fixed_16_16(uint_fixed_16_16_t max1,
+ uint_fixed_16_16_t max2)
+{
+ uint_fixed_16_16_t max;
+
+ max.val = max(max1.val, max2.val);
+ return max;
+}
+
+static inline uint_fixed_16_16_t fixed_16_16_div_round_up(uint32_t val,
+ uint32_t d)
+{
+ uint_fixed_16_16_t fp, res;
+
+ fp = u32_to_fixed_16_16(val);
+ res.val = DIV_ROUND_UP(fp.val, d);
+ return res;
+}
+
+static inline uint_fixed_16_16_t fixed_16_16_div_round_up_u64(uint32_t val,
+ uint32_t d)
+{
+ uint_fixed_16_16_t res;
+ uint64_t interm_val;
+
+ interm_val = (uint64_t)val << 16;
+ interm_val = DIV_ROUND_UP_ULL(interm_val, d);
+ WARN_ON(interm_val >> 32);
+ res.val = (uint32_t) interm_val;
+
+ return res;
+}
+
+static inline uint_fixed_16_16_t mul_u32_fixed_16_16(uint32_t val,
+ uint_fixed_16_16_t mul)
+{
+ uint64_t intermediate_val;
+ uint_fixed_16_16_t fp;
+
+ intermediate_val = (uint64_t) val * mul.val;
+ WARN_ON(intermediate_val >> 32);
+ fp.val = (uint32_t) intermediate_val;
+ return fp;
+}
+
static inline const char *yesno(bool v)
{
return v ? "yes" : "no";