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中设置分辨率便能正常设置了。

浙公网安备 33010602011771号