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