Lines Matching full:vfe
3 * camss-vfe.c
5 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module
25 #include "camss-vfe.h"
30 /* VFE reset timeout */
284 struct vfe_device *vfe = to_vfe(line); in vfe_src_pad_code() local
286 switch (vfe->camss->res->version) { in vfe_src_pad_code()
407 int vfe_reset(struct vfe_device *vfe) in vfe_reset() argument
411 reinit_completion(&vfe->reset_complete); in vfe_reset()
413 vfe->res->hw_ops->global_reset(vfe); in vfe_reset()
415 time = wait_for_completion_timeout(&vfe->reset_complete, in vfe_reset()
418 dev_err(vfe->camss->dev, "VFE reset timeout\n"); in vfe_reset()
425 static void vfe_init_outputs(struct vfe_device *vfe) in vfe_init_outputs() argument
429 for (i = 0; i < vfe->res->line_num; i++) { in vfe_init_outputs()
430 struct vfe_output *output = &vfe->line[i].output; in vfe_init_outputs()
439 static void vfe_reset_output_maps(struct vfe_device *vfe) in vfe_reset_output_maps() argument
443 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) in vfe_reset_output_maps()
444 vfe->wm_output_map[i] = VFE_LINE_NONE; in vfe_reset_output_maps()
447 int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id) in vfe_reserve_wm() argument
452 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) { in vfe_reserve_wm()
453 if (vfe->wm_output_map[i] == VFE_LINE_NONE) { in vfe_reserve_wm()
454 vfe->wm_output_map[i] = line_id; in vfe_reserve_wm()
463 int vfe_release_wm(struct vfe_device *vfe, u8 wm) in vfe_release_wm() argument
465 if (wm >= ARRAY_SIZE(vfe->wm_output_map)) in vfe_release_wm()
468 vfe->wm_output_map[wm] = VFE_LINE_NONE; in vfe_release_wm()
496 * @output: VFE output
513 struct vfe_device *vfe = to_vfe(line); in vfe_put_output() local
518 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_put_output()
521 vfe_release_wm(vfe, output->wm_idx[i]); in vfe_put_output()
525 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_put_output()
531 struct vfe_device *vfe = to_vfe(line); in vfe_disable_output() local
536 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_disable_output()
538 vfe->res->hw_ops->vfe_wm_stop(vfe, output->wm_idx[i]); in vfe_disable_output()
540 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_disable_output()
542 return vfe_reset(vfe); in vfe_disable_output()
546 * vfe_disable - Disable streaming on VFE line
547 * @line: VFE line
553 struct vfe_device *vfe = to_vfe(line); in vfe_disable() local
562 mutex_lock(&vfe->stream_lock); in vfe_disable()
564 vfe->stream_count--; in vfe_disable()
566 mutex_unlock(&vfe->stream_lock); in vfe_disable()
574 * @vfe: VFE Device
577 void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp) in vfe_isr_comp_done() argument
581 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) in vfe_isr_comp_done()
582 if (vfe->wm_output_map[i] == VFE_LINE_PIX) { in vfe_isr_comp_done()
583 vfe->isr_ops.wm_done(vfe, i); in vfe_isr_comp_done()
588 void vfe_isr_reset_ack(struct vfe_device *vfe) in vfe_isr_reset_ack() argument
590 complete(&vfe->reset_complete); in vfe_isr_reset_ack()
594 * vfe_pm_domain_off - Disable power domains specific to this VFE.
595 * @vfe: VFE Device
597 void vfe_pm_domain_off(struct vfe_device *vfe) in vfe_pm_domain_off() argument
599 if (!vfe->genpd) in vfe_pm_domain_off()
602 device_link_del(vfe->genpd_link); in vfe_pm_domain_off()
603 vfe->genpd_link = NULL; in vfe_pm_domain_off()
607 * vfe_pm_domain_on - Enable power domains specific to this VFE.
608 * @vfe: VFE Device
610 int vfe_pm_domain_on(struct vfe_device *vfe) in vfe_pm_domain_on() argument
612 struct camss *camss = vfe->camss; in vfe_pm_domain_on()
614 if (!vfe->genpd) in vfe_pm_domain_on()
617 vfe->genpd_link = device_link_add(camss->dev, vfe->genpd, in vfe_pm_domain_on()
621 if (!vfe->genpd_link) in vfe_pm_domain_on()
627 static int vfe_match_clock_names(struct vfe_device *vfe, in vfe_match_clock_names() argument
633 snprintf(vfe_name, sizeof(vfe_name), "vfe%d", vfe->id); in vfe_match_clock_names()
634 snprintf(vfe_lite_name, sizeof(vfe_lite_name), "vfe_lite%d", vfe->id); in vfe_match_clock_names()
642 * vfe_set_clock_rates - Calculate and set clock rates on VFE module
643 * @vfe: VFE device
647 static int vfe_set_clock_rates(struct vfe_device *vfe) in vfe_set_clock_rates() argument
649 struct device *dev = vfe->camss->dev; in vfe_set_clock_rates()
654 for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) { in vfe_set_clock_rates()
655 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity, in vfe_set_clock_rates()
661 for (i = 0; i < vfe->nclocks; i++) { in vfe_set_clock_rates()
662 struct camss_clock *clock = &vfe->clock[i]; in vfe_set_clock_rates()
664 if (vfe_match_clock_names(vfe, clock)) { in vfe_set_clock_rates()
668 for (j = VFE_LINE_RDI0; j < vfe->res->line_num; j++) { in vfe_set_clock_rates()
675 struct vfe_line *l = &vfe->line[j]; in vfe_set_clock_rates()
695 "Pixel clock is too high for VFE"); in vfe_set_clock_rates()
700 /* set highest possible VFE clock rate */ in vfe_set_clock_rates()
723 * vfe_check_clock_rates - Check current clock rates on VFE module
724 * @vfe: VFE device
729 static int vfe_check_clock_rates(struct vfe_device *vfe) in vfe_check_clock_rates() argument
735 for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) { in vfe_check_clock_rates()
736 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity, in vfe_check_clock_rates()
742 for (i = 0; i < vfe->nclocks; i++) { in vfe_check_clock_rates()
743 struct camss_clock *clock = &vfe->clock[i]; in vfe_check_clock_rates()
745 if (vfe_match_clock_names(vfe, clock)) { in vfe_check_clock_rates()
749 for (j = VFE_LINE_RDI0; j < vfe->res->line_num; j++) { in vfe_check_clock_rates()
756 struct vfe_line *l = &vfe->line[j]; in vfe_check_clock_rates()
780 * vfe_get - Power up and reset VFE module
781 * @vfe: VFE Device
785 int vfe_get(struct vfe_device *vfe) in vfe_get() argument
789 mutex_lock(&vfe->power_lock); in vfe_get()
791 if (vfe->power_count == 0) { in vfe_get()
792 ret = vfe->res->hw_ops->pm_domain_on(vfe); in vfe_get()
796 ret = pm_runtime_resume_and_get(vfe->camss->dev); in vfe_get()
800 ret = vfe_set_clock_rates(vfe); in vfe_get()
804 ret = camss_enable_clocks(vfe->nclocks, vfe->clock, in vfe_get()
805 vfe->camss->dev); in vfe_get()
809 ret = vfe_reset(vfe); in vfe_get()
813 vfe_reset_output_maps(vfe); in vfe_get()
815 vfe_init_outputs(vfe); in vfe_get()
817 vfe->res->hw_ops->hw_version(vfe); in vfe_get()
819 ret = vfe_check_clock_rates(vfe); in vfe_get()
823 vfe->power_count++; in vfe_get()
825 mutex_unlock(&vfe->power_lock); in vfe_get()
830 camss_disable_clocks(vfe->nclocks, vfe->clock); in vfe_get()
833 pm_runtime_put_sync(vfe->camss->dev); in vfe_get()
835 vfe->res->hw_ops->pm_domain_off(vfe); in vfe_get()
838 mutex_unlock(&vfe->power_lock); in vfe_get()
844 * vfe_put - Power down VFE module
845 * @vfe: VFE Device
847 void vfe_put(struct vfe_device *vfe) in vfe_put() argument
849 mutex_lock(&vfe->power_lock); in vfe_put()
851 if (vfe->power_count == 0) { in vfe_put()
852 dev_err(vfe->camss->dev, "vfe power off on power_count == 0\n"); in vfe_put()
854 } else if (vfe->power_count == 1) { in vfe_put()
855 if (vfe->was_streaming) { in vfe_put()
856 vfe->was_streaming = 0; in vfe_put()
857 vfe->res->hw_ops->vfe_halt(vfe); in vfe_put()
859 camss_disable_clocks(vfe->nclocks, vfe->clock); in vfe_put()
860 pm_runtime_put_sync(vfe->camss->dev); in vfe_put()
861 vfe->res->hw_ops->pm_domain_off(vfe); in vfe_put()
864 vfe->power_count--; in vfe_put()
867 mutex_unlock(&vfe->power_lock); in vfe_put()
884 struct vfe_device *vfe = to_vfe(line); in vfe_flush_buffers() local
890 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_flush_buffers()
905 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_flush_buffers()
911 * vfe_set_power - Power on/off VFE module
912 * @sd: VFE V4L2 subdevice
920 struct vfe_device *vfe = to_vfe(line); in vfe_set_power() local
924 ret = vfe_get(vfe); in vfe_set_power()
928 vfe_put(vfe); in vfe_set_power()
935 * vfe_set_stream - Enable/disable streaming on VFE module
936 * @sd: VFE V4L2 subdevice
939 * Main configuration of VFE module is triggered here.
946 struct vfe_device *vfe = to_vfe(line); in vfe_set_stream() local
951 ret = vfe->res->hw_ops->vfe_enable(line); in vfe_set_stream()
953 dev_err(vfe->camss->dev, in vfe_set_stream()
954 "Failed to enable vfe outputs\n"); in vfe_set_stream()
956 ret = vfe->res->hw_ops->vfe_disable(line); in vfe_set_stream()
958 dev_err(vfe->camss->dev, in vfe_set_stream()
959 "Failed to disable vfe outputs\n"); in vfe_set_stream()
967 * @line: VFE line
988 * @line: VFE line
1008 * @line: VFE line
1027 * @line: VFE line
1088 * @line: VFE line
1127 * @line: VFE line
1170 * @sd: VFE V4L2 subdevice
1204 * @sd: VFE V4L2 subdevice
1242 * @sd: VFE V4L2 subdevice
1270 * @sd: VFE V4L2 subdevice
1321 * @sd: VFE V4L2 subdevice
1391 * @sd: VFE V4L2 subdevice
1455 * @sd: VFE V4L2 subdevice
1479 * msm_vfe_subdev_init - Initialize VFE device structure and resources
1480 * @vfe: VFE device
1481 * @res: VFE module resources table
1485 int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, in msm_vfe_subdev_init() argument
1493 if (!res->vfe.line_num) in msm_vfe_subdev_init()
1496 vfe->res = &res->vfe; in msm_vfe_subdev_init()
1497 vfe->res->hw_ops->subdev_init(dev, vfe); in msm_vfe_subdev_init()
1501 if (res->vfe.pd_name) { in msm_vfe_subdev_init()
1502 vfe->genpd = dev_pm_domain_attach_by_name(camss->dev, in msm_vfe_subdev_init()
1503 res->vfe.pd_name); in msm_vfe_subdev_init()
1504 if (IS_ERR(vfe->genpd)) { in msm_vfe_subdev_init()
1505 ret = PTR_ERR(vfe->genpd); in msm_vfe_subdev_init()
1510 if (!vfe->genpd && res->vfe.has_pd) { in msm_vfe_subdev_init()
1517 * id must correspondng to the index of the VFE which must in msm_vfe_subdev_init()
1518 * come before the TOP GDSC. VFE Lite has no individually in msm_vfe_subdev_init()
1522 vfe->genpd = dev_pm_domain_attach_by_id(camss->dev, id); in msm_vfe_subdev_init()
1523 if (IS_ERR(vfe->genpd)) in msm_vfe_subdev_init()
1524 return PTR_ERR(vfe->genpd); in msm_vfe_subdev_init()
1529 vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]); in msm_vfe_subdev_init()
1530 if (IS_ERR(vfe->base)) { in msm_vfe_subdev_init()
1532 return PTR_ERR(vfe->base); in msm_vfe_subdev_init()
1541 vfe->irq = ret; in msm_vfe_subdev_init()
1542 snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d", in msm_vfe_subdev_init()
1544 ret = devm_request_irq(dev, vfe->irq, vfe->res->hw_ops->isr, in msm_vfe_subdev_init()
1545 IRQF_TRIGGER_RISING, vfe->irq_name, vfe); in msm_vfe_subdev_init()
1553 vfe->nclocks = 0; in msm_vfe_subdev_init()
1554 while (res->clock[vfe->nclocks]) in msm_vfe_subdev_init()
1555 vfe->nclocks++; in msm_vfe_subdev_init()
1557 vfe->clock = devm_kcalloc(dev, vfe->nclocks, sizeof(*vfe->clock), in msm_vfe_subdev_init()
1559 if (!vfe->clock) in msm_vfe_subdev_init()
1562 for (i = 0; i < vfe->nclocks; i++) { in msm_vfe_subdev_init()
1563 struct camss_clock *clock = &vfe->clock[i]; in msm_vfe_subdev_init()
1591 mutex_init(&vfe->power_lock); in msm_vfe_subdev_init()
1592 vfe->power_count = 0; in msm_vfe_subdev_init()
1594 mutex_init(&vfe->stream_lock); in msm_vfe_subdev_init()
1595 vfe->stream_count = 0; in msm_vfe_subdev_init()
1597 spin_lock_init(&vfe->output_lock); in msm_vfe_subdev_init()
1599 vfe->camss = camss; in msm_vfe_subdev_init()
1600 vfe->id = id; in msm_vfe_subdev_init()
1601 vfe->reg_update = 0; in msm_vfe_subdev_init()
1603 for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) { in msm_vfe_subdev_init()
1604 struct vfe_line *l = &vfe->line[i]; in msm_vfe_subdev_init()
1613 l->nformats = res->vfe.formats_pix->nformats; in msm_vfe_subdev_init()
1614 l->formats = res->vfe.formats_pix->formats; in msm_vfe_subdev_init()
1616 l->nformats = res->vfe.formats_rdi->nformats; in msm_vfe_subdev_init()
1617 l->formats = res->vfe.formats_rdi->formats; in msm_vfe_subdev_init()
1621 init_completion(&vfe->reset_complete); in msm_vfe_subdev_init()
1622 init_completion(&vfe->halt_complete); in msm_vfe_subdev_init()
1628 * msm_vfe_genpd_cleanup - Cleanup VFE genpd linkages
1629 * @vfe: VFE device
1631 void msm_vfe_genpd_cleanup(struct vfe_device *vfe) in msm_vfe_genpd_cleanup() argument
1633 if (vfe->genpd_link) in msm_vfe_genpd_cleanup()
1634 device_link_del(vfe->genpd_link); in msm_vfe_genpd_cleanup()
1636 if (vfe->genpd) in msm_vfe_genpd_cleanup()
1637 dev_pm_domain_detach(vfe->genpd, true); in msm_vfe_genpd_cleanup()
1641 * vfe_link_setup - Setup VFE connections
1692 static int vfe_bpl_align(struct vfe_device *vfe) in vfe_bpl_align() argument
1696 switch (vfe->camss->res->version) { in vfe_bpl_align()
1711 * msm_vfe_register_entities - Register subdev node for VFE module
1712 * @vfe: VFE device
1715 * Initialize and register a subdev node for the VFE module. Then
1722 int msm_vfe_register_entities(struct vfe_device *vfe, in msm_vfe_register_entities() argument
1725 struct device *dev = vfe->camss->dev; in msm_vfe_register_entities()
1732 for (i = 0; i < vfe->res->line_num; i++) { in msm_vfe_register_entities()
1735 sd = &vfe->line[i].subdev; in msm_vfe_register_entities()
1736 pads = vfe->line[i].pads; in msm_vfe_register_entities()
1737 video_out = &vfe->line[i].video_out; in msm_vfe_register_entities()
1744 MSM_VFE_NAME, vfe->id, "pix"); in msm_vfe_register_entities()
1747 MSM_VFE_NAME, vfe->id, "rdi", i); in msm_vfe_register_entities()
1749 v4l2_set_subdevdata(sd, &vfe->line[i]); in msm_vfe_register_entities()
1775 video_out->ops = &vfe->video_ops; in msm_vfe_register_entities()
1776 video_out->bpl_alignment = vfe_bpl_align(vfe); in msm_vfe_register_entities()
1783 video_out->nformats = vfe->line[i].nformats; in msm_vfe_register_entities()
1784 video_out->formats = vfe->line[i].formats; in msm_vfe_register_entities()
1787 MSM_VFE_NAME, vfe->id, "video", i); in msm_vfe_register_entities()
1820 sd = &vfe->line[i].subdev; in msm_vfe_register_entities()
1821 video_out = &vfe->line[i].video_out; in msm_vfe_register_entities()
1832 * msm_vfe_unregister_entities - Unregister VFE module subdev node
1833 * @vfe: VFE device
1835 void msm_vfe_unregister_entities(struct vfe_device *vfe) in msm_vfe_unregister_entities() argument
1839 mutex_destroy(&vfe->power_lock); in msm_vfe_unregister_entities()
1840 mutex_destroy(&vfe->stream_lock); in msm_vfe_unregister_entities()
1842 for (i = 0; i < vfe->res->line_num; i++) { in msm_vfe_unregister_entities()
1843 struct v4l2_subdev *sd = &vfe->line[i].subdev; in msm_vfe_unregister_entities()
1844 struct camss_video *video_out = &vfe->line[i].video_out; in msm_vfe_unregister_entities()
1852 bool vfe_is_lite(struct vfe_device *vfe) in vfe_is_lite() argument
1854 return vfe->camss->res->vfe_res[vfe->id].vfe.is_lite; in vfe_is_lite()