文章目录

  • 写在前面
  • 一、DRM基础
  • 二、DRM相关目录结构
  • 三、设备树
  • 四、component

写在前面

主要是介绍一下rk平台px30 移植LCD屏的工作心得

一、DRM基础

二、DRM相关目录结构

driver file doc
Core rockchip_drm_drv.c
Framebufferrock chip_drm_fb.c
GEM rockchip_drm_gem.c
VOP rockchip_drm_vop.c ,rockchip_vop_reg.c
LVDS rockchip_lvds.c
RGB rockchip_rgb.c
MIPI dw_mipi_dsi.c,phy_rockchip-inno-mipi-dphy.c
HDMI dw_hdmi-rockchip.c,dw-hdmi.c
INNO HDMI inno_hdmi.c
eDp analogix_dp-rockchip.c,analogix_dp_core.c,analogix_dp_reg.c,phy-rockchip-dp.c
DP cdn-dp-core.c,cdn-dp-reg.c
Panel panel-simple.c

三、设备树

绑定路径如下

//数据传递流程如下:
vop(相当于显示控制器) --> dis/vlds/edp/rgb(相当于encoder) --> panel(相当于显示器)
//分析2代的配置,数据流向
vopb_out_rgb -> rgb_in_vopb -> rgb_out_panel -> panel_in_rgb
//phy
&video_phy {status = "okay";
};//vop 配置
&display_subsystem {status = "okay";
};&rgb_in_vopb {status = "okay";
};&rgb_in_vopl {status = "disabled";
};
&route_rgb {connect = <&vopb_out_rgb>;//这块使能了,相当于使能了vopb_out_rgb输出status = "okay";
};//总结:以上配置相当于配置了vop -> vopb -> vopb_out_rgb//配置encoder
&rgb {//1.这块使能相当于使能了encoderstatus = "okay";ports {port@1 {reg = <1>;rgb_out_panel: endpoint {//2.这块定义了连接的panel,即显示器remote-endpoint = <&panel_in_rgb>;};};};
};//配置panel,在panel中设置与液晶屏相关内容,例如分辨率、时钟,时序等各参数
panel {compatible = "simple-panel";backlight = <&backlight>;power-supply = <&vcc_lcd>;enable-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;// prepare-delay-ms = <120>;// enable-delay-ms = <120>;// disable-delay-ms = <120>;// unprepare-delay-ms = <120>;bus-format = <MEDIA_BUS_FMT_RBG888_1X24>;width-mm = <108>;height-mm = <64>;display-timings {native-mode = <&timing0>;timing0: timing0 {clock-frequency = <33300000>;hactive = <800>;vactive = <480>;hback-porch = <36>;hfront-porch = <210>;vback-porch = <13>;vfront-porch = <22>;hsync-len = <10>;vsync-len = <10>;hsync-active = <0>;vsync-active = <0>;de-active = <1>;pixelclk-active = <1>;};};port {panel_in_rgb: endpoint {remote-endpoint = <&rgb_out_panel>;};};};
};

四、component

在DRM、ALSA等子系统中,通过超级设备(superdevice)管理多个组件(component)加载顺序,保证所有组件都可正常使用,在drm驱动中,component设备用来表示vop和各显示接口(如:HDMI、MIPI等)

在设备树中定义了如下的显示子系统

&display_subsystem {status = "disabled";ports = <&vopb_out>, <&vopl_out>;logo-memory-region = <&drm_logo>;route {route_lvds: route-lvds {status = "disabled";logo,uboot = "logo.bmp";logo,kernel = "logo_kernel.bmp";logo,mode = "center";charge_logo,mode = "center";connect = <&vopb_out_lvds>;};route_dsi: route-dsi {status = "disabled";logo,uboot = "logo.bmp";logo,kernel = "logo_kernel.bmp";logo,mode = "center";charge_logo,mode = "center";connect = <&vopb_out_dsi>;};route_rgb: route-rgb {status = "disabled";logo,uboot = "logo.bmp";logo,kernel = "logo_kernel.bmp";logo,mode = "center";charge_logo,mode = "center";connect = <&vopb_out_rgb>;};};
};

其中添加vop组件

struct platform_driver vop_platform_driver = {.probe = vop_probe,.remove = vop_remove,.driver = {.name = "rockchip-vop",.owner = THIS_MODULE,.of_match_table = of_match_ptr(vop_driver_dt_match),},
};
//探测函数 添加组件
static int vop_probe(struct platform_device *pdev)
{struct device *dev = &pdev->dev;if (!dev->of_node) {dev_err(dev, "can't find vop devices\n");return -ENODEV;}//添加组件return component_add(dev, &vop_component_ops);
}

添加rgb组件

static const struct of_device_id rockchip_rgb_dt_ids[] = {{ .compatible = "rockchip,px30-rgb", .data = &px30_rgb_funcs },{ .compatible = "rockchip,rk1808-rgb", .data = &rk1808_rgb_funcs },{ .compatible = "rockchip,rk3066-rgb", },{ .compatible = "rockchip,rk3128-rgb", },{ .compatible = "rockchip,rk3288-rgb", .data = &rk3288_rgb_funcs },{ .compatible = "rockchip,rk3308-rgb", },{ .compatible = "rockchip,rk3368-rgb", },{ .compatible = "rockchip,rv1108-rgb", },{}
};
MODULE_DEVICE_TABLE(of, rockchip_rgb_dt_ids);static struct platform_driver rockchip_rgb_driver = {.probe = rockchip_rgb_probe,.remove = rockchip_rgb_remove,.driver = {.name = "rockchip-rgb",.of_match_table = of_match_ptr(rockchip_rgb_dt_ids),},
};
//探测函数 添加组件
static int rockchip_rgb_probe(struct platform_device *pdev)
{struct device *dev = &pdev->dev;struct rockchip_rgb *rgb;int ret;rgb = devm_kzalloc(&pdev->dev, sizeof(*rgb), GFP_KERNEL);if (!rgb)return -ENOMEM;rgb->dev = dev;rgb->funcs = of_device_get_match_data(dev);platform_set_drvdata(pdev, rgb);rgb->data_sync = of_property_read_bool(dev->of_node,"rockchip,data-sync");if (dev->parent && dev->parent->of_node) {rgb->grf = syscon_node_to_regmap(dev->parent->of_node);if (IS_ERR(rgb->grf)) {ret = PTR_ERR(rgb->grf);dev_err(dev, "Unable to get grf: %d\n", ret);return ret;}}rgb->phy = devm_phy_optional_get(dev, "phy");if (IS_ERR(rgb->phy)) {ret = PTR_ERR(rgb->phy);dev_err(dev, "failed to get phy: %d\n", ret);return ret;}//添加组件return component_add(dev, &rockchip_rgb_component_ops);
}

其实核心函数为

static const struct of_device_id rockchip_drm_dt_ids[] = {{ .compatible = "rockchip,display-subsystem", },{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, rockchip_drm_dt_ids);static struct platform_driver rockchip_drm_platform_driver = {.probe = rockchip_drm_platform_probe,.remove = rockchip_drm_platform_remove,.shutdown = rockchip_drm_platform_shutdown,.driver = {.name = "rockchip-drm",.of_match_table = rockchip_drm_dt_ids,.pm = &rockchip_drm_pm_ops,},
};static int rockchip_drm_platform_probe(struct platform_device *pdev)
{struct device *dev = &pdev->dev;struct component_match *match = NULL;struct device_node *np = dev->of_node;struct device_node *port;int i;DRM_INFO("Rockchip DRM driver version: %s\n", DRIVER_VERSION);if (!np)return -ENODEV;/** Bind the crtc ports first, so that* drm_of_find_possible_crtcs called from encoder .bind callbacks* works as expected.*/for (i = 0;; i++) {struct device_node *iommu;port = of_parse_phandle(np, "ports", i);if (!port)break;if (!of_device_is_available(port->parent)) {of_node_put(port);continue;}iommu = of_parse_phandle(port->parent, "iommus", 0);if (!iommu || !of_device_is_available(iommu->parent)) {dev_dbg(dev, "no iommu attached for %s, using non-iommu buffers\n",port->parent->full_name);/** if there is a crtc not support iommu, force set all* crtc use non-iommu buffer.*/is_support_iommu = false;}component_match_add(dev, &match, compare_of, port->parent);of_node_put(port);}if (i == 0) {dev_err(dev, "missing 'ports' property\n");return -ENODEV;}if (!match) {dev_err(dev, "No available vop found for display-subsystem.\n");return -ENODEV;}/** For each bound crtc, bind the encoders attached to its* remote endpoint.*/for (i = 0;; i++) {port = of_parse_phandle(np, "ports", i);if (!port)break;if (!of_device_is_available(port->parent)) {of_node_put(port);continue;}rockchip_add_endpoints(dev, &match, port);of_node_put(port);}port = of_parse_phandle(np, "backlight", 0);if (port && of_device_is_available(port)) {component_match_add(dev, &match, compare_of, port);of_node_put(port);}return component_master_add_with_match(dev, &rockchip_drm_ops, match);
}

component_master_add_with_match的函数调用栈为

rockchip_drm_platform_probecomponent_master_add_with_matchtry_to_bring_up_masterfind_components/* Found all components */rockchip_drm_bind //ret = master->ops->bind(master->dev);component_bind_allcomponent->ops->bind //循环bind了所有组件

其实 也就是这张图

2.1 px30驱动移植-DRM驱动框架简介相关推荐

  1. 【华为云技术分享】小熊派华为物联网操作系统LiteOS裸机驱动移植02-LCD驱动移植及使用

    1. LCD裸机驱动 小熊派开发板使用的LCD屏幕为1.3寸的TFT彩屏,色彩深度16bit,分辨率240*240,使用 SPI 接口与 MCU 之间通信. 如果你对裸机玩转LCD屏幕还不熟悉,请先阅 ...

  2. Linux 音频驱动(一) ASoC音频框架简介

    目录 1. ALSA简介 2. ASoC音频驱动构成 3. PCM数据流 4. 数据结构简介 5. ASoC音频驱动注册流程 1. ALSA简介 Native ALSA Application:tin ...

  3. uboot 下spinand 驱动移植 ———1.驱动接口的添加到uboot中

    前面有篇文章谈到:https://blog.csdn.net/clam_zxf/article/details/108834541 平台驱动和单片机驱动异同,同样可以将uboot 除去它的引导加载:所 ...

  4. android nfc驱动,移植NFC驱动到android系统

    1>>>进入kernel目录,替换driver层文件: kernel/drivers/nfc/pn544.c kernel/include/linux/nfc/pn544.h 更新n ...

  5. GD32F4xx 以太网芯片(enc28j60)驱动移植

    1.enc28j60 简介 ENC28J60 是带有行业标准串行外设接口(SPI)的独立以太网控制器. 主要特性: (1)SPI最高通信速率:10Mb/s.只支持SPI的模式0,0,且SPI端口要求S ...

  6. 基于I.MX6UL平台的WIFI模块AP6214A 驱动移植

    基于I.MX6UL平台的WIFI模块AP6214A 驱动移植 IoT-6ULX简要介绍 IoT-6ULX,主要面向Internet Of Things应用,该产品集成了 ARM Cortex-A7 9 ...

  7. BH1750 传感器实战教学 —— 驱动移植篇

    前言 上一篇 BH1750 的实战教学我们说明的实际应用中传感器的硬件设计 : BH1750 传感器实战教学 -- 硬件设计篇 我们提到过在本次使用的芯片为 51 内核,I2C 通讯驱动实现与 STM ...

  8. 4G模块 EC20 R2.0 USB Serial/GobiNet/QMI WWAN 驱动移植过程

    4G模块 EC20 R2.0 USB Serial/GobiNet/QMI WWAN 驱动移植过程 一.开发环境 二.确定 EC20 R2.0 的基本信息 三.USB Serial 驱动移植 opti ...

  9. A20 wifi驱动移植

    A20 wifi驱动移植 本驱动移植是在ak27的平台上移植8089wifi驱动,驱动名字为eagle 一.lichee部分移植 测试模式部分: dragonboard下的文件主要是针对wifi在测试 ...

  10. DRM框架(vkms)分析(9)----drm驱动创建fbdevice分析(以rockchip_drm_drv为例)

    本文主要介绍DRM框架里的fbdev兼容逻辑 一 framebuffer框架简单介绍 framebuffer框架下fbdev的注册主要三步步: (1)创建fbdev操作函数,以rockchip为例: ...

最新文章

  1. 【Android UI设计与开发】第04期:引导界面(四)仿人人网V5.9.2最新版引导界面
  2. Logistic回归总结
  3. boost::signals2模块实现用于从槽返回值到信号调用的示例程序
  4. SpringBoot项目遇到的一些问题
  5. 云+X案例展 | 民生类:浪潮云打卡人间仙境张家界
  6. django 1.8 官方文档翻译:14-5 信号
  7. 摩托罗拉Edge真机谍照曝光:挖孔瀑布屏+骁龙765
  8. Stanford Parser demo错误:Unsupported major.minor version 52.0 error
  9. 天梯赛L2-6 树的遍历
  10. 自定义浏览器UA标识
  11. 误删了计算机桌面回收站,不小心误删电脑回收站怎么恢复?
  12. Linux性能分析命令
  13. Zemax曲率半径的控制方法
  14. 监控时代,那无处安放的隐私
  15. python中序列_python中什么是序列
  16. win10 eclipse适配笔记本4K屏幕
  17. 中科院广州电子CASAIM与东风日产在3D打印生产制造发动机检具及治具应用研究项目顺利落地
  18. qq因计算机丢失打不开,QQ面板链接打不开或失效怎么办?
  19. 【C++要笑着学】关键字 | 命名空间 | 输入和输出
  20. 搭建个人的Leanote云笔记本

热门文章

  1. 树莓派安装基地Debian-Pi-Aarch64系统 SSD启动
  2. iPhone MSN评测报告
  3. 游戏检测到计算机性能过低,windows检测到您的计算机性能缓慢
  4. 密码技术学习(8.1)-数字证书简介
  5. 这么有料的福利,你还不赶紧关注一波吗?(代码合集)
  6. 阳光牧场助手 阳光牧场外挂
  7. openwrt - transmission
  8. Fedora 9 感受
  9. 部署kubernetes
  10. 精品软件 推荐 淘宝 天猫 秒杀助手