rk3399 基于component 框架,在probe阶段解析dts中各个设备的信息,加到componet match 列表中,等所有的设备加载完毕后,就会引发master设备的bind。
1.vop probe
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);
}
const struct component_ops vop_component_ops = {
.bind = vop_bind,
.unbind = vop_unbind,
};
2. hdmi probe:
static struct platform_driver dw_hdmi_rockchip_pltfm_driver = {
.probe = dw_hdmi_rockchip_probe,
.remove = dw_hdmi_rockchip_remove,
.shutdown = dw_hdmi_rockchip_shutdown,
.driver = {
.name = "dwhdmi-rockchip",
.of_match_table = dw_hdmi_rockchip_dt_ids,
.pm = &dw_hdmi_pm_ops,
},
};
static int dw_hdmi_rockchip_probe(struct platform_device *pdev)
{
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
return component_add(&pdev->dev, &dw_hdmi_rockchip_ops);
}
static const struct component_ops dw_hdmi_rockchip_ops = {
.bind = dw_hdmi_rockchip_bind,
.unbind = dw_hdmi_rockchip_unbind,
};
3. 解析display_subsystem dts
display_subsystem: display-subsystem {
u-boot,dm-pre-reloc;
compatible = "rockchip,display-subsystem";
ports = <&vopl_out>, <&vopb_out>;
clocks = <&cru PLL_VPLL>, <&cru PLL_CPLL>;
clock-names = "hdmi-tmds-pll", "default-vop-pll";
devfreq = <&dmc>;
status = "disabled";
};
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,
},
};
4.bind 函数调用
rockchip_drm_platform_probe
//rockchip_drm_ops 指向
static const struct component_master_ops rockchip_drm_ops = {
.bind = rockchip_drm_bind,
.unbind = rockchip_drm_unbind,
};
component_master_add_with_match(dev, &rockchip_drm_ops, match); //rockchip_drm_ops 指向
try_to_bring_up_master
master->ops->bind // 指向rockchip_drm_bind
rockchip_drm_bind
drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev); //构建drm_devices
component_bind_all
rockchip_drm_fbdev_init
drm_dev_register // 注册drm 字符设备。
vop :
vop_bind
vop_create_crtc // 创建crtc
vop_plane_init //初始化:plane
drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor,&vop_crtc_funcs, NULL);
crtc->dev = dev; // 指向drm_device
crtc->funcs = funcs; //赋值vop_crtc_funcs
crtc->primary = primary; // primary plane
crtc->cursor = cursor; // 鼠标 plane
HDMI:
dw_hdmi_rockchip_bind
drm_encoder_helper_add // encoder 赋值 drm_encoder_helper_funcs
drm_encoder_init //encoder 赋值 const struct drm_encoder_funcs *funcs;
dw_hdmi_bind
dw_hdmi_register
bridge->funcs = &dw_hdmi_bridge_funcs;
drm_bridge_attach
drm_connector_helper_add //connecor 初始drm_connector_helper_funcs
drm_connector_init //connecor 初始 drm_connector_funcs
drm_mode_connector_attach_encoder //connecor 与encoder 结合
5. 字符设备注册:
drm_core_init
register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)
static const struct file_operations drm_stub_fops = {
.owner = THIS_MODULE,
.open = drm_stub_open,
.llseek = noop_llseek,
};
drm_dev_register
drm_minor_register
device_add