]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm: mxsfb: Increase number of outstanding requests on V4 and newer HW
authorMarek Vasut <marex@denx.de>
Sun, 20 Jun 2021 22:47:59 +0000 (00:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Sep 2021 07:50:35 +0000 (09:50 +0200)
[ Upstream commit 9891cb54445bc65bf156bda416b6215048c7f617 ]

In case the DRAM is under high load, the MXSFB FIFO might underflow
and that causes visible artifacts. This could be triggered on i.MX8MM
using e.g. "$ memtester 128M" on a device with 1920x1080 panel. The
first "Stuck Address" test of the memtester will completely corrupt
the image on the panel and leave the MXSFB FIFO in odd state.

To avoid this underflow, increase number of outstanding requests to
DRAM from 2 to 16, which is the maximum. This mitigates the issue
and it can no longer be triggered.

Fixes: 45d59d704080 ("drm: Add new driver for MXSFB controller")
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Daniel Abrecht <public@danielabrecht.ch>
Cc: Emil Velikov <emil.l.velikov@gmail.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Stefan Agner <stefan@agner.ch>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210620224759.189351-1-marex@denx.de
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/mxsfb/mxsfb_drv.c
drivers/gpu/drm/mxsfb/mxsfb_drv.h
drivers/gpu/drm/mxsfb/mxsfb_kms.c
drivers/gpu/drm/mxsfb/mxsfb_regs.h

index 17f26052e84508f0385c9db7f604e07545f9a1ce..f31e8ef3c258cc82973ee222e624ea0ea26a889e 100644 (file)
@@ -51,6 +51,7 @@ static const struct mxsfb_devdata mxsfb_devdata[] = {
                .hs_wdth_mask   = 0xff,
                .hs_wdth_shift  = 24,
                .has_overlay    = false,
+               .has_ctrl2      = false,
        },
        [MXSFB_V4] = {
                .transfer_count = LCDC_V4_TRANSFER_COUNT,
@@ -59,6 +60,7 @@ static const struct mxsfb_devdata mxsfb_devdata[] = {
                .hs_wdth_mask   = 0x3fff,
                .hs_wdth_shift  = 18,
                .has_overlay    = false,
+               .has_ctrl2      = true,
        },
        [MXSFB_V6] = {
                .transfer_count = LCDC_V4_TRANSFER_COUNT,
@@ -67,6 +69,7 @@ static const struct mxsfb_devdata mxsfb_devdata[] = {
                .hs_wdth_mask   = 0x3fff,
                .hs_wdth_shift  = 18,
                .has_overlay    = true,
+               .has_ctrl2      = true,
        },
 };
 
index 399d23e91ed10badde03b1c448b0c81c98633f2b..7c720e226fdfd480739045a5b62a3aa2e5d215ae 100644 (file)
@@ -22,6 +22,7 @@ struct mxsfb_devdata {
        unsigned int    hs_wdth_mask;
        unsigned int    hs_wdth_shift;
        bool            has_overlay;
+       bool            has_ctrl2;
 };
 
 struct mxsfb_drm_private {
index bc6d19d999ace7d2a777eb3b77318c760d201319..007ea29abfccd8083fc2ac930497783c6085de50 100644 (file)
@@ -107,6 +107,14 @@ static void mxsfb_enable_controller(struct mxsfb_drm_private *mxsfb)
                clk_prepare_enable(mxsfb->clk_disp_axi);
        clk_prepare_enable(mxsfb->clk);
 
+       /* Increase number of outstanding requests on all supported IPs */
+       if (mxsfb->devdata->has_ctrl2) {
+               reg = readl(mxsfb->base + LCDC_V4_CTRL2);
+               reg &= ~CTRL2_SET_OUTSTANDING_REQS_MASK;
+               reg |= CTRL2_SET_OUTSTANDING_REQS_16;
+               writel(reg, mxsfb->base + LCDC_V4_CTRL2);
+       }
+
        /* If it was disabled, re-enable the mode again */
        writel(CTRL_DOTCLK_MODE, mxsfb->base + LCDC_CTRL + REG_SET);
 
index df90e960f495c281b1c5233e4898c48ece91a7c5..694fea13e893e12b22aeeadc77ab613454bd446c 100644 (file)
@@ -15,6 +15,7 @@
 #define LCDC_CTRL                      0x00
 #define LCDC_CTRL1                     0x10
 #define LCDC_V3_TRANSFER_COUNT         0x20
+#define LCDC_V4_CTRL2                  0x20
 #define LCDC_V4_TRANSFER_COUNT         0x30
 #define LCDC_V4_CUR_BUF                        0x40
 #define LCDC_V4_NEXT_BUF               0x50
 #define CTRL1_CUR_FRAME_DONE_IRQ_EN    BIT(13)
 #define CTRL1_CUR_FRAME_DONE_IRQ       BIT(9)
 
+#define CTRL2_SET_OUTSTANDING_REQS_1   0
+#define CTRL2_SET_OUTSTANDING_REQS_2   (0x1 << 21)
+#define CTRL2_SET_OUTSTANDING_REQS_4   (0x2 << 21)
+#define CTRL2_SET_OUTSTANDING_REQS_8   (0x3 << 21)
+#define CTRL2_SET_OUTSTANDING_REQS_16  (0x4 << 21)
+#define CTRL2_SET_OUTSTANDING_REQS_MASK        (0x7 << 21)
+
 #define TRANSFER_COUNT_SET_VCOUNT(x)   (((x) & 0xffff) << 16)
 #define TRANSFER_COUNT_GET_VCOUNT(x)   (((x) >> 16) & 0xffff)
 #define TRANSFER_COUNT_SET_HCOUNT(x)   ((x) & 0xffff)