media: rockchip: isp: import dma API for memory synchronisation for thunderboot

Change-Id: I29b4b4fb381ff6ba4cc7ef203c431ec0b1b6055b
Signed-off-by: Ziyuan Xu <xzy.xu@rock-chips.com>
This commit is contained in:
Ziyuan Xu
2021-03-02 16:34:01 +08:00
committed by Tao Huang
parent 41d2151d7a
commit 3f1e1d3358
3 changed files with 53 additions and 19 deletions

View File

@@ -664,22 +664,26 @@ static int rkisp_get_reserved_mem(struct rkisp_device *isp_dev)
/* Get reserved memory region from Device-tree */
np = of_parse_phandle(dev->of_node, "memory-region-thunderboot", 0);
if (!np) {
dev_err(dev, "No %s specified\n", "memory-region-thunderboot");
return -1;
dev_info(dev, "No memory-region-thunderboot specified\n");
return 0;
}
ret = of_address_to_resource(np, 0, &r);
if (ret) {
dev_err(dev, "No memory address assigned to the region\n");
return -1;
return ret;
}
isp_dev->resmem_pa = r.start;
isp_dev->resmem_size = resource_size(&r);
isp_dev->resmem_addr = dma_map_single(dev, phys_to_virt(r.start),
sizeof(struct rkisp_thunderboot_resmem_head),
DMA_BIDIRECTIONAL);
ret = dma_mapping_error(dev, isp_dev->resmem_addr);
dev_info(dev, "Allocated reserved memory, paddr: 0x%x\n",
(u32)isp_dev->resmem_pa);
return 0;
return ret;
}
static int rkisp_plat_probe(struct platform_device *pdev)
@@ -717,7 +721,10 @@ static int rkisp_plat_probe(struct platform_device *pdev)
sprintf(isp_dev->name, "%s%d",
DRIVER_NAME, isp_dev->dev_id);
rkisp_get_reserved_mem(isp_dev);
ret = rkisp_get_reserved_mem(isp_dev);
if (ret)
return ret;
mutex_init(&isp_dev->apilock);
mutex_init(&isp_dev->iqlock);
atomic_set(&isp_dev->pipe.power_cnt, 0);

View File

@@ -209,6 +209,7 @@ struct rkisp_device {
struct mutex apilock; /* mutex to serialize the calls of stream */
struct mutex iqlock; /* mutex to serialize the calls of iq */
wait_queue_head_t sync_onoff;
dma_addr_t resmem_addr;
phys_addr_t resmem_pa;
size_t resmem_size;
int dev_id;

View File

@@ -1897,10 +1897,17 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
}
rkisp_chk_tb_over(isp_dev);
dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr,
sizeof(struct rkisp_thunderboot_resmem_head),
DMA_FROM_DEVICE);
resmem_va = phys_to_virt(isp_dev->resmem_pa);
head = (struct rkisp_thunderboot_resmem_head *)resmem_va;
if (head->complete != RKISP_TB_OK) {
resmem->resmem_size = 0;
dma_unmap_single(isp_dev->dev, isp_dev->resmem_pa,
sizeof(struct rkisp_thunderboot_resmem_head),
DMA_FROM_DEVICE);
free_reserved_area(phys_to_virt(isp_dev->resmem_pa),
phys_to_virt(isp_dev->resmem_pa) + isp_dev->resmem_size,
-1, "rkisp_thunderboot");
@@ -1910,10 +1917,14 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
}
break;
case RKISP_CMD_FREE_SHARED_BUF:
if (isp_dev->resmem_pa && isp_dev->resmem_size)
if (isp_dev->resmem_pa && isp_dev->resmem_size) {
dma_unmap_single(isp_dev->dev, isp_dev->resmem_pa,
sizeof(struct rkisp_thunderboot_resmem_head),
DMA_FROM_DEVICE);
free_reserved_area(phys_to_virt(isp_dev->resmem_pa),
phys_to_virt(isp_dev->resmem_pa) + isp_dev->resmem_size,
-1, "rkisp_thunderboot");
}
isp_dev->resmem_pa = 0;
isp_dev->resmem_size = 0;
@@ -2118,13 +2129,34 @@ void rkisp_unregister_isp_subdev(struct rkisp_device *isp_dev)
media_entity_cleanup(&sd->entity);
}
#define shm_head_poll_timeout(isp_dev, cond, sleep_us, timeout_us) \
({ \
u64 __timeout_us = (timeout_us); \
unsigned long __sleep_us = (sleep_us); \
ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
might_sleep_if((__sleep_us) != 0); \
for (;;) { \
dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr, \
sizeof(struct rkisp_thunderboot_resmem_head), \
DMA_FROM_DEVICE); \
if (cond) \
break; \
if (__timeout_us && \
ktime_compare(ktime_get(), __timeout) > 0) { \
break; \
} \
if (__sleep_us) \
usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
} \
(cond) ? 0 : -ETIMEDOUT; \
})
#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
void rkisp_chk_tb_over(struct rkisp_device *isp_dev)
{
struct rkisp_thunderboot_resmem_head *head;
enum rkisp_tb_state tb_state;
void *resmem_va;
u32 i;
if (!isp_dev->resmem_pa || !isp_dev->resmem_size) {
v4l2_info(&isp_dev->v4l2_dev,
@@ -2135,17 +2167,11 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev)
resmem_va = phys_to_virt(isp_dev->resmem_pa);
head = (struct rkisp_thunderboot_resmem_head *)resmem_va;
if (isp_dev->hw_dev->is_thunderboot) {
if ((!head->complete)) {
for (i = 0; i < 100; i++) {
usleep_range(5000, 6000);
if (head->complete)
break;
}
if (!head->complete)
v4l2_info(&isp_dev->v4l2_dev,
"wait thunderboot over timeout\n");
}
shm_head_poll_timeout(isp_dev, !!head->enable, 2000, 200 * USEC_PER_MSEC);
shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 500 * USEC_PER_MSEC);
if (head->complete != RKISP_TB_OK)
v4l2_info(&isp_dev->v4l2_dev,
"wait thunderboot over timeout\n");
v4l2_info(&isp_dev->v4l2_dev,
"thunderboot info: %d, %d, %d, %d, %d, %d, 0x%x\n",