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>
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
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
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()
498 dev_err(dev, "clk round rate failed: %ld\n", 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()
505 dev_err(dev, "clk set rate failed: %d\n", ret); in vfe_set_clock_rates()
515 * vfe_check_clock_rates - Check current clock rates on VFE module
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()
542 for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) { in vfe_check_clock_rates()
549 struct vfe_line *l = &vfe->line[j]; in vfe_check_clock_rates()
551 bpp = vfe_get_bpp(l->formats, in vfe_check_clock_rates()
552 l->nformats, in vfe_check_clock_rates()
553 l->fmt[MSM_VFE_PAD_SINK].code); in vfe_check_clock_rates()
563 rate = clk_get_rate(clock->clk); in vfe_check_clock_rates()
565 return -EBUSY; in vfe_check_clock_rates()
573 * vfe_get - Power up and reset VFE module
582 mutex_lock(&vfe->power_lock); in vfe_get()
584 if (vfe->power_count == 0) { in vfe_get()
585 ret = vfe->ops->pm_domain_on(vfe); in vfe_get()
589 ret = pm_runtime_resume_and_get(vfe->camss->dev); in vfe_get()
597 ret = camss_enable_clocks(vfe->nclocks, vfe->clock, in vfe_get()
598 vfe->camss->dev); in vfe_get()
610 vfe->ops->hw_version(vfe); in vfe_get()
616 vfe->power_count++; in vfe_get()
618 mutex_unlock(&vfe->power_lock); in vfe_get()
623 camss_disable_clocks(vfe->nclocks, vfe->clock); in vfe_get()
626 pm_runtime_put_sync(vfe->camss->dev); in vfe_get()
628 vfe->ops->pm_domain_off(vfe); in vfe_get()
631 mutex_unlock(&vfe->power_lock); in vfe_get()
637 * vfe_put - Power down VFE module
642 mutex_lock(&vfe->power_lock); in vfe_put()
644 if (vfe->power_count == 0) { in vfe_put()
645 dev_err(vfe->camss->dev, "vfe power off on power_count == 0\n"); in vfe_put()
647 } else if (vfe->power_count == 1) { in vfe_put()
648 if (vfe->was_streaming) { in vfe_put()
649 vfe->was_streaming = 0; in vfe_put()
650 vfe->ops->vfe_halt(vfe); in vfe_put()
652 camss_disable_clocks(vfe->nclocks, vfe->clock); in vfe_put()
653 pm_runtime_put_sync(vfe->camss->dev); in vfe_put()
654 vfe->ops->pm_domain_off(vfe); in vfe_put()
657 vfe->power_count--; in vfe_put()
660 mutex_unlock(&vfe->power_lock); in vfe_put()
664 * vfe_flush_buffers - Return all vb2 buffers
681 output = &line->output; in vfe_flush_buffers()
683 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_flush_buffers()
687 if (output->buf[0]) in vfe_flush_buffers()
688 vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state); in vfe_flush_buffers()
690 if (output->buf[1]) in vfe_flush_buffers()
691 vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state); in vfe_flush_buffers()
693 if (output->last_buffer) { in vfe_flush_buffers()
694 vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state); in vfe_flush_buffers()
695 output->last_buffer = NULL; in vfe_flush_buffers()
698 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_flush_buffers()
704 * vfe_set_power - Power on/off VFE module
728 * vfe_set_stream - Enable/disable streaming on VFE module
743 ret = vfe->ops->vfe_enable(line); in vfe_set_stream()
745 dev_err(vfe->camss->dev, in vfe_set_stream()
748 ret = vfe->ops->vfe_disable(line); in vfe_set_stream()
750 dev_err(vfe->camss->dev, in vfe_set_stream()
758 * __vfe_get_format - Get pointer to format structure
773 return v4l2_subdev_get_try_format(&line->subdev, sd_state, in __vfe_get_format()
776 return &line->fmt[pad]; in __vfe_get_format()
780 * __vfe_get_compose - Get pointer to compose selection structure
793 return v4l2_subdev_get_try_compose(&line->subdev, sd_state, in __vfe_get_compose()
796 return &line->compose; in __vfe_get_compose()
800 * __vfe_get_crop - Get pointer to crop selection structure
813 return v4l2_subdev_get_try_crop(&line->subdev, sd_state, in __vfe_get_crop()
816 return &line->crop; in __vfe_get_crop()
820 * vfe_try_format - Handle try format by pad subdev method
840 for (i = 0; i < line->nformats; i++) in vfe_try_format()
841 if (fmt->code == line->formats[i].code) in vfe_try_format()
845 if (i >= line->nformats) in vfe_try_format()
846 fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; in vfe_try_format()
848 fmt->width = clamp_t(u32, fmt->width, 1, 8191); in vfe_try_format()
849 fmt->height = clamp_t(u32, fmt->height, 1, 8191); in vfe_try_format()
851 fmt->field = V4L2_FIELD_NONE; in vfe_try_format()
852 fmt->colorspace = V4L2_COLORSPACE_SRGB; in vfe_try_format()
858 code = fmt->code; in vfe_try_format()
863 fmt->code = vfe_src_pad_code(line, fmt->code, 0, code); in vfe_try_format()
865 if (line->id == VFE_LINE_PIX) { in vfe_try_format()
870 fmt->width = rect->width; in vfe_try_format()
871 fmt->height = rect->height; in vfe_try_format()
877 fmt->colorspace = V4L2_COLORSPACE_SRGB; in vfe_try_format()
881 * vfe_try_compose - Handle try compose selection by pad subdev method
896 if (rect->width > fmt->width) in vfe_try_compose()
897 rect->width = fmt->width; in vfe_try_compose()
899 if (rect->height > fmt->height) in vfe_try_compose()
900 rect->height = fmt->height; in vfe_try_compose()
902 if (fmt->width > rect->width * SCALER_RATIO_MAX) in vfe_try_compose()
903 rect->width = (fmt->width + SCALER_RATIO_MAX - 1) / in vfe_try_compose()
906 rect->width &= ~0x1; in vfe_try_compose()
908 if (fmt->height > rect->height * SCALER_RATIO_MAX) in vfe_try_compose()
909 rect->height = (fmt->height + SCALER_RATIO_MAX - 1) / in vfe_try_compose()
912 if (rect->width < 16) in vfe_try_compose()
913 rect->width = 16; in vfe_try_compose()
915 if (rect->height < 4) in vfe_try_compose()
916 rect->height = 4; in vfe_try_compose()
920 * vfe_try_crop - Handle try crop selection by pad subdev method
935 if (rect->width > compose->width) in vfe_try_crop()
936 rect->width = compose->width; in vfe_try_crop()
938 if (rect->width + rect->left > compose->width) in vfe_try_crop()
939 rect->left = compose->width - rect->width; in vfe_try_crop()
941 if (rect->height > compose->height) in vfe_try_crop()
942 rect->height = compose->height; in vfe_try_crop()
944 if (rect->height + rect->top > compose->height) in vfe_try_crop()
945 rect->top = compose->height - rect->height; in vfe_try_crop()
948 rect->left += (rect->width & 0xf) >> 1; in vfe_try_crop()
949 rect->width &= ~0xf; in vfe_try_crop()
951 if (rect->width < 16) { in vfe_try_crop()
952 rect->left = 0; in vfe_try_crop()
953 rect->width = 16; in vfe_try_crop()
956 if (rect->height < 4) { in vfe_try_crop()
957 rect->top = 0; in vfe_try_crop()
958 rect->height = 4; in vfe_try_crop()
963 * vfe_enum_mbus_code - Handle pixel format enumeration
968 * return -EINVAL or zero on success
976 if (code->pad == MSM_VFE_PAD_SINK) { in vfe_enum_mbus_code()
977 if (code->index >= line->nformats) in vfe_enum_mbus_code()
978 return -EINVAL; in vfe_enum_mbus_code()
980 code->code = line->formats[code->index].code; in vfe_enum_mbus_code()
985 code->which); in vfe_enum_mbus_code()
987 code->code = vfe_src_pad_code(line, sink_fmt->code, in vfe_enum_mbus_code()
988 code->index, 0); in vfe_enum_mbus_code()
989 if (!code->code) in vfe_enum_mbus_code()
990 return -EINVAL; in vfe_enum_mbus_code()
997 * vfe_enum_frame_size - Handle frame size enumeration
1002 * Return -EINVAL or zero on success
1011 if (fse->index != 0) in vfe_enum_frame_size()
1012 return -EINVAL; in vfe_enum_frame_size()
1014 format.code = fse->code; in vfe_enum_frame_size()
1017 vfe_try_format(line, sd_state, fse->pad, &format, fse->which); in vfe_enum_frame_size()
1018 fse->min_width = format.width; in vfe_enum_frame_size()
1019 fse->min_height = format.height; in vfe_enum_frame_size()
1021 if (format.code != fse->code) in vfe_enum_frame_size()
1022 return -EINVAL; in vfe_enum_frame_size()
1024 format.code = fse->code; in vfe_enum_frame_size()
1025 format.width = -1; in vfe_enum_frame_size()
1026 format.height = -1; in vfe_enum_frame_size()
1027 vfe_try_format(line, sd_state, fse->pad, &format, fse->which); in vfe_enum_frame_size()
1028 fse->max_width = format.width; in vfe_enum_frame_size()
1029 fse->max_height = format.height; in vfe_enum_frame_size()
1035 * vfe_get_format - Handle get format by pads subdev method
1040 * Return -EINVAL or zero on success
1049 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which); in vfe_get_format()
1051 return -EINVAL; in vfe_get_format()
1053 fmt->format = *format; in vfe_get_format()
1060 struct v4l2_subdev_selection *sel);
1063 * vfe_set_format - Handle set format by pads subdev method
1068 * Return -EINVAL or zero on success
1077 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which); in vfe_set_format()
1079 return -EINVAL; in vfe_set_format()
1081 vfe_try_format(line, sd_state, fmt->pad, &fmt->format, fmt->which); in vfe_set_format()
1082 *format = fmt->format; in vfe_set_format()
1084 if (fmt->pad == MSM_VFE_PAD_SINK) { in vfe_set_format()
1085 struct v4l2_subdev_selection sel = { 0 }; in vfe_set_format() local
1090 fmt->which); in vfe_set_format()
1092 *format = fmt->format; in vfe_set_format()
1094 fmt->which); in vfe_set_format()
1096 if (line->id != VFE_LINE_PIX) in vfe_set_format()
1100 sel.which = fmt->which; in vfe_set_format()
1101 sel.pad = MSM_VFE_PAD_SINK; in vfe_set_format()
1102 sel.target = V4L2_SEL_TGT_COMPOSE; in vfe_set_format()
1103 sel.r.width = fmt->format.width; in vfe_set_format()
1104 sel.r.height = fmt->format.height; in vfe_set_format()
1105 ret = vfe_set_selection(sd, sd_state, &sel); in vfe_set_format()
1114 * vfe_get_selection - Handle get selection by pads subdev method
1117 * @sel: pointer to v4l2 subdev selection structure
1119 * Return -EINVAL or zero on success
1123 struct v4l2_subdev_selection *sel) in vfe_get_selection() argument
1130 if (line->id != VFE_LINE_PIX) in vfe_get_selection()
1131 return -EINVAL; in vfe_get_selection()
1133 if (sel->pad == MSM_VFE_PAD_SINK) in vfe_get_selection()
1134 switch (sel->target) { in vfe_get_selection()
1136 fmt.pad = sel->pad; in vfe_get_selection()
1137 fmt.which = sel->which; in vfe_get_selection()
1142 sel->r.left = 0; in vfe_get_selection()
1143 sel->r.top = 0; in vfe_get_selection()
1144 sel->r.width = fmt.format.width; in vfe_get_selection()
1145 sel->r.height = fmt.format.height; in vfe_get_selection()
1148 rect = __vfe_get_compose(line, sd_state, sel->which); in vfe_get_selection()
1150 return -EINVAL; in vfe_get_selection()
1152 sel->r = *rect; in vfe_get_selection()
1155 return -EINVAL; in vfe_get_selection()
1157 else if (sel->pad == MSM_VFE_PAD_SRC) in vfe_get_selection()
1158 switch (sel->target) { in vfe_get_selection()
1160 rect = __vfe_get_compose(line, sd_state, sel->which); in vfe_get_selection()
1162 return -EINVAL; in vfe_get_selection()
1164 sel->r.left = rect->left; in vfe_get_selection()
1165 sel->r.top = rect->top; in vfe_get_selection()
1166 sel->r.width = rect->width; in vfe_get_selection()
1167 sel->r.height = rect->height; in vfe_get_selection()
1170 rect = __vfe_get_crop(line, sd_state, sel->which); in vfe_get_selection()
1172 return -EINVAL; in vfe_get_selection()
1174 sel->r = *rect; in vfe_get_selection()
1177 return -EINVAL; in vfe_get_selection()
1184 * vfe_set_selection - Handle set selection by pads subdev method
1187 * @sel: pointer to v4l2 subdev selection structure
1189 * Return -EINVAL or zero on success
1193 struct v4l2_subdev_selection *sel) in vfe_set_selection() argument
1199 if (line->id != VFE_LINE_PIX) in vfe_set_selection()
1200 return -EINVAL; in vfe_set_selection()
1202 if (sel->target == V4L2_SEL_TGT_COMPOSE && in vfe_set_selection()
1203 sel->pad == MSM_VFE_PAD_SINK) { in vfe_set_selection()
1206 rect = __vfe_get_compose(line, sd_state, sel->which); in vfe_set_selection()
1208 return -EINVAL; in vfe_set_selection()
1210 vfe_try_compose(line, sd_state, &sel->r, sel->which); in vfe_set_selection()
1211 *rect = sel->r; in vfe_set_selection()
1214 crop.which = sel->which; in vfe_set_selection()
1219 } else if (sel->target == V4L2_SEL_TGT_CROP && in vfe_set_selection()
1220 sel->pad == MSM_VFE_PAD_SRC) { in vfe_set_selection()
1223 rect = __vfe_get_crop(line, sd_state, sel->which); in vfe_set_selection()
1225 return -EINVAL; in vfe_set_selection()
1227 vfe_try_crop(line, sd_state, &sel->r, sel->which); in vfe_set_selection()
1228 *rect = sel->r; in vfe_set_selection()
1231 fmt.which = sel->which; in vfe_set_selection()
1237 fmt.format.width = rect->width; in vfe_set_selection()
1238 fmt.format.height = rect->height; in vfe_set_selection()
1241 ret = -EINVAL; in vfe_set_selection()
1248 * vfe_init_formats - Initialize formats on all pads
1269 return vfe_set_format(sd, fh ? fh->state : NULL, &format); in vfe_init_formats()
1273 * msm_vfe_subdev_init - Initialize VFE device structure and resources
1282 struct device *dev = camss->dev; in msm_vfe_subdev_init()
1287 switch (camss->version) { in msm_vfe_subdev_init()
1289 vfe->ops = &vfe_ops_4_1; in msm_vfe_subdev_init()
1292 vfe->ops = &vfe_ops_4_7; in msm_vfe_subdev_init()
1295 vfe->ops = &vfe_ops_4_8; in msm_vfe_subdev_init()
1298 vfe->ops = &vfe_ops_170; in msm_vfe_subdev_init()
1301 vfe->ops = &vfe_ops_480; in msm_vfe_subdev_init()
1304 return -EINVAL; in msm_vfe_subdev_init()
1306 vfe->ops->subdev_init(dev, vfe); in msm_vfe_subdev_init()
1310 vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]); in msm_vfe_subdev_init()
1311 if (IS_ERR(vfe->base)) { in msm_vfe_subdev_init()
1313 return PTR_ERR(vfe->base); in msm_vfe_subdev_init()
1318 ret = platform_get_irq_byname(pdev, res->interrupt[0]); in msm_vfe_subdev_init()
1322 vfe->irq = ret; in msm_vfe_subdev_init()
1323 snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d", in msm_vfe_subdev_init()
1325 ret = devm_request_irq(dev, vfe->irq, vfe->ops->isr, in msm_vfe_subdev_init()
1326 IRQF_TRIGGER_RISING, vfe->irq_name, vfe); in msm_vfe_subdev_init()
1334 vfe->nclocks = 0; in msm_vfe_subdev_init()
1335 while (res->clock[vfe->nclocks]) in msm_vfe_subdev_init()
1336 vfe->nclocks++; in msm_vfe_subdev_init()
1338 vfe->clock = devm_kcalloc(dev, vfe->nclocks, sizeof(*vfe->clock), in msm_vfe_subdev_init()
1340 if (!vfe->clock) in msm_vfe_subdev_init()
1341 return -ENOMEM; in msm_vfe_subdev_init()
1343 for (i = 0; i < vfe->nclocks; i++) { in msm_vfe_subdev_init()
1344 struct camss_clock *clock = &vfe->clock[i]; in msm_vfe_subdev_init()
1346 clock->clk = devm_clk_get(dev, res->clock[i]); in msm_vfe_subdev_init()
1347 if (IS_ERR(clock->clk)) in msm_vfe_subdev_init()
1348 return PTR_ERR(clock->clk); in msm_vfe_subdev_init()
1350 clock->name = res->clock[i]; in msm_vfe_subdev_init()
1352 clock->nfreqs = 0; in msm_vfe_subdev_init()
1353 while (res->clock_rate[i][clock->nfreqs]) in msm_vfe_subdev_init()
1354 clock->nfreqs++; in msm_vfe_subdev_init()
1356 if (!clock->nfreqs) { in msm_vfe_subdev_init()
1357 clock->freq = NULL; in msm_vfe_subdev_init()
1361 clock->freq = devm_kcalloc(dev, in msm_vfe_subdev_init()
1362 clock->nfreqs, in msm_vfe_subdev_init()
1363 sizeof(*clock->freq), in msm_vfe_subdev_init()
1365 if (!clock->freq) in msm_vfe_subdev_init()
1366 return -ENOMEM; in msm_vfe_subdev_init()
1368 for (j = 0; j < clock->nfreqs; j++) in msm_vfe_subdev_init()
1369 clock->freq[j] = res->clock_rate[i][j]; in msm_vfe_subdev_init()
1372 mutex_init(&vfe->power_lock); in msm_vfe_subdev_init()
1373 vfe->power_count = 0; in msm_vfe_subdev_init()
1375 mutex_init(&vfe->stream_lock); in msm_vfe_subdev_init()
1376 vfe->stream_count = 0; in msm_vfe_subdev_init()
1378 spin_lock_init(&vfe->output_lock); in msm_vfe_subdev_init()
1380 vfe->camss = camss; in msm_vfe_subdev_init()
1381 vfe->id = id; in msm_vfe_subdev_init()
1382 vfe->reg_update = 0; in msm_vfe_subdev_init()
1384 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) { in msm_vfe_subdev_init()
1385 struct vfe_line *l = &vfe->line[i]; in msm_vfe_subdev_init()
1387 l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in msm_vfe_subdev_init()
1388 l->video_out.camss = camss; in msm_vfe_subdev_init()
1389 l->id = i; in msm_vfe_subdev_init()
1390 init_completion(&l->output.sof); in msm_vfe_subdev_init()
1391 init_completion(&l->output.reg_update); in msm_vfe_subdev_init()
1393 if (camss->version == CAMSS_8x16) { in msm_vfe_subdev_init()
1395 l->formats = formats_pix_8x16; in msm_vfe_subdev_init()
1396 l->nformats = ARRAY_SIZE(formats_pix_8x16); in msm_vfe_subdev_init()
1398 l->formats = formats_rdi_8x16; in msm_vfe_subdev_init()
1399 l->nformats = ARRAY_SIZE(formats_rdi_8x16); in msm_vfe_subdev_init()
1401 } else if (camss->version == CAMSS_8x96 || in msm_vfe_subdev_init()
1402 camss->version == CAMSS_660) { in msm_vfe_subdev_init()
1404 l->formats = formats_pix_8x96; in msm_vfe_subdev_init()
1405 l->nformats = ARRAY_SIZE(formats_pix_8x96); in msm_vfe_subdev_init()
1407 l->formats = formats_rdi_8x96; in msm_vfe_subdev_init()
1408 l->nformats = ARRAY_SIZE(formats_rdi_8x96); in msm_vfe_subdev_init()
1410 } else if (camss->version == CAMSS_845 || in msm_vfe_subdev_init()
1411 camss->version == CAMSS_8250) { in msm_vfe_subdev_init()
1412 l->formats = formats_rdi_845; in msm_vfe_subdev_init()
1413 l->nformats = ARRAY_SIZE(formats_rdi_845); in msm_vfe_subdev_init()
1415 return -EINVAL; in msm_vfe_subdev_init()
1419 init_completion(&vfe->reset_complete); in msm_vfe_subdev_init()
1420 init_completion(&vfe->halt_complete); in msm_vfe_subdev_init()
1426 * vfe_link_setup - Setup VFE connections
1440 return -EBUSY; in vfe_link_setup()
1478 * msm_vfe_register_entities - Register subdev node for VFE module
1492 struct device *dev = vfe->camss->dev; in msm_vfe_register_entities()
1499 for (i = 0; i < vfe->line_num; i++) { in msm_vfe_register_entities()
1502 sd = &vfe->line[i].subdev; in msm_vfe_register_entities()
1503 pads = vfe->line[i].pads; in msm_vfe_register_entities()
1504 video_out = &vfe->line[i].video_out; in msm_vfe_register_entities()
1507 sd->internal_ops = &vfe_v4l2_internal_ops; in msm_vfe_register_entities()
1508 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in msm_vfe_register_entities()
1510 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s", in msm_vfe_register_entities()
1511 MSM_VFE_NAME, vfe->id, "pix"); in msm_vfe_register_entities()
1513 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d", in msm_vfe_register_entities()
1514 MSM_VFE_NAME, vfe->id, "rdi", i); in msm_vfe_register_entities()
1516 v4l2_set_subdevdata(sd, &vfe->line[i]); in msm_vfe_register_entities()
1527 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; in msm_vfe_register_entities()
1528 sd->entity.ops = &vfe_media_ops; in msm_vfe_register_entities()
1529 ret = media_entity_pads_init(&sd->entity, MSM_VFE_PADS_NUM, in msm_vfe_register_entities()
1542 video_out->ops = &vfe->video_ops; in msm_vfe_register_entities()
1543 video_out->bpl_alignment = 8; in msm_vfe_register_entities()
1544 video_out->line_based = 0; in msm_vfe_register_entities()
1546 video_out->bpl_alignment = 16; in msm_vfe_register_entities()
1547 video_out->line_based = 1; in msm_vfe_register_entities()
1550 MSM_VFE_NAME, vfe->id, "video", i); in msm_vfe_register_entities()
1560 &sd->entity, MSM_VFE_PAD_SRC, in msm_vfe_register_entities()
1561 &video_out->vdev.entity, 0, in msm_vfe_register_entities()
1564 dev_err(dev, "Failed to link %s->%s entities: %d\n", in msm_vfe_register_entities()
1565 sd->entity.name, video_out->vdev.entity.name, in msm_vfe_register_entities()
1580 media_entity_cleanup(&sd->entity); in msm_vfe_register_entities()
1583 for (i--; i >= 0; i--) { in msm_vfe_register_entities()
1584 sd = &vfe->line[i].subdev; in msm_vfe_register_entities()
1585 video_out = &vfe->line[i].video_out; in msm_vfe_register_entities()
1589 media_entity_cleanup(&sd->entity); in msm_vfe_register_entities()
1596 * msm_vfe_unregister_entities - Unregister VFE module subdev node
1603 mutex_destroy(&vfe->power_lock); in msm_vfe_unregister_entities()
1604 mutex_destroy(&vfe->stream_lock); in msm_vfe_unregister_entities()
1606 for (i = 0; i < vfe->line_num; i++) { in msm_vfe_unregister_entities()
1607 struct v4l2_subdev *sd = &vfe->line[i].subdev; in msm_vfe_unregister_entities()
1608 struct camss_video *video_out = &vfe->line[i].video_out; in msm_vfe_unregister_entities()
1612 media_entity_cleanup(&sd->entity); in msm_vfe_unregister_entities()