Lines Matching full:pispbe

27 #define PISPBE_NAME "pispbe"
159 struct pispbe_dev *pispbe; member
172 /* For logging only, use the entity name with "pispbe" and separator removed */
205 struct pispbe_dev *pispbe; member
225 static u32 pispbe_rd(struct pispbe_dev *pispbe, unsigned int offset) in pispbe_rd() argument
227 return readl(pispbe->be_reg_base + offset); in pispbe_rd()
230 static void pispbe_wr(struct pispbe_dev *pispbe, unsigned int offset, u32 val) in pispbe_wr() argument
232 writel(val, pispbe->be_reg_base + offset); in pispbe_wr()
240 static void pispbe_queue_job(struct pispbe_dev *pispbe, in pispbe_queue_job() argument
245 if (pispbe_rd(pispbe, PISP_BE_STATUS_REG) & PISP_BE_STATUS_QUEUED) in pispbe_queue_job()
246 dev_err(pispbe->dev, "ERROR: not safe to queue new job!\n"); in pispbe_queue_job()
255 pispbe_wr(pispbe, PISP_BE_IO_ADDR_LOW(u), in pispbe_queue_job()
257 pispbe_wr(pispbe, PISP_BE_IO_ADDR_HIGH(u), in pispbe_queue_job()
260 pispbe_wr(pispbe, PISP_BE_GLOBAL_BAYER_ENABLE, in pispbe_queue_job()
262 pispbe_wr(pispbe, PISP_BE_GLOBAL_RGB_ENABLE, in pispbe_queue_job()
270 pispbe_wr(pispbe, PISP_BE_CONFIG_BASE_REG + sizeof(u32) * u, in pispbe_queue_job()
276 u64 along = pispbe_rd(pispbe, offset); in pispbe_queue_job()
278 along += ((u64)pispbe_rd(pispbe, offset + 4)) << 32; in pispbe_queue_job()
280 dev_dbg(pispbe->dev, in pispbe_queue_job()
290 pispbe_wr(pispbe, PISP_BE_TILE_ADDR_LO_REG, lower_32_bits(job->tiles)); in pispbe_queue_job()
291 pispbe_wr(pispbe, PISP_BE_TILE_ADDR_HI_REG, upper_32_bits(job->tiles)); in pispbe_queue_job()
294 pispbe_wr(pispbe, PISP_BE_CONTROL_REG, in pispbe_queue_job()
351 static void pispbe_xlate_addrs(struct pispbe_dev *pispbe, in pispbe_xlate_addrs() argument
369 &pispbe->node[MAIN_INPUT_NODE]); in pispbe_xlate_addrs()
375 dev_warn(pispbe->dev, "ISP-BE missing input\n"); in pispbe_xlate_addrs()
430 &pispbe->node[OUTPUT0_NODE + i]); in pispbe_xlate_addrs()
450 static int pispbe_prepare_job(struct pispbe_dev *pispbe, in pispbe_prepare_job() argument
458 lockdep_assert_held(&pispbe->hw_lock); in pispbe_prepare_job()
463 pispbe->streaming_map) != in pispbe_prepare_job()
467 node = &pispbe->node[CONFIG_NODE]; in pispbe_prepare_job()
474 pispbe->queued_job.buf[CONFIG_NODE] = buf[CONFIG_NODE]; in pispbe_prepare_job()
483 job->config = &pispbe->config[config_index]; in pispbe_prepare_job()
484 job->tiles = pispbe->config_dma_addr + in pispbe_prepare_job()
501 if (!(pispbe->streaming_map & BIT(i))) in pispbe_prepare_job()
525 node = &pispbe->node[i]; in pispbe_prepare_job()
534 pispbe->queued_job.buf[i] = buf[i]; in pispbe_prepare_job()
542 pispbe->queued_job.valid = true; in pispbe_prepare_job()
545 pispbe_xlate_addrs(pispbe, job, buf); in pispbe_prepare_job()
551 struct pispbe_node *n = &pispbe->node[i]; in pispbe_prepare_job()
562 memset(&pispbe->queued_job, 0, sizeof(pispbe->queued_job)); in pispbe_prepare_job()
567 static void pispbe_schedule(struct pispbe_dev *pispbe, bool clear_hw_busy) in pispbe_schedule() argument
573 spin_lock_irqsave(&pispbe->hw_lock, flags); in pispbe_schedule()
576 pispbe->hw_busy = false; in pispbe_schedule()
578 if (pispbe->hw_busy) in pispbe_schedule()
581 ret = pispbe_prepare_job(pispbe, &job); in pispbe_schedule()
591 pispbe->hw_busy = true; in pispbe_schedule()
592 spin_unlock_irqrestore(&pispbe->hw_lock, flags); in pispbe_schedule()
607 dev_dbg(pispbe->dev, "Bad job: invalid number of tiles: %u\n", in pispbe_schedule()
612 pispbe_queue_job(pispbe, &job); in pispbe_schedule()
618 spin_unlock_irqrestore(&pispbe->hw_lock, flags); in pispbe_schedule()
621 static void pispbe_isr_jobdone(struct pispbe_dev *pispbe, in pispbe_isr_jobdone() argument
630 buf[i]->vb.sequence = pispbe->sequence; in pispbe_isr_jobdone()
636 pispbe->sequence++; in pispbe_isr_jobdone()
641 struct pispbe_dev *pispbe = (struct pispbe_dev *)dev; in pispbe_isr() local
646 u = pispbe_rd(pispbe, PISP_BE_INTERRUPT_STATUS_REG); in pispbe_isr()
650 pispbe_wr(pispbe, PISP_BE_INTERRUPT_STATUS_REG, u); in pispbe_isr()
651 u = pispbe_rd(pispbe, PISP_BE_BATCH_STATUS_REG); in pispbe_isr()
660 if (pispbe->running_job.valid && pispbe->done != done) { in pispbe_isr()
661 pispbe_isr_jobdone(pispbe, &pispbe->running_job); in pispbe_isr()
662 memset(&pispbe->running_job, 0, sizeof(pispbe->running_job)); in pispbe_isr()
663 pispbe->done++; in pispbe_isr()
666 if (pispbe->started != started) { in pispbe_isr()
667 pispbe->started++; in pispbe_isr()
670 if (pispbe->done != done && pispbe->queued_job.valid) { in pispbe_isr()
671 pispbe_isr_jobdone(pispbe, &pispbe->queued_job); in pispbe_isr()
672 pispbe->done++; in pispbe_isr()
674 pispbe->running_job = pispbe->queued_job; in pispbe_isr()
677 memset(&pispbe->queued_job, 0, sizeof(pispbe->queued_job)); in pispbe_isr()
680 if (pispbe->done != done || pispbe->started != started) { in pispbe_isr()
681 dev_dbg(pispbe->dev, in pispbe_isr()
683 pispbe->done, done, pispbe->started, started); in pispbe_isr()
684 pispbe->started = started; in pispbe_isr()
685 pispbe->done = done; in pispbe_isr()
689 pispbe_schedule(pispbe, can_queue_another); in pispbe_isr()
694 static int pisp_be_validate_config(struct pispbe_dev *pispbe, in pisp_be_validate_config() argument
699 struct device *dev = pispbe->dev; in pisp_be_validate_config()
710 fmt = &pispbe->node[TDN_OUTPUT_NODE].format; in pisp_be_validate_config()
728 fmt = &pispbe->node[STITCH_OUTPUT_NODE].format; in pisp_be_validate_config()
754 fmt = &pispbe->node[OUTPUT0_NODE + j].format; in pisp_be_validate_config()
786 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_queue_setup() local
814 dev_dbg(pispbe->dev, in pispbe_node_queue_setup()
824 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_buffer_prepare() local
834 dev_dbg(pispbe->dev, in pispbe_node_buffer_prepare()
844 void *dst = &node->pispbe->config[vb->index]; in pispbe_node_buffer_prepare()
849 return pisp_be_validate_config(pispbe, dst); in pispbe_node_buffer_prepare()
862 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_buffer_queue() local
865 dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node)); in pispbe_node_buffer_queue()
874 pispbe_schedule(pispbe, false); in pispbe_node_buffer_queue()
880 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_start_streaming() local
885 ret = pm_runtime_resume_and_get(pispbe->dev); in pispbe_node_start_streaming()
889 spin_lock_irqsave(&pispbe->hw_lock, flags); in pispbe_node_start_streaming()
890 node->pispbe->streaming_map |= BIT(node->id); in pispbe_node_start_streaming()
891 node->pispbe->sequence = 0; in pispbe_node_start_streaming()
892 spin_unlock_irqrestore(&pispbe->hw_lock, flags); in pispbe_node_start_streaming()
894 dev_dbg(pispbe->dev, "%s: for node %s (count %u)\n", in pispbe_node_start_streaming()
896 dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n", in pispbe_node_start_streaming()
897 node->pispbe->streaming_map); in pispbe_node_start_streaming()
900 pispbe_schedule(pispbe, false); in pispbe_node_start_streaming()
905 spin_lock_irqsave(&pispbe->hw_lock, flags); in pispbe_node_start_streaming()
910 spin_unlock_irqrestore(&pispbe->hw_lock, flags); in pispbe_node_start_streaming()
918 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_stop_streaming() local
931 dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node)); in pispbe_node_stop_streaming()
932 spin_lock_irqsave(&pispbe->hw_lock, flags); in pispbe_node_stop_streaming()
946 spin_unlock_irqrestore(&pispbe->hw_lock, flags); in pispbe_node_stop_streaming()
950 spin_lock_irqsave(&pispbe->hw_lock, flags); in pispbe_node_stop_streaming()
951 pispbe->streaming_map &= ~BIT(node->id); in pispbe_node_stop_streaming()
952 spin_unlock_irqrestore(&pispbe->hw_lock, flags); in pispbe_node_stop_streaming()
954 pm_runtime_mark_last_busy(pispbe->dev); in pispbe_node_stop_streaming()
955 pm_runtime_put_autosuspend(pispbe->dev); in pispbe_node_stop_streaming()
957 dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n", in pispbe_node_stop_streaming()
958 pispbe->streaming_map); in pispbe_node_stop_streaming()
982 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_querycap() local
987 dev_dbg(pispbe->dev, "Caps for node %s: %x and %x (dev %x)\n", in pispbe_node_querycap()
998 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_g_fmt_vid_cap() local
1001 dev_dbg(pispbe->dev, in pispbe_node_g_fmt_vid_cap()
1008 dev_dbg(pispbe->dev, "Get capture format for node %s\n", in pispbe_node_g_fmt_vid_cap()
1018 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_g_fmt_vid_out() local
1021 dev_dbg(pispbe->dev, in pispbe_node_g_fmt_vid_out()
1028 dev_dbg(pispbe->dev, "Get output format for node %s\n", in pispbe_node_g_fmt_vid_out()
1038 struct pispbe_dev *pispbe = node->pispbe; in pispbe_node_g_fmt_meta_out() local
1041 dev_dbg(pispbe->dev, in pispbe_node_g_fmt_meta_out()
1048 dev_dbg(pispbe->dev, "Get output format for meta node %s\n", in pispbe_node_g_fmt_meta_out()
1095 struct pispbe_dev *pispbe = node->pispbe; in pispbe_try_format() local
1100 dev_dbg(pispbe->dev, in pispbe_try_format()
1108 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()
1422 q->dev = pispbe->dev; in pispbe_init_node()
1428 dev_err(pispbe->dev, "vb2_queue_init failed\n"); in pispbe_init_node()
1434 vdev->v4l2_dev = &pispbe->v4l2_dev; in pispbe_init_node()
1444 dev_err(pispbe->dev, in pispbe_init_node()
1452 dev_err(pispbe->dev, in pispbe_init_node()
1460 ret = media_create_pad_link(entity, 0, &pispbe->sd.entity, in pispbe_init_node()
1464 ret = media_create_pad_link(&pispbe->sd.entity, id, entity, in pispbe_init_node()
1470 dev_dbg(pispbe->dev, "%s device node registered as /dev/video%d\n", in pispbe_init_node()
1493 static int pispbe_init_subdev(struct pispbe_dev *pispbe) in pispbe_init_subdev() argument
1495 struct v4l2_subdev *sd = &pispbe->sd; in pispbe_init_subdev()
1501 sd->dev = pispbe->dev; in pispbe_init_subdev()
1505 pispbe->pad[i].flags = in pispbe_init_subdev()
1510 pispbe->pad); in pispbe_init_subdev()
1514 ret = v4l2_device_register_subdev(&pispbe->v4l2_dev, sd); in pispbe_init_subdev()
1525 static int pispbe_init_devices(struct pispbe_dev *pispbe) in pispbe_init_devices() argument
1533 mdev = &pispbe->mdev; in pispbe_init_devices()
1534 mdev->hw_revision = pispbe->hw_version; in pispbe_init_devices()
1535 mdev->dev = pispbe->dev; in pispbe_init_devices()
1539 v4l2_dev = &pispbe->v4l2_dev; in pispbe_init_devices()
1540 v4l2_dev->mdev = &pispbe->mdev; in pispbe_init_devices()
1543 ret = v4l2_device_register(pispbe->dev, v4l2_dev); in pispbe_init_devices()
1547 /* Register the PISPBE subdevice. */ in pispbe_init_devices()
1548 ret = pispbe_init_subdev(pispbe); in pispbe_init_devices()
1554 ret = pispbe_init_node(pispbe, num_regist); in pispbe_init_devices()
1563 pispbe->config = in pispbe_init_devices()
1564 dma_alloc_coherent(pispbe->dev, in pispbe_init_devices()
1567 &pispbe->config_dma_addr, GFP_KERNEL); in pispbe_init_devices()
1568 if (!pispbe->config) { in pispbe_init_devices()
1569 dev_err(pispbe->dev, "Unable to allocate cached config buffers.\n"); in pispbe_init_devices()
1580 video_unregister_device(&pispbe->node[num_regist].vfd); in pispbe_init_devices()
1581 vb2_queue_release(&pispbe->node[num_regist].queue); in pispbe_init_devices()
1583 v4l2_device_unregister_subdev(&pispbe->sd); in pispbe_init_devices()
1584 media_entity_cleanup(&pispbe->sd.entity); in pispbe_init_devices()
1592 static void pispbe_destroy_devices(struct pispbe_dev *pispbe) in pispbe_destroy_devices() argument
1594 if (pispbe->config) { in pispbe_destroy_devices()
1595 dma_free_coherent(pispbe->dev, in pispbe_destroy_devices()
1598 pispbe->config, in pispbe_destroy_devices()
1599 pispbe->config_dma_addr); in pispbe_destroy_devices()
1602 dev_dbg(pispbe->dev, "Unregister from media controller\n"); in pispbe_destroy_devices()
1604 v4l2_device_unregister_subdev(&pispbe->sd); in pispbe_destroy_devices()
1605 media_entity_cleanup(&pispbe->sd.entity); in pispbe_destroy_devices()
1606 media_device_unregister(&pispbe->mdev); in pispbe_destroy_devices()
1609 video_unregister_device(&pispbe->node[i].vfd); in pispbe_destroy_devices()
1610 vb2_queue_release(&pispbe->node[i].queue); in pispbe_destroy_devices()
1611 mutex_destroy(&pispbe->node[i].node_lock); in pispbe_destroy_devices()
1612 mutex_destroy(&pispbe->node[i].queue_lock); in pispbe_destroy_devices()
1615 media_device_cleanup(&pispbe->mdev); in pispbe_destroy_devices()
1616 v4l2_device_unregister(&pispbe->v4l2_dev); in pispbe_destroy_devices()
1621 struct pispbe_dev *pispbe = dev_get_drvdata(dev); in pispbe_runtime_suspend() local
1623 clk_disable_unprepare(pispbe->clk); in pispbe_runtime_suspend()
1630 struct pispbe_dev *pispbe = dev_get_drvdata(dev); in pispbe_runtime_resume() local
1633 ret = clk_prepare_enable(pispbe->clk); in pispbe_runtime_resume()
1640 __func__, clk_get_rate(pispbe->clk)); in pispbe_runtime_resume()
1645 static int pispbe_hw_init(struct pispbe_dev *pispbe) in pispbe_hw_init() argument
1650 u = pispbe_rd(pispbe, PISP_BE_VERSION_REG); in pispbe_hw_init()
1651 dev_dbg(pispbe->dev, "pispbe_probe: HW version: 0x%08x", u); in pispbe_hw_init()
1652 pispbe->hw_version = u; in pispbe_hw_init()
1657 pispbe_wr(pispbe, PISP_BE_INTERRUPT_STATUS_REG, 0xFFFFFFFFu); in pispbe_hw_init()
1658 u = pispbe_rd(pispbe, PISP_BE_BATCH_STATUS_REG); in pispbe_hw_init()
1659 dev_dbg(pispbe->dev, "pispbe_probe: BatchStatus: 0x%08x", u); in pispbe_hw_init()
1661 pispbe->done = (uint8_t)u; in pispbe_hw_init()
1662 pispbe->started = (uint8_t)(u >> 8); in pispbe_hw_init()
1663 u = pispbe_rd(pispbe, PISP_BE_STATUS_REG); in pispbe_hw_init()
1664 dev_dbg(pispbe->dev, "pispbe_probe: Status: 0x%08x", u); in pispbe_hw_init()
1666 if (u != 0 || pispbe->done != pispbe->started) { in pispbe_hw_init()
1667 dev_err(pispbe->dev, "pispbe_probe: HW is stuck or busy\n"); in pispbe_hw_init()
1676 pispbe_wr(pispbe, PISP_BE_AXI_REG, 0x32703200u); in pispbe_hw_init()
1679 pispbe_wr(pispbe, PISP_BE_INTERRUPT_EN_REG, 0x00000003u); in pispbe_hw_init()
1687 struct pispbe_dev *pispbe; in pispbe_probe() local
1690 pispbe = devm_kzalloc(&pdev->dev, sizeof(*pispbe), GFP_KERNEL); in pispbe_probe()
1691 if (!pispbe) in pispbe_probe()
1694 dev_set_drvdata(&pdev->dev, pispbe); in pispbe_probe()
1695 pispbe->dev = &pdev->dev; in pispbe_probe()
1696 platform_set_drvdata(pdev, pispbe); in pispbe_probe()
1698 pispbe->be_reg_base = devm_platform_ioremap_resource(pdev, 0); in pispbe_probe()
1699 if (IS_ERR(pispbe->be_reg_base)) { in pispbe_probe()
1701 return PTR_ERR(pispbe->be_reg_base); in pispbe_probe()
1704 pispbe->irq = platform_get_irq(pdev, 0); in pispbe_probe()
1705 if (pispbe->irq <= 0) in pispbe_probe()
1708 ret = devm_request_irq(&pdev->dev, pispbe->irq, pispbe_isr, 0, in pispbe_probe()
1709 PISPBE_NAME, pispbe); in pispbe_probe()
1715 ret = dma_set_mask_and_coherent(pispbe->dev, DMA_BIT_MASK(36)); in pispbe_probe()
1719 pispbe->clk = devm_clk_get(&pdev->dev, NULL); in pispbe_probe()
1720 if (IS_ERR(pispbe->clk)) in pispbe_probe()
1721 return dev_err_probe(&pdev->dev, PTR_ERR(pispbe->clk), in pispbe_probe()
1725 pm_runtime_set_autosuspend_delay(pispbe->dev, 200); in pispbe_probe()
1726 pm_runtime_use_autosuspend(pispbe->dev); in pispbe_probe()
1727 pm_runtime_enable(pispbe->dev); in pispbe_probe()
1729 ret = pispbe_runtime_resume(pispbe->dev); in pispbe_probe()
1733 pispbe->hw_busy = false; in pispbe_probe()
1734 spin_lock_init(&pispbe->hw_lock); in pispbe_probe()
1735 ret = pispbe_hw_init(pispbe); in pispbe_probe()
1739 ret = pispbe_init_devices(pispbe); in pispbe_probe()
1743 pm_runtime_mark_last_busy(pispbe->dev); in pispbe_probe()
1744 pm_runtime_put_autosuspend(pispbe->dev); in pispbe_probe()
1749 pispbe_destroy_devices(pispbe); in pispbe_probe()
1751 pispbe_runtime_suspend(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 pispbe_runtime_suspend(pispbe->dev); in pispbe_remove()
1766 pm_runtime_dont_use_autosuspend(pispbe->dev); in pispbe_remove()
1767 pm_runtime_disable(pispbe->dev); in pispbe_remove()
1776 .compatible = "raspberrypi,pispbe",