Lines Matching +full:sel +full:- +full:clk
1 // SPDX-License-Identifier: GPL-2.0
3 * camss-vfe.c
5 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module
7 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
8 * Copyright (C) 2015-2018 Linaro Ltd.
10 #include <linux/clk.h>
21 #include <media/media-entity.h>
22 #include <media/v4l2-device.h>
23 #include <media/v4l2-subdev.h>
25 #include "camss-vfe.h"
286 switch (vfe->camss->res->version) { in vfe_src_pad_code()
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()
419 return -EIO; in vfe_reset()
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()
432 output->state = VFE_OUTPUT_OFF; in vfe_init_outputs()
433 output->buf[0] = NULL; in vfe_init_outputs()
434 output->buf[1] = NULL; in vfe_init_outputs()
435 INIT_LIST_HEAD(&output->pending_bufs); in vfe_init_outputs()
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()
449 int ret = -EBUSY; in vfe_reserve_wm()
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()
465 if (wm >= ARRAY_SIZE(vfe->wm_output_map)) in vfe_release_wm()
466 return -EINVAL; in vfe_release_wm()
468 vfe->wm_output_map[wm] = VFE_LINE_NONE; in vfe_release_wm()
477 if (!list_empty(&output->pending_bufs)) { in vfe_buf_get_pending()
478 buffer = list_first_entry(&output->pending_bufs, in vfe_buf_get_pending()
481 list_del(&buffer->queue); in vfe_buf_get_pending()
490 INIT_LIST_HEAD(&buffer->queue); in vfe_buf_add_pending()
491 list_add_tail(&buffer->queue, &output->pending_bufs); in vfe_buf_add_pending()
495 * vfe_buf_flush_pending - Flush all pending buffers.
505 list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) { in vfe_buf_flush_pending()
506 vb2_buffer_done(&buf->vb.vb2_buf, state); in vfe_buf_flush_pending()
507 list_del(&buf->queue); in vfe_buf_flush_pending()
514 struct vfe_output *output = &line->output; in vfe_put_output()
518 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_put_output()
520 for (i = 0; i < output->wm_num; i++) in vfe_put_output()
521 vfe_release_wm(vfe, output->wm_idx[i]); in vfe_put_output()
523 output->state = VFE_OUTPUT_OFF; in vfe_put_output()
525 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_put_output()
532 struct vfe_output *output = &line->output; in vfe_disable_output()
536 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_disable_output()
537 for (i = 0; i < output->wm_num; i++) in vfe_disable_output()
538 vfe->res->hw_ops->vfe_wm_stop(vfe, output->wm_idx[i]); in vfe_disable_output()
539 output->gen2.active_num = 0; in vfe_disable_output()
540 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_disable_output()
546 * vfe_disable - Disable streaming on VFE line
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()
573 * vfe_isr_comp_done() - Process composite image done interrupt
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()
590 complete(&vfe->reset_complete); in vfe_isr_reset_ack()
594 * vfe_pm_domain_off - Disable power domains specific to this VFE.
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.
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()
622 return -EINVAL; in vfe_pm_domain_on()
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()
636 return (!strcmp(clock->name, vfe_name) || in vfe_match_clock_names()
637 !strcmp(clock->name, vfe_lite_name) || in vfe_match_clock_names()
638 !strcmp(clock->name, "vfe_lite")); in vfe_match_clock_names()
642 * vfe_set_clock_rates - Calculate and set clock rates on VFE module
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()
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()
677 bpp = camss_format_get_bpp(l->formats, in vfe_set_clock_rates()
678 l->nformats, in vfe_set_clock_rates()
679 l->fmt[MSM_VFE_PAD_SINK].code); in vfe_set_clock_rates()
689 for (j = 0; j < clock->nfreqs; j++) in vfe_set_clock_rates()
690 if (min_rate < clock->freq[j]) in vfe_set_clock_rates()
693 if (j == clock->nfreqs) { in vfe_set_clock_rates()
696 return -EINVAL; in vfe_set_clock_rates()
702 j = clock->nfreqs - 1; in vfe_set_clock_rates()
704 rate = clk_round_rate(clock->clk, clock->freq[j]); in vfe_set_clock_rates()
706 dev_err(dev, "clk round rate failed: %ld\n", in vfe_set_clock_rates()
708 return -EINVAL; in vfe_set_clock_rates()
711 ret = clk_set_rate(clock->clk, rate); in vfe_set_clock_rates()
713 dev_err(dev, "clk set rate failed: %d\n", ret); in vfe_set_clock_rates()
723 * vfe_check_clock_rates - Check current clock rates on VFE module
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()
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()
758 bpp = camss_format_get_bpp(l->formats, in vfe_check_clock_rates()
759 l->nformats, in vfe_check_clock_rates()
760 l->fmt[MSM_VFE_PAD_SINK].code); in vfe_check_clock_rates()
770 rate = clk_get_rate(clock->clk); in vfe_check_clock_rates()
772 return -EBUSY; in vfe_check_clock_rates()
780 * vfe_get - Power up and reset VFE module
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()
804 ret = camss_enable_clocks(vfe->nclocks, vfe->clock, in vfe_get()
805 vfe->camss->dev); in vfe_get()
817 vfe->res->hw_ops->hw_version(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
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()
871 * vfe_flush_buffers - Return all vb2 buffers
888 output = &line->output; in vfe_flush_buffers()
890 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_flush_buffers()
894 if (output->buf[0]) in vfe_flush_buffers()
895 vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state); in vfe_flush_buffers()
897 if (output->buf[1]) in vfe_flush_buffers()
898 vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state); in vfe_flush_buffers()
900 if (output->last_buffer) { in vfe_flush_buffers()
901 vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state); in vfe_flush_buffers()
902 output->last_buffer = NULL; 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
935 * vfe_set_stream - Enable/disable streaming on VFE module
950 line->output.state = VFE_OUTPUT_RESERVED; in vfe_set_stream()
951 ret = vfe->res->hw_ops->vfe_enable(line); in vfe_set_stream()
953 dev_err(vfe->camss->dev, 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()
966 * __vfe_get_format - Get pointer to format structure
983 return &line->fmt[pad]; in __vfe_get_format()
987 * __vfe_get_compose - Get pointer to compose selection structure
1003 return &line->compose; in __vfe_get_compose()
1007 * __vfe_get_crop - Get pointer to crop selection structure
1022 return &line->crop; in __vfe_get_crop()
1026 * vfe_try_format - Handle try format by pad subdev method
1046 for (i = 0; i < line->nformats; i++) in vfe_try_format()
1047 if (fmt->code == line->formats[i].code) in vfe_try_format()
1051 if (i >= line->nformats) in vfe_try_format()
1052 fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; in vfe_try_format()
1054 fmt->width = clamp_t(u32, fmt->width, 1, 8191); in vfe_try_format()
1055 fmt->height = clamp_t(u32, fmt->height, 1, 8191); in vfe_try_format()
1057 fmt->field = V4L2_FIELD_NONE; in vfe_try_format()
1058 fmt->colorspace = V4L2_COLORSPACE_SRGB; in vfe_try_format()
1064 code = fmt->code; in vfe_try_format()
1069 fmt->code = vfe_src_pad_code(line, fmt->code, 0, code); in vfe_try_format()
1071 if (line->id == VFE_LINE_PIX) { in vfe_try_format()
1076 fmt->width = rect->width; in vfe_try_format()
1077 fmt->height = rect->height; in vfe_try_format()
1083 fmt->colorspace = V4L2_COLORSPACE_SRGB; in vfe_try_format()
1087 * vfe_try_compose - Handle try compose selection by pad subdev method
1102 if (rect->width > fmt->width) in vfe_try_compose()
1103 rect->width = fmt->width; in vfe_try_compose()
1105 if (rect->height > fmt->height) in vfe_try_compose()
1106 rect->height = fmt->height; in vfe_try_compose()
1108 if (fmt->width > rect->width * SCALER_RATIO_MAX) in vfe_try_compose()
1109 rect->width = (fmt->width + SCALER_RATIO_MAX - 1) / in vfe_try_compose()
1112 rect->width &= ~0x1; in vfe_try_compose()
1114 if (fmt->height > rect->height * SCALER_RATIO_MAX) in vfe_try_compose()
1115 rect->height = (fmt->height + SCALER_RATIO_MAX - 1) / in vfe_try_compose()
1118 if (rect->width < 16) in vfe_try_compose()
1119 rect->width = 16; in vfe_try_compose()
1121 if (rect->height < 4) in vfe_try_compose()
1122 rect->height = 4; in vfe_try_compose()
1126 * vfe_try_crop - Handle try crop selection by pad subdev method
1141 if (rect->width > compose->width) in vfe_try_crop()
1142 rect->width = compose->width; in vfe_try_crop()
1144 if (rect->width + rect->left > compose->width) in vfe_try_crop()
1145 rect->left = compose->width - rect->width; in vfe_try_crop()
1147 if (rect->height > compose->height) in vfe_try_crop()
1148 rect->height = compose->height; in vfe_try_crop()
1150 if (rect->height + rect->top > compose->height) in vfe_try_crop()
1151 rect->top = compose->height - rect->height; in vfe_try_crop()
1154 rect->left += (rect->width & 0xf) >> 1; in vfe_try_crop()
1155 rect->width &= ~0xf; in vfe_try_crop()
1157 if (rect->width < 16) { in vfe_try_crop()
1158 rect->left = 0; in vfe_try_crop()
1159 rect->width = 16; in vfe_try_crop()
1162 if (rect->height < 4) { in vfe_try_crop()
1163 rect->top = 0; in vfe_try_crop()
1164 rect->height = 4; in vfe_try_crop()
1169 * vfe_enum_mbus_code - Handle pixel format enumeration
1174 * return -EINVAL or zero on success
1182 if (code->pad == MSM_VFE_PAD_SINK) { in vfe_enum_mbus_code()
1183 if (code->index >= line->nformats) in vfe_enum_mbus_code()
1184 return -EINVAL; in vfe_enum_mbus_code()
1186 code->code = line->formats[code->index].code; in vfe_enum_mbus_code()
1191 code->which); in vfe_enum_mbus_code()
1193 code->code = vfe_src_pad_code(line, sink_fmt->code, in vfe_enum_mbus_code()
1194 code->index, 0); in vfe_enum_mbus_code()
1195 if (!code->code) in vfe_enum_mbus_code()
1196 return -EINVAL; in vfe_enum_mbus_code()
1203 * vfe_enum_frame_size - Handle frame size enumeration
1208 * Return -EINVAL or zero on success
1217 if (fse->index != 0) in vfe_enum_frame_size()
1218 return -EINVAL; in vfe_enum_frame_size()
1220 format.code = fse->code; in vfe_enum_frame_size()
1223 vfe_try_format(line, sd_state, fse->pad, &format, fse->which); in vfe_enum_frame_size()
1224 fse->min_width = format.width; in vfe_enum_frame_size()
1225 fse->min_height = format.height; in vfe_enum_frame_size()
1227 if (format.code != fse->code) in vfe_enum_frame_size()
1228 return -EINVAL; in vfe_enum_frame_size()
1230 format.code = fse->code; in vfe_enum_frame_size()
1231 format.width = -1; in vfe_enum_frame_size()
1232 format.height = -1; in vfe_enum_frame_size()
1233 vfe_try_format(line, sd_state, fse->pad, &format, fse->which); in vfe_enum_frame_size()
1234 fse->max_width = format.width; in vfe_enum_frame_size()
1235 fse->max_height = format.height; in vfe_enum_frame_size()
1241 * vfe_get_format - Handle get format by pads subdev method
1246 * Return -EINVAL or zero on success
1255 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which); in vfe_get_format()
1257 return -EINVAL; in vfe_get_format()
1259 fmt->format = *format; in vfe_get_format()
1266 struct v4l2_subdev_selection *sel);
1269 * vfe_set_format - Handle set format by pads subdev method
1274 * Return -EINVAL or zero on success
1283 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which); in vfe_set_format()
1285 return -EINVAL; in vfe_set_format()
1287 vfe_try_format(line, sd_state, fmt->pad, &fmt->format, fmt->which); in vfe_set_format()
1288 *format = fmt->format; in vfe_set_format()
1290 if (fmt->pad == MSM_VFE_PAD_SINK) { in vfe_set_format()
1291 struct v4l2_subdev_selection sel = { 0 }; in vfe_set_format() local
1296 fmt->which); in vfe_set_format()
1298 *format = fmt->format; in vfe_set_format()
1300 fmt->which); in vfe_set_format()
1302 if (line->id != VFE_LINE_PIX) in vfe_set_format()
1306 sel.which = fmt->which; in vfe_set_format()
1307 sel.pad = MSM_VFE_PAD_SINK; in vfe_set_format()
1308 sel.target = V4L2_SEL_TGT_COMPOSE; in vfe_set_format()
1309 sel.r.width = fmt->format.width; in vfe_set_format()
1310 sel.r.height = fmt->format.height; in vfe_set_format()
1311 ret = vfe_set_selection(sd, sd_state, &sel); in vfe_set_format()
1320 * vfe_get_selection - Handle get selection by pads subdev method
1323 * @sel: pointer to v4l2 subdev selection structure
1325 * Return -EINVAL or zero on success
1329 struct v4l2_subdev_selection *sel) in vfe_get_selection() argument
1336 if (line->id != VFE_LINE_PIX) in vfe_get_selection()
1337 return -EINVAL; in vfe_get_selection()
1339 if (sel->pad == MSM_VFE_PAD_SINK) in vfe_get_selection()
1340 switch (sel->target) { in vfe_get_selection()
1342 fmt.pad = sel->pad; in vfe_get_selection()
1343 fmt.which = sel->which; in vfe_get_selection()
1348 sel->r.left = 0; in vfe_get_selection()
1349 sel->r.top = 0; in vfe_get_selection()
1350 sel->r.width = fmt.format.width; in vfe_get_selection()
1351 sel->r.height = fmt.format.height; in vfe_get_selection()
1354 rect = __vfe_get_compose(line, sd_state, sel->which); in vfe_get_selection()
1356 return -EINVAL; in vfe_get_selection()
1358 sel->r = *rect; in vfe_get_selection()
1361 return -EINVAL; in vfe_get_selection()
1363 else if (sel->pad == MSM_VFE_PAD_SRC) in vfe_get_selection()
1364 switch (sel->target) { in vfe_get_selection()
1366 rect = __vfe_get_compose(line, sd_state, sel->which); in vfe_get_selection()
1368 return -EINVAL; in vfe_get_selection()
1370 sel->r.left = rect->left; in vfe_get_selection()
1371 sel->r.top = rect->top; in vfe_get_selection()
1372 sel->r.width = rect->width; in vfe_get_selection()
1373 sel->r.height = rect->height; in vfe_get_selection()
1376 rect = __vfe_get_crop(line, sd_state, sel->which); in vfe_get_selection()
1378 return -EINVAL; in vfe_get_selection()
1380 sel->r = *rect; in vfe_get_selection()
1383 return -EINVAL; in vfe_get_selection()
1390 * vfe_set_selection - Handle set selection by pads subdev method
1393 * @sel: pointer to v4l2 subdev selection structure
1395 * Return -EINVAL or zero on success
1399 struct v4l2_subdev_selection *sel) in vfe_set_selection() argument
1405 if (line->id != VFE_LINE_PIX) in vfe_set_selection()
1406 return -EINVAL; in vfe_set_selection()
1408 if (sel->target == V4L2_SEL_TGT_COMPOSE && in vfe_set_selection()
1409 sel->pad == MSM_VFE_PAD_SINK) { in vfe_set_selection()
1412 rect = __vfe_get_compose(line, sd_state, sel->which); in vfe_set_selection()
1414 return -EINVAL; in vfe_set_selection()
1416 vfe_try_compose(line, sd_state, &sel->r, sel->which); in vfe_set_selection()
1417 *rect = sel->r; in vfe_set_selection()
1420 crop.which = sel->which; in vfe_set_selection()
1425 } else if (sel->target == V4L2_SEL_TGT_CROP && in vfe_set_selection()
1426 sel->pad == MSM_VFE_PAD_SRC) { in vfe_set_selection()
1429 rect = __vfe_get_crop(line, sd_state, sel->which); in vfe_set_selection()
1431 return -EINVAL; in vfe_set_selection()
1433 vfe_try_crop(line, sd_state, &sel->r, sel->which); in vfe_set_selection()
1434 *rect = sel->r; in vfe_set_selection()
1437 fmt.which = sel->which; in vfe_set_selection()
1443 fmt.format.width = rect->width; in vfe_set_selection()
1444 fmt.format.height = rect->height; in vfe_set_selection()
1447 ret = -EINVAL; in vfe_set_selection()
1454 * vfe_init_formats - Initialize formats on all pads
1475 return vfe_set_format(sd, fh ? fh->state : NULL, &format); in vfe_init_formats()
1479 * msm_vfe_subdev_init - Initialize VFE device structure and resources
1488 struct device *dev = camss->dev; in msm_vfe_subdev_init()
1493 if (!res->vfe.line_num) in msm_vfe_subdev_init()
1494 return -EINVAL; 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()
1514 * power-domain = <VFE_X>, 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()
1537 ret = platform_get_irq_byname(pdev, res->interrupt[0]); 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()
1560 return -ENOMEM; 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()
1565 clock->clk = devm_clk_get(dev, res->clock[i]); in msm_vfe_subdev_init()
1566 if (IS_ERR(clock->clk)) in msm_vfe_subdev_init()
1567 return PTR_ERR(clock->clk); in msm_vfe_subdev_init()
1569 clock->name = res->clock[i]; in msm_vfe_subdev_init()
1571 clock->nfreqs = 0; in msm_vfe_subdev_init()
1572 while (res->clock_rate[i][clock->nfreqs]) in msm_vfe_subdev_init()
1573 clock->nfreqs++; in msm_vfe_subdev_init()
1575 if (!clock->nfreqs) { in msm_vfe_subdev_init()
1576 clock->freq = NULL; in msm_vfe_subdev_init()
1580 clock->freq = devm_kcalloc(dev, in msm_vfe_subdev_init()
1581 clock->nfreqs, in msm_vfe_subdev_init()
1582 sizeof(*clock->freq), in msm_vfe_subdev_init()
1584 if (!clock->freq) in msm_vfe_subdev_init()
1585 return -ENOMEM; in msm_vfe_subdev_init()
1587 for (j = 0; j < clock->nfreqs; j++) in msm_vfe_subdev_init()
1588 clock->freq[j] = res->clock_rate[i][j]; 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()
1606 l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in msm_vfe_subdev_init()
1607 l->video_out.camss = camss; in msm_vfe_subdev_init()
1608 l->id = i; in msm_vfe_subdev_init()
1609 init_completion(&l->output.sof); in msm_vfe_subdev_init()
1610 init_completion(&l->output.reg_update); 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
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
1655 return -EBUSY; in vfe_link_setup()
1696 switch (vfe->camss->res->version) { in vfe_bpl_align()
1711 * msm_vfe_register_entities - Register subdev node for VFE module
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()
1740 sd->internal_ops = &vfe_v4l2_internal_ops; in msm_vfe_register_entities()
1741 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in msm_vfe_register_entities()
1743 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s", in msm_vfe_register_entities()
1744 MSM_VFE_NAME, vfe->id, "pix"); in msm_vfe_register_entities()
1746 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d", 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()
1760 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; in msm_vfe_register_entities()
1761 sd->entity.ops = &vfe_media_ops; in msm_vfe_register_entities()
1762 ret = media_entity_pads_init(&sd->entity, MSM_VFE_PADS_NUM, 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()
1777 video_out->line_based = 0; in msm_vfe_register_entities()
1779 video_out->bpl_alignment = 16; in msm_vfe_register_entities()
1780 video_out->line_based = 1; 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()
1796 &sd->entity, MSM_VFE_PAD_SRC, in msm_vfe_register_entities()
1797 &video_out->vdev.entity, 0, in msm_vfe_register_entities()
1800 dev_err(dev, "Failed to link %s->%s entities: %d\n", in msm_vfe_register_entities()
1801 sd->entity.name, video_out->vdev.entity.name, in msm_vfe_register_entities()
1816 media_entity_cleanup(&sd->entity); in msm_vfe_register_entities()
1819 for (i--; i >= 0; 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()
1825 media_entity_cleanup(&sd->entity); in msm_vfe_register_entities()
1832 * msm_vfe_unregister_entities - Unregister VFE module subdev node
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()
1848 media_entity_cleanup(&sd->entity); in msm_vfe_unregister_entities()
1854 return vfe->camss->res->vfe_res[vfe->id].vfe.is_lite; in vfe_is_lite()