]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00290361-2 MXC IPUv3 fb:Add check for a IDMAC errata
authorLiu Ying <Ying.Liu@freescale.com>
Mon, 2 Dec 2013 08:56:00 +0000 (16:56 +0800)
committerLiu Ying <Ying.Liu@freescale.com>
Tue, 3 Dec 2013 06:42:15 +0000 (14:42 +0800)
The IPUv3 IDMAC has a bug to read 32bpp pixels from a
graphics plane whose alpha component is at the most
significant 8 bits. The bug only impacts on cases in which
the relevant separate alpha channel is enabled.
This patch adds check for the errata so that the bad
cases won't be triggered.

Signed-off-by: Liu Ying <Ying.Liu@freescale.com>
drivers/video/mxc/mxc_ipuv3_fb.c

index 29b7333a0b6c923bbf23b7851f7e5d84515d8340..49abe8c284fc013992707ad5f77b0f8c19ffb0b4 100644 (file)
@@ -445,6 +445,13 @@ static int mxcfb_set_par(struct fb_info *fbi)
        struct mxcfb_info *mxc_fbi_fg = NULL;
        bool ovfbi_enable = false;
 
+       if (ipu_ch_param_bad_alpha_pos(fbi_to_pixfmt(fbi)) &&
+           mxc_fbi->alpha_chan_en) {
+               dev_err(fbi->device, "Bad pixel format for "
+                               "graphics plane fb\n");
+               return -EINVAL;
+       }
+
        if (mxc_fbi->ovfbi)
                mxc_fbi_fg = (struct mxcfb_info *)mxc_fbi->ovfbi->par;
 
@@ -986,22 +993,25 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
        case MXCFB_SET_LOC_ALPHA:
                {
                        struct mxcfb_loc_alpha la;
+                       bool bad_pixfmt =
+                               ipu_ch_param_bad_alpha_pos(fbi_to_pixfmt(fbi));
 
                        if (copy_from_user(&la, (void *)arg, sizeof(la))) {
                                retval = -EFAULT;
                                break;
                        }
 
-                       if (ipu_disp_set_global_alpha(mxc_fbi->ipu, mxc_fbi->ipu_ch,
-                                                     !(bool)la.enable, 0)) {
-                               retval = -EINVAL;
-                               break;
-                       }
-
                        if (la.enable && !la.alpha_in_pixel) {
                                struct fb_info *fbi_tmp;
                                ipu_channel_t ipu_ch;
 
+                               if (bad_pixfmt) {
+                                       dev_err(fbi->device, "Bad pixel format "
+                                               "for graphics plane fb\n");
+                                       retval = -EINVAL;
+                                       break;
+                               }
+
                                mxc_fbi->alpha_chan_en = true;
 
                                if (mxc_fbi->ipu_ch == MEM_FG_SYNC)
@@ -1019,6 +1029,13 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
                        } else
                                mxc_fbi->alpha_chan_en = false;
 
+                       if (ipu_disp_set_global_alpha(mxc_fbi->ipu,
+                                                     mxc_fbi->ipu_ch,
+                                                     !(bool)la.enable, 0)) {
+                               retval = -EINVAL;
+                               break;
+                       }
+
                        fbi->var.activate = (fbi->var.activate & ~FB_ACTIVATE_MASK) |
                                                FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
                        mxcfb_set_par(fbi);