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
Solved! Go to Solution.
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.
Can you share your code?I also encountered this problem,thanks
The key point is keep DSI_BIT_CLK as integer in MHz, < 750MHz
It fixed with proper parameters settings, and works fine.