From d0ded1652927016677e366e2cc8a112a60db251a Mon Sep 17 00:00:00 2001 From: Paul Ma Date: Fri, 8 May 2020 14:28:25 +0800 Subject: soc/mediatek: dsi: adjust hfp_byte and hbp_byte if too small If panel has too small hfp or hbp, hfp_byte or hbp_byte may become very small value or negative value. When very small value or negative value is used, the panel will be scrolling or distorted. This patch adjusts their values so that they are greater than the minimum value and keep total of them unchanged. DSI transfer HBP or HFP, There are some extra packet. ex. packet header(4byte) and eof(2byte) and (next)hs packet header(4 byte). the hfp_byte = HFP * BPP - packet header(4byte) and eof(2byte) and (next)hs packet header(4 byte). So the min hfp_byte is 2 when HFP = 4. This is equivalent to the Linux kernel DSI change in: https://chromium-review.googlesource.com/c/chromiumos/third_party/ kernel/+/2186872 BUG=b:144824303 BRANCH=kukui TEST=boot damu board with panel CMN N120ACA-EA1 (12" panel and its hbp only 6), the panel can display without scrolling or distortions. Signed-off-by: Paul Ma Change-Id: I608c01d41ae93c8d5094647bbf3e0ae4a23d814c Reviewed-on: https://review.coreboot.org/c/coreboot/+/41163 Reviewed-by: Hung-Te Lin Tested-by: build bot (Jenkins) --- src/soc/mediatek/common/dsi.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/soc/mediatek/common') diff --git a/src/soc/mediatek/common/dsi.c b/src/soc/mediatek/common/dsi.c index 3b9acd0ddc..73dacef33b 100644 --- a/src/soc/mediatek/common/dsi.c +++ b/src/soc/mediatek/common/dsi.c @@ -10,6 +10,9 @@ #include #include +#define MIN_HFP_BYTE 2 +#define MIN_HBP_BYTE 2 + static unsigned int mtk_dsi_get_bits_per_pixel(u32 format) { switch (format) { @@ -165,8 +168,8 @@ static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format, u32 lanes, u32 hsync_active_byte; u32 hbp; u32 hfp; - u32 hbp_byte; - u32 hfp_byte; + s32 hbp_byte; + s32 hfp_byte; u32 vbp_byte; u32 vfp_byte; u32 bytes_per_pixel; @@ -215,6 +218,21 @@ static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format, u32 lanes, "the panel may not work properly.\n"); } + if (hfp_byte + hbp_byte < MIN_HFP_BYTE + MIN_HBP_BYTE) { + printk(BIOS_ERR, "Calculated hfp_byte and hbp_byte are too small, " + "the panel may not work properly.\n"); + } else if (hfp_byte < MIN_HFP_BYTE) { + printk(BIOS_NOTICE, "Calculated hfp_byte is too small, " + "adjust it to the minimum value.\n"); + hbp_byte -= MIN_HFP_BYTE - hfp_byte; + hfp_byte = MIN_HFP_BYTE; + } else if (hbp_byte < MIN_HBP_BYTE) { + printk(BIOS_NOTICE, "Calculated hbp_byte is too small, " + "adjust it to the minimum value.\n"); + hfp_byte -= MIN_HBP_BYTE - hbp_byte; + hbp_byte = MIN_HBP_BYTE; + } + write32(&dsi0->dsi_hsa_wc, hsync_active_byte); write32(&dsi0->dsi_hbp_wc, hbp_byte); write32(&dsi0->dsi_hfp_wc, hfp_byte); -- cgit v1.2.3