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

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

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

Jump to solution
2,543 Views
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 Kudos
1 Solution
2,539 Views
x10
Contributor V

It fixed with proper parameters settings, and works fine.

View solution in original post

0 Kudos
4 Replies
1,631 Views
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 Kudos
2,400 Views
myy
Contributor II

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

0 Kudos
2,381 Views
x10
Contributor V

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

0 Kudos
2,540 Views
x10
Contributor V

It fixed with proper parameters settings, and works fine.

0 Kudos