1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * camss-vfe.c
4 *
5 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module
6 *
7 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
8 * Copyright (C) 2015-2018 Linaro Ltd.
9 */
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>
15 #include <linux/of.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_domain.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/spinlock_types.h>
20 #include <linux/spinlock.h>
21 #include <media/media-entity.h>
22 #include <media/v4l2-device.h>
23 #include <media/v4l2-subdev.h>
24
25 #include "camss-vfe.h"
26 #include "camss.h"
27
28 #define MSM_VFE_NAME "msm_vfe"
29
30 /* VFE reset timeout */
31 #define VFE_RESET_TIMEOUT_MS 50
32
33 #define SCALER_RATIO_MAX 16
34
35 struct vfe_format {
36 u32 code;
37 u8 bpp;
38 };
39
40 static const struct vfe_format formats_rdi_8x16[] = {
41 { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
42 { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
43 { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
44 { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
45 { MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
46 { MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
47 { MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
48 { MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
49 { MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
50 { MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
51 { MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
52 { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
53 { MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
54 { MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
55 { MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
56 { MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
57 { MEDIA_BUS_FMT_Y10_1X10, 10 },
58 };
59
60 static const struct vfe_format formats_pix_8x16[] = {
61 { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
62 { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
63 { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
64 { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
65 };
66
67 static const struct vfe_format formats_rdi_8x96[] = {
68 { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
69 { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
70 { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
71 { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
72 { MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
73 { MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
74 { MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
75 { MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
76 { MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
77 { MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
78 { MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
79 { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
80 { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16 },
81 { MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
82 { MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
83 { MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
84 { MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
85 { MEDIA_BUS_FMT_SBGGR14_1X14, 14 },
86 { MEDIA_BUS_FMT_SGBRG14_1X14, 14 },
87 { MEDIA_BUS_FMT_SGRBG14_1X14, 14 },
88 { MEDIA_BUS_FMT_SRGGB14_1X14, 14 },
89 { MEDIA_BUS_FMT_Y10_1X10, 10 },
90 { MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16 },
91 };
92
93 static const struct vfe_format formats_pix_8x96[] = {
94 { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
95 { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
96 { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
97 { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
98 };
99
100 static const struct vfe_format formats_rdi_845[] = {
101 { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
102 { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
103 { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
104 { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
105 { MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
106 { MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
107 { MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
108 { MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
109 { MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
110 { MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
111 { MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
112 { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
113 { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16 },
114 { MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
115 { MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
116 { MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
117 { MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
118 { MEDIA_BUS_FMT_SBGGR14_1X14, 14 },
119 { MEDIA_BUS_FMT_SGBRG14_1X14, 14 },
120 { MEDIA_BUS_FMT_SGRBG14_1X14, 14 },
121 { MEDIA_BUS_FMT_SRGGB14_1X14, 14 },
122 { MEDIA_BUS_FMT_Y8_1X8, 8 },
123 { MEDIA_BUS_FMT_Y10_1X10, 10 },
124 { MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16 },
125 };
126
127 /*
128 * vfe_get_bpp - map media bus format to bits per pixel
129 * @formats: supported media bus formats array
130 * @nformats: size of @formats array
131 * @code: media bus format code
132 *
133 * Return number of bits per pixel
134 */
vfe_get_bpp(const struct vfe_format * formats,unsigned int nformats,u32 code)135 static u8 vfe_get_bpp(const struct vfe_format *formats,
136 unsigned int nformats, u32 code)
137 {
138 unsigned int i;
139
140 for (i = 0; i < nformats; i++)
141 if (code == formats[i].code)
142 return formats[i].bpp;
143
144 WARN(1, "Unknown format\n");
145
146 return formats[0].bpp;
147 }
148
vfe_find_code(u32 * code,unsigned int n_code,unsigned int index,u32 req_code)149 static u32 vfe_find_code(u32 *code, unsigned int n_code,
150 unsigned int index, u32 req_code)
151 {
152 int i;
153
154 if (!req_code && (index >= n_code))
155 return 0;
156
157 for (i = 0; i < n_code; i++)
158 if (req_code) {
159 if (req_code == code[i])
160 return req_code;
161 } else {
162 if (i == index)
163 return code[i];
164 }
165
166 return code[0];
167 }
168
vfe_src_pad_code(struct vfe_line * line,u32 sink_code,unsigned int index,u32 src_req_code)169 static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
170 unsigned int index, u32 src_req_code)
171 {
172 struct vfe_device *vfe = to_vfe(line);
173
174 switch (vfe->camss->res->version) {
175 case CAMSS_8x16:
176 switch (sink_code) {
177 case MEDIA_BUS_FMT_YUYV8_1X16:
178 {
179 u32 src_code[] = {
180 MEDIA_BUS_FMT_YUYV8_1X16,
181 MEDIA_BUS_FMT_YUYV8_1_5X8,
182 };
183
184 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
185 index, src_req_code);
186 }
187 case MEDIA_BUS_FMT_YVYU8_1X16:
188 {
189 u32 src_code[] = {
190 MEDIA_BUS_FMT_YVYU8_1X16,
191 MEDIA_BUS_FMT_YVYU8_1_5X8,
192 };
193
194 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
195 index, src_req_code);
196 }
197 case MEDIA_BUS_FMT_UYVY8_1X16:
198 {
199 u32 src_code[] = {
200 MEDIA_BUS_FMT_UYVY8_1X16,
201 MEDIA_BUS_FMT_UYVY8_1_5X8,
202 };
203
204 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
205 index, src_req_code);
206 }
207 case MEDIA_BUS_FMT_VYUY8_1X16:
208 {
209 u32 src_code[] = {
210 MEDIA_BUS_FMT_VYUY8_1X16,
211 MEDIA_BUS_FMT_VYUY8_1_5X8,
212 };
213
214 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
215 index, src_req_code);
216 }
217 default:
218 if (index > 0)
219 return 0;
220
221 return sink_code;
222 }
223 break;
224 case CAMSS_8x96:
225 case CAMSS_660:
226 case CAMSS_845:
227 case CAMSS_8250:
228 switch (sink_code) {
229 case MEDIA_BUS_FMT_YUYV8_1X16:
230 {
231 u32 src_code[] = {
232 MEDIA_BUS_FMT_YUYV8_1X16,
233 MEDIA_BUS_FMT_YVYU8_1X16,
234 MEDIA_BUS_FMT_UYVY8_1X16,
235 MEDIA_BUS_FMT_VYUY8_1X16,
236 MEDIA_BUS_FMT_YUYV8_1_5X8,
237 };
238
239 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
240 index, src_req_code);
241 }
242 case MEDIA_BUS_FMT_YVYU8_1X16:
243 {
244 u32 src_code[] = {
245 MEDIA_BUS_FMT_YVYU8_1X16,
246 MEDIA_BUS_FMT_YUYV8_1X16,
247 MEDIA_BUS_FMT_UYVY8_1X16,
248 MEDIA_BUS_FMT_VYUY8_1X16,
249 MEDIA_BUS_FMT_YVYU8_1_5X8,
250 };
251
252 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
253 index, src_req_code);
254 }
255 case MEDIA_BUS_FMT_UYVY8_1X16:
256 {
257 u32 src_code[] = {
258 MEDIA_BUS_FMT_UYVY8_1X16,
259 MEDIA_BUS_FMT_YUYV8_1X16,
260 MEDIA_BUS_FMT_YVYU8_1X16,
261 MEDIA_BUS_FMT_VYUY8_1X16,
262 MEDIA_BUS_FMT_UYVY8_1_5X8,
263 };
264
265 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
266 index, src_req_code);
267 }
268 case MEDIA_BUS_FMT_VYUY8_1X16:
269 {
270 u32 src_code[] = {
271 MEDIA_BUS_FMT_VYUY8_1X16,
272 MEDIA_BUS_FMT_YUYV8_1X16,
273 MEDIA_BUS_FMT_YVYU8_1X16,
274 MEDIA_BUS_FMT_UYVY8_1X16,
275 MEDIA_BUS_FMT_VYUY8_1_5X8,
276 };
277
278 return vfe_find_code(src_code, ARRAY_SIZE(src_code),
279 index, src_req_code);
280 }
281 default:
282 if (index > 0)
283 return 0;
284
285 return sink_code;
286 }
287 break;
288 }
289 return 0;
290 }
291
vfe_reset(struct vfe_device * vfe)292 int vfe_reset(struct vfe_device *vfe)
293 {
294 unsigned long time;
295
296 reinit_completion(&vfe->reset_complete);
297
298 vfe->ops->global_reset(vfe);
299
300 time = wait_for_completion_timeout(&vfe->reset_complete,
301 msecs_to_jiffies(VFE_RESET_TIMEOUT_MS));
302 if (!time) {
303 dev_err(vfe->camss->dev, "VFE reset timeout\n");
304 return -EIO;
305 }
306
307 return 0;
308 }
309
vfe_init_outputs(struct vfe_device * vfe)310 static void vfe_init_outputs(struct vfe_device *vfe)
311 {
312 int i;
313
314 for (i = 0; i < vfe->line_num; i++) {
315 struct vfe_output *output = &vfe->line[i].output;
316
317 output->state = VFE_OUTPUT_OFF;
318 output->buf[0] = NULL;
319 output->buf[1] = NULL;
320 INIT_LIST_HEAD(&output->pending_bufs);
321 }
322 }
323
vfe_reset_output_maps(struct vfe_device * vfe)324 static void vfe_reset_output_maps(struct vfe_device *vfe)
325 {
326 int i;
327
328 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
329 vfe->wm_output_map[i] = VFE_LINE_NONE;
330 }
331
vfe_reserve_wm(struct vfe_device * vfe,enum vfe_line_id line_id)332 int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id)
333 {
334 int ret = -EBUSY;
335 int i;
336
337 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) {
338 if (vfe->wm_output_map[i] == VFE_LINE_NONE) {
339 vfe->wm_output_map[i] = line_id;
340 ret = i;
341 break;
342 }
343 }
344
345 return ret;
346 }
347
vfe_release_wm(struct vfe_device * vfe,u8 wm)348 int vfe_release_wm(struct vfe_device *vfe, u8 wm)
349 {
350 if (wm >= ARRAY_SIZE(vfe->wm_output_map))
351 return -EINVAL;
352
353 vfe->wm_output_map[wm] = VFE_LINE_NONE;
354
355 return 0;
356 }
357
vfe_buf_get_pending(struct vfe_output * output)358 struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output)
359 {
360 struct camss_buffer *buffer = NULL;
361
362 if (!list_empty(&output->pending_bufs)) {
363 buffer = list_first_entry(&output->pending_bufs,
364 struct camss_buffer,
365 queue);
366 list_del(&buffer->queue);
367 }
368
369 return buffer;
370 }
371
vfe_buf_add_pending(struct vfe_output * output,struct camss_buffer * buffer)372 void vfe_buf_add_pending(struct vfe_output *output,
373 struct camss_buffer *buffer)
374 {
375 INIT_LIST_HEAD(&buffer->queue);
376 list_add_tail(&buffer->queue, &output->pending_bufs);
377 }
378
379 /*
380 * vfe_buf_flush_pending - Flush all pending buffers.
381 * @output: VFE output
382 * @state: vb2 buffer state
383 */
vfe_buf_flush_pending(struct vfe_output * output,enum vb2_buffer_state state)384 static void vfe_buf_flush_pending(struct vfe_output *output,
385 enum vb2_buffer_state state)
386 {
387 struct camss_buffer *buf;
388 struct camss_buffer *t;
389
390 list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) {
391 vb2_buffer_done(&buf->vb.vb2_buf, state);
392 list_del(&buf->queue);
393 }
394 }
395
vfe_put_output(struct vfe_line * line)396 int vfe_put_output(struct vfe_line *line)
397 {
398 struct vfe_device *vfe = to_vfe(line);
399 struct vfe_output *output = &line->output;
400 unsigned long flags;
401 unsigned int i;
402
403 spin_lock_irqsave(&vfe->output_lock, flags);
404
405 for (i = 0; i < output->wm_num; i++)
406 vfe_release_wm(vfe, output->wm_idx[i]);
407
408 output->state = VFE_OUTPUT_OFF;
409
410 spin_unlock_irqrestore(&vfe->output_lock, flags);
411 return 0;
412 }
413
vfe_disable_output(struct vfe_line * line)414 static int vfe_disable_output(struct vfe_line *line)
415 {
416 struct vfe_device *vfe = to_vfe(line);
417 struct vfe_output *output = &line->output;
418 unsigned long flags;
419 unsigned int i;
420
421 spin_lock_irqsave(&vfe->output_lock, flags);
422 for (i = 0; i < output->wm_num; i++)
423 vfe->ops->vfe_wm_stop(vfe, output->wm_idx[i]);
424 output->gen2.active_num = 0;
425 spin_unlock_irqrestore(&vfe->output_lock, flags);
426
427 return vfe_reset(vfe);
428 }
429
430 /*
431 * vfe_disable - Disable streaming on VFE line
432 * @line: VFE line
433 *
434 * Return 0 on success or a negative error code otherwise
435 */
vfe_disable(struct vfe_line * line)436 int vfe_disable(struct vfe_line *line)
437 {
438 struct vfe_device *vfe = to_vfe(line);
439 int ret;
440
441 ret = vfe_disable_output(line);
442 if (ret)
443 goto error;
444
445 vfe_put_output(line);
446
447 mutex_lock(&vfe->stream_lock);
448
449 vfe->stream_count--;
450
451 mutex_unlock(&vfe->stream_lock);
452
453 error:
454 return ret;
455 }
456
457 /**
458 * vfe_isr_comp_done() - Process composite image done interrupt
459 * @vfe: VFE Device
460 * @comp: Composite image id
461 */
vfe_isr_comp_done(struct vfe_device * vfe,u8 comp)462 void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp)
463 {
464 unsigned int i;
465
466 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
467 if (vfe->wm_output_map[i] == VFE_LINE_PIX) {
468 vfe->isr_ops.wm_done(vfe, i);
469 break;
470 }
471 }
472
vfe_isr_reset_ack(struct vfe_device * vfe)473 void vfe_isr_reset_ack(struct vfe_device *vfe)
474 {
475 complete(&vfe->reset_complete);
476 }
477
478 /*
479 * vfe_pm_domain_off - Disable power domains specific to this VFE.
480 * @vfe: VFE Device
481 */
vfe_pm_domain_off(struct vfe_device * vfe)482 void vfe_pm_domain_off(struct vfe_device *vfe)
483 {
484 if (!vfe->genpd)
485 return;
486
487 device_link_del(vfe->genpd_link);
488 vfe->genpd_link = NULL;
489 }
490
491 /*
492 * vfe_pm_domain_on - Enable power domains specific to this VFE.
493 * @vfe: VFE Device
494 */
vfe_pm_domain_on(struct vfe_device * vfe)495 int vfe_pm_domain_on(struct vfe_device *vfe)
496 {
497 struct camss *camss = vfe->camss;
498
499 if (!vfe->genpd)
500 return 0;
501
502 vfe->genpd_link = device_link_add(camss->dev, vfe->genpd,
503 DL_FLAG_STATELESS |
504 DL_FLAG_PM_RUNTIME |
505 DL_FLAG_RPM_ACTIVE);
506 if (!vfe->genpd_link)
507 return -EINVAL;
508
509 return 0;
510 }
511
vfe_match_clock_names(struct vfe_device * vfe,struct camss_clock * clock)512 static int vfe_match_clock_names(struct vfe_device *vfe,
513 struct camss_clock *clock)
514 {
515 char vfe_name[7]; /* vfeXXX\0 */
516 char vfe_lite_name[12]; /* vfe_liteXXX\0 */
517
518 snprintf(vfe_name, sizeof(vfe_name), "vfe%d", vfe->id);
519 snprintf(vfe_lite_name, sizeof(vfe_lite_name), "vfe_lite%d", vfe->id);
520
521 return (!strcmp(clock->name, vfe_name) ||
522 !strcmp(clock->name, vfe_lite_name) ||
523 !strcmp(clock->name, "vfe_lite"));
524 }
525
526 /*
527 * vfe_set_clock_rates - Calculate and set clock rates on VFE module
528 * @vfe: VFE device
529 *
530 * Return 0 on success or a negative error code otherwise
531 */
vfe_set_clock_rates(struct vfe_device * vfe)532 static int vfe_set_clock_rates(struct vfe_device *vfe)
533 {
534 struct device *dev = vfe->camss->dev;
535 u64 pixel_clock[VFE_LINE_NUM_MAX];
536 int i, j;
537 int ret;
538
539 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
540 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
541 &pixel_clock[i]);
542 if (ret)
543 pixel_clock[i] = 0;
544 }
545
546 for (i = 0; i < vfe->nclocks; i++) {
547 struct camss_clock *clock = &vfe->clock[i];
548
549 if (vfe_match_clock_names(vfe, clock)) {
550 u64 min_rate = 0;
551 long rate;
552
553 for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) {
554 u32 tmp;
555 u8 bpp;
556
557 if (j == VFE_LINE_PIX) {
558 tmp = pixel_clock[j];
559 } else {
560 struct vfe_line *l = &vfe->line[j];
561
562 bpp = vfe_get_bpp(l->formats,
563 l->nformats,
564 l->fmt[MSM_VFE_PAD_SINK].code);
565 tmp = pixel_clock[j] * bpp / 64;
566 }
567
568 if (min_rate < tmp)
569 min_rate = tmp;
570 }
571
572 camss_add_clock_margin(&min_rate);
573
574 for (j = 0; j < clock->nfreqs; j++)
575 if (min_rate < clock->freq[j])
576 break;
577
578 if (j == clock->nfreqs) {
579 dev_err(dev,
580 "Pixel clock is too high for VFE");
581 return -EINVAL;
582 }
583
584 /* if sensor pixel clock is not available */
585 /* set highest possible VFE clock rate */
586 if (min_rate == 0)
587 j = clock->nfreqs - 1;
588
589 rate = clk_round_rate(clock->clk, clock->freq[j]);
590 if (rate < 0) {
591 dev_err(dev, "clk round rate failed: %ld\n",
592 rate);
593 return -EINVAL;
594 }
595
596 ret = clk_set_rate(clock->clk, rate);
597 if (ret < 0) {
598 dev_err(dev, "clk set rate failed: %d\n", ret);
599 return ret;
600 }
601 }
602 }
603
604 return 0;
605 }
606
607 /*
608 * vfe_check_clock_rates - Check current clock rates on VFE module
609 * @vfe: VFE device
610 *
611 * Return 0 if current clock rates are suitable for a new pipeline
612 * or a negative error code otherwise
613 */
vfe_check_clock_rates(struct vfe_device * vfe)614 static int vfe_check_clock_rates(struct vfe_device *vfe)
615 {
616 u64 pixel_clock[VFE_LINE_NUM_MAX];
617 int i, j;
618 int ret;
619
620 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
621 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
622 &pixel_clock[i]);
623 if (ret)
624 pixel_clock[i] = 0;
625 }
626
627 for (i = 0; i < vfe->nclocks; i++) {
628 struct camss_clock *clock = &vfe->clock[i];
629
630 if (vfe_match_clock_names(vfe, clock)) {
631 u64 min_rate = 0;
632 unsigned long rate;
633
634 for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) {
635 u32 tmp;
636 u8 bpp;
637
638 if (j == VFE_LINE_PIX) {
639 tmp = pixel_clock[j];
640 } else {
641 struct vfe_line *l = &vfe->line[j];
642
643 bpp = vfe_get_bpp(l->formats,
644 l->nformats,
645 l->fmt[MSM_VFE_PAD_SINK].code);
646 tmp = pixel_clock[j] * bpp / 64;
647 }
648
649 if (min_rate < tmp)
650 min_rate = tmp;
651 }
652
653 camss_add_clock_margin(&min_rate);
654
655 rate = clk_get_rate(clock->clk);
656 if (rate < min_rate)
657 return -EBUSY;
658 }
659 }
660
661 return 0;
662 }
663
664 /*
665 * vfe_get - Power up and reset VFE module
666 * @vfe: VFE Device
667 *
668 * Return 0 on success or a negative error code otherwise
669 */
vfe_get(struct vfe_device * vfe)670 int vfe_get(struct vfe_device *vfe)
671 {
672 int ret;
673
674 mutex_lock(&vfe->power_lock);
675
676 if (vfe->power_count == 0) {
677 ret = vfe->ops->pm_domain_on(vfe);
678 if (ret < 0)
679 goto error_pm_domain;
680
681 ret = pm_runtime_resume_and_get(vfe->camss->dev);
682 if (ret < 0)
683 goto error_domain_off;
684
685 ret = vfe_set_clock_rates(vfe);
686 if (ret < 0)
687 goto error_pm_runtime_get;
688
689 ret = camss_enable_clocks(vfe->nclocks, vfe->clock,
690 vfe->camss->dev);
691 if (ret < 0)
692 goto error_pm_runtime_get;
693
694 ret = vfe_reset(vfe);
695 if (ret < 0)
696 goto error_reset;
697
698 vfe_reset_output_maps(vfe);
699
700 vfe_init_outputs(vfe);
701
702 vfe->ops->hw_version(vfe);
703 } else {
704 ret = vfe_check_clock_rates(vfe);
705 if (ret < 0)
706 goto error_pm_domain;
707 }
708 vfe->power_count++;
709
710 mutex_unlock(&vfe->power_lock);
711
712 return 0;
713
714 error_reset:
715 camss_disable_clocks(vfe->nclocks, vfe->clock);
716
717 error_pm_runtime_get:
718 pm_runtime_put_sync(vfe->camss->dev);
719 error_domain_off:
720 vfe->ops->pm_domain_off(vfe);
721
722 error_pm_domain:
723 mutex_unlock(&vfe->power_lock);
724
725 return ret;
726 }
727
728 /*
729 * vfe_put - Power down VFE module
730 * @vfe: VFE Device
731 */
vfe_put(struct vfe_device * vfe)732 void vfe_put(struct vfe_device *vfe)
733 {
734 mutex_lock(&vfe->power_lock);
735
736 if (vfe->power_count == 0) {
737 dev_err(vfe->camss->dev, "vfe power off on power_count == 0\n");
738 goto exit;
739 } else if (vfe->power_count == 1) {
740 if (vfe->was_streaming) {
741 vfe->was_streaming = 0;
742 vfe->ops->vfe_halt(vfe);
743 }
744 camss_disable_clocks(vfe->nclocks, vfe->clock);
745 pm_runtime_put_sync(vfe->camss->dev);
746 vfe->ops->pm_domain_off(vfe);
747 }
748
749 vfe->power_count--;
750
751 exit:
752 mutex_unlock(&vfe->power_lock);
753 }
754
755 /*
756 * vfe_flush_buffers - Return all vb2 buffers
757 * @vid: Video device structure
758 * @state: vb2 buffer state of the returned buffers
759 *
760 * Return all buffers to vb2. This includes queued pending buffers (still
761 * unused) and any buffers given to the hardware but again still not used.
762 *
763 * Return 0 on success or a negative error code otherwise
764 */
vfe_flush_buffers(struct camss_video * vid,enum vb2_buffer_state state)765 int vfe_flush_buffers(struct camss_video *vid,
766 enum vb2_buffer_state state)
767 {
768 struct vfe_line *line = container_of(vid, struct vfe_line, video_out);
769 struct vfe_device *vfe = to_vfe(line);
770 struct vfe_output *output;
771 unsigned long flags;
772
773 output = &line->output;
774
775 spin_lock_irqsave(&vfe->output_lock, flags);
776
777 vfe_buf_flush_pending(output, state);
778
779 if (output->buf[0])
780 vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state);
781
782 if (output->buf[1])
783 vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state);
784
785 if (output->last_buffer) {
786 vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state);
787 output->last_buffer = NULL;
788 }
789
790 spin_unlock_irqrestore(&vfe->output_lock, flags);
791
792 return 0;
793 }
794
795 /*
796 * vfe_set_power - Power on/off VFE module
797 * @sd: VFE V4L2 subdevice
798 * @on: Requested power state
799 *
800 * Return 0 on success or a negative error code otherwise
801 */
vfe_set_power(struct v4l2_subdev * sd,int on)802 static int vfe_set_power(struct v4l2_subdev *sd, int on)
803 {
804 struct vfe_line *line = v4l2_get_subdevdata(sd);
805 struct vfe_device *vfe = to_vfe(line);
806 int ret;
807
808 if (on) {
809 ret = vfe_get(vfe);
810 if (ret < 0)
811 return ret;
812 } else {
813 vfe_put(vfe);
814 }
815
816 return 0;
817 }
818
819 /*
820 * vfe_set_stream - Enable/disable streaming on VFE module
821 * @sd: VFE V4L2 subdevice
822 * @enable: Requested streaming state
823 *
824 * Main configuration of VFE module is triggered here.
825 *
826 * Return 0 on success or a negative error code otherwise
827 */
vfe_set_stream(struct v4l2_subdev * sd,int enable)828 static int vfe_set_stream(struct v4l2_subdev *sd, int enable)
829 {
830 struct vfe_line *line = v4l2_get_subdevdata(sd);
831 struct vfe_device *vfe = to_vfe(line);
832 int ret;
833
834 if (enable) {
835 line->output.state = VFE_OUTPUT_RESERVED;
836 ret = vfe->ops->vfe_enable(line);
837 if (ret < 0)
838 dev_err(vfe->camss->dev,
839 "Failed to enable vfe outputs\n");
840 } else {
841 ret = vfe->ops->vfe_disable(line);
842 if (ret < 0)
843 dev_err(vfe->camss->dev,
844 "Failed to disable vfe outputs\n");
845 }
846
847 return ret;
848 }
849
850 /*
851 * __vfe_get_format - Get pointer to format structure
852 * @line: VFE line
853 * @sd_state: V4L2 subdev state
854 * @pad: pad from which format is requested
855 * @which: TRY or ACTIVE format
856 *
857 * Return pointer to TRY or ACTIVE format structure
858 */
859 static struct v4l2_mbus_framefmt *
__vfe_get_format(struct vfe_line * line,struct v4l2_subdev_state * sd_state,unsigned int pad,enum v4l2_subdev_format_whence which)860 __vfe_get_format(struct vfe_line *line,
861 struct v4l2_subdev_state *sd_state,
862 unsigned int pad,
863 enum v4l2_subdev_format_whence which)
864 {
865 if (which == V4L2_SUBDEV_FORMAT_TRY)
866 return v4l2_subdev_state_get_format(sd_state, pad);
867
868 return &line->fmt[pad];
869 }
870
871 /*
872 * __vfe_get_compose - Get pointer to compose selection structure
873 * @line: VFE line
874 * @sd_state: V4L2 subdev state
875 * @which: TRY or ACTIVE format
876 *
877 * Return pointer to TRY or ACTIVE compose rectangle structure
878 */
879 static struct v4l2_rect *
__vfe_get_compose(struct vfe_line * line,struct v4l2_subdev_state * sd_state,enum v4l2_subdev_format_whence which)880 __vfe_get_compose(struct vfe_line *line,
881 struct v4l2_subdev_state *sd_state,
882 enum v4l2_subdev_format_whence which)
883 {
884 if (which == V4L2_SUBDEV_FORMAT_TRY)
885 return v4l2_subdev_state_get_compose(sd_state,
886 MSM_VFE_PAD_SINK);
887
888 return &line->compose;
889 }
890
891 /*
892 * __vfe_get_crop - Get pointer to crop selection structure
893 * @line: VFE line
894 * @sd_state: V4L2 subdev state
895 * @which: TRY or ACTIVE format
896 *
897 * Return pointer to TRY or ACTIVE crop rectangle structure
898 */
899 static struct v4l2_rect *
__vfe_get_crop(struct vfe_line * line,struct v4l2_subdev_state * sd_state,enum v4l2_subdev_format_whence which)900 __vfe_get_crop(struct vfe_line *line,
901 struct v4l2_subdev_state *sd_state,
902 enum v4l2_subdev_format_whence which)
903 {
904 if (which == V4L2_SUBDEV_FORMAT_TRY)
905 return v4l2_subdev_state_get_crop(sd_state, MSM_VFE_PAD_SRC);
906
907 return &line->crop;
908 }
909
910 /*
911 * vfe_try_format - Handle try format by pad subdev method
912 * @line: VFE line
913 * @sd_state: V4L2 subdev state
914 * @pad: pad on which format is requested
915 * @fmt: pointer to v4l2 format structure
916 * @which: wanted subdev format
917 */
vfe_try_format(struct vfe_line * line,struct v4l2_subdev_state * sd_state,unsigned int pad,struct v4l2_mbus_framefmt * fmt,enum v4l2_subdev_format_whence which)918 static void vfe_try_format(struct vfe_line *line,
919 struct v4l2_subdev_state *sd_state,
920 unsigned int pad,
921 struct v4l2_mbus_framefmt *fmt,
922 enum v4l2_subdev_format_whence which)
923 {
924 unsigned int i;
925 u32 code;
926
927 switch (pad) {
928 case MSM_VFE_PAD_SINK:
929 /* Set format on sink pad */
930
931 for (i = 0; i < line->nformats; i++)
932 if (fmt->code == line->formats[i].code)
933 break;
934
935 /* If not found, use UYVY as default */
936 if (i >= line->nformats)
937 fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
938
939 fmt->width = clamp_t(u32, fmt->width, 1, 8191);
940 fmt->height = clamp_t(u32, fmt->height, 1, 8191);
941
942 fmt->field = V4L2_FIELD_NONE;
943 fmt->colorspace = V4L2_COLORSPACE_SRGB;
944
945 break;
946
947 case MSM_VFE_PAD_SRC:
948 /* Set and return a format same as sink pad */
949 code = fmt->code;
950
951 *fmt = *__vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK,
952 which);
953
954 fmt->code = vfe_src_pad_code(line, fmt->code, 0, code);
955
956 if (line->id == VFE_LINE_PIX) {
957 struct v4l2_rect *rect;
958
959 rect = __vfe_get_crop(line, sd_state, which);
960
961 fmt->width = rect->width;
962 fmt->height = rect->height;
963 }
964
965 break;
966 }
967
968 fmt->colorspace = V4L2_COLORSPACE_SRGB;
969 }
970
971 /*
972 * vfe_try_compose - Handle try compose selection by pad subdev method
973 * @line: VFE line
974 * @sd_state: V4L2 subdev state
975 * @rect: pointer to v4l2 rect structure
976 * @which: wanted subdev format
977 */
vfe_try_compose(struct vfe_line * line,struct v4l2_subdev_state * sd_state,struct v4l2_rect * rect,enum v4l2_subdev_format_whence which)978 static void vfe_try_compose(struct vfe_line *line,
979 struct v4l2_subdev_state *sd_state,
980 struct v4l2_rect *rect,
981 enum v4l2_subdev_format_whence which)
982 {
983 struct v4l2_mbus_framefmt *fmt;
984
985 fmt = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK, which);
986
987 if (rect->width > fmt->width)
988 rect->width = fmt->width;
989
990 if (rect->height > fmt->height)
991 rect->height = fmt->height;
992
993 if (fmt->width > rect->width * SCALER_RATIO_MAX)
994 rect->width = (fmt->width + SCALER_RATIO_MAX - 1) /
995 SCALER_RATIO_MAX;
996
997 rect->width &= ~0x1;
998
999 if (fmt->height > rect->height * SCALER_RATIO_MAX)
1000 rect->height = (fmt->height + SCALER_RATIO_MAX - 1) /
1001 SCALER_RATIO_MAX;
1002
1003 if (rect->width < 16)
1004 rect->width = 16;
1005
1006 if (rect->height < 4)
1007 rect->height = 4;
1008 }
1009
1010 /*
1011 * vfe_try_crop - Handle try crop selection by pad subdev method
1012 * @line: VFE line
1013 * @sd_state: V4L2 subdev state
1014 * @rect: pointer to v4l2 rect structure
1015 * @which: wanted subdev format
1016 */
vfe_try_crop(struct vfe_line * line,struct v4l2_subdev_state * sd_state,struct v4l2_rect * rect,enum v4l2_subdev_format_whence which)1017 static void vfe_try_crop(struct vfe_line *line,
1018 struct v4l2_subdev_state *sd_state,
1019 struct v4l2_rect *rect,
1020 enum v4l2_subdev_format_whence which)
1021 {
1022 struct v4l2_rect *compose;
1023
1024 compose = __vfe_get_compose(line, sd_state, which);
1025
1026 if (rect->width > compose->width)
1027 rect->width = compose->width;
1028
1029 if (rect->width + rect->left > compose->width)
1030 rect->left = compose->width - rect->width;
1031
1032 if (rect->height > compose->height)
1033 rect->height = compose->height;
1034
1035 if (rect->height + rect->top > compose->height)
1036 rect->top = compose->height - rect->height;
1037
1038 /* wm in line based mode writes multiple of 16 horizontally */
1039 rect->left += (rect->width & 0xf) >> 1;
1040 rect->width &= ~0xf;
1041
1042 if (rect->width < 16) {
1043 rect->left = 0;
1044 rect->width = 16;
1045 }
1046
1047 if (rect->height < 4) {
1048 rect->top = 0;
1049 rect->height = 4;
1050 }
1051 }
1052
1053 /*
1054 * vfe_enum_mbus_code - Handle pixel format enumeration
1055 * @sd: VFE V4L2 subdevice
1056 * @sd_state: V4L2 subdev state
1057 * @code: pointer to v4l2_subdev_mbus_code_enum structure
1058 *
1059 * return -EINVAL or zero on success
1060 */
vfe_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_mbus_code_enum * code)1061 static int vfe_enum_mbus_code(struct v4l2_subdev *sd,
1062 struct v4l2_subdev_state *sd_state,
1063 struct v4l2_subdev_mbus_code_enum *code)
1064 {
1065 struct vfe_line *line = v4l2_get_subdevdata(sd);
1066
1067 if (code->pad == MSM_VFE_PAD_SINK) {
1068 if (code->index >= line->nformats)
1069 return -EINVAL;
1070
1071 code->code = line->formats[code->index].code;
1072 } else {
1073 struct v4l2_mbus_framefmt *sink_fmt;
1074
1075 sink_fmt = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK,
1076 code->which);
1077
1078 code->code = vfe_src_pad_code(line, sink_fmt->code,
1079 code->index, 0);
1080 if (!code->code)
1081 return -EINVAL;
1082 }
1083
1084 return 0;
1085 }
1086
1087 /*
1088 * vfe_enum_frame_size - Handle frame size enumeration
1089 * @sd: VFE V4L2 subdevice
1090 * @sd_state: V4L2 subdev state
1091 * @fse: pointer to v4l2_subdev_frame_size_enum structure
1092 *
1093 * Return -EINVAL or zero on success
1094 */
vfe_enum_frame_size(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_frame_size_enum * fse)1095 static int vfe_enum_frame_size(struct v4l2_subdev *sd,
1096 struct v4l2_subdev_state *sd_state,
1097 struct v4l2_subdev_frame_size_enum *fse)
1098 {
1099 struct vfe_line *line = v4l2_get_subdevdata(sd);
1100 struct v4l2_mbus_framefmt format;
1101
1102 if (fse->index != 0)
1103 return -EINVAL;
1104
1105 format.code = fse->code;
1106 format.width = 1;
1107 format.height = 1;
1108 vfe_try_format(line, sd_state, fse->pad, &format, fse->which);
1109 fse->min_width = format.width;
1110 fse->min_height = format.height;
1111
1112 if (format.code != fse->code)
1113 return -EINVAL;
1114
1115 format.code = fse->code;
1116 format.width = -1;
1117 format.height = -1;
1118 vfe_try_format(line, sd_state, fse->pad, &format, fse->which);
1119 fse->max_width = format.width;
1120 fse->max_height = format.height;
1121
1122 return 0;
1123 }
1124
1125 /*
1126 * vfe_get_format - Handle get format by pads subdev method
1127 * @sd: VFE V4L2 subdevice
1128 * @sd_state: V4L2 subdev state
1129 * @fmt: pointer to v4l2 subdev format structure
1130 *
1131 * Return -EINVAL or zero on success
1132 */
vfe_get_format(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_format * fmt)1133 static int vfe_get_format(struct v4l2_subdev *sd,
1134 struct v4l2_subdev_state *sd_state,
1135 struct v4l2_subdev_format *fmt)
1136 {
1137 struct vfe_line *line = v4l2_get_subdevdata(sd);
1138 struct v4l2_mbus_framefmt *format;
1139
1140 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which);
1141 if (format == NULL)
1142 return -EINVAL;
1143
1144 fmt->format = *format;
1145
1146 return 0;
1147 }
1148
1149 static int vfe_set_selection(struct v4l2_subdev *sd,
1150 struct v4l2_subdev_state *sd_state,
1151 struct v4l2_subdev_selection *sel);
1152
1153 /*
1154 * vfe_set_format - Handle set format by pads subdev method
1155 * @sd: VFE V4L2 subdevice
1156 * @sd_state: V4L2 subdev state
1157 * @fmt: pointer to v4l2 subdev format structure
1158 *
1159 * Return -EINVAL or zero on success
1160 */
vfe_set_format(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_format * fmt)1161 static int vfe_set_format(struct v4l2_subdev *sd,
1162 struct v4l2_subdev_state *sd_state,
1163 struct v4l2_subdev_format *fmt)
1164 {
1165 struct vfe_line *line = v4l2_get_subdevdata(sd);
1166 struct v4l2_mbus_framefmt *format;
1167
1168 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which);
1169 if (format == NULL)
1170 return -EINVAL;
1171
1172 vfe_try_format(line, sd_state, fmt->pad, &fmt->format, fmt->which);
1173 *format = fmt->format;
1174
1175 if (fmt->pad == MSM_VFE_PAD_SINK) {
1176 struct v4l2_subdev_selection sel = { 0 };
1177 int ret;
1178
1179 /* Propagate the format from sink to source */
1180 format = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SRC,
1181 fmt->which);
1182
1183 *format = fmt->format;
1184 vfe_try_format(line, sd_state, MSM_VFE_PAD_SRC, format,
1185 fmt->which);
1186
1187 if (line->id != VFE_LINE_PIX)
1188 return 0;
1189
1190 /* Reset sink pad compose selection */
1191 sel.which = fmt->which;
1192 sel.pad = MSM_VFE_PAD_SINK;
1193 sel.target = V4L2_SEL_TGT_COMPOSE;
1194 sel.r.width = fmt->format.width;
1195 sel.r.height = fmt->format.height;
1196 ret = vfe_set_selection(sd, sd_state, &sel);
1197 if (ret < 0)
1198 return ret;
1199 }
1200
1201 return 0;
1202 }
1203
1204 /*
1205 * vfe_get_selection - Handle get selection by pads subdev method
1206 * @sd: VFE V4L2 subdevice
1207 * @sd_state: V4L2 subdev state
1208 * @sel: pointer to v4l2 subdev selection structure
1209 *
1210 * Return -EINVAL or zero on success
1211 */
vfe_get_selection(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_selection * sel)1212 static int vfe_get_selection(struct v4l2_subdev *sd,
1213 struct v4l2_subdev_state *sd_state,
1214 struct v4l2_subdev_selection *sel)
1215 {
1216 struct vfe_line *line = v4l2_get_subdevdata(sd);
1217 struct v4l2_subdev_format fmt = { 0 };
1218 struct v4l2_rect *rect;
1219 int ret;
1220
1221 if (line->id != VFE_LINE_PIX)
1222 return -EINVAL;
1223
1224 if (sel->pad == MSM_VFE_PAD_SINK)
1225 switch (sel->target) {
1226 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1227 fmt.pad = sel->pad;
1228 fmt.which = sel->which;
1229 ret = vfe_get_format(sd, sd_state, &fmt);
1230 if (ret < 0)
1231 return ret;
1232
1233 sel->r.left = 0;
1234 sel->r.top = 0;
1235 sel->r.width = fmt.format.width;
1236 sel->r.height = fmt.format.height;
1237 break;
1238 case V4L2_SEL_TGT_COMPOSE:
1239 rect = __vfe_get_compose(line, sd_state, sel->which);
1240 if (rect == NULL)
1241 return -EINVAL;
1242
1243 sel->r = *rect;
1244 break;
1245 default:
1246 return -EINVAL;
1247 }
1248 else if (sel->pad == MSM_VFE_PAD_SRC)
1249 switch (sel->target) {
1250 case V4L2_SEL_TGT_CROP_BOUNDS:
1251 rect = __vfe_get_compose(line, sd_state, sel->which);
1252 if (rect == NULL)
1253 return -EINVAL;
1254
1255 sel->r.left = rect->left;
1256 sel->r.top = rect->top;
1257 sel->r.width = rect->width;
1258 sel->r.height = rect->height;
1259 break;
1260 case V4L2_SEL_TGT_CROP:
1261 rect = __vfe_get_crop(line, sd_state, sel->which);
1262 if (rect == NULL)
1263 return -EINVAL;
1264
1265 sel->r = *rect;
1266 break;
1267 default:
1268 return -EINVAL;
1269 }
1270
1271 return 0;
1272 }
1273
1274 /*
1275 * vfe_set_selection - Handle set selection by pads subdev method
1276 * @sd: VFE V4L2 subdevice
1277 * @sd_state: V4L2 subdev state
1278 * @sel: pointer to v4l2 subdev selection structure
1279 *
1280 * Return -EINVAL or zero on success
1281 */
vfe_set_selection(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_selection * sel)1282 static int vfe_set_selection(struct v4l2_subdev *sd,
1283 struct v4l2_subdev_state *sd_state,
1284 struct v4l2_subdev_selection *sel)
1285 {
1286 struct vfe_line *line = v4l2_get_subdevdata(sd);
1287 struct v4l2_rect *rect;
1288 int ret;
1289
1290 if (line->id != VFE_LINE_PIX)
1291 return -EINVAL;
1292
1293 if (sel->target == V4L2_SEL_TGT_COMPOSE &&
1294 sel->pad == MSM_VFE_PAD_SINK) {
1295 struct v4l2_subdev_selection crop = { 0 };
1296
1297 rect = __vfe_get_compose(line, sd_state, sel->which);
1298 if (rect == NULL)
1299 return -EINVAL;
1300
1301 vfe_try_compose(line, sd_state, &sel->r, sel->which);
1302 *rect = sel->r;
1303
1304 /* Reset source crop selection */
1305 crop.which = sel->which;
1306 crop.pad = MSM_VFE_PAD_SRC;
1307 crop.target = V4L2_SEL_TGT_CROP;
1308 crop.r = *rect;
1309 ret = vfe_set_selection(sd, sd_state, &crop);
1310 } else if (sel->target == V4L2_SEL_TGT_CROP &&
1311 sel->pad == MSM_VFE_PAD_SRC) {
1312 struct v4l2_subdev_format fmt = { 0 };
1313
1314 rect = __vfe_get_crop(line, sd_state, sel->which);
1315 if (rect == NULL)
1316 return -EINVAL;
1317
1318 vfe_try_crop(line, sd_state, &sel->r, sel->which);
1319 *rect = sel->r;
1320
1321 /* Reset source pad format width and height */
1322 fmt.which = sel->which;
1323 fmt.pad = MSM_VFE_PAD_SRC;
1324 ret = vfe_get_format(sd, sd_state, &fmt);
1325 if (ret < 0)
1326 return ret;
1327
1328 fmt.format.width = rect->width;
1329 fmt.format.height = rect->height;
1330 ret = vfe_set_format(sd, sd_state, &fmt);
1331 } else {
1332 ret = -EINVAL;
1333 }
1334
1335 return ret;
1336 }
1337
1338 /*
1339 * vfe_init_formats - Initialize formats on all pads
1340 * @sd: VFE V4L2 subdevice
1341 * @fh: V4L2 subdev file handle
1342 *
1343 * Initialize all pad formats with default values.
1344 *
1345 * Return 0 on success or a negative error code otherwise
1346 */
vfe_init_formats(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)1347 static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1348 {
1349 struct v4l2_subdev_format format = {
1350 .pad = MSM_VFE_PAD_SINK,
1351 .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
1352 V4L2_SUBDEV_FORMAT_ACTIVE,
1353 .format = {
1354 .code = MEDIA_BUS_FMT_UYVY8_1X16,
1355 .width = 1920,
1356 .height = 1080
1357 }
1358 };
1359
1360 return vfe_set_format(sd, fh ? fh->state : NULL, &format);
1361 }
1362
1363 /*
1364 * msm_vfe_subdev_init - Initialize VFE device structure and resources
1365 * @vfe: VFE device
1366 * @res: VFE module resources table
1367 *
1368 * Return 0 on success or a negative error code otherwise
1369 */
msm_vfe_subdev_init(struct camss * camss,struct vfe_device * vfe,const struct camss_subdev_resources * res,u8 id)1370 int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
1371 const struct camss_subdev_resources *res, u8 id)
1372 {
1373 struct device *dev = camss->dev;
1374 struct platform_device *pdev = to_platform_device(dev);
1375 int i, j;
1376 int ret;
1377
1378 vfe->ops = res->ops;
1379
1380 if (!res->line_num)
1381 return -EINVAL;
1382
1383 /* Power domain */
1384
1385 if (res->pd_name) {
1386 vfe->genpd = dev_pm_domain_attach_by_name(camss->dev,
1387 res->pd_name);
1388 if (IS_ERR(vfe->genpd)) {
1389 ret = PTR_ERR(vfe->genpd);
1390 return ret;
1391 }
1392 }
1393
1394 if (!vfe->genpd && res->has_pd) {
1395 /*
1396 * Legacy magic index.
1397 * Requires
1398 * power-domain = <VFE_X>,
1399 * <VFE_Y>,
1400 * <TITAN_TOP>
1401 * id must correspondng to the index of the VFE which must
1402 * come before the TOP GDSC. VFE Lite has no individually
1403 * collapasible domain which is why id < vfe_num is a valid
1404 * check.
1405 */
1406 vfe->genpd = dev_pm_domain_attach_by_id(camss->dev, id);
1407 if (IS_ERR(vfe->genpd))
1408 return PTR_ERR(vfe->genpd);
1409 }
1410
1411 vfe->line_num = res->line_num;
1412 vfe->ops->subdev_init(dev, vfe);
1413
1414 /* Memory */
1415
1416 vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
1417 if (IS_ERR(vfe->base)) {
1418 dev_err(dev, "could not map memory\n");
1419 return PTR_ERR(vfe->base);
1420 }
1421
1422 /* Interrupt */
1423
1424 ret = platform_get_irq_byname(pdev, res->interrupt[0]);
1425 if (ret < 0)
1426 return ret;
1427
1428 vfe->irq = ret;
1429 snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d",
1430 dev_name(dev), MSM_VFE_NAME, id);
1431 ret = devm_request_irq(dev, vfe->irq, vfe->ops->isr,
1432 IRQF_TRIGGER_RISING, vfe->irq_name, vfe);
1433 if (ret < 0) {
1434 dev_err(dev, "request_irq failed: %d\n", ret);
1435 return ret;
1436 }
1437
1438 /* Clocks */
1439
1440 vfe->nclocks = 0;
1441 while (res->clock[vfe->nclocks])
1442 vfe->nclocks++;
1443
1444 vfe->clock = devm_kcalloc(dev, vfe->nclocks, sizeof(*vfe->clock),
1445 GFP_KERNEL);
1446 if (!vfe->clock)
1447 return -ENOMEM;
1448
1449 for (i = 0; i < vfe->nclocks; i++) {
1450 struct camss_clock *clock = &vfe->clock[i];
1451
1452 clock->clk = devm_clk_get(dev, res->clock[i]);
1453 if (IS_ERR(clock->clk))
1454 return PTR_ERR(clock->clk);
1455
1456 clock->name = res->clock[i];
1457
1458 clock->nfreqs = 0;
1459 while (res->clock_rate[i][clock->nfreqs])
1460 clock->nfreqs++;
1461
1462 if (!clock->nfreqs) {
1463 clock->freq = NULL;
1464 continue;
1465 }
1466
1467 clock->freq = devm_kcalloc(dev,
1468 clock->nfreqs,
1469 sizeof(*clock->freq),
1470 GFP_KERNEL);
1471 if (!clock->freq)
1472 return -ENOMEM;
1473
1474 for (j = 0; j < clock->nfreqs; j++)
1475 clock->freq[j] = res->clock_rate[i][j];
1476 }
1477
1478 mutex_init(&vfe->power_lock);
1479 vfe->power_count = 0;
1480
1481 mutex_init(&vfe->stream_lock);
1482 vfe->stream_count = 0;
1483
1484 spin_lock_init(&vfe->output_lock);
1485
1486 vfe->camss = camss;
1487 vfe->id = id;
1488 vfe->reg_update = 0;
1489
1490 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
1491 struct vfe_line *l = &vfe->line[i];
1492
1493 l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1494 l->video_out.camss = camss;
1495 l->id = i;
1496 init_completion(&l->output.sof);
1497 init_completion(&l->output.reg_update);
1498
1499 switch (camss->res->version) {
1500 case CAMSS_8x16:
1501 if (i == VFE_LINE_PIX) {
1502 l->formats = formats_pix_8x16;
1503 l->nformats = ARRAY_SIZE(formats_pix_8x16);
1504 } else {
1505 l->formats = formats_rdi_8x16;
1506 l->nformats = ARRAY_SIZE(formats_rdi_8x16);
1507 }
1508 break;
1509 case CAMSS_8x96:
1510 case CAMSS_660:
1511 if (i == VFE_LINE_PIX) {
1512 l->formats = formats_pix_8x96;
1513 l->nformats = ARRAY_SIZE(formats_pix_8x96);
1514 } else {
1515 l->formats = formats_rdi_8x96;
1516 l->nformats = ARRAY_SIZE(formats_rdi_8x96);
1517 }
1518 break;
1519 case CAMSS_845:
1520 case CAMSS_8250:
1521 l->formats = formats_rdi_845;
1522 l->nformats = ARRAY_SIZE(formats_rdi_845);
1523 break;
1524 }
1525 }
1526
1527 init_completion(&vfe->reset_complete);
1528 init_completion(&vfe->halt_complete);
1529
1530 return 0;
1531 }
1532
1533 /*
1534 * msm_vfe_genpd_cleanup - Cleanup VFE genpd linkages
1535 * @vfe: VFE device
1536 */
msm_vfe_genpd_cleanup(struct vfe_device * vfe)1537 void msm_vfe_genpd_cleanup(struct vfe_device *vfe)
1538 {
1539 if (vfe->genpd_link)
1540 device_link_del(vfe->genpd_link);
1541
1542 if (vfe->genpd)
1543 dev_pm_domain_detach(vfe->genpd, true);
1544 }
1545
1546 /*
1547 * vfe_link_setup - Setup VFE connections
1548 * @entity: Pointer to media entity structure
1549 * @local: Pointer to local pad
1550 * @remote: Pointer to remote pad
1551 * @flags: Link flags
1552 *
1553 * Return 0 on success
1554 */
vfe_link_setup(struct media_entity * entity,const struct media_pad * local,const struct media_pad * remote,u32 flags)1555 static int vfe_link_setup(struct media_entity *entity,
1556 const struct media_pad *local,
1557 const struct media_pad *remote, u32 flags)
1558 {
1559 if (flags & MEDIA_LNK_FL_ENABLED)
1560 if (media_pad_remote_pad_first(local))
1561 return -EBUSY;
1562
1563 return 0;
1564 }
1565
1566 static const struct v4l2_subdev_core_ops vfe_core_ops = {
1567 .s_power = vfe_set_power,
1568 };
1569
1570 static const struct v4l2_subdev_video_ops vfe_video_ops = {
1571 .s_stream = vfe_set_stream,
1572 };
1573
1574 static const struct v4l2_subdev_pad_ops vfe_pad_ops = {
1575 .enum_mbus_code = vfe_enum_mbus_code,
1576 .enum_frame_size = vfe_enum_frame_size,
1577 .get_fmt = vfe_get_format,
1578 .set_fmt = vfe_set_format,
1579 .get_selection = vfe_get_selection,
1580 .set_selection = vfe_set_selection,
1581 };
1582
1583 static const struct v4l2_subdev_ops vfe_v4l2_ops = {
1584 .core = &vfe_core_ops,
1585 .video = &vfe_video_ops,
1586 .pad = &vfe_pad_ops,
1587 };
1588
1589 static const struct v4l2_subdev_internal_ops vfe_v4l2_internal_ops = {
1590 .open = vfe_init_formats,
1591 };
1592
1593 static const struct media_entity_operations vfe_media_ops = {
1594 .link_setup = vfe_link_setup,
1595 .link_validate = v4l2_subdev_link_validate,
1596 };
1597
1598 /*
1599 * msm_vfe_register_entities - Register subdev node for VFE module
1600 * @vfe: VFE device
1601 * @v4l2_dev: V4L2 device
1602 *
1603 * Initialize and register a subdev node for the VFE module. Then
1604 * call msm_video_register() to register the video device node which
1605 * will be connected to this subdev node. Then actually create the
1606 * media link between them.
1607 *
1608 * Return 0 on success or a negative error code otherwise
1609 */
msm_vfe_register_entities(struct vfe_device * vfe,struct v4l2_device * v4l2_dev)1610 int msm_vfe_register_entities(struct vfe_device *vfe,
1611 struct v4l2_device *v4l2_dev)
1612 {
1613 struct device *dev = vfe->camss->dev;
1614 struct v4l2_subdev *sd;
1615 struct media_pad *pads;
1616 struct camss_video *video_out;
1617 int ret;
1618 int i;
1619
1620 for (i = 0; i < vfe->line_num; i++) {
1621 char name[32];
1622
1623 sd = &vfe->line[i].subdev;
1624 pads = vfe->line[i].pads;
1625 video_out = &vfe->line[i].video_out;
1626
1627 v4l2_subdev_init(sd, &vfe_v4l2_ops);
1628 sd->internal_ops = &vfe_v4l2_internal_ops;
1629 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1630 if (i == VFE_LINE_PIX)
1631 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s",
1632 MSM_VFE_NAME, vfe->id, "pix");
1633 else
1634 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d",
1635 MSM_VFE_NAME, vfe->id, "rdi", i);
1636
1637 v4l2_set_subdevdata(sd, &vfe->line[i]);
1638
1639 ret = vfe_init_formats(sd, NULL);
1640 if (ret < 0) {
1641 dev_err(dev, "Failed to init format: %d\n", ret);
1642 goto error_init;
1643 }
1644
1645 pads[MSM_VFE_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1646 pads[MSM_VFE_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
1647
1648 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
1649 sd->entity.ops = &vfe_media_ops;
1650 ret = media_entity_pads_init(&sd->entity, MSM_VFE_PADS_NUM,
1651 pads);
1652 if (ret < 0) {
1653 dev_err(dev, "Failed to init media entity: %d\n", ret);
1654 goto error_init;
1655 }
1656
1657 ret = v4l2_device_register_subdev(v4l2_dev, sd);
1658 if (ret < 0) {
1659 dev_err(dev, "Failed to register subdev: %d\n", ret);
1660 goto error_reg_subdev;
1661 }
1662
1663 video_out->ops = &vfe->video_ops;
1664 if (vfe->camss->res->version == CAMSS_845 ||
1665 vfe->camss->res->version == CAMSS_8250)
1666 video_out->bpl_alignment = 16;
1667 else
1668 video_out->bpl_alignment = 8;
1669 video_out->line_based = 0;
1670 if (i == VFE_LINE_PIX) {
1671 video_out->bpl_alignment = 16;
1672 video_out->line_based = 1;
1673 }
1674 snprintf(name, ARRAY_SIZE(name), "%s%d_%s%d",
1675 MSM_VFE_NAME, vfe->id, "video", i);
1676 ret = msm_video_register(video_out, v4l2_dev, name,
1677 i == VFE_LINE_PIX ? 1 : 0);
1678 if (ret < 0) {
1679 dev_err(dev, "Failed to register video node: %d\n",
1680 ret);
1681 goto error_reg_video;
1682 }
1683
1684 ret = media_create_pad_link(
1685 &sd->entity, MSM_VFE_PAD_SRC,
1686 &video_out->vdev.entity, 0,
1687 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
1688 if (ret < 0) {
1689 dev_err(dev, "Failed to link %s->%s entities: %d\n",
1690 sd->entity.name, video_out->vdev.entity.name,
1691 ret);
1692 goto error_link;
1693 }
1694 }
1695
1696 return 0;
1697
1698 error_link:
1699 msm_video_unregister(video_out);
1700
1701 error_reg_video:
1702 v4l2_device_unregister_subdev(sd);
1703
1704 error_reg_subdev:
1705 media_entity_cleanup(&sd->entity);
1706
1707 error_init:
1708 for (i--; i >= 0; i--) {
1709 sd = &vfe->line[i].subdev;
1710 video_out = &vfe->line[i].video_out;
1711
1712 msm_video_unregister(video_out);
1713 v4l2_device_unregister_subdev(sd);
1714 media_entity_cleanup(&sd->entity);
1715 }
1716
1717 return ret;
1718 }
1719
1720 /*
1721 * msm_vfe_unregister_entities - Unregister VFE module subdev node
1722 * @vfe: VFE device
1723 */
msm_vfe_unregister_entities(struct vfe_device * vfe)1724 void msm_vfe_unregister_entities(struct vfe_device *vfe)
1725 {
1726 int i;
1727
1728 mutex_destroy(&vfe->power_lock);
1729 mutex_destroy(&vfe->stream_lock);
1730
1731 for (i = 0; i < vfe->line_num; i++) {
1732 struct v4l2_subdev *sd = &vfe->line[i].subdev;
1733 struct camss_video *video_out = &vfe->line[i].video_out;
1734
1735 msm_video_unregister(video_out);
1736 v4l2_device_unregister_subdev(sd);
1737 media_entity_cleanup(&sd->entity);
1738 }
1739 }
1740
vfe_is_lite(struct vfe_device * vfe)1741 bool vfe_is_lite(struct vfe_device *vfe)
1742 {
1743 return vfe->camss->res->vfe_res[vfe->id].is_lite;
1744 }
1745