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.
21 #include <media/media-entity.h>
22 #include <media/v4l2-device.h>
23 #include <media/v4l2-subdev.h>
25 #include "camss-vfe.h"
128 * vfe_get_bpp - map media bus format to bits per pixel
174 switch (vfe->camss->res->version) { in vfe_src_pad_code()
296 reinit_completion(&vfe->reset_complete); in vfe_reset()
298 vfe->ops->global_reset(vfe); in vfe_reset()
300 time = wait_for_completion_timeout(&vfe->reset_complete, in vfe_reset()
303 dev_err(vfe->camss->dev, "VFE reset timeout\n"); in vfe_reset()
304 return -EIO; in vfe_reset()
314 for (i = 0; i < vfe->line_num; i++) { in vfe_init_outputs()
315 struct vfe_output *output = &vfe->line[i].output; in vfe_init_outputs()
317 output->state = VFE_OUTPUT_OFF; in vfe_init_outputs()
318 output->buf[0] = NULL; in vfe_init_outputs()
319 output->buf[1] = NULL; in vfe_init_outputs()
320 INIT_LIST_HEAD(&output->pending_bufs); in vfe_init_outputs()
328 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) in vfe_reset_output_maps()
329 vfe->wm_output_map[i] = VFE_LINE_NONE; in vfe_reset_output_maps()
334 int ret = -EBUSY; in vfe_reserve_wm()
337 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) { in vfe_reserve_wm()
338 if (vfe->wm_output_map[i] == VFE_LINE_NONE) { in vfe_reserve_wm()
339 vfe->wm_output_map[i] = line_id; in vfe_reserve_wm()
350 if (wm >= ARRAY_SIZE(vfe->wm_output_map)) in vfe_release_wm()
351 return -EINVAL; in vfe_release_wm()
353 vfe->wm_output_map[wm] = VFE_LINE_NONE; in vfe_release_wm()
362 if (!list_empty(&output->pending_bufs)) { in vfe_buf_get_pending()
363 buffer = list_first_entry(&output->pending_bufs, in vfe_buf_get_pending()
366 list_del(&buffer->queue); in vfe_buf_get_pending()
375 INIT_LIST_HEAD(&buffer->queue); in vfe_buf_add_pending()
376 list_add_tail(&buffer->queue, &output->pending_bufs); in vfe_buf_add_pending()
380 * vfe_buf_flush_pending - Flush all pending buffers.
390 list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) { in vfe_buf_flush_pending()
391 vb2_buffer_done(&buf->vb.vb2_buf, state); in vfe_buf_flush_pending()
392 list_del(&buf->queue); in vfe_buf_flush_pending()
399 struct vfe_output *output = &line->output; in vfe_put_output()
403 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_put_output()
405 for (i = 0; i < output->wm_num; i++) in vfe_put_output()
406 vfe_release_wm(vfe, output->wm_idx[i]); in vfe_put_output()
408 output->state = VFE_OUTPUT_OFF; in vfe_put_output()
410 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_put_output()
417 struct vfe_output *output = &line->output; in vfe_disable_output()
421 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_disable_output()
422 for (i = 0; i < output->wm_num; i++) in vfe_disable_output()
423 vfe->ops->vfe_wm_stop(vfe, output->wm_idx[i]); in vfe_disable_output()
424 output->gen2.active_num = 0; in vfe_disable_output()
425 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_disable_output()
431 * vfe_disable - Disable streaming on VFE line
447 mutex_lock(&vfe->stream_lock); in vfe_disable()
449 vfe->stream_count--; in vfe_disable()
451 mutex_unlock(&vfe->stream_lock); in vfe_disable()
458 * vfe_isr_comp_done() - Process composite image done interrupt
459 * @vfe: VFE Device
466 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) in vfe_isr_comp_done()
467 if (vfe->wm_output_map[i] == VFE_LINE_PIX) { in vfe_isr_comp_done()
468 vfe->isr_ops.wm_done(vfe, i); in vfe_isr_comp_done()
475 complete(&vfe->reset_complete); in vfe_isr_reset_ack()
479 * vfe_pm_domain_off - Disable power domains specific to this VFE.
480 * @vfe: VFE Device
484 if (!vfe->genpd) in vfe_pm_domain_off()
487 device_link_del(vfe->genpd_link); in vfe_pm_domain_off()
488 vfe->genpd_link = NULL; in vfe_pm_domain_off()
492 * vfe_pm_domain_on - Enable power domains specific to this VFE.
493 * @vfe: VFE Device
497 struct camss *camss = vfe->camss; in vfe_pm_domain_on()
499 if (!vfe->genpd) in vfe_pm_domain_on()
502 vfe->genpd_link = device_link_add(camss->dev, vfe->genpd, in vfe_pm_domain_on()
506 if (!vfe->genpd_link) in vfe_pm_domain_on()
507 return -EINVAL; in vfe_pm_domain_on()
518 snprintf(vfe_name, sizeof(vfe_name), "vfe%d", vfe->id); in vfe_match_clock_names()
519 snprintf(vfe_lite_name, sizeof(vfe_lite_name), "vfe_lite%d", vfe->id); in vfe_match_clock_names()
521 return (!strcmp(clock->name, vfe_name) || in vfe_match_clock_names()
522 !strcmp(clock->name, vfe_lite_name) || in vfe_match_clock_names()
523 !strcmp(clock->name, "vfe_lite")); in vfe_match_clock_names()
527 * vfe_set_clock_rates - Calculate and set clock rates on VFE module
528 * @vfe: VFE device
534 struct device *dev = vfe->camss->dev; in vfe_set_clock_rates()
539 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) { in vfe_set_clock_rates()
540 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity, in vfe_set_clock_rates()
546 for (i = 0; i < vfe->nclocks; i++) { in vfe_set_clock_rates()
547 struct camss_clock *clock = &vfe->clock[i]; in vfe_set_clock_rates()
553 for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) { in vfe_set_clock_rates()
560 struct vfe_line *l = &vfe->line[j]; in vfe_set_clock_rates()
562 bpp = vfe_get_bpp(l->formats, in vfe_set_clock_rates()
563 l->nformats, in vfe_set_clock_rates()
564 l->fmt[MSM_VFE_PAD_SINK].code); in vfe_set_clock_rates()
574 for (j = 0; j < clock->nfreqs; j++) in vfe_set_clock_rates()
575 if (min_rate < clock->freq[j]) in vfe_set_clock_rates()
578 if (j == clock->nfreqs) { in vfe_set_clock_rates()
581 return -EINVAL; in vfe_set_clock_rates()
587 j = clock->nfreqs - 1; in vfe_set_clock_rates()
589 rate = clk_round_rate(clock->clk, clock->freq[j]); in vfe_set_clock_rates()
593 return -EINVAL; in vfe_set_clock_rates()
596 ret = clk_set_rate(clock->clk, rate); in vfe_set_clock_rates()
608 * vfe_check_clock_rates - Check current clock rates on VFE module
609 * @vfe: VFE device
620 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) { in vfe_check_clock_rates()
621 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity, in vfe_check_clock_rates()
627 for (i = 0; i < vfe->nclocks; i++) { in vfe_check_clock_rates()
628 struct camss_clock *clock = &vfe->clock[i]; in vfe_check_clock_rates()
634 for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) { in vfe_check_clock_rates()
641 struct vfe_line *l = &vfe->line[j]; in vfe_check_clock_rates()
643 bpp = vfe_get_bpp(l->formats, in vfe_check_clock_rates()
644 l->nformats, in vfe_check_clock_rates()
645 l->fmt[MSM_VFE_PAD_SINK].code); in vfe_check_clock_rates()
655 rate = clk_get_rate(clock->clk); in vfe_check_clock_rates()
657 return -EBUSY; in vfe_check_clock_rates()
665 * vfe_get - Power up and reset VFE module
666 * @vfe: VFE Device
674 mutex_lock(&vfe->power_lock); in vfe_get()
676 if (vfe->power_count == 0) { in vfe_get()
677 ret = vfe->ops->pm_domain_on(vfe); in vfe_get()
681 ret = pm_runtime_resume_and_get(vfe->camss->dev); in vfe_get()
689 ret = camss_enable_clocks(vfe->nclocks, vfe->clock, in vfe_get()
690 vfe->camss->dev); in vfe_get()
702 vfe->ops->hw_version(vfe); in vfe_get()
708 vfe->power_count++; in vfe_get()
710 mutex_unlock(&vfe->power_lock); in vfe_get()
715 camss_disable_clocks(vfe->nclocks, vfe->clock); in vfe_get()
718 pm_runtime_put_sync(vfe->camss->dev); in vfe_get()
720 vfe->ops->pm_domain_off(vfe); in vfe_get()
723 mutex_unlock(&vfe->power_lock); in vfe_get()
729 * vfe_put - Power down VFE module
730 * @vfe: VFE Device
734 mutex_lock(&vfe->power_lock); in vfe_put()
736 if (vfe->power_count == 0) { in vfe_put()
737 dev_err(vfe->camss->dev, "vfe power off on power_count == 0\n"); in vfe_put()
739 } else if (vfe->power_count == 1) { in vfe_put()
740 if (vfe->was_streaming) { in vfe_put()
741 vfe->was_streaming = 0; in vfe_put()
742 vfe->ops->vfe_halt(vfe); in vfe_put()
744 camss_disable_clocks(vfe->nclocks, vfe->clock); in vfe_put()
745 pm_runtime_put_sync(vfe->camss->dev); in vfe_put()
746 vfe->ops->pm_domain_off(vfe); in vfe_put()
749 vfe->power_count--; in vfe_put()
752 mutex_unlock(&vfe->power_lock); in vfe_put()
756 * vfe_flush_buffers - Return all vb2 buffers
757 * @vid: Video device structure
773 output = &line->output; in vfe_flush_buffers()
775 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_flush_buffers()
779 if (output->buf[0]) in vfe_flush_buffers()
780 vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state); in vfe_flush_buffers()
782 if (output->buf[1]) in vfe_flush_buffers()
783 vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state); in vfe_flush_buffers()
785 if (output->last_buffer) { in vfe_flush_buffers()
786 vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state); in vfe_flush_buffers()
787 output->last_buffer = NULL; in vfe_flush_buffers()
790 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_flush_buffers()
796 * vfe_set_power - Power on/off VFE module
820 * vfe_set_stream - Enable/disable streaming on VFE module
835 line->output.state = VFE_OUTPUT_RESERVED; in vfe_set_stream()
836 ret = vfe->ops->vfe_enable(line); in vfe_set_stream()
838 dev_err(vfe->camss->dev, in vfe_set_stream()
841 ret = vfe->ops->vfe_disable(line); in vfe_set_stream()
843 dev_err(vfe->camss->dev, in vfe_set_stream()
851 * __vfe_get_format - Get pointer to format structure
868 return &line->fmt[pad]; in __vfe_get_format()
872 * __vfe_get_compose - Get pointer to compose selection structure
888 return &line->compose; in __vfe_get_compose()
892 * __vfe_get_crop - Get pointer to crop selection structure
907 return &line->crop; in __vfe_get_crop()
911 * vfe_try_format - Handle try format by pad subdev method
931 for (i = 0; i < line->nformats; i++) in vfe_try_format()
932 if (fmt->code == line->formats[i].code) in vfe_try_format()
936 if (i >= line->nformats) in vfe_try_format()
937 fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; in vfe_try_format()
939 fmt->width = clamp_t(u32, fmt->width, 1, 8191); in vfe_try_format()
940 fmt->height = clamp_t(u32, fmt->height, 1, 8191); in vfe_try_format()
942 fmt->field = V4L2_FIELD_NONE; in vfe_try_format()
943 fmt->colorspace = V4L2_COLORSPACE_SRGB; in vfe_try_format()
949 code = fmt->code; in vfe_try_format()
954 fmt->code = vfe_src_pad_code(line, fmt->code, 0, code); in vfe_try_format()
956 if (line->id == VFE_LINE_PIX) { in vfe_try_format()
961 fmt->width = rect->width; in vfe_try_format()
962 fmt->height = rect->height; in vfe_try_format()
968 fmt->colorspace = V4L2_COLORSPACE_SRGB; in vfe_try_format()
972 * vfe_try_compose - Handle try compose selection by pad subdev method
987 if (rect->width > fmt->width) in vfe_try_compose()
988 rect->width = fmt->width; in vfe_try_compose()
990 if (rect->height > fmt->height) in vfe_try_compose()
991 rect->height = fmt->height; in vfe_try_compose()
993 if (fmt->width > rect->width * SCALER_RATIO_MAX) in vfe_try_compose()
994 rect->width = (fmt->width + SCALER_RATIO_MAX - 1) / in vfe_try_compose()
997 rect->width &= ~0x1; in vfe_try_compose()
999 if (fmt->height > rect->height * SCALER_RATIO_MAX) in vfe_try_compose()
1000 rect->height = (fmt->height + SCALER_RATIO_MAX - 1) / in vfe_try_compose()
1003 if (rect->width < 16) in vfe_try_compose()
1004 rect->width = 16; in vfe_try_compose()
1006 if (rect->height < 4) in vfe_try_compose()
1007 rect->height = 4; in vfe_try_compose()
1011 * vfe_try_crop - Handle try crop selection by pad subdev method
1026 if (rect->width > compose->width) in vfe_try_crop()
1027 rect->width = compose->width; in vfe_try_crop()
1029 if (rect->width + rect->left > compose->width) in vfe_try_crop()
1030 rect->left = compose->width - rect->width; in vfe_try_crop()
1032 if (rect->height > compose->height) in vfe_try_crop()
1033 rect->height = compose->height; in vfe_try_crop()
1035 if (rect->height + rect->top > compose->height) in vfe_try_crop()
1036 rect->top = compose->height - rect->height; in vfe_try_crop()
1039 rect->left += (rect->width & 0xf) >> 1; in vfe_try_crop()
1040 rect->width &= ~0xf; in vfe_try_crop()
1042 if (rect->width < 16) { in vfe_try_crop()
1043 rect->left = 0; in vfe_try_crop()
1044 rect->width = 16; in vfe_try_crop()
1047 if (rect->height < 4) { in vfe_try_crop()
1048 rect->top = 0; in vfe_try_crop()
1049 rect->height = 4; in vfe_try_crop()
1054 * vfe_enum_mbus_code - Handle pixel format enumeration
1059 * return -EINVAL or zero on success
1067 if (code->pad == MSM_VFE_PAD_SINK) { in vfe_enum_mbus_code()
1068 if (code->index >= line->nformats) in vfe_enum_mbus_code()
1069 return -EINVAL; in vfe_enum_mbus_code()
1071 code->code = line->formats[code->index].code; in vfe_enum_mbus_code()
1076 code->which); in vfe_enum_mbus_code()
1078 code->code = vfe_src_pad_code(line, sink_fmt->code, in vfe_enum_mbus_code()
1079 code->index, 0); in vfe_enum_mbus_code()
1080 if (!code->code) in vfe_enum_mbus_code()
1081 return -EINVAL; in vfe_enum_mbus_code()
1088 * vfe_enum_frame_size - Handle frame size enumeration
1093 * Return -EINVAL or zero on success
1102 if (fse->index != 0) in vfe_enum_frame_size()
1103 return -EINVAL; in vfe_enum_frame_size()
1105 format.code = fse->code; in vfe_enum_frame_size()
1106 format.width = 1; in vfe_enum_frame_size()
1108 vfe_try_format(line, sd_state, fse->pad, &format, fse->which); in vfe_enum_frame_size()
1109 fse->min_width = format.width; in vfe_enum_frame_size()
1110 fse->min_height = format.height; in vfe_enum_frame_size()
1112 if (format.code != fse->code) in vfe_enum_frame_size()
1113 return -EINVAL; in vfe_enum_frame_size()
1115 format.code = fse->code; in vfe_enum_frame_size()
1116 format.width = -1; in vfe_enum_frame_size()
1117 format.height = -1; in vfe_enum_frame_size()
1118 vfe_try_format(line, sd_state, fse->pad, &format, fse->which); in vfe_enum_frame_size()
1119 fse->max_width = format.width; in vfe_enum_frame_size()
1120 fse->max_height = format.height; in vfe_enum_frame_size()
1126 * vfe_get_format - Handle get format by pads subdev method
1131 * Return -EINVAL or zero on success
1140 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which); in vfe_get_format()
1142 return -EINVAL; in vfe_get_format()
1144 fmt->format = *format; in vfe_get_format()
1154 * vfe_set_format - Handle set format by pads subdev method
1159 * Return -EINVAL or zero on success
1168 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which); in vfe_set_format()
1170 return -EINVAL; in vfe_set_format()
1172 vfe_try_format(line, sd_state, fmt->pad, &fmt->format, fmt->which); in vfe_set_format()
1173 *format = fmt->format; in vfe_set_format()
1175 if (fmt->pad == MSM_VFE_PAD_SINK) { in vfe_set_format()
1181 fmt->which); in vfe_set_format()
1183 *format = fmt->format; in vfe_set_format()
1185 fmt->which); in vfe_set_format()
1187 if (line->id != VFE_LINE_PIX) in vfe_set_format()
1191 sel.which = fmt->which; in vfe_set_format()
1194 sel.r.width = fmt->format.width; in vfe_set_format()
1195 sel.r.height = fmt->format.height; in vfe_set_format()
1205 * vfe_get_selection - Handle get selection by pads subdev method
1210 * Return -EINVAL or zero on success
1221 if (line->id != VFE_LINE_PIX) in vfe_get_selection()
1222 return -EINVAL; in vfe_get_selection()
1224 if (sel->pad == MSM_VFE_PAD_SINK) in vfe_get_selection()
1225 switch (sel->target) { in vfe_get_selection()
1227 fmt.pad = sel->pad; in vfe_get_selection()
1228 fmt.which = sel->which; in vfe_get_selection()
1233 sel->r.left = 0; in vfe_get_selection()
1234 sel->r.top = 0; in vfe_get_selection()
1235 sel->r.width = fmt.format.width; in vfe_get_selection()
1236 sel->r.height = fmt.format.height; in vfe_get_selection()
1239 rect = __vfe_get_compose(line, sd_state, sel->which); in vfe_get_selection()
1241 return -EINVAL; in vfe_get_selection()
1243 sel->r = *rect; in vfe_get_selection()
1246 return -EINVAL; in vfe_get_selection()
1248 else if (sel->pad == MSM_VFE_PAD_SRC) in vfe_get_selection()
1249 switch (sel->target) { in vfe_get_selection()
1251 rect = __vfe_get_compose(line, sd_state, sel->which); in vfe_get_selection()
1253 return -EINVAL; in vfe_get_selection()
1255 sel->r.left = rect->left; in vfe_get_selection()
1256 sel->r.top = rect->top; in vfe_get_selection()
1257 sel->r.width = rect->width; in vfe_get_selection()
1258 sel->r.height = rect->height; in vfe_get_selection()
1261 rect = __vfe_get_crop(line, sd_state, sel->which); in vfe_get_selection()
1263 return -EINVAL; in vfe_get_selection()
1265 sel->r = *rect; in vfe_get_selection()
1268 return -EINVAL; in vfe_get_selection()
1275 * vfe_set_selection - Handle set selection by pads subdev method
1280 * Return -EINVAL or zero on success
1290 if (line->id != VFE_LINE_PIX) in vfe_set_selection()
1291 return -EINVAL; in vfe_set_selection()
1293 if (sel->target == V4L2_SEL_TGT_COMPOSE && in vfe_set_selection()
1294 sel->pad == MSM_VFE_PAD_SINK) { in vfe_set_selection()
1297 rect = __vfe_get_compose(line, sd_state, sel->which); in vfe_set_selection()
1299 return -EINVAL; in vfe_set_selection()
1301 vfe_try_compose(line, sd_state, &sel->r, sel->which); in vfe_set_selection()
1302 *rect = sel->r; in vfe_set_selection()
1305 crop.which = sel->which; in vfe_set_selection()
1310 } else if (sel->target == V4L2_SEL_TGT_CROP && in vfe_set_selection()
1311 sel->pad == MSM_VFE_PAD_SRC) { in vfe_set_selection()
1314 rect = __vfe_get_crop(line, sd_state, sel->which); in vfe_set_selection()
1316 return -EINVAL; in vfe_set_selection()
1318 vfe_try_crop(line, sd_state, &sel->r, sel->which); in vfe_set_selection()
1319 *rect = sel->r; in vfe_set_selection()
1321 /* Reset source pad format width and height */ in vfe_set_selection()
1322 fmt.which = sel->which; in vfe_set_selection()
1328 fmt.format.width = rect->width; in vfe_set_selection()
1329 fmt.format.height = rect->height; in vfe_set_selection()
1332 ret = -EINVAL; in vfe_set_selection()
1339 * vfe_init_formats - Initialize formats on all pads
1355 .width = 1920, in vfe_init_formats()
1360 return vfe_set_format(sd, fh ? fh->state : NULL, &format); in vfe_init_formats()
1364 * msm_vfe_subdev_init - Initialize VFE device structure and resources
1365 * @vfe: VFE device
1373 struct device *dev = camss->dev; in msm_vfe_subdev_init()
1378 vfe->ops = res->ops; in msm_vfe_subdev_init()
1380 if (!res->line_num) in msm_vfe_subdev_init()
1381 return -EINVAL; in msm_vfe_subdev_init()
1385 if (res->pd_name) { in msm_vfe_subdev_init()
1386 vfe->genpd = dev_pm_domain_attach_by_name(camss->dev, in msm_vfe_subdev_init()
1387 res->pd_name); in msm_vfe_subdev_init()
1388 if (IS_ERR(vfe->genpd)) { in msm_vfe_subdev_init()
1389 ret = PTR_ERR(vfe->genpd); in msm_vfe_subdev_init()
1394 if (!vfe->genpd && res->has_pd) { in msm_vfe_subdev_init()
1398 * power-domain = <VFE_X>, in msm_vfe_subdev_init()
1406 vfe->genpd = dev_pm_domain_attach_by_id(camss->dev, id); in msm_vfe_subdev_init()
1407 if (IS_ERR(vfe->genpd)) in msm_vfe_subdev_init()
1408 return PTR_ERR(vfe->genpd); in msm_vfe_subdev_init()
1411 vfe->line_num = res->line_num; in msm_vfe_subdev_init()
1412 vfe->ops->subdev_init(dev, vfe); in msm_vfe_subdev_init()
1416 vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]); in msm_vfe_subdev_init()
1417 if (IS_ERR(vfe->base)) { in msm_vfe_subdev_init()
1419 return PTR_ERR(vfe->base); in msm_vfe_subdev_init()
1424 ret = platform_get_irq_byname(pdev, res->interrupt[0]); in msm_vfe_subdev_init()
1428 vfe->irq = ret; in msm_vfe_subdev_init()
1429 snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d", in msm_vfe_subdev_init()
1431 ret = devm_request_irq(dev, vfe->irq, vfe->ops->isr, in msm_vfe_subdev_init()
1432 IRQF_TRIGGER_RISING, vfe->irq_name, vfe); in msm_vfe_subdev_init()
1440 vfe->nclocks = 0; in msm_vfe_subdev_init()
1441 while (res->clock[vfe->nclocks]) in msm_vfe_subdev_init()
1442 vfe->nclocks++; in msm_vfe_subdev_init()
1444 vfe->clock = devm_kcalloc(dev, vfe->nclocks, sizeof(*vfe->clock), in msm_vfe_subdev_init()
1446 if (!vfe->clock) in msm_vfe_subdev_init()
1447 return -ENOMEM; in msm_vfe_subdev_init()
1449 for (i = 0; i < vfe->nclocks; i++) { in msm_vfe_subdev_init()
1450 struct camss_clock *clock = &vfe->clock[i]; in msm_vfe_subdev_init()
1452 clock->clk = devm_clk_get(dev, res->clock[i]); in msm_vfe_subdev_init()
1453 if (IS_ERR(clock->clk)) in msm_vfe_subdev_init()
1454 return PTR_ERR(clock->clk); in msm_vfe_subdev_init()
1456 clock->name = res->clock[i]; in msm_vfe_subdev_init()
1458 clock->nfreqs = 0; in msm_vfe_subdev_init()
1459 while (res->clock_rate[i][clock->nfreqs]) in msm_vfe_subdev_init()
1460 clock->nfreqs++; in msm_vfe_subdev_init()
1462 if (!clock->nfreqs) { in msm_vfe_subdev_init()
1463 clock->freq = NULL; in msm_vfe_subdev_init()
1467 clock->freq = devm_kcalloc(dev, in msm_vfe_subdev_init()
1468 clock->nfreqs, in msm_vfe_subdev_init()
1469 sizeof(*clock->freq), in msm_vfe_subdev_init()
1471 if (!clock->freq) in msm_vfe_subdev_init()
1472 return -ENOMEM; in msm_vfe_subdev_init()
1474 for (j = 0; j < clock->nfreqs; j++) in msm_vfe_subdev_init()
1475 clock->freq[j] = res->clock_rate[i][j]; in msm_vfe_subdev_init()
1478 mutex_init(&vfe->power_lock); in msm_vfe_subdev_init()
1479 vfe->power_count = 0; in msm_vfe_subdev_init()
1481 mutex_init(&vfe->stream_lock); in msm_vfe_subdev_init()
1482 vfe->stream_count = 0; in msm_vfe_subdev_init()
1484 spin_lock_init(&vfe->output_lock); in msm_vfe_subdev_init()
1486 vfe->camss = camss; in msm_vfe_subdev_init()
1487 vfe->id = id; in msm_vfe_subdev_init()
1488 vfe->reg_update = 0; in msm_vfe_subdev_init()
1490 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) { in msm_vfe_subdev_init()
1491 struct vfe_line *l = &vfe->line[i]; in msm_vfe_subdev_init()
1493 l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in msm_vfe_subdev_init()
1494 l->video_out.camss = camss; in msm_vfe_subdev_init()
1495 l->id = i; in msm_vfe_subdev_init()
1496 init_completion(&l->output.sof); in msm_vfe_subdev_init()
1497 init_completion(&l->output.reg_update); in msm_vfe_subdev_init()
1499 switch (camss->res->version) { in msm_vfe_subdev_init()
1502 l->formats = formats_pix_8x16; in msm_vfe_subdev_init()
1503 l->nformats = ARRAY_SIZE(formats_pix_8x16); in msm_vfe_subdev_init()
1505 l->formats = formats_rdi_8x16; in msm_vfe_subdev_init()
1506 l->nformats = ARRAY_SIZE(formats_rdi_8x16); in msm_vfe_subdev_init()
1512 l->formats = formats_pix_8x96; in msm_vfe_subdev_init()
1513 l->nformats = ARRAY_SIZE(formats_pix_8x96); in msm_vfe_subdev_init()
1515 l->formats = formats_rdi_8x96; in msm_vfe_subdev_init()
1516 l->nformats = ARRAY_SIZE(formats_rdi_8x96); in msm_vfe_subdev_init()
1521 l->formats = formats_rdi_845; in msm_vfe_subdev_init()
1522 l->nformats = ARRAY_SIZE(formats_rdi_845); in msm_vfe_subdev_init()
1527 init_completion(&vfe->reset_complete); in msm_vfe_subdev_init()
1528 init_completion(&vfe->halt_complete); in msm_vfe_subdev_init()
1534 * msm_vfe_genpd_cleanup - Cleanup VFE genpd linkages
1535 * @vfe: VFE device
1539 if (vfe->genpd_link) in msm_vfe_genpd_cleanup()
1540 device_link_del(vfe->genpd_link); in msm_vfe_genpd_cleanup()
1542 if (vfe->genpd) in msm_vfe_genpd_cleanup()
1543 dev_pm_domain_detach(vfe->genpd, true); in msm_vfe_genpd_cleanup()
1547 * vfe_link_setup - Setup VFE connections
1561 return -EBUSY; in vfe_link_setup()
1599 * msm_vfe_register_entities - Register subdev node for VFE module
1600 * @vfe: VFE device
1601 * @v4l2_dev: V4L2 device
1604 * call msm_video_register() to register the video device node which
1613 struct device *dev = vfe->camss->dev; in msm_vfe_register_entities()
1620 for (i = 0; i < vfe->line_num; i++) { in msm_vfe_register_entities()
1623 sd = &vfe->line[i].subdev; in msm_vfe_register_entities()
1624 pads = vfe->line[i].pads; in msm_vfe_register_entities()
1625 video_out = &vfe->line[i].video_out; in msm_vfe_register_entities()
1628 sd->internal_ops = &vfe_v4l2_internal_ops; in msm_vfe_register_entities()
1629 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in msm_vfe_register_entities()
1631 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s", in msm_vfe_register_entities()
1632 MSM_VFE_NAME, vfe->id, "pix"); in msm_vfe_register_entities()
1634 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d", in msm_vfe_register_entities()
1635 MSM_VFE_NAME, vfe->id, "rdi", i); in msm_vfe_register_entities()
1637 v4l2_set_subdevdata(sd, &vfe->line[i]); in msm_vfe_register_entities()
1648 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; in msm_vfe_register_entities()
1649 sd->entity.ops = &vfe_media_ops; in msm_vfe_register_entities()
1650 ret = media_entity_pads_init(&sd->entity, MSM_VFE_PADS_NUM, in msm_vfe_register_entities()
1663 video_out->ops = &vfe->video_ops; in msm_vfe_register_entities()
1664 if (vfe->camss->res->version == CAMSS_845 || in msm_vfe_register_entities()
1665 vfe->camss->res->version == CAMSS_8250) in msm_vfe_register_entities()
1666 video_out->bpl_alignment = 16; in msm_vfe_register_entities()
1668 video_out->bpl_alignment = 8; in msm_vfe_register_entities()
1669 video_out->line_based = 0; in msm_vfe_register_entities()
1671 video_out->bpl_alignment = 16; in msm_vfe_register_entities()
1672 video_out->line_based = 1; in msm_vfe_register_entities()
1675 MSM_VFE_NAME, vfe->id, "video", i); in msm_vfe_register_entities()
1685 &sd->entity, MSM_VFE_PAD_SRC, in msm_vfe_register_entities()
1686 &video_out->vdev.entity, 0, in msm_vfe_register_entities()
1689 dev_err(dev, "Failed to link %s->%s entities: %d\n", in msm_vfe_register_entities()
1690 sd->entity.name, video_out->vdev.entity.name, in msm_vfe_register_entities()
1705 media_entity_cleanup(&sd->entity); in msm_vfe_register_entities()
1708 for (i--; i >= 0; i--) { in msm_vfe_register_entities()
1709 sd = &vfe->line[i].subdev; in msm_vfe_register_entities()
1710 video_out = &vfe->line[i].video_out; in msm_vfe_register_entities()
1714 media_entity_cleanup(&sd->entity); in msm_vfe_register_entities()
1721 * msm_vfe_unregister_entities - Unregister VFE module subdev node
1722 * @vfe: VFE device
1728 mutex_destroy(&vfe->power_lock); in msm_vfe_unregister_entities()
1729 mutex_destroy(&vfe->stream_lock); in msm_vfe_unregister_entities()
1731 for (i = 0; i < vfe->line_num; i++) { in msm_vfe_unregister_entities()
1732 struct v4l2_subdev *sd = &vfe->line[i].subdev; in msm_vfe_unregister_entities()
1733 struct camss_video *video_out = &vfe->line[i].video_out; in msm_vfe_unregister_entities()
1737 media_entity_cleanup(&sd->entity); in msm_vfe_unregister_entities()
1743 return vfe->camss->res->vfe_res[vfe->id].is_lite; in vfe_is_lite()