From 613092e2fd58ac50f4416f73a37ed47de6275a51 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Fri, 26 Feb 2021 10:24:48 -0800 Subject: [PATCH] MLK-25320 video: imx_lcdifv3: Add memory priority threshold setting Add the panic control from kernel for lcdifv3 to increase the memory request priority to resolve QoS issue. User can adjust the thresholds by using 'thres-low' and 'thres-high' properties in DTS. Signed-off-by: Ye Li Reviewed-by: Jian Li (cherry picked from commit f81e7caa100940206550ee4e2f64b5b799a5d92e) --- drivers/video/nxp/imx/imx_lcdifv3.c | 90 +++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/drivers/video/nxp/imx/imx_lcdifv3.c b/drivers/video/nxp/imx/imx_lcdifv3.c index 4c1c1f4..8a1fa18 100644 --- a/drivers/video/nxp/imx/imx_lcdifv3.c +++ b/drivers/video/nxp/imx/imx_lcdifv3.c @@ -30,6 +30,11 @@ struct lcdifv3_priv { fdt_addr_t reg_base; struct udevice *disp_dev; + + u32 thres_low_mul; + u32 thres_low_div; + u32 thres_high_mul; + u32 thres_high_div; }; static int lcdifv3_set_pix_fmt(struct lcdifv3_priv *priv, unsigned int format) @@ -114,6 +119,38 @@ static void lcdifv3_set_bus_fmt(struct lcdifv3_priv *priv) writel(disp_para, (ulong)(priv->reg_base + LCDIFV3_DISP_PARA)); } +static void lcdifv3_enable_plane_panic(struct lcdifv3_priv *priv) +{ + u32 panic_thres, thres_low, thres_high; + + /* apb clock has been enabled */ + + /* As suggestion, the thres_low should be 1/3 FIFO, + * and thres_high should be 2/3 FIFO (The FIFO size + * is 8KB = 512 * 128bit). + * threshold = n * 128bit (n: 0 ~ 511) + */ + thres_low = DIV_ROUND_UP(511 * priv->thres_low_mul, + priv->thres_low_div); + thres_high = DIV_ROUND_UP(511 * priv->thres_high_mul, + priv->thres_high_div); + + panic_thres = PANIC0_THRES_PANIC_THRES_LOW(thres_low) | + PANIC0_THRES_PANIC_THRES_HIGH(thres_high); + + writel(panic_thres, priv->reg_base + LCDIFV3_PANIC0_THRES); + + /* Enable Panic: + * + * As designed, the panic won't trigger an irq, + * so it is unnecessary to handle this as an irq + * and NoC + QoS modules will handle panic + * automatically. + */ + writel(INT_ENABLE_D1_PLANE_PANIC_EN, + priv->reg_base + LCDIFV3_INT_ENABLE_D1); +} + static void lcdifv3_enable_controller(struct lcdifv3_priv *priv) { u32 disp_para, ctrldescl0_5; @@ -162,6 +199,9 @@ static void lcdifv3_init(struct udevice *dev, writel(CTRL_SW_RESET, (ulong)(priv->reg_base + LCDIFV3_CTRL_CLR)); + /* enable plane FIFO panic */ + lcdifv3_enable_plane_panic(priv); + lcdifv3_set_mode(priv, mode); lcdifv3_set_bus_fmt(priv); @@ -224,6 +264,54 @@ static int lcdifv3_of_get_timings(struct udevice *dev, return ret; } +static int lcdifv3_check_thres_value(u32 mul, u32 div) +{ + if (!div) + return -EINVAL; + + if (mul > div) + return -EINVAL; + + return 0; +} + +static void lcdifv3_of_parse_thres(struct udevice *dev) +{ + int ret; + u32 thres_low[2], thres_high[2]; + struct lcdifv3_priv *priv = dev_get_priv(dev); + + + /* default 'thres-low' value: FIFO * 1/3; + * default 'thres-high' value: FIFO * 2/3. + */ + priv->thres_low_mul = 1; + priv->thres_low_div = 3; + priv->thres_high_mul = 2; + priv->thres_high_div = 3; + + ret = dev_read_u32_array(dev, "thres-low", thres_low, 2); + if (!ret) { + /* check the value effectiveness */ + ret = lcdifv3_check_thres_value(thres_low[0], thres_low[1]); + if (!ret) { + priv->thres_low_mul = thres_low[0]; + priv->thres_low_div = thres_low[1]; + } + } + + ret = dev_read_u32_array(dev, "thres-high", thres_high, 2); + if (!ret) { + /* check the value effectiveness */ + ret = lcdifv3_check_thres_value(thres_high[0], thres_high[1]); + if (!ret) { + priv->thres_high_mul = thres_high[0]; + priv->thres_high_div = thres_high[1]; + } + } +} + + static int lcdifv3_video_probe(struct udevice *dev) { struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); @@ -249,6 +337,8 @@ static int lcdifv3_video_probe(struct udevice *dev) if (ret) return ret; + lcdifv3_of_parse_thres(dev); + if (priv->disp_dev) { #if IS_ENABLED(CONFIG_VIDEO_BRIDGE) if (device_get_uclass_id(priv->disp_dev) == UCLASS_VIDEO_BRIDGE) { -- 1.9.1