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_get_sync(vfe->camss->dev); 588 if (ret < 0) 589 goto error_pm_runtime_get; 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 vfe->ops->pm_domain_off(vfe); 624 625 error_pm_domain: 626 mutex_unlock(&vfe->power_lock); 627 628 return ret; 629 } 630 631 /* 632 * vfe_put - Power down VFE module 633 * @vfe: VFE Device 634 */ 635 static void vfe_put(struct vfe_device *vfe) 636 { 637 mutex_lock(&vfe->power_lock); 638 639 if (vfe->power_count == 0) { 640 dev_err(vfe->camss->dev, "vfe power off on power_count == 0\n"); 641 goto exit; 642 } else if (vfe->power_count == 1) { 643 if (vfe->was_streaming) { 644 vfe->was_streaming = 0; 645 vfe->ops->vfe_halt(vfe); 646 } 647 camss_disable_clocks(vfe->nclocks, vfe->clock); 648 pm_runtime_put_sync(vfe->camss->dev); 649 vfe->ops->pm_domain_off(vfe); 650 } 651 652 vfe->power_count--; 653 654 exit: 655 mutex_unlock(&vfe->power_lock); 656 } 657 658 /* 659 * vfe_flush_buffers - Return all vb2 buffers 660 * @vid: Video device structure 661 * @state: vb2 buffer state of the returned buffers 662 * 663 * Return all buffers to vb2. This includes queued pending buffers (still 664 * unused) and any buffers given to the hardware but again still not used. 665 * 666 * Return 0 on success or a negative error code otherwise 667 */ 668 int vfe_flush_buffers(struct camss_video *vid, 669 enum vb2_buffer_state state) 670 { 671 struct vfe_line *line = container_of(vid, struct vfe_line, video_out); 672 struct vfe_device *vfe = to_vfe(line); 673 struct vfe_output *output; 674 unsigned long flags; 675 676 output = &line->output; 677 678 spin_lock_irqsave(&vfe->output_lock, flags); 679 680 vfe_buf_flush_pending(output, state); 681 682 if (output->buf[0]) 683 vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state); 684 685 if (output->buf[1]) 686 vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state); 687 688 if (output->last_buffer) { 689 vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state); 690 output->last_buffer = NULL; 691 } 692 693 spin_unlock_irqrestore(&vfe->output_lock, flags); 694 695 return 0; 696 } 697 698 /* 699 * vfe_set_power - Power on/off VFE module 700 * @sd: VFE V4L2 subdevice 701 * @on: Requested power state 702 * 703 * Return 0 on success or a negative error code otherwise 704 */ 705 static int vfe_set_power(struct v4l2_subdev *sd, int on) 706 { 707 struct vfe_line *line = v4l2_get_subdevdata(sd); 708 struct vfe_device *vfe = to_vfe(line); 709 int ret; 710 711 if (on) { 712 ret = vfe_get(vfe); 713 if (ret < 0) 714 return ret; 715 716 vfe->ops->hw_version_read(vfe, vfe->camss->dev); 717 } else { 718 vfe_put(vfe); 719 } 720 721 return 0; 722 } 723 724 /* 725 * vfe_set_stream - Enable/disable streaming on VFE module 726 * @sd: VFE V4L2 subdevice 727 * @enable: Requested streaming state 728 * 729 * Main configuration of VFE module is triggered here. 730 * 731 * Return 0 on success or a negative error code otherwise 732 */ 733 static int vfe_set_stream(struct v4l2_subdev *sd, int enable) 734 { 735 struct vfe_line *line = v4l2_get_subdevdata(sd); 736 struct vfe_device *vfe = to_vfe(line); 737 int ret; 738 739 if (enable) { 740 ret = vfe->ops->vfe_enable(line); 741 if (ret < 0) 742 dev_err(vfe->camss->dev, 743 "Failed to enable vfe outputs\n"); 744 } else { 745 ret = vfe->ops->vfe_disable(line); 746 if (ret < 0) 747 dev_err(vfe->camss->dev, 748 "Failed to disable vfe outputs\n"); 749 } 750 751 return ret; 752 } 753 754 /* 755 * __vfe_get_format - Get pointer to format structure 756 * @line: VFE line 757 * @cfg: V4L2 subdev pad configuration 758 * @pad: pad from which format is requested 759 * @which: TRY or ACTIVE format 760 * 761 * Return pointer to TRY or ACTIVE format structure 762 */ 763 static struct v4l2_mbus_framefmt * 764 __vfe_get_format(struct vfe_line *line, 765 struct v4l2_subdev_pad_config *cfg, 766 unsigned int pad, 767 enum v4l2_subdev_format_whence which) 768 { 769 if (which == V4L2_SUBDEV_FORMAT_TRY) 770 return v4l2_subdev_get_try_format(&line->subdev, cfg, 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_pad_config *cfg, 786 enum v4l2_subdev_format_whence which) 787 { 788 if (which == V4L2_SUBDEV_FORMAT_TRY) 789 return v4l2_subdev_get_try_compose(&line->subdev, cfg, 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_pad_config *cfg, 806 enum v4l2_subdev_format_whence which) 807 { 808 if (which == V4L2_SUBDEV_FORMAT_TRY) 809 return v4l2_subdev_get_try_crop(&line->subdev, cfg, 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_pad_config *cfg, 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, cfg, MSM_VFE_PAD_SINK, which); 857 858 fmt->code = vfe_src_pad_code(line, fmt->code, 0, code); 859 860 if (line->id == VFE_LINE_PIX) { 861 struct v4l2_rect *rect; 862 863 rect = __vfe_get_crop(line, cfg, which); 864 865 fmt->width = rect->width; 866 fmt->height = rect->height; 867 } 868 869 break; 870 } 871 872 fmt->colorspace = V4L2_COLORSPACE_SRGB; 873 } 874 875 /* 876 * vfe_try_compose - Handle try compose selection by pad subdev method 877 * @line: VFE line 878 * @cfg: V4L2 subdev pad configuration 879 * @rect: pointer to v4l2 rect structure 880 * @which: wanted subdev format 881 */ 882 static void vfe_try_compose(struct vfe_line *line, 883 struct v4l2_subdev_pad_config *cfg, 884 struct v4l2_rect *rect, 885 enum v4l2_subdev_format_whence which) 886 { 887 struct v4l2_mbus_framefmt *fmt; 888 889 fmt = __vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, which); 890 891 if (rect->width > fmt->width) 892 rect->width = fmt->width; 893 894 if (rect->height > fmt->height) 895 rect->height = fmt->height; 896 897 if (fmt->width > rect->width * SCALER_RATIO_MAX) 898 rect->width = (fmt->width + SCALER_RATIO_MAX - 1) / 899 SCALER_RATIO_MAX; 900 901 rect->width &= ~0x1; 902 903 if (fmt->height > rect->height * SCALER_RATIO_MAX) 904 rect->height = (fmt->height + SCALER_RATIO_MAX - 1) / 905 SCALER_RATIO_MAX; 906 907 if (rect->width < 16) 908 rect->width = 16; 909 910 if (rect->height < 4) 911 rect->height = 4; 912 } 913 914 /* 915 * vfe_try_crop - Handle try crop selection by pad subdev method 916 * @line: VFE line 917 * @cfg: V4L2 subdev pad configuration 918 * @rect: pointer to v4l2 rect structure 919 * @which: wanted subdev format 920 */ 921 static void vfe_try_crop(struct vfe_line *line, 922 struct v4l2_subdev_pad_config *cfg, 923 struct v4l2_rect *rect, 924 enum v4l2_subdev_format_whence which) 925 { 926 struct v4l2_rect *compose; 927 928 compose = __vfe_get_compose(line, cfg, which); 929 930 if (rect->width > compose->width) 931 rect->width = compose->width; 932 933 if (rect->width + rect->left > compose->width) 934 rect->left = compose->width - rect->width; 935 936 if (rect->height > compose->height) 937 rect->height = compose->height; 938 939 if (rect->height + rect->top > compose->height) 940 rect->top = compose->height - rect->height; 941 942 /* wm in line based mode writes multiple of 16 horizontally */ 943 rect->left += (rect->width & 0xf) >> 1; 944 rect->width &= ~0xf; 945 946 if (rect->width < 16) { 947 rect->left = 0; 948 rect->width = 16; 949 } 950 951 if (rect->height < 4) { 952 rect->top = 0; 953 rect->height = 4; 954 } 955 } 956 957 /* 958 * vfe_enum_mbus_code - Handle pixel format enumeration 959 * @sd: VFE V4L2 subdevice 960 * @cfg: V4L2 subdev pad configuration 961 * @code: pointer to v4l2_subdev_mbus_code_enum structure 962 * 963 * return -EINVAL or zero on success 964 */ 965 static int vfe_enum_mbus_code(struct v4l2_subdev *sd, 966 struct v4l2_subdev_pad_config *cfg, 967 struct v4l2_subdev_mbus_code_enum *code) 968 { 969 struct vfe_line *line = v4l2_get_subdevdata(sd); 970 971 if (code->pad == MSM_VFE_PAD_SINK) { 972 if (code->index >= line->nformats) 973 return -EINVAL; 974 975 code->code = line->formats[code->index].code; 976 } else { 977 struct v4l2_mbus_framefmt *sink_fmt; 978 979 sink_fmt = __vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, 980 code->which); 981 982 code->code = vfe_src_pad_code(line, sink_fmt->code, 983 code->index, 0); 984 if (!code->code) 985 return -EINVAL; 986 } 987 988 return 0; 989 } 990 991 /* 992 * vfe_enum_frame_size - Handle frame size enumeration 993 * @sd: VFE V4L2 subdevice 994 * @cfg: V4L2 subdev pad configuration 995 * @fse: pointer to v4l2_subdev_frame_size_enum structure 996 * 997 * Return -EINVAL or zero on success 998 */ 999 static int vfe_enum_frame_size(struct v4l2_subdev *sd, 1000 struct v4l2_subdev_pad_config *cfg, 1001 struct v4l2_subdev_frame_size_enum *fse) 1002 { 1003 struct vfe_line *line = v4l2_get_subdevdata(sd); 1004 struct v4l2_mbus_framefmt format; 1005 1006 if (fse->index != 0) 1007 return -EINVAL; 1008 1009 format.code = fse->code; 1010 format.width = 1; 1011 format.height = 1; 1012 vfe_try_format(line, cfg, fse->pad, &format, fse->which); 1013 fse->min_width = format.width; 1014 fse->min_height = format.height; 1015 1016 if (format.code != fse->code) 1017 return -EINVAL; 1018 1019 format.code = fse->code; 1020 format.width = -1; 1021 format.height = -1; 1022 vfe_try_format(line, cfg, fse->pad, &format, fse->which); 1023 fse->max_width = format.width; 1024 fse->max_height = format.height; 1025 1026 return 0; 1027 } 1028 1029 /* 1030 * vfe_get_format - Handle get format by pads subdev method 1031 * @sd: VFE V4L2 subdevice 1032 * @cfg: V4L2 subdev pad configuration 1033 * @fmt: pointer to v4l2 subdev format structure 1034 * 1035 * Return -EINVAL or zero on success 1036 */ 1037 static int vfe_get_format(struct v4l2_subdev *sd, 1038 struct v4l2_subdev_pad_config *cfg, 1039 struct v4l2_subdev_format *fmt) 1040 { 1041 struct vfe_line *line = v4l2_get_subdevdata(sd); 1042 struct v4l2_mbus_framefmt *format; 1043 1044 format = __vfe_get_format(line, cfg, fmt->pad, fmt->which); 1045 if (format == NULL) 1046 return -EINVAL; 1047 1048 fmt->format = *format; 1049 1050 return 0; 1051 } 1052 1053 static int vfe_set_selection(struct v4l2_subdev *sd, 1054 struct v4l2_subdev_pad_config *cfg, 1055 struct v4l2_subdev_selection *sel); 1056 1057 /* 1058 * vfe_set_format - Handle set format by pads subdev method 1059 * @sd: VFE V4L2 subdevice 1060 * @cfg: V4L2 subdev pad configuration 1061 * @fmt: pointer to v4l2 subdev format structure 1062 * 1063 * Return -EINVAL or zero on success 1064 */ 1065 static int vfe_set_format(struct v4l2_subdev *sd, 1066 struct v4l2_subdev_pad_config *cfg, 1067 struct v4l2_subdev_format *fmt) 1068 { 1069 struct vfe_line *line = v4l2_get_subdevdata(sd); 1070 struct v4l2_mbus_framefmt *format; 1071 1072 format = __vfe_get_format(line, cfg, fmt->pad, fmt->which); 1073 if (format == NULL) 1074 return -EINVAL; 1075 1076 vfe_try_format(line, cfg, fmt->pad, &fmt->format, fmt->which); 1077 *format = fmt->format; 1078 1079 if (fmt->pad == MSM_VFE_PAD_SINK) { 1080 struct v4l2_subdev_selection sel = { 0 }; 1081 int ret; 1082 1083 /* Propagate the format from sink to source */ 1084 format = __vfe_get_format(line, cfg, MSM_VFE_PAD_SRC, 1085 fmt->which); 1086 1087 *format = fmt->format; 1088 vfe_try_format(line, cfg, MSM_VFE_PAD_SRC, format, 1089 fmt->which); 1090 1091 if (line->id != VFE_LINE_PIX) 1092 return 0; 1093 1094 /* Reset sink pad compose selection */ 1095 sel.which = fmt->which; 1096 sel.pad = MSM_VFE_PAD_SINK; 1097 sel.target = V4L2_SEL_TGT_COMPOSE; 1098 sel.r.width = fmt->format.width; 1099 sel.r.height = fmt->format.height; 1100 ret = vfe_set_selection(sd, cfg, &sel); 1101 if (ret < 0) 1102 return ret; 1103 } 1104 1105 return 0; 1106 } 1107 1108 /* 1109 * vfe_get_selection - Handle get selection by pads subdev method 1110 * @sd: VFE V4L2 subdevice 1111 * @cfg: V4L2 subdev pad configuration 1112 * @sel: pointer to v4l2 subdev selection structure 1113 * 1114 * Return -EINVAL or zero on success 1115 */ 1116 static int vfe_get_selection(struct v4l2_subdev *sd, 1117 struct v4l2_subdev_pad_config *cfg, 1118 struct v4l2_subdev_selection *sel) 1119 { 1120 struct vfe_line *line = v4l2_get_subdevdata(sd); 1121 struct v4l2_subdev_format fmt = { 0 }; 1122 struct v4l2_rect *rect; 1123 int ret; 1124 1125 if (line->id != VFE_LINE_PIX) 1126 return -EINVAL; 1127 1128 if (sel->pad == MSM_VFE_PAD_SINK) 1129 switch (sel->target) { 1130 case V4L2_SEL_TGT_COMPOSE_BOUNDS: 1131 fmt.pad = sel->pad; 1132 fmt.which = sel->which; 1133 ret = vfe_get_format(sd, cfg, &fmt); 1134 if (ret < 0) 1135 return ret; 1136 1137 sel->r.left = 0; 1138 sel->r.top = 0; 1139 sel->r.width = fmt.format.width; 1140 sel->r.height = fmt.format.height; 1141 break; 1142 case V4L2_SEL_TGT_COMPOSE: 1143 rect = __vfe_get_compose(line, cfg, sel->which); 1144 if (rect == NULL) 1145 return -EINVAL; 1146 1147 sel->r = *rect; 1148 break; 1149 default: 1150 return -EINVAL; 1151 } 1152 else if (sel->pad == MSM_VFE_PAD_SRC) 1153 switch (sel->target) { 1154 case V4L2_SEL_TGT_CROP_BOUNDS: 1155 rect = __vfe_get_compose(line, cfg, sel->which); 1156 if (rect == NULL) 1157 return -EINVAL; 1158 1159 sel->r.left = rect->left; 1160 sel->r.top = rect->top; 1161 sel->r.width = rect->width; 1162 sel->r.height = rect->height; 1163 break; 1164 case V4L2_SEL_TGT_CROP: 1165 rect = __vfe_get_crop(line, cfg, sel->which); 1166 if (rect == NULL) 1167 return -EINVAL; 1168 1169 sel->r = *rect; 1170 break; 1171 default: 1172 return -EINVAL; 1173 } 1174 1175 return 0; 1176 } 1177 1178 /* 1179 * vfe_set_selection - Handle set selection by pads subdev method 1180 * @sd: VFE V4L2 subdevice 1181 * @cfg: V4L2 subdev pad configuration 1182 * @sel: pointer to v4l2 subdev selection structure 1183 * 1184 * Return -EINVAL or zero on success 1185 */ 1186 static int vfe_set_selection(struct v4l2_subdev *sd, 1187 struct v4l2_subdev_pad_config *cfg, 1188 struct v4l2_subdev_selection *sel) 1189 { 1190 struct vfe_line *line = v4l2_get_subdevdata(sd); 1191 struct v4l2_rect *rect; 1192 int ret; 1193 1194 if (line->id != VFE_LINE_PIX) 1195 return -EINVAL; 1196 1197 if (sel->target == V4L2_SEL_TGT_COMPOSE && 1198 sel->pad == MSM_VFE_PAD_SINK) { 1199 struct v4l2_subdev_selection crop = { 0 }; 1200 1201 rect = __vfe_get_compose(line, cfg, sel->which); 1202 if (rect == NULL) 1203 return -EINVAL; 1204 1205 vfe_try_compose(line, cfg, &sel->r, sel->which); 1206 *rect = sel->r; 1207 1208 /* Reset source crop selection */ 1209 crop.which = sel->which; 1210 crop.pad = MSM_VFE_PAD_SRC; 1211 crop.target = V4L2_SEL_TGT_CROP; 1212 crop.r = *rect; 1213 ret = vfe_set_selection(sd, cfg, &crop); 1214 } else if (sel->target == V4L2_SEL_TGT_CROP && 1215 sel->pad == MSM_VFE_PAD_SRC) { 1216 struct v4l2_subdev_format fmt = { 0 }; 1217 1218 rect = __vfe_get_crop(line, cfg, sel->which); 1219 if (rect == NULL) 1220 return -EINVAL; 1221 1222 vfe_try_crop(line, cfg, &sel->r, sel->which); 1223 *rect = sel->r; 1224 1225 /* Reset source pad format width and height */ 1226 fmt.which = sel->which; 1227 fmt.pad = MSM_VFE_PAD_SRC; 1228 ret = vfe_get_format(sd, cfg, &fmt); 1229 if (ret < 0) 1230 return ret; 1231 1232 fmt.format.width = rect->width; 1233 fmt.format.height = rect->height; 1234 ret = vfe_set_format(sd, cfg, &fmt); 1235 } else { 1236 ret = -EINVAL; 1237 } 1238 1239 return ret; 1240 } 1241 1242 /* 1243 * vfe_init_formats - Initialize formats on all pads 1244 * @sd: VFE V4L2 subdevice 1245 * @fh: V4L2 subdev file handle 1246 * 1247 * Initialize all pad formats with default values. 1248 * 1249 * Return 0 on success or a negative error code otherwise 1250 */ 1251 static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 1252 { 1253 struct v4l2_subdev_format format = { 1254 .pad = MSM_VFE_PAD_SINK, 1255 .which = fh ? V4L2_SUBDEV_FORMAT_TRY : 1256 V4L2_SUBDEV_FORMAT_ACTIVE, 1257 .format = { 1258 .code = MEDIA_BUS_FMT_UYVY8_2X8, 1259 .width = 1920, 1260 .height = 1080 1261 } 1262 }; 1263 1264 return vfe_set_format(sd, fh ? fh->pad : NULL, &format); 1265 } 1266 1267 /* 1268 * msm_vfe_subdev_init - Initialize VFE device structure and resources 1269 * @vfe: VFE device 1270 * @res: VFE module resources table 1271 * 1272 * Return 0 on success or a negative error code otherwise 1273 */ 1274 int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, 1275 const struct resources *res, u8 id) 1276 { 1277 struct device *dev = camss->dev; 1278 struct platform_device *pdev = to_platform_device(dev); 1279 struct resource *r; 1280 int i, j; 1281 int ret; 1282 1283 switch (camss->version) { 1284 case CAMSS_8x16: 1285 vfe->ops = &vfe_ops_4_1; 1286 break; 1287 case CAMSS_8x96: 1288 vfe->ops = &vfe_ops_4_7; 1289 break; 1290 case CAMSS_660: 1291 vfe->ops = &vfe_ops_4_8; 1292 break; 1293 1294 case CAMSS_845: 1295 vfe->ops = &vfe_ops_170; 1296 break; 1297 default: 1298 return -EINVAL; 1299 } 1300 vfe->ops->subdev_init(dev, vfe); 1301 1302 /* Memory */ 1303 1304 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]); 1305 vfe->base = devm_ioremap_resource(dev, r); 1306 if (IS_ERR(vfe->base)) { 1307 dev_err(dev, "could not map memory\n"); 1308 return PTR_ERR(vfe->base); 1309 } 1310 1311 /* Interrupt */ 1312 1313 r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, 1314 res->interrupt[0]); 1315 if (!r) { 1316 dev_err(dev, "missing IRQ\n"); 1317 return -EINVAL; 1318 } 1319 1320 vfe->irq = r->start; 1321 snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d", 1322 dev_name(dev), MSM_VFE_NAME, vfe->id); 1323 ret = devm_request_irq(dev, vfe->irq, vfe->ops->isr, 1324 IRQF_TRIGGER_RISING, vfe->irq_name, vfe); 1325 if (ret < 0) { 1326 dev_err(dev, "request_irq failed: %d\n", ret); 1327 return ret; 1328 } 1329 1330 /* Clocks */ 1331 1332 vfe->nclocks = 0; 1333 while (res->clock[vfe->nclocks]) 1334 vfe->nclocks++; 1335 1336 vfe->clock = devm_kcalloc(dev, vfe->nclocks, sizeof(*vfe->clock), 1337 GFP_KERNEL); 1338 if (!vfe->clock) 1339 return -ENOMEM; 1340 1341 for (i = 0; i < vfe->nclocks; i++) { 1342 struct camss_clock *clock = &vfe->clock[i]; 1343 1344 clock->clk = devm_clk_get(dev, res->clock[i]); 1345 if (IS_ERR(clock->clk)) 1346 return PTR_ERR(clock->clk); 1347 1348 clock->name = res->clock[i]; 1349 1350 clock->nfreqs = 0; 1351 while (res->clock_rate[i][clock->nfreqs]) 1352 clock->nfreqs++; 1353 1354 if (!clock->nfreqs) { 1355 clock->freq = NULL; 1356 continue; 1357 } 1358 1359 clock->freq = devm_kcalloc(dev, 1360 clock->nfreqs, 1361 sizeof(*clock->freq), 1362 GFP_KERNEL); 1363 if (!clock->freq) 1364 return -ENOMEM; 1365 1366 for (j = 0; j < clock->nfreqs; j++) 1367 clock->freq[j] = res->clock_rate[i][j]; 1368 } 1369 1370 mutex_init(&vfe->power_lock); 1371 vfe->power_count = 0; 1372 1373 mutex_init(&vfe->stream_lock); 1374 vfe->stream_count = 0; 1375 1376 spin_lock_init(&vfe->output_lock); 1377 1378 vfe->camss = camss; 1379 vfe->id = id; 1380 vfe->reg_update = 0; 1381 1382 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) { 1383 struct vfe_line *l = &vfe->line[i]; 1384 1385 l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1386 l->video_out.camss = camss; 1387 l->id = i; 1388 init_completion(&l->output.sof); 1389 init_completion(&l->output.reg_update); 1390 1391 if (camss->version == CAMSS_8x16) { 1392 if (i == VFE_LINE_PIX) { 1393 l->formats = formats_pix_8x16; 1394 l->nformats = ARRAY_SIZE(formats_pix_8x16); 1395 } else { 1396 l->formats = formats_rdi_8x16; 1397 l->nformats = ARRAY_SIZE(formats_rdi_8x16); 1398 } 1399 } else if (camss->version == CAMSS_8x96 || 1400 camss->version == CAMSS_660) { 1401 if (i == VFE_LINE_PIX) { 1402 l->formats = formats_pix_8x96; 1403 l->nformats = ARRAY_SIZE(formats_pix_8x96); 1404 } else { 1405 l->formats = formats_rdi_8x96; 1406 l->nformats = ARRAY_SIZE(formats_rdi_8x96); 1407 } 1408 } else if (camss->version == CAMSS_845) { 1409 l->formats = formats_rdi_845; 1410 l->nformats = ARRAY_SIZE(formats_rdi_845); 1411 } else { 1412 return -EINVAL; 1413 } 1414 } 1415 1416 init_completion(&vfe->reset_complete); 1417 init_completion(&vfe->halt_complete); 1418 1419 return 0; 1420 } 1421 1422 /* 1423 * msm_vfe_get_vfe_id - Get VFE HW module id 1424 * @entity: Pointer to VFE media entity structure 1425 * @id: Return CSID HW module id here 1426 */ 1427 void msm_vfe_get_vfe_id(struct media_entity *entity, u8 *id) 1428 { 1429 struct v4l2_subdev *sd; 1430 struct vfe_line *line; 1431 struct vfe_device *vfe; 1432 1433 sd = media_entity_to_v4l2_subdev(entity); 1434 line = v4l2_get_subdevdata(sd); 1435 vfe = to_vfe(line); 1436 1437 *id = vfe->id; 1438 } 1439 1440 /* 1441 * msm_vfe_get_vfe_line_id - Get VFE line id by media entity 1442 * @entity: Pointer to VFE media entity structure 1443 * @id: Return VFE line id here 1444 */ 1445 void msm_vfe_get_vfe_line_id(struct media_entity *entity, enum vfe_line_id *id) 1446 { 1447 struct v4l2_subdev *sd; 1448 struct vfe_line *line; 1449 1450 sd = media_entity_to_v4l2_subdev(entity); 1451 line = v4l2_get_subdevdata(sd); 1452 1453 *id = line->id; 1454 } 1455 1456 /* 1457 * vfe_link_setup - Setup VFE connections 1458 * @entity: Pointer to media entity structure 1459 * @local: Pointer to local pad 1460 * @remote: Pointer to remote pad 1461 * @flags: Link flags 1462 * 1463 * Return 0 on success 1464 */ 1465 static int vfe_link_setup(struct media_entity *entity, 1466 const struct media_pad *local, 1467 const struct media_pad *remote, u32 flags) 1468 { 1469 if (flags & MEDIA_LNK_FL_ENABLED) 1470 if (media_entity_remote_pad(local)) 1471 return -EBUSY; 1472 1473 return 0; 1474 } 1475 1476 static const struct v4l2_subdev_core_ops vfe_core_ops = { 1477 .s_power = vfe_set_power, 1478 }; 1479 1480 static const struct v4l2_subdev_video_ops vfe_video_ops = { 1481 .s_stream = vfe_set_stream, 1482 }; 1483 1484 static const struct v4l2_subdev_pad_ops vfe_pad_ops = { 1485 .enum_mbus_code = vfe_enum_mbus_code, 1486 .enum_frame_size = vfe_enum_frame_size, 1487 .get_fmt = vfe_get_format, 1488 .set_fmt = vfe_set_format, 1489 .get_selection = vfe_get_selection, 1490 .set_selection = vfe_set_selection, 1491 }; 1492 1493 static const struct v4l2_subdev_ops vfe_v4l2_ops = { 1494 .core = &vfe_core_ops, 1495 .video = &vfe_video_ops, 1496 .pad = &vfe_pad_ops, 1497 }; 1498 1499 static const struct v4l2_subdev_internal_ops vfe_v4l2_internal_ops = { 1500 .open = vfe_init_formats, 1501 }; 1502 1503 static const struct media_entity_operations vfe_media_ops = { 1504 .link_setup = vfe_link_setup, 1505 .link_validate = v4l2_subdev_link_validate, 1506 }; 1507 1508 /* 1509 * msm_vfe_register_entities - Register subdev node for VFE module 1510 * @vfe: VFE device 1511 * @v4l2_dev: V4L2 device 1512 * 1513 * Initialize and register a subdev node for the VFE module. Then 1514 * call msm_video_register() to register the video device node which 1515 * will be connected to this subdev node. Then actually create the 1516 * media link between them. 1517 * 1518 * Return 0 on success or a negative error code otherwise 1519 */ 1520 int msm_vfe_register_entities(struct vfe_device *vfe, 1521 struct v4l2_device *v4l2_dev) 1522 { 1523 struct device *dev = vfe->camss->dev; 1524 struct v4l2_subdev *sd; 1525 struct media_pad *pads; 1526 struct camss_video *video_out; 1527 int ret; 1528 int i; 1529 1530 for (i = 0; i < vfe->line_num; i++) { 1531 char name[32]; 1532 1533 sd = &vfe->line[i].subdev; 1534 pads = vfe->line[i].pads; 1535 video_out = &vfe->line[i].video_out; 1536 1537 v4l2_subdev_init(sd, &vfe_v4l2_ops); 1538 sd->internal_ops = &vfe_v4l2_internal_ops; 1539 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1540 if (i == VFE_LINE_PIX) 1541 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s", 1542 MSM_VFE_NAME, vfe->id, "pix"); 1543 else 1544 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d", 1545 MSM_VFE_NAME, vfe->id, "rdi", i); 1546 1547 v4l2_set_subdevdata(sd, &vfe->line[i]); 1548 1549 ret = vfe_init_formats(sd, NULL); 1550 if (ret < 0) { 1551 dev_err(dev, "Failed to init format: %d\n", ret); 1552 goto error_init; 1553 } 1554 1555 pads[MSM_VFE_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 1556 pads[MSM_VFE_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE; 1557 1558 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; 1559 sd->entity.ops = &vfe_media_ops; 1560 ret = media_entity_pads_init(&sd->entity, MSM_VFE_PADS_NUM, 1561 pads); 1562 if (ret < 0) { 1563 dev_err(dev, "Failed to init media entity: %d\n", ret); 1564 goto error_init; 1565 } 1566 1567 ret = v4l2_device_register_subdev(v4l2_dev, sd); 1568 if (ret < 0) { 1569 dev_err(dev, "Failed to register subdev: %d\n", ret); 1570 goto error_reg_subdev; 1571 } 1572 1573 video_out->ops = &vfe->video_ops; 1574 video_out->bpl_alignment = 8; 1575 video_out->line_based = 0; 1576 if (i == VFE_LINE_PIX) { 1577 video_out->bpl_alignment = 16; 1578 video_out->line_based = 1; 1579 } 1580 snprintf(name, ARRAY_SIZE(name), "%s%d_%s%d", 1581 MSM_VFE_NAME, vfe->id, "video", i); 1582 ret = msm_video_register(video_out, v4l2_dev, name, 1583 i == VFE_LINE_PIX ? 1 : 0); 1584 if (ret < 0) { 1585 dev_err(dev, "Failed to register video node: %d\n", 1586 ret); 1587 goto error_reg_video; 1588 } 1589 1590 ret = media_create_pad_link( 1591 &sd->entity, MSM_VFE_PAD_SRC, 1592 &video_out->vdev.entity, 0, 1593 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); 1594 if (ret < 0) { 1595 dev_err(dev, "Failed to link %s->%s entities: %d\n", 1596 sd->entity.name, video_out->vdev.entity.name, 1597 ret); 1598 goto error_link; 1599 } 1600 } 1601 1602 return 0; 1603 1604 error_link: 1605 msm_video_unregister(video_out); 1606 1607 error_reg_video: 1608 v4l2_device_unregister_subdev(sd); 1609 1610 error_reg_subdev: 1611 media_entity_cleanup(&sd->entity); 1612 1613 error_init: 1614 for (i--; i >= 0; i--) { 1615 sd = &vfe->line[i].subdev; 1616 video_out = &vfe->line[i].video_out; 1617 1618 msm_video_unregister(video_out); 1619 v4l2_device_unregister_subdev(sd); 1620 media_entity_cleanup(&sd->entity); 1621 } 1622 1623 return ret; 1624 } 1625 1626 /* 1627 * msm_vfe_unregister_entities - Unregister VFE module subdev node 1628 * @vfe: VFE device 1629 */ 1630 void msm_vfe_unregister_entities(struct vfe_device *vfe) 1631 { 1632 int i; 1633 1634 mutex_destroy(&vfe->power_lock); 1635 mutex_destroy(&vfe->stream_lock); 1636 1637 for (i = 0; i < vfe->line_num; i++) { 1638 struct v4l2_subdev *sd = &vfe->line[i].subdev; 1639 struct camss_video *video_out = &vfe->line[i].video_out; 1640 1641 msm_video_unregister(video_out); 1642 v4l2_device_unregister_subdev(sd); 1643 media_entity_cleanup(&sd->entity); 1644 } 1645 } 1646