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