camss.c (42008B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * camss.c 4 * 5 * Qualcomm MSM Camera Subsystem - Core 6 * 7 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 8 * Copyright (C) 2015-2018 Linaro Ltd. 9 */ 10#include <linux/clk.h> 11#include <linux/interconnect.h> 12#include <linux/media-bus-format.h> 13#include <linux/media.h> 14#include <linux/module.h> 15#include <linux/platform_device.h> 16#include <linux/of.h> 17#include <linux/of_graph.h> 18#include <linux/pm_runtime.h> 19#include <linux/pm_domain.h> 20#include <linux/slab.h> 21#include <linux/videodev2.h> 22 23#include <media/media-device.h> 24#include <media/v4l2-async.h> 25#include <media/v4l2-device.h> 26#include <media/v4l2-mc.h> 27#include <media/v4l2-fwnode.h> 28 29#include "camss.h" 30 31#define CAMSS_CLOCK_MARGIN_NUMERATOR 105 32#define CAMSS_CLOCK_MARGIN_DENOMINATOR 100 33 34static const struct resources csiphy_res_8x16[] = { 35 /* CSIPHY0 */ 36 { 37 .regulators = {}, 38 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" }, 39 .clock_rate = { { 0 }, 40 { 0 }, 41 { 0 }, 42 { 100000000, 200000000 } }, 43 .reg = { "csiphy0", "csiphy0_clk_mux" }, 44 .interrupt = { "csiphy0" } 45 }, 46 47 /* CSIPHY1 */ 48 { 49 .regulators = {}, 50 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" }, 51 .clock_rate = { { 0 }, 52 { 0 }, 53 { 0 }, 54 { 100000000, 200000000 } }, 55 .reg = { "csiphy1", "csiphy1_clk_mux" }, 56 .interrupt = { "csiphy1" } 57 } 58}; 59 60static const struct resources csid_res_8x16[] = { 61 /* CSID0 */ 62 { 63 .regulators = { "vdda" }, 64 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", 65 "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, 66 .clock_rate = { { 0 }, 67 { 0 }, 68 { 0 }, 69 { 0 }, 70 { 100000000, 200000000 }, 71 { 0 }, 72 { 0 }, 73 { 0 } }, 74 .reg = { "csid0" }, 75 .interrupt = { "csid0" } 76 }, 77 78 /* CSID1 */ 79 { 80 .regulators = { "vdda" }, 81 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", 82 "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, 83 .clock_rate = { { 0 }, 84 { 0 }, 85 { 0 }, 86 { 0 }, 87 { 100000000, 200000000 }, 88 { 0 }, 89 { 0 }, 90 { 0 } }, 91 .reg = { "csid1" }, 92 .interrupt = { "csid1" } 93 }, 94}; 95 96static const struct resources_ispif ispif_res_8x16 = { 97 /* ISPIF */ 98 .clock = { "top_ahb", "ahb", "ispif_ahb", 99 "csi0", "csi0_pix", "csi0_rdi", 100 "csi1", "csi1_pix", "csi1_rdi" }, 101 .clock_for_reset = { "vfe0", "csi_vfe0" }, 102 .reg = { "ispif", "csi_clk_mux" }, 103 .interrupt = "ispif" 104 105}; 106 107static const struct resources vfe_res_8x16[] = { 108 /* VFE0 */ 109 { 110 .regulators = {}, 111 .clock = { "top_ahb", "vfe0", "csi_vfe0", 112 "vfe_ahb", "vfe_axi", "ahb" }, 113 .clock_rate = { { 0 }, 114 { 50000000, 80000000, 100000000, 160000000, 115 177780000, 200000000, 266670000, 320000000, 116 400000000, 465000000 }, 117 { 0 }, 118 { 0 }, 119 { 0 }, 120 { 0 }, 121 { 0 }, 122 { 0 }, 123 { 0 } }, 124 .reg = { "vfe0" }, 125 .interrupt = { "vfe0" } 126 } 127}; 128 129static const struct resources csiphy_res_8x96[] = { 130 /* CSIPHY0 */ 131 { 132 .regulators = {}, 133 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" }, 134 .clock_rate = { { 0 }, 135 { 0 }, 136 { 0 }, 137 { 100000000, 200000000, 266666667 } }, 138 .reg = { "csiphy0", "csiphy0_clk_mux" }, 139 .interrupt = { "csiphy0" } 140 }, 141 142 /* CSIPHY1 */ 143 { 144 .regulators = {}, 145 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" }, 146 .clock_rate = { { 0 }, 147 { 0 }, 148 { 0 }, 149 { 100000000, 200000000, 266666667 } }, 150 .reg = { "csiphy1", "csiphy1_clk_mux" }, 151 .interrupt = { "csiphy1" } 152 }, 153 154 /* CSIPHY2 */ 155 { 156 .regulators = {}, 157 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer" }, 158 .clock_rate = { { 0 }, 159 { 0 }, 160 { 0 }, 161 { 100000000, 200000000, 266666667 } }, 162 .reg = { "csiphy2", "csiphy2_clk_mux" }, 163 .interrupt = { "csiphy2" } 164 } 165}; 166 167static const struct resources csid_res_8x96[] = { 168 /* CSID0 */ 169 { 170 .regulators = { "vdda" }, 171 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", 172 "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, 173 .clock_rate = { { 0 }, 174 { 0 }, 175 { 0 }, 176 { 0 }, 177 { 100000000, 200000000, 266666667 }, 178 { 0 }, 179 { 0 }, 180 { 0 } }, 181 .reg = { "csid0" }, 182 .interrupt = { "csid0" } 183 }, 184 185 /* CSID1 */ 186 { 187 .regulators = { "vdda" }, 188 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", 189 "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, 190 .clock_rate = { { 0 }, 191 { 0 }, 192 { 0 }, 193 { 0 }, 194 { 100000000, 200000000, 266666667 }, 195 { 0 }, 196 { 0 }, 197 { 0 } }, 198 .reg = { "csid1" }, 199 .interrupt = { "csid1" } 200 }, 201 202 /* CSID2 */ 203 { 204 .regulators = { "vdda" }, 205 .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb", 206 "csi2", "csi2_phy", "csi2_pix", "csi2_rdi" }, 207 .clock_rate = { { 0 }, 208 { 0 }, 209 { 0 }, 210 { 0 }, 211 { 100000000, 200000000, 266666667 }, 212 { 0 }, 213 { 0 }, 214 { 0 } }, 215 .reg = { "csid2" }, 216 .interrupt = { "csid2" } 217 }, 218 219 /* CSID3 */ 220 { 221 .regulators = { "vdda" }, 222 .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb", 223 "csi3", "csi3_phy", "csi3_pix", "csi3_rdi" }, 224 .clock_rate = { { 0 }, 225 { 0 }, 226 { 0 }, 227 { 0 }, 228 { 100000000, 200000000, 266666667 }, 229 { 0 }, 230 { 0 }, 231 { 0 } }, 232 .reg = { "csid3" }, 233 .interrupt = { "csid3" } 234 } 235}; 236 237static const struct resources_ispif ispif_res_8x96 = { 238 /* ISPIF */ 239 .clock = { "top_ahb", "ahb", "ispif_ahb", 240 "csi0", "csi0_pix", "csi0_rdi", 241 "csi1", "csi1_pix", "csi1_rdi", 242 "csi2", "csi2_pix", "csi2_rdi", 243 "csi3", "csi3_pix", "csi3_rdi" }, 244 .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" }, 245 .reg = { "ispif", "csi_clk_mux" }, 246 .interrupt = "ispif" 247}; 248 249static const struct resources vfe_res_8x96[] = { 250 /* VFE0 */ 251 { 252 .regulators = {}, 253 .clock = { "top_ahb", "ahb", "vfe0", "csi_vfe0", "vfe_ahb", 254 "vfe0_ahb", "vfe_axi", "vfe0_stream"}, 255 .clock_rate = { { 0 }, 256 { 0 }, 257 { 75000000, 100000000, 300000000, 258 320000000, 480000000, 600000000 }, 259 { 0 }, 260 { 0 }, 261 { 0 }, 262 { 0 }, 263 { 0 } }, 264 .reg = { "vfe0" }, 265 .interrupt = { "vfe0" } 266 }, 267 268 /* VFE1 */ 269 { 270 .regulators = {}, 271 .clock = { "top_ahb", "ahb", "vfe1", "csi_vfe1", "vfe_ahb", 272 "vfe1_ahb", "vfe_axi", "vfe1_stream"}, 273 .clock_rate = { { 0 }, 274 { 0 }, 275 { 75000000, 100000000, 300000000, 276 320000000, 480000000, 600000000 }, 277 { 0 }, 278 { 0 }, 279 { 0 }, 280 { 0 }, 281 { 0 } }, 282 .reg = { "vfe1" }, 283 .interrupt = { "vfe1" } 284 } 285}; 286 287static const struct resources csiphy_res_660[] = { 288 /* CSIPHY0 */ 289 { 290 .regulators = {}, 291 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer", 292 "csi0_phy", "csiphy_ahb2crif" }, 293 .clock_rate = { { 0 }, 294 { 0 }, 295 { 0 }, 296 { 100000000, 200000000, 269333333 }, 297 { 0 } }, 298 .reg = { "csiphy0", "csiphy0_clk_mux" }, 299 .interrupt = { "csiphy0" } 300 }, 301 302 /* CSIPHY1 */ 303 { 304 .regulators = {}, 305 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer", 306 "csi1_phy", "csiphy_ahb2crif" }, 307 .clock_rate = { { 0 }, 308 { 0 }, 309 { 0 }, 310 { 100000000, 200000000, 269333333 }, 311 { 0 } }, 312 .reg = { "csiphy1", "csiphy1_clk_mux" }, 313 .interrupt = { "csiphy1" } 314 }, 315 316 /* CSIPHY2 */ 317 { 318 .regulators = {}, 319 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer", 320 "csi2_phy", "csiphy_ahb2crif" }, 321 .clock_rate = { { 0 }, 322 { 0 }, 323 { 0 }, 324 { 100000000, 200000000, 269333333 }, 325 { 0 } }, 326 .reg = { "csiphy2", "csiphy2_clk_mux" }, 327 .interrupt = { "csiphy2" } 328 } 329}; 330 331static const struct resources csid_res_660[] = { 332 /* CSID0 */ 333 { 334 .regulators = { "vdda", "vdd_sec" }, 335 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", 336 "csi0", "csi0_phy", "csi0_pix", "csi0_rdi", 337 "cphy_csid0" }, 338 .clock_rate = { { 0 }, 339 { 0 }, 340 { 0 }, 341 { 0 }, 342 { 100000000, 200000000, 310000000, 343 404000000, 465000000 }, 344 { 0 }, 345 { 0 }, 346 { 0 }, 347 { 0 } }, 348 .reg = { "csid0" }, 349 .interrupt = { "csid0" } 350 }, 351 352 /* CSID1 */ 353 { 354 .regulators = { "vdda", "vdd_sec" }, 355 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", 356 "csi1", "csi1_phy", "csi1_pix", "csi1_rdi", 357 "cphy_csid1" }, 358 .clock_rate = { { 0 }, 359 { 0 }, 360 { 0 }, 361 { 0 }, 362 { 100000000, 200000000, 310000000, 363 404000000, 465000000 }, 364 { 0 }, 365 { 0 }, 366 { 0 }, 367 { 0 } }, 368 .reg = { "csid1" }, 369 .interrupt = { "csid1" } 370 }, 371 372 /* CSID2 */ 373 { 374 .regulators = { "vdda", "vdd_sec" }, 375 .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb", 376 "csi2", "csi2_phy", "csi2_pix", "csi2_rdi", 377 "cphy_csid2" }, 378 .clock_rate = { { 0 }, 379 { 0 }, 380 { 0 }, 381 { 0 }, 382 { 100000000, 200000000, 310000000, 383 404000000, 465000000 }, 384 { 0 }, 385 { 0 }, 386 { 0 }, 387 { 0 } }, 388 .reg = { "csid2" }, 389 .interrupt = { "csid2" } 390 }, 391 392 /* CSID3 */ 393 { 394 .regulators = { "vdda", "vdd_sec" }, 395 .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb", 396 "csi3", "csi3_phy", "csi3_pix", "csi3_rdi", 397 "cphy_csid3" }, 398 .clock_rate = { { 0 }, 399 { 0 }, 400 { 0 }, 401 { 0 }, 402 { 100000000, 200000000, 310000000, 403 404000000, 465000000 }, 404 { 0 }, 405 { 0 }, 406 { 0 }, 407 { 0 } }, 408 .reg = { "csid3" }, 409 .interrupt = { "csid3" } 410 } 411}; 412 413static const struct resources_ispif ispif_res_660 = { 414 /* ISPIF */ 415 .clock = { "top_ahb", "ahb", "ispif_ahb", 416 "csi0", "csi0_pix", "csi0_rdi", 417 "csi1", "csi1_pix", "csi1_rdi", 418 "csi2", "csi2_pix", "csi2_rdi", 419 "csi3", "csi3_pix", "csi3_rdi" }, 420 .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" }, 421 .reg = { "ispif", "csi_clk_mux" }, 422 .interrupt = "ispif" 423}; 424 425static const struct resources vfe_res_660[] = { 426 /* VFE0 */ 427 { 428 .regulators = {}, 429 .clock = { "throttle_axi", "top_ahb", "ahb", "vfe0", 430 "csi_vfe0", "vfe_ahb", "vfe0_ahb", "vfe_axi", 431 "vfe0_stream"}, 432 .clock_rate = { { 0 }, 433 { 0 }, 434 { 0 }, 435 { 120000000, 200000000, 256000000, 436 300000000, 404000000, 480000000, 437 540000000, 576000000 }, 438 { 0 }, 439 { 0 }, 440 { 0 }, 441 { 0 }, 442 { 0 } }, 443 .reg = { "vfe0" }, 444 .interrupt = { "vfe0" } 445 }, 446 447 /* VFE1 */ 448 { 449 .regulators = {}, 450 .clock = { "throttle_axi", "top_ahb", "ahb", "vfe1", 451 "csi_vfe1", "vfe_ahb", "vfe1_ahb", "vfe_axi", 452 "vfe1_stream"}, 453 .clock_rate = { { 0 }, 454 { 0 }, 455 { 0 }, 456 { 120000000, 200000000, 256000000, 457 300000000, 404000000, 480000000, 458 540000000, 576000000 }, 459 { 0 }, 460 { 0 }, 461 { 0 }, 462 { 0 }, 463 { 0 } }, 464 .reg = { "vfe1" }, 465 .interrupt = { "vfe1" } 466 } 467}; 468 469static const struct resources csiphy_res_845[] = { 470 /* CSIPHY0 */ 471 { 472 .regulators = {}, 473 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", 474 "cpas_ahb", "cphy_rx_src", "csiphy0", 475 "csiphy0_timer_src", "csiphy0_timer" }, 476 .clock_rate = { { 0 }, 477 { 0 }, 478 { 0 }, 479 { 0 }, 480 { 0 }, 481 { 0 }, 482 { 0 }, 483 { 19200000, 240000000, 269333333 } }, 484 .reg = { "csiphy0" }, 485 .interrupt = { "csiphy0" } 486 }, 487 488 /* CSIPHY1 */ 489 { 490 .regulators = {}, 491 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", 492 "cpas_ahb", "cphy_rx_src", "csiphy1", 493 "csiphy1_timer_src", "csiphy1_timer" }, 494 .clock_rate = { { 0 }, 495 { 0 }, 496 { 0 }, 497 { 0 }, 498 { 0 }, 499 { 0 }, 500 { 0 }, 501 { 19200000, 240000000, 269333333 } }, 502 .reg = { "csiphy1" }, 503 .interrupt = { "csiphy1" } 504 }, 505 506 /* CSIPHY2 */ 507 { 508 .regulators = {}, 509 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", 510 "cpas_ahb", "cphy_rx_src", "csiphy2", 511 "csiphy2_timer_src", "csiphy2_timer" }, 512 .clock_rate = { { 0 }, 513 { 0 }, 514 { 0 }, 515 { 0 }, 516 { 0 }, 517 { 0 }, 518 { 0 }, 519 { 19200000, 240000000, 269333333 } }, 520 .reg = { "csiphy2" }, 521 .interrupt = { "csiphy2" } 522 }, 523 524 /* CSIPHY3 */ 525 { 526 .regulators = {}, 527 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", 528 "cpas_ahb", "cphy_rx_src", "csiphy3", 529 "csiphy3_timer_src", "csiphy3_timer" }, 530 .clock_rate = { { 0 }, 531 { 0 }, 532 { 0 }, 533 { 0 }, 534 { 0 }, 535 { 0 }, 536 { 0 }, 537 { 19200000, 240000000, 269333333 } }, 538 .reg = { "csiphy3" }, 539 .interrupt = { "csiphy3" } 540 } 541}; 542 543static const struct resources csid_res_845[] = { 544 /* CSID0 */ 545 { 546 .regulators = { "vdda-phy", "vdda-pll" }, 547 .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", 548 "soc_ahb", "vfe0", "vfe0_src", 549 "vfe0_cphy_rx", "csi0", 550 "csi0_src" }, 551 .clock_rate = { { 0 }, 552 { 384000000 }, 553 { 80000000 }, 554 { 0 }, 555 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, 556 { 320000000 }, 557 { 0 }, 558 { 19200000, 75000000, 384000000, 538666667 }, 559 { 384000000 } }, 560 .reg = { "csid0" }, 561 .interrupt = { "csid0" } 562 }, 563 564 /* CSID1 */ 565 { 566 .regulators = { "vdda-phy", "vdda-pll" }, 567 .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", 568 "soc_ahb", "vfe1", "vfe1_src", 569 "vfe1_cphy_rx", "csi1", 570 "csi1_src" }, 571 .clock_rate = { { 0 }, 572 { 384000000 }, 573 { 80000000 }, 574 { 0 }, 575 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, 576 { 320000000 }, 577 { 0 }, 578 { 19200000, 75000000, 384000000, 538666667 }, 579 { 384000000 } }, 580 .reg = { "csid1" }, 581 .interrupt = { "csid1" } 582 }, 583 584 /* CSID2 */ 585 { 586 .regulators = { "vdda-phy", "vdda-pll" }, 587 .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", 588 "soc_ahb", "vfe_lite", "vfe_lite_src", 589 "vfe_lite_cphy_rx", "csi2", 590 "csi2_src" }, 591 .clock_rate = { { 0 }, 592 { 384000000 }, 593 { 80000000 }, 594 { 0 }, 595 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, 596 { 320000000 }, 597 { 0 }, 598 { 19200000, 75000000, 384000000, 538666667 }, 599 { 384000000 } }, 600 .reg = { "csid2" }, 601 .interrupt = { "csid2" } 602 } 603}; 604 605static const struct resources vfe_res_845[] = { 606 /* VFE0 */ 607 { 608 .regulators = {}, 609 .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src", 610 "soc_ahb", "vfe0", "vfe0_axi", 611 "vfe0_src", "csi0", 612 "csi0_src"}, 613 .clock_rate = { { 0 }, 614 { 0 }, 615 { 80000000 }, 616 { 0 }, 617 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, 618 { 0 }, 619 { 320000000 }, 620 { 19200000, 75000000, 384000000, 538666667 }, 621 { 384000000 } }, 622 .reg = { "vfe0" }, 623 .interrupt = { "vfe0" } 624 }, 625 626 /* VFE1 */ 627 { 628 .regulators = {}, 629 .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src", 630 "soc_ahb", "vfe1", "vfe1_axi", 631 "vfe1_src", "csi1", 632 "csi1_src"}, 633 .clock_rate = { { 0 }, 634 { 0 }, 635 { 80000000 }, 636 { 0 }, 637 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, 638 { 0 }, 639 { 320000000 }, 640 { 19200000, 75000000, 384000000, 538666667 }, 641 { 384000000 } }, 642 .reg = { "vfe1" }, 643 .interrupt = { "vfe1" } 644 }, 645 646 /* VFE-lite */ 647 { 648 .regulators = {}, 649 .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src", 650 "soc_ahb", "vfe_lite", 651 "vfe_lite_src", "csi2", 652 "csi2_src"}, 653 .clock_rate = { { 0 }, 654 { 0 }, 655 { 80000000 }, 656 { 0 }, 657 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, 658 { 320000000 }, 659 { 19200000, 75000000, 384000000, 538666667 }, 660 { 384000000 } }, 661 .reg = { "vfe_lite" }, 662 .interrupt = { "vfe_lite" } 663 } 664}; 665 666static const struct resources csiphy_res_8250[] = { 667 /* CSIPHY0 */ 668 { 669 .regulators = {}, 670 .clock = { "csiphy0", "csiphy0_timer" }, 671 .clock_rate = { { 400000000 }, 672 { 300000000 } }, 673 .reg = { "csiphy0" }, 674 .interrupt = { "csiphy0" } 675 }, 676 /* CSIPHY1 */ 677 { 678 .regulators = {}, 679 .clock = { "csiphy1", "csiphy1_timer" }, 680 .clock_rate = { { 400000000 }, 681 { 300000000 } }, 682 .reg = { "csiphy1" }, 683 .interrupt = { "csiphy1" } 684 }, 685 /* CSIPHY2 */ 686 { 687 .regulators = {}, 688 .clock = { "csiphy2", "csiphy2_timer" }, 689 .clock_rate = { { 400000000 }, 690 { 300000000 } }, 691 .reg = { "csiphy2" }, 692 .interrupt = { "csiphy2" } 693 }, 694 /* CSIPHY3 */ 695 { 696 .regulators = {}, 697 .clock = { "csiphy3", "csiphy3_timer" }, 698 .clock_rate = { { 400000000 }, 699 { 300000000 } }, 700 .reg = { "csiphy3" }, 701 .interrupt = { "csiphy3" } 702 }, 703 /* CSIPHY4 */ 704 { 705 .regulators = {}, 706 .clock = { "csiphy4", "csiphy4_timer" }, 707 .clock_rate = { { 400000000 }, 708 { 300000000 } }, 709 .reg = { "csiphy4" }, 710 .interrupt = { "csiphy4" } 711 }, 712 /* CSIPHY5 */ 713 { 714 .regulators = {}, 715 .clock = { "csiphy5", "csiphy5_timer" }, 716 .clock_rate = { { 400000000 }, 717 { 300000000 } }, 718 .reg = { "csiphy5" }, 719 .interrupt = { "csiphy5" } 720 } 721}; 722 723static const struct resources csid_res_8250[] = { 724 /* CSID0 */ 725 { 726 .regulators = { "vdda-phy", "vdda-pll" }, 727 .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_areg", "vfe0_ahb" }, 728 .clock_rate = { { 400000000 }, 729 { 400000000 }, 730 { 350000000, 475000000, 576000000, 720000000 }, 731 { 100000000, 200000000, 300000000, 400000000 }, 732 { 0 } }, 733 .reg = { "csid0" }, 734 .interrupt = { "csid0" } 735 }, 736 /* CSID1 */ 737 { 738 .regulators = { "vdda-phy", "vdda-pll" }, 739 .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_areg", "vfe1_ahb" }, 740 .clock_rate = { { 400000000 }, 741 { 400000000 }, 742 { 350000000, 475000000, 576000000, 720000000 }, 743 { 100000000, 200000000, 300000000, 400000000 }, 744 { 0 } }, 745 .reg = { "csid1" }, 746 .interrupt = { "csid1" } 747 }, 748 /* CSID2 */ 749 { 750 .regulators = { "vdda-phy", "vdda-pll" }, 751 .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite", "vfe_lite_ahb" }, 752 .clock_rate = { { 400000000 }, 753 { 400000000 }, 754 { 400000000, 480000000 }, 755 { 0 } }, 756 .reg = { "csid2" }, 757 .interrupt = { "csid2" } 758 }, 759 /* CSID3 */ 760 { 761 .regulators = { "vdda-phy", "vdda-pll" }, 762 .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite", "vfe_lite_ahb" }, 763 .clock_rate = { { 400000000 }, 764 { 400000000 }, 765 { 400000000, 480000000 }, 766 { 0 } }, 767 .reg = { "csid3" }, 768 .interrupt = { "csid3" } 769 } 770}; 771 772static const struct resources vfe_res_8250[] = { 773 /* VFE0 */ 774 { 775 .regulators = {}, 776 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb", 777 "camnoc_axi", "vfe0_ahb", "vfe0_areg", "vfe0", 778 "vfe0_axi", "cam_hf_axi" }, 779 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 }, 780 { 19200000, 80000000 }, 781 { 19200000 }, 782 { 0 }, 783 { 0 }, 784 { 100000000, 200000000, 300000000, 400000000 }, 785 { 350000000, 475000000, 576000000, 720000000 }, 786 { 0 }, 787 { 0 } }, 788 .reg = { "vfe0" }, 789 .interrupt = { "vfe0" } 790 }, 791 /* VFE1 */ 792 { 793 .regulators = {}, 794 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb", 795 "camnoc_axi", "vfe1_ahb", "vfe1_areg", "vfe1", 796 "vfe1_axi", "cam_hf_axi" }, 797 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 }, 798 { 19200000, 80000000 }, 799 { 19200000 }, 800 { 0 }, 801 { 0 }, 802 { 100000000, 200000000, 300000000, 400000000 }, 803 { 350000000, 475000000, 576000000, 720000000 }, 804 { 0 }, 805 { 0 } }, 806 .reg = { "vfe1" }, 807 .interrupt = { "vfe1" } 808 }, 809 /* VFE2 (lite) */ 810 { 811 .regulators = {}, 812 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb", 813 "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi", 814 "vfe_lite", "cam_hf_axi" }, 815 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 }, 816 { 19200000, 80000000 }, 817 { 19200000 }, 818 { 0 }, 819 { 0 }, 820 { 0 }, 821 { 400000000, 480000000 }, 822 { 0 } }, 823 .reg = { "vfe_lite0" }, 824 .interrupt = { "vfe_lite0" } 825 }, 826 /* VFE3 (lite) */ 827 { 828 .regulators = {}, 829 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb", 830 "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi", 831 "vfe_lite", "cam_hf_axi" }, 832 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 }, 833 { 19200000, 80000000 }, 834 { 19200000 }, 835 { 0 }, 836 { 0 }, 837 { 0 }, 838 { 400000000, 480000000 }, 839 { 0 } }, 840 .reg = { "vfe_lite1" }, 841 .interrupt = { "vfe_lite1" } 842 }, 843}; 844 845static const struct resources_icc icc_res_sm8250[] = { 846 { 847 .name = "cam_ahb", 848 .icc_bw_tbl.avg = 38400, 849 .icc_bw_tbl.peak = 76800, 850 }, 851 { 852 .name = "cam_hf_0_mnoc", 853 .icc_bw_tbl.avg = 2097152, 854 .icc_bw_tbl.peak = 2097152, 855 }, 856 { 857 .name = "cam_sf_0_mnoc", 858 .icc_bw_tbl.avg = 0, 859 .icc_bw_tbl.peak = 2097152, 860 }, 861 { 862 .name = "cam_sf_icp_mnoc", 863 .icc_bw_tbl.avg = 2097152, 864 .icc_bw_tbl.peak = 2097152, 865 }, 866}; 867 868/* 869 * camss_add_clock_margin - Add margin to clock frequency rate 870 * @rate: Clock frequency rate 871 * 872 * When making calculations with physical clock frequency values 873 * some safety margin must be added. Add it. 874 */ 875inline void camss_add_clock_margin(u64 *rate) 876{ 877 *rate *= CAMSS_CLOCK_MARGIN_NUMERATOR; 878 *rate = div_u64(*rate, CAMSS_CLOCK_MARGIN_DENOMINATOR); 879} 880 881/* 882 * camss_enable_clocks - Enable multiple clocks 883 * @nclocks: Number of clocks in clock array 884 * @clock: Clock array 885 * @dev: Device 886 * 887 * Return 0 on success or a negative error code otherwise 888 */ 889int camss_enable_clocks(int nclocks, struct camss_clock *clock, 890 struct device *dev) 891{ 892 int ret; 893 int i; 894 895 for (i = 0; i < nclocks; i++) { 896 ret = clk_prepare_enable(clock[i].clk); 897 if (ret) { 898 dev_err(dev, "clock enable failed: %d\n", ret); 899 goto error; 900 } 901 } 902 903 return 0; 904 905error: 906 for (i--; i >= 0; i--) 907 clk_disable_unprepare(clock[i].clk); 908 909 return ret; 910} 911 912/* 913 * camss_disable_clocks - Disable multiple clocks 914 * @nclocks: Number of clocks in clock array 915 * @clock: Clock array 916 */ 917void camss_disable_clocks(int nclocks, struct camss_clock *clock) 918{ 919 int i; 920 921 for (i = nclocks - 1; i >= 0; i--) 922 clk_disable_unprepare(clock[i].clk); 923} 924 925/* 926 * camss_find_sensor - Find a linked media entity which represents a sensor 927 * @entity: Media entity to start searching from 928 * 929 * Return a pointer to sensor media entity or NULL if not found 930 */ 931struct media_entity *camss_find_sensor(struct media_entity *entity) 932{ 933 struct media_pad *pad; 934 935 while (1) { 936 pad = &entity->pads[0]; 937 if (!(pad->flags & MEDIA_PAD_FL_SINK)) 938 return NULL; 939 940 pad = media_entity_remote_pad(pad); 941 if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) 942 return NULL; 943 944 entity = pad->entity; 945 946 if (entity->function == MEDIA_ENT_F_CAM_SENSOR) 947 return entity; 948 } 949} 950 951/** 952 * camss_get_link_freq - Get link frequency from sensor 953 * @entity: Media entity in the current pipeline 954 * @bpp: Number of bits per pixel for the current format 955 * @lanes: Number of lanes in the link to the sensor 956 * 957 * Return link frequency on success or a negative error code otherwise 958 */ 959s64 camss_get_link_freq(struct media_entity *entity, unsigned int bpp, 960 unsigned int lanes) 961{ 962 struct media_entity *sensor; 963 struct v4l2_subdev *subdev; 964 965 sensor = camss_find_sensor(entity); 966 if (!sensor) 967 return -ENODEV; 968 969 subdev = media_entity_to_v4l2_subdev(sensor); 970 971 return v4l2_get_link_freq(subdev->ctrl_handler, bpp, 2 * lanes); 972} 973 974/* 975 * camss_get_pixel_clock - Get pixel clock rate from sensor 976 * @entity: Media entity in the current pipeline 977 * @pixel_clock: Received pixel clock value 978 * 979 * Return 0 on success or a negative error code otherwise 980 */ 981int camss_get_pixel_clock(struct media_entity *entity, u64 *pixel_clock) 982{ 983 struct media_entity *sensor; 984 struct v4l2_subdev *subdev; 985 struct v4l2_ctrl *ctrl; 986 987 sensor = camss_find_sensor(entity); 988 if (!sensor) 989 return -ENODEV; 990 991 subdev = media_entity_to_v4l2_subdev(sensor); 992 993 ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE); 994 995 if (!ctrl) 996 return -EINVAL; 997 998 *pixel_clock = v4l2_ctrl_g_ctrl_int64(ctrl); 999 1000 return 0; 1001} 1002 1003int camss_pm_domain_on(struct camss *camss, int id) 1004{ 1005 int ret = 0; 1006 1007 if (id < camss->vfe_num) { 1008 struct vfe_device *vfe = &camss->vfe[id]; 1009 1010 ret = vfe->ops->pm_domain_on(vfe); 1011 } 1012 1013 return ret; 1014} 1015 1016void camss_pm_domain_off(struct camss *camss, int id) 1017{ 1018 if (id < camss->vfe_num) { 1019 struct vfe_device *vfe = &camss->vfe[id]; 1020 1021 vfe->ops->pm_domain_off(vfe); 1022 } 1023} 1024 1025/* 1026 * camss_of_parse_endpoint_node - Parse port endpoint node 1027 * @dev: Device 1028 * @node: Device node to be parsed 1029 * @csd: Parsed data from port endpoint node 1030 * 1031 * Return 0 on success or a negative error code on failure 1032 */ 1033static int camss_of_parse_endpoint_node(struct device *dev, 1034 struct device_node *node, 1035 struct camss_async_subdev *csd) 1036{ 1037 struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg; 1038 struct v4l2_mbus_config_mipi_csi2 *mipi_csi2; 1039 struct v4l2_fwnode_endpoint vep = { { 0 } }; 1040 unsigned int i; 1041 1042 v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep); 1043 1044 csd->interface.csiphy_id = vep.base.port; 1045 1046 mipi_csi2 = &vep.bus.mipi_csi2; 1047 lncfg->clk.pos = mipi_csi2->clock_lane; 1048 lncfg->clk.pol = mipi_csi2->lane_polarities[0]; 1049 lncfg->num_data = mipi_csi2->num_data_lanes; 1050 1051 lncfg->data = devm_kcalloc(dev, 1052 lncfg->num_data, sizeof(*lncfg->data), 1053 GFP_KERNEL); 1054 if (!lncfg->data) 1055 return -ENOMEM; 1056 1057 for (i = 0; i < lncfg->num_data; i++) { 1058 lncfg->data[i].pos = mipi_csi2->data_lanes[i]; 1059 lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1]; 1060 } 1061 1062 return 0; 1063} 1064 1065/* 1066 * camss_of_parse_ports - Parse ports node 1067 * @dev: Device 1068 * @notifier: v4l2_device notifier data 1069 * 1070 * Return number of "port" nodes found in "ports" node 1071 */ 1072static int camss_of_parse_ports(struct camss *camss) 1073{ 1074 struct device *dev = camss->dev; 1075 struct device_node *node = NULL; 1076 struct device_node *remote = NULL; 1077 int ret, num_subdevs = 0; 1078 1079 for_each_endpoint_of_node(dev->of_node, node) { 1080 struct camss_async_subdev *csd; 1081 1082 if (!of_device_is_available(node)) 1083 continue; 1084 1085 remote = of_graph_get_remote_port_parent(node); 1086 if (!remote) { 1087 dev_err(dev, "Cannot get remote parent\n"); 1088 ret = -EINVAL; 1089 goto err_cleanup; 1090 } 1091 1092 csd = v4l2_async_nf_add_fwnode(&camss->notifier, 1093 of_fwnode_handle(remote), 1094 struct camss_async_subdev); 1095 of_node_put(remote); 1096 if (IS_ERR(csd)) { 1097 ret = PTR_ERR(csd); 1098 goto err_cleanup; 1099 } 1100 1101 ret = camss_of_parse_endpoint_node(dev, node, csd); 1102 if (ret < 0) 1103 goto err_cleanup; 1104 1105 num_subdevs++; 1106 } 1107 1108 return num_subdevs; 1109 1110err_cleanup: 1111 of_node_put(node); 1112 return ret; 1113} 1114 1115/* 1116 * camss_init_subdevices - Initialize subdev structures and resources 1117 * @camss: CAMSS device 1118 * 1119 * Return 0 on success or a negative error code on failure 1120 */ 1121static int camss_init_subdevices(struct camss *camss) 1122{ 1123 const struct resources *csiphy_res; 1124 const struct resources *csid_res; 1125 const struct resources_ispif *ispif_res; 1126 const struct resources *vfe_res; 1127 unsigned int i; 1128 int ret; 1129 1130 if (camss->version == CAMSS_8x16) { 1131 csiphy_res = csiphy_res_8x16; 1132 csid_res = csid_res_8x16; 1133 ispif_res = &ispif_res_8x16; 1134 vfe_res = vfe_res_8x16; 1135 } else if (camss->version == CAMSS_8x96) { 1136 csiphy_res = csiphy_res_8x96; 1137 csid_res = csid_res_8x96; 1138 ispif_res = &ispif_res_8x96; 1139 vfe_res = vfe_res_8x96; 1140 } else if (camss->version == CAMSS_660) { 1141 csiphy_res = csiphy_res_660; 1142 csid_res = csid_res_660; 1143 ispif_res = &ispif_res_660; 1144 vfe_res = vfe_res_660; 1145 } else if (camss->version == CAMSS_845) { 1146 csiphy_res = csiphy_res_845; 1147 csid_res = csid_res_845; 1148 /* Titan VFEs don't have an ISPIF */ 1149 ispif_res = NULL; 1150 vfe_res = vfe_res_845; 1151 } else if (camss->version == CAMSS_8250) { 1152 csiphy_res = csiphy_res_8250; 1153 csid_res = csid_res_8250; 1154 /* Titan VFEs don't have an ISPIF */ 1155 ispif_res = NULL; 1156 vfe_res = vfe_res_8250; 1157 } else { 1158 return -EINVAL; 1159 } 1160 1161 for (i = 0; i < camss->csiphy_num; i++) { 1162 ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i], 1163 &csiphy_res[i], i); 1164 if (ret < 0) { 1165 dev_err(camss->dev, 1166 "Failed to init csiphy%d sub-device: %d\n", 1167 i, ret); 1168 return ret; 1169 } 1170 } 1171 1172 /* note: SM8250 requires VFE to be initialized before CSID */ 1173 for (i = 0; i < camss->vfe_num; i++) { 1174 ret = msm_vfe_subdev_init(camss, &camss->vfe[i], 1175 &vfe_res[i], i); 1176 if (ret < 0) { 1177 dev_err(camss->dev, 1178 "Fail to init vfe%d sub-device: %d\n", i, ret); 1179 return ret; 1180 } 1181 } 1182 1183 for (i = 0; i < camss->csid_num; i++) { 1184 ret = msm_csid_subdev_init(camss, &camss->csid[i], 1185 &csid_res[i], i); 1186 if (ret < 0) { 1187 dev_err(camss->dev, 1188 "Failed to init csid%d sub-device: %d\n", 1189 i, ret); 1190 return ret; 1191 } 1192 } 1193 1194 ret = msm_ispif_subdev_init(camss, ispif_res); 1195 if (ret < 0) { 1196 dev_err(camss->dev, "Failed to init ispif sub-device: %d\n", 1197 ret); 1198 return ret; 1199 } 1200 1201 return 0; 1202} 1203 1204/* 1205 * camss_register_entities - Register subdev nodes and create links 1206 * @camss: CAMSS device 1207 * 1208 * Return 0 on success or a negative error code on failure 1209 */ 1210static int camss_register_entities(struct camss *camss) 1211{ 1212 int i, j, k; 1213 int ret; 1214 1215 for (i = 0; i < camss->csiphy_num; i++) { 1216 ret = msm_csiphy_register_entity(&camss->csiphy[i], 1217 &camss->v4l2_dev); 1218 if (ret < 0) { 1219 dev_err(camss->dev, 1220 "Failed to register csiphy%d entity: %d\n", 1221 i, ret); 1222 goto err_reg_csiphy; 1223 } 1224 } 1225 1226 for (i = 0; i < camss->csid_num; i++) { 1227 ret = msm_csid_register_entity(&camss->csid[i], 1228 &camss->v4l2_dev); 1229 if (ret < 0) { 1230 dev_err(camss->dev, 1231 "Failed to register csid%d entity: %d\n", 1232 i, ret); 1233 goto err_reg_csid; 1234 } 1235 } 1236 1237 ret = msm_ispif_register_entities(camss->ispif, 1238 &camss->v4l2_dev); 1239 if (ret < 0) { 1240 dev_err(camss->dev, "Failed to register ispif entities: %d\n", 1241 ret); 1242 goto err_reg_ispif; 1243 } 1244 1245 for (i = 0; i < camss->vfe_num; i++) { 1246 ret = msm_vfe_register_entities(&camss->vfe[i], 1247 &camss->v4l2_dev); 1248 if (ret < 0) { 1249 dev_err(camss->dev, 1250 "Failed to register vfe%d entities: %d\n", 1251 i, ret); 1252 goto err_reg_vfe; 1253 } 1254 } 1255 1256 for (i = 0; i < camss->csiphy_num; i++) { 1257 for (j = 0; j < camss->csid_num; j++) { 1258 ret = media_create_pad_link( 1259 &camss->csiphy[i].subdev.entity, 1260 MSM_CSIPHY_PAD_SRC, 1261 &camss->csid[j].subdev.entity, 1262 MSM_CSID_PAD_SINK, 1263 0); 1264 if (ret < 0) { 1265 dev_err(camss->dev, 1266 "Failed to link %s->%s entities: %d\n", 1267 camss->csiphy[i].subdev.entity.name, 1268 camss->csid[j].subdev.entity.name, 1269 ret); 1270 goto err_link; 1271 } 1272 } 1273 } 1274 1275 if (camss->ispif) { 1276 for (i = 0; i < camss->csid_num; i++) { 1277 for (j = 0; j < camss->ispif->line_num; j++) { 1278 ret = media_create_pad_link( 1279 &camss->csid[i].subdev.entity, 1280 MSM_CSID_PAD_SRC, 1281 &camss->ispif->line[j].subdev.entity, 1282 MSM_ISPIF_PAD_SINK, 1283 0); 1284 if (ret < 0) { 1285 dev_err(camss->dev, 1286 "Failed to link %s->%s entities: %d\n", 1287 camss->csid[i].subdev.entity.name, 1288 camss->ispif->line[j].subdev.entity.name, 1289 ret); 1290 goto err_link; 1291 } 1292 } 1293 } 1294 1295 for (i = 0; i < camss->ispif->line_num; i++) 1296 for (k = 0; k < camss->vfe_num; k++) 1297 for (j = 0; j < camss->vfe[k].line_num; j++) { 1298 struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev; 1299 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; 1300 1301 ret = media_create_pad_link(&ispif->entity, 1302 MSM_ISPIF_PAD_SRC, 1303 &vfe->entity, 1304 MSM_VFE_PAD_SINK, 1305 0); 1306 if (ret < 0) { 1307 dev_err(camss->dev, 1308 "Failed to link %s->%s entities: %d\n", 1309 ispif->entity.name, 1310 vfe->entity.name, 1311 ret); 1312 goto err_link; 1313 } 1314 } 1315 } else { 1316 for (i = 0; i < camss->csid_num; i++) 1317 for (k = 0; k < camss->vfe_num; k++) 1318 for (j = 0; j < camss->vfe[k].line_num; j++) { 1319 struct v4l2_subdev *csid = &camss->csid[i].subdev; 1320 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; 1321 1322 ret = media_create_pad_link(&csid->entity, 1323 MSM_CSID_PAD_SRC, 1324 &vfe->entity, 1325 MSM_VFE_PAD_SINK, 1326 0); 1327 if (ret < 0) { 1328 dev_err(camss->dev, 1329 "Failed to link %s->%s entities: %d\n", 1330 csid->entity.name, 1331 vfe->entity.name, 1332 ret); 1333 goto err_link; 1334 } 1335 } 1336 } 1337 1338 return 0; 1339 1340err_link: 1341 i = camss->vfe_num; 1342err_reg_vfe: 1343 for (i--; i >= 0; i--) 1344 msm_vfe_unregister_entities(&camss->vfe[i]); 1345 1346err_reg_ispif: 1347 msm_ispif_unregister_entities(camss->ispif); 1348 1349 i = camss->csid_num; 1350err_reg_csid: 1351 for (i--; i >= 0; i--) 1352 msm_csid_unregister_entity(&camss->csid[i]); 1353 1354 i = camss->csiphy_num; 1355err_reg_csiphy: 1356 for (i--; i >= 0; i--) 1357 msm_csiphy_unregister_entity(&camss->csiphy[i]); 1358 1359 return ret; 1360} 1361 1362/* 1363 * camss_unregister_entities - Unregister subdev nodes 1364 * @camss: CAMSS device 1365 * 1366 * Return 0 on success or a negative error code on failure 1367 */ 1368static void camss_unregister_entities(struct camss *camss) 1369{ 1370 unsigned int i; 1371 1372 for (i = 0; i < camss->csiphy_num; i++) 1373 msm_csiphy_unregister_entity(&camss->csiphy[i]); 1374 1375 for (i = 0; i < camss->csid_num; i++) 1376 msm_csid_unregister_entity(&camss->csid[i]); 1377 1378 msm_ispif_unregister_entities(camss->ispif); 1379 1380 for (i = 0; i < camss->vfe_num; i++) 1381 msm_vfe_unregister_entities(&camss->vfe[i]); 1382} 1383 1384static int camss_subdev_notifier_bound(struct v4l2_async_notifier *async, 1385 struct v4l2_subdev *subdev, 1386 struct v4l2_async_subdev *asd) 1387{ 1388 struct camss *camss = container_of(async, struct camss, notifier); 1389 struct camss_async_subdev *csd = 1390 container_of(asd, struct camss_async_subdev, asd); 1391 u8 id = csd->interface.csiphy_id; 1392 struct csiphy_device *csiphy = &camss->csiphy[id]; 1393 1394 csiphy->cfg.csi2 = &csd->interface.csi2; 1395 subdev->host_priv = csiphy; 1396 1397 return 0; 1398} 1399 1400static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async) 1401{ 1402 struct camss *camss = container_of(async, struct camss, notifier); 1403 struct v4l2_device *v4l2_dev = &camss->v4l2_dev; 1404 struct v4l2_subdev *sd; 1405 int ret; 1406 1407 list_for_each_entry(sd, &v4l2_dev->subdevs, list) { 1408 if (sd->host_priv) { 1409 struct media_entity *sensor = &sd->entity; 1410 struct csiphy_device *csiphy = 1411 (struct csiphy_device *) sd->host_priv; 1412 struct media_entity *input = &csiphy->subdev.entity; 1413 unsigned int i; 1414 1415 for (i = 0; i < sensor->num_pads; i++) { 1416 if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE) 1417 break; 1418 } 1419 if (i == sensor->num_pads) { 1420 dev_err(camss->dev, 1421 "No source pad in external entity\n"); 1422 return -EINVAL; 1423 } 1424 1425 ret = media_create_pad_link(sensor, i, 1426 input, MSM_CSIPHY_PAD_SINK, 1427 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); 1428 if (ret < 0) { 1429 dev_err(camss->dev, 1430 "Failed to link %s->%s entities: %d\n", 1431 sensor->name, input->name, ret); 1432 return ret; 1433 } 1434 } 1435 } 1436 1437 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); 1438 if (ret < 0) 1439 return ret; 1440 1441 return media_device_register(&camss->media_dev); 1442} 1443 1444static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = { 1445 .bound = camss_subdev_notifier_bound, 1446 .complete = camss_subdev_notifier_complete, 1447}; 1448 1449static const struct media_device_ops camss_media_ops = { 1450 .link_notify = v4l2_pipeline_link_notify, 1451}; 1452 1453static int camss_configure_pd(struct camss *camss) 1454{ 1455 int nbr_pm_domains = 0; 1456 int last_pm_domain = 0; 1457 int i; 1458 int ret; 1459 1460 if (camss->version == CAMSS_8x96 || 1461 camss->version == CAMSS_660) 1462 nbr_pm_domains = PM_DOMAIN_GEN1_COUNT; 1463 else if (camss->version == CAMSS_845 || 1464 camss->version == CAMSS_8250) 1465 nbr_pm_domains = PM_DOMAIN_GEN2_COUNT; 1466 1467 for (i = 0; i < nbr_pm_domains; i++) { 1468 camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i); 1469 if (IS_ERR(camss->genpd[i])) { 1470 ret = PTR_ERR(camss->genpd[i]); 1471 goto fail_pm; 1472 } 1473 1474 camss->genpd_link[i] = device_link_add(camss->dev, camss->genpd[i], 1475 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | 1476 DL_FLAG_RPM_ACTIVE); 1477 if (!camss->genpd_link[i]) { 1478 dev_pm_domain_detach(camss->genpd[i], true); 1479 ret = -EINVAL; 1480 goto fail_pm; 1481 } 1482 1483 last_pm_domain = i; 1484 } 1485 1486 return 0; 1487 1488fail_pm: 1489 for (i = 0; i < last_pm_domain; i++) { 1490 device_link_del(camss->genpd_link[i]); 1491 dev_pm_domain_detach(camss->genpd[i], true); 1492 } 1493 1494 return ret; 1495} 1496 1497static int camss_icc_get(struct camss *camss) 1498{ 1499 const struct resources_icc *icc_res; 1500 int nbr_icc_paths = 0; 1501 int i; 1502 1503 if (camss->version == CAMSS_8250) { 1504 icc_res = &icc_res_sm8250[0]; 1505 nbr_icc_paths = ICC_SM8250_COUNT; 1506 } 1507 1508 for (i = 0; i < nbr_icc_paths; i++) { 1509 camss->icc_path[i] = devm_of_icc_get(camss->dev, 1510 icc_res[i].name); 1511 if (IS_ERR(camss->icc_path[i])) 1512 return PTR_ERR(camss->icc_path[i]); 1513 1514 camss->icc_bw_tbl[i] = icc_res[i].icc_bw_tbl; 1515 } 1516 1517 return 0; 1518} 1519 1520/* 1521 * camss_probe - Probe CAMSS platform device 1522 * @pdev: Pointer to CAMSS platform device 1523 * 1524 * Return 0 on success or a negative error code on failure 1525 */ 1526static int camss_probe(struct platform_device *pdev) 1527{ 1528 struct device *dev = &pdev->dev; 1529 struct camss *camss; 1530 int num_subdevs, ret; 1531 1532 camss = kzalloc(sizeof(*camss), GFP_KERNEL); 1533 if (!camss) 1534 return -ENOMEM; 1535 1536 atomic_set(&camss->ref_count, 0); 1537 camss->dev = dev; 1538 platform_set_drvdata(pdev, camss); 1539 1540 if (of_device_is_compatible(dev->of_node, "qcom,msm8916-camss")) { 1541 camss->version = CAMSS_8x16; 1542 camss->csiphy_num = 2; 1543 camss->csid_num = 2; 1544 camss->vfe_num = 1; 1545 } else if (of_device_is_compatible(dev->of_node, 1546 "qcom,msm8996-camss")) { 1547 camss->version = CAMSS_8x96; 1548 camss->csiphy_num = 3; 1549 camss->csid_num = 4; 1550 camss->vfe_num = 2; 1551 } else if (of_device_is_compatible(dev->of_node, 1552 "qcom,sdm660-camss")) { 1553 camss->version = CAMSS_660; 1554 camss->csiphy_num = 3; 1555 camss->csid_num = 4; 1556 camss->vfe_num = 2; 1557 } else if (of_device_is_compatible(dev->of_node, 1558 "qcom,sdm845-camss")) { 1559 camss->version = CAMSS_845; 1560 camss->csiphy_num = 4; 1561 camss->csid_num = 3; 1562 camss->vfe_num = 3; 1563 } else if (of_device_is_compatible(dev->of_node, 1564 "qcom,sm8250-camss")) { 1565 camss->version = CAMSS_8250; 1566 camss->csiphy_num = 6; 1567 camss->csid_num = 4; 1568 camss->vfe_num = 4; 1569 } else { 1570 ret = -EINVAL; 1571 goto err_free; 1572 } 1573 1574 camss->csiphy = devm_kcalloc(dev, camss->csiphy_num, 1575 sizeof(*camss->csiphy), GFP_KERNEL); 1576 if (!camss->csiphy) { 1577 ret = -ENOMEM; 1578 goto err_free; 1579 } 1580 1581 camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid), 1582 GFP_KERNEL); 1583 if (!camss->csid) { 1584 ret = -ENOMEM; 1585 goto err_free; 1586 } 1587 1588 if (camss->version == CAMSS_8x16 || 1589 camss->version == CAMSS_8x96) { 1590 camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL); 1591 if (!camss->ispif) { 1592 ret = -ENOMEM; 1593 goto err_free; 1594 } 1595 } 1596 1597 camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe), 1598 GFP_KERNEL); 1599 if (!camss->vfe) { 1600 ret = -ENOMEM; 1601 goto err_free; 1602 } 1603 1604 v4l2_async_nf_init(&camss->notifier); 1605 1606 num_subdevs = camss_of_parse_ports(camss); 1607 if (num_subdevs < 0) { 1608 ret = num_subdevs; 1609 goto err_cleanup; 1610 } 1611 1612 ret = camss_icc_get(camss); 1613 if (ret < 0) 1614 goto err_cleanup; 1615 1616 ret = camss_init_subdevices(camss); 1617 if (ret < 0) 1618 goto err_cleanup; 1619 1620 ret = dma_set_mask_and_coherent(dev, 0xffffffff); 1621 if (ret) 1622 goto err_cleanup; 1623 1624 camss->media_dev.dev = camss->dev; 1625 strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem", 1626 sizeof(camss->media_dev.model)); 1627 camss->media_dev.ops = &camss_media_ops; 1628 media_device_init(&camss->media_dev); 1629 1630 camss->v4l2_dev.mdev = &camss->media_dev; 1631 ret = v4l2_device_register(camss->dev, &camss->v4l2_dev); 1632 if (ret < 0) { 1633 dev_err(dev, "Failed to register V4L2 device: %d\n", ret); 1634 goto err_cleanup; 1635 } 1636 1637 ret = camss_register_entities(camss); 1638 if (ret < 0) 1639 goto err_register_entities; 1640 1641 if (num_subdevs) { 1642 camss->notifier.ops = &camss_subdev_notifier_ops; 1643 1644 ret = v4l2_async_nf_register(&camss->v4l2_dev, 1645 &camss->notifier); 1646 if (ret) { 1647 dev_err(dev, 1648 "Failed to register async subdev nodes: %d\n", 1649 ret); 1650 goto err_register_subdevs; 1651 } 1652 } else { 1653 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); 1654 if (ret < 0) { 1655 dev_err(dev, "Failed to register subdev nodes: %d\n", 1656 ret); 1657 goto err_register_subdevs; 1658 } 1659 1660 ret = media_device_register(&camss->media_dev); 1661 if (ret < 0) { 1662 dev_err(dev, "Failed to register media device: %d\n", 1663 ret); 1664 goto err_register_subdevs; 1665 } 1666 } 1667 1668 ret = camss_configure_pd(camss); 1669 if (ret < 0) { 1670 dev_err(dev, "Failed to configure power domains: %d\n", ret); 1671 return ret; 1672 } 1673 1674 pm_runtime_enable(dev); 1675 1676 return 0; 1677 1678err_register_subdevs: 1679 camss_unregister_entities(camss); 1680err_register_entities: 1681 v4l2_device_unregister(&camss->v4l2_dev); 1682err_cleanup: 1683 v4l2_async_nf_cleanup(&camss->notifier); 1684err_free: 1685 kfree(camss); 1686 1687 return ret; 1688} 1689 1690void camss_delete(struct camss *camss) 1691{ 1692 int nbr_pm_domains = 0; 1693 int i; 1694 1695 v4l2_device_unregister(&camss->v4l2_dev); 1696 media_device_unregister(&camss->media_dev); 1697 media_device_cleanup(&camss->media_dev); 1698 1699 pm_runtime_disable(camss->dev); 1700 1701 if (camss->version == CAMSS_8x96 || 1702 camss->version == CAMSS_660) 1703 nbr_pm_domains = PM_DOMAIN_GEN1_COUNT; 1704 else if (camss->version == CAMSS_845 || 1705 camss->version == CAMSS_8250) 1706 nbr_pm_domains = PM_DOMAIN_GEN2_COUNT; 1707 1708 for (i = 0; i < nbr_pm_domains; i++) { 1709 device_link_del(camss->genpd_link[i]); 1710 dev_pm_domain_detach(camss->genpd[i], true); 1711 } 1712 1713 kfree(camss); 1714} 1715 1716/* 1717 * camss_remove - Remove CAMSS platform device 1718 * @pdev: Pointer to CAMSS platform device 1719 * 1720 * Always returns 0. 1721 */ 1722static int camss_remove(struct platform_device *pdev) 1723{ 1724 struct camss *camss = platform_get_drvdata(pdev); 1725 1726 v4l2_async_nf_unregister(&camss->notifier); 1727 v4l2_async_nf_cleanup(&camss->notifier); 1728 camss_unregister_entities(camss); 1729 1730 if (atomic_read(&camss->ref_count) == 0) 1731 camss_delete(camss); 1732 1733 return 0; 1734} 1735 1736static const struct of_device_id camss_dt_match[] = { 1737 { .compatible = "qcom,msm8916-camss" }, 1738 { .compatible = "qcom,msm8996-camss" }, 1739 { .compatible = "qcom,sdm660-camss" }, 1740 { .compatible = "qcom,sdm845-camss" }, 1741 { .compatible = "qcom,sm8250-camss" }, 1742 { } 1743}; 1744 1745MODULE_DEVICE_TABLE(of, camss_dt_match); 1746 1747static int __maybe_unused camss_runtime_suspend(struct device *dev) 1748{ 1749 struct camss *camss = dev_get_drvdata(dev); 1750 int nbr_icc_paths = 0; 1751 int i; 1752 int ret; 1753 1754 if (camss->version == CAMSS_8250) 1755 nbr_icc_paths = ICC_SM8250_COUNT; 1756 1757 for (i = 0; i < nbr_icc_paths; i++) { 1758 ret = icc_set_bw(camss->icc_path[i], 0, 0); 1759 if (ret) 1760 return ret; 1761 } 1762 1763 return 0; 1764} 1765 1766static int __maybe_unused camss_runtime_resume(struct device *dev) 1767{ 1768 struct camss *camss = dev_get_drvdata(dev); 1769 int nbr_icc_paths = 0; 1770 int i; 1771 int ret; 1772 1773 if (camss->version == CAMSS_8250) 1774 nbr_icc_paths = ICC_SM8250_COUNT; 1775 1776 for (i = 0; i < nbr_icc_paths; i++) { 1777 ret = icc_set_bw(camss->icc_path[i], 1778 camss->icc_bw_tbl[i].avg, 1779 camss->icc_bw_tbl[i].peak); 1780 if (ret) 1781 return ret; 1782 } 1783 1784 return 0; 1785} 1786 1787static const struct dev_pm_ops camss_pm_ops = { 1788 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1789 pm_runtime_force_resume) 1790 SET_RUNTIME_PM_OPS(camss_runtime_suspend, camss_runtime_resume, NULL) 1791}; 1792 1793static struct platform_driver qcom_camss_driver = { 1794 .probe = camss_probe, 1795 .remove = camss_remove, 1796 .driver = { 1797 .name = "qcom-camss", 1798 .of_match_table = camss_dt_match, 1799 .pm = &camss_pm_ops, 1800 }, 1801}; 1802 1803module_platform_driver(qcom_camss_driver); 1804 1805MODULE_ALIAS("platform:qcom-camss"); 1806MODULE_DESCRIPTION("Qualcomm Camera Subsystem driver"); 1807MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>"); 1808MODULE_LICENSE("GPL v2");