Files
BPI-M2C/HDMI/LT8912B-HDMI-extra.patch
T
2026-09-22 09:38:26 +08:00

302 lines
9.6 KiB
Diff

diff --git a/layers/meta-unisoc/recipes-kernel/linux/linux-unisoc-5.4/uis7885/lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi b/layers/meta-unisoc/recipes-kernel/linux/linux-unisoc-5.4/uis7885/lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi
--- a/layers/meta-unisoc/recipes-kernel/linux/linux-unisoc-5.4/uis7885/lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi
+++ b/layers/meta-unisoc/recipes-kernel/linux/linux-unisoc-5.4/uis7885/lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi
@@ -42,9 +42,9 @@
hfront-porch = <88>;
hsync-len = <44>;
hback-porch = <148>;
- vfront-porch = <56>;
- vsync-len = <6>;
- vback-porch = <60>;
+ vfront-porch = <4>;
+ vsync-len = <5>;
+ vback-porch = <36>;
};
};
};
diff --git a/source/kernel/kernel5.4/arch/arm64/boot/dts/sprd/lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi b/source/kernel/kernel5.4/arch/arm64/boot/dts/sprd/lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi
--- a/source/kernel/kernel5.4/arch/arm64/boot/dts/sprd/lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi
+++ b/source/kernel/kernel5.4/arch/arm64/boot/dts/sprd/lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi
@@ -42,9 +42,9 @@
hfront-porch = <88>;
hsync-len = <44>;
hback-porch = <148>;
- vfront-porch = <56>;
- vsync-len = <6>;
- vback-porch = <60>;
+ vfront-porch = <4>;
+ vsync-len = <5>;
+ vback-porch = <36>;
};
};
};
diff --git a/source/bsp/u-boot22/arch/arm/dts/lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi b/source/bsp/u-boot22/arch/arm/dts/lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi
--- a/source/bsp/u-boot22/arch/arm/dts/lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi
+++ b/source/bsp/u-boot22/arch/arm/dts/lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi
@@ -47,9 +47,9 @@
hfront-porch = <88>;
hsync-len = <44>;
hback-porch = <148>;
- vfront-porch = <56>;
+ vfront-porch = <38>;
vsync-len = <6>;
- vback-porch = <60>;
+ vback-porch = <40>;
};
};
};
diff --git a/source/kernel/kernel5.4/drivers/video/LT8912B/src/LT8912B.c b/source/kernel/kernel5.4/drivers/video/LT8912B/src/LT8912B.c
--- a/source/kernel/kernel5.4/drivers/video/LT8912B/src/LT8912B.c
+++ b/source/kernel/kernel5.4/drivers/video/LT8912B/src/LT8912B.c
@@ -9,6 +9,7 @@
u8 Hsync_L, Hsync_H, Vsync_L, Vsync_H;
u8 mipi_det_fail_count = 0;
u8 mipi_relock_count = 0;
+bool mipi_video_ready = 0;
bool suspend_on = 0;
@@ -24,11 +25,13 @@
struct video_timing video_1280x720_60Hz = {110, 40, 220, 1280, 1650, 5, 5, 20, 720, 750, 1,1, 4, AR_16_9, 74250};
struct video_timing video_1280x800_60Hz = {28, 32, 100, 1280, 1440, 2, 6, 15, 800, 823, 0,0, 0, AR_16_9, 71000};
//struct video_timing video_1920x1080_60Hz = {88, 44, 148, 1920, 2200, 4, 5, 36, 1080, 1125, 1,1,16, AR_16_9, 148500};
-struct video_timing video_1920x1080_60Hz = {88, 44, 148, 1920, 2200, 56, 6, 60, 1080, 1202, 1,1, 0, AR_16_9, 153600};
+struct video_timing video_1920x1080_60Hz = {88, 44, 148, 1920, 2200, 4, 5, 36, 1080, 1125, 1,1,16, AR_16_9, 153600};
struct video_timing *video;
-void DDSConfig(void);
+void DDSConfig(struct video_timing *video_format);
+void HdmiOutput(bool on);
+u8 LT8912_Get_HPD(void);
void DigitalClockEn(void)
{
@@ -72,25 +75,66 @@
{
u8 VIC = video_format->vic;
u8 AR = video_format->aspact_ratio;
- u8 pb0,pb2,pb4,Sync_Polarity;
+ u8 pb0,pb1,pb2,pb4,Sync_Polarity;
+ u8 pb6, pb7, pb8, pb9, pb10, pb11, pb12, pb13;
+ u8 checksum;
I2CADR = 0x94;
HDMI_WriteI2C_Byte(0x3c,0x41); //enable null package
Sync_Polarity = (video_format->h_polarity*0x02) + (video_format->v_polarity*0x01);
- pb2 = (AR<<4) + 0x08;
- pb4 = VIC;
- pb0 = (((pb2 + pb4) <= 0x5f)?(0x5f - pb2 - pb4):(0x15f - pb2 - pb4));
+ if (video_format->hact == 1920 && video_format->vact == 1080) {
+ Sync_Polarity = 0x03;
+ pb1 = 0x1c;
+ pb2 = 0xa8;
+ pb4 = 0x10;
+ pb6 = 0x29;
+ pb7 = 0x00;
+ pb8 = 0x61;
+ pb9 = 0x04;
+ pb10 = 0xc0;
+ pb11 = 0x00;
+ pb12 = 0x40;
+ pb13 = 0x08;
+ } else {
+ pb1 = 0x10;
+ pb2 = (AR<<4) + 0x08;
+ pb4 = VIC;
+ pb6 = 0x00;
+ pb7 = 0x00;
+ pb8 = 0x00;
+ pb9 = 0x00;
+ pb10 = 0x00;
+ pb11 = 0x00;
+ pb12 = 0x00;
+ pb13 = 0x00;
+ }
+
+ checksum = 0x82 + 0x02 + 0x0d + pb1 + pb2 + pb4;
+ checksum += pb6 + pb7 + pb8 + pb9;
+ checksum += pb10 + pb11 + pb12 + pb13;
+ pb0 = 0x100 - checksum;
I2CADR = 0x90;
HDMI_WriteI2C_Byte(0xab,Sync_Polarity); //sync polarity
I2CADR = 0x94;
HDMI_WriteI2C_Byte(0x43,pb0); //PB0:check sum
- HDMI_WriteI2C_Byte(0x44,0x10); //PB1:RGB888
+ HDMI_WriteI2C_Byte(0x44,pb1); //PB1
HDMI_WriteI2C_Byte(0x45,pb2); //PB2
HDMI_WriteI2C_Byte(0x46,0x00); //PB3
HDMI_WriteI2C_Byte(0x47,pb4); //PB4:vic
+ HDMI_WriteI2C_Byte(0x49,pb6);
+ HDMI_WriteI2C_Byte(0x4a,pb7);
+ HDMI_WriteI2C_Byte(0x4b,pb8);
+ HDMI_WriteI2C_Byte(0x4c,pb9);
+ HDMI_WriteI2C_Byte(0x4d,pb10);
+ HDMI_WriteI2C_Byte(0x4e,pb11);
+ HDMI_WriteI2C_Byte(0x4f,pb12);
+ HDMI_WriteI2C_Byte(0x50,pb13);
+ printk("%s AviInfoframe %ux%u pb0=0x%02x pb1=0x%02x pb2=0x%02x vic=%u sync=0x%02x\n",
+ LOG_FLAG, video_format->hact, video_format->vact,
+ pb0, pb1, pb2, pb4, Sync_Polarity);
}
void MipiAnalog(void)
@@ -128,7 +172,13 @@
void MIPI_Video_Setup(struct video_timing *video_format)
{
+ u8 settle = 0x10;
+
+ if (video_format->vact == 1080)
+ settle = 0x0a;
+
I2CADR = 0x92;
+ HDMI_WriteI2C_Byte(0x11, settle); // settle
HDMI_WriteI2C_Byte(0x18,(u8)(video_format->hs%256)); // hwidth
HDMI_WriteI2C_Byte(0x19,(u8)(video_format->vs%256)); // vwidth
HDMI_WriteI2C_Byte(0x1c,(u8)(video_format->hact%256)); // H_active[7:0]
@@ -146,6 +196,10 @@
HDMI_WriteI2C_Byte(0x3d,(u8)(video_format->hbp/256)); // HBP[15:8]
HDMI_WriteI2C_Byte(0x3e,(u8)(video_format->hfp%256)); // HFP[7:0]
HDMI_WriteI2C_Byte(0x3f,(u8)(video_format->hfp/256)); // HFP[15:8]
+ printk("%s MIPI_Video_Setup %ux%u total=%ux%u pclk=%u settle=0x%02x vic=%u\n",
+ LOG_FLAG, video_format->hact, video_format->vact,
+ video_format->htotal, video_format->vtotal,
+ video_format->pclk_khz, settle, video_format->vic);
video = video_format;
}
@@ -168,19 +222,26 @@
MipiAnalog();
MipiBasicSet();
- DDSConfig();
+ DDSConfig(&video_1920x1080_60Hz);
MIPI_Video_Setup(&video_1920x1080_60Hz);
AviInfoframe(&video_1920x1080_60Hz);
MIPIRxLogicRes();
}
-void DDSConfig(void)
+void DDSConfig(struct video_timing *video_format)
{
+ u32 dds_word;
+
+ dds_word = (video_format->pclk_khz / 1000) * 0x16C16;
+ dds_word += ((video_format->pclk_khz % 1000) * 0x16C16 + 500) / 1000;
+
I2CADR = 0x92;
- HDMI_WriteI2C_Byte(0x4e,0x93);//strm_sw_freq_word[ 7: 0]
- HDMI_WriteI2C_Byte(0x4f,0x3E);//strm_sw_freq_word[15: 8]
- HDMI_WriteI2C_Byte(0x50,0x29);//strm_sw_freq_word[23:16]
+ HDMI_WriteI2C_Byte(0x4e,(u8)(dds_word & 0xff));//strm_sw_freq_word[ 7: 0]
+ HDMI_WriteI2C_Byte(0x4f,(u8)((dds_word >> 8) & 0xff));//strm_sw_freq_word[15: 8]
+ HDMI_WriteI2C_Byte(0x50,(u8)((dds_word >> 16) & 0xff));//strm_sw_freq_word[23:16]
HDMI_WriteI2C_Byte(0x51,0x80);//[0]=strm_sw_freq_word[24]
+ printk("%s DDSConfig pclk=%u kHz word=0x%06x\n",
+ LOG_FLAG, video_format->pclk_khz, dds_word);
HDMI_WriteI2C_Byte(0x1e,0x4f);
HDMI_WriteI2C_Byte(0x1f,0x5e);//full_value 464
HDMI_WriteI2C_Byte(0x20,0x01);
@@ -231,8 +292,15 @@
I2CADR = 0x94;
HDMI_WriteI2C_Byte(0x06,0x08);
HDMI_WriteI2C_Byte(0x07,0xF0);
- HDMI_WriteI2C_Byte(0x34,0xD2);//0xE2:32FS; 0xD2:64FS
+ HDMI_WriteI2C_Byte(0x09,0x00);
+ HDMI_WriteI2C_Byte(0x34,0xE2);//0xE2:32FS; 0xD2:64FS
+ HDMI_WriteI2C_Byte(0x35,0x00);//N = 6144(0x1800)
+ HDMI_WriteI2C_Byte(0x36,0x18);
+ HDMI_WriteI2C_Byte(0x37,0x00);
+ HDMI_WriteI2C_Byte(0x3c,0x41);
+ HDMI_WriteI2C_Byte(0x3e,0x0a);
HDMI_WriteI2C_Byte(0x0F,0x2B);
+ printk("%s HDMI audio packet setup: 48k N=0x1800\n", LOG_FLAG);
}
void AudioSpdifEn(void)
@@ -500,11 +568,8 @@
if (mipi_det_fail_count < 0xff)
mipi_det_fail_count++;
- if (mipi_det_fail_count >= 10 && mipi_relock_count < 5) {
- mipi_relock_count++;
- mipi_det_fail_count = 0;
- LT8912B_MIPI_Relock();
- }
+ if (mipi_det_fail_count == 10)
+ printk("%s MIPI input invalid, skip auto relock\n", LOG_FLAG);
} else {
mipi_det_fail_count = 0;
}
@@ -525,7 +590,7 @@
video_valid = true;
printk("%s videoformat = VESA_1280x800_60\n",LOG_FLAG);
}
- else if(Vsync_H == 0x04 && Vsync_L <= 0xb6&&Vsync_L >= 0x63)//0x4b2
+ else if(Vsync_H == 0x04 && Vsync_L <= 0x67&&Vsync_L >= 0x63)//0x465
{
video = &video_1920x1080_60Hz;
video_valid = true;
@@ -544,9 +609,21 @@
if (video_valid) {
mipi_det_fail_count = 0;
mipi_relock_count = 0;
+ mipi_video_ready = 1;
+ DDSConfig(video);
MIPI_Video_Setup(video);
AviInfoframe(video);
MIPIRxLogicRes();
+
+ #ifdef _hdmi_output
+ if (LT8912_Get_HPD() && !Tx_HPD) {
+ msleep(50);
+ HdmiOutput(1);
+ Tx_HPD = 1;
+ printk("%s HDMI output enabled after valid MIPI video\n",
+ LOG_FLAG);
+ }
+ #endif
}
}
@@ -716,7 +793,7 @@
HDMIPllAnalog();
MipiAnalog();
MipiBasicSet();
- DDSConfig();
+ DDSConfig(&video_1920x1080_60Hz);
MIPI_Video_Setup(&video_1920x1080_60Hz);
MIPI_Input_det();
AudioIIsEn();
@@ -726,7 +803,7 @@
lt8912_check_dds(); // can be removed when debug stage.
#endif
- #ifdef _lvds_bypass
+ #ifdef _lvds_output
lvds_output_cfg();
LvdsOutput(1);
#endif
@@ -737,7 +814,7 @@
/////////////////////////////////////////////////////////////
#ifdef _hdmi_output
- if(LT8912_Get_HPD())
+ if(LT8912_Get_HPD() && mipi_video_ready)
{
if(!Tx_HPD)
{
@@ -769,7 +846,7 @@
#ifdef _hdmi_output
if(LT8912_Get_HPD())
{
- if(!Tx_HPD)
+ if(mipi_video_ready && !Tx_HPD)
{
LT8912B_Suspend(0);
HdmiOutput(1);