Hi,
I'm trying to add a mipi-dsi display to our custom board (Ixora based, with mipi-dsi connector available), using Apalis iMX6 Dual. The display (http://www.cct.com.my/pdf/TFT-color-spec2017/4.0%20-T400A01X00_REV2/4.0%20-T400A01X00_REV2.pdf) uses a Sitronix ST7701 controller ( http://www.startek-lcd.com/res/starteklcd/pdres/201705/20170512144242904.pdf ).
No modifications are made in u-boot. The modification in the imx6qdl-apalis-ixora-v1.1_custom.dtsi file, to allow mipi-dsi are:
&mxcfb1 {
disp_dev = "mipi_dsi";
interface_pix_fmt = "RGB24";
mode_str ="ST7701-WVGA";
default_bpp = <24>;
status = "okay";
};
&mipi_dsi {
dev_id = <0>;
disp_id = <1>;
lcd_panel = "ST7701-WVGA";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mipi_dsi_reset>;
reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
reset-delay-us = <120000>;
#reset-cells = <0>;
status = "okay";
};
the driver code
#define REFRESH 60
#define XRES 480
#define YRES 854
#define LEFT_MARGIN 12 /* HBP horizontal back porch */
#define RIGHT_MARGIN 38 /* HFP horizontal front porch */
#define HSYNC_LEN 12 /* HSW horizontal pulse width */
#define UPPER_MARGIN 4 /* VBP vertical back porch */
#define LOWER_MARGIN 18 /* VFP vertical front porch */
#define VSYNC_LEN 8 /* VSW vertical low pulse width */
#define PIXCLOCK KHZ2PICOS( (XRES + LEFT_MARGIN + RIGHT_MARGIN + HSYNC_LEN)* (YRES + UPPER_MARGIN + LOWER_MARGIN + VSYNC_LEN) * REFRESH / 1000 )
static int st7701_bl_brightness;
static struct fb_videomode st7701_lcd_modedb[] = {
{
"ST7701-WVGA", /* name */
REFRESH, /* refresh / frame rate */
XRES, YRES, /* resolution */
PIXCLOCK, /* pixel clock */
LEFT_MARGIN, RIGHT_MARGIN, /* l/r margin */
UPPER_MARGIN, LOWER_MARGIN, /* u/l margin */
HSYNC_LEN, VSYNC_LEN, /* hsync/vsync length */
FB_SYNC_OE_LOW_ACT, /* sync */
FB_VMODE_NONINTERLACED, /* vmode FB_VMODE_NONINTERLACED FB_VMODE_INTERLACED FB_VMODE_DOUBLE */
0, /* flag FB_MODE_IS_DETAILED*/
},
};
static inline int st7701_dsi_write(struct mipi_dsi_info *mipi_dsi, const void *seq, size_t len)
{
int err;
err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi,MIPI_DSI_GENERIC_LONG_WRITE, (u32*)seq, len);
CHECK_RETCODE(err);
}
#define ST7701_DSI(mipi_dsi, seq...) \
{ \
const u8 d[] = { seq }; \
st7701_dsi_write(mipi_dsi, d, ARRAY_SIZE(d)); \
}
static struct mipi_lcd_config lcd_config = {
.virtual_ch = 0,
.data_lane_num = 2,
.max_phy_clk = 800,
.dpi_fmt = MIPI_RGB888,
};
void mipid_st7701_get_lcd_videomode(struct fb_videomode **mode, int *size,
struct mipi_lcd_config **data)
{
*mode = &st7701_lcd_modedb[0];
*size = ARRAY_SIZE(st7701_lcd_modedb);
*data = &lcd_config;
}
int mipid_st7701_lcd_setup(struct mipi_dsi_info *mipi_dsi)
{
u8 buf[DSI_CMD_BUF_MAXSIZE];
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI st7701 LCD PIXCLOCK %d \n",KHZ2PICOS(PIXCLOCK));
ST7701_DSI(mipi_dsi, MIPI_DCS_SOFT_RESET, 0x00);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI SOFT RESET ...OK.\n");
/* We need to wait 5ms before sending new commands */
msleep(5);
ST7701_DSI(mipi_dsi, MIPI_DCS_EXIT_SLEEP_MODE, 0x00);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Sleep Out ...OK.\n");
msleep( 80 ); // sleep delay
// Command2, BK0
// Display Control setting
ST7701_DSI(mipi_dsi, DSI_CMD2BKX_SEL, 0x77, 0x01, 0x00, 0x00, DSI_CMD2BK0_SEL );
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Command2_BK0 Function Selection ...OK.\n");
ST7701_DSI(mipi_dsi, DSI_CMD2_BK0_NVGAMCTRL, 0x00, 0x0E, 0x95, 0x0F, 0x13, 0x07, 0x09, 0x08, 0x08, 0x22, 0x04, 0x10, 0x0E, 0x2C, 0x34, 0x1F);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Negative Voltage Gamma Control ...OK.\n");
ST7701_DSI(mipi_dsi, DSI_CMD2_BK0_LNESET, DSI_CMD2_BK0_LNESET_B0, DSI_CMD2_BK0_LNESET_B1);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Display Line setting ...OK. [%d] [0x%02X]\n", st7701_lcd_modedb[0].xres, ((st7701_lcd_modedb[0].xres - 8)/8) );
ST7701_DSI(mipi_dsi, DSI_CMD2_BK0_PORCTRL,DSI_CMD2_BK0_PORCTRL_B0(st7701_lcd_modedb),DSI_CMD2_BK0_PORCTRL_B1(st7701_lcd_modedb));
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Porch control ...OK. [0x%02X] [0x%02X]\n",DSI_CMD2_BK0_PORCTRL_B1(st7701_lcd_modedb), DSI_CMD2_BK0_PORCTRL_B0(st7701_lcd_modedb));
ST7701_DSI(mipi_dsi, DSI_CMD2_BK0_INVSEL, DSI_CMD2_BK0_INVSEL_B0, DSI_CMD2_BK0_INVSEL_B1);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Inversion selection & Frame Rate Control ...OK.\n");
/* Command2, BK1 */
ST7701_DSI(mipi_dsi, DSI_CMD2BKX_SEL, 0x77, 0x01, 0x00, 0x00, DSI_CMD2BK1_SEL);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Command2_BK1 Function Selection ...OK.\n");
ST7701_DSI(mipi_dsi, DSI_CMD2_BK1_VRHS, DSI_CMD2_BK1_VRHA_SET);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Vop amplitude setting ...OK.\n");
ST7701_DSI(mipi_dsi, DSI_CMD2_BK1_VCOM, DSI_CMD2_BK1_VCOM_SET);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI VCOM amplitude setting ...OK.\n");
ST7701_DSI(mipi_dsi, DSI_CMD2_BK1_VGHSS, DSI_CMD2_BK1_VGHSS_SET);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI VGH Voltage setting ...OK.\n");
ST7701_DSI(mipi_dsi, DSI_CMD2_BK1_TESTCMD, DSI_CMD2_BK1_TESTCMD_VAL);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI TEST Command Setting ...OK.\n");
ST7701_DSI(mipi_dsi, DSI_CMD2_BK1_VGLS, DSI_CMD2_BK1_VGLS_SET);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI VGL Voltage setting ...OK.\n");
ST7701_DSI(mipi_dsi, DSI_CMD2_BK1_PWCTLR1, DSI_CMD2_BK1_PWCTLR1_SET);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Power Control 1 ...OK.\n");
ST7701_DSI(mipi_dsi, DSI_CMD2_BK1_PWCTLR2, DSI_CMD2_BK1_PWCTLR2_SET);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Power Control 2 ...OK.\n");
ST7701_DSI(mipi_dsi, DSI_CMD2_BK1_SPD1, DSI_CMD2_BK1_SPD1_SET);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Source pre_drive timing set1 ...OK.\n");
ST7701_DSI(mipi_dsi, DSI_CMD2_BK1_SPD2, DSI_CMD2_BK1_SPD2_SET);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Source pre_drive timing set2 ...OK.\n");
ST7701_DSI(mipi_dsi, DSI_CMD2_BK1_MIPISET1, DSI_CMD2_BK1_MIPISET1_SET);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI MIPI Setting 1 ...OK.\n");
msleep(100);
/**
* ST7701_SPEC_V1.2 is unable to provide enough information above this
* specific command sequence, so grab the same from vendor BSP driver.
*/
// GIP Settings
ST7701_DSI(mipi_dsi, 0xE0, 0x00, 0x00, 0x02);
ST7701_DSI(mipi_dsi, 0xE1, 0x0B, 0x00, 0x0D, 0x00, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x44, 0x44);
ST7701_DSI(mipi_dsi, 0xE2, 0x33, 0x33, 0x44, 0x44, 0x64, 0x00, 0x66, 0x00, 0x65, 0x00, 0x67, 0x00, 0x00);
ST7701_DSI(mipi_dsi, 0xE3, 0x00, 0x00, 0x33, 0x33);
ST7701_DSI(mipi_dsi, 0xE4, 0x44, 0x44);
ST7701_DSI(mipi_dsi, 0xE5, 0x0C, 0x78, 0x3C, 0xA0, 0x0E, 0x78, 0x3C, 0xA0, 0x10, 0x78, 0x3C, 0xA0, 0x12, 0x78, 0x3C, 0xA0);
ST7701_DSI(mipi_dsi, 0xE6, 0x00, 0x00, 0x33, 0x33);
ST7701_DSI(mipi_dsi, 0xE7, 0x44, 0x44);
ST7701_DSI(mipi_dsi, 0xE8, 0x0D, 0x78, 0x3C, 0xA0, 0x0F, 0x78, 0x3C, 0xA0, 0x11, 0x78, 0x3C, 0xA0, 0x13, 0x78, 0x3C, 0xA0);
ST7701_DSI(mipi_dsi, 0xEB, 0x02, 0x02, 0x39, 0x39, 0xEE, 0x44, 0x00);
ST7701_DSI(mipi_dsi, 0xEC, 0x00, 0x00);
ST7701_DSI(mipi_dsi, 0xED, 0xFF, 0xF1, 0x04, 0x56, 0x72, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x27, 0x65, 0x40, 0x1F, 0xFF);
// End GIP Setting
// End Power Control Registers Initial
// End Bank1 Setting
/* disable Command2 */
ST7701_DSI(mipi_dsi, DSI_CMD2BKX_SEL, 0x77, 0x01, 0x00, 0x00, DSI_CMD2BKX_SEL_NONE);
msleep(10);
ST7701_DSI(mipi_dsi, MIPI_DCS_SET_DISPLAY_ON, 0x00);
dev_info(&mipi_dsi->pdev->dev, "MIPI DSI Display On ...OK.\n");
/* We need to wait 200ms after a sleep out command */
msleep(200);
return 0;
}
When Linux starts the driver is registered, but I cannot get a valid image,
root@apalis-imx6:~# fbset -i
mode "480x854-60"
#28.747 MHz, H: 53.039 kHz, V: 59.999 Hz
geometry 480 854 480 864 32
timings 34786 12 38 4 18 12 8
rgba 8/16,8/8,8/0,8/24
endmode
Frame buffer device information:
Name : DISP3 BG - DI1
Address : 0x20800000
Size : 16715520
Type : PACKED PIXELS
Visual : TRUECOLOR
XPanStep : 1
YPanStep : 1
YWrapStep : 1
LineLength : 1920
Accelerator : No
At linux boot the display image is
the LXDE desktop
and the command
gst-launch-1.0 -v videotestsrc ! imxg2dvideosink force-aspect-ratio=false
Anybody knows how to solve this?
Regards,
Rui
Hi Bastos
for new lcd its timings parameters should be entered in struct fb_videomode,
one can check example in linux/drivers/video/fbdev/mxc/ mxcfb_hx8369_wvga.c
Chapter 7 MIPI DSI Driver attached Linux Manual.
Also may be useful to check below patch
Patch to support MIPI display(hx8369) in uboot for i.mx6DL/DQ SebreSD boards
and try with nxp linux from codeaurora.org repository:
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------