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 <magf@bitland.corp-partner.google.com>
Change-Id: I608c01d41ae93c8d5094647bbf3e0ae4a23d814c
Reviewed-on: https://review.coreboot.org/c/coreboot/+/41163
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Paul Ma 2020-05-08 14:28:25 +08:00 committed by Patrick Georgi
parent e8d1bef8cb
commit d0ded16529
1 changed files with 20 additions and 2 deletions

View File

@ -10,6 +10,9 @@
#include <string.h> #include <string.h>
#include <timer.h> #include <timer.h>
#define MIN_HFP_BYTE 2
#define MIN_HBP_BYTE 2
static unsigned int mtk_dsi_get_bits_per_pixel(u32 format) static unsigned int mtk_dsi_get_bits_per_pixel(u32 format)
{ {
switch (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 hsync_active_byte;
u32 hbp; u32 hbp;
u32 hfp; u32 hfp;
u32 hbp_byte; s32 hbp_byte;
u32 hfp_byte; s32 hfp_byte;
u32 vbp_byte; u32 vbp_byte;
u32 vfp_byte; u32 vfp_byte;
u32 bytes_per_pixel; 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"); "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_hsa_wc, hsync_active_byte);
write32(&dsi0->dsi_hbp_wc, hbp_byte); write32(&dsi0->dsi_hbp_wc, hbp_byte);
write32(&dsi0->dsi_hfp_wc, hfp_byte); write32(&dsi0->dsi_hfp_wc, hfp_byte);