mipiLCD屏幕参数_mipi接口液晶屏

mipiLCD屏幕参数_mipi接口液晶屏主屏通过lt8911exb将mipi信号转换成EDP信号输出,调试从大的方向上看,主要是两方面,一个是bootloader阶段的的显示,一个是kernel阶段的现实,lt8911exb的初始化主要在bootloader阶段调试简介:本次调试lt8911exb的I2C接到SDM450的I2C3接口bootloader阶段由于lt8911exb使用的是I2C接口,所以在bootloader阶段需要实现该I2C接口的初始化工作,然后去初始化lt8911exb。然后再按照通用的方式去配置屏.

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

主屏通过lt8911exb 将mipi信号转换成EDP信号输出,调试从大的方向上看,主要是两方面,一个是bootloader阶段的lt8911exb初始化,为了让现实过程更完整,需要在lk的display init之前就要将lt8911exb准备好.当lt8911exb准备好后,就可以当lt8911exb不存在,以平时的方式去调试一个屏幕。本次调试lt8911exb 的I2C接到SDM450的I2C3接口上,以下是调试步骤概要

 

1、原理图的简单分析

2、lt8911exb的初始化

3、bootloader阶段的屏幕调试

4、kernel阶段移植

 

一、原理图的简单分析

原理图分析这一块,因为涉及到具体的产品,所以这里只是简单的介绍lt8911exb主控的接口

mipiLCD屏幕参数_mipi接口液晶屏

                                                         图一

mipiLCD屏幕参数_mipi接口液晶屏

                                             图2

mipiLCD屏幕参数_mipi接口液晶屏

                                                          图三

主控部分和I2C上拉,电平转换等都没有贴出来,以下是简单的总结一下LT8911和主控的接口描述

LT8911的mipi输入端和SDM450的主屏(mdss_dsi0)通过4lane连接

LT8911的I2C接口接SDM450的I2C3

LT8911的上电使能管脚(LCDO_PWR)接SDM450的GPIO19

LT8911的reset管脚(LCD0_RST)接SDM450的GPIO61

屏幕的上电使能(LCD0_EN)接SDM450的GPIO24

屏幕的背光使能(EDP_BL_EN)接SDM450的GPIO44

屏幕的背光接(EDP_BL_PWM)接SDM450主屏PWM

LT8911和屏幕通过2lane连接

LT8911七位I2C地址是0x29

对于LT8911的操作主要是上电、复位、初始化,对于屏幕来说就是上电是能、背光控制

 

二、lt8911exb初始化

主屏幕的lt8911exb初始化放在bootloader完成,由于SDM450的bootloader阶段I2C接口还没做初始化,所以我们得先初始化好I2C后,再初始化lt8911,具体过程如下

1、SDM450bootloader阶段I2C3初始化

      I2C3时钟初始化

bootable/bootloader/lk/platform/msm8953/include/platform/iomap.h
+#define BLSP_QUP_BASE(blsp_id, qup_id) 	(PERIPH_SS_BASE + 0xB5000 + 0x1000 * qup_id)
+#define GCC_BLSP1_QUP3_APPS_CBCR    	(CLK_CTL_BASE + 0x04020)
+#define GCC_BLSP1_QUP3_CMD_RCGR	(CLK_CTL_BASE + 0x04000)
+#define GCC_BLSP1_QUP3_CFG_RCGR	(CLK_CTL_BASE + 0x04004)

bootable/bootloader/lk/platform/msm8953/msm8953-clock.c
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup3_i2c_apps_clk_src[] =
+{
+	F(      96000,    cxo,  10,   1,  2),
+	F(    4800000,    cxo,   4,   0,  0),
+	F(    9600000,    cxo,   2,   0,  0),
+	F(   16000000,  gpll0,  10,   1,  5),
+	F(   19200000,  gpll0,   1,   0,  0),
+	F(   25000000,  gpll0,  16,   1,  2),
+	F(   50000000,  gpll0,  16,   0,  0),
+	F_END
+};
+static struct rcg_clk gcc_blsp1_qup3_i2c_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) GCC_BLSP1_QUP3_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_BLSP1_QUP3_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_blsp1_qup3_i2c_apps_clk_src,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
+	.cbcr_reg = (uint32_t *)GCC_BLSP1_QUP3_APPS_CBCR,
+	.parent   = &gcc_blsp1_qup3_i2c_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};

 static struct rcg_clk sdcc2_apps_clk_src ={
........
+	CLK_LOOKUP("blsp1_ahb_clk", gcc_blsp1_ahb_clk.c),
+	CLK_LOOKUP("gcc_blsp1_qup3_i2c_apps_clk_src", gcc_blsp1_qup3_i2c_apps_clk_src.c),
+	CLK_LOOKUP("gcc_blsp1_qup3_i2c_apps_clk", gcc_blsp1_qup3_i2c_apps_clk.c),
}

//实现时钟配置函数
bootable/bootloader/lk/platform/msm8953/include/platform/clock.h
void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id);

bootable/bootloader/lk/platform/msm8953/acpuclock.c
#include <blsp_qup.h>
void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
{
    uint8_t ret = 0;
    char clk_name[64];

    struct clk *qup_clk;
    if((blsp_id != BLSP_ID_1) || (qup_id > QUP_ID_5)) {
        dprintf(CRITICAL, "Incorrect BLSP-%d or QUP-%d configuration\n", blsp_id, qup_id);
        ASSERT(0);
    }

    snprintf(clk_name, sizeof(clk_name), "blsp1_ahb_clk");

    ret = clk_get_set_enable(clk_name, 0 , 1);
    if (ret) {
        dprintf(CRITICAL, "Failed to enable %s clock\n", clk_name);
        return;
    }

    snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup3_i2c_apps_clk");

    qup_clk = clk_get(clk_name);
    if (!qup_clk) {
        dprintf(CRITICAL, "Failed to get %s\n", clk_name);
        return;
    }

    ret = clk_enable(qup_clk);

    if (ret) {
        dprintf(CRITICAL, "Failed to enable %s\n", clk_name);
        return;
    }
}

    2、SDM450 I2C3管脚复用功能配置接口实现

bootable/bootloader/lk/platform/msm8953/include/platform/gpio.h
+void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id);

bootable/bootloader/lk/platform/msm8953/gpio.c
void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
{
    if(blsp_id == BLSP_ID_1) {
        switch (qup_id) {
            	case QUP_ID_2:
                /* configure I2C SDA gpio */
               /*
                1 arg: GPIO #
                2 arg: GPIO Function (Check GPIO MAP)
                3 arg: Doesn't matter
                4 arg: Should be GPIO_NO_PULL
                5 arg: Drive Strength: Lower the better
                6 arg: doesn't matter
                /* configure I2C SDA gpio */
                gpio_tlmm_config(10, 2, GPIO_OUTPUT, GPIO_NO_PULL,
                        GPIO_8MA, GPIO_DISABLE);
                /* configure I2C SCL gpio */
                gpio_tlmm_config(11, 2, GPIO_OUTPUT, GPIO_NO_PULL,
                    GPIO_8MA, GPIO_DISABLE);
            break;
		case QUP_ID_1:
                /* configure I2C SDA gpio */
               /*
                1 arg: GPIO #
                2 arg: GPIO Function (Check GPIO MAP)
                3 arg: Doesn't matter
                4 arg: Should be GPIO_NO_PULL
                5 arg: Drive Strength: Lower the better
                6 arg: doesn't matter
               */
                /* configure I2C SDA gpio */
                gpio_tlmm_config(6, 3, GPIO_OUTPUT, GPIO_NO_PULL,
                        GPIO_8MA, GPIO_DISABLE);

                /* configure I2C SCL gpio */
                gpio_tlmm_config(7, 3, GPIO_OUTPUT, GPIO_NO_PULL,
                    GPIO_8MA, GPIO_DISABLE);
            break;
            default:
                dprintf(CRITICAL, "Incorrect QUP id %d\n",qup_id);
                ASSERT(0);
        };
    } else {
        dprintf(CRITICAL, "Incorrect BLSP id %d\n",blsp_id);
        ASSERT(0);
    }
}

3、配置I2C3控制器的内部中断

bootable/bootloader/lk/platform/msm8953/include/platform/irqs.h
+#define BLSP_QUP_IRQ(blsp_id, qup_id)          (GIC_SPI_START + 95 + qup_id)

4、实现I2C3接口的配置函数(这里其实是bootloader自带的)


bootable/bootloader/lk/platform/msm_shared/mipi_dsi_i2c.c

int mipi_dsi_i2c_device_init(uint8_t blsp_id, uint8_t qup_id)
{
	i2c_dev = qup_blsp_i2c_init(blsp_id, qup_id,
				I2C_CLK_FREQ, I2C_SRC_CLK_FREQ);
	if(!i2c_dev) {
		dprintf(CRITICAL, "mipi_dsi_i2c_device_init() failed\n");
		return ERR_NOT_VALID;
	}
	return NO_ERROR;
}

bootable/bootloader/lk/platform/msm_shared/i2c_qup.c

struct qup_i2c_dev *qup_blsp_i2c_init(uint8_t blsp_id, uint8_t qup_id,
									  uint32_t clk_freq, uint32_t src_clk_freq)
{
	struct qup_i2c_dev *dev;

	if (dev_addr != NULL) {
		return dev_addr;
	}
	dev = malloc(sizeof(struct qup_i2c_dev));
	if (!dev) {
		return NULL;
	}
	dev = memset(dev, 0, sizeof(struct qup_i2c_dev));

	/* Platform uses BLSP */
	dev->qup_irq = BLSP_QUP_IRQ(blsp_id, qup_id);
	dev->qup_base = BLSP_QUP_BASE(blsp_id, qup_id);
	/* This must be done for qup_i2c_interrupt to work. */
	dev_addr = dev;

	/* Initialize the GPIO for BLSP i2c */
	gpio_config_blsp_i2c(blsp_id, qup_id);

	clock_config_blsp_i2c(blsp_id, qup_id);
	qup_i2c_sec_init(dev, clk_freq, src_clk_freq);

	return dev;
}

5、将i2c_qup.c 和mipi_dsi_i2c.c

bootable/bootloader/lk/platform/msm_shared/rules.mk
+			$(LOCAL_DIR)/i2c_qup.o \
+			$(LOCAL_DIR)/mipi_dsi_i2c.o

6、初始化lt8911exb, 这部分只贴出大概架构,其他的没贴出来

bootable/bootloader/lk/include/target.h
定义lt8911exb_config
void lt8911exb_config(void);

bootable/bootloader/lk/app/aboot/aboot.c
在aboot init中添加lt8911的初始化
void aboot_init(const struct app_descriptor *app)
{     
..........
    lt8911exb_config();
..........
}

bootable/bootloader/lk/target/msm8953/lt8911exb_config.c
void lt8911exb_config(void)
{
	lt8911exb_reset();
	mipi_dsi_i2c_device_init(BLSP_ID_1, QUP_ID_2);
	mdelay(50);
	lt8911exb_read_chip_id();
	lt8911exb_edp_video_cfg();
	lt8911exb_init();


	Read_DPCD010A = dpcd_read( 0x010A ) & 0x01;

	if( Read_DPCD010A )
	{
		ScrambleMode = 1;
	}else
	{
		ScrambleMode = 0;
	}
	lt8911exb_link_train( );


	lt8911exb_tx_swing_pre_set( );

	lcd_and_bl_power_on();
}

三、bootloader阶段的屏幕调试

1、添加屏幕信息头文件,这个不详细介绍如何生成文件
bootable/bootloader/lk/dev/gcdb/display/include/panel_pt156fhm_n10_1080p_video.h

2、修改bootable/bootloader/lk/target/msm8953/oem_panel.c文件进行屏幕的添加
bootable/bootloader/lk/target/msm8953/oem_panel.c
+#include "panel_pt156fhm_n10_1080p_video.h"
enum {
+PB156FHM_N10_800P_VIDEO_PANEL,
}

static struct panel_list supp_panels[] = {
+{"pt156fnm_n10_1080p_video", PB156FHM_N10_800P_VIDEO_PANEL},
}

static int init_panel_data(struct panel_struct *panelstruct,
			struct msm_panel_info *pinfo,
			struct mdss_dsi_phy_ctrl *phy_db)
{
	case PB156FHM_N10_800P_VIDEO_PANEL:
		panelstruct->paneldata    = &pt156fhm_n10_1080p_video_panel_data;
		panelstruct->panelres     = &pt156fhm_n10_1080p_video_panel_res;
		panelstruct->color        = &pt156fhm_n10_1080p_video_color;
		panelstruct->videopanel   =
				&pt156fhm_n10_1080p_video_video_panel;
		panelstruct->commandpanel =
				&pt156fhm_n10_1080p_video_command_panel;
		panelstruct->state        = &pt156fhm_n10_1080p_video_state;
		panelstruct->laneconfig   =
				&pt156fhm_n10_1080p_video_lane_config;
		panelstruct->paneltiminginfo
				= &pt156fhm_n10_1080p_video_timing_info;
		panelstruct->panelresetseq
				= &pt156fhm_n10_1080p_video_reset_seq;
		panelstruct->backlightinfo = &pt156fhm_n10_1080p_video_backlight;
		pinfo->mipi.panel_on_cmds
				= pt156fhm_n10_1080p_video_on_command;
		pinfo->mipi.num_of_panel_on_cmds
				= PT156FHM_N10_1080P_VIDEO_OFF_COMMAND;	
		pinfo->mipi.panel_off_cmds
				= pt156fhm_n10_1080p_video_off_command;
		pinfo->mipi.num_of_panel_off_cmds
				= PT156FHM_N10_1080P_VIDEO_OFF_COMMAND;
		memcpy(phy_db->timing,
			pt156fhm_n10_14nm_1080p_video_timings, MAX_TIMING_CONFIG * sizeof(uint32_t));
		pinfo->mipi.signature    = PT156FHM_N10_1080P_VEDIO_SIGNATURE;
		break;	
}

int oem_panel_select(const char *panel_name, struct panel_struct *panelstruct,
			struct msm_panel_info *pinfo,
			struct mdss_dsi_phy_ctrl *phy_db)
{
	case HW_PLATFORM_RCM:
panel_id = PB156FHM_N10_800P_VIDEO_PANEL;
}

四、kernel阶段移植

1、添加屏幕的dtsi文件,具体怎么生成这个文件,不做讲解
kernel/msm-4.9/arch/arm64/boot/dts/qcom/dsi-panel-pt156fnm-n10-1080p-video.dtsi
2、增加这款屏幕支持
kernel/msm-4.9/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
+#include "dsi-panel-pt156fnm-n10-1080p-video.dtsi"

kernel/msm-4.9/arch/arm64/boot/dts/qcom/msm8953-nopmi-panel-camera.dtsi

mipiLCD屏幕参数_mipi接口液晶屏

 

五、调试总结

在调试过程中,注意事项:

1、LT8911的地址,在调试过程中先保证出彩条,确认后级电路没问题

2、LT8911的复位时,reset管脚的高低高输出

3、LT8911和主控mipi端接口是几lane

4、LT8911和屏幕的接口是几lane

 

 

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/180394.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 带你详细了解,一致性哈希算法的实现原理

    带你详细了解,一致性哈希算法的实现原理一致性哈希算法在1997年由麻省理工学院的Karger等人在解决分布式Cache中提出的,设计目标是为了解决因特网中的热点问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简单哈希算法带来的问题,使得DHT可以在P2P环境中真正得到应用。但现在一致性哈希算法在分布式系统中也得到了广泛应用,研究过Memcached缓存数据库的人都知道,Memcached服务器端本身不提供分布式Cache的一致性,而是由客户端来提供,具体在计算一致性哈希时采用如下步骤:

    2022年7月27日
    7
  • 基于MATLAB的智能交通信号灯控制系统的实现

    基于MATLAB的智能交通信号灯控制系统的实现写在前面1)现实意义早期使用的交通信号灯是固定配时的调控方式,无法随着车流量的变动而调整绿灯时间,这降低绿灯的使用效益,增大了车辆在交叉口的延误。堵车现象频繁发生,给市民工作生活带来了极大不便,国民经济受到影响。这时候提高道路通行效率,特别是交叉路口的车辆通行效率就显得尤为重要。2)关键技术智能交通系统的核心是交通信号灯的智能控制算法,根据实时交通流的大小,配置信号周期及各种色灯的闪亮时间…

    2022年9月24日
    2
  • Java开发手册之常量定义

    Java开发手册之常量定义Java开发手册之常量定义

    2022年4月22日
    41
  • WireShark抓包后数据分析

    WireShark抓包后数据分析在分析数据之前,我们先了解一下我们传输数据的结构体系,如下图:这是两种体系,我们常知的一般都是TCP/IP体系结构。TCP/IP体系架构分析不难发现,TCP/IP体系中包含着很多我们熟悉的协议,比如说:http、smtp、https等。而我们人(使用者)是站在应用层之上的,我们想把数据上传或者说发送给别人,就要通过一些应用,如:QQ、微信、百度网盘等。然后就经过一层层加密(在数据包前加个“头”),一层层的传递。Frame层(物理层)分析这是我自己抓包的一个例子,我从我自己的QQ发了一条消息给朋友,

    2025年9月6日
    8
  • WXS 模块

    WXS 模块WXS 代码可以编写在 wxml 文件中的 nbsp nbsp 标签内 或以 nbsp wxs nbsp 为后缀名的文件内 模块每一个 nbsp wxs nbsp 文件和 nbsp nbsp 标签都是一个单独的模块 每个模块都有自己独立的作用域 即在一个模块里面定义的变量与函数 默认为私有的 对其他模块不可见 一个模块要想对外暴露其内部的私有变量与函数 只能通过 nbsp module exports nbsp 实现 wxs 文件在微信开发者工具里面 右

    2025年11月8日
    5
  • Git出现Couldn’t save uncommitted changes.问题的解决

    Git出现Couldn’t save uncommitted changes.问题的解决Couldn’t save uncommitted changes

    2022年6月24日
    89

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号