0.關鍵字
MDSS : 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 (核心層)
(2)drivers\video\msm\mdss\mdss_fb.c (mdss 核心層 fbx平台裝置驅動)
(4)msm8610-mdss.dtsi (檔案名通常為 msmxxx-mdss.dtsi 指定了mdss 的 mdp 和 dsi)
mdss_mdp: qcom,mdss_mdp@fd900000 {
compatible = "qcom,mdss_mdp3"; // 對應mdss驅動 mdss_mdp.c
----------
mdss_dsi0: qcom,mdss_dsi@fdd00000 {
compatible = "qcom,msm-dsi-v2"; // 對應dsi解析驅動 dsi_host_v2.c
或者
mdss_dsi0: qcom,mdss_dsi_ctrl@1a94000 {
compatible = "qcom,mdss-dsi-ctrl"; // 對應dsi解析驅動 mdss_dsi.c
(3)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
(5)drivers\video\msm\mdss\mdp3.c (mdp)
.compatible = "qcom,mdss_mdp3",
(6)msm8610-asus.dts (指定mdp中的哪一個配置)
通常在dts檔案的 mdss_dsi0 lab裡面通過 qcom,dsi-pref-prim-pan 屬性 指定使用哪一個lcd配置
&mdss_dsi0 {
qcom,dsi-pref-prim-pan = <&dsi_fl10802_fwvga_vid>;
};
(7)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.時序圖
http://download.csdn.net/detail/u012719256/9603691
畫的有點渣,湊活看吧,不要在意細節
4. 重要結構
結構關系
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"; // 對應 sys/class/graphic/fb0/panl_info 中的資訊
6.dts中command格式解析
qcom,mdss-dsi-on-command = [
// 延時 reg data
F A5
F A5
C
C7
C5
AA
A0
A1
C
A9 B
F ];
7.fb旋轉參數配置
(1) 方法1
(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;
}
(3)方法三
system/build.prop
+ ro.panel.mountflip=3
frameworks/native/services/surfaceflinger/DisplayDevice.cpp
DisplayDevice::DisplayDevice
// 1: H-Flip, 2: V-Flip, 3: 180 (HV Flip)
property_get("ro.panel.mountflip", property, "0");
mPanelMountFlip = atoi(property);
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-c:ssc_ppm_default & ssc_freq_default
展頻範圍:
down mode : freq - freq * (ssc_ppm/,)
center mode : freq ± freq * (ssc_ppm/,) /
up mode : freq + freq * (ssc_ppm/,)
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- = <&mdss_dsi_active>;
pinctrl- = <&mdss_dsi_suspend>;
qcom,platform-reset-gpio = <&tlmm >; // rst
qcom,platform-enable-gpio= <&tlmm >; //供電引腳
};
//(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", );
ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,"qcom,platform-te-gpio", );
ctrl_pdata->bklt_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,"qcom,platform-bklight-en-gpio", );
ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,"qcom,platform-reset-gpio", );
ctrl_pdata->mode_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,"qcom,platform-mode-gpio", );
// mdss_dsi_panel_power_on
mdss_dsi_panel_reset(pdata, ); // (mdss_dsi_panel.c)
gpio_set_value((ctrl_pdata->bklt_en_gpio), );
gpio_set_value((ctrl_pdata->disp_en_gpio), );
gpio_set_value((ctrl_pdata->rst_gpio), );
// mdss_dsi_panel_power_off
mdss_dsi_panel_reset(pdata, ); // (mdss_dsi_panel.c)
gpio_set_value((ctrl_pdata->bklt_en_gpio), );
gpio_set_value((ctrl_pdata->disp_en_gpio), );
gpio_set_value((ctrl_pdata->rst_gpio), );
// (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 mA */
bias-disable = <>; /* no pull */
// output-high;
};
};
mdss_dsi_suspend: mdss_dsi_suspend {
mux {
pins = "gpio60", "gpio46";
function = "gpio";
};
config {
pins = "gpio60", "gpio46";
drive-strength = <>; /* 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 = <>;
qcom,mdss-dsi-te-v-sync-rd-ptr-irq-line = <>;
qcom,mdss-dsi-te-v-sync-continue-lines = <>;
qcom,mdss-dsi-te-dcs-command = <>;
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 = [ A ];
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>;