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