Android版本:5.1
内核版本:3.10.79
要使板子HDMI输出4K,需要修改内核层和Android framework层。
一、内核层修改
在没修改内核前,adb进入shell,
cd /sys/class/display/HDMI;cat modes,输出当前显示器支持的显示格式。
即使显示器支持4K显示,这里也不会有4K分辨率(3840x2160)。修改内核层目标是使这里识别出4K分辨率。
内核层只需要修改对应dts即可,修改地方为2处,一是禁用掉VGA,
二是修改disp_timings。进入目录firefly-rk3288_android5.1_git/kernel/arch/arm/boot/dts,该Android系统使用的dts为firefly-rk3288.dts,打开该文件,发现该dts引用了
#include "rk3288.dtsi"
#include "lcd-box.dtsi"
两个头文件。
①禁用掉VGA
在rk3288.dtsi,找到hdmi标签:
hdmi: hdmi@ff980000 {
compatible = "rockchip,rk3288-hdmi";
reg = <0xff980000 0x20000>;
interrupts = ;
pinctrl-names = "default", "sleep";
pinctrl-0 = ;
pinctrl-1 = ;
clocks = , ,;
clock-names = "pclk_hdmi", "hdcp_clk_hdmi","cec_clk_hdmi";
//rockchip,hdmi_video_source = ;
rockchip,hdmi_video_source =;
rockchip,hdmi_audio_source = <0>;
rockchip,hdcp_enable = <0>;
rockchip,cec_enable = <0>;
status = "disabled";
};
这里修改rockchip,hdmi_video_source 为DISPLAY_SOURCE_LCDC0;即HDMI的视频源为lcdc0。
【说明】因为dtsi文件可能有其他dts引用,最好不要直接修改dtsi文件,而是应该在设备dts即firefly-rk3288.dts中通过引用的方式对欲修改的项目进行覆盖修改。例如,上面修改可以在firefly-rk3288.dts中添加
&hdmi {
rockchip,hdmi_video_source =;
};
这里为了方便,就直接修改了dtsi,但是不提倡。
然后修改firefly-rk3288.dts,打开该文件,发现vga相关设备都挂在i2c4下,并且该控制器下没有挂其它设备,直接禁用掉该路I2C控制器省事,修改 status = "disabled"。
&i2c4 {
//status = "okay";
status = "disabled";
。。。下面省略。。。
}
这时候lcdc1已经没用了,直接禁用掉:
&lcdc1 {
//status = "okay";
status = "disabled";
rockchip,iommu-enabled = <1>;
rockchip,prop = ;
};
②修改disp_timings显示时序
在lcd-box.dtsi中已经定义好了3组timing:timing0、timing1、timing2。它们对应的最大显示分辨率依次增加,当前使用模式通过native-mode指定,在该文件中默认native-mode = 。我们不在该dtsi文件中进行修改,而是在firefly-rk3288.dts中覆盖修改。打开firefly-rk3288.dts,找到disp_timings,修改为timing2:
&disp_timings {
native-mode = ;
};
这里对timing2定义也进行了一些修改,由原来的3840x2160改成了1920x1080;如果不修改会使安卓显示内容过小,看是来不舒服(或许也可以通过修改build.prop的lcd_density来改善,没尝试)。
上面这个得去掉,必须是3840*2160才可以(2018-07-13)!
进行完上述修改后,内核层修改完成,这时烧入新的设备树,cd /sys/class/display/HDMI;cat modes:
auto
3840x2160p-30
3840x2160p-25
3840x2160p-24
1920x1080p-60
1920x1080p-50
1920x1080p-24
1280x720p-60
1280x720p-50
720x576p-50
720x480p-60复制代码发现4K显示器支持的分辨率都已经有了。
【遇到的坑】我在烧写RK3288设备树的时候,遇到了一个坑,无论怎么烧写resource.img(内包含最新的设备树),新的设备树根本不起作用,甚至擦除掉kernel.img和resource.img所在分区的内容,系统也能照常起来。后来发现内核和设备树都是使用的boot.img里面的,但是通过使用安卓源码里面的mkimage.sh默认生成的boot.img不包含kernel和resource,后来我修改了mkimage.sh,使里面的TARGET=$BOOT_OTA,才生成了包含内核和dtb的boot.img,重新烧写了生成的boot.img才使修改生效。在此记录一下。
二、安卓层修改因为该安卓硬件抽象层里rockchip对分辨率进行了限制,强制忽略了1080p以上的分辨率,这里取消该限制。
进入hardware/rockchip/hwcomposer目录,修改rk_hwcomposer.cpp文件:
在hotplug_set_config()函数里,找到:
} else if(ctxp->dpyAttr[dType].yres > 1080) {
这一行,修改为:
} else if(ctxp->dpyAttr[dType].yres > 2160) { 即可
int hotplug_set_config()
{
int dType = HWC_DISPLAY_EXTERNAL;
hwcContext * ctxp = _contextAnchor;
hwcContext * ctxe = _contextAnchor1;
if(ctxe != NULL) {
ctxp->dpyAttr[dType].fd = ctxe->dpyAttr[dType].fd;
ctxp->dpyAttr[dType].stride = ctxe->dpyAttr[dType].stride;
ctxp->dpyAttr[dType].xres = ctxe->dpyAttr[dType].xres;
ctxp->dpyAttr[dType].yres = ctxe->dpyAttr[dType].yres;
ctxp->dpyAttr[dType].xdpi = ctxe->dpyAttr[dType].xdpi;
ctxp->dpyAttr[dType].ydpi = ctxe->dpyAttr[dType].ydpi;
ctxp->dpyAttr[dType].vsync_period = ctxe->dpyAttr[dType].vsync_period;
ctxp->dpyAttr[dType].connected = true;
if(ctxp->mIsDualViewMode) {
ctxp->dpyAttr[dType].xres = ctxe->dpyAttr[dType].xres * 2;
ctxp->dpyAttr[dType].yres = ctxe->dpyAttr[dType].yres;
ctxe->mIsDualViewMode = true;
LOGV("w_s,h_s,w_d,h_d = [%d,%d,%d,%d]",
ctxp->dpyAttr[dType].xres,ctxp->dpyAttr[dType].yres,
ctxe->dpyAttr[dType].xres,ctxe->dpyAttr[dType].yres);
//} else if(ctxp->dpyAttr[dType].yres > 1080) {
} else if(ctxp->dpyAttr[dType].yres > 2160) {
ctxp->dpyAttr[dType].xres = 1920;
ctxp->dpyAttr[dType].yres = 1080;
ctxp->mHdmiSI.NeedReDst = true;
LOGV("w_s,h_s,w_d,h_d = [%d,%d,%d,%d]",
ctxp->dpyAttr[dType].xres,ctxp->dpyAttr[dType].yres,
ctxe->dpyAttr[dType].xres,ctxe->dpyAttr[dType].yres);
} else {
ctxp->mIsDualViewMode = false;
ctxp->mHdmiSI.NeedReDst = false;
}
return 0;
} else {
ctxp->dpyAttr[dType].connected = false;
ctxp->mIsDualViewMode = false;
ALOGE("hotplug_set_config fail,ctxe is null");
return -ENODEV;
}
}
所有上述修改完成后,重现编译安卓系统,生成system.img后,烧写,安卓HDMI就完美支持4K了。
另外:如果感觉4K下字体太小,是因为默认的density 160太小造成的,可以在adb shell下执行
wm density看下默认density,执行wm density 320 看下界面就比较合适了;修改/system/build.prop:
ro.sf.lcd_density=320
就可以了(编译前修改或者烧写后adb root;adb remount挂载/system可读写后修改也可以)。
|