前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >tinker board 2s android11 dsi 屏幕驱动

tinker board 2s android11 dsi 屏幕驱动

原创
作者头像
以为带点燃结局就会改变
发布2022-05-10 10:30:36
1.5K0
发布2022-05-10 10:30:36
举报
文章被收录于专栏:tinker board 2s嵌入式

上一期介绍了一下tinkerboard2 Android11下面的bootloader,这一期来介绍一下tinkerboard2在Android11下面适配DSI屏幕的方式。

硬件准备

首先介绍一下硬件。主板是华硕tinkerboard2。之前的文章已经介绍过它的硬件资源,它支持三种显示接口,包括HDMI DP DSI,可以选择其中两个接口,接两个显示屏。

电源要用12V 2A的,不然带不动屏幕,屏幕电源要由主板提供,且电源质量要比较好,不然会干扰屏幕显示。

屏幕为7寸,分辨率1024*600,如下图

屏幕出来的原始接口是不能接到主板上面的,这里要感谢深圳风火轮,他们作为华硕tinkerboard官方合作伙伴,推出了这款屏幕转接板,将屏幕的接口转换为tinkerboard2上面的DSI接口,同时引出了供电,触摸等引脚。屏幕转接板如下图。

然后需要接线,在上图中已经标明了转接板上面的接口,其中

触摸接口和屏幕接口接7寸屏的触摸排线和显示排线

Tinker board 2 mipi interface接tinker2的mipi接口,转接板附送了排线

上方排针的3.3V为屏幕逻辑板(TCON)的电源,接开发板40pin 接口的pin1

GND接pin6或者pin9都可以

BLED为背光使能,接pin17

LCD_EN为逻辑板(TCON)的使能脚,低电平有效,接pin30

如果只用到显示功能,接上面四个pin即可,另外还有触摸相关的IO,下一篇文章会介绍

Kernel部分修改

由于RK3399支持双屏显示,下面以HDMI+DSI为例介绍kernel部分的修改。

目前Android全部采用的都是Linux DRM框架进行显示,在DRM框架中,其显示通路如下图所示

图中的几个组成部分

Framebuffer:显存,嵌入式系统使用的是内存的一部分

CRTC:显示控制器,在RK3399平台是SOC 内部VOP,RK3399里面包含两个VOP;

Encoder:输出转换器,指RGB、LVDS、DSI、eDP、HDMI、CVBS、VGA 等显示接口,它本质就是一个编码器,将CRTC提供过来的信号编码为对应显示接口需要的信号。

Connector:连接器,指encoder 和panel 之间交互的接口部分;

Panel:各种具体的屏幕

因此,要驱动DSI屏幕,有三个部分需要配置,包括VOP,DSI控制器,屏幕的参数。

RK3399支持两个VOP,其支持的情况如下图

一般选择VOP和具体显示接口的对应关系时,会考虑性能问题,DP HDMI这些会使用VOPB,这样可以驱动更大分辨率的屏,市面上一般的MIPI屏分辨率不会大于1080P,用VOPB没有意义,采用VOPL足够,因此配置的时候,VOPB绑定HDMI,VOPL绑定MIPI

找到设备树kernel/arch/arm64/boot/dts/rockchip/rk3399-tinker-board-2.dtsi

首先修改VOP的配置,

代码语言:javascript
复制
&vopb {
 //打开vopb的功能
    status = "okay";
 //指定vopb的时钟,接HDMI的那个VOP clock-parents必须指定为PLL_VPLL
    assigned-clocks = <&cru DCLK_VOP0_DIV>;
    assigned-clock-parents = <&cru PLL_VPLL>;
    support-multi-area;
};
//启用mmu
&vopb_mmu {
    status = "okay";
};
&vopl {
 //打开vopl的功能
    status = "okay";
 //指定vopl的时钟,不接HDMI的VOP clock-parents用PLL_CPLL
    assigned-clocks = <&cru DCLK_VOP1_DIV>;
    assigned-clock-parents = <&cru PLL_CPLL>;
    support-multi-area;
};
//启用mmu
&vopl_mmu {
    status = "okay";
};

然后修改DSI和panel的配置。

代码语言:javascript
复制
&dsi {
    status = "okay";
 //配置dsi每个lane的频率,一般出现花屏,条纹等可以调整这个值改善
 //如果这个值不配置,DSI驱动会自动计算
    rockchip,lane-rate = <500>;
 panel@0 {
 //屏幕的具体参数,使用dsi接口的屏幕其属性必须是simple-panel-dsi
        compatible = "simple-panel-dsi";
        reg = <0>;
 //背光,即使不启用背光调节功能,这个属性也必须配置,且backlight的节点必须是有效的
 //否则驱动会加载失败
        backlight = <&backlight>;
 //使能脚,如果enable 接到一个gpio,这个属性必须设置
        enable-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
 //这些根据规格书填写即可
        bpc = <8>;
        bus-format = <0x100a>;
        width-mm = <476>;
        height-mm = <267>;
        dsi,flags = <3>;
        dsi,format = <0>;
        dsi,lanes = <4>;
 //屏幕初始化序列,屏厂会提供
        panel-init-sequence = [
            15 00 02 80 ac
            15 00 02 81 b8
            15 00 02 82 09
            15 00 02 83 78
            15 00 02 84 7f
            15 00 02 85 bb
            15 00 02 86 70
        ];
 display-timings {
            native-mode = <&timing2>;
 //下面timing的参数按wiki上面的
 timing2: timing2 {
                clock-frequency = <52000000>; //DCLK
                hactive = <1024>;             //hactive
                vactive = <600>;              //vactive
                hfront-porch = <160>;         //hfp
                hback-porch = <160>;          //hbp
                hsync-len = <10>;             //hsa
                vfront-porch = <12>;          //vfp
                vsync-len = <1>;              //vsa
                vback-porch = <23>;           //vbp
                hsync-active = <0>;           //hync 极性控制 置 1 反转极性
                vsync-active = <0>;           //vsync 极性控制 置 1 反转极性
                de-active = <1>;              //DEN 极性控制
                pixelclk-active = <0>;        //dclk 极性控制
            };
        };
 //这个ports是panel的,这个port要和dsi对应的port绑定
 ports {
            #address-cells = <1>;
            #size-cells = <0>;
 port@0 {
                reg = <0>;
 panel_in_dsi: endpoint {
                    remote-endpoint = <&dsi_out_panel>;
                };
            };
        };
    };
 //这个ports是dsi的,这个port要和目标panel的port绑定
 ports {
        #address-cells = <1>;
        #size-cells = <0>;
 port@1 {
            reg = <1>;
 dsi_out_panel: endpoint {
                remote-endpoint = <&panel_in_dsi>;
            };
        };
    };
};

然后需要设置绑定关系

代码语言:javascript
复制
//这个属性设置为okay,这样hdmi可以显示logo
&route_hdmi {
    status = "okay";
    connect = <&vopb_out_hdmi>;
};
//这个属性设置为okay,这样dsi可以显示logo
&route_dsi{
    status = "okay";
    connect = <&vopl_out_dsi>;
};
//dsi属性设置为okay时,不与它绑定的那个要设置为disabled
&dsi_in_vopb {
    status = "disabled";
};
//hdmi属性设置为okay时,不与它绑定的那个要设置为disabled
&hdmi_in_vopl {
    status = "disabled";
};

之前介绍bootloader的文章提过,其uboot会取kernel的设备树并进行一些设置,显示logo的操作是放在uboot部分,因此要配置route_dsi,这样可以让uboot将logo配置到dsi屏幕。

最后执行编译,如果之前编译过整个sdk,则编译的命令如下

代码语言:javascript
复制
./build.sh –K

最后会生成目标文件,将这个编译好的boot.img烧录到板上,然后注意一下串口的kernel log

这个log说明drm驱动已经能够正常运作

这个log说明dsi控制器已经工作,且已经绑定到drm框架中

这个log说明输出的lane clock,一般来说输出这个信息,说明dsi控制器和panel已经绑定

这个log说明panel已经工作,且输出这个log的时候,一般屏幕上面会显示一些图像

如果确认上述的log都有,到这里,应该开机,能显示出logo

到这里,kernel部分的修改完成

Android部分修改

Android里面修改的是HWComposer部分的内容,这个HWComposer被Android的SurfaceFlinger调用,操作GPU VOP RGA等的驱动。HWComposer由OEM厂商提供。RK的HWComposer有一系列系统属性,用于帮助客户能够根据需求配置显示。

在device目录下找到目前启用的产品型号对应的mk文件(如果编译的时候选择的板型是WW_Tinker_Board_2,则找到WW_Tinker_Board_2.mk,如果编译的时候选择的是rk官方版本的rk3399_Android11,则找到rk3399_Android11.mk),加入如下信息

代码语言:javascript
复制
PRODUCT_PROPERTY_OVERRIDES += \
    vendor.gralloc.no_afbc_for_fb_target_layer=1 \
    vendor.gralloc.no_afbc_for_sf_client_layer=1 \
    vendor.hwc.device.primary=HDMI-A \
    vendor.hwc.device.extend=DSI

前面两行的意思是关闭AFBDC。AFBDC 编码是 GPU 与 VOP 之前以降低带宽为目的的一种图像压缩格式,只有 VOP BIG 支持AFBDC 编码,VOP LITTLE 不支持该编码格式。如果有两个显示屏,VOPL的时候,如果不关闭AFBDC,则有可能将AFBDC 编码的framebuffer传递到VOPL,这时候会出现部分区域花屏,黑屏的现象。

后面两行则是设置主副显示屏,默认状态下,Android的窗口大小(wm size)和旋转方向跟主显示屏一致。因为这里使用的DSI屏和HDMI的横纵比差不多,如果没有特别的要求,HDMI和DSI哪个当主显示屏都可以。

修改此处后执行make –j8,烧录super.img到板上,即可正常显示出Android的画面,默认状态下,DSI和HDMI显示的内容是一样的,RK也有双屏异显的DEMO,后面再介绍。

到这里,这款风火轮为tinkerboard2定制的DSI屏幕的调试就完成了,且支持了HDMI+DSI的双屏异显。有任何疑问可到华硕官方论坛(https://tinkerboard.cn/forum.php)发帖留言。

总结

本文以tinkerboard2对接7寸1024*600分辨率的DSI屏幕为例,介绍了在tinkerboard2在Android11下面适配DSI屏幕的方式。此方法对于其他分辨率的屏幕同样适用。

上面提到的电源适配器,屏幕,转接板,都可以从深圳风火轮处购买。深圳风火轮对tinkerboard2进行了很完善的支持,同样他们还有很多其他的配件,后面会继续与大家分享。

最后还是想提一下,相比起树莓派封闭的生态,tinkerboard2开源了其Android源码,因此可以有更多的客制化功能。就拿屏幕来说,目前市面上的树莓派屏幕,多数是HDMI接口的,因为HDMI支持EDID,可以动态读取分辨率,但是很多场合HDMI屏并不适用。而树莓派支持的DSI屏幕又很有限,价格贵,因此,如果是想将产品应用于一些商显的场合,tinkerboard2无疑更加合适。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档