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
");
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
");
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
");
375 goto fail_backlight;
376 }
377
378 if (panel_mod->enable_gpio)
379 dev_info(&pdev->dev, "found enable GPIO
");
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
");
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
");
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
");
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
", __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
", __func__);
306 return NULL;
307 }
308
309 info = kzalloc(sizeof(*info), GFP_KERNEL);
310 if (!info) {
311 pr_err("%s: allocation failed
", __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
", __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 };
重新编译设备树,重新启动,看效果。