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