RK3328为HDMI输出添加新的分辨率(如1280x800)

平台:rk3328

系统版本:Android 8.1

        百度到的大多数解法都是Android 5.1版本,但是在rk Android8.1的源码中,关于hdmi部分均由drm负责(kernel\drivers\gpu\drm)。所以我们首先需要修改的是drm_edid.c文件。

在edid_cea_modes后面,将1280x800写到末尾

	/* 108 - 1280x800p@60Hz 16:10 */
	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 71000, 1280, 1328,
		1360, 1440, 0, 800, 803, 809, 823, 0,
		DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC),
	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },

然后,根目录\device\rockchip\common\resolution_white.xml中添加,其中的参数,我是根据 VESA分辨率标准 来的(别人给的,不清楚)。或者看一下drm_edid.c中是否带有该分辨率,将其抄过来。

	<resolution> <!-- 1280x800P60 -->
		<clock>71000</clock>
		<hdisplay>1280</hdisplay>
		<hsync_start>1328</hsync_start>
		<hsync_end>1360</hsync_end>
		<htotal>1440</htotal>
		<hskew>0</hskew>
		<vdisplay>800</vdisplay>
		<vsync_start>803</vsync_start>
		<vsync_end>809</vsync_end>
		<vtotal>823</vtotal>
		<vscan>0</vscan>
		<vrefresh>60</vrefresh>
		<flags>9</flags>
		<vic>108</vic>
	</resolution>

到这里可能有部分人已经可以正常跑起来了。我百度搜索了下,发觉有部分改法和我这个是一样的,但是我仍然成功不了。仔细看了log,发现在rockchip_drm_vop.c文件中,vop_crtc_mode_valid的clk_round_rate返回值一直是24M,跟分辨率所需的71M是两码事。于是我去看了下rk3328.dtsi,查看clock设置,

                phys = <&hdmiphy>;        ---------------         hdmiphy: hdmiphy@ff430000 {      compatible = "rockchip,rk3328-hdmi-phy";     }

于是我找到了kernel\drivers\phy\rockchip\phy-rockchip-inno-hdmi-phy.c :

static const struct pre_pll_config pre_pll_cfg_table[] = {
    ........
	{ 59400000,  59400000, 1,  99, 3, 1, 1,  1, 3, 3, 4, 0, 0},
	{ 59341000,  74176250, 1,  98, 0, 3, 3,  1, 3, 3, 4, 0, 0xE6AE6B},
	{ 59400000,  74250000, 1,  99, 1, 2, 2,  1, 3, 3, 4, 0, 0},//
	{ 71000000,  71000000, 3, 284, 0, 3, 3,  1, 0, 0, 8, 0, 0},//新增的,原先没有
	{ 71000000,  88750000, 3, 355, 0, 3, 3,  1, 0, 0, 10, 0, 0},//新增的,原先没有
	{ 74176000,  74176000, 1,  98, 1, 2, 2,  1, 2, 3, 4, 0, 0xE6AE6B},
	{ 74250000,  74250000, 1,  99, 1, 2, 2,  1, 2, 3, 4, 0, 0},
	{ 74176000,  92720000, 4, 494, 1, 2, 2,  1, 3, 3, 4, 0, 0x816817},
	{ 74250000,  92812500, 4, 495, 1, 2, 2,  1, 3, 3, 4, 0, 0},
	{148352000, 148352000, 1,  98, 1, 1, 1,  1, 2, 2, 2, 0, 0xE6AE6B},
	{148500000, 148500000, 1,  99, 1, 1, 1,  1, 2, 2, 2, 0, 0},
	{148352000, 185440000, 4, 494, 0, 2, 2,  1, 3, 2, 2, 0, 0x816817},
	{148500000, 185625000, 4, 495, 0, 2, 2,  1, 3, 2, 2, 0, 0},
	{162000000, 162000000, 1, 108, 0, 2, 2,  1, 0, 0, 4, 0, 0},
	{162000000, 202500000, 1, 135, 0, 2, 2,  1, 0, 0,  5, 0, 0},
	{296703000, 296703000, 1,  98, 0, 1, 1,  1, 0, 2, 2, 0, 0xE6AE6B},
	{297000000, 297000000, 1,  99, 0, 1, 1,  1, 0, 2, 2, 0, 0},
	{296703000, 370878750, 4, 494, 1, 2, 0,  1, 3, 1, 1, 0, 0x816817},
	{297000000, 371250000, 4, 495, 1, 2, 0,  1, 3, 1, 1, 0, 0},
	{593407000, 296703500, 1,  98, 0, 1, 1,  1, 0, 2, 1, 0, 0xE6AE6B},
	{594000000, 297000000, 1,  99, 0, 1, 1,  1, 0, 2, 1, 0, 0},
	{593407000, 370879375, 4, 494, 1, 2, 0,  1, 3, 1, 1, 1, 0x816817},
	{594000000, 371250000, 4, 495, 1, 2, 0,  1, 3, 1, 1, 1, 0},
	{593407000, 593407000, 1,  98, 0, 2, 0,  1, 0, 1, 1, 0, 0xE6AE6B},
	{594000000, 594000000, 1,  99, 0, 2, 0,  1, 0, 1, 1, 0, 0},
	{     ~0UL,	    0, 0,   0, 0, 0, 0,  0, 0, 0, 0, 0, 0}
};

 这样,hdmiphy才能分频出需要的clock。可以在文件系统中  cat /sys/class/drm/card0-HDMI-A-1/mode得到支持的分辨率。

22年最新补充说明:phy的相关值,是需要通过rockchip的工具去算出来的,否则实际pix clock会有误,可能会影响视频,也可能会影响音频。(代码中不是按照71000000直接设置的,而是通过71000000后面的数值计算出实际要输出的pixclock)

工具:https://files.cnblogs.com/files/blogs/679767/innophy.7z?t=1648185237

同时也可以在UI界面setting下查看到由相关分辨率。

20年11月12日新增:

在新增了该分辨率之后,发现在UI界面setting里设置1280x800分辨率,会跳到1080p分辨率去。目前没有找到原因,但是暂时解决了。

在hardware/rockchip中:

--- a/hwcomposer/hwc_rockchip.cpp
+++ b/hwcomposer/hwc_rockchip.cpp
@@ -2480,7 +2480,11 @@ int hwc_get_baseparameter_config(char *parameter, int display, int flag, int typ
                     }else{
                         vfresh = (float)clock / (htotal*vtotal);
                     }

+                                       if((h == 1280) && (w == 800))
+                                       {
+                                               if((vfresh <=60.0f) && (vfresh>=59.0f))
+                                                       vfresh = 60.0f;
+                                       }

以及

diff --git a/services/core/java/com/android/server/rkdisplay/RkDisplayModes.java b/services/core/java/com/android/server/rkdi
splay/RkDisplayModes.java
index d57e6bdb..e4755a6b 100755
--- a/services/core/java/com/android/server/rkdisplay/RkDisplayModes.java
+++ b/services/core/java/com/android/server/rkdisplay/RkDisplayModes.java
@@ -447,6 +447,9 @@ public class RkDisplayModes {
         else
             builder.append("p");
 */
+               if((info.refreshRate<60)&&(info.refreshRate>59))
+                       info.refreshRate = (float)60;


UI界面setting中设置分辨率便能正常设置了。

 

posted @ 2022-04-11 11:10  xahsxd1056  阅读(1991)  评论(0)    收藏  举报