X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=kernel%2Fdrivers%2Fgpu%2Fdrm%2Fexynos%2Fexynos_drm_ipp.c;h=67d24236e745c4dd1cc014ba0c5386784d3441f8;hb=e09b41010ba33a20a87472ee821fa407a5b8da36;hp=b7f1cbc46cc2c306a5135e52cd19959462d3667e;hpb=f93b97fd65072de626c074dbe099a1fff05ce060;p=kvmfornfv.git diff --git a/kernel/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/kernel/drivers/gpu/drm/exynos/exynos_drm_ipp.c index b7f1cbc46..67d24236e 100644 --- a/kernel/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/kernel/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -45,9 +45,6 @@ #define get_ipp_context(dev) platform_get_drvdata(to_platform_device(dev)) #define ipp_is_m2m_cmd(c) (c == IPP_CMD_M2M) -/* platform device pointer for ipp device. */ -static struct platform_device *exynos_drm_ipp_pdev; - /* * A structure of event. * @@ -102,30 +99,6 @@ static LIST_HEAD(exynos_drm_ippdrv_list); static DEFINE_MUTEX(exynos_drm_ippdrv_lock); static BLOCKING_NOTIFIER_HEAD(exynos_drm_ippnb_list); -int exynos_platform_device_ipp_register(void) -{ - struct platform_device *pdev; - - if (exynos_drm_ipp_pdev) - return -EEXIST; - - pdev = platform_device_register_simple("exynos-drm-ipp", -1, NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - exynos_drm_ipp_pdev = pdev; - - return 0; -} - -void exynos_platform_device_ipp_unregister(void) -{ - if (exynos_drm_ipp_pdev) { - platform_device_unregister(exynos_drm_ipp_pdev); - exynos_drm_ipp_pdev = NULL; - } -} - int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv) { mutex_lock(&exynos_drm_ippdrv_lock); @@ -482,12 +455,11 @@ static int ipp_validate_mem_node(struct drm_device *drm_dev, { struct drm_exynos_ipp_config *ipp_cfg; unsigned int num_plane; - unsigned long min_size, size; - unsigned int bpp; + unsigned long size, buf_size = 0, plane_size, img_size = 0; + unsigned int bpp, width, height; int i; - /* The property id should already be varified */ - ipp_cfg = &c_node->property.config[m_node->prop_id]; + ipp_cfg = &c_node->property.config[m_node->ops_id]; num_plane = drm_format_num_planes(ipp_cfg->fmt); /** @@ -498,20 +470,45 @@ static int ipp_validate_mem_node(struct drm_device *drm_dev, * but it seems more than enough */ for (i = 0; i < num_plane; ++i) { - if (!m_node->buf_info.handles[i]) { - DRM_ERROR("invalid handle for plane %d\n", i); - return -EINVAL; - } + width = ipp_cfg->sz.hsize; + height = ipp_cfg->sz.vsize; bpp = drm_format_plane_cpp(ipp_cfg->fmt, i); - min_size = (ipp_cfg->sz.hsize * ipp_cfg->sz.vsize * bpp) >> 3; - size = exynos_drm_gem_get_size(drm_dev, - m_node->buf_info.handles[i], - c_node->filp); - if (min_size > size) { - DRM_ERROR("invalid size for plane %d\n", i); - return -EINVAL; + + /* + * The result of drm_format_plane_cpp() for chroma planes must + * be used with drm_format_xxxx_chroma_subsampling() for + * correct result. + */ + if (i > 0) { + width /= drm_format_horz_chroma_subsampling( + ipp_cfg->fmt); + height /= drm_format_vert_chroma_subsampling( + ipp_cfg->fmt); + } + plane_size = width * height * bpp; + img_size += plane_size; + + if (m_node->buf_info.handles[i]) { + size = exynos_drm_gem_get_size(drm_dev, + m_node->buf_info.handles[i], + c_node->filp); + if (plane_size > size) { + DRM_ERROR( + "buffer %d is smaller than required\n", + i); + return -EINVAL; + } + + buf_size += size; } } + + if (buf_size < img_size) { + DRM_ERROR("size of buffers(%lu) is smaller than image(%lu)\n", + buf_size, img_size); + return -EINVAL; + } + return 0; } @@ -1625,12 +1622,10 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev) INIT_LIST_HEAD(&ippdrv->cmd_list); mutex_init(&ippdrv->cmd_lock); - if (is_drm_iommu_supported(drm_dev)) { - ret = drm_iommu_attach_device(drm_dev, ippdrv->dev); - if (ret) { - DRM_ERROR("failed to activate iommu\n"); - goto err; - } + ret = drm_iommu_attach_device(drm_dev, ippdrv->dev); + if (ret) { + DRM_ERROR("failed to activate iommu\n"); + goto err; } } @@ -1640,8 +1635,7 @@ err: /* get ipp driver entry */ list_for_each_entry_continue_reverse(ippdrv, &exynos_drm_ippdrv_list, drv_list) { - if (is_drm_iommu_supported(drm_dev)) - drm_iommu_detach_device(drm_dev, ippdrv->dev); + drm_iommu_detach_device(drm_dev, ippdrv->dev); ipp_remove_id(&ctx->ipp_idr, &ctx->ipp_lock, ippdrv->prop_list.ipp_id); @@ -1657,8 +1651,7 @@ static void ipp_subdrv_remove(struct drm_device *drm_dev, struct device *dev) /* get ipp driver entry */ list_for_each_entry_safe(ippdrv, t, &exynos_drm_ippdrv_list, drv_list) { - if (is_drm_iommu_supported(drm_dev)) - drm_iommu_detach_device(drm_dev, ippdrv->dev); + drm_iommu_detach_device(drm_dev, ippdrv->dev); ipp_remove_id(&ctx->ipp_idr, &ctx->ipp_lock, ippdrv->prop_list.ipp_id);