Lines Matching +full:device +full:- +full:width
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.
20 #include <media/media-entity.h>
21 #include <media/v4l2-device.h>
22 #include <media/v4l2-subdev.h>
24 #include "camss-vfe.h"
127 * vfe_get_bpp - map media bus format to bits per pixel
173 if (vfe->camss->version == CAMSS_8x16) in vfe_src_pad_code()
221 else if (vfe->camss->version == CAMSS_8x96 || in vfe_src_pad_code()
222 vfe->camss->version == CAMSS_660 || in vfe_src_pad_code()
223 vfe->camss->version == CAMSS_845 || in vfe_src_pad_code()
224 vfe->camss->version == CAMSS_8250) in vfe_src_pad_code()
292 reinit_completion(&vfe->reset_complete); in vfe_reset()
294 vfe->ops->global_reset(vfe); in vfe_reset()
296 time = wait_for_completion_timeout(&vfe->reset_complete, in vfe_reset()
299 dev_err(vfe->camss->dev, "VFE reset timeout\n"); in vfe_reset()
300 return -EIO; in vfe_reset()
310 for (i = 0; i < vfe->line_num; i++) { in vfe_init_outputs()
311 struct vfe_output *output = &vfe->line[i].output; in vfe_init_outputs()
313 output->state = VFE_OUTPUT_OFF; in vfe_init_outputs()
314 output->buf[0] = NULL; in vfe_init_outputs()
315 output->buf[1] = NULL; in vfe_init_outputs()
316 INIT_LIST_HEAD(&output->pending_bufs); in vfe_init_outputs()
324 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) in vfe_reset_output_maps()
325 vfe->wm_output_map[i] = VFE_LINE_NONE; in vfe_reset_output_maps()
330 int ret = -EBUSY; in vfe_reserve_wm()
333 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) { in vfe_reserve_wm()
334 if (vfe->wm_output_map[i] == VFE_LINE_NONE) { in vfe_reserve_wm()
335 vfe->wm_output_map[i] = line_id; in vfe_reserve_wm()
346 if (wm >= ARRAY_SIZE(vfe->wm_output_map)) in vfe_release_wm()
347 return -EINVAL; in vfe_release_wm()
349 vfe->wm_output_map[wm] = VFE_LINE_NONE; in vfe_release_wm()
358 if (!list_empty(&output->pending_bufs)) { in vfe_buf_get_pending()
359 buffer = list_first_entry(&output->pending_bufs, in vfe_buf_get_pending()
362 list_del(&buffer->queue); in vfe_buf_get_pending()
371 INIT_LIST_HEAD(&buffer->queue); in vfe_buf_add_pending()
372 list_add_tail(&buffer->queue, &output->pending_bufs); in vfe_buf_add_pending()
376 * vfe_buf_flush_pending - Flush all pending buffers.
386 list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) { in vfe_buf_flush_pending()
387 vb2_buffer_done(&buf->vb.vb2_buf, state); in vfe_buf_flush_pending()
388 list_del(&buf->queue); in vfe_buf_flush_pending()
395 struct vfe_output *output = &line->output; in vfe_put_output()
399 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_put_output()
401 for (i = 0; i < output->wm_num; i++) in vfe_put_output()
402 vfe_release_wm(vfe, output->wm_idx[i]); in vfe_put_output()
404 output->state = VFE_OUTPUT_OFF; in vfe_put_output()
406 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_put_output()
411 * vfe_isr_comp_done() - Process composite image done interrupt
412 * @vfe: VFE Device
419 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) in vfe_isr_comp_done()
420 if (vfe->wm_output_map[i] == VFE_LINE_PIX) { in vfe_isr_comp_done()
421 vfe->isr_ops.wm_done(vfe, i); in vfe_isr_comp_done()
428 complete(&vfe->reset_complete); in vfe_isr_reset_ack()
432 * vfe_set_clock_rates - Calculate and set clock rates on VFE module
433 * @vfe: VFE device
439 struct device *dev = vfe->camss->dev; in vfe_set_clock_rates()
444 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) { in vfe_set_clock_rates()
445 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity, in vfe_set_clock_rates()
451 for (i = 0; i < vfe->nclocks; i++) { in vfe_set_clock_rates()
452 struct camss_clock *clock = &vfe->clock[i]; in vfe_set_clock_rates()
454 if (!strcmp(clock->name, "vfe0") || in vfe_set_clock_rates()
455 !strcmp(clock->name, "vfe1") || in vfe_set_clock_rates()
456 !strcmp(clock->name, "vfe_lite")) { in vfe_set_clock_rates()
460 for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) { in vfe_set_clock_rates()
467 struct vfe_line *l = &vfe->line[j]; in vfe_set_clock_rates()
469 bpp = vfe_get_bpp(l->formats, in vfe_set_clock_rates()
470 l->nformats, in vfe_set_clock_rates()
471 l->fmt[MSM_VFE_PAD_SINK].code); in vfe_set_clock_rates()
481 for (j = 0; j < clock->nfreqs; j++) in vfe_set_clock_rates()
482 if (min_rate < clock->freq[j]) in vfe_set_clock_rates()
485 if (j == clock->nfreqs) { in vfe_set_clock_rates()
488 return -EINVAL; in vfe_set_clock_rates()
494 j = clock->nfreqs - 1; in vfe_set_clock_rates()
496 rate = clk_round_rate(clock->clk, clock->freq[j]); in vfe_set_clock_rates()
500 return -EINVAL; in vfe_set_clock_rates()
503 ret = clk_set_rate(clock->clk, rate); in vfe_set_clock_rates()
515 * vfe_check_clock_rates - Check current clock rates on VFE module
516 * @vfe: VFE device
527 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) { in vfe_check_clock_rates()
528 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity, in vfe_check_clock_rates()
534 for (i = 0; i < vfe->nclocks; i++) { in vfe_check_clock_rates()
535 struct camss_clock *clock = &vfe->clock[i]; in vfe_check_clock_rates()
537 if (!strcmp(clock->name, "vfe0") || in vfe_check_clock_rates()
538 !strcmp(clock->name, "vfe1") || in vfe_check_clock_rates()
539 !strcmp(clock->name, "vfe_lite")) { in vfe_check_clock_rates()
543 for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) { in vfe_check_clock_rates()
550 struct vfe_line *l = &vfe->line[j]; in vfe_check_clock_rates()
552 bpp = vfe_get_bpp(l->formats, in vfe_check_clock_rates()
553 l->nformats, in vfe_check_clock_rates()
554 l->fmt[MSM_VFE_PAD_SINK].code); in vfe_check_clock_rates()
564 rate = clk_get_rate(clock->clk); in vfe_check_clock_rates()
566 return -EBUSY; in vfe_check_clock_rates()
574 * vfe_get - Power up and reset VFE module
575 * @vfe: VFE Device
583 mutex_lock(&vfe->power_lock); in vfe_get()
585 if (vfe->power_count == 0) { in vfe_get()
586 ret = vfe->ops->pm_domain_on(vfe); in vfe_get()
590 ret = pm_runtime_resume_and_get(vfe->camss->dev); in vfe_get()
598 ret = camss_enable_clocks(vfe->nclocks, vfe->clock, in vfe_get()
599 vfe->camss->dev); in vfe_get()
611 vfe->ops->hw_version(vfe); in vfe_get()
617 vfe->power_count++; in vfe_get()
619 mutex_unlock(&vfe->power_lock); in vfe_get()
624 camss_disable_clocks(vfe->nclocks, vfe->clock); in vfe_get()
627 pm_runtime_put_sync(vfe->camss->dev); in vfe_get()
629 vfe->ops->pm_domain_off(vfe); in vfe_get()
632 mutex_unlock(&vfe->power_lock); in vfe_get()
638 * vfe_put - Power down VFE module
639 * @vfe: VFE Device
643 mutex_lock(&vfe->power_lock); in vfe_put()
645 if (vfe->power_count == 0) { in vfe_put()
646 dev_err(vfe->camss->dev, "vfe power off on power_count == 0\n"); in vfe_put()
648 } else if (vfe->power_count == 1) { in vfe_put()
649 if (vfe->was_streaming) { in vfe_put()
650 vfe->was_streaming = 0; in vfe_put()
651 vfe->ops->vfe_halt(vfe); in vfe_put()
653 camss_disable_clocks(vfe->nclocks, vfe->clock); in vfe_put()
654 pm_runtime_put_sync(vfe->camss->dev); in vfe_put()
655 vfe->ops->pm_domain_off(vfe); in vfe_put()
658 vfe->power_count--; in vfe_put()
661 mutex_unlock(&vfe->power_lock); in vfe_put()
665 * vfe_flush_buffers - Return all vb2 buffers
666 * @vid: Video device structure
682 output = &line->output; in vfe_flush_buffers()
684 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_flush_buffers()
688 if (output->buf[0]) in vfe_flush_buffers()
689 vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state); in vfe_flush_buffers()
691 if (output->buf[1]) in vfe_flush_buffers()
692 vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state); in vfe_flush_buffers()
694 if (output->last_buffer) { in vfe_flush_buffers()
695 vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state); in vfe_flush_buffers()
696 output->last_buffer = NULL; in vfe_flush_buffers()
699 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_flush_buffers()
705 * vfe_set_power - Power on/off VFE module
729 * vfe_set_stream - Enable/disable streaming on VFE module
744 line->output.state = VFE_OUTPUT_RESERVED; in vfe_set_stream()
745 ret = vfe->ops->vfe_enable(line); in vfe_set_stream()
747 dev_err(vfe->camss->dev, in vfe_set_stream()
750 ret = vfe->ops->vfe_disable(line); in vfe_set_stream()
752 dev_err(vfe->camss->dev, in vfe_set_stream()
760 * __vfe_get_format - Get pointer to format structure
775 return v4l2_subdev_get_try_format(&line->subdev, sd_state, in __vfe_get_format()
778 return &line->fmt[pad]; in __vfe_get_format()
782 * __vfe_get_compose - Get pointer to compose selection structure
795 return v4l2_subdev_get_try_compose(&line->subdev, sd_state, in __vfe_get_compose()
798 return &line->compose; in __vfe_get_compose()
802 * __vfe_get_crop - Get pointer to crop selection structure
815 return v4l2_subdev_get_try_crop(&line->subdev, sd_state, in __vfe_get_crop()
818 return &line->crop; in __vfe_get_crop()
822 * vfe_try_format - Handle try format by pad subdev method
842 for (i = 0; i < line->nformats; i++) in vfe_try_format()
843 if (fmt->code == line->formats[i].code) in vfe_try_format()
847 if (i >= line->nformats) in vfe_try_format()
848 fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; in vfe_try_format()
850 fmt->width = clamp_t(u32, fmt->width, 1, 8191); in vfe_try_format()
851 fmt->height = clamp_t(u32, fmt->height, 1, 8191); in vfe_try_format()
853 fmt->field = V4L2_FIELD_NONE; in vfe_try_format()
854 fmt->colorspace = V4L2_COLORSPACE_SRGB; in vfe_try_format()
860 code = fmt->code; in vfe_try_format()
865 fmt->code = vfe_src_pad_code(line, fmt->code, 0, code); in vfe_try_format()
867 if (line->id == VFE_LINE_PIX) { in vfe_try_format()
872 fmt->width = rect->width; in vfe_try_format()
873 fmt->height = rect->height; in vfe_try_format()
879 fmt->colorspace = V4L2_COLORSPACE_SRGB; in vfe_try_format()
883 * vfe_try_compose - Handle try compose selection by pad subdev method
898 if (rect->width > fmt->width) in vfe_try_compose()
899 rect->width = fmt->width; in vfe_try_compose()
901 if (rect->height > fmt->height) in vfe_try_compose()
902 rect->height = fmt->height; in vfe_try_compose()
904 if (fmt->width > rect->width * SCALER_RATIO_MAX) in vfe_try_compose()
905 rect->width = (fmt->width + SCALER_RATIO_MAX - 1) / in vfe_try_compose()
908 rect->width &= ~0x1; in vfe_try_compose()
910 if (fmt->height > rect->height * SCALER_RATIO_MAX) in vfe_try_compose()
911 rect->height = (fmt->height + SCALER_RATIO_MAX - 1) / in vfe_try_compose()
914 if (rect->width < 16) in vfe_try_compose()
915 rect->width = 16; in vfe_try_compose()
917 if (rect->height < 4) in vfe_try_compose()
918 rect->height = 4; in vfe_try_compose()
922 * vfe_try_crop - Handle try crop selection by pad subdev method
937 if (rect->width > compose->width) in vfe_try_crop()
938 rect->width = compose->width; in vfe_try_crop()
940 if (rect->width + rect->left > compose->width) in vfe_try_crop()
941 rect->left = compose->width - rect->width; in vfe_try_crop()
943 if (rect->height > compose->height) in vfe_try_crop()
944 rect->height = compose->height; in vfe_try_crop()
946 if (rect->height + rect->top > compose->height) in vfe_try_crop()
947 rect->top = compose->height - rect->height; in vfe_try_crop()
950 rect->left += (rect->width & 0xf) >> 1; in vfe_try_crop()
951 rect->width &= ~0xf; in vfe_try_crop()
953 if (rect->width < 16) { in vfe_try_crop()
954 rect->left = 0; in vfe_try_crop()
955 rect->width = 16; in vfe_try_crop()
958 if (rect->height < 4) { in vfe_try_crop()
959 rect->top = 0; in vfe_try_crop()
960 rect->height = 4; in vfe_try_crop()
965 * vfe_enum_mbus_code - Handle pixel format enumeration
970 * return -EINVAL or zero on success
978 if (code->pad == MSM_VFE_PAD_SINK) { in vfe_enum_mbus_code()
979 if (code->index >= line->nformats) in vfe_enum_mbus_code()
980 return -EINVAL; in vfe_enum_mbus_code()
982 code->code = line->formats[code->index].code; in vfe_enum_mbus_code()
987 code->which); in vfe_enum_mbus_code()
989 code->code = vfe_src_pad_code(line, sink_fmt->code, in vfe_enum_mbus_code()
990 code->index, 0); in vfe_enum_mbus_code()
991 if (!code->code) in vfe_enum_mbus_code()
992 return -EINVAL; in vfe_enum_mbus_code()
999 * vfe_enum_frame_size - Handle frame size enumeration
1004 * Return -EINVAL or zero on success
1013 if (fse->index != 0) in vfe_enum_frame_size()
1014 return -EINVAL; in vfe_enum_frame_size()
1016 format.code = fse->code; in vfe_enum_frame_size()
1017 format.width = 1; in vfe_enum_frame_size()
1019 vfe_try_format(line, sd_state, fse->pad, &format, fse->which); in vfe_enum_frame_size()
1020 fse->min_width = format.width; in vfe_enum_frame_size()
1021 fse->min_height = format.height; in vfe_enum_frame_size()
1023 if (format.code != fse->code) in vfe_enum_frame_size()
1024 return -EINVAL; in vfe_enum_frame_size()
1026 format.code = fse->code; in vfe_enum_frame_size()
1027 format.width = -1; in vfe_enum_frame_size()
1028 format.height = -1; in vfe_enum_frame_size()
1029 vfe_try_format(line, sd_state, fse->pad, &format, fse->which); in vfe_enum_frame_size()
1030 fse->max_width = format.width; in vfe_enum_frame_size()
1031 fse->max_height = format.height; in vfe_enum_frame_size()
1037 * vfe_get_format - Handle get format by pads subdev method
1042 * Return -EINVAL or zero on success
1051 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which); in vfe_get_format()
1053 return -EINVAL; in vfe_get_format()
1055 fmt->format = *format; in vfe_get_format()
1065 * vfe_set_format - Handle set format by pads subdev method
1070 * Return -EINVAL or zero on success
1079 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which); in vfe_set_format()
1081 return -EINVAL; in vfe_set_format()
1083 vfe_try_format(line, sd_state, fmt->pad, &fmt->format, fmt->which); in vfe_set_format()
1084 *format = fmt->format; in vfe_set_format()
1086 if (fmt->pad == MSM_VFE_PAD_SINK) { in vfe_set_format()
1092 fmt->which); in vfe_set_format()
1094 *format = fmt->format; in vfe_set_format()
1096 fmt->which); in vfe_set_format()
1098 if (line->id != VFE_LINE_PIX) in vfe_set_format()
1102 sel.which = fmt->which; in vfe_set_format()
1105 sel.r.width = fmt->format.width; in vfe_set_format()
1106 sel.r.height = fmt->format.height; in vfe_set_format()
1116 * vfe_get_selection - Handle get selection by pads subdev method
1121 * Return -EINVAL or zero on success
1132 if (line->id != VFE_LINE_PIX) in vfe_get_selection()
1133 return -EINVAL; in vfe_get_selection()
1135 if (sel->pad == MSM_VFE_PAD_SINK) in vfe_get_selection()
1136 switch (sel->target) { in vfe_get_selection()
1138 fmt.pad = sel->pad; in vfe_get_selection()
1139 fmt.which = sel->which; in vfe_get_selection()
1144 sel->r.left = 0; in vfe_get_selection()
1145 sel->r.top = 0; in vfe_get_selection()
1146 sel->r.width = fmt.format.width; in vfe_get_selection()
1147 sel->r.height = fmt.format.height; in vfe_get_selection()
1150 rect = __vfe_get_compose(line, sd_state, sel->which); in vfe_get_selection()
1152 return -EINVAL; in vfe_get_selection()
1154 sel->r = *rect; in vfe_get_selection()
1157 return -EINVAL; in vfe_get_selection()
1159 else if (sel->pad == MSM_VFE_PAD_SRC) in vfe_get_selection()
1160 switch (sel->target) { in vfe_get_selection()
1162 rect = __vfe_get_compose(line, sd_state, sel->which); in vfe_get_selection()
1164 return -EINVAL; in vfe_get_selection()
1166 sel->r.left = rect->left; in vfe_get_selection()
1167 sel->r.top = rect->top; in vfe_get_selection()
1168 sel->r.width = rect->width; in vfe_get_selection()
1169 sel->r.height = rect->height; in vfe_get_selection()
1172 rect = __vfe_get_crop(line, sd_state, sel->which); in vfe_get_selection()
1174 return -EINVAL; in vfe_get_selection()
1176 sel->r = *rect; in vfe_get_selection()
1179 return -EINVAL; in vfe_get_selection()
1186 * vfe_set_selection - Handle set selection by pads subdev method
1191 * Return -EINVAL or zero on success
1201 if (line->id != VFE_LINE_PIX) in vfe_set_selection()
1202 return -EINVAL; in vfe_set_selection()
1204 if (sel->target == V4L2_SEL_TGT_COMPOSE && in vfe_set_selection()
1205 sel->pad == MSM_VFE_PAD_SINK) { in vfe_set_selection()
1208 rect = __vfe_get_compose(line, sd_state, sel->which); in vfe_set_selection()
1210 return -EINVAL; in vfe_set_selection()
1212 vfe_try_compose(line, sd_state, &sel->r, sel->which); in vfe_set_selection()
1213 *rect = sel->r; in vfe_set_selection()
1216 crop.which = sel->which; in vfe_set_selection()
1221 } else if (sel->target == V4L2_SEL_TGT_CROP && in vfe_set_selection()
1222 sel->pad == MSM_VFE_PAD_SRC) { in vfe_set_selection()
1225 rect = __vfe_get_crop(line, sd_state, sel->which); in vfe_set_selection()
1227 return -EINVAL; in vfe_set_selection()
1229 vfe_try_crop(line, sd_state, &sel->r, sel->which); in vfe_set_selection()
1230 *rect = sel->r; in vfe_set_selection()
1232 /* Reset source pad format width and height */ in vfe_set_selection()
1233 fmt.which = sel->which; in vfe_set_selection()
1239 fmt.format.width = rect->width; in vfe_set_selection()
1240 fmt.format.height = rect->height; in vfe_set_selection()
1243 ret = -EINVAL; in vfe_set_selection()
1250 * vfe_init_formats - Initialize formats on all pads
1266 .width = 1920, in vfe_init_formats()
1271 return vfe_set_format(sd, fh ? fh->state : NULL, &format); in vfe_init_formats()
1275 * msm_vfe_subdev_init - Initialize VFE device structure and resources
1276 * @vfe: VFE device
1284 struct device *dev = camss->dev; in msm_vfe_subdev_init()
1289 switch (camss->version) { in msm_vfe_subdev_init()
1291 vfe->ops = &vfe_ops_4_1; in msm_vfe_subdev_init()
1294 vfe->ops = &vfe_ops_4_7; in msm_vfe_subdev_init()
1297 vfe->ops = &vfe_ops_4_8; in msm_vfe_subdev_init()
1300 vfe->ops = &vfe_ops_170; in msm_vfe_subdev_init()
1303 vfe->ops = &vfe_ops_480; in msm_vfe_subdev_init()
1306 return -EINVAL; in msm_vfe_subdev_init()
1308 vfe->ops->subdev_init(dev, vfe); in msm_vfe_subdev_init()
1312 vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]); in msm_vfe_subdev_init()
1313 if (IS_ERR(vfe->base)) { in msm_vfe_subdev_init()
1315 return PTR_ERR(vfe->base); in msm_vfe_subdev_init()
1320 ret = platform_get_irq_byname(pdev, res->interrupt[0]); in msm_vfe_subdev_init()
1324 vfe->irq = ret; in msm_vfe_subdev_init()
1325 snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d", in msm_vfe_subdev_init()
1327 ret = devm_request_irq(dev, vfe->irq, vfe->ops->isr, in msm_vfe_subdev_init()
1328 IRQF_TRIGGER_RISING, vfe->irq_name, vfe); in msm_vfe_subdev_init()
1336 vfe->nclocks = 0; in msm_vfe_subdev_init()
1337 while (res->clock[vfe->nclocks]) in msm_vfe_subdev_init()
1338 vfe->nclocks++; in msm_vfe_subdev_init()
1340 vfe->clock = devm_kcalloc(dev, vfe->nclocks, sizeof(*vfe->clock), in msm_vfe_subdev_init()
1342 if (!vfe->clock) in msm_vfe_subdev_init()
1343 return -ENOMEM; in msm_vfe_subdev_init()
1345 for (i = 0; i < vfe->nclocks; i++) { in msm_vfe_subdev_init()
1346 struct camss_clock *clock = &vfe->clock[i]; in msm_vfe_subdev_init()
1348 clock->clk = devm_clk_get(dev, res->clock[i]); in msm_vfe_subdev_init()
1349 if (IS_ERR(clock->clk)) in msm_vfe_subdev_init()
1350 return PTR_ERR(clock->clk); in msm_vfe_subdev_init()
1352 clock->name = res->clock[i]; in msm_vfe_subdev_init()
1354 clock->nfreqs = 0; in msm_vfe_subdev_init()
1355 while (res->clock_rate[i][clock->nfreqs]) in msm_vfe_subdev_init()
1356 clock->nfreqs++; in msm_vfe_subdev_init()
1358 if (!clock->nfreqs) { in msm_vfe_subdev_init()
1359 clock->freq = NULL; in msm_vfe_subdev_init()
1363 clock->freq = devm_kcalloc(dev, in msm_vfe_subdev_init()
1364 clock->nfreqs, in msm_vfe_subdev_init()
1365 sizeof(*clock->freq), in msm_vfe_subdev_init()
1367 if (!clock->freq) in msm_vfe_subdev_init()
1368 return -ENOMEM; in msm_vfe_subdev_init()
1370 for (j = 0; j < clock->nfreqs; j++) in msm_vfe_subdev_init()
1371 clock->freq[j] = res->clock_rate[i][j]; in msm_vfe_subdev_init()
1374 mutex_init(&vfe->power_lock); in msm_vfe_subdev_init()
1375 vfe->power_count = 0; in msm_vfe_subdev_init()
1377 mutex_init(&vfe->stream_lock); in msm_vfe_subdev_init()
1378 vfe->stream_count = 0; in msm_vfe_subdev_init()
1380 spin_lock_init(&vfe->output_lock); in msm_vfe_subdev_init()
1382 vfe->camss = camss; in msm_vfe_subdev_init()
1383 vfe->id = id; in msm_vfe_subdev_init()
1384 vfe->reg_update = 0; in msm_vfe_subdev_init()
1386 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) { in msm_vfe_subdev_init()
1387 struct vfe_line *l = &vfe->line[i]; in msm_vfe_subdev_init()
1389 l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in msm_vfe_subdev_init()
1390 l->video_out.camss = camss; in msm_vfe_subdev_init()
1391 l->id = i; in msm_vfe_subdev_init()
1392 init_completion(&l->output.sof); in msm_vfe_subdev_init()
1393 init_completion(&l->output.reg_update); in msm_vfe_subdev_init()
1395 if (camss->version == CAMSS_8x16) { in msm_vfe_subdev_init()
1397 l->formats = formats_pix_8x16; in msm_vfe_subdev_init()
1398 l->nformats = ARRAY_SIZE(formats_pix_8x16); in msm_vfe_subdev_init()
1400 l->formats = formats_rdi_8x16; in msm_vfe_subdev_init()
1401 l->nformats = ARRAY_SIZE(formats_rdi_8x16); in msm_vfe_subdev_init()
1403 } else if (camss->version == CAMSS_8x96 || in msm_vfe_subdev_init()
1404 camss->version == CAMSS_660) { in msm_vfe_subdev_init()
1406 l->formats = formats_pix_8x96; in msm_vfe_subdev_init()
1407 l->nformats = ARRAY_SIZE(formats_pix_8x96); in msm_vfe_subdev_init()
1409 l->formats = formats_rdi_8x96; in msm_vfe_subdev_init()
1410 l->nformats = ARRAY_SIZE(formats_rdi_8x96); in msm_vfe_subdev_init()
1412 } else if (camss->version == CAMSS_845 || in msm_vfe_subdev_init()
1413 camss->version == CAMSS_8250) { in msm_vfe_subdev_init()
1414 l->formats = formats_rdi_845; in msm_vfe_subdev_init()
1415 l->nformats = ARRAY_SIZE(formats_rdi_845); in msm_vfe_subdev_init()
1417 return -EINVAL; in msm_vfe_subdev_init()
1421 init_completion(&vfe->reset_complete); in msm_vfe_subdev_init()
1422 init_completion(&vfe->halt_complete); in msm_vfe_subdev_init()
1428 * vfe_link_setup - Setup VFE connections
1442 return -EBUSY; in vfe_link_setup()
1480 * msm_vfe_register_entities - Register subdev node for VFE module
1481 * @vfe: VFE device
1482 * @v4l2_dev: V4L2 device
1485 * call msm_video_register() to register the video device node which
1494 struct device *dev = vfe->camss->dev; in msm_vfe_register_entities()
1501 for (i = 0; i < vfe->line_num; i++) { in msm_vfe_register_entities()
1504 sd = &vfe->line[i].subdev; in msm_vfe_register_entities()
1505 pads = vfe->line[i].pads; in msm_vfe_register_entities()
1506 video_out = &vfe->line[i].video_out; in msm_vfe_register_entities()
1509 sd->internal_ops = &vfe_v4l2_internal_ops; in msm_vfe_register_entities()
1510 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in msm_vfe_register_entities()
1512 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s", in msm_vfe_register_entities()
1513 MSM_VFE_NAME, vfe->id, "pix"); in msm_vfe_register_entities()
1515 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d", in msm_vfe_register_entities()
1516 MSM_VFE_NAME, vfe->id, "rdi", i); in msm_vfe_register_entities()
1518 v4l2_set_subdevdata(sd, &vfe->line[i]); in msm_vfe_register_entities()
1529 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; in msm_vfe_register_entities()
1530 sd->entity.ops = &vfe_media_ops; in msm_vfe_register_entities()
1531 ret = media_entity_pads_init(&sd->entity, MSM_VFE_PADS_NUM, in msm_vfe_register_entities()
1544 video_out->ops = &vfe->video_ops; in msm_vfe_register_entities()
1545 if (vfe->camss->version == CAMSS_845 || in msm_vfe_register_entities()
1546 vfe->camss->version == CAMSS_8250) in msm_vfe_register_entities()
1547 video_out->bpl_alignment = 16; in msm_vfe_register_entities()
1549 video_out->bpl_alignment = 8; in msm_vfe_register_entities()
1550 video_out->line_based = 0; in msm_vfe_register_entities()
1552 video_out->bpl_alignment = 16; in msm_vfe_register_entities()
1553 video_out->line_based = 1; in msm_vfe_register_entities()
1556 MSM_VFE_NAME, vfe->id, "video", i); in msm_vfe_register_entities()
1566 &sd->entity, MSM_VFE_PAD_SRC, in msm_vfe_register_entities()
1567 &video_out->vdev.entity, 0, in msm_vfe_register_entities()
1570 dev_err(dev, "Failed to link %s->%s entities: %d\n", in msm_vfe_register_entities()
1571 sd->entity.name, video_out->vdev.entity.name, in msm_vfe_register_entities()
1586 media_entity_cleanup(&sd->entity); in msm_vfe_register_entities()
1589 for (i--; i >= 0; i--) { in msm_vfe_register_entities()
1590 sd = &vfe->line[i].subdev; in msm_vfe_register_entities()
1591 video_out = &vfe->line[i].video_out; in msm_vfe_register_entities()
1595 media_entity_cleanup(&sd->entity); in msm_vfe_register_entities()
1602 * msm_vfe_unregister_entities - Unregister VFE module subdev node
1603 * @vfe: VFE device
1609 mutex_destroy(&vfe->power_lock); in msm_vfe_unregister_entities()
1610 mutex_destroy(&vfe->stream_lock); in msm_vfe_unregister_entities()
1612 for (i = 0; i < vfe->line_num; i++) { in msm_vfe_unregister_entities()
1613 struct v4l2_subdev *sd = &vfe->line[i].subdev; in msm_vfe_unregister_entities()
1614 struct camss_video *video_out = &vfe->line[i].video_out; in msm_vfe_unregister_entities()
1618 media_entity_cleanup(&sd->entity); in msm_vfe_unregister_entities()