4. MIPI DSI (starting with SDK V6.3.4)

Overview

The Display Serial Interface (DSI) is defined by the Mobile Industry Processor Interface Alliance (Mobile Industry Processor Interface Alliance (MIPI Alliance)) defines a high-speed serial interface primarily used to connect processors and display modules.

This chapter describes how to develop and debug an MIPI LCD panel on CVITEK processor solutions, helping customers develop MIPI LCD applications in an orderly and efficient way.

4.1. Environment Preparation

4.1.1. MIPI DSI Panel Interface

An MIPI DSI panel generally has the following signals, as shown in the figure.

  • MIPI clock line (CLK)

  • MIPI data line (DATA), up to 4 lanes (only 1/2/4 lanes are supported)

  • Backlight control signal (BACKLIGHT)

  • Reset pin (RESET)

  • Panel power supply (POWER)

MIPI DSI Interface Wiring Diagram

_images/MIPIDS002.png

4.1.2. Hardware Wiring Check

Check the hardware wiring and confirm that it is correct. For pin differences, refer to the panel vendor specification and schematic.

4.2. PanelSupportList Framework Overview

The SDK uses the PanelSupportList repository to centrally manage all panel-parameter headers. U-Boot, cvi_mpi, and AliOS share the same panel data, but their configuration methods differ.

The framework is structured as follows:

  • Panel-parameter headers: all are placed under PanelSupportList/panels/ and follow the naming rules.

Panel-parameter inclusion methods for the three systems:

  • u-boot / cvi_alios: through PanelSupportList/cvi_panels.h aggregatetotalintoport, use CONFIG_ macroincompilestageselectonlyoneoneblockpanel. cvi_panels.h only supportssingleselect, notcanat the same timeenablemultiple panelspanel.

  • cvi_mpi: in sample_panel.h indirectlyconnect #include thehaspanelreferenceheader file, runwhenthrough --panel= command lineparametermovestateselect, can at the same timecompileintothehaspanelreference.

Basic steps for integrating a new MIPI panel:

  1. Write a correctly named panel-parameter header under PanelSupportList/panels/.

  2. Select the registration method according to the target system (see below).

  3. Configure, enable, and build.

4.3. Configure the MIPI Panel (systemoneflow)

4.3.1. Step 1: Write the Panel-Parameter Header

4.3.1.1. Naming Rules

Place all header files under PanelSupportList/panels/. Naming format:

dsi_{driveric}_{wxh}_{moduleid}_{lanenum}lane_{fps}fps[_vN].h
  • driveric: driver IC, smallwrite, for example hx8394.

  • wxh: validresolution, for example 720x1280.

  • moduleid: panelmodelgroup ID; notdeterminewhenuse NULL.

  • lanenum: physical DSI lane number, for example 4lane.

  • fps: targetrefreshrate, for example 60fps.

  • _vN (can select) : When sameone IC + resolution + lane + fps stillneed toareapartnotsamehardwareversionthiswhenuse.

Example:

dsi_hx8394_720x1280_NULL_4lane_60fps.h
dsi_st7701_480x640_NULL_2lane_60fps.h

4.3.1.2. header filecontenttemplate

Each header file must include panel_platform.h (provideplatformsuitablecompatiblelayerand DSI_CMD etc.macro) , Then, pressorderdefinition timing macro, deviceconfigure, HS timing andInitialization Commands.

The following is a complete example:

#include "panel_platform.h"

/* ---- Timing 宏 ---- */
#define DSI_HX8394_720X1280_NULL_4LANE_60FPS_VACT   1280
#define DSI_HX8394_720X1280_NULL_4LANE_60FPS_VSA    16
#define DSI_HX8394_720X1280_NULL_4LANE_60FPS_VBP    4
#define DSI_HX8394_720X1280_NULL_4LANE_60FPS_VFP    6
#define DSI_HX8394_720X1280_NULL_4LANE_60FPS_HACT   720
#define DSI_HX8394_720X1280_NULL_4LANE_60FPS_HSA    64
#define DSI_HX8394_720X1280_NULL_4LANE_60FPS_HBP    36
#define DSI_HX8394_720X1280_NULL_4LANE_60FPS_HFP    128
#define DSI_HX8394_720X1280_NULL_4LANE_60FPS_FPS    60

/* ---- MIPI Tx 设备配置 ---- */
struct combo_dev_cfg_s dev_cfg_dsi_hx8394_720x1280_NULL_4lane_60fps = {
    .devno = 0,
    .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK,
                MIPI_TX_LANE_2, MIPI_TX_LANE_3},
    .lane_pn_swap = {true, true, true, true, true},
    .output_mode = OUTPUT_MODE_DSI_VIDEO,
    .video_mode = BURST_MODE,
    .output_format = OUT_FORMAT_RGB_24_BIT,
    .sync_info = {
        .vid_hsa_pixels = DSI_HX8394_720X1280_NULL_4LANE_60FPS_HSA,
        .vid_hbp_pixels = DSI_HX8394_720X1280_NULL_4LANE_60FPS_HBP,
        .vid_hfp_pixels = DSI_HX8394_720X1280_NULL_4LANE_60FPS_HFP,
        .vid_hline_pixels = DSI_HX8394_720X1280_NULL_4LANE_60FPS_HACT,
        .vid_vsa_lines = DSI_HX8394_720X1280_NULL_4LANE_60FPS_VSA,
        .vid_vbp_lines = DSI_HX8394_720X1280_NULL_4LANE_60FPS_VBP,
        .vid_vfp_lines = DSI_HX8394_720X1280_NULL_4LANE_60FPS_VFP,
        .vid_active_lines = DSI_HX8394_720X1280_NULL_4LANE_60FPS_VACT,
        .vid_vsa_pos_polarity = false,
        .vid_hsa_pos_polarity = true,
    },
    .pixel_clk = PIXEL_CLK(DSI_HX8394_720X1280_NULL_4LANE_60FPS),
};

/* ---- HS timing 配置 ---- */
struct hs_settle_s hs_timing_cfg_dsi_hx8394_720x1280_NULL_4lane_60fps = {
    .prepare = 6, .zero = 32, .trail = 1
};

/* ---- 初始化命令 ---- */
struct dsc_instr dsi_init_cmds_dsi_hx8394_720x1280_NULL_4lane_60fps[] = {
    DSI_CMD(0,   0xb9, 0xff, 0x83, 0x94),
    DSI_CMD(0,   0xb1, 0x50, 0x15, 0x75, 0x09, 0x32, 0x44, 0x71, 0x31,
            0x4d, 0x2f, 0x56, 0x73, 0x02, 0x02),
    /* ... 更多初始化命令 ... */
    DSI_CMD(120, 0x11),       /* Sleep Out, delay 120ms */
    DSI_CMD(20,  0x29),       /* Display On, delay 20ms  */
};

4.3.1.3. key data-structure description

combo_dev_cfg_s (MIPI Tx deviceattribute)

struct combo_dev_cfg_s {
    unsigned int devno;
    enum mipi_tx_lane_id lane_id[LANE_MAX_NUM];
    enum output_mode_e output_mode;
    enum video_mode_e video_mode;
    enum output_format_e output_format;
    struct sync_info_s sync_info;
    unsigned int pixel_clk;
    bool lane_pn_swap[LANE_MAX_NUM];
};

Member Name

Description

devno

MIPI Tx devicenumber, default 0

lane_id

host and panel sides Lane numbercorrespondence, unuseduse Lane fill -1 that is, can .

a total of 5 itemmember, sequentiallyrespectivelyrepresenthost side MIPI_TX_0 ~ MIPI_TX_4, actualfill incontentneed toaccording tocorrespondingtopanel side MIPI lane number.

for example, firstitemmemberishost MIPI_TX_0, checkcircuitschematiccorrespondingtopanel side MIPI lane3, thenfill inis MIPI_TX_LANE_3.

correspondencenotcorrect, willcausepanelcannotlight up.

output_mode

MIPI Tx outputmode, default OUTPUT_MODE_DSI_VIDEO

video_mode

MIPI Tx videomode, default BURST_MODE

output_format

MIPI Tx outputformat, default OUT_FORMAT_RGB_24_BIT

sync_info

MIPI Tx devicesynchronizationinformation (seeunderside)

pixel_clk

pixelclock, unitis KHz.

use PIXEL_CLK(x) macroautomaticcalculate:

#define PIXEL_CLK(x) \
    ((x##_VACT + x##_VSA + x##_VBP + x##_VFP) \
     * (x##_HACT + x##_HSA + x##_HBP + x##_HFP) * x##_FPS / 1000)

lane_clk according to pixel_clk derive backward, conversionformula:

lane_clk = pixel_clk × 24 / 4 / 2 (24 means RGB888 each pixel occupy 24 bits, 4 meansuse 4 item Data Lane, 2 means MIPI clk isdual-edge triggered)

lane_pn_swap

MIPI Tx Lane P/N extremeiswhether to swap

true: swap false: notswap

sync_info_s (MIPI Tx devicesynchronizationinformation)

struct sync_info_s {
    unsigned short vid_hsa_pixels;
    unsigned short vid_hbp_pixels;
    unsigned short vid_hfp_pixels;
    unsigned short vid_hline_pixels;
    unsigned short vid_vsa_lines;
    unsigned short vid_vbp_lines;
    unsigned short vid_vfp_lines;
    unsigned short vid_active_lines;
    bool vid_vsa_pos_polarity;
    bool vid_hsa_pos_polarity;
};

Member Name

Description

vid_hsa_pixels

Horizontal Sync Pulse (HSA) , unitispixel

vid_hbp_pixels

Horizontal Blankingafterporch (HBP) , unitispixel

vid_hfp_pixels

Horizontal Blankingbeforeporch (HFP) , unitispixel

vid_hline_pixels

Horizontal active area (HACT) , unitispixel

vid_vsa_lines

Vertical Sync Pulse (VSA) , unitisline

vid_vbp_lines

Vertical Blankingafterporch (VBP) , unitisline

vid_vfp_lines

Vertical Blankingbeforeporch (VFP) , unitisline

vid_active_lines

Vertical active area (VACT) , unitisline

vid_vsa_pos_polarity

Vertical active-signal polarity, false isHighvalid, true isLowvalid

vid_hsa_pos_polarity

Horizontal active-signal polarity, false isHighvalid, true isLowvalid

MIPI DSI protocolunder MIPI pixelareaillustration

_images/MIPIDS003.png

It is recommended to first define the timing parameters from the panel specification as macros (useheader file stem largewriteshapeformoperationisbeforesuffix) , thenin sync_info ininclude, avoidraw constantspartscatteredineachplacedifficultwithmaintenance.

hs_settle_s (MIPI Tx HS timing)

struct hs_settle_s {
    unsigned char prepare;
    unsigned char zero;
    unsigned char trail;
};

Member Name

Description

prepare

MIPI Tx prepare signal, default value 6

zero

MIPI Tx zero signal, default value 32

trail

MIPI Tx trail signal, default value 1

MIPI Tx timing diagram

_images/MIPIDS004.png

4.3.1.4. Initialization Commands

Panel initialization commands are defined with DSI_CMD() Macro, does not need to be written manually data_type and size. macrowillautomaticpressdatabytesnumberselect data type:

  • 1 bytes → 0x05 (onlyhasregisteraddress, nonedata)

  • 2 bytes → 0x15 (registeraddress + 1 itemdata)

  • 3 bytesandwithon → 0x29 (registeraddress + 2 itemandwithondata)

/* 第一个参数始终是 delay(发送后延时,单位 ms),后面是寄存器地址 + 数据 */
#define DSI_CMD(delay_ms, ...)  \
    {.delay = (delay_ms),       \
     .data_type = ...,          \
     .size = sizeof(...),       \
     .data = (CVI_U8[]){__VA_ARGS__} }

useExample:

struct dsc_instr dsi_init_cmds_dsi_hx8394_720x1280_NULL_4lane_60fps[] = {
    DSI_CMD(0,   0xb9, 0xff, 0x83, 0x94),  /* 多字节,自动选 0x29 */
    DSI_CMD(0,   0x36, 0x02),               /* 2 字节,自动选 0x15 */
    DSI_CMD(120, 0x11),                     /* Sleep Out,1 字节 → 0x05 */
    DSI_CMD(20,  0x29),                     /* Display On */
};

If panelmanufacturerspecifiednotsame data type (if 0x23, 0x39) , use DSI_CMD_TYPE displayformspecified:

DSI_CMD_TYPE(0, 0x39, 0xff, 0x77, 0x01, 0x00),

The initialization sequence is provided by the panel vendor. Refer to the panel specification or Driver IC datasheet for the meaning of each command.

4.3.2. Step 2: Register the panel-parameter header file

Select the registration method according to the target system.

4.3.2.1. u-boot / cvi_alios registration method (cvi_panels.h)

in PanelSupportList/cvi_panels.h inincreaseone #elif block. cvi_panels.h is u-boot and cvi_alios a total ofusecompilestagesingleselectintoport, through CONFIG_ macrodetermineusewhichoneblockpanel, notcanat the same timeselectmultiple panelspanel.

#elif CONFIG_DSI_HX8394_720X1280_NULL_4LANE_60FPS
#include "panels/dsi_hx8394_720x1280_NULL_4lane_60fps.h"
static struct panel_desc_s panel_desc = {
    .panel_name = "HX8394-720x1280-NULL-4lane-60fps",
    .dev_cfg = &dev_cfg_dsi_hx8394_720x1280_NULL_4lane_60fps,
    .hs_timing_cfg = &hs_timing_cfg_dsi_hx8394_720x1280_NULL_4lane_60fps,
    .dsi_init_cmds = dsi_init_cmds_dsi_hx8394_720x1280_NULL_4lane_60fps,
    .dsi_init_cmds_size = ARRAY_SIZE(dsi_init_cmds_dsi_hx8394_720x1280_NULL_4lane_60fps),
};

Note:

  • CONFIG_ macrobyheader file stem largewritederive (dsi_hx8394_720x1280_NULL_4lane_60fpsCONFIG_DSI_HX8394_720X1280_NULL_4LANE_60FPS) .

  • notthenuseoldform MIPI_PANEL_HX8394 etc.differencename, systemoneuse CONFIG_ macro.

4.3.2.2. cvi_mpi registration method (sample_panel.h + sample_panel.c)

cvi_mpi notuse cvi_panels.h, andisin sample_panel.h indirectlyconnect include thehaspanelreferenceheader file, runwhenthroughcommand lineparameterselect.

  1. in sample_panel.h inAdd #include:

#include "dsi_hx8394_720x1280_NULL_4lane_60fps.h"
  1. in sample_panel.c SAMPLE_SET_PANEL_DESC functioninincrease case:

case DSI_PANEL_HX8394_EVB:
    g_panel_desc.panel_type = PANEL_MODE_DSI;
    g_panel_desc.stdsicfg.dev_cfg =
        (struct combo_dev_cfg_s *)&dev_cfg_dsi_hx8394_720x1280_NULL_4lane_60fps;
    g_panel_desc.stdsicfg.hs_timing_cfg =
        &hs_timing_cfg_dsi_hx8394_720x1280_NULL_4lane_60fps;
    g_panel_desc.stdsicfg.dsi_init_cmds =
        dsi_init_cmds_dsi_hx8394_720x1280_NULL_4lane_60fps;
    g_panel_desc.stdsicfg.dsi_init_cmds_size =
        ARRAY_SIZE(dsi_init_cmds_dsi_hx8394_720x1280_NULL_4lane_60fps);
    break;

cvi_mpi methodsupportcompileintothehaspanelreference, runwhenuse ./sample_panel --panel=xxx switch, suitable fordebugstepsegmentfastverification.

4.3.3. Step 3: enable the configuration and build

4.3.3.1. u-boot configuration

First, runscriptthisgenerate Kconfig (scan panels/ Contentsunderthehas .h file) :

cd PanelSupportList
python3 gen_panel_config.py

The generated Kconfig.panels is used by U-Boot, includingsimilarwithundercontent:

config DSI_HX8394_720X1280_NULL_4LANE_60FPS
    bool "dsi_hx8394_720x1280_NULL_4lane_60fps"
    help
      "y" Config dsi_hx8394_720x1280_NULL_4lane_60fps.

Then enable it using either of the following methods:

  • make u-boot-menuconfig entergraphicalinterfaceselectsideboard.

  • orin build/boards/<board>/u-boot/<board>_defconfig inAdd CONFIG_DSI_HX8394_720X1280_NULL_4LANE_60FPS=y.

4.3.3.2. cvi_alios configuration

in cvi_alios/solutions/normboot/package_yamls/package.yaml.turnkey set the corresponding macro to 1 and the others to 0:

CONFIG_DSI_HX8394_720X1280_NULL_4LANE_60FPS: 1
CONFIG_PANEL_HX8394: 0

Note: The old CONFIG_PANEL_xxx aliases are retained but set to 0; new panels uniformly use CONFIG_DSI_xxx.

4.3.3.3. cvi_mpi configuration

cvi_mpi requires no build-time configuration; all panel parameters are included in sample_panel.h Medium include. compileafterthroughcommand lineselect:

./sample_panel --panel=HX8394_EVB

4.3.3.4. build

After completing the configuration above, run build_all to build the complete system.

4.4. RESET / POWER / BACKLIGHT pin configuration

Of the three systems, only U-Boot supports automatic GPIO control through the device tree; cvi_mpi and cvi_alios require GPIOs to be controlled manually in code.

4.4.1. u-boot configuration method (DTS)

U-Boot configures GPIOs through the device tree (DTS). in build/boards/default/dts/cv184x/cv184x_base.dtsi mipi_tx sectionpointinconfigure:

mipi_tx: mipi_tx {
    compatible = "cvitek,mipi_tx";
    reset-gpio = <&porte 2 GPIO_ACTIVE_LOW>;
    pwm-gpio = <&porte 0 GPIO_ACTIVE_HIGH>;
    power-ct-gpio = <&porte 1 GPIO_ACTIVE_HIGH>;
    clocks = <&clk CV181X_CLK_DISP_VIP>, <&clk CV181X_CLK_DSI_MAC_VIP>;
    clock-names = "clk_disp", "clk_dsi";
};

Note:

  • reset-gpio: resetbitspin, presspanelspecificationdocumentfill in GPIO group, sequencenumberandvalidlevel. driveraccording to GPIO_ACTIVE_LOW / GPIO_ACTIVE_HIGH automaticgenerate high-low-high (or low-high-low) resetbitstiming.

  • pwm-gpio: backlightcontrol. debugstepsegmentcan firstuse GPIO controllight upbacklight; laterifneed toadjustluma, configuration pinmux is PWM functionafterwillthislinedelete, changeuse PWM method.

  • power-ct-gpio: Panel powercontrol. ifpaneldirectlyconnectpower supplynoneneed tosoftwarecontrolthendelete.

  • Confirm the GPIO group and index for each pin against CV184X_PINOUT_CN.

  • For unused pins, omit the corresponding DTS property; the driver skips it when loading.

4.4.2. cvi_mpi configuration method (manual GPIO)

cvi_mpi does not parse GPIO properties in the DTS; control them at the application layer through sysfs or sample_panel command lineparametermanualcontrol.

4.4.2.1. methodone: sample_panel command lineparameter (onlydebuguse, codeinalreadycomment)

Pass GPIO numbers at runtime:

./sample_panel --panel=HX8394_EVB --gpio=354,0,353,1,352,1

The three GPIOs are RESET, POWER, and PWM in order; each GPIO takes two parameters (number and level).

4.4.2.2. Method 2: shell manual operation sysfs

First use cat /sys/kernel/debug/gpio to view the GPIO number ranges, after confirming the starting number for each GPIO group, calculate the target pin global number:

# 假设 RESET=GPIOE2(354), POWER=GPIOE1(353), PWM=GPIOE0(352)
echo 352 > /sys/class/gpio/export
echo 353 > /sys/class/gpio/export
echo 354 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio352/direction
echo out > /sys/class/gpio/gpio353/direction
echo out > /sys/class/gpio/gpio354/direction
echo 1 > /sys/class/gpio/gpio352/value    # 背光点亮
echo 1 > /sys/class/gpio/gpio353/value    # 电源使能
echo 1 > /sys/class/gpio/gpio354/value    # RESET 拉高
sleep 0.02
echo 0 > /sys/class/gpio/gpio354/value    # RESET 拉低
sleep 0.02
echo 1 > /sys/class/gpio/gpio354/value    # RESET 拉高

During debugging, the backlight can initially be controlled by GPIO; when brightness adjustment is needed later, configure pinmux as PWM in U-Boot and omit the backlight GPIO from the command.

4.4.3. cvi_alios configuration method (PLATFORM_PanelInit)

cvi_alios does not parse the device tree; GPIO control is completed manually in PLATFORM_PanelInit thefunctionbitsin board-level customizationContentsunder, For example:

cvi_alios/solutions/normboot/customization/<board>/src/custom_platform.c

in PLATFORM_PanelInit use _GPIOSetValue to control each pin manually:

int PLATFORM_PanelInit(void)
{
#if CONFIG_PANEL_HX8394
    u8 pw_port, pw_pin, bl_port, bl_pin, rst_port, rst_pin;
    pw_port = 4;  pw_pin = 1;   /* POWER  → GPIOE1 */
    bl_port = 4;  bl_pin = 0;   /* BACKLIGHT → GPIOE0 */
    rst_port = 4; rst_pin = 2;  /* RESET  → GPIOE2 */
    _GPIOSetValue(pw_port, pw_pin, 1);
    _GPIOSetValue(bl_port, bl_pin, 1);
    _GPIOSetValue(rst_port, rst_pin, 1);
    udelay(20 * 1000);
    _GPIOSetValue(rst_port, rst_pin, 0);
    udelay(20 * 1000);
    _GPIOSetValue(rst_port, rst_pin, 1);
    udelay(20 * 1000);
#endif
    return CVI_SUCCESS;
}

Note:

  • port is GPIO group number: 0 = GPIOA, 1 = GPIOB, ..., 4 = GPIOE.

  • pin isgroupinNo., compare with"CV184X_PINOUT_CN"confirm.

  • Refer to the panel specification for the reset sequence, which is typically high-low-high (or low-high-low).

  • When adding panel parameters, add the corresponding PLATFORM_PanelInit inAdd corresponding #if CONFIG_xxx branch.

  • To adjust backlight brightness with PWM, configure pinmux and the PWM registers separately; this section only controls GPIOs.

4.6. Build, Program, and Verify

After completing all the steps above, rebuild and program the image. Power on the device to verify that the MIPI panel lights up correctly.

If the display is abnormal, troubleshoot it as follows:

  1. Confirm that the backlight is on.

  2. confirm RESET pinlevelstatusreachexpected (if high-low-high) .

  3. Confirm that panel power is normal.

  4. execute devmem 0x0a094094 32 0x0701000a to enable the VO test pattern; if panel initialization succeeds, a color bar appears.

The test-pattern register is shown below:

_images/MIPIDS005.png

If the test pattern is normal but no image is displayed, the issue is usually in the initialization sequence or timing parameters; If test pattern alsonotnormal, check MIPI Lane order, RESET/POWER/PWM configuration, andusemultimeter/oscilloscopeconfirmcircuitlevel.

Check the Driver IC datasheet or consult the panel vendor to enable the panel BIST mode (usuallyisadjustinitialization sequenceinaregistervalue) , can fastdetermineishost sideconfigureproblemalsois a panel problem.

  • BIST abnormal -> check the Lane order, RESET, POWER, PWM, and hardware circuitry, or consult the panel vendor.

  • BIST normal -> the configuration and hardware are normal; focus on adjusting sync_info_s in timing Parameters.

Debugging tip: first use sample_panel on the cvi_mpi side to quickly verify panel parameters, with the command format ./sample_panel --panel=<PANEL_NAME>. then build and verify the complete system after it works, to avoid repeatedly programming U-Boot.