热门内容

公众号"MAKE1"

获取行业最新资讯

请扫码添加

专业客服企业微信

MIPI LCD CMD模式和VIDEO模式驱动代码分析

简介

Android驱动开发 MIPI LCD CMD模式和VIDEO模式驱动代码分析

目前MIPI 控制器支持CMD 模式和VIDEO 模式,对于新增LCD 屏的配置如下:

文件路径:arch/arm/plat-lc/drivers/video/comipfb2

新增文件名称:lcd_xxx_sss.c (xxx: 屏厂名称;sss:IC 厂名称)

(1)所需结构体介绍:

struct comipfb_dev

struct comipfb_dev {

const char* name; /* Device name. */

unsigned int interface_info;//interface infomation MIPI or RGB

unsigned int lcd_id;

unsigned int refresh_en; /* Refresh enable. */

unsigned int pclk; /* Pixel clock in HZ. */

unsigned int bpp; /* Bits per pixel. */

unsigned int xres; /* Device resolution. */

unsigned int yres;

unsigned int width; /* Width of device in mm. */

unsigned int height; /* Height of device in mm. */

unsigned int flags; /* Device flags. */

union {

//struct comipfb_dev_timing_rgb rgb;

struct comipfb_dev_timing_mipi mipi;

} timing;

struct comipfb_dev_cmds cmds_init;

struct comipfb_dev_cmds cmds_suspend;

struct comipfb_dev_cmds cmds_resume;

struct comipfb_dev_cmds esd_cmd;

struct comipfb_dev_cmds esd_rsp;

struct bl_cmds backlight_info;

int (*reset)(struct comipfb_info *fbi);

int (*suspend)(struct comipfb_info *fbi);

int (*resume)(struct comipfb_info *fbi);

};

Name:lcd 设备名称。

Interface_info:屏使用接口信息。一般固定为COMIPFB_MIPI_IF。

Lcd_id:LCD 当同一块单板上使用两款以上的屏时,需要设置该成员。

Refresh_en:自刷新使能。一般Video 模式需要打开自刷新功能;

Pclk:像素时钟频率。该时钟需要满足如下公式:

pclk = pll1_out / (div +1) / 8 * (grp +1);其中pll1_out 默认为1248Mhz,div 和grp 为

寄存器AP_PWR_LCDC0CLK_CTL 中相应字段;

Bpp:像素深度,表示每个像素用多少个bit 位来存储,根据输入的像素格式进行配置,

一般固定为32。

Xres:显示宽度,以像素为单位。

Yres:显示高度,以像素为单位。

Width:屏幕宽度,单位为mm,目前没有设置。

Hight:屏幕高度,单位为mm,目前没有设置。

Cmds_int:初始化命令参数结构。命令的结构为:对于长包而言(命令+参数 > 2 的

包):{Delay,命令模式,命令的类型,总长度,命令及其参数的长度,命令,参数};

对于短包而言:{Delay,命令模式,命令的类型,命令及其参数的长度,命令,参数}

Cmds_suspend:睡眠命令参数结构。

Cmds_resume:唤醒命令参数结构。

esd_cmd:如果单板支持ESD 功能,该命令指向ESD 功能发送命令数组。

esd_rsp:如果单板支持ESD 功能,该命令指向ESD 功能返回命令数组。

backlight_info:如果单板的背光调节采用CABC 技术,则该数据结构设定有效,其

指向的数组代表调节背光的命令及参数,这个数据结构中包含有名为brightness_bit 的成

员变量,他表示设置的亮度值在MIPI CMD 命令的第几个字节。

reset、resume、suspend:抽象接口函数指针,驱动通过这三个函数指针访问对应的

屏的功能函数。

 

struct comipfb_dev_timing_mipi

struct comipfb_dev_timing_mipi {

unsigned int hs_freq; /*PHY output freq, bytes KHZ*/

unsigned int lp_freq; /*default is 10MHZ*/

unsigned int no_lanes; /*lane numbers*/

unsigned int display_mode; //video mode or command mode.

unsigned int auto_stop_clklane_en;

unsigned int im_pin_val;

struct mipi_color_bits color_mode; /*color bits*/

struct video_mode_info videomode_info;

struct command_mode_info commandmode_info;

struct phy_time_info phytime_info;

struct te_info teinfo;

struct external_info ext_info;

};

Hs_freq:每条Lane 的PHY 的高速时钟频率,以Kbytes 为单位。需要满足一下公式:

hs_freq/8 = phy_ref_freq * loop_divider * 1.0 / input_divider;其中hs_freq 为26Mhz;

Lp_freq:以KHz 为单位,表示MIPI 接口Lane0 的PHY 低速时钟频率,默认值为

10MHz。建议由hs_freq 整数倍分频得到,必须小于20Mhz;

No_lanes:lane 个数。

Auto_stop_clklane_en:clklane 自动停止使能。

Im_pin_val:VIDE/CMD 模式选择pin 脚值。该引脚一般不会使用;

Color_mode:MIPI 接口输出像素格式定义;

Videoomde_info:VIDEO 模式信息。

Commandmode_info:CMD 模式信息。

Phytime_info:PHY 时序相关信息。

Teinfo:te 相关信息。

Ext_info:扩展信息。

struct mipi_color_bits

struct mipi_color_bits {

unsigned int color_bits; // must be set !!

unsigned int is_18bit_loosely; // optional

};

color_bits:MIPI 要传输的像素bit 位数。目前一般采用COLOR_CODE_24BIT,表

示RGB888。

is_18bit_loosely:只对每个pixel 用18bits 表示有效,表示使能 18 位的loosely packet

pixel stream。

struct video_mode_info

struct video_mode_info {

unsigned int hsync; /* Horizontal Synchronization, unit : pclk. */

unsigned int hbp; /* Horizontal Back Porch, unit : pclk. */

unsigned int hfp; /* Horizontal Front Porch, unit : pclk. */

unsigned int vsync; /* Vertical Synchronization, unit : line. */

unsigned int vbp; /* Vertical Back Porch, unit : line. */

unsigned int vfp; /* Vertical Front Porch, unit : line. */

unsigned int hs_pol:1; /* lcdc hs pol 1 is high for lcdc , is low for mipi*/

unsigned int vs_pol:1; /* lcdc vs pol 1 is high for lcdc, is low for mipi*/

unsigned int dataen_pol:1; /* lcdc has not this bit, mipi dataen ,use default value

currently: 1 low activate*/

unsigned int lp_cmd_en:1;

unsigned int frame_bta_ack:1;

unsigned int lp_hfp_en:1; // default should be 1

unsigned int lp_hbp_en:1;

unsigned int lp_vact_en:1;

unsigned int lp_vfp_en:1;

unsigned int lp_vbp_en:1;

unsigned int lp_vsa_en:1;

dsih_video_mode_t mipi_trans_type; /* burst or no burst*/

};

这个结构体表示VIDEO 模式LCD 的配置信息:

Hsync:行同步信号。

Hbp:行后porch。

Hfp:行前porch。

Vsync:列同步信号。

Vbp:列后porch。

Vfp:列前porch。

Hs_pol:行同步的有效极性。

Vs_pol:列同步的有效极性。

Dataen_pol:数据使能信号有效极性。

Lp_cmd_en:在传输数据过程中,用LP 模式发送数据使能位。

Frame_bta_ack:MIPI 一帧数据传输结束响应使能位。

Lp_hfp_en:hfp 在HS 传输空闲时进行LP 状态使能位。

Lp_hbp_en:hbp 在HS 传输空闲时进行LP 状态使能位。

Lp_vact_en:vact 在HS 传输空闲时进行LP 状态使能位。

Lp_vfp_en:vfp 在HS 传输空闲时进行LP 状态使能位。

Lp_vbp_en:vbp 在HS 传输空闲时进行LP 状态使能位。

Lp_vsa_en:vsa 在HS 传输空闲时进行LP 状态使能位。

Mipi_trans_type:MIPI 传输方式选择。

struct command_mode_info

struct command_mode_info {

unsigned int tear_fx_en:1;

unsigned int ack_rqst_en:1;

unsigned int gen_sw_0p_tx:1; // default should be 1

unsigned int gen_sw_1p_tx:1; // default should be 1

unsigned int gen_sw_2p_tx:1; // default should be 1

unsigned int gen_sr_0p_tx:1; // default should be 1

unsigned int gen_sr_1p_tx:1; // default should be 1

unsigned int gen_sr_2p_tx:1; // default should be 1

unsigned int gen_lw_tx:1; // default should be 1

unsigned int dcs_sw_0p_tx:1; // default should be 1

unsigned int dcs_sw_1p_tx:1; // default should be 1

unsigned int dcs_sr_0p_tx:1; // default should be 1

unsigned int dcs_lw_tx:1; // default should be 1

unsigned int max_rd_pkt_size:1; // default should be 1

struct rw_timeout timeout;

};

Tear_fx_en:TE 响应使能位。

Ack_rqst_en:每个数据包传输结束后响应。

Gen_sw_0p_tx:GEN 短包命令以LP 模式进行写使能。

Gen_sw_1p_tx:GEN 短包命令以LP 模式进行写使能。

Gen_sw_2p_tx:GEN 短包命令以LP 模式进行写使能。

Gen_sr_0p_tx:GEN 短包命令以LP 模式进行读使能。

Gen_sr_1p_tx:GEN 短包命令以LP 模式进行读使能。

Gen_sr_2p_tx:GEN 短包命令以LP 模式进行读使能。

Gen_lw_tx:GEN 长包命令以LP 模式进行写使能。

Dcs_sw_0p_tx:DCS 短包命令以LP 模式进行写使能。

Dcs_sw_1p_tx:DCS 短包命令以LP 模式进行写使能。

Dcs_sr_0p_tx:DCS 短包命令以LP 模式进行读使能。

Dcs_lw_tx:DCS 长包命令以LP 模式进行读使能。

Max_rd_pkt_size:读包长度命令以LP 模式进行发送使能。

struct rw_timeout

struct rw_timeout {

unsigned int hs_rd_to_cnt;

unsigned int lp_rd_to_cnt;

unsigned int hs_wr_to_cnt;

unsigned int lp_wr_to_cnt;

unsigned int bta_to_cnt;

};

这个结构表示控制器发送相关请求后的等待超时时间。仅用于command 模式;

hs_rd_to_cnt:在发送完高速读操作指令后的等待时间,以lanebyteclk 为单位。

当DPHY 进入 stop state (LP11)时开始计时。

lp_rd_to_cnt:在发送完低功耗读操作指令后的等待时间,以lanebyteclk 为单位。

当DPHY 进入stop state(LP11)时开始计时。

hs_wr_to_cnt:在发送完高速写操作后的等待时间,以lanebyteclk 为单位。当

DPHY 进入stop state 时开始计时。

lp_wr_to_cnt:在发送完低功耗写操作后的等待时间,以lanebyteclk 为单位。当

DPHY 进入stopstate 时开始计时。

bta_to_cnt:在完成一次BTA 操作后的等待时间,以lanebyteclk 为单位。当DPHY

进入stop state 时开始计时。

这几个参数的值一般从屏厂家获取,当屏显示异常时,可能需要进行一定的调整。

struct phy_time_info

struct phy_time_info {

unsigned char lpx;

//unsigned char clk_lpx;

unsigned char clk_tprepare;

unsigned char clk_hs_zero;

unsigned char clk_hs_trail;

unsigned char clk_hs_exit;

unsigned char clk_hs_post;

//unsigned char data_lpx;

unsigned char data_tprepare;

unsigned char data_hs_zero;

unsigned char data_hs_trail;

unsigned char data_hs_exit;

unsigned char data_hs_post;

}

这个结构体是用来配置和调整PHY 的时序参数的,这部分是比较深层次的配置,一般

来说,采用默认值在大多数情况下都能正常工作;这部分参数不需要用户设置,驱动中均

采用默认值;

lpx:这是DSI_DATA 或者DSI_CLK 在进高速模式时LP-01 的时间长度。

clk_tprepare/ data_tprepare:表示在进高速模式时LP-00 的时间长度,以lanebyte 为单

位。

clk_hs_zero/ data_hs_zero:表示进高速模式LP-00 之后HS-0 的时间长度,以lanebyte

为单位。

clk_hs_trail,clk_hs_exit,clk_hs_post,data_hs_trail,data_hs_exit,data_hs_post:这几

个成员的含义也是代表进出高速模式的一些时间配置,这几个值在目前的驱动中不支持配

置。

struct te_info

struct te_info {

unsigned int te_source;

unsigned int te_trigger_mode;

unsigned int te_en;

unsigned int te_sync_en; // In command mode should set 1, video should set 0

};

Te_source:te 信号源。为1 表示外部信号,也就是通常意义上的通过LCD 模组的

TE 引脚输入,使用芯片外部管脚输入的TE 信号。为0 表示采用内部信号,即使用DSI

控制器输出的TE 信号。

Te_trigger_mode:te 外部信号源触发模式。0:当有上升沿时触发TE 同步,1:当有

大于 1000us 宽度高电平时触发TE 同步。通常这个位置0,上升沿触发。

Te_en:te 功能使能。表示使用TE 接收功能,对于COMMAND 模式,一般需要使

能TE 功能,用来同步图像数据传输。

Te_sync_en:start 信号与te 信号同步使能。在COMMAND 模式下时选择是否使能

TEAR_EFFECT 同步。

struct external_info

struct external_info {

unsigned char crc_rx_en:1;

unsigned char ecc_rx_en:1;

unsigned char eotp_rx_en:1;

unsigned char eotp_tx_en:1;

unsigned int dev_read_time; //HSBYTECLK is danwe

};

Crc_rx_en:读CRC 校验使能。

Ecc_rx_en:读ECC 校验使能。

Eotp_rx_en:读EOTP 使能。

Eotp_tx_en:写EOTP 使能。

Dev_read_time:屏返回数据所需时间。

 

(2)对于VIDEO 模式,配置举例如下,红色部分是需要修改之处:

struct comipfb_dev lcd_zetrax_8009a_dev = {

.name = "lcd_zetrax_otm8009a",

.interface_info = COMIPFB_MIPI_IF,

.lcd_id = 0,

.refresh_en = 1,

.bpp = 32,

.xres = 480,

.yres = 854,

.flags = 0,

.pclk = 31000000,//28000000

.timing = {

.mipi = {

.hs_freq = 52500, //Kbyte

.lp_freq = 15000, //KHZ

.no_lanes = 2,

.display_mode = MIPI_VIDEO_MODE,

.auto_stop_clklane_en = 0,

.im_pin_val = 1,

.color_mode = {

.color_bits = COLOR_CODE_24BIT,

.is_18bit_loosely = 0,

},

.videomode_info = {

.hsync = 4,

.hbp = 36,

.hfp = 34,

.vsync = 2,

.vbp = 20,

.vfp = 21,

.lp_cmd_en = 1,

.frame_bta_ack = 0,

.lp_hfp_en = 1,

.lp_hbp_en = 1,

.lp_vact_en = 1,

.lp_vfp_en = 1,

.lp_vbp_en = 1,

.lp_vsa_en = 1,

.mipi_trans_type

VIDEO_BURST_WITH_SYNC_PULSES,

},

.phytime_info = {

.clk_tprepare = 3, //HSBYTECLK

},

.teinfo = {

.te_source = 1, //external signal

.te_trigger_mode = 0,

.te_en = 0,

.te_sync_en = 0,

},

.ext_info = {

.eotp_tx_en = 0,

},

},

},

.cmds_init = {ARRAY_AND_SIZE(lcd_cmds_init)},

.cmds_suspend = {ARRAY_AND_SIZE(lcd_cmds_suspend)},

.cmds_resume = {ARRAY_AND_SIZE(lcd_cmds_resume)},

.reset = lcd_zetrax_8009a_reset,

.suspend = lcd_zetrax_8009a_suspend,

.resume = lcd_zetrax_8009a_resume,

.backlight_info = {ARRAY_AND_SIZE(backlight_cmds),

.brightness_bit = 8,

},

};

(3)对于CMD 模式,配置举例如下,红色部分是需要修改之处:

struct comipfb_dev lcd_zetrax_8009a_dev = {

.name = "lcd_zetrax_otm8009a",

.interface_info = COMIPFB_MIPI_IF,

.lcd_id = 0,

.refresh_en = 0,

.bpp = 32,

.xres = 480,

.yres = 854,

.flags = 0,

.pclk = 31000000,//28000000

.timing = {

.mipi = {

.hs_freq = 52500, //Kbyte

.lp_freq = 15000, //KHZ

.no_lanes = 2,

.display_mode = MIPI_COMMAND_MODE,

.auto_stop_clklane_en = 0,

.im_pin_val = 1,

.color_mode = {

.color_bits = COLOR_CODE_24BIT,

.is_18bit_loosely = 0,

},

.commandmode_info = {

.tear_fx_en = 1,

.ack_rqst_en = 0,

.gen_sw_0p_tx = 1,

.gen_sw_1p_tx = 1,

.gen_sw_2p_tx = 1,

.gen_sr_0p_tx = 1,

.gen_sr_1p_tx = 1,

.gen_sr_2p_tx = 1,

.gen_lw_tx = 1,

.dcs_sw_0p_tx = 1,

.dcs_sw_1p_tx = 1,

.dcs_sr_0p_tx = 1,

.dcs_lw_tx = 1,

.max_rd_pkt_size = 1,

.timeout = {

.hs_rd_to_cnt = 0,

.lp_rd_to_cnt = 0,

.hs_wr_to_cnt = 20,

.lp_wr_to_cnt = 20,

.bta_to_cnt = 100,

},

},

.phytime_info = {

.clk_tprepare = 3, //HSBYTECLK

},

.teinfo = {

.te_source = 1, //external signal

.te_trigger_mode = 0,

.te_en = 1,

.te_sync_en = 1,

},

.ext_info = {

.eotp_tx_en = 0,

},

},

},

.cmds_init = {ARRAY_AND_SIZE(lcd_cmds_init)},

.cmds_suspend = {ARRAY_AND_SIZE(lcd_cmds_suspend)},

.cmds_resume = {ARRAY_AND_SIZE(lcd_cmds_resume)},

.reset = lcd_zetrax_8009a_reset,

.suspend = lcd_zetrax_8009a_suspend,

.resume = lcd_zetrax_8009a_resume,

.backlight_info = {ARRAY_AND_SIZE(backlight_cmds),

.brightness_bit = 8,

},

};

(4)配置文件添加

在/arch/arm/plat-lc/drivers/video 的Kconfig 中添加如下(红色为要修改部分):

config LCD_TM_NT35516

boolean "TM NT35516(NOVATEK Driver IC) lcd panel"

---help---

TM NT35516(NOVATEK Driver IC) It's resolution is 540 x 960.

This panel is connected with MIPI interface.

在drivers/video/comip_lc1860 的Makefile 中添加如下(红色为要修改部分):

obj-$(CONFIG_LCD_ZET_SSD2075) += lcd_zetrax_ssd2075.o

 

0
 条评论
相关内容推荐