tiny4412 驱动 (19)设备树之lcd驱动(基于DRM)

关于DRM,参考https://blog.csdn.net/hexiaolong2009/category_9281458.html

前面基于传统framebuffer的驱动,作为模块加载时没问题, 和内核一起编译后,内核启动到文件系统时LCD不再显示。

echo hello > /dev/tty1也不会有任何反应。目前得到的信息, 和内核一起编译后LCD控制寄存器的值全部变成了0;原因不明。

 

现在换个思路,使用DRM框架来写LCD驱动。其实非常简单。

参考:

Documentation/devicetree/bindings/display/panel/display-timing.txt
Documentation/devicetree/bindings/media/video-interfaces.txt
Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt

 

我们需要的设备树文件:

&fimd {
        pinctrl-0 = <&lcd_clk &lcd_data24 &pwm1_out>;
        pinctrl-names = "default";
        samsung,invert-vclk;     //vclk翻转
        status = "okay";

        display-timings {
                native-mode = <&timing0>;
                timing0: timing {
                        pixelclk-active = <1>;
                        clock-frequency = <50000000>;
                        hactive = <1024>;
                        vactive = <600>;
                        hfront-porch = <80>;
                        hback-porch = <36>;
                        hsync-len = <10>;
                        vback-porch = <15>;
                        vfront-porch = <1>;
                        vsync-len = <8>;
                };
        };
};

在make menuconfig里面配置

Device Drivers  ---> 
	Graphics support  --->
		<*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)  --->
		<*> DRM Support for Samsung SoC EXYNOS Series
		[*]   FIMD 
		[*]   Virtual Display 
		[*]   Parallel output

编译后重新加载内核,log

[    2.295886] [drm] Exynos DRM: using 11c00000.fimd device for DMA mapping operations
[    2.301078] exynos-drm exynos-drm: bound 11c00000.fimd (ops fimd_component_ops)
[    2.307068] exynos-drm exynos-drm: bound exynos-drm-vidi (ops vidi_component_ops)
[    2.314410] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[    2.320960] [drm] No driver support for vblank timestamp query.
[    2.335615] [drm] sclk_fimd clock too low(1500000) for requested pixel clock(50000000)
[    2.336165] [drm] sclk_fimd clock too low(1500000) for requested pixel clock(50000000)
[    2.344475] [drm] sclk_fimd clock too low(1500000) for requested pixel clock(50000000)
[    2.344655] [drm] sclk_fimd clock too low(1500000) for requested pixel clock(50000000)
[    2.351467] Console: switching to colour frame buffer device 128x37
[    2.351582] [drm] sclk_fimd clock too low(1500000) for requested pixel clock(50000000)
[    2.375919] exynos-drm exynos-drm: fb0:  frame buffer device
[    2.384032] [drm] Initialized exynos 1.1.0 20180330 for exynos-drm on minor 0

很明显,时钟不对,只有1.5MHz

期望时钟频率50MHz。


static int fimd_atomic_check(struct exynos_drm_crtc *crtc,
		struct drm_crtc_state *state)
{
    ...
    ideal_clk = mode->clock * 1000;
    lcd_rate = clk_get_rate(ctx->lcd_clk);
    if (2 * lcd_rate < ideal_clk) {
		DRM_INFO("sclk_fimd clock too low(%lu) for requested pixel clock(%lu)\n",
			 lcd_rate, ideal_clk);
		return -EINVAL;
	}
    ...
}

可知,时钟源应该大于50M*2

时钟为什么只有1.5MHz呢?

猜测sclk_fimd0的时钟源选为了XusbXTI,即24M,然后16分频分频得到1.5M。如果我们希望得到50M,那么时钟源应该时SCLK_MPLL_USER_T,而且时钟要设置为800M (800 / 16 = 50M)

将sclk_fimd时钟变成800M

vim drivers/clk/samsung/clk-exynos4.c

static void __init exynos4_clk_init(struct device_node *np,
                                    enum exynos4_soc soc)
{
...
    struct clk *mout_mpll_user_t    = NULL;
    struct clk *mount_fimd0         = NULL;
    struct clk *sclk_fimd0          = NULL;

    int ret = 0;

...
   mout_mpll_user_t = __clk_lookup("mout_mpll_user_t");
    if (IS_ERR(mout_mpll_user_t)) {
            pr_info("failed to get mout_mpll_user_t clock\n");
            return;
    }

    mount_fimd0 = __clk_lookup("mout_fimd0");
    if (IS_ERR(mount_fimd0)) {
            pr_info("failed to get mout_fimd0 clock\n");
            return ;
    }

    sclk_fimd0 = __clk_lookup("sclk_fimd0");
        if (IS_ERR(sclk_fimd0)) {
                pr_info("failed to get sclk_fimd0 clock\n");
                return ;
        }
        clk_set_parent(mount_fimd0,mout_mpll_user_t);

        ret = clk_set_rate(mount_fimd0,800000000);
        if(ret){
                pr_info("failed to clock set rate\n");
                return ;
        }

        ret = clk_set_rate(sclk_fimd0,800000000);
        if(ret){
                pr_info("failed to clock set rate\n");
                return ;
        }

        pr_info("[drm] mout_mpll_user_t = %ld mount_fimd0 = %ld sclk_fimd0 = %ld\n",
                        clk_get_rate(mout_mpll_user_t),clk_get_rate(mount_fimd0),clk_get_rate(sclk_fimd0));	


...

}

最终,输出日志:

[    2.304538] [drm] Exynos DRM: using 11c00000.fimd device for DMA mapping operations
[    2.309715] exynos-drm exynos-drm: bound 11c00000.fimd (ops fimd_component_ops)
[    2.315699] exynos-drm exynos-drm: bound exynos-drm-vidi (ops vidi_component_ops)
[    2.323006] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[    2.329625] [drm] No driver support for vblank timestamp query.
[    2.438170] Console: switching to colour frame buffer device 128x37
[    2.459272] exynos-drm exynos-drm: fb0:  frame buffer device
[    2.462032] [drm] Initialized exynos 1.1.0 20180330 for exynos-drm on minor 0

可以看到LCD正常。

注意,背光(一线触控)必须要有且被加载才行。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值