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 时钟翻转设置记录的更多相关文章

  1. jquery模拟LCD 时钟

    查看效果网址:http://keleyi.com/keleyi/phtml/jqtexiao/24.htm 以下是HTML文件源代码: <!DOCTYPE html PUBLIC "- ...

  2. 在Ubuntu 12.04 桌面上设置启动器(快捷方式)

    在Ubuntu 12.04 桌面上设置启动器(快捷方式)过程讲解: 如下图所示,Eclipse 和 SQLDeveloper 都可以直接双击打开,这些应用程序的启动器都在 /usr/share/app ...

  3. NTP网络授时服务器部署及网络时钟同步设置说明

    NTP网络授时服务器部署及网络时钟同步设置说明 NTP网络授时服务器部署及网络时钟同步设置说明  本文由安徽京准科技提供@请勿转载. 一.前言 1.NTP简介 NTP是网络时间协议(Network T ...

  4. iPhone 12 Pro 屏幕时间设置的密码锁出现弹窗 UI 错位重大 Bug

    iPhone 12 Pro 屏幕时间设置的密码锁出现弹窗 UI 错位重大 Bug iOS 14.1 Bug 弹窗 UI 非常丑 弹窗屏占太高了 屏幕使用时间 https://support.apple ...

  5. 12天学好C语言——记录我的C语言学习之路(Day 6)

    12天学好C语言--记录我的C语言学习之路 Day 6: 今天,我们要开始学习数组了. //①数组部分,数组的大小不能够动态定义.如下: //int n;   scanf("%d,& ...

  6. 12天学好C语言——记录我的C语言学习之路(Day 12)

    12天学好C语言--记录我的C语言学习之路 Day 12: 进入最后一天的学习,用这样一个程序来综合考量指针和字符串的关系,写完这个程序,你对字符串和指针的理解应该就不错了. //输入一个字符串,内有 ...

  7. 12天学好C语言——记录我的C语言学习之路(Day 11)

    12天学好C语言--记录我的C语言学习之路 Day 11: 因为指针部分比较的难,所以我们花费的时间也是最长的,希望大家耐的住性子,多多理解,多多打代码.好了,废话不多说,来看第11天的学习. //编 ...

  8. 12天学好C语言——记录我的C语言学习之路(Day 10)

    12天学好C语言--记录我的C语言学习之路 Day 10: 接着昨天的指针部分学习,有这么一个题目: //还是四个学生,四门成绩,只要有学生一门功课没及格就输出这个学生的所有成绩 /*//progra ...

  9. 12天学好C语言——记录我的C语言学习之路(Day 9)

    12天学好C语言--记录我的C语言学习之路 Day 9: 函数部分告一段落,但是我们并不是把函数完全放下,因为函数无处不在,我们今后的程序仍然会大量运用到函数 //转入指针部分的学习,了解指针是什么 ...

随机推荐

  1. [LeetCode] Unique Binary Search Trees 独一无二的二叉搜索树

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

  2. [LeetCode] Combination Sum 组合之和

    Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C wher ...

  3. 关于js的回调函数的一点看法

    算了一下又有好几个月没写博客了,最近在忙公司android的项目,所以也就很少抽时间来写些东西了.刚闲下来,我就翻了翻之前看的东西.做了android之后更加感觉到手机端开发的重要性,现在做nativ ...

  4. Android---观察者模式的简单实现demo

    ObserverListerner: subjectListener: 观察者管理类: 使用方法: 1. 接口: 2. 注册观察者: 3. 通知:(触发事件执行): 4. 实现方法:(都要写, 只在要 ...

  5. java Ajax的应用

    一.Ajax的使用步骤 步一:创建AJAX异步对象,例如:createAJAX() 步二:准备发送异步请求,例如:ajax.open(method,url) 步三:如果是POST请求的话,一定要设置A ...

  6. ES6深入学习记录(一)class方法相关

    今天学习class相关的一些使用方法,着重在于class extends class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多. 上面的代码定义了一 ...

  7. 由于服务器意外的断电,导致SQL SERVER服务器上数据库出现“置疑”而无法使用,

    来自百度 1.停止数据库服务器,将数据库MDF文件和LDF文件复制备份一份2.启动数据库服务器,删除置疑的数据库3.仅用备份的数据库MDF文件附加数据库,sp_attach_db或者sp_attach ...

  8. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

  9. 清北 Noip 2016 考前刷题冲刺济南班

    2016 10 29 周六 第一天 %%%,%ZHX大神 上午,60分, 下午,爆零orz 2016 10 30 周天 第二天 炒鸡倒霉的一天 %%%,%ZHX大神 据大神第一天的题最简单. 上午,和 ...

  10. 【JavaWeb】Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基础框架(五)

    SpringSecurity(2) 好久没有写了,之前只写了一半,我是一边开发一边写Blog一边上班,所以真心没有那么多时间来维护Blog,项目已经开发到编写逻辑及页面部分了,框架基本上已经搭建好不会 ...