mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user