lkml.org 
[lkml]   [2021]   [Nov]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v1 1/3] media: staging: tegra-vde: Support reference picture marking
    Date
    From: Thierry Reding <treding@nvidia.com>

    Tegra114 and Tegra124 support reference picture marking, which will
    cause BSEV to write picture marking data to SDRAM. Make sure there is
    a valid destination address for that data to avoid error messages from
    the memory controller.

    [digetx@gmail.com: added BO support and moved secure BO allocation to kernel]
    Tested-by: Anton Bambura <jenneron@protonmail.com> # T114 ASUS TF701T
    Signed-off-by: Thierry Reding <treding@nvidia.com>
    Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
    ---
    drivers/staging/media/tegra-vde/vde.c | 120 +++++++++++++++++++++++++-
    drivers/staging/media/tegra-vde/vde.h | 18 ++++
    2 files changed, 137 insertions(+), 1 deletion(-)

    diff --git a/drivers/staging/media/tegra-vde/vde.c b/drivers/staging/media/tegra-vde/vde.c
    index 859f60a70904..42da57f191ef 100644
    --- a/drivers/staging/media/tegra-vde/vde.c
    +++ b/drivers/staging/media/tegra-vde/vde.c
    @@ -85,6 +85,92 @@ static int tegra_vde_wait_mbe(struct tegra_vde *vde)
    (tmp >= 0x10), 1, 100);
    }

    +static struct tegra_vde_bo *
    +tegra_vde_alloc_bo(struct tegra_vde *vde, enum dma_data_direction dma_dir,
    + size_t size)
    +{
    + struct device *dev = vde->miscdev.parent;
    + struct tegra_vde_bo *bo;
    + int err;
    +
    + bo = kzalloc(sizeof(*bo), GFP_KERNEL);
    + if (!bo)
    + return NULL;
    +
    + bo->vde = vde;
    + bo->size = size;
    + bo->dma_dir = dma_dir;
    + bo->dma_attrs = DMA_ATTR_WRITE_COMBINE |
    + DMA_ATTR_NO_KERNEL_MAPPING;
    +
    + if (!vde->domain)
    + bo->dma_attrs |= DMA_ATTR_FORCE_CONTIGUOUS;
    +
    + bo->dma_cookie = dma_alloc_attrs(dev, bo->size, &bo->dma_handle,
    + GFP_KERNEL, bo->dma_attrs);
    + if (!bo->dma_cookie) {
    + dev_err(dev, "Failed to allocate DMA buffer of size: %zu\n",
    + bo->size);
    + goto free_bo;
    + }
    +
    + err = dma_get_sgtable_attrs(dev, &bo->sgt, bo->dma_cookie,
    + bo->dma_handle, bo->size, bo->dma_attrs);
    + if (err) {
    + dev_err(dev, "Failed to get DMA buffer SG table: %d\n", err);
    + goto free_attrs;
    + }
    +
    + err = dma_map_sgtable(dev, &bo->sgt, bo->dma_dir, bo->dma_attrs);
    + if (err) {
    + dev_err(dev, "Failed to map DMA buffer SG table: %d\n", err);
    + goto free_table;
    + }
    +
    + if (vde->domain) {
    + err = tegra_vde_iommu_map(vde, &bo->sgt, &bo->iova, bo->size);
    + if (err) {
    + dev_err(dev, "Failed to map DMA buffer IOVA: %d\n", err);
    + goto unmap_sgtable;
    + }
    +
    + bo->dma_addr = iova_dma_addr(&vde->iova, bo->iova);
    + } else {
    + bo->dma_addr = sg_dma_address(bo->sgt.sgl);
    + }
    +
    + return bo;
    +
    +unmap_sgtable:
    + dma_unmap_sgtable(dev, &bo->sgt, bo->dma_dir, bo->dma_attrs);
    +free_table:
    + sg_free_table(&bo->sgt);
    +free_attrs:
    + dma_free_attrs(dev, bo->size, bo->dma_cookie, bo->dma_handle,
    + bo->dma_attrs);
    +free_bo:
    + kfree(bo);
    +
    + return NULL;
    +}
    +
    +static void tegra_vde_free_bo(struct tegra_vde_bo *bo)
    +{
    + struct tegra_vde *vde = bo->vde;
    + struct device *dev = vde->miscdev.parent;
    +
    + if (vde->domain)
    + tegra_vde_iommu_unmap(vde, bo->iova);
    +
    + dma_unmap_sgtable(dev, &bo->sgt, bo->dma_dir, bo->dma_attrs);
    +
    + sg_free_table(&bo->sgt);
    +
    + dma_free_attrs(dev, bo->size, bo->dma_cookie, bo->dma_handle,
    + bo->dma_attrs);
    + kfree(bo);
    +}
    +
    static int tegra_vde_setup_mbe_frame_idx(struct tegra_vde *vde,
    unsigned int refs_nb,
    bool setup_refs)
    @@ -425,6 +511,9 @@ static int tegra_vde_setup_hw_context(struct tegra_vde *vde,

    tegra_vde_writel(vde, bitstream_data_addr, vde->sxe, 0x6C);

    + if (vde->soc->supports_ref_pic_marking)
    + tegra_vde_writel(vde, vde->secure_bo->dma_addr, vde->sxe, 0x7c);
    +
    value = 0x10000005;
    value |= ctx->pic_width_in_mbs << 11;
    value |= ctx->pic_height_in_mbs << 3;
    @@ -994,6 +1083,8 @@ static int tegra_vde_probe(struct platform_device *pdev)

    platform_set_drvdata(pdev, vde);

    + vde->soc = of_device_get_match_data(&pdev->dev);
    +
    vde->sxe = devm_platform_ioremap_resource_byname(pdev, "sxe");
    if (IS_ERR(vde->sxe))
    return PTR_ERR(vde->sxe);
    @@ -1119,6 +1210,12 @@ static int tegra_vde_probe(struct platform_device *pdev)

    pm_runtime_put(dev);

    + vde->secure_bo = tegra_vde_alloc_bo(vde, DMA_FROM_DEVICE, 4096);
    + if (!vde->secure_bo) {
    + dev_err(dev, "Failed to allocate secure BO\n");
    + goto err_pm_runtime;
    + }
    +
    return 0;

    err_pm_runtime:
    @@ -1142,6 +1239,8 @@ static int tegra_vde_remove(struct platform_device *pdev)
    struct tegra_vde *vde = platform_get_drvdata(pdev);
    struct device *dev = &pdev->dev;

    + tegra_vde_free_bo(vde->secure_bo);
    +
    /*
    * As it increments RPM usage_count even on errors, we don't need to
    * check the returned code here.
    @@ -1214,8 +1313,27 @@ static const struct dev_pm_ops tegra_vde_pm_ops = {
    tegra_vde_pm_resume)
    };

    +static const struct tegra_vde_soc tegra124_vde_soc = {
    + .supports_ref_pic_marking = true,
    +};
    +
    +static const struct tegra_vde_soc tegra114_vde_soc = {
    + .supports_ref_pic_marking = true,
    +};
    +
    +static const struct tegra_vde_soc tegra30_vde_soc = {
    + .supports_ref_pic_marking = false,
    +};
    +
    +static const struct tegra_vde_soc tegra20_vde_soc = {
    + .supports_ref_pic_marking = false,
    +};
    +
    static const struct of_device_id tegra_vde_of_match[] = {
    - { .compatible = "nvidia,tegra20-vde", },
    + { .compatible = "nvidia,tegra124-vde", .data = &tegra124_vde_soc },
    + { .compatible = "nvidia,tegra114-vde", .data = &tegra114_vde_soc },
    + { .compatible = "nvidia,tegra30-vde", .data = &tegra30_vde_soc },
    + { .compatible = "nvidia,tegra20-vde", .data = &tegra20_vde_soc },
    { },
    };
    MODULE_DEVICE_TABLE(of, tegra_vde_of_match);
    diff --git a/drivers/staging/media/tegra-vde/vde.h b/drivers/staging/media/tegra-vde/vde.h
    index 5561291b0c88..bbd42b8d9991 100644
    --- a/drivers/staging/media/tegra-vde/vde.h
    +++ b/drivers/staging/media/tegra-vde/vde.h
    @@ -24,6 +24,22 @@ struct iommu_domain;
    struct reset_control;
    struct dma_buf_attachment;

    +struct tegra_vde_soc {
    + bool supports_ref_pic_marking;
    +};
    +
    +struct tegra_vde_bo {
    + struct iova *iova;
    + struct sg_table sgt;
    + struct tegra_vde *vde;
    + enum dma_data_direction dma_dir;
    + unsigned long dma_attrs;
    + dma_addr_t dma_handle;
    + dma_addr_t dma_addr;
    + void *dma_cookie;
    + size_t size;
    +};
    +
    struct tegra_vde {
    void __iomem *sxe;
    void __iomem *bsev;
    @@ -48,6 +64,8 @@ struct tegra_vde {
    struct iova_domain iova;
    struct iova *iova_resv_static_addresses;
    struct iova *iova_resv_last_page;
    + const struct tegra_vde_soc *soc;
    + struct tegra_vde_bo *secure_bo;
    dma_addr_t iram_lists_addr;
    u32 *iram;
    };
    --
    2.33.1
    \
     
     \ /
      Last update: 2021-11-14 23:24    [W:2.865 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site