mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 22:14:04 +02:00
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 <hjc@rock-chips.com>
This commit is contained in:
parent
4600ef8027
commit
f831f246a0
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user