Lines Matching refs:pispbe
161 struct pispbe_dev *pispbe; member
207 struct pispbe_dev *pispbe; member
229 static u32 pispbe_rd(struct pispbe_dev *pispbe, unsigned int offset) in pispbe_rd() argument
231 return readl(pispbe->be_reg_base + offset); in pispbe_rd()
234 static void pispbe_wr(struct pispbe_dev *pispbe, unsigned int offset, u32 val) in pispbe_wr() argument
236 writel(val, pispbe->be_reg_base + offset); in pispbe_wr()
244 static void pispbe_queue_job(struct pispbe_dev *pispbe, in pispbe_queue_job() argument
249 if (pispbe_rd(pispbe, PISP_BE_STATUS_REG) & PISP_BE_STATUS_QUEUED) in pispbe_queue_job()
250 dev_err(pispbe->dev, "ERROR: not safe to queue new job!\n"); in pispbe_queue_job()
259 pispbe_wr(pispbe, PISP_BE_IO_ADDR_LOW(u), in pispbe_queue_job()
261 pispbe_wr(pispbe, PISP_BE_IO_ADDR_HIGH(u), in pispbe_queue_job()
264 pispbe_wr(pispbe, PISP_BE_GLOBAL_BAYER_ENABLE, in pispbe_queue_job()
266 pispbe_wr(pispbe, PISP_BE_GLOBAL_RGB_ENABLE, in pispbe_queue_job()
274 pispbe_wr(pispbe, PISP_BE_CONFIG_BASE_REG + sizeof(u32) * u, in pispbe_queue_job()
280 u64 along = pispbe_rd(pispbe, offset); in pispbe_queue_job()
282 along += ((u64)pispbe_rd(pispbe, offset + 4)) << 32; in pispbe_queue_job()
284 dev_dbg(pispbe->dev, in pispbe_queue_job()
294 pispbe_wr(pispbe, PISP_BE_TILE_ADDR_LO_REG, lower_32_bits(job->tiles)); in pispbe_queue_job()
295 pispbe_wr(pispbe, PISP_BE_TILE_ADDR_HI_REG, upper_32_bits(job->tiles)); in pispbe_queue_job()
298 pispbe_wr(pispbe, PISP_BE_CONTROL_REG, in pispbe_queue_job()
355 static void pispbe_xlate_addrs(struct pispbe_dev *pispbe, in pispbe_xlate_addrs() argument
373 &pispbe->node[MAIN_INPUT_NODE]); in pispbe_xlate_addrs()
376 dev_warn(pispbe->dev, "ISP-BE missing input\n"); in pispbe_xlate_addrs()
431 &pispbe->node[OUTPUT0_NODE + i]); in pispbe_xlate_addrs()
452 static int pispbe_prepare_job(struct pispbe_dev *pispbe) in pispbe_prepare_job() argument
462 scoped_guard(spinlock_irq, &pispbe->hw_lock) { in pispbe_prepare_job()
465 if ((pispbe->streaming_map & mask) != mask) in pispbe_prepare_job()
472 streaming_map = pispbe->streaming_map; in pispbe_prepare_job()
479 node = &pispbe->node[CONFIG_NODE]; in pispbe_prepare_job()
490 job->config = &pispbe->config[config_index]; in pispbe_prepare_job()
491 job->tiles = pispbe->config_dma_addr + in pispbe_prepare_job()
532 node = &pispbe->node[i]; in pispbe_prepare_job()
548 pispbe_xlate_addrs(pispbe, job, buf); in pispbe_prepare_job()
550 scoped_guard(spinlock_irq, &pispbe->hw_lock) { in pispbe_prepare_job()
551 list_add_tail(&job->queue, &pispbe->job_queue); in pispbe_prepare_job()
561 struct pispbe_node *n = &pispbe->node[i]; in pispbe_prepare_job()
573 static void pispbe_schedule(struct pispbe_dev *pispbe, bool clear_hw_busy) in pispbe_schedule() argument
577 scoped_guard(spinlock_irqsave, &pispbe->hw_lock) { in pispbe_schedule()
579 pispbe->hw_busy = false; in pispbe_schedule()
581 if (pispbe->hw_busy) in pispbe_schedule()
584 job = list_first_entry_or_null(&pispbe->job_queue, in pispbe_schedule()
593 pispbe->queued_job.buf[i] = job->buffers[i]; in pispbe_schedule()
594 pispbe->queued_job.valid = true; in pispbe_schedule()
596 pispbe->hw_busy = true; in pispbe_schedule()
605 pispbe_queue_job(pispbe, job); in pispbe_schedule()
609 static void pispbe_isr_jobdone(struct pispbe_dev *pispbe, in pispbe_isr_jobdone() argument
618 buf[i]->vb.sequence = pispbe->sequence; in pispbe_isr_jobdone()
624 pispbe->sequence++; in pispbe_isr_jobdone()
629 struct pispbe_dev *pispbe = (struct pispbe_dev *)dev; in pispbe_isr() local
634 u = pispbe_rd(pispbe, PISP_BE_INTERRUPT_STATUS_REG); in pispbe_isr()
638 pispbe_wr(pispbe, PISP_BE_INTERRUPT_STATUS_REG, u); in pispbe_isr()
639 u = pispbe_rd(pispbe, PISP_BE_BATCH_STATUS_REG); in pispbe_isr()
648 if (pispbe->running_job.valid && pispbe->done != done) { in pispbe_isr()
649 pispbe_isr_jobdone(pispbe, &pispbe->running_job); in pispbe_isr()
650 memset(&pispbe->running_job, 0, sizeof(pispbe->running_job)); in pispbe_isr()
651 pispbe->done++; in pispbe_isr()
654 if (pispbe->started != started) { in pispbe_isr()
655 pispbe->started++; in pispbe_isr()
658 if (pispbe->done != done && pispbe->queued_job.valid) { in pispbe_isr()
659 pispbe_isr_jobdone(pispbe, &pispbe->queued_job); in pispbe_isr()
660 pispbe->done++; in pispbe_isr()
662 pispbe->running_job = pispbe->queued_job; in pispbe_isr()
665 memset(&pispbe->queued_job, 0, sizeof(pispbe->queued_job)); in pispbe_isr()
668 if (pispbe->done != done || pispbe->started != started) { in pispbe_isr()
669 dev_dbg(pispbe->dev, in pispbe_isr()
671 pispbe->done, done, pispbe->started, started); in pispbe_isr()
672 pispbe->started = started; in pispbe_isr()
673 pispbe->done = done; in pispbe_isr()
677 pispbe_schedule(pispbe, can_queue_another); in pispbe_isr()
682 static int pisp_be_validate_config(struct pispbe_dev *pispbe, in pisp_be_validate_config() argument
687 struct device *dev = pispbe->dev; in pisp_be_validate_config()
705 fmt = &pispbe->node[TDN_OUTPUT_NODE].format; in pisp_be_validate_config()
723 fmt = &pispbe->node[STITCH_OUTPUT_NODE].format; in pisp_be_validate_config()
749 fmt = &pispbe->node[OUTPUT0_NODE + j].format; in pisp_be_validate_config()
781 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_queue_setup() local
809 dev_dbg(pispbe->dev, in pispbe_node_queue_setup()
819 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_buffer_prepare() local
829 dev_dbg(pispbe->dev, in pispbe_node_buffer_prepare()
839 void *dst = &node->pispbe->config[vb->index]; in pispbe_node_buffer_prepare()
844 return pisp_be_validate_config(pispbe, dst); in pispbe_node_buffer_prepare()
857 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_buffer_queue() local
859 dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node)); in pispbe_node_buffer_queue()
866 if (!pispbe_prepare_job(pispbe)) in pispbe_node_buffer_queue()
867 pispbe_schedule(pispbe, false); in pispbe_node_buffer_queue()
873 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_start_streaming() local
877 ret = pm_runtime_resume_and_get(pispbe->dev); in pispbe_node_start_streaming()
881 scoped_guard(spinlock_irq, &pispbe->hw_lock) { in pispbe_node_start_streaming()
882 node->pispbe->streaming_map |= BIT(node->id); in pispbe_node_start_streaming()
883 node->pispbe->sequence = 0; in pispbe_node_start_streaming()
886 dev_dbg(pispbe->dev, "%s: for node %s (count %u)\n", in pispbe_node_start_streaming()
888 dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n", in pispbe_node_start_streaming()
889 node->pispbe->streaming_map); in pispbe_node_start_streaming()
892 if (!pispbe_prepare_job(pispbe)) in pispbe_node_start_streaming()
893 pispbe_schedule(pispbe, false); in pispbe_node_start_streaming()
909 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_stop_streaming() local
923 dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node)); in pispbe_node_stop_streaming()
936 spin_lock_irq(&pispbe->hw_lock); in pispbe_node_stop_streaming()
937 pispbe->streaming_map &= ~BIT(node->id); in pispbe_node_stop_streaming()
939 if (pispbe->streaming_map == 0) { in pispbe_node_stop_streaming()
944 list_splice_init(&pispbe->job_queue, &tmp_list); in pispbe_node_stop_streaming()
946 spin_unlock_irq(&pispbe->hw_lock); in pispbe_node_stop_streaming()
953 pm_runtime_put_autosuspend(pispbe->dev); in pispbe_node_stop_streaming()
955 dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n", in pispbe_node_stop_streaming()
956 pispbe->streaming_map); in pispbe_node_stop_streaming()
980 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_querycap() local
985 dev_dbg(pispbe->dev, "Caps for node %s: %x and %x (dev %x)\n", in pispbe_node_querycap()
996 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_g_fmt_vid_cap() local
999 dev_dbg(pispbe->dev, in pispbe_node_g_fmt_vid_cap()
1006 dev_dbg(pispbe->dev, "Get capture format for node %s\n", in pispbe_node_g_fmt_vid_cap()
1016 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_g_fmt_vid_out() local
1019 dev_dbg(pispbe->dev, in pispbe_node_g_fmt_vid_out()
1026 dev_dbg(pispbe->dev, "Get output format for node %s\n", in pispbe_node_g_fmt_vid_out()
1036 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_g_fmt_meta_out() local
1039 dev_dbg(pispbe->dev, in pispbe_node_g_fmt_meta_out()
1046 dev_dbg(pispbe->dev, "Get output format for meta node %s\n", in pispbe_node_g_fmt_meta_out()
1093 struct pispbe_dev *pispbe = node->pispbe; in pispbe_try_format() local
1098 dev_dbg(pispbe->dev, in pispbe_try_format()
1106 dev_dbg(pispbe->dev, in pispbe_try_format()
1146 dev_dbg(pispbe->dev, in pispbe_try_format()
1159 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_try_fmt_vid_cap() local
1162 dev_dbg(pispbe->dev, in pispbe_node_try_fmt_vid_cap()
1177 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_try_fmt_vid_out() local
1180 dev_dbg(pispbe->dev, in pispbe_node_try_fmt_vid_out()
1195 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_try_fmt_meta_out() local
1198 dev_dbg(pispbe->dev, in pispbe_node_try_fmt_meta_out()
1214 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_s_fmt_vid_cap() local
1227 dev_dbg(pispbe->dev, "Set capture format for node %s to %p4cc\n", in pispbe_node_s_fmt_vid_cap()
1237 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_s_fmt_vid_out() local
1250 dev_dbg(pispbe->dev, "Set output format for node %s to %p4cc\n", in pispbe_node_s_fmt_vid_out()
1260 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_s_fmt_meta_out() local
1273 dev_dbg(pispbe->dev, "Set output format for meta node %s to %p4cc\n", in pispbe_node_s_fmt_meta_out()
1309 struct pispbe_dev *pispbe = node->pispbe; in pispbe_enum_framesizes() local
1315 dev_dbg(pispbe->dev, "Invalid pixel code: %x\n", in pispbe_enum_framesizes()
1394 static int pispbe_init_node(struct pispbe_dev *pispbe, unsigned int id) in pispbe_init_node() argument
1397 struct pispbe_node *node = &pispbe->node[id]; in pispbe_init_node()
1404 node->pispbe = pispbe; in pispbe_init_node()
1421 q->dev = pispbe->dev; in pispbe_init_node()
1427 dev_err(pispbe->dev, "vb2_queue_init failed\n"); in pispbe_init_node()
1433 vdev->v4l2_dev = &pispbe->v4l2_dev; in pispbe_init_node()
1443 dev_err(pispbe->dev, in pispbe_init_node()
1451 dev_err(pispbe->dev, in pispbe_init_node()
1459 ret = media_create_pad_link(entity, 0, &pispbe->sd.entity, in pispbe_init_node()
1463 ret = media_create_pad_link(&pispbe->sd.entity, id, entity, in pispbe_init_node()
1469 dev_dbg(pispbe->dev, "%s device node registered as /dev/video%d\n", in pispbe_init_node()
1492 static int pispbe_init_subdev(struct pispbe_dev *pispbe) in pispbe_init_subdev() argument
1494 struct v4l2_subdev *sd = &pispbe->sd; in pispbe_init_subdev()
1500 sd->dev = pispbe->dev; in pispbe_init_subdev()
1504 pispbe->pad[i].flags = in pispbe_init_subdev()
1509 pispbe->pad); in pispbe_init_subdev()
1513 ret = v4l2_device_register_subdev(&pispbe->v4l2_dev, sd); in pispbe_init_subdev()
1524 static int pispbe_init_devices(struct pispbe_dev *pispbe) in pispbe_init_devices() argument
1532 mdev = &pispbe->mdev; in pispbe_init_devices()
1533 mdev->hw_revision = pispbe->hw_version; in pispbe_init_devices()
1534 mdev->dev = pispbe->dev; in pispbe_init_devices()
1538 v4l2_dev = &pispbe->v4l2_dev; in pispbe_init_devices()
1539 v4l2_dev->mdev = &pispbe->mdev; in pispbe_init_devices()
1542 ret = v4l2_device_register(pispbe->dev, v4l2_dev); in pispbe_init_devices()
1547 ret = pispbe_init_subdev(pispbe); in pispbe_init_devices()
1553 ret = pispbe_init_node(pispbe, num_regist); in pispbe_init_devices()
1562 pispbe->config = in pispbe_init_devices()
1563 dma_alloc_coherent(pispbe->dev, in pispbe_init_devices()
1566 &pispbe->config_dma_addr, GFP_KERNEL); in pispbe_init_devices()
1567 if (!pispbe->config) { in pispbe_init_devices()
1568 dev_err(pispbe->dev, "Unable to allocate cached config buffers.\n"); in pispbe_init_devices()
1579 video_unregister_device(&pispbe->node[num_regist].vfd); in pispbe_init_devices()
1580 vb2_queue_release(&pispbe->node[num_regist].queue); in pispbe_init_devices()
1582 v4l2_device_unregister_subdev(&pispbe->sd); in pispbe_init_devices()
1583 media_entity_cleanup(&pispbe->sd.entity); in pispbe_init_devices()
1591 static void pispbe_destroy_devices(struct pispbe_dev *pispbe) in pispbe_destroy_devices() argument
1593 if (pispbe->config) { in pispbe_destroy_devices()
1594 dma_free_coherent(pispbe->dev, in pispbe_destroy_devices()
1597 pispbe->config, in pispbe_destroy_devices()
1598 pispbe->config_dma_addr); in pispbe_destroy_devices()
1601 dev_dbg(pispbe->dev, "Unregister from media controller\n"); in pispbe_destroy_devices()
1603 v4l2_device_unregister_subdev(&pispbe->sd); in pispbe_destroy_devices()
1604 media_entity_cleanup(&pispbe->sd.entity); in pispbe_destroy_devices()
1605 media_device_unregister(&pispbe->mdev); in pispbe_destroy_devices()
1608 video_unregister_device(&pispbe->node[i].vfd); in pispbe_destroy_devices()
1609 vb2_queue_release(&pispbe->node[i].queue); in pispbe_destroy_devices()
1610 mutex_destroy(&pispbe->node[i].node_lock); in pispbe_destroy_devices()
1611 mutex_destroy(&pispbe->node[i].queue_lock); in pispbe_destroy_devices()
1614 media_device_cleanup(&pispbe->mdev); in pispbe_destroy_devices()
1615 v4l2_device_unregister(&pispbe->v4l2_dev); in pispbe_destroy_devices()
1620 struct pispbe_dev *pispbe = dev_get_drvdata(dev); in pispbe_runtime_suspend() local
1622 clk_disable_unprepare(pispbe->clk); in pispbe_runtime_suspend()
1629 struct pispbe_dev *pispbe = dev_get_drvdata(dev); in pispbe_runtime_resume() local
1632 ret = clk_prepare_enable(pispbe->clk); in pispbe_runtime_resume()
1639 __func__, clk_get_rate(pispbe->clk)); in pispbe_runtime_resume()
1644 static int pispbe_hw_init(struct pispbe_dev *pispbe) in pispbe_hw_init() argument
1649 u = pispbe_rd(pispbe, PISP_BE_VERSION_REG); in pispbe_hw_init()
1650 dev_dbg(pispbe->dev, "pispbe_probe: HW version: 0x%08x", u); in pispbe_hw_init()
1651 pispbe->hw_version = u; in pispbe_hw_init()
1656 pispbe_wr(pispbe, PISP_BE_INTERRUPT_STATUS_REG, 0xFFFFFFFFu); in pispbe_hw_init()
1657 u = pispbe_rd(pispbe, PISP_BE_BATCH_STATUS_REG); in pispbe_hw_init()
1658 dev_dbg(pispbe->dev, "pispbe_probe: BatchStatus: 0x%08x", u); in pispbe_hw_init()
1660 pispbe->done = (uint8_t)u; in pispbe_hw_init()
1661 pispbe->started = (uint8_t)(u >> 8); in pispbe_hw_init()
1662 u = pispbe_rd(pispbe, PISP_BE_STATUS_REG); in pispbe_hw_init()
1663 dev_dbg(pispbe->dev, "pispbe_probe: Status: 0x%08x", u); in pispbe_hw_init()
1665 if (u != 0 || pispbe->done != pispbe->started) { in pispbe_hw_init()
1666 dev_err(pispbe->dev, "pispbe_probe: HW is stuck or busy\n"); in pispbe_hw_init()
1675 pispbe_wr(pispbe, PISP_BE_AXI_REG, 0x32703200u); in pispbe_hw_init()
1678 pispbe_wr(pispbe, PISP_BE_INTERRUPT_EN_REG, 0x00000003u); in pispbe_hw_init()
1686 struct pispbe_dev *pispbe; in pispbe_probe() local
1689 pispbe = devm_kzalloc(&pdev->dev, sizeof(*pispbe), GFP_KERNEL); in pispbe_probe()
1690 if (!pispbe) in pispbe_probe()
1693 INIT_LIST_HEAD(&pispbe->job_queue); in pispbe_probe()
1695 dev_set_drvdata(&pdev->dev, pispbe); in pispbe_probe()
1696 pispbe->dev = &pdev->dev; in pispbe_probe()
1697 platform_set_drvdata(pdev, pispbe); in pispbe_probe()
1699 pispbe->be_reg_base = devm_platform_ioremap_resource(pdev, 0); in pispbe_probe()
1700 if (IS_ERR(pispbe->be_reg_base)) { in pispbe_probe()
1702 return PTR_ERR(pispbe->be_reg_base); in pispbe_probe()
1705 pispbe->irq = platform_get_irq(pdev, 0); in pispbe_probe()
1706 if (pispbe->irq <= 0) in pispbe_probe()
1709 ret = devm_request_irq(&pdev->dev, pispbe->irq, pispbe_isr, 0, in pispbe_probe()
1710 PISPBE_NAME, pispbe); in pispbe_probe()
1716 ret = dma_set_mask_and_coherent(pispbe->dev, DMA_BIT_MASK(36)); in pispbe_probe()
1720 pispbe->clk = devm_clk_get(&pdev->dev, NULL); in pispbe_probe()
1721 if (IS_ERR(pispbe->clk)) in pispbe_probe()
1722 return dev_err_probe(&pdev->dev, PTR_ERR(pispbe->clk), in pispbe_probe()
1726 pm_runtime_set_autosuspend_delay(pispbe->dev, 200); in pispbe_probe()
1727 pm_runtime_use_autosuspend(pispbe->dev); in pispbe_probe()
1728 pm_runtime_enable(pispbe->dev); in pispbe_probe()
1730 ret = pm_runtime_resume_and_get(pispbe->dev); in pispbe_probe()
1734 pispbe->hw_busy = false; in pispbe_probe()
1735 spin_lock_init(&pispbe->hw_lock); in pispbe_probe()
1736 ret = pispbe_hw_init(pispbe); in pispbe_probe()
1740 ret = pispbe_init_devices(pispbe); in pispbe_probe()
1744 pm_runtime_put_autosuspend(pispbe->dev); in pispbe_probe()
1749 pispbe_destroy_devices(pispbe); in pispbe_probe()
1751 pm_runtime_put(pispbe->dev); in pispbe_probe()
1753 pm_runtime_dont_use_autosuspend(pispbe->dev); in pispbe_probe()
1754 pm_runtime_disable(pispbe->dev); in pispbe_probe()
1761 struct pispbe_dev *pispbe = platform_get_drvdata(pdev); in pispbe_remove() local
1763 pispbe_destroy_devices(pispbe); in pispbe_remove()
1765 pm_runtime_dont_use_autosuspend(pispbe->dev); in pispbe_remove()
1766 pm_runtime_disable(pispbe->dev); in pispbe_remove()