iMX8M series technical sticker | OKMX8MM-C development board UBOOT adds new display support

Posted by Wakab on Sat, 22 Jan 2022 07:05:59 +0100

OKMX8MM-CDevelopment board be based on NXP Corporate i.MX8MM ini quad core 64 bit processor design, using Core board +Backplane structure, with a maximum dominant frequency of 1.8GHz, Cortex -A53 architecture; 2GB DDR4 RAM, supporting a universal Cortex ®- M4 400MHz core processor provides a variety of peripheral interfaces, such as MIPI-CSI, MIPI-DSI, USB, PCIe and UA RT ,eCSPI , IIC and Gigabit Ethernet. This article mainly explains the OKMX8MM-C development board platform uboot Add new display support.

1, Display device that MIPI interface can connect to

OKMX8MM-C development board has only one MIPI DSI Display interface , this interface can not only connect MIPI display, but also connect LVDS display or HDMI display through MIPI to LVDS module.

MIPI display screen is also divided into those that need to be configured and those that do not need to be configured.

1. MIPI screen without configuration

The display screen of MIPI interface is divided into those requiring DSI access command MIPI screen that can only be displayed after mode configuration and MIPI screen that does not need configuration. The MIPI screen that does not need to be configured is relatively simple. As long as the MIPI DSI interface outputs normally, the signal can be displayed normally, Feiling embedded The 7-inch MIPI screen with 1024x600 resolution provided by OKMX8MM-C development board is a MIPI screen that does not need to be configured. It works in 4lanes high-speed mode by default. It only needs to configure the display related modules in the CPU and let it start working, and the MIPI screen can be displayed normally.

2. MIPI screen to be configured

For the MIPI screen to be configured, the DSI interface needs to enter the command mode to configure the display screen before outputting the display signal. The configuration parameters are generally provided by the screen manufacturer. NXP  i.MX8MM The OLED screen RM67191 used in the Evaluation Kit is a MIPI display that needs to be configured.

3. MIPI to LVDS and HDMI module

This module can convert MIPI signal into LVDS or HDMI signal. LVDS display screen or HDMI display screen can be connected through this module. MIPI to LVDS & HDMI module needs to be transferred through I2C configuration to configure the display parameters and other information including the corresponding display screen to chip Then the MIPI interface outputs the corresponding display signal.

2, LOGO display of UBOOT stage

OKMX8MM-C development board is added by default

  • 1024x600 7-inch screen (MIPI7);
  • Custom 7MIPI display (MIPICUSTOM);
  • 1920x1080 of MIPI to HDMI (MIPI2hdmi1920x1080);
  • 1280x720 (MIPI2HDMI1280x720);
  • 640x480 (MIPI2HDMI640x480);
  • 10.1-inch 1280x800LVDS display (MIPI2HDMI1280x800);
  • Customize MIPI to LVDS (MIPI2HDMICUSTOM).

Xiaobian intercepted MIPI7 and MIPI2hdmi_ The complete display parameters of 1280x720 correspond to the direct connection to MIPI screen and the connection to LVDS or HDMI screen through MIPI to LVDS & HDMI module.

struct display_info_t const displays[] = {
        {
                .bus = LCDIF_BASE_ADDR,
                .addr = 0,
                .pixfmt = 24,
                .detect = NULL,
                .enable = do_enable_mipi_led,
                .mode   = {
                        .name                   = "MIPI7",
                        .refresh                = 60,
                        .xres                   = 1024 ,
                        .yres                   = 600,
                        .pixclock               = 22733, /* 43987200 */
                        .left_margin    = 48,
                        .right_margin   = 40,
                        .upper_margin   = 16,
                        .lower_margin   = 13,
                        .hsync_len              = 48,
                        .vsync_len              = 3,
                        .sync                   = FB_SYNC_EXT,
                        .vmode                  = FB_VMODE_NONINTERLACED
                }
        },
    	...
        {       
                .bus = LCDIF_BASE_ADDR,
                .addr = 0,
                .pixfmt = 24,
                .detect = NULL,
                .enable = do_enable_mipi2hdmi,
                .mode   = {
                        .name                   = "MIPI2HDMI_1280x720",
                        .refresh                = 60,
                        .xres                   = 1280,
                        .yres                   = 720,
                        .pixclock               = 13468, //74250000
                        .left_margin    = 220,
                        .right_margin   = 110,
                        .upper_margin   = 20,
                        .lower_margin   = 5,    
                        .hsync_len              = 40,
                        .vsync_len              = 5,
                        .sync                   = FB_SYNC_EXT,
                        .vmode                  = FB_VMODE_NONINTERLACED
                }
        },
      ...
}

1. How to select display parameters

In the UBOOT phase, you can determine which group of display parameters to use by reading the value of the UBOOT environment variable panel. You can set the value of the panel through the UBOOT command line or the UBOOT menu. The method can be referred to FeilingEmbedded User manual provided. UBOOT code selects which group of parameters by judging which group of parameters the name value of the mode field is equal to the value of panel. For example, if the value of panel is equal to MIPI7, the group of display parameters corresponding to MIPI7 will be selected, that is, the 7-inch MIPI screen with 1024x600 resolution provided by Feiling embedded.

2. What do custom parameters mean

When debugging the display, we need to modify the parameters in the display parameter structure corresponding to the panel. Custom parameters refer to the parameters in the display parameter structure that can be modified by setting environment variables on the UBOOT command line. The usage of custom parameters is to set the value of panel to MIPI2HDMI_CUSTOM or MIPI_CUSTOM code reads the environment variable customvideomode, and then parses the values of xres, yres and other parameters to display xres, yres and other parameters in the parameter structure. The code is implemented as follows.

int board_video_skip(void)
{
        int i;
        int ret = 0;
        char const *panel = env_get("panel");
        if (!panel) {
             ...
        } else {
                for (i = 0; i < display_count; i++) {
                        if (!strcmp(panel, displays[i].mode.name))
                                break;
                }
        }
        if (i < display_count) {
                if(!strcmp(panel, "MIPI_CUSTOM") || !strcmp(panel, "MIPI2HDMI_CUSTOM")) {
                        char const* options = env_get("custom_video_mode");
                        char *opt = strdup(options);
                        get_mode_frome_env(&displays[i], opt);
                }
		...

static void get_mode_frome_env(struct display_info_t *dev, char *options)
{       
        char *opt;
        while ((opt = strsep(&options, ",")) != NULL) {
                if (!*opt)
                        continue; 
                if (!strncmp(opt, "xres=", 5)) {
                        dev->mode.xres = simple_strtoul(opt + 5, NULL, 0);
                } else if (!strncmp(opt, "yres=", 5)) {
                        dev->mode.yres = simple_strtoul(opt + 5, NULL, 0);
                } else if (!strncmp(opt, "pixclock=", 9)) {
                        dev->mode.pixclock = simple_strtoul(opt + 9, NULL, 0);
                } else if (!strncmp(opt, "left_margin=", 12)) {
                        dev->mode.left_margin = simple_strtoul(opt + 12, NULL, 0);
                } else if (!strncmp(opt, "right_margin=", 13)) {
                        dev->mode.right_margin = simple_strtoul(opt + 13, NULL, 0);
                } else if (!strncmp(opt, "upper_margin=", 13)) {
                        dev->mode.upper_margin = simple_strtoul(opt + 13, NULL, 0);
                } else if (!strncmp(opt, "lower_margin=", 13)) {
                        dev->mode.lower_margin = simple_strtoul(opt + 13, NULL, 0);
                } else if (!strncmp(opt, "hsync_len=", 10)) {
                        dev->mode.hsync_len = simple_strtoul(opt + 10, NULL, 0);
                } else if (!strncmp(opt, "vsync_len=", 10)) {
                        dev->mode.vsync_len = simple_strtoul(opt + 10, NULL, 0);
                } else if (!strncmp(opt, "sync=", 5)) {
                        dev->mode.sync = simple_strtoul(opt + 5, NULL, 0);
                } else if (!strncmp(opt, "vmode=", 6)) {
                        dev->mode.vmode = simple_strtoul(opt + 6, NULL, 0);
                } else if (!strncmp(opt, "refresh=", 8)) {
                        dev->mode.refresh = simple_strtoul(opt + 8 , NULL, 0);
                }
        }
        printf("use custom mode %s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %08X, %08X \n ", \
                        dev->mode.name,dev->mode.refresh, dev->mode.xres, dev->mode.yres, dev->mode.pixclock, \
                        dev->mode.left_margin, dev->mode.right_margin,  dev->mode.upper_margin, dev->mode.lower_margin, \
                        dev->mode.hsync_len, dev->mode.vsync_len, dev->mode.sync, dev->mode.vmode);
}

3, UBOOT new display debugging

When UBOOT adds a new display screen, first confirm which type of display screen is added, and then follow the Xiaobian to debug different display screens.

1. MIPI to LVDS and HDMI module

When MIPI is converted to LVDS and HDMI module, the conditions for normal display are:

  • The display parameters of the current display screen are configured in the display structure;
  • I2C sends the correct configuration parameters to the transfer module.

The configuration parameters to be issued by I2C are calculated through the display parameters, so when connecting LVDS or HDMI display, UBOOT can display the LOGO normally only by correctly configuring the display parameters. The code provided by Feiling embedded supports four resolutions by default: 640x480, 1280x720, 1920x1080 and 1280x800. If the display screen with these resolutions is selected, it can be displayed directly through the menu (the maximum resolution of LVDS interface is 1280x800). If you want to add a display screen with other resolutions, Feiling embedded provides a set of parameters that can customize the display, Just set the value of the panel to "mipi2hdcustom", then set the environment variable customvideo_mode, modify the xres and yres equivalence you need, save the environment variable, and restart to detect whether the LOGO can be displayed. You can see the newly set display parameters during startup to verify whether the modification is successful.

...
u-boot=> setenv panel MIPI2HDMI_CUSTOM              
u-boot=> setenv custom_video_mode xres=1024,yres=768
u-boot=> sa                                         
Saving Environment to MMC... Writing to MMC(1)... OK
u-boot=> reset 
resetting ...
...
Loading Environment from MMC... OK
use custom mode MIPI2HDMI_CUSTOM: 60, 1024, 768, 12048, 200, 64, 24, 1, 136, 3, 00000004, 00000000 
...

2. MIPI display without configuration

The MIPI screen does not need to be configured, and the LOGO can be displayed normally only by modifying the display parameters. The Feiling embedded development board supports a display screen with a resolution of 1024x600 by default. If you need to add a new display screen of this type, Feiling embedded provides a set of parameters that can customize the display, Just set the value of the panel to "MIPICUSTOM", then set the environment variable customvideo_mode, modify the xres and yres equivalents you need, save the environment variable, and restart to detect whether the LOGO can be displayed. You can see the newly set display parameters during startup to verify whether the modification is successful.

...
u-boot=> setenv panel MIPI_CUSTOM
u-boot=> setenv custom_video_mode xres=800,yres=600,pixclock=20000,refresh=55
u-boot=> sa
Saving Environment to MMC... Writing to MMC(1)... OK
u-boot=> reset 
resetting ...
...
Loading Environment from MMC... OK
use custom mode MIPI_CUSTOM: 55, 800, 600, 20000, 48, 40, 16, 13, 48, 3, 00000004, 00000000 
 Display: MIPI_CUSTOM (800x600)
Video: 800x600x24
...

3. MIPI display to be configured

Compared with the MIPI display that does not need to be configured, this display has one more step configuration, which can be modified with reference to RM67191 provided by the original factory.

First, add a group of display parameters. The display parameters are modified according to the display screen. Modify the file board / Freescale / imx8mmevk / imx8mmevk c.

 {
        .bus = LCDIF_BASE_ADDR,
        .addr = 0,
        .pixfmt = 24,
        .detect = NULL,
        .enable = do_enable_mipi_led,
        .mode   = {
        		.name                   = "RM67191_OLED",
        		.refresh                = 60,
       			.xres                   = 1080,
        		.yres                   = 1920,
        		.pixclock               = 7575, /* 132000000 */
        		.left_margin    = 34,
        		.right_margin   = 20,
        		.upper_margin   = 4,
        		.lower_margin   = 10,
        		.hsync_len              = 2,
        		.vsync_len              = 2,
        		.sync                   = FB_SYNC_EXT,
        	.vmode                  = FB_VMODE_NONINTERLACED         
         } 
 }

Then modify the enabling function of this set of parameters

void do_enable_mipi_led(struct display_info_t const *dev)
{
        imx_iomux_v3_setup_multiple_pads(backlight_pads,
                                         ARRAY_SIZE(backlight_pads));
        gpio_request(IMX_GPIO_NR(1, 1), "backlight");
        gpio_direction_output(IMX_GPIO_NR(1, 1), 0);
        gpio_request(IMX_GPIO_NR(1, 8), "DSI EN");
        gpio_direction_output(IMX_GPIO_NR(1, 8), 0);
        mdelay(10);
        gpio_direction_output(IMX_GPIO_NR(1, 8), 1);
        /* enable the dispmix & mipi phy power domain */
        call_imx_sip(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_PM_DOMAIN, DISPMIX, true, 0);
        call_imx_sip(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_PM_DOMAIN, MIPI, true, 0);
        /* Put lcdif out of reset */
        disp_mix_bus_rstn_reset(imx8mm_mipi_dsim_plat_data.gpr_base, false);
        disp_mix_lcdif_clks_enable(imx8mm_mipi_dsim_plat_data.gpr_base, true);
        /* Setup mipi dsim */
        sec_mipi_dsim_setup(&imx8mm_mipi_dsim_plat_data);
		rm67191_init();
        rm67191_dev.name = dev->mode.name;
		imx_mipi_dsi_bridge_attach(&rm67191_dev); /* attach rm67191 device */
}
struct mipi_dsi_client_dev rm67191_dev = {
        .channel        = 0,
        .lanes = 4,
        .format  = MIPI_DSI_FMT_RGB888,
        .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
                          MIPI_DSI_MODE_EOT_PACKET | MIPI_DSI_MODE_VIDEO_HSE,
};

Modify display driver / video / rm67191 c. Add the initialization sequence of your own screen in the function int rm67191lcdsetup(struct mipidsiclientdev *paneldev).

Compile the test after modification.

Note: the uboot code is not open source. To modify the code, you need to contact the sales staff

Topics: Linux AI ARM