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 717 vfe->ops->hw_version_read(vfe, vfe->camss->dev); 718 } else { 719 vfe_put(vfe); 720 } 721 722 return 0; 723 } 724 725 /* 726 * vfe_set_stream - Enable/disable streaming on VFE module 727 * @sd: VFE V4L2 subdevice 728 * @enable: Requested streaming state 729 * 730 * Main configuration of VFE module is triggered here. 731 * 732 * Return 0 on success or a negative error code otherwise 733 */ 734 static int vfe_set_stream(struct v4l2_subdev *sd, int enable) 735 { 736 struct vfe_line *line = v4l2_get_subdevdata(sd); 737 struct vfe_device *vfe = to_vfe(line); 738 int ret; 739 740 if (enable) { 741 ret = vfe->ops->vfe_enable(line); 742 if (ret < 0) 743 dev_err(vfe->camss->dev, 744 "Failed to enable vfe outputs\n"); 745 } else { 746 ret = vfe->ops->vfe_disable(line); 747 if (ret < 0) 748 dev_err(vfe->camss->dev, 749 "Failed to disable vfe outputs\n"); 750 } 751 752 return ret; 753 } 754 755 /* 756 * __vfe_get_format - Get pointer to format structure 757 * @line: VFE line 758 * @cfg: V4L2 subdev pad configuration 759 * @pad: pad from which format is requested 760 * @which: TRY or ACTIVE format 761 * 762 * Return pointer to TRY or ACTIVE format structure 763 */ 764 static struct v4l2_mbus_framefmt * 765 __vfe_get_format(struct vfe_line *line, 766 struct v4l2_subdev_pad_config *cfg, 767 unsigned int pad, 768 enum v4l2_subdev_format_whence which) 769 { 770 if (which == V4L2_SUBDEV_FORMAT_TRY) 771 return v4l2_subdev_get_try_format(&line->subdev, cfg, pad); 772 773 return &line->fmt[pad]; 774 } 775 776 /* 777 * __vfe_get_compose - Get pointer to compose selection structure 778 * @line: VFE line 779 * @cfg: V4L2 subdev pad configuration 780 * @which: TRY or ACTIVE format 781 * 782 * Return pointer to TRY or ACTIVE compose rectangle structure 783 */ 784 static struct v4l2_rect * 785 __vfe_get_compose(struct vfe_line *line, 786 struct v4l2_subdev_pad_config *cfg, 787 enum v4l2_subdev_format_whence which) 788 { 789 if (which == V4L2_SUBDEV_FORMAT_TRY) 790 return v4l2_subdev_get_try_compose(&line->subdev, cfg, 791 MSM_VFE_PAD_SINK); 792 793 return &line->compose; 794 } 795 796 /* 797 * __vfe_get_crop - Get pointer to crop selection structure 798 * @line: VFE line 799 * @cfg: V4L2 subdev pad configuration 800 * @which: TRY or ACTIVE format 801 * 802 * Return pointer to TRY or ACTIVE crop rectangle structure 803 */ 804 static struct v4l2_rect * 805 __vfe_get_crop(struct vfe_line *line, 806 struct v4l2_subdev_pad_config *cfg, 807 enum v4l2_subdev_format_whence which) 808 { 809 if (which == V4L2_SUBDEV_FORMAT_TRY) 810 return v4l2_subdev_get_try_crop(&line->subdev, cfg, 811 MSM_VFE_PAD_SRC); 812 813 return &line->crop; 814 } 815 816 /* 817 * vfe_try_format - Handle try format by pad subdev method 818 * @line: VFE line 819 * @cfg: V4L2 subdev pad configuration 820 * @pad: pad on which format is requested 821 * @fmt: pointer to v4l2 format structure 822 * @which: wanted subdev format 823 */ 824 static void vfe_try_format(struct vfe_line *line, 825 struct v4l2_subdev_pad_config *cfg, 826 unsigned int pad, 827 struct v4l2_mbus_framefmt *fmt, 828 enum v4l2_subdev_format_whence which) 829 { 830 unsigned int i; 831 u32 code; 832 833 switch (pad) { 834 case MSM_VFE_PAD_SINK: 835 /* Set format on sink pad */ 836 837 for (i = 0; i < line->nformats; i++) 838 if (fmt->code == line->formats[i].code) 839 break; 840 841 /* If not found, use UYVY as default */ 842 if (i >= line->nformats) 843 fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; 844 845 fmt->width = clamp_t(u32, fmt->width, 1, 8191); 846 fmt->height = clamp_t(u32, fmt->height, 1, 8191); 847 848 fmt->field = V4L2_FIELD_NONE; 849 fmt->colorspace = V4L2_COLORSPACE_SRGB; 850 851 break; 852 853 case MSM_VFE_PAD_SRC: 854 /* Set and return a format same as sink pad */ 855 code = fmt->code; 856 857 *fmt = *__vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, 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, cfg, 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_pad_config *cfg, 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, cfg, 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_pad_config *cfg, 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, cfg, 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_pad_config *cfg, 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, cfg, 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_pad_config *cfg, 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, cfg, 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, cfg, 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_pad_config *cfg, 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, cfg, 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_pad_config *cfg, 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_pad_config *cfg, 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, cfg, fmt->pad, fmt->which); 1074 if (format == NULL) 1075 return -EINVAL; 1076 1077 vfe_try_format(line, cfg, 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, cfg, MSM_VFE_PAD_SRC, 1086 fmt->which); 1087 1088 *format = fmt->format; 1089 vfe_try_format(line, cfg, 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, cfg, &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_pad_config *cfg, 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, cfg, &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, cfg, 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, cfg, 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, cfg, 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_pad_config *cfg, 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, cfg, sel->which); 1203 if (rect == NULL) 1204 return -EINVAL; 1205 1206 vfe_try_compose(line, cfg, &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, cfg, &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, cfg, sel->which); 1220 if (rect == NULL) 1221 return -EINVAL; 1222 1223 vfe_try_crop(line, cfg, &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, cfg, &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, cfg, &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->pad : 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 1303 /* Memory */ 1304 1305 vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]); 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