[RK3399][Android8.1] 调试记录2 --- LT9611驱动调试

Platform: RK3399
OS: Android 8.1

现象:

上篇介绍了如何修改LT9611驱动,调试可以正常输出HDMI,接双屏(HDMI+9611HDMI)后,热插拔9611HDMI系统会崩溃。

问题1

通过查看LOG,猜测崩溃原因是主副屏切换造成的系统崩溃,猜测MIPI接口热插拔会导致系统崩溃,

由于最终我们的目标是三屏异显(mipi转HDMI,mipi转EDP,HDMI)。所以两个mipi输出分辨率固定为EDP屏的分辨率1080P 60

所以修改方案为:

将LT9611看成一个显示屏,RK3399mipi开机后对外输出1080P图像,LT9611检测HPD状态,如果有设备插入,输出1080P图像,如果设备拔出,LT9611失能

解决方法:

1.修改DTS文件,使LT9611不再直接挂在DRM上,DSI直接输出1080P图像

&dsi {
        status = "okay";
	rockchip,lane-rate = <1200>;
ports {
                #address-cells = <1>;
                #size-cells = <0>;

                 port@1 {
                        reg = <1>;
                        dsi_out_hdmi: endpoint {
                                remote-endpoint = <&hdmi_in_dsi>;
                        };
                };
        };

        panel {
                compatible ="simple-panel-dsi";
                status = "okay";
                reg = <0>;
//		power-supply = <&vcc3v3_sys>;
                backlight = <&backlight>;
//                enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
//		reset-gpios  = <&gpio1 0 GPIO_ACTIVE_HIGH>;
                dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
                                MIPI_DSI_MODE_VIDEO_SYNC_PULSE)>;
                dsi,format = <MIPI_DSI_FMT_RGB888>;
//		bus-format = <MEDIA_BUS_FMT_RGB666_1X24>;
                dsi,lanes = <4>;
//              reset-delay-ms = <20>;
//              init-delay-ms = <20>;
//              enable-delay-ms = <120>;
                prepare-delay-ms = <120>;

                display-timings {
                        native-mode = <&timing0>;
			timing0: timing0 {
				clock-frequency = <148500000>;//15
				hactive = <1920>;
				vactive = <1200>;
				hback-porch = <60>;
				hfront-porch = <16>;
				vback-porch = <23>;
				vfront-porch = <12>;
				hsync-len = <20>;
				vsync-len = <3>;
				de-active = <0>;
                                hsync-active = <0>;
                                vsync-active = <0>;
				pixelclk-active = <1>;
			};


			timing1: timing1{
				clock-frequency = <140000000>;
				hactive = <1920>;
				vactive = <1200>;
				hback-porch = <60>;
				hfront-porch = <16>;
				vback-porch = <23>;
				vfront-porch = <12>;
				hsync-len = <20>;
				vsync-len = <3>;
				de-active = <0>;
                                hsync-active = <0>;
                                vsync-active = <0>;
				pixelclk-active = <0>;
			};
                };
        };
};

2.修改LT9611驱动文件, 不再通过判断MIPI信号以及bridge状态来进行HDMI输出,修改为通过判断HPD状态来进行HDMI输出

	if (lt->rxsense){
			ret = lt9611_poweron(lt);
	}else{
			ret = lt9611_poweroff(lt);
	}
	return ret;

3.因为lt9611获取不到DRM输出的分辨率,所以将LT9611获取到的MIPI模式固定为1080P60

static int lt9611_display_mode_to_timing(struct lt9611 *lt, struct drm_display_mode *mode)
{
	u16 h_act,h_tal,v_act,v_tal,htotal_sysclk; //hfp,hs_width,hbp,vfp,vs_width,vbp,
	int ret = 0;

	h_act = video_1920x1080_60Hz.hact;
	v_act = video_1920x1080_60Hz.vact;
	h_tal = video_1920x1080_60Hz.htotal;
	v_tal = video_1920x1080_60Hz.vtotal;
	htotal_sysclk = lt9611_htotal_sysclk(lt);;
/*
	lt->vd_timing.vact = mode->vdisplay;
	lt->vd_timing.vbp  = mode->vtotal - mode->vsync_end; //mode->vback_porch;
	lt->vd_timing.vfp  = mode->vsync_start - mode->vdisplay; //mode->vfront_porch;
	lt->vd_timing.vs   = mode->vsync_end - mode->vsync_start; //mode->vsync_len;
	lt->vd_timing.vtotal = mode->vtotal; //mode->vsync_len + mode->vfront_porch + mode->vback_porch + mode->vactive;   

	lt->vd_timing.hact = mode->hdisplay; //mode->hactive;
	lt->vd_timing.hbp  = mode->htotal - mode->hsync_end; //mode->hback_porch;
	lt->vd_timing.hfp  = mode->hsync_start - mode->hdisplay; //mode->hfront_porch;
	lt->vd_timing.hs   = mode->hsync_end - mode->hsync_start; //mode->hsync_len;
	lt->vd_timing.htotal = mode->htotal; //mode->hactive + mode->hback_porch + mode->hfront_porch + mode->hsync_len;

	lt->vd_timing.pclk_khz = mode->clock;
*/

	lt->vd_timing.vact = video_1920x1080_60Hz.vact;
	lt->vd_timing.vbp  = video_1920x1080_60Hz.vbp;
	lt->vd_timing.vfp  = video_1920x1080_60Hz.vfp;
	lt->vd_timing.vs   = video_1920x1080_60Hz.vs;
	lt->vd_timing.vtotal = video_1920x1080_60Hz.vtotal;   

	lt->vd_timing.hact = video_1920x1080_60Hz.hact;
	lt->vd_timing.hbp  = video_1920x1080_60Hz.hbp;
	lt->vd_timing.hfp  = video_1920x1080_60Hz.hfp;
	lt->vd_timing.hs   = video_1920x1080_60Hz.hs;
	lt->vd_timing.htotal = video_1920x1080_60Hz.htotal;

	lt->vd_timing.pclk_khz = video_1920x1080_60Hz.pclk_khz;
	
	if ((h_act == video_640x480_60Hz.hact) && (v_act == video_640x480_60Hz.vact) && (v_tal == video_640x480_60Hz.vtotal)) {
		DRM_ERROR("video_format = video_640x480_60Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal,htotal_sysclk);
		lt->video_format = video_640x480_60Hz_vic1;
		lt->hdmi_vic = 1;
		lt->hdmi_sync_pol = 3;
	} else if ((h_act == video_720x480_60Hz.hact) && (v_act == video_720x480_60Hz.vact) && (v_tal == video_720x480_60Hz.vtotal)) {
		DRM_ERROR("video_format = video_720x480_60Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal,htotal_sysclk);
		lt->video_format = video_720x480_60Hz_vic3;
		lt->hdmi_vic = 3;
		lt->hdmi_sync_pol = 3;
	} else if ((h_act == video_720x576_50Hz.hact) && (v_act == video_720x576_50Hz.vact) && (v_tal==video_720x576_50Hz.vtotal)) {
		DRM_ERROR("video_format = video_720x576_50Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal,htotal_sysclk);
		lt->video_format = video_720x576_50Hz_vic17;
		lt->hdmi_vic = 17;
		lt->hdmi_sync_pol = 3;
	} else if ((h_act == video_1280x720_60Hz.hact) && (v_act == video_1280x720_60Hz.vact) && (v_tal==video_1280x720_60Hz.vtotal)) {
		if (htotal_sysclk > 1700) {
			DRM_ERROR("video_format = video_1280x720_50Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
			lt->video_format = video_1280x720_50Hz_vic19;	
			lt->hdmi_vic = 19;
			lt->hdmi_sync_pol = 0;
		} else {
			DRM_ERROR("video_format = video_1280x720_60Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
			lt->video_format = video_1280x720_60Hz_vic4;	
			lt->hdmi_vic = 4;
			lt->hdmi_sync_pol = 0;
		}
	} else if ((h_act == video_1920x1080_60Hz.hact) && (v_act == video_1920x1080_60Hz.vact)) {
		if (htotal_sysclk > 500) {
			DRM_ERROR("video_format = video_1920x1080_30Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
			lt->video_format = video_1920x1080_30Hz_vic;
			lt->hdmi_vic = 34;
			lt->hdmi_sync_pol = 0;
		} else if (htotal_sysclk > 420) {
			DRM_ERROR("video_format = video_1920x1080_50Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
			lt->video_format = video_1920x1080_50Hz_vic31;
			lt->hdmi_vic = 31;
			lt->hdmi_sync_pol = 0;
		} else {
			DRM_ERROR("video_format = video_1920x1080_60Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
			lt->video_format =video_1920x1080_60Hz_vic16;
			lt->hdmi_vic = 16;
			lt->hdmi_sync_pol=0;
		}
	} else if ((h_act == video_3840x2160_30Hz.hact) && (v_act == video_3840x2160_30Hz.vact)) {
		DRM_ERROR("video_format = video_3840x2160_30Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
		lt->video_format = video_3840x2160_30Hz_vic;
		lt->hdmi_vic = 95;
		lt->hdmi_sync_pol = 0;
	} else if ((h_act == video_3840x1080_60Hz.hact) && (v_act == video_3840x1080_60Hz.vact)) {
		DRM_ERROR("video_format = video_3840x2160_30Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
		lt->video_format = video_3840x1080_60Hz_vic;
		lt->hdmi_vic = 0;
		lt->hdmi_sync_pol = 0;
	} else if ((h_act == video_1024x768_70Hz.hact) && (v_act == video_1024x768_70Hz.vact)) {
		DRM_ERROR("video_format = video_1024x768_70Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
		lt->video_format = video_1024x768_70Hz_vic;
		lt->hdmi_vic = 0;
		lt->hdmi_sync_pol = 3;
	} else if ((h_act == video_1280x1024_60Hz.hact) && (v_act == video_1280x1024_60Hz.vact)) {
		DRM_ERROR("video_format = video_1280x1024_60Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
		lt->video_format = video_1280x1024_60Hz_vic;
		lt->hdmi_vic = 0;
		lt->hdmi_sync_pol = 0;
	} else if ((h_act == video_1366x768_60Hz.hact) && (v_act == video_1366x768_60Hz.vact)) {
		DRM_ERROR("video_format = video_1366x768_60Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
		lt->video_format = video_1366x768_60Hz_vic;
		lt->hdmi_vic = 0;
		lt->hdmi_sync_pol = 0;
	} else if ((h_act == video_1440x900_60Hz.hact) &&(v_act == video_1440x900_60Hz.vact)) {
		DRM_ERROR("video_format = video_1440x900_60Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
		lt->video_format = video_1440x900_60Hz_vic;
		lt->hdmi_vic = 14;
	} else if ((h_act == video_1600x900_60Hz.hact) && (v_act == video_1600x900_60Hz.vact)) {
		DRM_ERROR("video_format = video_1600x900_60Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
		lt->video_format = video_1600x900_60Hz_vic;
		lt->hdmi_vic = 0;
		lt->hdmi_sync_pol = 0;
	} else if ((h_act == video_1680x1050_60Hz.hact) && (v_act == video_1680x1050_60Hz.vact)) {
		DRM_ERROR("video_format = video_1680x1050_60Hz(h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d)\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
		lt->video_format = video_1680x1050_60Hz_vic;
		lt->hdmi_vic = 0;
		lt->hdmi_sync_pol = 0;
	} else {
		DRM_ERROR("video_format = unknown video format: h_act: %d, v_act: %d, v_tal: %d, h_tal: %d, htotal_sysclk: %d\n", h_act, v_act, v_tal, h_tal, htotal_sysclk);
		lt->video_format = video_1920x1080_60Hz_vic16;
		lt->hdmi_vic = 16;
		lt->hdmi_sync_pol = 0;
	}

	return ret;	
}

4.修改中断部分逻辑,这里不贴出了

扫描二维码关注公众号,回复: 8680272 查看本文章

问题2

编译后LT9611HDMI接显示屏,插拔HDMI后屏幕有识别到信号源的动作,但是没有图像输出

 

解决方法:

1.修改DTS中mipi输出timing为标准时钟输出,输出正常。

   timing1: timing1 {
                                clock-frequency = <148500000>;
                                hactive = <1920>;
                                vactive = <1080>;
                                hfront-porch = <88>;
                                hsync-len = <44>;
                                hback-porch = <148>;
                                vfront-porch = <4>;
                                vsync-len = <5>;
                                vback-porch = <36>;
                                hsync-active = <0>;
                                vsync-active = <0>;
                                de-active = <0>;
                                pixelclk-active = <0>;
                        };

总结

修改后mipi作为主屏,HDMI作为副屏,可以实现双屏同显功能,并且支持热插拔。后续会继续更新三屏异显

发布了12 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/oliverJ/article/details/103701301