drm/rockchip: drv: logo: add vm reserved for logo memory

Signed-off-by: Sandy Huang <hjc@rock-chips.com>
Change-Id: I91f0831d24d29015389a66b68ef39e0fbd96dcde
This commit is contained in:
Sandy Huang 2022-01-19 10:51:58 +08:00 committed by Tao Huang
parent 10f028dc00
commit 68580e2435
2 changed files with 39 additions and 1 deletions

View File

@ -206,6 +206,7 @@ struct rockchip_drm_vcnt {
struct rockchip_logo {
dma_addr_t dma_addr;
struct drm_mm_node logo_reserved_node;
void *kvaddr;
phys_addr_t start;
phys_addr_t size;
@ -393,6 +394,7 @@ struct rockchip_drm_private {
dma_addr_t cubic_lut_dma_addr;
void *cubic_lut_kvaddr;
struct drm_mm_node *clut_reserved_node;
struct loader_cubic_lut cubic_lut[ROCKCHIP_MAX_CRTC];
};

View File

@ -121,6 +121,25 @@ sub_dev = rockchip_drm_get_sub_dev(np_connector);
return sub_dev;
}
static void rockchip_drm_release_reserve_vm(struct drm_mm_node *node)
{
if (drm_mm_node_allocated(node))
drm_mm_remove_node(node);
}
static int rockchip_drm_reserve_vm(struct drm_mm *mm,
struct drm_mm_node *node, u64 size, u64 offset)
{
int ret;
node->size = size;
node->start = offset;
node->color = 0;
ret = drm_mm_reserve_node(mm, node);
return ret;
}
static unsigned long
rockchip_drm_free_reserved_area(void *start, void *end, int poison, const char *s)
{
@ -175,6 +194,7 @@ void rockchip_free_loader_memory(struct drm_device *drm)
u32 pg_size = 1UL << __ffs(private->domain->pgsize_bitmap);
iommu_unmap(private->domain, logo->dma_addr, ALIGN(logo->size, pg_size));
rockchip_drm_release_reserve_vm(&logo->logo_reserved_node);
}
memblock_free(logo->start, logo->size);
@ -220,6 +240,9 @@ static int init_loader_memory(struct drm_device *drm_dev)
logo->kvaddr = phys_to_virt(start);
if (private->domain) {
ret = rockchip_drm_reserve_vm(&private->mm, &logo->logo_reserved_node, size, start);
if (ret)
dev_err(drm_dev->dev, "failed to reserve vm for logo memory\n");
ret = iommu_map(private->domain, start, start, ALIGN(size, pg_size),
IOMMU_WRITE | IOMMU_READ);
if (ret) {
@ -251,18 +274,31 @@ static int init_loader_memory(struct drm_device *drm_dev)
private->cubic_lut_kvaddr = phys_to_virt(start);
if (private->domain) {
private->clut_reserved_node = kmalloc(sizeof(struct drm_mm_node), GFP_KERNEL);
if (!private->clut_reserved_node)
return -ENOMEM;
ret = rockchip_drm_reserve_vm(&private->mm, private->clut_reserved_node, size, start);
if (ret)
dev_err(drm_dev->dev, "failed to reserve vm for clut memory\n");
ret = iommu_map(private->domain, start, start, ALIGN(size, pg_size),
IOMMU_WRITE | IOMMU_READ);
if (ret) {
dev_err(drm_dev->dev, "failed to create 1v1 mapping for cubic lut\n");
goto err_free_logo;
goto err_free_clut;
}
}
private->cubic_lut_dma_addr = start;
return 0;
err_free_clut:
rockchip_drm_release_reserve_vm(private->clut_reserved_node);
kfree(private->clut_reserved_node);
private->clut_reserved_node = NULL;
err_free_logo:
rockchip_drm_release_reserve_vm(&logo->logo_reserved_node);
kfree(logo);
return ret;