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

 

 

 

 

 

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • springboot详细讲解_Springboot框架

    springboot详细讲解_Springboot框架一、SpringApplication的几种常用方式二、定制启动Banner三、SpringBoot事件和监听器四、SpringBoot的Web环境信息五、SpringBoot的ApplicationRunner接口和CommandLineRunner接口SpringBoot版本:1.5.13.RELEASE对应官方文档链接:https://docs.s…

  • Vue上传图片并展示

    Vue上传图片并展示上传图片并展示

  • Tomcat日志乱码问题

    Tomcat日志乱码问题昨天本来准备更新一下Tomcat版本,但是发现新版本的日志打印中文会出现乱码(Tomcat自身打印的日志),不管是使用bat脚本启动还是在Idea中启动,都是乱码。研究了一个晚上,百度上的那些方式都试遍了,都是设置各种JVM启动参数,发现并没有卵用。在使用bat文件启动Tomcat时,Tomcat目录下的logs文件夹会生成相应的日志文件,发现旧版本生成的日志文件编码是GBK,而Windows控…

  • Eclipse 添加 Tomcat Server 配置

    Eclipse 添加 Tomcat Server 配置以下步骤是将一个独立安装的(standalone)Tomcat整合到Eclipse中,方便在Eclipse发布Web工程到Tomcat服务器,启停WebServer调试程序。项目开发中不推荐使用Eclipse自带的WebServer,不便于运行调试,往往需要根据项目需求独立安装指定厂家和版本的Webserver。(项目部署参考–>Eclipse部署项目到Tomcat)…

    2022年10月25日
  • MySQL截取字符串的方法-substring_index

    MySQL截取字符串的方法-substring_indexsubstring_index的用法substring_index(str,delim,count)str:要处理的字符串delim:分隔符count:计数(要截取的位置,正数为从左向右,负数为从右向左)工作中遇到的案例:排查生产问题的时候,需要从类似下面的日志中取出一个orderId这个字段对应的数字customer_id=87380–>customer_id有最新跟进的订单,orderId=293976–>ENDSQL语句:selectsubstring_ind

  • 面试题之  什么是不可变类? 为什么String是不可变类? 如何创建一个不可变类

    面试题之  什么是不可变类? 为什么String是不可变类? 如何创建一个不可变类面试题:     什么是不可变类? 为什么String是不可变类? 如何创建一个不可变类不可变类当类的对象创建后,它的值就不可以再更改了相比于可变对象,不可变对象有很多优势不可变对象可以提高String Pool(字符串常量池)的效率和安全性。如果你知道一个对象是不可变的 ,那么需要拷贝对象的内容时就不用复制它本身而只复制它的地址,复制地址(通常一个指针的大小)需要很小的内存,效率…

发表回复

您的电子邮箱地址不会被公开。

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