tinkerboard2 Android11系列-DSI屏幕的支持

上一期介绍了一下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的配置,

&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的时钟,不接HDMIVOP clock-parentsPLL_CPLL

    assigned-clocks = <&cru DCLK_VOP1_DIV>;

    assigned-clock-parents = <&cru PLL_CPLL>;

    support-multi-area;

};

//启用mmu

&vopl_mmu {

    status = "okay";

};

然后修改DSI和panel的配置。其中panel的配置,是参考风火轮的wiki, http://wiki.smartfire.cn/Tinkerboard2/lcd

&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 极性控制

            };

        };

        //这个portspanel的,这个port要和dsi对应的port绑定

        ports {

            #address-cells = <1>;

            #size-cells = <0>;

            port@0 {

                reg = <0>;

                panel_in_dsi: endpoint {

                    remote-endpoint = <&dsi_out_panel>;

                };

            };

        };

    };

    //这个portsdsi的,这个port要和目标panelport绑定

    ports {

        #address-cells = <1>;

        #size-cells = <0>;

        port@1 {

            reg = <1>;

            dsi_out_panel: endpoint {

                remote-endpoint = <&panel_in_dsi>;

            };

        };

    };

};

然后需要设置绑定关系

//这个属性设置为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屏幕

然后是驱动文件的修改,vop和dsi控制器的驱动不用改,而panel的驱动,因为被asus在rk原始版本的基础上修改过,要修改一下,这里有两种修改方式

方式一,采用风火轮电子wiki里面的方式

方式二,直接去rk官方的git上面下载一个,将sdk里面的panel-simple.c替换掉,地址为kernel/panel-simple.c at develop-4.19 · rockchip-linux/kernel · GitHub

两种方式效果一样

另外还要配置一下menuconfig,按照风火轮wiki里面描述的

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

./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),加入如下信息

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的双屏异显。

总结

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

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

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

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值