jitao shi has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/39026 )
Change subject: drivers/analogix: fixup the video banking area timing to meet chip ......................................................................
drivers/analogix: fixup the video banking area timing to meet chip
Fixup HFP/HBP/HSYNC meet the chip (must larger than 8 and even number)
BUG=b:149051882 BRANCH=kukui TEST=None
Change-Id: I3715fa854649f20fbef4e0bdfce59ebfa1f5f2b5 Signed-off-by: Jitao Shi jitao.shi@mediatek.com --- M src/drivers/analogix/anx7625/anx7625.c 1 file changed, 118 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/26/39026/1
diff --git a/src/drivers/analogix/anx7625/anx7625.c b/src/drivers/analogix/anx7625/anx7625.c index d2d09d8..10aa8b5 100644 --- a/src/drivers/analogix/anx7625/anx7625.c +++ b/src/drivers/analogix/anx7625/anx7625.c @@ -827,6 +827,119 @@ dt->vactive, dt->vsync_len, dt->vfront_porch, dt->vback_porch); }
+static void anx7625_modify_edid(struct edid *edid, + struct display_timing *dt) +{ + u32 hsync, hfp, hbp, hactive, hblanking, htotal, vtotal; + u32 adj_hsync, adj_hfp, adj_hbp, adj_hblanking, delta_adj; + u32 vref, adj_clock; + + hactive = dt->hactive; + hfp = dt->hfront_porch; + hbp = dt->hback_porch; + hsync = dt->hsync_len; + hblanking = hfp + hbp + hsync; + htotal = hactive + hfp + hbp + hsync; + vtotal = dt->vactive + dt->vsync_len + + dt->vfront_porch + dt->vback_porch; + + ANXINFO("before mode fixup\n"); + ANXINFO("hsync(%d),hfp(%d),hbp(%d),clock(%d)\n", + hsync, + hfp, + hbp, + dt->pixelclock); + + adj_hfp = hfp; + adj_hsync = hsync; + adj_hbp = hbp; + adj_hblanking = hblanking; + + /* plus 1 if hfp is odd */ + if (hfp & 0x1) { + adj_hfp = hfp + 1; + adj_hblanking += 1; + } + + /* minus 1 if hbp is odd */ + if (hbp & 0x1) { + adj_hbp = hbp - 1; + adj_hblanking -= 1; + } + + /* plus 1 if hsync is odd */ + if (hsync & 0x1) { + if (adj_hblanking < hblanking) + adj_hsync = hsync + 1; + else + adj_hsync = hsync - 1; + } + + /* + * once illegal timing detected, use default HFP, HSYNC, HBP + */ + if ((hblanking < HBLANKING_MIN) || (hfp < HP_MIN && hbp < HP_MIN)) + { + adj_hsync = SYNC_LEN_DEF; + adj_hfp = HFP_HBP_DEF; + adj_hbp = HFP_HBP_DEF; + vref = dt->pixelclock * 1000 / (htotal * vtotal); + if (hblanking < HBLANKING_MIN) { + delta_adj = HBLANKING_MIN - hblanking; + adj_clock = vref * delta_adj * vtotal; + dt->pixelclock += DIV_ROUND_UP(adj_clock, 1000); + } else { + delta_adj = hblanking - HBLANKING_MIN; + adj_clock = vref * delta_adj * vtotal; + dt->pixelclock -= DIV_ROUND_UP(adj_clock, 1000); + } + + ANXINFO("warn: illegal hblanking timing, use default.\n"); + ANXINFO("warn: hfp(%d),hbp(%d),hsync(%d).\n", hfp, hbp, hsync); + } else if (adj_hfp < HP_MIN) { + /* adjust hfp if hfp less than HP_MIN */ + delta_adj = HP_MIN - adj_hfp; + adj_hfp = HP_MIN; + + /* + * balance total HBlanking pixel, if HBP hasn't enough space, + * adjust HSYNC length, otherwize adjust HBP + */ + if ((adj_hbp - delta_adj) < HP_MIN) + /* hbp not enough space */ + adj_hsync -= delta_adj; + else + adj_hbp -= delta_adj; + } else if (adj_hbp < HP_MIN) { + delta_adj = HP_MIN - adj_hbp; + adj_hbp = HP_MIN; + + /* + * balance total HBlanking pixel, if HBP hasn't enough space, + * adjust HSYNC length, otherwize adjust HBP + */ + if ((adj_hfp - delta_adj) < HP_MIN) + /* hbp not enough space */ + adj_hsync -= delta_adj; + else + adj_hfp -= delta_adj; + } + + ANXINFO("after mode fixup\n"); + ANXINFO("hsync(%d),hfp(%d),hbp(%d),clock(%d)\n", + adj_hsync, + adj_hfp, + adj_hbp, + dt->pixelclock); + + /* reconstructure EDID */ + edid->mode.hspw = adj_hsync; + edid->mode.hso = adj_hfp + edid->mode.hborder; + edid->mode.hbl = adj_hbp + edid->mode.hso + + edid->mode.hspw + edid->mode.hborder; + edid->mode.pixel_clock = dt->pixelclock; +} + int anx7625_dp_start(uint8_t bus, const struct edid *edid) { int ret; @@ -847,6 +960,7 @@ { int block_num; int ret; + struct display_timing dtiming; u8 edid[FOUR_BLOCK_SIZE];
block_num = sp_tx_edid_read(bus, edid, FOUR_BLOCK_SIZE); @@ -861,6 +975,10 @@ return -1; }
+ anx7625_parse_edid(out, &dtiming); + + anx7625_modify_edid(out, &dtiming); + return 0; }