Only half display on a dual-link LVDS LCD 1920x1080 using SN65DSI84 bridge iMX8MM mipi-dsi

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

Only half display on a dual-link LVDS LCD 1920x1080 using SN65DSI84 bridge iMX8MM mipi-dsi

跳至解决方案
3,472 次查看
x10
Contributor V

Hi,all

Plateform: yocto linux-4.14.98_2.0.0ga + iMX8MM.

Using SN65DSI83 to bridge iMX8MM mipi dsi on my customized board for single-link LVDS LCD,which works fine with variouse resolutions. Then replace SN65DSI83 with SN65DSI84 to bring up dual-link LVDS LCD with resulotion of 1920x1080 with following dts code:

dsi_lvds_bridge: sn65dsi83@2c {
compatible = "ti,sn65dsi83";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mipi_dsi_en>;
reg = <0x2c>;
ti,dsi-lanes = <4>;
ti,lvds-format = <1>;
ti,lvds-bpp = <24>;
ti,width-mm = <154>;
ti,height-mm = <87>;
enable-gpio = <&gpio4 0 GPIO_ACTIVE_HIGH>;
lcd-bl = <&gpio1 15 GPIO_ACTIVE_HIGH>;
status = "okay";

port {
sn65dsi83_from_dsim: endpoint {
remote-endpoint = <&dsim_to_sn65dsi83>;
};
};

display-timings {
native-mode = <&timing0>;
timing0: 1920x1080 {
clock-frequency = <149800000>; // LCD clock * 2
hactive = <1920>;
vactive = <1080>; //

hfront-porch = <60>; // DE mode, Blanking 90*2
hback-porch = <60>;
hsync-len = <60>;
vback-porch = <20>;
vfront-porch = <20>;
vsync-len = <10>;

hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};

with config code as follows:

static int sn65dsi83_brg_configure(struct sn65dsi83_brg *brg)
{
int regval = 0;
struct i2c_client *client = I2C_CLIENT(brg);
struct videomode *vm = VM(brg);
u32 dlink = (VACTIVE > 1000) ? 2 : 1; // VACTIVE > 1000 => dual-link LVDS
u32 lvds_clk = PIXCLK / dlink;
u32 dsi_clk = (((PIXCLK * BPP(brg)) / DSI_LANES(brg)) >> 1);

dev_info(&client->dev, "DSI clock [ %u ] Hz\n",dsi_clk);
dev_info(&client->dev, "GeoMetry [ %d x %d ] \n",HACTIVE,VACTIVE);

/* Reset PLL_EN and SOFT_RESET registers */
SN65DSI83_WRITE(SN65DSI83_SOFT_RESET,0x00);
SN65DSI83_WRITE(SN65DSI83_PLL_EN,0x00);

/* LVDS clock setup */
if ((25000000 <= lvds_clk) && (lvds_clk < 37500000))
regval = 0;
else
regval = sn65dsi83_calk_clk_range(0x01, 0x05, 37500000, 25000000, lvds_clk);

if (regval < 0) {
dev_err(&client->dev, "failed to configure LVDS clock");
return -EINVAL;
}

regval = (regval << LVDS_CLK_RANGE_SHIFT);
regval |= (1 << HS_CLK_SRC_SHIFT); /* Use DSI clock */
SN65DSI83_WRITE(SN65DSI83_CORE_PLL,regval);

/* DSI clock range, max value = 500MHz */
regval = sn65dsi83_calk_clk_range(0x08, 0x64, 40000000, 5000000, dsi_clk);
if (regval < 0) {
dev_err(&client->dev, "failed to configure DSI clock range\n");
return -EINVAL;
}
SN65DSI83_WRITE(SN65DSI83_CHA_DSI_CLK_RNG,regval);

/* DSI clock divider */
regval = sn65dsi83_calk_div(0x0, 0x18, 1, 1, dsi_clk, lvds_clk);
if (regval < 0) {
dev_err(&client->dev, "failed to calculate DSI clock divider");
return -EINVAL;
}

regval = regval << DSI_CLK_DIV_SHIFT;
SN65DSI83_WRITE(SN65DSI83_PLL_DIV,regval);

/* Configure DSI_LANES */
regval = SN65DSI83_READ(SN65DSI83_DSI_CFG);
regval &= ~(3 << CHA_DSI_LANES_SHIFT);
regval |= ((4 - DSI_LANES(brg)) << CHA_DSI_LANES_SHIFT);
SN65DSI83_WRITE(SN65DSI83_DSI_CFG,regval);

/* CHA_DSI_DATA_EQ - No Equalization */
/* CHA_DSI_CLK_EQ - No Equalization */
SN65DSI83_WRITE(SN65DSI83_DSI_EQ,0x00);

/* Video formats */
regval = 0;
if (FLAGS & DISPLAY_FLAGS_HSYNC_LOW)
regval |= (1 << HS_NEG_POLARITY_SHIFT);

if (FLAGS & DISPLAY_FLAGS_VSYNC_LOW)
regval |= (1 << VS_NEG_POLARITY_SHIFT);

if (FLAGS & DISPLAY_FLAGS_DE_LOW)
regval |= (1 << DE_NEG_POLARITY_SHIFT);

if (BPP(brg) == 24) {
regval |= (1 << CHA_24BPP_MODE_SHIFT);
if(dlink == 2)
regval |= (1 << CHA_24BPP_MODE_SHIFT);
}

if (FORMAT(brg) == 1) {
regval |= (1 << CHA_24BPP_FMT1_SHIFT);
if(dlink == 2) {
regval |= (1 << CHB_24BPP_FMT1_SHIFT);
}
}

if(dlink == 1) {
regval |= (1 << LVDS_LINK_CFG_SHIFT);

}
dev_info(&client->dev, "video formats: 0x%x\n",regval);
SN65DSI83_WRITE(SN65DSI83_LVDS_MODE,regval);

/* Voltage and pins */
SN65DSI83_WRITE(SN65DSI83_LVDS_SIGN,0x00);
SN65DSI83_WRITE(SN65DSI83_LVDS_TERM,0x03);
SN65DSI83_WRITE(SN65DSI83_LVDS_CM_ADJ,0x00);

/* Configure sync delay to minimal allowed value */
SN65DSI83_WRITE(SN65DSI83_CHA_SYNC_DELAY_LO,0x21);
SN65DSI83_WRITE(SN65DSI83_CHA_SYNC_DELAY_HI,0x00);

/* Geometry */
SN65DSI83_WRITE(SN65DSI83_CHA_LINE_LEN_LO,LOW(HACTIVE/dlink));
SN65DSI83_WRITE(SN65DSI83_CHA_LINE_LEN_HI,HIGH(HACTIVE/dlink));

SN65DSI83_WRITE(SN65DSI83_CHA_VERT_LINES_LO,LOW(VACTIVE));
SN65DSI83_WRITE(SN65DSI83_CHA_VERT_LINES_HI,HIGH(VACTIVE));

SN65DSI83_WRITE(SN65DSI83_CHA_HSYNC_WIDTH_LO,LOW(HPW/dlink));
SN65DSI83_WRITE(SN65DSI83_CHA_HSYNC_WIDTH_HI,HIGH(HPW/dlink));

SN65DSI83_WRITE(SN65DSI83_CHA_VSYNC_WIDTH_LO,LOW(VPW));
SN65DSI83_WRITE(SN65DSI83_CHA_VSYNC_WIDTH_HI,HIGH(VPW));

SN65DSI83_WRITE(SN65DSI83_CHA_HORZ_BACKPORCH,LOW(HBP/dlink));
SN65DSI83_WRITE(SN65DSI83_CHA_VERT_BACKPORCH,LOW(VBP));

SN65DSI83_WRITE(SN65DSI83_CHA_HORZ_FRONTPORCH,LOW(HFP/dlink));
SN65DSI83_WRITE(SN65DSI83_CHA_VERT_FRONTPORCH,LOW(VFP));

SN65DSI83_WRITE(SN65DSI83_TEST_PATTERN,0x00);
// CS&ZHL NOV-25-2020: testing -> dual-link LVDS does wrking!
//SN65DSI83_WRITE(SN65DSI83_TEST_PATTERN,(1 << CHA_TEST_PATTERN_SHIFT));

return 0;
}

wih above setting => lvds_clk = 74.9MHz, dsi_clk = 449.4MHz

The test pattern of SN65DSI84 are fine, but with DSI input, only left half side display is on, right half side just blank. It's appreciated for any help, thanks very much.

 

ChengShi

www.emtronix.com

0 项奖励
回复
1 解答
3,468 次查看
x10
Contributor V

It fixed with proper parameters settings, and works fine.

在原帖中查看解决方案

0 项奖励
回复
4 回复数
2,560 次查看
embdev1
Contributor I

I am facing a similar issue. Can you please explain the solution in little more detail (as I am new to AOSP)? Thanks in advance.

0 项奖励
回复
3,329 次查看
myy
Contributor II

Can you share your code?I also encountered this problem,thanks

0 项奖励
回复
3,310 次查看
x10
Contributor V

The key point is keep DSI_BIT_CLK as integer in MHz, < 750MHz

0 项奖励
回复
3,469 次查看
x10
Contributor V

It fixed with proper parameters settings, and works fine.

0 项奖励
回复