现在的位置: 首页 > 综合 > 正文

Notes for debugging LCD based on msm8930 and orise

2013年11月19日 ⁄ 综合 ⁄ 共 21205字 ⁄ 字号 评论关闭

1  frame update

struct vsync_update {
	int update_cnt;	/* pipes to be updated */
	struct completion vsync_comp;
	struct mdp4_overlay_pipe plist[OVERLAY_PIPE_MAX];
};

enum {
	OVERLAY_PIPE_VG1,	/* video/graphic */
	OVERLAY_PIPE_VG2,
	OVERLAY_PIPE_RGB1,
	OVERLAY_PIPE_RGB2,
	OVERLAY_PIPE_RGB3,
	OVERLAY_PIPE_VG3,
	OVERLAY_PIPE_VG4,
	OVERLAY_PIPE_MAX
};

enum {
	OVERLAY_TYPE_RGB,
	OVERLAY_TYPE_VIDEO,
	OVERLAY_TYPE_BF
};

enum {
	MDP4_MIXER0,
	MDP4_MIXER1,
	MDP4_MIXER2,
	MDP4_MIXER_MAX
};

enum {
	OVERLAY_PLANE_INTERLEAVED,
	OVERLAY_PLANE_PLANAR,
	OVERLAY_PLANE_PSEUDO_PLANAR
};

enum {
	MDP4_MIXER_STAGE_UNUNSED,	/* pipe not used */
	MDP4_MIXER_STAGE_BASE,
	MDP4_MIXER_STAGE0,	/* zorder 0 */
	MDP4_MIXER_STAGE1,	/* zorder 1 */
	MDP4_MIXER_STAGE2,	/* zorder 2 */
	MDP4_MIXER_STAGE3,	/* zorder 3 */
	MDP4_MIXER_STAGE_MAX
};

enum {
	MDP4_FRAME_FORMAT_LINEAR,
	MDP4_FRAME_FORMAT_ARGB_TILE,
	MDP4_FRAME_FORMAT_VIDEO_SUPERTILE
};

enum {
	MDP4_CHROMA_RGB,
	MDP4_CHROMA_H2V1,
	MDP4_CHROMA_H1V2,
	MDP4_CHROMA_420
};

static struct vsycn_ctrl {
	struct device *dev;
	int inited;
	int update_ndx;
	int ov_koff;
	int ov_done;
	atomic_t suspend;
	atomic_t vsync_resume;
	int wait_vsync_cnt;
	int blt_change;
	int blt_free;
	int blt_ctrl;
	int sysfs_created;
	struct mutex update_lock;
	struct completion ov_comp;
	struct completion dmap_comp;
	struct completion vsync_comp;
	spinlock_t spin_lock;
	struct msm_fb_data_type *mfd;
	struct mdp4_overlay_pipe *base_pipe;
	struct vsync_update vlist[2];
	int vsync_irq_enabled;
	ktime_t vsync_time;
} vsync_ctrl_db[MAX_CONTROLLER];

struct mdp4_overlay_ctrl {
	struct mdp4_overlay_pipe plist[OVERLAY_PIPE_MAX];
	struct mdp4_overlay_pipe *stage[MDP4_MIXER_MAX][MDP4_MIXER_STAGE_MAX];
	struct mdp4_overlay_pipe *baselayer[MDP4_MIXER_MAX];
	struct blend_cfg blend[MDP4_MIXER_MAX][MDP4_MIXER_STAGE_MAX];
	uint32 mixer_cfg[MDP4_MIXER_MAX]; // mixer:混合器(名词); blend:混合(动词)
	uint32 flush[MDP4_MIXER_MAX];
	struct iommu_free_list iommu_free[MDP4_MIXER_MAX];
	uint32 dmap_cfg[5];
	uint32 cs_controller;
	uint32 panel_3d;
	uint32 panel_mode;
	uint32 mixer0_played;
	uint32 mixer1_played;
	uint32 mixer2_played;
} mdp4_overlay_db = {
	.cs_controller = CS_CONTROLLER_0,
	.plist = {
		{
			.pipe_type = OVERLAY_TYPE_RGB,
			.pipe_num = OVERLAY_PIPE_RGB1, // 2
			.pipe_ndx = 1,
		},
		{
			.pipe_type = OVERLAY_TYPE_RGB,
			.pipe_num = OVERLAY_PIPE_RGB2, // 3
			.pipe_ndx = 2,
		},
		{
			.pipe_type = OVERLAY_TYPE_VIDEO,
			.pipe_num = OVERLAY_PIPE_VG1, // 0
			.pipe_ndx = 3,
		},
		{
			.pipe_type = OVERLAY_TYPE_VIDEO,
			.pipe_num = OVERLAY_PIPE_VG2, // 1
			.pipe_ndx = 4,
		},
		{
			.pipe_type = OVERLAY_TYPE_BF,
			.pipe_num = OVERLAY_PIPE_RGB3, // 4, mixer0
			.pipe_ndx = 5,
			.mixer_num = MDP4_MIXER0,
		},
		{
			.pipe_type = OVERLAY_TYPE_BF,
			.pipe_num = OVERLAY_PIPE_VG3, // 5, mixer1
			.pipe_ndx = 6,
			.mixer_num = MDP4_MIXER1,
		},
		{
			.pipe_type = OVERLAY_TYPE_BF,
			.pipe_num = OVERLAY_PIPE_VG4, // 6, mixer2
			.pipe_ndx = 7,
			.mixer_num = MDP4_MIXER2,
		},
	},
};

static DEFINE_MUTEX(iommu_mutex);
static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db;

The registers of Mobile Display Processor(MDP) are accessible by ARM CPU through the Peripheral Bus AHB interface. For read accesses, the number of cycles before data is available is variable depending on the register being read.

ARM registers:

NOTE: RGB3 and Video/Graphics3 Pipe are used for the border color feature in LM. These two registers don't have fetch logic and just provide a solid background color for LM 0/1.

MDP ARM register grouping:

Global general operation

Interrupts

EBI2 LCD parameters

MDDI parameters

DSI 1 command mode parameters(ID_MAP and TRIGGER_EN)

DSI 2 command mode parameters

Internal Memory Chip Select control register

Synchronization registers (VSYNC_CLK, MDP_CLK)

MGEN2MAXI control registers

    Client0 - VG1 read, Client1 - VG2 read, Client2 - RGB1 read, Client3 - RGB2 read, Client4 - DMA_P Image read, Client5 - DMA_P Cursor read, Client6 - DMA_S read, Client7 - DMA_E Image read, Client8 - DMA_E Cursor read, Client9 - Overlay0 write, Client10
-Overlay1 write

Overlay processor registers (Layer Mixer0, Layer Mixer1, V/G1 pipe, V/G2 pipe, RGB1/2/3 pipe, V/G3 pipe, Layer mixer2)

Primary Display Driver Settings

Secondary Display Driver Settings

External Display Driver Settings

DSI2 Video Mode/LCDC Timing Generator

DTV  Timing Generator

DSI1 Video Mode/LCDC Timing Generator

Test Bus and MISR Access(MDP_CLK, HCLK, DCLK, TV_CLK, DSI_PCLK, AXI_CLK)

log:

[    1.287715] mipi_global_lcd_probe: enter
[    1.288631] mipi_global_lcd_probe: enter
[    1.288814] setting pdata->panel_info.fb_num to 3. type: 8
[    1.320952] FrameBuffer[0] 540x960 size=6266880 bytes is registered successfully!
[    1.322600] mipi_global_lcd_probe: exit
[    1.323882] setting pdata->panel_info.fb_num to 1. type: 10
[    1.324462] Inside writeback_driver_init
[    1.325103] Inside writeback_probe
[    1.327239] FrameBuffer[1] 1280x720 size=0 bytes is registered successfully!
[    1.330749]
[    1.330779]  msm_vidc_enc: Inside vid_enc_init()
[    1.332031]
[    1.332031]  msm_vidc_enc: Inside vid_enc_vcd_init()

----------------------------------probe--------------------顺序为:

c0d68278 t __initcall_msm_fb_init6
c0d6827c t __initcall_mdp_driver_init6
c0d68280 t __initcall_mipi_dsi_driver_init6
c0d68284 t __initcall_mipi_video_mipi_global_wvga_pt_init6
c0d68288 t __initcall_writeback_panel_init6
c0d6828c t __initcall_writeback_driver_init6
c0d68290 t __initcall_vidc_init6
c0d68294 t __initcall_vid_dec_init6
c0d68298 t __initcall_vid_enc_init6
c0d6829c t __initcall_vfb_init6
c0d682a0 t __initcall_pty_init6
c0d682a4 t __initcall_sysrq_init6
c0d682a8 t __initcall_smux_init6
c0d682ac t __initcall_smux_ctl_init6
c0d682b0 t __initcall_msm_serial_hs_init6
c0d682b4 t __initcall_msm_serial_hsl_init6
c0d682b8 t __initcall_rand_initialize6
c0d682bc t __initcall_msm_rng_init6
c0d682c0 t __initcall_msm_rotator_init6

-------------------------------------end--------------

lcd on:

[    9.747047] mipi_global_lcd_on: lcd begin to open, cmds = 147
[    9.917106] mipi_global_lcd_on: lcd has opened successfully.
[    9.922661] ....................alloc count = 4, mixer:0,pipe.mixer_num:0, ptype:0, pipe index:1, type:0
[    9.922722] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x20000, srcp0_ystride:2176
[    9.922722] mdp4_overlayproc_cfg:-----------------directout mode
[   10.067083] ....................alloc count = 5, mixer:0,pipe.mixer_num:0, ptype:2, pipe index:5, type:2
[   10.145093] mdp4_dsi_video_pipe_commit:----------- pipe->ov_blt_addr is ZERO

[   10.739722] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video
[   11.190019] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video
[   11.391942] ....................alloc count = 6, mixer:0,pipe.mixer_num:0, ptype:0, pipe index:1, type:0
[   11.415992] mdp4_overlay_play:............1.............srcp0_addr:0x700000, srcp0_ystride:2176
[   11.425789] mdp4_overlay_play:............2.............srcp0_addr:0x700000, srcp0_ystride:2176
[   11.435464] mdp4_overlay_mdp_perf_upd mdp clk is changed [1] from 0 to 59080000
[   11.459209] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_vsync_commit
[   11.465344] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x700000, srcp0_ystride:2176
[   11.490767] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_iommu_pipe_free
[   11.523546] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video
[   11.615351] mdp4_overlay_play:............1.............srcp0_addr:0x900000, srcp0_ystride:2176
[   11.632137] mdp4_overlay_play:............2.............srcp0_addr:0x900000, srcp0_ystride:2176
[   11.641141] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_vsync_commit
[   11.648130] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x900000, srcp0_ystride:2176
[   11.670685] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_iommu_pipe_free
[   11.690340] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video
[   11.876972] mdp4_overlay_play:............1.............srcp0_addr:0x700000, srcp0_ystride:2176
[   11.885914] mdp4_overlay_play:............2.............srcp0_addr:0x700000, srcp0_ystride:2176

[   11.947169] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_vsync_commit
[   11.953334] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x700000, srcp0_ystride:2176
[   11.967251] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_iommu_pipe_free
[   11.973844] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video
[   12.140149] pil_get: 'q6' depends_on = 'none', count: 10
[   12.146497] apr_tal: SMD_EVENT_OPEN
[   12.180741] mdp4_overlay_play:............1.............srcp0_addr:0x900000, srcp0_ystride:2176
[   12.199999] mdp4_overlay_play:............2.............srcp0_addr:0x900000, srcp0_ystride:2176
[   12.208026] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_vsync_commit
[   12.214832] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x900000, srcp0_ystride:2176
[   12.237356] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_iommu_pipe_free
[   12.257347] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video
[   12.364718] mdp4_overlay_play:............1.............srcp0_addr:0x700000, srcp0_ystride:2176
[   12.389989] mdp4_overlay_play:............2.............srcp0_addr:0x700000, srcp0_ystride:2176
[   12.407172] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_vsync_commit
[   12.413337] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x700000, srcp0_ystride:2176
[   12.427224] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_iommu_pipe_free
[   12.440805] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video
[   12.569479] mdp4_overlay_play:............1.............srcp0_addr:0x900000, srcp0_ystride:2176
[   12.585197] mdp4_overlay_play:............2.............srcp0_addr:0x900000, srcp0_ystride:2176
[   12.616908] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_vsync_commit
[   12.623195] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x900000, srcp0_ystride:2176
[   12.667205] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_iommu_pipe_free
[   12.674286] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video

[   12.759529] mdp4_overlay_play:............1.............srcp0_addr:0x700000, srcp0_ystride:2176
[   12.787242] mdp4_overlay_play:............2.............srcp0_addr:0x700000, srcp0_ystride:2176
[   12.795116] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_vsync_commit
[   12.805127] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x700000, srcp0_ystride:2176
[   12.827224] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_iommu_pipe_free
[   12.841049] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video
[   12.976957] mdp4_overlay_play:............1.............srcp0_addr:0x900000, srcp0_ystride:2176
[   12.989317] mdp4_overlay_play:............2.............srcp0_addr:0x900000, srcp0_ystride:2176
[   13.012757] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_vsync_commit
[   13.027163] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x900000, srcp0_ystride:2176
[   13.035434] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_iommu_pipe_free
[   13.047428] mdp4_dsi_video_pipe_commit:----------- pipe->ov_blt_addr is ZERO
[   13.057836] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video
[   13.092934] mdp4_overlay_play:............1.............srcp0_addr:0x700000, srcp0_ystride:2176
[   13.118022] mdp4_overlay_play:............2.............srcp0_addr:0x700000, srcp0_ystride:2176
[   13.125866] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_vsync_commit
[   13.142377] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x700000, srcp0_ystride:2176
[   13.150801] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_iommu_pipe_free
[   13.174607] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video
[   13.243125] mdp4_overlay_play:............1.............srcp0_addr:0x900000, srcp0_ystride:2176
[   13.267968] mdp4_overlay_play:............2.............srcp0_addr:0x900000, srcp0_ystride:2176
[   13.275965] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_vsync_commit
[   13.283076] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x900000, srcp0_ystride:2176
[   13.309079] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_iommu_pipe_free
[   13.341370] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video
[   13.360201] mdp4_overlay_play:............1.............srcp0_addr:0x700000, srcp0_ystride:2176
[   13.387273] mdp4_overlay_play:............2.............srcp0_addr:0x700000, srcp0_ystride:2176
[   13.395116] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_vsync_commit
[   13.407111] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x700000, srcp0_ystride:2176
[   13.415443] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_iommu_pipe_free
[   13.458110] mdp4_dmap_done_dsi_video: ---------------------mdp4_dmap_done_dsi_video
[   13.466229] mdp4_overlay_play:............1.............srcp0_addr:0x900000, srcp0_ystride:2176
[   13.487227] mdp4_overlay_play:............2.............srcp0_addr:0x900000, srcp0_ystride:2176
[   13.495101] mdp4_dsi_video_pipe_commit:----------- mdp4_overlay_vsync_commit
[   13.507126] mdp4_overlay_rgb_setup:.........................srcp0_addr:0x900000, srcp0_ystride:2176

mdp 处理数据并update流程:

ioctl调用:

static int msmfb_display_commit(struct fb_info *info, unsigned long *argp) {
	int ret;
	struct mdp_display_commit disp_commit;
	ret = copy_from_user(&disp_commit, argp, sizeof(disp_commit));
	if (ret) {
		pr_err("%s:copy_from_user failed", __func__);
		return ret;
	}

	ret = msm_fb_pan_display_ex(info, &disp_commit);

	return ret;
}

msm_fb_pan_display_ex() -> schedule_work(&mfd->commit_work);

a. INIT_WORK(&mfd->commit_work, msm_fb_commit_wq_handler);  // 通过这个工作队列更新

b. 通过调用mdp4_overlay_commit

if (fb_backup->disp_commit.flags & MDP_DISPLAY_COMMIT_OVERLAY) {  
    mdp4_overlay_commit(info);  
}

mdp4_overlay_mdp_perf_upd(mfd, 1); // Implementation, as follow:  
mdp_set_core_clk(perf_req->mdp_clk_rate); // 设置core时钟:mdp_clk_rate  
mdp_bus_scale_update_request(...);   // bandwidth update  
if ((mfd->panel_info.pdest == DISPLAY_1 &&  // use_ov_blt isn't used 
		perf_req->use_ov_blt[0] && !perf_cur->use_ov_blt[0])) {
	if (mfd->panel_info.type == MIPI_VIDEO_PANEL)  
                mdp4_dsi_video_blt_start(mfd);
}

c. 对于video panel调用以下的case

case MIPI_VIDEO_PANEL:  
        mdp4_dsi_video_pipe_commit(0, 1);  
        break;

d. mdp4_overlay_vsync_commit

for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {  
        if (pipe->pipe_used) {  
            cnt++;  
            real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);  
            if (real_pipe && real_pipe->pipe_used) {  
                /* pipe not unset */  
                mdp4_overlay_vsync_commit(pipe);  // 这个小函数非常重要,提交了需要更新的framebuffer,下面具体分析此函数  
            }  
            /* free previous iommu to freelist which will be freed at next pipe_commit */  
            mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);  
            pipe->pipe_used = 0; /* clear */  
        }  
    }

(1) Implementation: mdp4_overlay_vsync_commit 

void mdp4_overlay_vsync_commit(struct mdp4_overlay_pipe *pipe)  
{  
    if (pipe->pipe_type == OVERLAY_TYPE_VIDEO)  
        mdp4_overlay_vg_setup(pipe);    /* video/graphic pipe */  
    else  
        mdp4_overlay_rgb_setup(pipe);   /* rgb pipe 对于UI一般情况下就是rgb pipe了 */  
  
    pr_debug("%s: pipe=%x ndx=%d num=%d used=%d\n", __func__,  
        (int) pipe, pipe->pipe_ndx, pipe->pipe_num, pipe->pipe_used);  
    mdp4_overlay_reg_flush(pipe, 1);
    mdp4_mixer_stage_up(pipe, 0);
}

(2) Implementation:mdp4_overlay_rgb_setup

void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe)  
{  
    char *rgb_base;  
    uint32 src_size, src_xy, dst_size, dst_xy;  
    uint32 format, pattern;  
    uint32 curr, mask;  
    uint32 offset = 0;  
    int pnum;  
  
    pnum = pipe->pipe_num - OVERLAY_PIPE_RGB1; /* start from 0 */  
    rgb_base = MDP_BASE + MDP4_RGB_BASE;  
    rgb_base += (MDP4_RGB_OFF * pnum);  
  
    src_size = ((pipe->src_h << 16) | pipe->src_w);  
    src_xy = ((pipe->src_y << 16) | pipe->src_x);  
    dst_size = ((pipe->dst_h << 16) | pipe->dst_w);  
    dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);  
  
    if ((pipe->src_x + pipe->src_w) > 0x7FF) {  
        offset += pipe->src_x * pipe->bpp;  
        src_xy &= 0xFFFF0000;  
    }  
  
    if ((pipe->src_y + pipe->src_h) > 0x7FF) {  
        offset += pipe->src_y * pipe->src_width * pipe->bpp;  
        src_xy &= 0x0000FFFF;  
    }  
  
    format = mdp4_overlay_format(pipe);  
    pattern = mdp4_overlay_unpack_pattern(pipe);  
  
    mdp4_scale_setup(pipe);  
  
    mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);  
  
    /* Ensure proper covert matrix loaded when color space swaps */  
    curr = inpdw(rgb_base + 0x0058);  
    /* Don't touch bits you don't want to configure*/  
    mask = 0xFFFEFFFF;  
    pipe->op_mode = (pipe->op_mode & mask) | (curr & ~mask);  
  
    outpdw(rgb_base + 0x0000, src_size);    /* MDP_RGB_SRC_SIZE */  
    outpdw(rgb_base + 0x0004, src_xy);  /* MDP_RGB_SRC_XY */  
    outpdw(rgb_base + 0x0008, dst_size);    /* MDP_RGB_DST_SIZE */  
    outpdw(rgb_base + 0x000c, dst_xy);  /* MDP_RGB_DST_XY */  
  
    outpdw(rgb_base + 0x0010, pipe->srcp0_addr + offset);// 对应于源地址,传到寄存器中  
    outpdw(rgb_base + 0x0040, pipe->srcp0_ystride);// 这里需要进一步打印出地址再进一步确认和overlay_play中如何控制?  
  
    outpdw(rgb_base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */  
    outpdw(rgb_base + 0x0054, pattern);/* MDP_RGB_SRC_UNPACK_PATTERN */  
    if (format & MDP4_FORMAT_SOLID_FILL) {  
        u32 op_mode = pipe->op_mode;  
        op_mode &= ~(MDP4_OP_FLIP_LR + MDP4_OP_SCALEX_EN);  
        op_mode &= ~(MDP4_OP_FLIP_UD + MDP4_OP_SCALEY_EN);  
        outpdw(rgb_base + 0x0058, op_mode);/* MDP_RGB_OP_MODE */  
    } else {  
        if (pipe->op_mode & MDP4_OP_FLIP_LR && mdp_rev >= MDP_REV_42) {  
            /* Enable x-scaling bit to enable LR flip */  
            /* for MDP > 4.2 targets */  
            pipe->op_mode |= 0x01;  
        }  
        outpdw(rgb_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */  
    }  
    outpdw(rgb_base + 0x005c, pipe->phasex_step);  
    outpdw(rgb_base + 0x0060, pipe->phasey_step);  
  
    mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);  
  
    mdp4_stat.pipe[pipe->pipe_num]++;  
}

e. 启动时序引擎

/* start timing generator & mmu if they are not started yet */  
    mdp4_overlay_dsi_video_start(); // 启动dsi video 控制

f. 使能中断位,DMA_P_DONE

if (pipe->ov_blt_addr) {   // 这个addr 默认未使用所以走else分支,所以只打开了DMA_P_DONE中断  
        mdp4_dsi_video_blt_ov_update(pipe);  
        pipe->ov_cnt++;  
        INIT_COMPLETION(vctrl->ov_comp);  
        vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM);  
        mb();  
        vctrl->ov_koff++;  
        /* kickoff overlay engine */  
        mdp4_stat.kickoff_ov0++;  
        outpdw(MDP_BASE + 0x0004, 0);  
    }  else {  
        /* schedule second phase update  at dmap */  
        INIT_COMPLETION(vctrl->dmap_comp);  
        vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);  // enable INTR_DMA_P_DONE(DMA_P Transfer done)  
    }

static void vsync_irq_enable(int intr, int term)  
{  
    unsigned long flag;  
  
    spin_lock_irqsave(&mdp_spin_lock, flag);  
    outp32(MDP_INTR_CLEAR, intr);  
    mdp_intr_mask |= intr;  
    outp32(MDP_INTR_ENABLE, mdp_intr_mask);  
    mdp_enable_irq(term);  
    spin_unlock_irqrestore(&mdp_spin_lock, flag);  
    pr_debug("%s: IRQ-en done, term=%x\n", __func__, term);  
}

h. 中断,一个是vsync,一个是dmap done 

if (isr & INTR_PRIMARY_VSYNC) {  
        mdp4_stat.intr_vsync_p++;  
        if (panel & MDP4_PANEL_LCDC)  
            mdp4_primary_vsync_lcdc();  
        else if (panel & MDP4_PANEL_DSI_VIDEO)  
            mdp4_primary_vsync_dsi_video();  
    }


if (isr & INTR_DMA_P_DONE) {  
        mdp4_stat.intr_dma_p++;  
        dma = &dma2_data;  
        if (panel & MDP4_PANEL_LCDC)  
            mdp4_dmap_done_lcdc(0);  
        else if (panel & MDP4_PANEL_DSI_VIDEO)  
            mdp4_dmap_done_dsi_video(0); 
}

2  LCD resume time

  1. 537.952815</span>] request_suspend_state: wakeup (3->0) at 537941084255 (2013-05-27 10:53:03.049466690 UTC)
  2. [  537.962307] get_prop_batt_temp: batt_temp phy = 312 meas = 0xc02b17ecec479268
  3. [  537.972256] report_state_of_charge: calculated_soc = 73,last_soc = 73,start_percent = -22,charge_time_us = 0,catch_up_time_us = 0
  4. [  538.007202] =====enter in rmi_f01_resume=====
  5. [  538.031893] report_state_of_charge: Reported SOC = 73
  6. [  538.063360] get_prop_batt_ocv: get_prop_batt_ocv:ocv_uv =3910136,ibatt_ua =329800.
  7. [  538.064703] get_prop_batt_temp: batt_temp phy = 314 meas = 0xecc33000

[  538.131878] mipi_global_lcd_on: ready for opening lcd

  1. [  538.312559] mipi_global_lcd_on: lcd is on, count = 147 
  2. [  538.365298] mdp4_overlay_mdp_perf_upd mdp clk is changed [1] from 0 to 59080000

  3. 按照log可以发现从请求wakeup到lcd on大概花费了360ms,所以开屏的过程还是比较慢的,这里还没计算再次打开背光的时间,这个也要通过mipi发给LCD(lcd提供背光的话)。而主要的停留是在mipi lcd on cmds的低速发送上等待时间比较长,这个dma搬运的时间持续了180ms,不过这里有147条开屏的cmds要通过mipi发给lcd,所以dma搬运的过程肯定会消耗不少时间。
  1. [  594.616419] mipi_global_lcd_off: ready for closing lcd
  2. [  594.837784] mipi_global_lcd_off: lcd is off, count = 2
  3. [  594.891255] request_suspend_state: sleep (0->3) at 594875256577 (2013-05-27 11:10:12.737098649 UTC)
  4. [  594.899893] =====enter in rmi_f01_suspend===== 
  5. [  597.610926] PM: suspend entry 2013-05-27 11:10:15.456769024 UTC

从log可以发现从LCD off到LCD完成off花费了220ms,这命令比LCD on的时间更长,现在原因还不太确定。不过总的来说LCD 的开屏和关屏时间还是比较长。所以在开屏和关屏期间需要注意背光的控制不能在开屏过程或者关屏过程进行!


Bug如下:

------ watchdog state ------

  1. [!!!!] Read b3af1000 from IMEM successfully!
  2. [!!!!] An FIQ occured on the system!
  3. running dump version 1
  4. Core 0 PC: mipi_dsi_isr+3c <c03026e4>
  5. Core 0 LR: uncached_logk_pc+20 <c007d8e8>
  6. [<c03026e4>] mipi_dsi_isr+0x3c
  7. [<c00d4798>] handle_irq_event_percpu+0xb0
  8. [<c00d49b4>] handle_irq_event+0x3c
  9. [<c00d75a0>] handle_fasteoi_irq+0xdc
  10. [<c00d3ffc>] generic_handle_irq+0x30
  11. [<c000efb0>] handle_IRQ+0x7c
  12. [<c00085b8>] gic_handle_irq+0x94
  13. [<c080aa40>] __irq_svc+0x40
  14. [<c0088184>] __do_softirq+0x4c
  15. [<c00887b0>] irq_exit+0x48
  16. [<c000efb4>] handle_IRQ+0x80
  17. [<c00085b8>] gic_handle_irq+0x94
  18. [<c080aa40>] __irq_svc+0x40
  19. [<c080a674>] _raw_spin_unlock_irqrestore+0x10
  20. [<c03c3d40>] pm8xxx_get_irq_stat+0x134
  21. [<c0550f14>] pm_chg_get_rt_status+0x34
  22. [<c0555590>] unplug_check_worker+0x70
  23. [<c009a950>] process_one_work+0x27c
  24. [<c009acf8>] worker_thread+0x1a0
  25. [<c009ec80>] kthread+0x80
  26. [<c000f130>] kernel_thread_exit+0x0
  27. Core 1 PC: go_wfi+4 <c0024a88>
  28. Core 1 LR: msm_pm_idle_enter+68 <c0057194>
  29. [   62.812635] mdp4_mixer_blend_setup: Error: no bg_pipe at mixer=0
  30. [   63.244925] setup_clocks: Failed to set fs_mdp tv_src_clk rate to 0 Hz.
  31. [   63.250602] fs_mdp: failed to disable
  32. [   63.531176] mipi_dsi_ahb_ctrl: ahb clks already ON
  33. [   63.537097] mipi_dsi_clk_enable: mipi_dsi_clks already ON 
  34. [   63.741126] mipi_dsi_cmd_dma_tx: dma timeout error  
  35. [   63.981168] mipi_dsi_cmd_dma_tx: dma timeout error
  36. [   64.181138] mipi_dsi_cmd_dma_tx: dma timeout error

  37. Bug 引起的根源是在充电模式下,直接调用了写文件的方式来让kernel suspend/resume,然后suspend和resume的切换又非常快导致suspend未完全结束,resume又开始执行,所以导致了中断、dsi dma异常,有些地方触摸屏也异常,很明显这里应该利用通知的方式等待系统完成suspend或者resume,才再次切换到下一种状态!

3  LCD点亮注意事项

1. phy参数(高通提供了计算相应数值的excel,所以只要按照它那个再填进来即可,大部分数值按照原先数值即可):
2. 高通DTYPE_DCS_WRITE这个0x05有写失败的场景,需要注意,所以最好都使用DTYPE_DCS_LWRITE
3. LCD 示波器背光测试(PWM由LCD输出波形如下所示,占空比为50%,波形为各占50%,高电平为1.8V,低电平为0V,100%为完全1.8V高电平),需要连接LCD后才能很好的测试。ORISE可通过开关CABC这个功能来选择省电。若开CABC,将会导致背光设为100%后,实际背光达不到100%。
4. frame rate 60Hz, 对于mipi接口又是如何,如下图所示:(1格的时间间隔是2ms
通过波形可以发现发完一帧,mipi会切换状态到low power mode,状态的变换细节等有空再仔细分析。注意高速和低速信号的swing
5. 几个tips,关于TFT lcd
a.  图像显示的偏色可能和背光灯的颜色有关系
b. 输出给LCD背光灯电压较大,我们平台为30V,所以额外需要IC来驱动
c. LCD灰阶分成一定等分,并给定相应的电压,如分成255
d. LCD显示效果起决定性因素的还是玻璃
e. LCD也需要调整白平衡
f. 平板电脑可能是由多个IC驱动LCD modules,通常经过一个时序IC来控制多个IC的输出顺序
g. porch的大小可能会影响LCD的flicker,同时porch的增加会增加mipi的带宽
h. OLED自发光,不再需要外围背光驱动,更省电
i. LCD驱动IC 使用command mode会节省主控CPU的消耗,但是这样的IC成本会提高,因为增加了ram,增加了面积,也增加了芯片的成本 
6. LCD 显示原理,如下图:

抱歉!评论已关闭.