1 // SPDX-License-Identifier: GPL-2.0
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>
11 #include <linux/completion.h>
12 #include <linux/interrupt.h>
13 #include <linux/iommu.h>
14 #include <linux/mutex.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/spinlock_types.h>
19 #include <linux/spinlock.h>
20 #include <media/media-entity.h>
21 #include <media/v4l2-device.h>
22 #include <media/v4l2-subdev.h>
24 #include "camss-vfe.h"
27 #define MSM_VFE_NAME "msm_vfe"
29 /* VFE reset timeout */
30 #define VFE_RESET_TIMEOUT_MS 50
32 #define SCALER_RATIO_MAX 16
39 static const struct vfe_format formats_rdi_8x16[] = {
40 { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
41 { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
42 { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
43 { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
44 { MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
45 { MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
46 { MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
47 { MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
48 { MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
49 { MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
50 { MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
51 { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
52 { MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
53 { MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
54 { MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
55 { MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
56 { MEDIA_BUS_FMT_Y10_1X10, 10 },
59 static const struct vfe_format formats_pix_8x16[] = {
60 { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
61 { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
62 { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
63 { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
66 static const struct vfe_format formats_rdi_8x96[] = {
67 { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
68 { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
69 { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
70 { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
71 { MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
72 { MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
73 { MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
74 { MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
75 { MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
76 { MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
77 { MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
78 { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
79 { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16 },
80 { MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
81 { MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
82 { MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
83 { MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
84 { MEDIA_BUS_FMT_SBGGR14_1X14, 14 },
85 { MEDIA_BUS_FMT_SGBRG14_1X14, 14 },
86 { MEDIA_BUS_FMT_SGRBG14_1X14, 14 },
87 { MEDIA_BUS_FMT_SRGGB14_1X14, 14 },
88 { MEDIA_BUS_FMT_Y10_1X10, 10 },
89 { MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16 },
92 static const struct vfe_format formats_pix_8x96[] = {
93 { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
94 { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
95 { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
96 { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
99 static const struct vfe_format formats_rdi_845[] = {
100 { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
101 { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
102 { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
103 { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
104 { MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
105 { MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
106 { MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
107 { MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
108 { MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
109 { MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
110 { MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
111 { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
112 { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16 },
113 { MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
114 { MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
115 { MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
116 { MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
117 { MEDIA_BUS_FMT_SBGGR14_1X14, 14 },
118 { MEDIA_BUS_FMT_SGBRG14_1X14, 14 },
119 { MEDIA_BUS_FMT_SGRBG14_1X14, 14 },
120 { MEDIA_BUS_FMT_SRGGB14_1X14, 14 },
121 { MEDIA_BUS_FMT_Y8_1X8, 8 },
122 { MEDIA_BUS_FMT_Y10_1X10, 10 },
123 { MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16 },
127 * vfe_get_bpp - map media bus format to bits per pixel
128 * @formats: supported media bus formats array
129 * @nformats: size of @formats array
130 * @code: media bus format code
132 * Return number of bits per pixel
134 static u8 vfe_get_bpp(const struct vfe_format *formats,
135 unsigned int nformats, u32 code)
139 for (i = 0; i < nformats; i++)
140 if (code == formats[i].code)
141 return formats[i].bpp;
143 WARN(1, "Unknown format\n");
145 return formats[0].bpp;
148 static u32 vfe_find_code(u32 *code, unsigned int n_code,
149 unsigned int index, u32 req_code)
153 if (!req_code && (index >= n_code))
156 for (i = 0; i < n_code; i++)
158 if (req_code == code[i])
168 static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
169 unsigned int index, u32 src_req_code)
171 struct vfe_device *vfe = to_vfe(line);
173 switch (vfe->camss->res->version) {
176 case MEDIA_BUS_FMT_YUYV8_1X16:
179 MEDIA_BUS_FMT_YUYV8_1X16,
180 MEDIA_BUS_FMT_YUYV8_1_5X8,
183 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
184 index, src_req_code);
186 case MEDIA_BUS_FMT_YVYU8_1X16:
189 MEDIA_BUS_FMT_YVYU8_1X16,
190 MEDIA_BUS_FMT_YVYU8_1_5X8,
193 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
194 index, src_req_code);
196 case MEDIA_BUS_FMT_UYVY8_1X16:
199 MEDIA_BUS_FMT_UYVY8_1X16,
200 MEDIA_BUS_FMT_UYVY8_1_5X8,
203 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
204 index, src_req_code);
206 case MEDIA_BUS_FMT_VYUY8_1X16:
209 MEDIA_BUS_FMT_VYUY8_1X16,
210 MEDIA_BUS_FMT_VYUY8_1_5X8,
213 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
214 index, src_req_code);
228 case MEDIA_BUS_FMT_YUYV8_1X16:
231 MEDIA_BUS_FMT_YUYV8_1X16,
232 MEDIA_BUS_FMT_YVYU8_1X16,
233 MEDIA_BUS_FMT_UYVY8_1X16,
234 MEDIA_BUS_FMT_VYUY8_1X16,
235 MEDIA_BUS_FMT_YUYV8_1_5X8,
238 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
239 index, src_req_code);
241 case MEDIA_BUS_FMT_YVYU8_1X16:
244 MEDIA_BUS_FMT_YVYU8_1X16,
245 MEDIA_BUS_FMT_YUYV8_1X16,
246 MEDIA_BUS_FMT_UYVY8_1X16,
247 MEDIA_BUS_FMT_VYUY8_1X16,
248 MEDIA_BUS_FMT_YVYU8_1_5X8,
251 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
252 index, src_req_code);
254 case MEDIA_BUS_FMT_UYVY8_1X16:
257 MEDIA_BUS_FMT_UYVY8_1X16,
258 MEDIA_BUS_FMT_YUYV8_1X16,
259 MEDIA_BUS_FMT_YVYU8_1X16,
260 MEDIA_BUS_FMT_VYUY8_1X16,
261 MEDIA_BUS_FMT_UYVY8_1_5X8,
264 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
265 index, src_req_code);
267 case MEDIA_BUS_FMT_VYUY8_1X16:
270 MEDIA_BUS_FMT_VYUY8_1X16,
271 MEDIA_BUS_FMT_YUYV8_1X16,
272 MEDIA_BUS_FMT_YVYU8_1X16,
273 MEDIA_BUS_FMT_UYVY8_1X16,
274 MEDIA_BUS_FMT_VYUY8_1_5X8,
277 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
278 index, src_req_code);
291 int vfe_reset(struct vfe_device *vfe)
295 reinit_completion(&vfe->reset_complete);
297 vfe->ops->global_reset(vfe);
299 time = wait_for_completion_timeout(&vfe->reset_complete,
300 msecs_to_jiffies(VFE_RESET_TIMEOUT_MS));
302 dev_err(vfe->camss->dev, "VFE reset timeout\n");
309 static void vfe_init_outputs(struct vfe_device *vfe)
313 for (i = 0; i < vfe->line_num; i++) {
314 struct vfe_output *output = &vfe->line[i].output;
316 output->state = VFE_OUTPUT_OFF;
317 output->buf[0] = NULL;
318 output->buf[1] = NULL;
319 INIT_LIST_HEAD(&output->pending_bufs);
323 static void vfe_reset_output_maps(struct vfe_device *vfe)
327 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
328 vfe->wm_output_map[i] = VFE_LINE_NONE;
331 int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id)
336 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) {
337 if (vfe->wm_output_map[i] == VFE_LINE_NONE) {
338 vfe->wm_output_map[i] = line_id;
347 int vfe_release_wm(struct vfe_device *vfe, u8 wm)
349 if (wm >= ARRAY_SIZE(vfe->wm_output_map))
352 vfe->wm_output_map[wm] = VFE_LINE_NONE;
357 struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output)
359 struct camss_buffer *buffer = NULL;
361 if (!list_empty(&output->pending_bufs)) {
362 buffer = list_first_entry(&output->pending_bufs,
365 list_del(&buffer->queue);
371 void vfe_buf_add_pending(struct vfe_output *output,
372 struct camss_buffer *buffer)
374 INIT_LIST_HEAD(&buffer->queue);
375 list_add_tail(&buffer->queue, &output->pending_bufs);
379 * vfe_buf_flush_pending - Flush all pending buffers.
380 * @output: VFE output
381 * @state: vb2 buffer state
383 static void vfe_buf_flush_pending(struct vfe_output *output,
384 enum vb2_buffer_state state)
386 struct camss_buffer *buf;
387 struct camss_buffer *t;
389 list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) {
390 vb2_buffer_done(&buf->vb.vb2_buf, state);
391 list_del(&buf->queue);
395 int vfe_put_output(struct vfe_line *line)
397 struct vfe_device *vfe = to_vfe(line);
398 struct vfe_output *output = &line->output;
402 spin_lock_irqsave(&vfe->output_lock, flags);
404 for (i = 0; i < output->wm_num; i++)
405 vfe_release_wm(vfe, output->wm_idx[i]);
407 output->state = VFE_OUTPUT_OFF;
409 spin_unlock_irqrestore(&vfe->output_lock, flags);
413 static int vfe_disable_output(struct vfe_line *line)
415 struct vfe_device *vfe = to_vfe(line);
416 struct vfe_output *output = &line->output;
420 spin_lock_irqsave(&vfe->output_lock, flags);
421 for (i = 0; i < output->wm_num; i++)
422 vfe->ops->vfe_wm_stop(vfe, output->wm_idx[i]);
423 output->gen2.active_num = 0;
424 spin_unlock_irqrestore(&vfe->output_lock, flags);
426 return vfe_reset(vfe);
430 * vfe_disable - Disable streaming on VFE line
433 * Return 0 on success or a negative error code otherwise
435 int vfe_disable(struct vfe_line *line)
437 struct vfe_device *vfe = to_vfe(line);
440 ret = vfe_disable_output(line);
444 vfe_put_output(line);
446 mutex_lock(&vfe->stream_lock);
450 mutex_unlock(&vfe->stream_lock);
457 * vfe_isr_comp_done() - Process composite image done interrupt
459 * @comp: Composite image id
461 void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp)
465 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
466 if (vfe->wm_output_map[i] == VFE_LINE_PIX) {
467 vfe->isr_ops.wm_done(vfe, i);
472 void vfe_isr_reset_ack(struct vfe_device *vfe)
474 complete(&vfe->reset_complete);
477 static int vfe_match_clock_names(struct vfe_device *vfe,
478 struct camss_clock *clock)
480 char vfe_name[7]; /* vfeXXX\0 */
481 char vfe_lite_name[12]; /* vfe_liteXXX\0 */
483 snprintf(vfe_name, sizeof(vfe_name), "vfe%d", vfe->id);
484 snprintf(vfe_lite_name, sizeof(vfe_lite_name), "vfe_lite%d", vfe->id);
486 return (!strcmp(clock->name, vfe_name) ||
487 !strcmp(clock->name, vfe_lite_name) ||
488 !strcmp(clock->name, "vfe_lite"));
492 * vfe_set_clock_rates - Calculate and set clock rates on VFE module
495 * Return 0 on success or a negative error code otherwise
497 static int vfe_set_clock_rates(struct vfe_device *vfe)
499 struct device *dev = vfe->camss->dev;
500 u64 pixel_clock[VFE_LINE_NUM_MAX];
504 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
505 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
511 for (i = 0; i < vfe->nclocks; i++) {
512 struct camss_clock *clock = &vfe->clock[i];
514 if (vfe_match_clock_names(vfe, clock)) {
518 for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) {
522 if (j == VFE_LINE_PIX) {
523 tmp = pixel_clock[j];
525 struct vfe_line *l = &vfe->line[j];
527 bpp = vfe_get_bpp(l->formats,
529 l->fmt[MSM_VFE_PAD_SINK].code);
530 tmp = pixel_clock[j] * bpp / 64;
537 camss_add_clock_margin(&min_rate);
539 for (j = 0; j < clock->nfreqs; j++)
540 if (min_rate < clock->freq[j])
543 if (j == clock->nfreqs) {
545 "Pixel clock is too high for VFE");
549 /* if sensor pixel clock is not available */
550 /* set highest possible VFE clock rate */
552 j = clock->nfreqs - 1;
554 rate = clk_round_rate(clock->clk, clock->freq[j]);
556 dev_err(dev, "clk round rate failed: %ld\n",
561 ret = clk_set_rate(clock->clk, rate);
563 dev_err(dev, "clk set rate failed: %d\n", ret);
573 * vfe_check_clock_rates - Check current clock rates on VFE module
576 * Return 0 if current clock rates are suitable for a new pipeline
577 * or a negative error code otherwise
579 static int vfe_check_clock_rates(struct vfe_device *vfe)
581 u64 pixel_clock[VFE_LINE_NUM_MAX];
585 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
586 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
592 for (i = 0; i < vfe->nclocks; i++) {
593 struct camss_clock *clock = &vfe->clock[i];
595 if (vfe_match_clock_names(vfe, clock)) {
599 for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) {
603 if (j == VFE_LINE_PIX) {
604 tmp = pixel_clock[j];
606 struct vfe_line *l = &vfe->line[j];
608 bpp = vfe_get_bpp(l->formats,
610 l->fmt[MSM_VFE_PAD_SINK].code);
611 tmp = pixel_clock[j] * bpp / 64;
618 camss_add_clock_margin(&min_rate);
620 rate = clk_get_rate(clock->clk);
630 * vfe_get - Power up and reset VFE module
633 * Return 0 on success or a negative error code otherwise
635 int vfe_get(struct vfe_device *vfe)
639 mutex_lock(&vfe->power_lock);
641 if (vfe->power_count == 0) {
642 ret = vfe->ops->pm_domain_on(vfe);
644 goto error_pm_domain;
646 ret = pm_runtime_resume_and_get(vfe->camss->dev);
648 goto error_domain_off;
650 ret = vfe_set_clock_rates(vfe);
652 goto error_pm_runtime_get;
654 ret = camss_enable_clocks(vfe->nclocks, vfe->clock,
657 goto error_pm_runtime_get;
659 ret = vfe_reset(vfe);
663 vfe_reset_output_maps(vfe);
665 vfe_init_outputs(vfe);
667 vfe->ops->hw_version(vfe);
669 ret = vfe_check_clock_rates(vfe);
671 goto error_pm_domain;
675 mutex_unlock(&vfe->power_lock);
680 camss_disable_clocks(vfe->nclocks, vfe->clock);
682 error_pm_runtime_get:
683 pm_runtime_put_sync(vfe->camss->dev);
685 vfe->ops->pm_domain_off(vfe);
688 mutex_unlock(&vfe->power_lock);
694 * vfe_put - Power down VFE module
697 void vfe_put(struct vfe_device *vfe)
699 mutex_lock(&vfe->power_lock);
701 if (vfe->power_count == 0) {
702 dev_err(vfe->camss->dev, "vfe power off on power_count == 0\n");
704 } else if (vfe->power_count == 1) {
705 if (vfe->was_streaming) {
706 vfe->was_streaming = 0;
707 vfe->ops->vfe_halt(vfe);
709 camss_disable_clocks(vfe->nclocks, vfe->clock);
710 pm_runtime_put_sync(vfe->camss->dev);
711 vfe->ops->pm_domain_off(vfe);
717 mutex_unlock(&vfe->power_lock);
721 * vfe_flush_buffers - Return all vb2 buffers
722 * @vid: Video device structure
723 * @state: vb2 buffer state of the returned buffers
725 * Return all buffers to vb2. This includes queued pending buffers (still
726 * unused) and any buffers given to the hardware but again still not used.
728 * Return 0 on success or a negative error code otherwise
730 int vfe_flush_buffers(struct camss_video *vid,
731 enum vb2_buffer_state state)
733 struct vfe_line *line = container_of(vid, struct vfe_line, video_out);
734 struct vfe_device *vfe = to_vfe(line);
735 struct vfe_output *output;
738 output = &line->output;
740 spin_lock_irqsave(&vfe->output_lock, flags);
742 vfe_buf_flush_pending(output, state);
745 vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state);
748 vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state);
750 if (output->last_buffer) {
751 vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state);
752 output->last_buffer = NULL;
755 spin_unlock_irqrestore(&vfe->output_lock, flags);
761 * vfe_set_power - Power on/off VFE module
762 * @sd: VFE V4L2 subdevice
763 * @on: Requested power state
765 * Return 0 on success or a negative error code otherwise
767 static int vfe_set_power(struct v4l2_subdev *sd, int on)
769 struct vfe_line *line = v4l2_get_subdevdata(sd);
770 struct vfe_device *vfe = to_vfe(line);
785 * vfe_set_stream - Enable/disable streaming on VFE module
786 * @sd: VFE V4L2 subdevice
787 * @enable: Requested streaming state
789 * Main configuration of VFE module is triggered here.
791 * Return 0 on success or a negative error code otherwise
793 static int vfe_set_stream(struct v4l2_subdev *sd, int enable)
795 struct vfe_line *line = v4l2_get_subdevdata(sd);
796 struct vfe_device *vfe = to_vfe(line);
800 line->output.state = VFE_OUTPUT_RESERVED;
801 ret = vfe->ops->vfe_enable(line);
803 dev_err(vfe->camss->dev,
804 "Failed to enable vfe outputs\n");
806 ret = vfe->ops->vfe_disable(line);
808 dev_err(vfe->camss->dev,
809 "Failed to disable vfe outputs\n");
816 * __vfe_get_format - Get pointer to format structure
818 * @cfg: V4L2 subdev pad configuration
819 * @pad: pad from which format is requested
820 * @which: TRY or ACTIVE format
822 * Return pointer to TRY or ACTIVE format structure
824 static struct v4l2_mbus_framefmt *
825 __vfe_get_format(struct vfe_line *line,
826 struct v4l2_subdev_state *sd_state,
828 enum v4l2_subdev_format_whence which)
830 if (which == V4L2_SUBDEV_FORMAT_TRY)
831 return v4l2_subdev_get_try_format(&line->subdev, sd_state,
834 return &line->fmt[pad];
838 * __vfe_get_compose - Get pointer to compose selection structure
840 * @cfg: V4L2 subdev pad configuration
841 * @which: TRY or ACTIVE format
843 * Return pointer to TRY or ACTIVE compose rectangle structure
845 static struct v4l2_rect *
846 __vfe_get_compose(struct vfe_line *line,
847 struct v4l2_subdev_state *sd_state,
848 enum v4l2_subdev_format_whence which)
850 if (which == V4L2_SUBDEV_FORMAT_TRY)
851 return v4l2_subdev_get_try_compose(&line->subdev, sd_state,
854 return &line->compose;
858 * __vfe_get_crop - Get pointer to crop selection structure
860 * @cfg: V4L2 subdev pad configuration
861 * @which: TRY or ACTIVE format
863 * Return pointer to TRY or ACTIVE crop rectangle structure
865 static struct v4l2_rect *
866 __vfe_get_crop(struct vfe_line *line,
867 struct v4l2_subdev_state *sd_state,
868 enum v4l2_subdev_format_whence which)
870 if (which == V4L2_SUBDEV_FORMAT_TRY)
871 return v4l2_subdev_get_try_crop(&line->subdev, sd_state,
878 * vfe_try_format - Handle try format by pad subdev method
880 * @cfg: V4L2 subdev pad configuration
881 * @pad: pad on which format is requested
882 * @fmt: pointer to v4l2 format structure
883 * @which: wanted subdev format
885 static void vfe_try_format(struct vfe_line *line,
886 struct v4l2_subdev_state *sd_state,
888 struct v4l2_mbus_framefmt *fmt,
889 enum v4l2_subdev_format_whence which)
895 case MSM_VFE_PAD_SINK:
896 /* Set format on sink pad */
898 for (i = 0; i < line->nformats; i++)
899 if (fmt->code == line->formats[i].code)
902 /* If not found, use UYVY as default */
903 if (i >= line->nformats)
904 fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
906 fmt->width = clamp_t(u32, fmt->width, 1, 8191);
907 fmt->height = clamp_t(u32, fmt->height, 1, 8191);
909 fmt->field = V4L2_FIELD_NONE;
910 fmt->colorspace = V4L2_COLORSPACE_SRGB;
914 case MSM_VFE_PAD_SRC:
915 /* Set and return a format same as sink pad */
918 *fmt = *__vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK,
921 fmt->code = vfe_src_pad_code(line, fmt->code, 0, code);
923 if (line->id == VFE_LINE_PIX) {
924 struct v4l2_rect *rect;
926 rect = __vfe_get_crop(line, sd_state, which);
928 fmt->width = rect->width;
929 fmt->height = rect->height;
935 fmt->colorspace = V4L2_COLORSPACE_SRGB;
939 * vfe_try_compose - Handle try compose selection by pad subdev method
941 * @cfg: V4L2 subdev pad configuration
942 * @rect: pointer to v4l2 rect structure
943 * @which: wanted subdev format
945 static void vfe_try_compose(struct vfe_line *line,
946 struct v4l2_subdev_state *sd_state,
947 struct v4l2_rect *rect,
948 enum v4l2_subdev_format_whence which)
950 struct v4l2_mbus_framefmt *fmt;
952 fmt = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK, which);
954 if (rect->width > fmt->width)
955 rect->width = fmt->width;
957 if (rect->height > fmt->height)
958 rect->height = fmt->height;
960 if (fmt->width > rect->width * SCALER_RATIO_MAX)
961 rect->width = (fmt->width + SCALER_RATIO_MAX - 1) /
966 if (fmt->height > rect->height * SCALER_RATIO_MAX)
967 rect->height = (fmt->height + SCALER_RATIO_MAX - 1) /
970 if (rect->width < 16)
973 if (rect->height < 4)
978 * vfe_try_crop - Handle try crop selection by pad subdev method
980 * @cfg: V4L2 subdev pad configuration
981 * @rect: pointer to v4l2 rect structure
982 * @which: wanted subdev format
984 static void vfe_try_crop(struct vfe_line *line,
985 struct v4l2_subdev_state *sd_state,
986 struct v4l2_rect *rect,
987 enum v4l2_subdev_format_whence which)
989 struct v4l2_rect *compose;
991 compose = __vfe_get_compose(line, sd_state, which);
993 if (rect->width > compose->width)
994 rect->width = compose->width;
996 if (rect->width + rect->left > compose->width)
997 rect->left = compose->width - rect->width;
999 if (rect->height > compose->height)
1000 rect->height = compose->height;
1002 if (rect->height + rect->top > compose->height)
1003 rect->top = compose->height - rect->height;
1005 /* wm in line based mode writes multiple of 16 horizontally */
1006 rect->left += (rect->width & 0xf) >> 1;
1007 rect->width &= ~0xf;
1009 if (rect->width < 16) {
1014 if (rect->height < 4) {
1021 * vfe_enum_mbus_code - Handle pixel format enumeration
1022 * @sd: VFE V4L2 subdevice
1023 * @cfg: V4L2 subdev pad configuration
1024 * @code: pointer to v4l2_subdev_mbus_code_enum structure
1026 * return -EINVAL or zero on success
1028 static int vfe_enum_mbus_code(struct v4l2_subdev *sd,
1029 struct v4l2_subdev_state *sd_state,
1030 struct v4l2_subdev_mbus_code_enum *code)
1032 struct vfe_line *line = v4l2_get_subdevdata(sd);
1034 if (code->pad == MSM_VFE_PAD_SINK) {
1035 if (code->index >= line->nformats)
1038 code->code = line->formats[code->index].code;
1040 struct v4l2_mbus_framefmt *sink_fmt;
1042 sink_fmt = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK,
1045 code->code = vfe_src_pad_code(line, sink_fmt->code,
1055 * vfe_enum_frame_size - Handle frame size enumeration
1056 * @sd: VFE V4L2 subdevice
1057 * @cfg: V4L2 subdev pad configuration
1058 * @fse: pointer to v4l2_subdev_frame_size_enum structure
1060 * Return -EINVAL or zero on success
1062 static int vfe_enum_frame_size(struct v4l2_subdev *sd,
1063 struct v4l2_subdev_state *sd_state,
1064 struct v4l2_subdev_frame_size_enum *fse)
1066 struct vfe_line *line = v4l2_get_subdevdata(sd);
1067 struct v4l2_mbus_framefmt format;
1069 if (fse->index != 0)
1072 format.code = fse->code;
1075 vfe_try_format(line, sd_state, fse->pad, &format, fse->which);
1076 fse->min_width = format.width;
1077 fse->min_height = format.height;
1079 if (format.code != fse->code)
1082 format.code = fse->code;
1085 vfe_try_format(line, sd_state, fse->pad, &format, fse->which);
1086 fse->max_width = format.width;
1087 fse->max_height = format.height;
1093 * vfe_get_format - Handle get format by pads subdev method
1094 * @sd: VFE V4L2 subdevice
1095 * @cfg: V4L2 subdev pad configuration
1096 * @fmt: pointer to v4l2 subdev format structure
1098 * Return -EINVAL or zero on success
1100 static int vfe_get_format(struct v4l2_subdev *sd,
1101 struct v4l2_subdev_state *sd_state,
1102 struct v4l2_subdev_format *fmt)
1104 struct vfe_line *line = v4l2_get_subdevdata(sd);
1105 struct v4l2_mbus_framefmt *format;
1107 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which);
1111 fmt->format = *format;
1116 static int vfe_set_selection(struct v4l2_subdev *sd,
1117 struct v4l2_subdev_state *sd_state,
1118 struct v4l2_subdev_selection *sel);
1121 * vfe_set_format - Handle set format by pads subdev method
1122 * @sd: VFE V4L2 subdevice
1123 * @cfg: V4L2 subdev pad configuration
1124 * @fmt: pointer to v4l2 subdev format structure
1126 * Return -EINVAL or zero on success
1128 static int vfe_set_format(struct v4l2_subdev *sd,
1129 struct v4l2_subdev_state *sd_state,
1130 struct v4l2_subdev_format *fmt)
1132 struct vfe_line *line = v4l2_get_subdevdata(sd);
1133 struct v4l2_mbus_framefmt *format;
1135 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which);
1139 vfe_try_format(line, sd_state, fmt->pad, &fmt->format, fmt->which);
1140 *format = fmt->format;
1142 if (fmt->pad == MSM_VFE_PAD_SINK) {
1143 struct v4l2_subdev_selection sel = { 0 };
1146 /* Propagate the format from sink to source */
1147 format = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SRC,
1150 *format = fmt->format;
1151 vfe_try_format(line, sd_state, MSM_VFE_PAD_SRC, format,
1154 if (line->id != VFE_LINE_PIX)
1157 /* Reset sink pad compose selection */
1158 sel.which = fmt->which;
1159 sel.pad = MSM_VFE_PAD_SINK;
1160 sel.target = V4L2_SEL_TGT_COMPOSE;
1161 sel.r.width = fmt->format.width;
1162 sel.r.height = fmt->format.height;
1163 ret = vfe_set_selection(sd, sd_state, &sel);
1172 * vfe_get_selection - Handle get selection by pads subdev method
1173 * @sd: VFE V4L2 subdevice
1174 * @cfg: V4L2 subdev pad configuration
1175 * @sel: pointer to v4l2 subdev selection structure
1177 * Return -EINVAL or zero on success
1179 static int vfe_get_selection(struct v4l2_subdev *sd,
1180 struct v4l2_subdev_state *sd_state,
1181 struct v4l2_subdev_selection *sel)
1183 struct vfe_line *line = v4l2_get_subdevdata(sd);
1184 struct v4l2_subdev_format fmt = { 0 };
1185 struct v4l2_rect *rect;
1188 if (line->id != VFE_LINE_PIX)
1191 if (sel->pad == MSM_VFE_PAD_SINK)
1192 switch (sel->target) {
1193 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1195 fmt.which = sel->which;
1196 ret = vfe_get_format(sd, sd_state, &fmt);
1202 sel->r.width = fmt.format.width;
1203 sel->r.height = fmt.format.height;
1205 case V4L2_SEL_TGT_COMPOSE:
1206 rect = __vfe_get_compose(line, sd_state, sel->which);
1215 else if (sel->pad == MSM_VFE_PAD_SRC)
1216 switch (sel->target) {
1217 case V4L2_SEL_TGT_CROP_BOUNDS:
1218 rect = __vfe_get_compose(line, sd_state, sel->which);
1222 sel->r.left = rect->left;
1223 sel->r.top = rect->top;
1224 sel->r.width = rect->width;
1225 sel->r.height = rect->height;
1227 case V4L2_SEL_TGT_CROP:
1228 rect = __vfe_get_crop(line, sd_state, sel->which);
1242 * vfe_set_selection - Handle set selection by pads subdev method
1243 * @sd: VFE V4L2 subdevice
1244 * @cfg: V4L2 subdev pad configuration
1245 * @sel: pointer to v4l2 subdev selection structure
1247 * Return -EINVAL or zero on success
1249 static int vfe_set_selection(struct v4l2_subdev *sd,
1250 struct v4l2_subdev_state *sd_state,
1251 struct v4l2_subdev_selection *sel)
1253 struct vfe_line *line = v4l2_get_subdevdata(sd);
1254 struct v4l2_rect *rect;
1257 if (line->id != VFE_LINE_PIX)
1260 if (sel->target == V4L2_SEL_TGT_COMPOSE &&
1261 sel->pad == MSM_VFE_PAD_SINK) {
1262 struct v4l2_subdev_selection crop = { 0 };
1264 rect = __vfe_get_compose(line, sd_state, sel->which);
1268 vfe_try_compose(line, sd_state, &sel->r, sel->which);
1271 /* Reset source crop selection */
1272 crop.which = sel->which;
1273 crop.pad = MSM_VFE_PAD_SRC;
1274 crop.target = V4L2_SEL_TGT_CROP;
1276 ret = vfe_set_selection(sd, sd_state, &crop);
1277 } else if (sel->target == V4L2_SEL_TGT_CROP &&
1278 sel->pad == MSM_VFE_PAD_SRC) {
1279 struct v4l2_subdev_format fmt = { 0 };
1281 rect = __vfe_get_crop(line, sd_state, sel->which);
1285 vfe_try_crop(line, sd_state, &sel->r, sel->which);
1288 /* Reset source pad format width and height */
1289 fmt.which = sel->which;
1290 fmt.pad = MSM_VFE_PAD_SRC;
1291 ret = vfe_get_format(sd, sd_state, &fmt);
1295 fmt.format.width = rect->width;
1296 fmt.format.height = rect->height;
1297 ret = vfe_set_format(sd, sd_state, &fmt);
1306 * vfe_init_formats - Initialize formats on all pads
1307 * @sd: VFE V4L2 subdevice
1308 * @fh: V4L2 subdev file handle
1310 * Initialize all pad formats with default values.
1312 * Return 0 on success or a negative error code otherwise
1314 static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1316 struct v4l2_subdev_format format = {
1317 .pad = MSM_VFE_PAD_SINK,
1318 .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
1319 V4L2_SUBDEV_FORMAT_ACTIVE,
1321 .code = MEDIA_BUS_FMT_UYVY8_1X16,
1327 return vfe_set_format(sd, fh ? fh->state : NULL, &format);
1331 * msm_vfe_subdev_init - Initialize VFE device structure and resources
1333 * @res: VFE module resources table
1335 * Return 0 on success or a negative error code otherwise
1337 int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
1338 const struct camss_subdev_resources *res, u8 id)
1340 struct device *dev = camss->dev;
1341 struct platform_device *pdev = to_platform_device(dev);
1345 vfe->ops = res->ops;
1350 vfe->line_num = res->line_num;
1351 vfe->ops->subdev_init(dev, vfe);
1355 vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
1356 if (IS_ERR(vfe->base)) {
1357 dev_err(dev, "could not map memory\n");
1358 return PTR_ERR(vfe->base);
1363 ret = platform_get_irq_byname(pdev, res->interrupt[0]);
1368 snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d",
1369 dev_name(dev), MSM_VFE_NAME, id);
1370 ret = devm_request_irq(dev, vfe->irq, vfe->ops->isr,
1371 IRQF_TRIGGER_RISING, vfe->irq_name, vfe);
1373 dev_err(dev, "request_irq failed: %d\n", ret);
1380 while (res->clock[vfe->nclocks])
1383 vfe->clock = devm_kcalloc(dev, vfe->nclocks, sizeof(*vfe->clock),
1388 for (i = 0; i < vfe->nclocks; i++) {
1389 struct camss_clock *clock = &vfe->clock[i];
1391 clock->clk = devm_clk_get(dev, res->clock[i]);
1392 if (IS_ERR(clock->clk))
1393 return PTR_ERR(clock->clk);
1395 clock->name = res->clock[i];
1398 while (res->clock_rate[i][clock->nfreqs])
1401 if (!clock->nfreqs) {
1406 clock->freq = devm_kcalloc(dev,
1408 sizeof(*clock->freq),
1413 for (j = 0; j < clock->nfreqs; j++)
1414 clock->freq[j] = res->clock_rate[i][j];
1417 mutex_init(&vfe->power_lock);
1418 vfe->power_count = 0;
1420 mutex_init(&vfe->stream_lock);
1421 vfe->stream_count = 0;
1423 spin_lock_init(&vfe->output_lock);
1427 vfe->reg_update = 0;
1429 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
1430 struct vfe_line *l = &vfe->line[i];
1432 l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1433 l->video_out.camss = camss;
1435 init_completion(&l->output.sof);
1436 init_completion(&l->output.reg_update);
1438 switch (camss->res->version) {
1440 if (i == VFE_LINE_PIX) {
1441 l->formats = formats_pix_8x16;
1442 l->nformats = ARRAY_SIZE(formats_pix_8x16);
1444 l->formats = formats_rdi_8x16;
1445 l->nformats = ARRAY_SIZE(formats_rdi_8x16);
1450 if (i == VFE_LINE_PIX) {
1451 l->formats = formats_pix_8x96;
1452 l->nformats = ARRAY_SIZE(formats_pix_8x96);
1454 l->formats = formats_rdi_8x96;
1455 l->nformats = ARRAY_SIZE(formats_rdi_8x96);
1460 l->formats = formats_rdi_845;
1461 l->nformats = ARRAY_SIZE(formats_rdi_845);
1466 init_completion(&vfe->reset_complete);
1467 init_completion(&vfe->halt_complete);
1473 * vfe_link_setup - Setup VFE connections
1474 * @entity: Pointer to media entity structure
1475 * @local: Pointer to local pad
1476 * @remote: Pointer to remote pad
1477 * @flags: Link flags
1479 * Return 0 on success
1481 static int vfe_link_setup(struct media_entity *entity,
1482 const struct media_pad *local,
1483 const struct media_pad *remote, u32 flags)
1485 if (flags & MEDIA_LNK_FL_ENABLED)
1486 if (media_pad_remote_pad_first(local))
1492 static const struct v4l2_subdev_core_ops vfe_core_ops = {
1493 .s_power = vfe_set_power,
1496 static const struct v4l2_subdev_video_ops vfe_video_ops = {
1497 .s_stream = vfe_set_stream,
1500 static const struct v4l2_subdev_pad_ops vfe_pad_ops = {
1501 .enum_mbus_code = vfe_enum_mbus_code,
1502 .enum_frame_size = vfe_enum_frame_size,
1503 .get_fmt = vfe_get_format,
1504 .set_fmt = vfe_set_format,
1505 .get_selection = vfe_get_selection,
1506 .set_selection = vfe_set_selection,
1509 static const struct v4l2_subdev_ops vfe_v4l2_ops = {
1510 .core = &vfe_core_ops,
1511 .video = &vfe_video_ops,
1512 .pad = &vfe_pad_ops,
1515 static const struct v4l2_subdev_internal_ops vfe_v4l2_internal_ops = {
1516 .open = vfe_init_formats,
1519 static const struct media_entity_operations vfe_media_ops = {
1520 .link_setup = vfe_link_setup,
1521 .link_validate = v4l2_subdev_link_validate,
1525 * msm_vfe_register_entities - Register subdev node for VFE module
1527 * @v4l2_dev: V4L2 device
1529 * Initialize and register a subdev node for the VFE module. Then
1530 * call msm_video_register() to register the video device node which
1531 * will be connected to this subdev node. Then actually create the
1532 * media link between them.
1534 * Return 0 on success or a negative error code otherwise
1536 int msm_vfe_register_entities(struct vfe_device *vfe,
1537 struct v4l2_device *v4l2_dev)
1539 struct device *dev = vfe->camss->dev;
1540 struct v4l2_subdev *sd;
1541 struct media_pad *pads;
1542 struct camss_video *video_out;
1546 for (i = 0; i < vfe->line_num; i++) {
1549 sd = &vfe->line[i].subdev;
1550 pads = vfe->line[i].pads;
1551 video_out = &vfe->line[i].video_out;
1553 v4l2_subdev_init(sd, &vfe_v4l2_ops);
1554 sd->internal_ops = &vfe_v4l2_internal_ops;
1555 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1556 if (i == VFE_LINE_PIX)
1557 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s",
1558 MSM_VFE_NAME, vfe->id, "pix");
1560 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d",
1561 MSM_VFE_NAME, vfe->id, "rdi", i);
1563 v4l2_set_subdevdata(sd, &vfe->line[i]);
1565 ret = vfe_init_formats(sd, NULL);
1567 dev_err(dev, "Failed to init format: %d\n", ret);
1571 pads[MSM_VFE_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1572 pads[MSM_VFE_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
1574 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
1575 sd->entity.ops = &vfe_media_ops;
1576 ret = media_entity_pads_init(&sd->entity, MSM_VFE_PADS_NUM,
1579 dev_err(dev, "Failed to init media entity: %d\n", ret);
1583 ret = v4l2_device_register_subdev(v4l2_dev, sd);
1585 dev_err(dev, "Failed to register subdev: %d\n", ret);
1586 goto error_reg_subdev;
1589 video_out->ops = &vfe->video_ops;
1590 if (vfe->camss->res->version == CAMSS_845 ||
1591 vfe->camss->res->version == CAMSS_8250)
1592 video_out->bpl_alignment = 16;
1594 video_out->bpl_alignment = 8;
1595 video_out->line_based = 0;
1596 if (i == VFE_LINE_PIX) {
1597 video_out->bpl_alignment = 16;
1598 video_out->line_based = 1;
1600 snprintf(name, ARRAY_SIZE(name), "%s%d_%s%d",
1601 MSM_VFE_NAME, vfe->id, "video", i);
1602 ret = msm_video_register(video_out, v4l2_dev, name,
1603 i == VFE_LINE_PIX ? 1 : 0);
1605 dev_err(dev, "Failed to register video node: %d\n",
1607 goto error_reg_video;
1610 ret = media_create_pad_link(
1611 &sd->entity, MSM_VFE_PAD_SRC,
1612 &video_out->vdev.entity, 0,
1613 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
1615 dev_err(dev, "Failed to link %s->%s entities: %d\n",
1616 sd->entity.name, video_out->vdev.entity.name,
1625 msm_video_unregister(video_out);
1628 v4l2_device_unregister_subdev(sd);
1631 media_entity_cleanup(&sd->entity);
1634 for (i--; i >= 0; i--) {
1635 sd = &vfe->line[i].subdev;
1636 video_out = &vfe->line[i].video_out;
1638 msm_video_unregister(video_out);
1639 v4l2_device_unregister_subdev(sd);
1640 media_entity_cleanup(&sd->entity);
1647 * msm_vfe_unregister_entities - Unregister VFE module subdev node
1650 void msm_vfe_unregister_entities(struct vfe_device *vfe)
1654 mutex_destroy(&vfe->power_lock);
1655 mutex_destroy(&vfe->stream_lock);
1657 for (i = 0; i < vfe->line_num; i++) {
1658 struct v4l2_subdev *sd = &vfe->line[i].subdev;
1659 struct camss_video *video_out = &vfe->line[i].video_out;
1661 msm_video_unregister(video_out);
1662 v4l2_device_unregister_subdev(sd);
1663 media_entity_cleanup(&sd->entity);