当前位置: 代码迷 >> 综合 >> [RK3288][Android7.1]调试笔记 --- LVDS+HDMI输出特殊分辨率800*1280竖屏
  详细解决方案

[RK3288][Android7.1]调试笔记 --- LVDS+HDMI输出特殊分辨率800*1280竖屏

热度:82   发布时间:2023-10-09 13:36:25.0

Platform: RK3288
OS: Android 7.1.2
Kernel: v4.4.143

需求:

RK3288双屏同显,一路LVDS,一路HDMI,其中HDMI经过驱动板点亮同一块LVDS屏,实现RK3288点两路800*1280LVDS屏,驱动板型号为:CY.R8311 V2,LVDS屏为MX1010503081NB;客户由于价格的原因没有采用1280*800横扫描的屏,而采用了800*1280竖扫描的屏;

方法:

1、驱动800*1280LVDS

1.1、TIMING

首先,我们拿到厂商提供的规格书,确认一下屏的时序参数;

[RK3288][Android7.1]调试笔记 --- LVDS+HDMI输出特殊分辨率800*1280竖屏

[RK3288][Android7.1]调试笔记 --- LVDS+HDMI输出特殊分辨率800*1280竖屏

由图1、图2时序表,我们确认下以下参数

像素时钟频率clock-frequency =60MHz或者20MHz≤clock-frequency≤85MHz或者通过公式计算H*V(总周期)*fps

水平有效像素Hactive=800

水平总周期=920

根据公式水平总周期 = hback-porch + hfront-porch + hsync-len+Hactive

得出hback-porch + hfront-porch + hsync-len = 水平总周期 - Hactive = 120

垂直有效像素Vactive=1280

垂直总周期=1304

根据公式垂直总周期 = vback-porch + vfront-porch + vsync-len+Vactive

得出vback-porch + vfront-porch + vsync-len = 垂直总周期 - Vactive = 24

各值再按照时序表格中已知的填写,未知的自行分配,一般情况下hbp和vbp取较大值

timing0: timing0 {clock-frequency = <60000000>;hactive = <800>;vactive = <1280>;hback-porch = <24>;hfront-porch = <72>;vback-porch = <10>;vfront-porch = <12>;hsync-len = <24>;vsync-len = <2>;hsync-active = <0>;vsync-active = <0>;de-active = <0>;pixelclk-active = <0>;
};

1.2、panel参数

[RK3288][Android7.1]调试笔记 --- LVDS+HDMI输出特殊分辨率800*1280竖屏

[RK3288][Android7.1]调试笔记 --- LVDS+HDMI输出特殊分辨率800*1280竖屏

由上两图可知,该屏支持单路 6BIT和单路 8BIT信号,由于我们主板支持8BIT,故我们采用单路 8BIT信号调试;

bus-format = <MEDIA_BUS_FMT_RGB888_1X24>;
rockchip,data-width = <24>;
rockchip,output = "lvds";

又由上图1可知,具体参考LVDS 数据映射(MappingMapping)标准

rockchip,data-mapping = "vesa";

2、HDMI强制输出特殊分辨率800*1280

2.1、确定驱动板的edid

cat /sys/class/drm/card0-HDMI-A-1/modes

先获取驱动板的edid,若没有800*1280,则需要固件调试强制输出特殊分辨率;

2.2、恢复到原厂的源码

公司以前对HDMI输出分辨率修改过,需要将这部分代码恢复到原厂源码,如果不恢复的话,会导致drm_display_mode edid_cea_modes[]数组不生效;

涉及文件:kernel/drivers/gpu/drm/drm_edid.c

2.3、强制输出800*1280

参考RK的文档:Rockchip_Developer_Guide_HDMI_Based_on_DRM_Framework_CN&EN

刚好文档提供的实例就是800*1280,故就没做更改,正确的做法应该参考上面LVDS的时序进行调试。

[RK3288][Android7.1]调试笔记 --- LVDS+HDMI输出特殊分辨率800*1280竖屏

2.4、 添加上层白名单resolution_white.xml

涉及文件:device/rockchip/common/resolution_white.xml

这是上层对底层分辨率的过滤,通过resolution_white.xml 定义合法分辨率,只有包含在该 xml 中的分辨率才可以设置;具体的参数值参考2.3,一致即可。

2.5、hdmiphy分频对应的clock

百度了一下,clock必须得在phy-rockchip-inno-hdmi-phy.c的pre_pll_cfg_table[]数组上添加,才能分频出对应的clock;

涉及文件:

kernel/drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c

下面是数组的原始数据

[RK3288][Android7.1]调试笔记 --- LVDS+HDMI输出特殊分辨率800*1280竖屏

网上是说把2.3和2.4的clock添加到这个数组里面去,因为不清楚数组里面是具体什么含义,所以我把这里面有的74250000放到2.3和2.4里面去,整体patch如下;

文件1:kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
old mode 100644
new mode 100755
index d57d999..cce9ca3
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2497,7 +2497,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)connector);struct edid *edid;struct drm_display_mode *mode;
-       const u8 def_modes[6] = {4, 16, 31, 19, 17, 2};
+       const u8 def_modes[6] = {108, 16, 31, 19, 17, 2};struct drm_display_info *info = &connector->display_info;struct hdr_static_metadata *metedata =&connector->display_info.hdmi.hdr_panel_metadata;
@@ -2506,7 +2506,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)if (!hdmi->ddc)return 0;-       edid = drm_get_edid(connector, hdmi->ddc);
+       edid = NULL;if (edid) {dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",edid->width_cm, edid->height_cm);

文件2:kernel//drivers/gpu/drm/drm_edid.c

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index c225e54..25f5b5e 100755
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1360,6 +1220,11 @@ static const struct drm_display_mode edid_cea_modes[] = {4104, 4400, 0, 2160, 2168, 2178, 2250, 0,DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),.vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+       /* 108 - 800x1280@60Hz add by OLJ */
+       { DRM_MODE("800x1280", DRM_MODE_TYPE_DRIVER, 74250, 800, 848,
+               880, 960, 0, 1280, 1300, 1304, 1314, 0,
+               DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC),
+         .vrefresh = 60, },};

文件3:device/rockchip/common/resolution_white.xml

diff --git a/resolution_white.xml b/resolution_white.xml
index 846938a..a1a9f1c 100755
--- a/resolution_white.xml
+++ b/resolution_white.xml
@@ -416,4 +416,20 @@<flags>5</flags><vic>102</vic></resolution>
+               <resolution> <!-- 800x1280P60 -->
+               <clock>74250</clock>
+               <hdisplay>800</hdisplay>
+               <hsync_start>848</hsync_start>
+               <hsync_end>880</hsync_end>
+               <htotal>960</htotal>
+               <hskew>0</hskew>
+               <vdisplay>1280</vdisplay>
+               <vsync_start>1300</vsync_start>
+               <vsync_end>1304</vsync_end>
+               <vtotal>1314</vtotal>
+               <vscan>0</vscan>
+               <vrefresh>60</vrefresh>
+               <flags>5</flags>
+               <vic>108</vic>
+       </resolution></resolutions>

参考文档

RK支持文档:Rockchip_Developer_Guide_HDMI_Based_on_DRM_Framework_CN&EN

网友文档:LVDS接口分类,时序,输出格式???????

  相关解决方案