/* * Attach a (component) device to the shared drm dma mapping from master drm * device. This is used by the VOPs to map GEM buffers to a common DMA * mapping.
*/ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev, struct device *dev)
{ struct rockchip_drm_private *private = drm_dev->dev_private; int ret;
if (!private->domain) return 0;
if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) { struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
if (mapping) {
arm_iommu_detach_device(dev);
arm_iommu_release_mapping(mapping);
}
}
ret = iommu_attach_device(private->domain, dev); if (ret) {
DRM_DEV_ERROR(dev, "Failed to attach iommu device\n"); return ret;
}
/* Remove existing drivers that may own the framebuffer memory. */
ret = aperture_remove_all_conflicting_devices(rockchip_drm_driver.name); if (ret) {
DRM_DEV_ERROR(dev, "Failed to remove existing framebuffers - %d.\n",
ret); return ret;
}
drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev); if (IS_ERR(drm_dev)) return PTR_ERR(drm_dev);
dev_set_drvdata(dev, drm_dev);
private = devm_kzalloc(drm_dev->dev, sizeof(*private), GFP_KERNEL); if (!private) {
ret = -ENOMEM; goto err_free;
}
drm_dev->dev_private = private;
ret = drmm_mode_config_init(drm_dev); if (ret) goto err_free;
rockchip_drm_mode_config_init(drm_dev);
/* Try to bind all sub drivers. */
ret = component_bind_all(dev, drm_dev); if (ret) goto err_free;
ret = rockchip_drm_init_iommu(drm_dev); if (ret) goto err_unbind_all;
ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc); if (ret) goto err_iommu_cleanup;
drm_mode_config_reset(drm_dev);
/* init kms poll for handling hpd */
drm_kms_helper_poll_init(drm_dev);
ret = drm_dev_register(drm_dev, 0); if (ret) goto err_kms_helper_poll_fini;
/* * Get the endpoint id of the remote endpoint of the given encoder. This * information is used by the VOP2 driver to identify the encoder. * * @rkencoder: The encoder to get the remote endpoint id from * @np: The encoder device node * @port: The number of the port leading to the VOP2 * @reg: The endpoint number leading to the VOP2
*/ int rockchip_drm_encoder_set_crtc_endpoint_id(struct rockchip_encoder *rkencoder, struct device_node *np, int port, int reg)
{ struct of_endpoint ep; struct device_node *en, *ren; int ret;
en = of_graph_get_endpoint_by_regs(np, port, reg); if (!en) return -ENOENT;
ren = of_graph_get_remote_endpoint(en); if (!ren) return -ENOENT;
ret = of_graph_parse_endpoint(ren, &ep); if (ret) return ret;
rkencoder->crtc_endpoint_id = ep.id;
return 0;
}
/* * Check if a vop endpoint is leading to a rockchip subdriver or bridge. * Should be called from the component bind stage of the drivers * to ensure that all subdrivers are probed. * * @ep: endpoint of a rockchip vop * * returns true if subdriver, false if external bridge and -ENODEV * if remote port does not contain a device.
*/ int rockchip_drm_endpoint_is_subdriver(struct device_node *ep)
{ struct device_node *node = of_graph_get_remote_port_parent(ep); struct platform_device *pdev; struct device_driver *drv; int i;
if (!node) return -ENODEV;
/* status disabled will prevent creation of platform-devices */ if (!of_device_is_available(node)) {
of_node_put(node); return -ENODEV;
}
/* enabled non-platform-devices can immediately return here */ if (!pdev) returnfalse;
/* * All rockchip subdrivers have probed at this point, so * any device not having a driver now is an external bridge.
*/
drv = pdev->dev.driver; if (!drv) {
platform_device_put(pdev); returnfalse;
}
for (i = 0; i < num_rockchip_sub_drivers; i++) { if (rockchip_sub_drivers[i] == to_platform_driver(drv)) {
platform_device_put(pdev); returntrue;
}
}
/* add preferred vop device match before adding driver device matches */ for (i = 0; ; i++) {
port = of_parse_phandle(dev->of_node, "ports", i); if (!port) break;
if (of_device_is_available(port->parent) &&
of_device_compatible_match(port->parent,
rockchip_drm_match_preferred))
drm_of_component_match_add(dev, &match,
component_compare_of,
port->parent);
of_node_put(port);
}
for (i = 0; i < num_rockchip_sub_drivers; i++) { struct platform_driver *drv = rockchip_sub_drivers[i]; struct device *p = NULL, *d;
do {
d = platform_find_device_by_driver(p, &drv->driver);
put_device(p);
p = d;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.