From f831f246a043e20e9338797e43c2d21de5eb7570 Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Tue, 2 Jun 2020 17:05:13 +0800 Subject: [PATCH] drm/rockchip: add support drm logo buffer 1:1 mapping we reserved the DDR last 32M as uboot logo and kernel logo, here we create 1:1 mapping for this buffer, this is prepare for uboot logo phy addr switch to kernel logo vir addr and iommu enable. Change-Id: I090665f29f7f4f7cf5456b9edbddea60485376cf Signed-off-by: Sandy Huang --- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 80 +++++---------------- drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 4 -- 2 files changed, 17 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 2f757c7f9741..d3b3573c7809 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -208,22 +208,15 @@ void rockchip_free_loader_memory(struct drm_device *drm) return; logo = private->logo; - start = phys_to_virt(logo->start); - end = phys_to_virt(logo->start + logo->size); + start = phys_to_virt(logo->dma_addr); + end = phys_to_virt(logo->dma_addr + logo->size); if (private->domain) { - iommu_unmap(private->domain, logo->dma_addr, - logo->iommu_map_size); - mutex_lock(&private->mm_lock); - drm_mm_remove_node(&logo->mm); - mutex_unlock(&private->mm_lock); - } else { - dma_unmap_sg(drm->dev, logo->sgt->sgl, - logo->sgt->nents, DMA_TO_DEVICE); + u32 pg_size = 1UL << __ffs(private->domain->pgsize_bitmap); + + iommu_unmap(private->domain, logo->dma_addr, ALIGN(logo->size, pg_size)); } - kfree(logo->pages); - sg_free_table(logo->sgt); - kfree(logo->sgt); + memblock_free(logo->start, logo->size); free_reserved_area(start, end, -1, "drm_logo"); kfree(logo); @@ -237,12 +230,10 @@ static int init_loader_memory(struct drm_device *drm_dev) struct rockchip_logo *logo; struct device_node *np = drm_dev->dev->of_node; struct device_node *node; - unsigned long nr_pages; - struct page **pages; - struct sg_table *sgt; phys_addr_t start, size; + u32 pg_size = PAGE_SIZE; struct resource res; - int i, ret; + int ret; node = of_parse_phandle(np, "logo-memory-region", 0); if (!node) @@ -251,7 +242,9 @@ static int init_loader_memory(struct drm_device *drm_dev) ret = of_address_to_resource(node, 0, &res); if (ret) return ret; - start = res.start; + if (private->domain) + pg_size = 1UL << __ffs(private->domain->pgsize_bitmap); + start = ALIGN_DOWN(res.start, pg_size); size = resource_size(&res); if (!size) return -ENOMEM; @@ -261,62 +254,23 @@ static int init_loader_memory(struct drm_device *drm_dev) return -ENOMEM; logo->kvaddr = phys_to_virt(start); - nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; - pages = kmalloc_array(nr_pages, sizeof(*pages), GFP_KERNEL); - if (!pages) - goto err_free_logo; - i = 0; - while (i < nr_pages) { - pages[i] = phys_to_page(start); - start += PAGE_SIZE; - i++; - } - sgt = drm_prime_pages_to_sg(pages, nr_pages); - if (IS_ERR(sgt)) { - ret = PTR_ERR(sgt); - goto err_free_pages; - } if (private->domain) { - memset(&logo->mm, 0, sizeof(logo->mm)); - mutex_lock(&private->mm_lock); - ret = drm_mm_insert_node_generic(&private->mm, &logo->mm, - size, PAGE_SIZE, - 0, 0); - mutex_unlock(&private->mm_lock); - if (ret < 0) { - DRM_ERROR("out of I/O virtual memory: %d\n", ret); - goto err_free_pages; + 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\n"); + goto err_free_logo; } - - logo->dma_addr = logo->mm.start; - - 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; - } - } else { - dma_map_sg(drm_dev->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE); - logo->dma_addr = sg_dma_address(sgt->sgl); } - logo->sgt = sgt; - logo->start = res.start; + logo->dma_addr = start; logo->size = size; logo->count = 1; private->logo = logo; - logo->pages = pages; return 0; -err_remove_node: - drm_mm_remove_node(&logo->mm); -err_free_pages: - kfree(pages); err_free_logo: kfree(logo); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index 74c9eebcf2e0..d8336fbc5977 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -127,15 +127,11 @@ struct rockchip_crtc_state { container_of(s, struct rockchip_crtc_state, base) struct rockchip_logo { - struct sg_table *sgt; - struct drm_mm_node mm; dma_addr_t dma_addr; void *kvaddr; phys_addr_t start; phys_addr_t size; - size_t iommu_map_size; int count; - struct page **pages; }; /*