hwc: Fix truncation errors in scaling decision

When checking if we are downscaling beyond what the hardware
supports, we were dividing by the factors rather than multiplying
the other side with them.  The truncation of the divisions had
hwc allowing downscaling by a factor slightly larger than what
was supported.

Change-Id: I6ae4d897f4afe68ae26f0d7385e4003d6f2a4253
Signed-off-by: Lajos Molnar <lajos@ti.com>
diff --git a/hwc/hwc.c b/hwc/hwc.c
index b5b80ec..d6c28f7 100644
--- a/hwc/hwc.c
+++ b/hwc/hwc.c
@@ -46,6 +46,8 @@
 #define WIDTH(rect) ((rect).right - (rect).left)
 #define HEIGHT(rect) ((rect).bottom - (rect).top)
 
+#define DIV_ROUND_UP(a, b) (((a) + (b) - 1) / (b))
+
 #include <video/dsscomp.h>
 
 #include "hal_public.h"
@@ -716,6 +718,8 @@
                                __u32 pclk)
 {
     __u32 fclk = limits->fclk / 1000;
+    __u32 min_src_w = DIV_ROUND_UP(src_w, is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d);
+    __u32 min_src_h = DIV_ROUND_UP(src_h, is_2d ? limits->max_ydecim_2d : limits->max_ydecim_1d);
 
     /* ERRATAs */
     /* cannot render 1-width layers on DSI video mode panels - we just disallow all 1-width LCD layers */
@@ -729,15 +733,15 @@
         return 0;
 
     /* max downscale */
-    if (dst_h < src_h / limits->max_downscale / (is_2d ? limits->max_ydecim_2d : limits->max_ydecim_1d))
+    if (dst_h * limits->max_downscale < min_src_h)
         return 0;
 
     /* for manual panels pclk is 0, and there are no pclk based scaling limits */
     if (!pclk)
-        return (dst_w < src_w / limits->max_downscale / (is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d));
+        return !(dst_w * limits->max_downscale < min_src_w);
 
     /* :HACK: limit horizontal downscale well below theoretical limit as we saw display artifacts */
-    if (dst_w < src_w / 4)
+    if (dst_w * 4 < src_w)
         return 0;
 
     /* max horizontal downscale is 4, or the fclk/pixclk */
@@ -746,7 +750,7 @@
     /* for small parts, we need to use integer fclk/pixclk */
     if (src_w < limits->integer_scale_ratio_limit)
         fclk = fclk / pclk * pclk;
-    if ((__u32) dst_w < src_w * pclk / fclk / (is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d))
+    if ((__u32) dst_w * fclk < min_src_w * pclk)
         return 0;
 
     return 1;