AM335x kernel4.4.12 LCD 时钟翻转设置记录
TI AM335x kernel 4.4.12 LCD display 时钟翻转记录
因为公司硬件上已经确定LCD 转LVDS 转换芯片上确认以上升沿时钟为基准,所以只能在软件上调整相关东西。
入口在:
drivers/gpu/drm/tilcdc/tilcdc_drv.c
入口函数:
module_init(tilcdc_drm_init);
出口函数:
module_exit(tilcdc_drm_fini);
722 static int __init tilcdc_drm_init(void)
723 {
724 DBG("init");
725 tilcdc_tfp410_init();
726 tilcdc_panel_init(); ---> 这里面有关监视器的初始化----------
727 return platform_driver_register(&tilcdc_platform_driver); |
728 } |
|
|
drivers/gpu/drm/tilcdc/tilcdc_panel.c |
|
452 int __init tilcdc_panel_init(void) <--------------------------
453 {
454 return platform_driver_register(&panel_driver);
455 } |----------
|
437 static struct of_device_id panel_of_match[] = { |
438 { .compatible = "ti,tilcdc,panel", }, |
439 { }, |
440 }; |
441 |
442 struct platform_driver panel_driver = { <------------
443 .probe = panel_probe,
444 .remove = panel_remove,
445 .driver = {
446 .owner = THIS_MODULE,
447 .name = "panel",
448 .of_match_table = panel_of_match,
449 },
450 };
根据panel_of_match[].compatible = "ti,tilcdc,panel", 找到设备树相应内容。
arch/arm/boot/dts/am335x-chenfl.dts
47 panel {
48 compatible = "ti,tilcdc,panel";
49 status = "okay";
50 pinctrl-names = "default";
51 pinctrl-0 = <&lcd_pins_s0>;
52 panel-info {
53 ac-bias = <255>;
54 ac-bias-intrpt = <0>;
55 dma-burst-sz = <16>;
56 bpp = <16>;
57 fdd = <0x80>;
58 sync-edge = <0>;
59 sync-ctrl = <1>;
60 raster-order = <0>;
61 fifo-th = <0>;
62 invert-pxl-clk = <1>;
63 };
64
65 display-timings {
66 native-mode = <&timing0>;
67 timing0: 800x480 {
68 clock-frequency = <33260000>;
69 hactive = <800>;
70 vactive = <480>;
71 hfront-porch = <39>;
72 hback-porch = <39>;
73 hsync-len = <47>;
74 vback-porch = <29>;
75 vfront-porch = <13>;
76 vsync-len = <2>;
77 hsync-active = <1>;
78 vsync-active = <1>;
79 };
80 };
81 };
确定平台设备与平台驱动已经相互匹配之后,我们可以直接跟踪驱动的probe
回到drivers/gpu/drm/tilcdc/tilcdc_panel.c
看到:
442 struct platform_driver panel_driver = {
443 .probe = panel_probe,
444 .remove = panel_remove,
445 .driver = {
446 .owner = THIS_MODULE,
447 .name = "panel",
448 .of_match_table = panel_of_match,
449 },
450 };
panel_probe:
341 static int panel_probe(struct platform_device *pdev)
342 {
343 struct device_node *bl_node, *node = pdev->dev.of_node;
344 struct panel_module *panel_mod;
345 struct tilcdc_module *mod;
346 struct pinctrl *pinctrl;
347 int ret;
348 /* 如果没有设备树数据就直接跳出来 */
349 /* bail out early if no DT data: */
350 if (!node) {
351 dev_err(&pdev->dev, "device-tree data is missing\n");
352 return -ENXIO;
353 }
354
355 panel_mod = devm_kzalloc(&pdev->dev, sizeof(*panel_mod), GFP_KERNEL);
356 if (!panel_mod)
357 return -ENOMEM;
358
359 bl_node = of_parse_phandle(node, "backlight", 0);
360 if (bl_node) {
361 panel_mod->backlight = of_find_backlight_by_node(bl_node);
362 of_node_put(bl_node);
363
364 if (!panel_mod->backlight)
365 return -EPROBE_DEFER;
366
367 dev_info(&pdev->dev, "found backlight\n");
368 }
369
370 panel_mod->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
371 GPIOD_OUT_LOW);
372 if (IS_ERR(panel_mod->enable_gpio)) {
373 ret = PTR_ERR(panel_mod->enable_gpio);
374 dev_err(&pdev->dev, "failed to request enable GPIO\n");
375 goto fail_backlight;
376 }
377
378 if (panel_mod->enable_gpio)
379 dev_info(&pdev->dev, "found enable GPIO\n");
380
381 mod = &panel_mod->base;
382 pdev->dev.platform_data = mod;
383
384 tilcdc_module_init(mod, "panel", &panel_module_ops);
385
386 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
387 if (IS_ERR(pinctrl))
388 dev_warn(&pdev->dev, "pins are not configured\n");
389 /* 对应时序的设置,和设备树中的display-timings 有关 */
390 panel_mod->timings = of_get_display_timings(node);
391 if (!panel_mod->timings) {
392 dev_err(&pdev->dev, "could not get panel timings\n");
393 ret = -EINVAL;
394 goto fail_free;
395 }
396 /* 对应的相关信息设置,跟panel-info 这个节点有关 */
397 panel_mod->info = of_get_panel_info(node);
398 if (!panel_mod->info) {
399 dev_err(&pdev->dev, "could not get panel info\n");
400 ret = -EINVAL;
401 goto fail_timings;
402 }
403
404 mod->preferred_bpp = panel_mod->info->bpp;
405
406 return 0;
407
408 fail_timings:
409 display_timings_release(panel_mod->timings);
410
411 fail_free:
412 tilcdc_module_cleanup(mod);
413
414 fail_backlight:
415 if (panel_mod->backlight)
416 put_device(&panel_mod->backlight->dev);
417 return ret;
418 }
/* 这是上面的 of_get_panel_info 传进来的 */
292 static struct tilcdc_panel_info *of_get_panel_info(struct device_node *np)
293 {
294 struct device_node *info_np;
295 struct tilcdc_panel_info *info;
296 int ret = 0;
297
298 if (!np) {
299 pr_err("%s: no devicenode given\n", __func__);
300 return NULL;
301 }
302
303 info_np = of_get_child_by_name(np, "panel-info");
304 if (!info_np) {
305 pr_err("%s: could not find panel-info node\n", __func__);
306 return NULL;
307 }
308
309 info = kzalloc(sizeof(*info), GFP_KERNEL);
310 if (!info) {
311 pr_err("%s: allocation failed\n", __func__);
312 of_node_put(info_np);
313 return NULL;
314 }
315 /* 这里我们可以看到,如果一个出错,ret 就会为真,这是上面的设备树的必需选项的配对 */
316 ret |= of_property_read_u32(info_np, "ac-bias", &info->ac_bias);
317 ret |= of_property_read_u32(info_np, "ac-bias-intrpt", &info->ac_bias_intrpt);
318 ret |= of_property_read_u32(info_np, "dma-burst-sz", &info->dma_burst_sz);
319 ret |= of_property_read_u32(info_np, "bpp", &info->bpp);
320 ret |= of_property_read_u32(info_np, "fdd", &info->fdd);
321 ret |= of_property_read_u32(info_np, "sync-edge", &info->sync_edge);
322 ret |= of_property_read_u32(info_np, "sync-ctrl", &info->sync_ctrl);
323 ret |= of_property_read_u32(info_np, "raster-order", &info->raster_order);
324 ret |= of_property_read_u32(info_np, "fifo-th", &info->fifo_th);
325
326 /* optional: */
/* 这是可选选项,下面第二个则是时钟反转的选项。在设备中添加一个选项即可。 */
327 info->tft_alt_mode = of_property_read_bool(info_np, "tft-alt-mode");
328 info->invert_pxl_clk = of_property_read_bool(info_np, "invert-pxl-clk");
329
330 if (ret) {
331 pr_err("%s: error reading panel-info properties\n", __func__);
332 kfree(info);
333 of_node_put(info_np);
334 return NULL;
335 }
336 of_node_put(info_np);
337
338 return info;
339 }
/* 设备树修改 */
47 panel {
48 compatible = "ti,tilcdc,panel";
49 status = "okay";
50 pinctrl-names = "default";
51 pinctrl-0 = <&lcd_pins_s0>;
52 panel-info {
53 ac-bias = <255>;
54 ac-bias-intrpt = <0>;
55 dma-burst-sz = <16>;
56 bpp = <16>;
57 fdd = <0x80>;
58 sync-edge = <0>;
59 sync-ctrl = <1>;
60 raster-order = <0>;
61 fifo-th = <0>;
62 invert-pxl-clk = <1>; /* 添加这个选项设置为1 */
63 };
重新编译设备树,重新启动,看效果。
AM335x kernel4.4.12 LCD 时钟翻转设置记录的更多相关文章
- jquery模拟LCD 时钟
查看效果网址:http://keleyi.com/keleyi/phtml/jqtexiao/24.htm 以下是HTML文件源代码: <!DOCTYPE html PUBLIC "- ...
- 在Ubuntu 12.04 桌面上设置启动器(快捷方式)
在Ubuntu 12.04 桌面上设置启动器(快捷方式)过程讲解: 如下图所示,Eclipse 和 SQLDeveloper 都可以直接双击打开,这些应用程序的启动器都在 /usr/share/app ...
- NTP网络授时服务器部署及网络时钟同步设置说明
NTP网络授时服务器部署及网络时钟同步设置说明 NTP网络授时服务器部署及网络时钟同步设置说明 本文由安徽京准科技提供@请勿转载. 一.前言 1.NTP简介 NTP是网络时间协议(Network T ...
- iPhone 12 Pro 屏幕时间设置的密码锁出现弹窗 UI 错位重大 Bug
iPhone 12 Pro 屏幕时间设置的密码锁出现弹窗 UI 错位重大 Bug iOS 14.1 Bug 弹窗 UI 非常丑 弹窗屏占太高了 屏幕使用时间 https://support.apple ...
- 12天学好C语言——记录我的C语言学习之路(Day 6)
12天学好C语言--记录我的C语言学习之路 Day 6: 今天,我们要开始学习数组了. //①数组部分,数组的大小不能够动态定义.如下: //int n; scanf("%d,& ...
- 12天学好C语言——记录我的C语言学习之路(Day 12)
12天学好C语言--记录我的C语言学习之路 Day 12: 进入最后一天的学习,用这样一个程序来综合考量指针和字符串的关系,写完这个程序,你对字符串和指针的理解应该就不错了. //输入一个字符串,内有 ...
- 12天学好C语言——记录我的C语言学习之路(Day 11)
12天学好C语言--记录我的C语言学习之路 Day 11: 因为指针部分比较的难,所以我们花费的时间也是最长的,希望大家耐的住性子,多多理解,多多打代码.好了,废话不多说,来看第11天的学习. //编 ...
- 12天学好C语言——记录我的C语言学习之路(Day 10)
12天学好C语言--记录我的C语言学习之路 Day 10: 接着昨天的指针部分学习,有这么一个题目: //还是四个学生,四门成绩,只要有学生一门功课没及格就输出这个学生的所有成绩 /*//progra ...
- 12天学好C语言——记录我的C语言学习之路(Day 9)
12天学好C语言--记录我的C语言学习之路 Day 9: 函数部分告一段落,但是我们并不是把函数完全放下,因为函数无处不在,我们今后的程序仍然会大量运用到函数 //转入指针部分的学习,了解指针是什么 ...
随机推荐
- [LeetCode] Count Complete Tree Nodes 求完全二叉树的节点个数
Given a complete binary tree, count the number of nodes. Definition of a complete binary tree from W ...
- [LeetCode] Add and Search Word - Data structure design 添加和查找单词-数据结构设计
Design a data structure that supports the following two operations: void addWord(word) bool search(w ...
- ASP.NET MVC VS2010中更改默认调试浏览器
在Visual Studio 2010(RC)中右键点击 .aspx 页面已不复存在"browse with"菜单项.那要如何修改调试时使用的默认浏览器呢? 默认情况下,VS会使用 ...
- java-w3c.document生成xml文件
案例 /** * 创建和写入xml * @param xmlrootname * @param waitConverList */ private void createAndWriterXML(St ...
- 为什么要用 WebSocket
使用传统的 HTTP 轮询或者长连接的方式也可以实现类似服务器推送的效果,但是这类方式都存在资源消耗过大或推送延迟等问题.而 WebSocket 直接使用 TCP 连接保持全双工的传输,可以有效地减少 ...
- asp.net配置web.config支持jQuery.Uploadify插件上传大文件
配置web.config有两处地方需要配置,分别是集成模式和经典模式. 集成模式: <!--文件上传大小设置--> <httpRuntime requestValidationMod ...
- MySQL二进制日志
一.二进制日志(The Binary Log) 1.简介 包含所有更新了的数据或者已经潜在更新了的数据(比如一条没有匹配任何行的delete语句) 包含所有更新语句执行时间的信息 不记录没有修改数据的 ...
- Beta阶段第十次Scrum Meeting
情况简述 BETA阶段第十次Scrum Meeting 敏捷开发起始时间 2017/1/4 00:00 敏捷开发终止时间 2017/1/5 00:00 会议基本内容摘要 deadline到来 参与讨论 ...
- 基于Dubbo框架构建分布式服务(一)
Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配 ...
- HDU3394:Railway
传送门 点双练习. 对于一张图,询问有多少条边不属于任意一个点双和多少条边至少属于两个点双. 显然,一张图里有多少个桥就是第一问的答案. 对于第二问,考虑对于一个点双,如果其中的边数等于点数,那么这个 ...