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