关于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正常。
注意,背光(一线触控)必须要有且被加载才行。