}
if (private->domain) {
- int prot = IOMMU_READ | IOMMU_WRITE;
-
memset(&logo->mm, 0, sizeof(logo->mm));
ret = drm_mm_insert_node_generic(&private->mm, &logo->mm,
size, PAGE_SIZE,
logo->dma_addr = logo->mm.start;
- if (iommu_map_sg(private->domain, logo->dma_addr, sgt->sgl,
- sgt->nents, prot) < size) {
+ logo->iommu_map_size = iommu_map_sg(private->domain,
+ logo->dma_addr, sgt->sgl,
+ sgt->nents, IOMMU_READ);
+ if (logo->iommu_map_size < size) {
DRM_ERROR("failed to map buffer");
ret = -ENOMEM;
goto err_remove_node;
!connector_helper_funcs->best_encoder)
return -ENXIO;
encoder = connector_helper_funcs->best_encoder(connector);
+ if (!encoder)
+ return -ENXIO;
encoder_helper_funcs = encoder->helper_private;
- if (!encoder || !encoder_helper_funcs->atomic_check)
+ if (!encoder_helper_funcs->atomic_check)
return -ENXIO;
ret = encoder_helper_funcs->atomic_check(encoder, crtc->state,
conn_state);
if (ret)
return ret;
+ if (encoder_helper_funcs->mode_set)
+ encoder_helper_funcs->mode_set(encoder, mode, mode);
priv->crtc_funcs[pipe]->loader_protect(crtc, true);
}
int pipe = drm_crtc_index(crtc);
struct rockchip_drm_private *priv = crtc->dev->dev_private;
- if (pipe > ROCKCHIP_MAX_CRTC)
+ if (pipe >= ROCKCHIP_MAX_CRTC)
return -EINVAL;
priv->crtc_funcs[pipe] = crtc_funcs;
int pipe = drm_crtc_index(crtc);
struct rockchip_drm_private *priv = crtc->dev->dev_private;
- if (pipe > ROCKCHIP_MAX_CRTC)
+ if (pipe >= ROCKCHIP_MAX_CRTC)
return;
priv->crtc_funcs[pipe] = NULL;
iommu_domain_free(private->domain);
}
+#ifdef CONFIG_DEBUG_FS
+static int rockchip_drm_mm_dump(struct seq_file *s, void *data)
+{
+ struct drm_info_node *node = s->private;
+ struct drm_minor *minor = node->minor;
+ struct drm_device *drm_dev = minor->dev;
+ struct rockchip_drm_private *priv = drm_dev->dev_private;
+ int ret;
+
+ mutex_lock(&priv->mm_lock);
+
+ ret = drm_mm_dump_table(s, &priv->mm);
+
+ mutex_unlock(&priv->mm_lock);
+
+ return ret;
+}
+
+static int rockchip_drm_summary_show(struct seq_file *s, void *data)
+{
+ struct drm_info_node *node = s->private;
+ struct drm_minor *minor = node->minor;
+ struct drm_device *drm_dev = minor->dev;
+ struct rockchip_drm_private *priv = drm_dev->dev_private;
+ struct drm_crtc *crtc;
+
+ drm_for_each_crtc(crtc, drm_dev) {
+ int pipe = drm_crtc_index(crtc);
+
+ if (priv->crtc_funcs[pipe] &&
+ priv->crtc_funcs[pipe]->debugfs_dump)
+ priv->crtc_funcs[pipe]->debugfs_dump(crtc, s);
+ }
+
+ return 0;
+}
+
+static struct drm_info_list rockchip_debugfs_files[] = {
+ { "summary", rockchip_drm_summary_show, 0, NULL },
+ { "mm_dump", rockchip_drm_mm_dump, 0, NULL },
+};
+
+static int rockchip_drm_debugfs_init(struct drm_minor *minor)
+{
+ struct drm_device *dev = minor->dev;
+ int ret;
+
+ ret = drm_debugfs_create_files(rockchip_debugfs_files,
+ ARRAY_SIZE(rockchip_debugfs_files),
+ minor->debugfs_root,
+ minor);
+ if (ret) {
+ dev_err(dev->dev, "could not install rockchip_debugfs_list\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static void rockchip_drm_debugfs_cleanup(struct drm_minor *minor)
+{
+ drm_debugfs_remove_files(rockchip_debugfs_files,
+ ARRAY_SIZE(rockchip_debugfs_files), minor);
+}
+#endif
+
static int rockchip_drm_bind(struct device *dev)
{
struct drm_device *drm_dev;
struct rockchip_drm_private *private;
- struct drm_connector *connector;
int ret;
drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev);
if (!drm_dev)
return -ENOMEM;
- ret = drm_dev_register(drm_dev, 0);
+ ret = drm_dev_set_unique(drm_dev, "%s", dev_name(dev));
if (ret)
goto err_free;
private = devm_kzalloc(drm_dev->dev, sizeof(*private), GFP_KERNEL);
if (!private) {
ret = -ENOMEM;
- goto err_unregister;
+ goto err_free;
}
mutex_init(&private->commit.lock);
if (ret)
goto err_iommu_cleanup;
- ret = drm_connector_register_all(drm_dev);
- if (ret) {
- dev_err(dev, "failed to register connectors\n");
- goto err_unbind;
- }
-
/* init kms poll for handling hpd */
drm_kms_helper_poll_init(drm_dev);
drm_dev->mode_config.allow_fb_modifiers = true;
+ ret = drm_dev_register(drm_dev, 0);
+ if (ret)
+ goto err_fbdev_fini;
+
return 0;
+err_fbdev_fini:
+ rockchip_drm_fbdev_fini(drm_dev);
err_vblank_cleanup:
drm_vblank_cleanup(drm_dev);
err_kms_helper_poll_fini:
drm_kms_helper_poll_fini(drm_dev);
-err_unbind:
component_unbind_all(dev, drm_dev);
err_iommu_cleanup:
rockchip_iommu_cleanup(drm_dev);
err_config_cleanup:
drm_mode_config_cleanup(drm_dev);
drm_dev->dev_private = NULL;
-err_unregister:
- drm_dev_unregister(drm_dev);
err_free:
drm_dev_unref(drm_dev);
return ret;
static void rockchip_drm_unbind(struct device *dev)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
- struct rockchip_drm_private *private = drm_dev->dev_private;
rockchip_drm_fbdev_fini(drm_dev);
drm_vblank_cleanup(drm_dev);
.gem_prime_vmap = rockchip_gem_prime_vmap,
.gem_prime_vunmap = rockchip_gem_prime_vunmap,
.gem_prime_mmap = rockchip_gem_mmap_buf,
+#ifdef CONFIG_DEBUG_FS
+ .debugfs_init = rockchip_drm_debugfs_init,
+ .debugfs_cleanup = rockchip_drm_debugfs_cleanup,
+#endif
.ioctls = rockchip_ioctls,
.num_ioctls = ARRAY_SIZE(rockchip_ioctls),
.fops = &rockchip_drm_driver_fops,