高通display驱动

0. 关键字

MDSS : 高通平台lcd multimedia Display sub system

DSI: Display Serial Interface

qcom,mdss-dsi-force-clock-lane-hs;          // faulse :clock每帧回lp11   ture: clock不回
qcom,mdss-dsi-hfp-power-mode; // data 每行回lp11,对应的hfp要修改成300以上

1. 涉及文件

  1. drivers\video\fbmem.c(核心层)
register_framebuffer(struct fb_info *fb_info)   //对外暴露核心函数
  1. drivers\video\msm\mdss\mdss_fb.c (mdss 核心层 fbx平台设备驱动)
// 调用 fbmem.c的 register_framebuffer注册 fbx
  1. msm8909-mdss.dtsi(文件名通常为msm8909-mdss.dtsi指定了mdss的mdp和dsi)
mdss_mdp: qcom,mdss_mdp@fd900000 {
compatible = "qcom,mdss_mdp3"; // 对应mdss驱动 mdss_mdp.
mdss_dsi0: qcom,mdss_dsi@fdd00000 {
compatible = "qcom,msm-dsi-v2"; // 对应dsi解析驱动 dsi_host_v2.c
  1. drivers\video\msm\mdss\dsi_host_v2.c (lcd驱动 dsi)
// 通过下面函数向 mdss_fb.c 注册了fb_info结构  (包含在mdss_dsi_ctrl_pdata结构中)
dsi_panel_device_register_v2(struct platform_device *dev,struct mdss_dsi_ctrl_pdata *ctrl_pdata)
static const struct of_device_id msm_dsi_v2_dt_match[] = {
{.compatible = "qcom,msm-dsi-v2"},
{}
};

或者

drivers\video\msm\mdss\mdss_dsi.c

  1. drivers\video\msm\mdss\mdp3.c (mdp)
   .compatible = "qcom,mdss_mdp3",
  1. arch/arm/boot/dts/qcom/msm8909-qrd-skua.dtsi

    通常在dts文件的 mdss_dsi0 lab里面通过qcom,dsi-pref-prim-pan 属性 指定使用哪一个lcd配置
&mdss_dsi0 {
qcom,dsi-pref-prim-pan = <&dsi_hx8379a_fwvga_skua_vid>;
pinctrl-names = "mdss_default", "mdss_sleep";
pinctrl-0 = <&mdss_dsi_active &mdss_te_active>;
pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>;
qcom,platform-reset-gpio = <&msm_gpio 25 0>;
};
  1. dsi-panel-fl10802-fwvga-video.dtsi
&mdss_mdp {
dsi_fl10802_fwvga_vid: qcom,mdss_dsi_fl10802_fwvga_video {
qcom,mdss-dsi-panel-name = "fl10802 fwvga video mode dsi panel";
qcom,mdss-dsi-drive-ic = "fl10802";
qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
qcom,mdss-dsi-panel-type = "dsi_video_mode";
qcom,mdss-dsi-panel-destination = "display_1";
...
}

2. mdss_mdp 和 mdss_dsi0 的关系

mdss_mdp 相当于一个数组,里面定义了很多不同lcd显示屏的配置项包括分辨率等等

mdss_dsi0 的 “qcom,dsi-pref-prim-pan ” 属性指定了使用mdss_mdp中哪一个lcd配置选项

3.时序图

4. 重要结构

4.1 结构关系

backLight
关键字:qcom,mdss-dsi-bl-pmic-control-type
struct mdss_dsi_ctrl_pdata {
int ndx; /* panel_num */
int (*on) (struct mdss_panel_data *pdata); // ★ on
int (*off) (struct mdss_panel_data *pdata); // ★ off
int (*partial_update_fnc) (struct mdss_panel_data *pdata);
int (*check_status) (struct mdss_dsi_ctrl_pdata *pdata);
int (*cmdlist_commit)(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
void (*switch_mode) (struct mdss_panel_data *pdata, int mode);
struct mdss_panel_data panel_data; //★ panel_data.set_backlight 设置背光亮度函数
//★ panel_data.panel_info = struct mdss_panel_info ①
unsigned char *ctrl_base;
struct dss_io_data ctrl_io;
struct dss_io_data mmss_misc_io;
struct dss_io_data phy_io;
int reg_size;
u32 bus_clk_cnt;
u32 link_clk_cnt;
u32 flags;
struct clk *mdp_core_clk;
struct clk *ahb_clk;
struct clk *axi_clk;
struct clk *mmss_misc_ahb_clk;
struct clk *byte_clk;
struct clk *esc_clk;
struct clk *pixel_clk;
u8 ctrl_state;
int panel_mode;
int irq_cnt;
int rst_gpio; // ★ gpio qcom,platform-reset-gpio: Specifies the panel reset gpio.
int disp_en_gpio; // qcom,platform-enable-gpio: Specifies the panel lcd/display enable gpio.
int disp_te_gpio; // qcom,platform-te-gpio: Specifies the gpio used for TE.
int mode_gpio; // qcom,platform-mode-gpio: Select video/command mode of panel through gpio when it supports both modes.
int disp_te_gpio_requested;
int bklt_ctrl; /* backlight ctrl 背光类型*/
int pwm_period;
int pwm_pmic_gpio;
int pwm_lpg_chan;
int bklt_max;
int new_fps;
int pwm_enabled;
bool dmap_iommu_map;
struct pwm_device *pwm_bl;
struct dsi_drv_cm_data shared_pdata;
u32 pclk_rate;
u32 byte_clk_rate;
struct dss_module_power power_data; // ★ clock & regulator
u32 dsi_irq_mask;
struct mdss_hw *dsi_hw;
struct mdss_panel_recovery *recovery; struct dsi_panel_cmds on_cmds; // light on cmd ★ qcom,mdss-dsi-on-command struct dsi_panel_cmds off_cmds; // off cmd ★ qcom,mdss-dsi-off-command
struct dsi_panel_cmds status_cmds;
u32 status_value; struct dsi_panel_cmds video2cmd;
struct dsi_panel_cmds cmd2video; struct dcs_cmd_list cmdlist;
struct completion dma_comp;
struct completion mdp_comp;
struct completion video_comp;
struct completion bta_comp;
spinlock_t irq_lock;
spinlock_t mdp_lock;
int mdp_busy;
struct mutex mutex;
struct mutex cmd_mutex; bool ulps; struct dsi_buf tx_buf;
struct dsi_buf rx_buf;
struct dsi_buf status_buf;
int status_mode;
};

struct mdss_panel_info结构体

struct mdss_panel_info {
u32 xres; // x 分辨率 qcom,mdss-dsi-panel-width
u32 yres; // y 分辨率 qcom,mdss-dsi-panel-height
u32 physical_width; // x 物理大小 qcom,mdss-pan-physical-width-dimension
u32 physical_height; // y 物理大小 qcom,mdss-pan-physical-height-dimension
struct lcd_panel_info lcdc; // 边界 (1.1)边界
u32 bpp; // bpp qcom,mdss-dsi-bpp
struct mipi_panel_info mipi; // mipi显示模式 video or cmd (1.2)mipi u32 type;
u32 wait_cycle;
u32 pdest; // 第几个fb设备 qcom,mdss-dsi-panel-destination = "display_1";
u32 brightness_max;
u32 bl_max;
u32 bl_min;
u32 fb_num;
u32 clk_rate;
u32 clk_min;
u32 clk_max;
u32 frame_count;
u32 is_3d_panel;
u32 out_format;
u32 rst_seq[MDSS_DSI_RST_SEQ_LEN];
...
}

(1.1)边界

struct lcd_panel_info {
u32 h_back_porch;
u32 h_front_porch;
u32 h_pulse_width;
u32 v_back_porch;
u32 v_front_porch;
u32 v_pulse_width;
u32 border_clr;
u32 underflow_clr;
u32 hsync_skew;
/* Pad width */
u32 xres_pad; // qcom,mdss-dsi-h-left-border
/* Pad height */
u32 yres_pad; // qcom,mdss-dsi-h-right-border
};

(1.2)mipi

struct mipi_panel_info {
char mode; /* video/cmd */ // 显示模式 qcom,mdss-dsi-panel-type = "dsi_video_mode";
char interleave_mode;
char crc_check;
char ecc_check;
char dst_format; /* shared by video and command */
char data_lane0;
char data_lane1;
char data_lane2;
char data_lane3;
char dlane_swap; /* data lane swap */
char rgb_swap;
char b_sel;
char g_sel;
char r_sel;
char rx_eot_ignore;
char tx_eot_append;
char t_clk_post; /* 0xc0, DSI_CLKOUT_TIMING_CTRL */
char t_clk_pre; /* 0xc0, DSI_CLKOUT_TIMING_CTRL */
char vc; /* virtual channel */
struct mdss_dsi_phy_ctrl dsi_phy_db;
/* video mode */
char pulse_mode_hsa_he;
char hfp_power_stop;
char hbp_power_stop;
char hsa_power_stop;
char eof_bllp_power_stop;
char last_line_interleave_en;
char bllp_power_stop;
char traffic_mode;
char frame_rate;
/* command mode */
char interleave_max;
char insert_dcs_cmd;
char wr_mem_continue;
char wr_mem_start;
char te_sel;
char stream; /* 0 or 1 */
char mdp_trigger;
char dma_trigger;
/*Dynamic Switch Support*/
bool dynamic_switch_enabled;
u32 pixel_packing;
u32 dsi_pclk_rate;
/* The packet-size should not bet changed */
char no_max_pkt_size;
/* Clock required during LP commands */
char force_clk_lane_hs; //强制DSI_CLK始终处于HS,因我们用DSI CLK as 参考时钟 char vsync_enable;
char hw_vsync_mode; char lp11_init;
u32 init_delay;
};

5.结构赋值

//结构从设备数中获取数据赋值     mdss_dsi_panel.c
int mdss_dsi_panel_init(struct device_node *node,struct mdss_dsi_ctrl_pdata *ctrl_pdata, int ndx)
// use
Dsi_host_v2.c (drivers\video\msm\mdss):
rc = mdss_dsi_panel_init(dsi_pan_node, ctrl_pdata, cmd_cfg_cont_splash);
Mdss_dsi.c (drivers\video\msm\mdss):
rc = mdss_dsi_panel_init(dsi_pan_node, ctrl_pdata, ndx);

6.lk中传递lcm使用的dsi配置名字给kernel

aboot_init                           // lk\app\aboot\aboot.c
target_display_init // lk\target\msm8953\target_display.c
gcdb_display_init // lk\dev\gcdb\display\gcdb_display.c
msm_display_init // display.c
display_image_on_screen // aboot_init // lk\app\aboot\aboot.c
target_display_init // lk\target\msm8953\target_display.c
gcdb_display_init // lk\dev\gcdb\display\gcdb_display.c
oem_panel_select // lk\target\msm8953\oem_panel.c panel_id = NT51021B_INX_WUXGA_VIDEO_PANEL; // ☆ panel_id 赋值,使用哪个lcd配置 init_panel_data switch (panel_id) {
case NT51021B_INX_WUXGA_VIDEO_PANEL:
panelstruct->paneldata = &nt51021b_inx_wuxga_video_panel_data; // 根据 panel_id 指定传给kernel使用的lcm配置 ----------
// lk\dev\gcdb\display\include\panel_nt51021b_inx_wuxga_video.h (lcm配置文件) static struct panel_config nt51021b_inx_wuxga_video_panel_data = {
"qcom,mdss_dsi_nt51021b_inx_wuxga_video", // ☆ panel_node_id 对应dtsi中 panel使用的名字
"dsi:0:", "qcom,mdss-dsi-panel",
10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 1, 10000, 0, 0, 0, 0, 0, 0, NULL
};
----------
// arch\arm64\boot\dts\qcom\dsi-panel-nt51021b-inx-wuxga-video.dtsi
&mdss_mdp {
dsi_nt51021b_inx_wuxga_vid: qcom,mdss_dsi_nt51021b_inx_wuxga_video {//dts中的 panel名字
qcom,mdss-dsi-panel-name = "nt51021b inx wuxga video mode dsi panel"; /

6.1 dts中command格式解析

qcom,mdss-dsi-on-command = [
// 延时 reg data
29 01 00 00 01 00 02 8F A5
29 01 00 00 14 00 02 01 00
29 01 00 00 01 00 02 8F A5
29 01 00 00 00 00 02 8C 80
29 01 00 00 00 00 02 C7 50
29 01 00 00 00 00 02 C5 50
29 01 00 00 00 00 02 85 04
29 01 00 00 00 00 02 86 08
29 01 00 00 00 00 02 83 AA
29 01 00 00 00 00 02 84 11
29 01 00 00 00 00 02 A0 36
29 01 00 00 00 00 02 A1 36
29 01 00 00 00 00 02 9C 10
29 01 00 00 00 00 02 A9 4B
29 01 00 00 00 00 02 8F 00];

7. fb旋转参数配置

7.1 方法1

fb_info->var->rotate                             // 是否旋转

7.2 方法2

msm_fb_data_type->panel_orientation                  //是否旋转fb   (mdss_fb.h)

// 通过dsi中的 qcom,mdss-dsi-panel-orientation 关键字控制  (mdss_dsi_panel.c)
data = of_get_property(np, "qcom,mdss-dsi-panel-orientation", NULL);
if (data) {
pr_debug("panel orientation is %s\n", data);
if (!strcmp(data, "180"))
pinfo->panel_orientation = MDP_ROT_180;
else if (!strcmp(data, "hflip"))
pinfo->panel_orientation = MDP_FLIP_LR;
else if (!strcmp(data, "vflip"))
pinfo->panel_orientation = MDP_FLIP_UD;
}

7.3 方法三

system/build.prop

8.展频

mdss-pll.c
展频开关:
arch/arm/boot/dts/qcom/msm8953-mdss-pll.dtsi qcom,dsi-pll-ssc-en;
mode:
qcom,dsi-pll-ssc-mode = "down-spread"; two parameters to program SSC : clk/msm/mdss/mdss-dsi-pll-8996.c:ssc_ppm_default & ssc_freq_default 展频范围: down mode : freq - freq * (ssc_ppm/1000,000) center mode : freq ± freq * (ssc_ppm/1000,000) / 2 up mode : freq + freq * (ssc_ppm/1000,000)

9. bklt_en_gpio、 disp_en_gpio、 rst_gpio相关gpio口

// (msm8917-pmi8937-qrd-sku5.dtsi  board.dtsi )   mdss_dsi_active   mdss_dsi_suspend  qcom,platform-reset-gpio  qcom,platform-enable-gpio
&mdss_dsi0 {
qcom,dsi-pref-prim-pan = <&dsi_hx8394f_720p_video>;
pinctrl-names = "mdss_default", "mdss_sleep";
pinctrl-0 = <&mdss_dsi_active>;
pinctrl-1 = <&mdss_dsi_suspend>; qcom,platform-reset-gpio = <&tlmm 60 0>; // rst
qcom,platform-enable-gpio= <&tlmm 46 0>; //供电引脚
}; //(mdss_dsi.c) disp_en_gpio bklt_en_gpio rst_gpio
// mdss_dsi_parse_gpio_params
ctrl_pdata->disp_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,"qcom,platform-enable-gpio", 0);
ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,"qcom,platform-te-gpio", 0);
ctrl_pdata->bklt_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,"qcom,platform-bklight-en-gpio", 0);
ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,"qcom,platform-reset-gpio", 0);
ctrl_pdata->mode_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,"qcom,platform-mode-gpio", 0); // mdss_dsi_panel_power_on
mdss_dsi_panel_reset(pdata, 1); // (mdss_dsi_panel.c)
gpio_set_value((ctrl_pdata->bklt_en_gpio), 0);
gpio_set_value((ctrl_pdata->disp_en_gpio), 0);
gpio_set_value((ctrl_pdata->rst_gpio), 0); // mdss_dsi_panel_power_off
mdss_dsi_panel_reset(pdata, 0); // (mdss_dsi_panel.c)
gpio_set_value((ctrl_pdata->bklt_en_gpio), 0);
gpio_set_value((ctrl_pdata->disp_en_gpio), 0);
gpio_set_value((ctrl_pdata->rst_gpio), 0);
// (msm8917-pinctrl.dtsi) pmx_mdss: pmx_mdss {
mdss_dsi_active: mdss_dsi_active {
mux {
pins = "gpio60", "gpio46";
function = "gpio";
}; config {
pins = "gpio60", "gpio46";
drive-strength = <8>; /* 8 mA */
bias-disable = <0>; /* no pull */
// output-high;
};
};
mdss_dsi_suspend: mdss_dsi_suspend {
mux {
pins = "gpio60", "gpio46";
function = "gpio";
}; config {
pins = "gpio60", "gpio46";
drive-strength = <2>; /* 2 mA */
bias-pull-down; /* pull down */
};
};

10. esd功能

qcom,esd-check-enabled                      // 是否使用esd check 功能
qcom,mdss-dsi-panel-status-check-mode // esd check的方式 te_signal_check (只能在cmd模式下用)or reg_read

10.1 cmd mode demo

qcom,mdss-dsi-te-pin-select = <1>;
qcom,mdss-dsi-te-v-sync-rd-ptr-irq-line = <0x2c>;
qcom,mdss-dsi-te-v-sync-continue-lines = <0x3c>;
qcom,mdss-dsi-te-dcs-command = <1>;
qcom,esd-check-enabled; // enable esd check
qcom,mdss-dsi-panel-status-check-mode = "te_signal_check"; // esd check mode te模式 (只能用作cmd模式)
qcom,mdss-dsi-te-check-enable; // te
qcom,mdss-dsi-te-using-te-pin; // use te pin

10.2 video mode demo

qcom,esd-check-enabled;
qcom,mdss-dsi-panel-status-check-mode = "reg_read";
qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 02 0A 08];
qcom,mdss-dsi-panel-status-command-state = "dsi_lp_mode";
qcom,mdss-dsi-panel-status-read-length = <1>;
qcom,mdss-dsi-panel-max-error-count = <2>;
qcom,mdss-dsi-panel-status-value = <0x9c>;

高通 display 驱动【转】的更多相关文章

  1. 高通LCD驱动调试

    本文转载自:http://www.itgo.me/a/x6305658852004979994/lcd%20qcom 来自 :http://blog.csdn.net/dacaozuo/article ...

  2. 高通Camera驱动分析【转】

    本文转载自:http://blog.csdn.net/liwei16611/article/details/53955711 1.Sensor slave配置 结构体msm_camera_sensor ...

  3. 高通GPIO驱动(DTS方式)

    gpio调试的方式有很多,linux3.0以上ARM架构的处理器基本上都采用了DTS的方式,在linux3.0可以通过获取sysfs的方式来获取gpio状态: sysfs文件系统的建立可以参照下面的博 ...

  4. 小米手机(HM1SW)高通开发android程序全过程

    小米手机(HM1SW)开发android程序全过程 修改历史: 2016年5月9日  --------  整理文档 a.增加了手机基本信息. b.增加360手机助手连接说明 2016年2月26日  - ...

  5. 高通Android display架构分析

    目录(?)[-] Kernel Space Display架构介绍 函数和数据结构介绍 函数和数据结构介绍 函数和数据结构介绍 数据流分析 初始化过程分析 User Space display接口 K ...

  6. 高通Android display分析【转】

    本文转载自:http://blog.csdn.net/zhangchiytu/article/details/6777039 高通7系列硬件架构分析 如上图,高通7系列 Display的硬件部分主要由 ...

  7. 高通ASOC中的machine驱动

    ASoC被分为Machine.Platform和Codec三大部分,其中的Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的代码,再次引用上一节的内容:Machin ...

  8. 高通ASOC中的codec驱动

    ASOC的出现是为了让codec独立于CPU,减少和CPU之间的耦合,这样同一个codec驱动就无需修改就可以匹配任何一款平台. 在Machine中已经知道,snd_soc_dai_link结构就指明 ...

  9. linux驱动由浅入深系列:PBL-SBL1-(bootloader)LK-Android启动过程详解之一(高通MSM8953启动实例)

    转自:http://blog.csdn.net/radianceblau/article/details/73229005 http://www.aiuxian.com/article/p-14142 ...

随机推荐

  1. linux-centos使用 wget命令获取jdk

    1, 首先去官网看下地址是否变化了 2, 然后输入以下命令即可 wget --no-check-certificate --no-cookies --header "Cookie: orac ...

  2. Prim Algoritm(最小生成树)

    Prim Algorithm.这个算法可以分为下面几个步骤: 将顶点集V分成两个集合A和B,其中集合A表示目前已经在MST中的顶点,而集合B则表示目前不在MST中的顶点. 在B寻找与集合A连通的最短的 ...

  3. SpringBoot入门 (十一) 数据校验

    本文记录学习在SpringBoot中做数据校验. 一 什么是数据校验 数据校验就是在应用程序中,对输入进来得数据做语义分析判断,阻挡不符合规则得数据,放行符合规则得数据,以确保被保存得数据符合我们得数 ...

  4. php功底你修炼到哪一级

    第一阶段:基础阶段(基础PHP程序员) 重点:把LNMP搞熟练(核心是安装配置基本操作) 目标:能够完成基本的LNMP系统安装,简单配置维护:能够做基本的简单系统的PHP开发:能够在PHP中型系统中支 ...

  5. SpringMVC源码阅读:属性编辑器、数据绑定

    1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将通过源码(基于Spring ...

  6. Windows Live Writer 2012离线发布WP文章教程

    1. WLW简介 Windows Live Writer是一款微软开发的文章离线发布软件,对博客文章的排版类似Word操作,比普通的HTML编辑器更强大的是其离线发布功能.支持新浪博客.网易博客.博客 ...

  7. 深入出不来nodejs源码-events模块

    这一节内容超级简单,纯JS,就当给自己放个假了,V8引擎和node的C++代码看得有点脑阔疼. 学过DOM的应该都知道一个API,叫addeventlistener,即事件绑定.这个东西贯穿了整个JS ...

  8. Excel核心技巧【干货】

    进入职场后发现,几乎有很大一部分时间都耗在了表格上. Excel的存在是为了更高效工作,但庞大的数据处理却成了你每晚加班的“凶手”? 其实,从数据整理到数据分析,只要掌握20%的Excel技巧,就足以 ...

  9. 撩课-Web架构师养成系列第一篇

    前言 Web架构师养成系列共15篇,每周更新一篇,主要分享.探讨目前大前端领域(前端.后端.移动端)企业中正在用的各种成熟的.新的技术.部分文章也会分析一些框架的底层实现,让我们做到知其然知其所以然. ...

  10. Spring是什么 包括SpringBean SpringMVC SpringBoot SpringCloud

    什么是Spring:spring是个开源框架,spring mvc是基于spring的一个mvc框架,spring boot是基于spring4的条件注册的一套快速开发整合包. Spring两大特征: ...