iMX8M系列技術(shù)貼 | OKMX8MM-C開發(fā)板UBOOT添加新的顯示支持
OKMX8MM-C開發(fā)板基于NXP公司的i.MX8MMini 四核64位處理器設(shè)計,采用核心板+底板結(jié)構(gòu),主頻最高1.8GHz,Cortex-A53架構(gòu);2GB DDR4 RAM,支持一個通用型Cortex?-M4 400MHz內(nèi)核處理器提供多種外設(shè)接口,如MIPI-CSI、MIPI-DSI、USB、PCIe、UART 、eCSPI 、IIC和千兆以太網(wǎng)。本文主要講解OKMX8MM-C開發(fā)板平臺uboot添加新的顯示支持。
一、MIPI接口能夠連接的顯示設(shè)備
OKMX8MM-C開發(fā)板只有一個MIPI DSI顯示接口,這個接口除了可以連接MIPI顯示屏,還可以通過MIPI轉(zhuǎn)LVDS模塊,連接LVDS顯示屏或HDMI顯示屏。
其中MIPI顯示屏還分為需要配置和不需要配置的。
1、不需要配置的MIPI屏
MIPI接口的顯示屏分為需要DSI進入命令模式配置后才能顯示的MIPI屏和不需要配置的MIPI屏。不需要配置的MIPI屏比較簡單,只要MIPI DSI接口正常輸出信號就能正常顯示,飛凌嵌入式OKMX8MM-C開發(fā)板提供的1024x600分辨率的7寸MIPI屏就是一塊不需要配置的MIPI屏,它默認就工作在4lanes高速模式下,只需要將CPU內(nèi)的顯示相關(guān)的模塊配置好,并讓其開始工作,MIPI屏就能夠正常顯示。
2、需要配置的MIPI屏
需要配置的MIPI屏,DSI接口在輸出顯示信號前需要進入命令模式對顯示屏進行配置,配置參數(shù)一般由屏體廠家提供。NXP i.MX8MM 評估套件使用的OLED屏RM67191,就是一款需要配置的MIPI顯示屏。
3、MIPI轉(zhuǎn)LVDS和HDMI模塊
這個模塊能將MIPI信號轉(zhuǎn)換為LVDS或HDMI信號,通過這個模塊可以連接LVDS顯示屏或者HDMI顯示屏。MIPI轉(zhuǎn)LVDS&HDMI模塊需要通過I2C配置轉(zhuǎn)接,將包含對應的顯示屏的顯示參數(shù)等信息配置到芯片內(nèi),然后MIPI接口輸出對應的顯示信號。
二、UBOOT階段的LOGO顯示
OKMX8MM-C開發(fā)板默認添加了
-
1024x600的7寸屏(MIPI7);
-
自定義7MIPI顯示(MIPICUSTOM);
-
MIPI轉(zhuǎn)HDMI的1920x1080 (MIPI2HDMI1920x1080);
-
1280x720 (MIPI2HDMI1280x720);
-
640x480 (MIPI2HDMI640x480);
-
10.1寸1280x800LVDS顯示屏(MIPI2HDMI1280x800);
-
自定義MIPI轉(zhuǎn)LVDS(MIPI2HDMICUSTOM)。
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 } }, ... }
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); }
三、UBOOT新增顯示調(diào)試
UBOOT新增顯示屏時,先確認增加的是哪種類型的顯示屏,下面跟著小編一起對不同的顯示屏進行調(diào)試。1、MIPI轉(zhuǎn)LVDS和HDMI模塊
MIPI轉(zhuǎn)LVDS和HDMI模塊,能夠正常顯示的條件是:
- 顯示結(jié)構(gòu)體內(nèi)配置當前顯示屏的顯示參數(shù);
- I2C下發(fā)正確的配置參數(shù)到轉(zhuǎn)接模塊。
I2C需要下發(fā)的配置參數(shù)是通過顯示參數(shù)計算得出,所以當連接LVDS或HDMI顯示時,只需要正確配置顯示參數(shù)就能讓UBOOT正常顯示LOGO。飛凌嵌入式提供的代碼已經(jīng)默認支持了640x480、1280x720、1920x1080、1280x800四種分辨率,如果選擇這幾種分辨率的顯示屏,直接通過菜單顯示即可(LVDS接口分辨率最大支持到1280x800)。如果要添加其它分辨率的顯示屏,飛凌嵌入式提供了一組可以自定義顯示的參數(shù),只需要將panel的值設(shè)置為”MIPI2HDMICUSTOM“,然后設(shè)置環(huán)境變量customvideo_mode,修改你需要的xres、yres等值后保存環(huán)境變量,重啟檢測能否顯示LOGO。在啟動的過程可以看到新設(shè)置的顯示參數(shù),方便驗證修改的是否成功。
... 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顯示屏
不需配置的MIPI屏,只需要修改顯示參數(shù)即可正常顯示LOGO。飛凌嵌入式開發(fā)板默認支持分辨率為1024x600的顯示屏,如需添加新的此類型的顯示屏,飛凌嵌入式提供了一組可以自定義顯示的參數(shù),只需要將panel的值設(shè)置為”MIPICUSTOM“,然后設(shè)置環(huán)境變量customvideo_mode,修改你需要的xres、yres等值后保存環(huán)境變量,重啟檢測能否顯示LOGO。在啟動的過程可以看到新設(shè)置的顯示參數(shù),方便驗證修改的是否成功。
... 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顯示屏
這種顯示屏對比不需配置的MIPI顯示屏多了一步配置,可以參照原廠提供的RM67191進行修改。
首先,添加一組顯示參數(shù),顯示參數(shù)根據(jù)顯示屏修改,修改文件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 } }
然后修改這組參數(shù)的使能函數(shù)
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, };
修改顯示屏驅(qū)動drivers/video/rm67191.c,在函數(shù)int rm67191lcdsetup(struct mipidsiclientdev *paneldev)添加自己的屏的初始化序列。
修改完成后編譯測試。
注意:uboot代碼不開源,修改代碼需要聯(lián)系銷售人員
相關(guān)產(chǎn)品 >
-
OKMX8MP-C開發(fā)板
內(nèi)置NPU、ISP,AI計算能力高達2.3TOPS|飛凌嵌入式i.MX8MP 系列-NXP iMX8M Plus 開發(fā)板 基于高性能低功耗工業(yè)級iMX8MP核心板設(shè)計,支持多種多種高速通信接口。iMX8MP開發(fā)板內(nèi)置NPU,AI計算能力2.3TOPS,支持4K,支持雙圖像信號處理器(ISP),是一款支持LinuxQT/android操作系統(tǒng)的iMX8MP開發(fā)板。
了解詳情 -
FETMX8MP-C核心板
iMX8MP核心板基于 NXP i.MX 8M Plus 處理器設(shè)計, 采用4核Cortex-A53 和 Cortex-M7架構(gòu)。支持雙千兆網(wǎng)口,iMX8MP性能強勁最高運行速率可達2.3TOPS,并且i.MX8MP功耗更低≤2W 。iMX 8M Plus系列專注于機器學習和視覺、高級多媒體以及具有高可靠性的工業(yè)自動化。它旨在滿足智慧家庭、樓宇、城市和工業(yè)4.0應用的需求。飛凌iMX8MP核心板提供用戶手冊,iMX8MP原理圖,引腳定義等。
了解詳情