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_device.h> 18 #include <linux/of_graph.h> 19 #include <linux/pm_runtime.h> 20 #include <linux/pm_domain.h> 21 #include <linux/slab.h> 22 #include <linux/videodev2.h> 23 24 #include <media/media-device.h> 25 #include <media/v4l2-async.h> 26 #include <media/v4l2-device.h> 27 #include <media/v4l2-mc.h> 28 #include <media/v4l2-fwnode.h> 29 30 #include "camss.h" 31 32 #define CAMSS_CLOCK_MARGIN_NUMERATOR 105 33 #define CAMSS_CLOCK_MARGIN_DENOMINATOR 100 34 35 static const struct parent_dev_ops vfe_parent_dev_ops; 36 37 static const struct camss_subdev_resources csiphy_res_8x16[] = { 38 /* CSIPHY0 */ 39 { 40 .regulators = {}, 41 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" }, 42 .clock_rate = { { 0 }, 43 { 0 }, 44 { 0 }, 45 { 100000000, 200000000 } }, 46 .reg = { "csiphy0", "csiphy0_clk_mux" }, 47 .interrupt = { "csiphy0" }, 48 .csiphy = { 49 .hw_ops = &csiphy_ops_2ph_1_0, 50 .formats = &csiphy_formats_8x16 51 } 52 }, 53 54 /* CSIPHY1 */ 55 { 56 .regulators = {}, 57 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" }, 58 .clock_rate = { { 0 }, 59 { 0 }, 60 { 0 }, 61 { 100000000, 200000000 } }, 62 .reg = { "csiphy1", "csiphy1_clk_mux" }, 63 .interrupt = { "csiphy1" }, 64 .csiphy = { 65 .hw_ops = &csiphy_ops_2ph_1_0, 66 .formats = &csiphy_formats_8x16 67 } 68 } 69 }; 70 71 static const struct camss_subdev_resources csid_res_8x16[] = { 72 /* CSID0 */ 73 { 74 .regulators = { "vdda" }, 75 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", 76 "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, 77 .clock_rate = { { 0 }, 78 { 0 }, 79 { 0 }, 80 { 0 }, 81 { 100000000, 200000000 }, 82 { 0 }, 83 { 0 }, 84 { 0 } }, 85 .reg = { "csid0" }, 86 .interrupt = { "csid0" }, 87 .csid = { 88 .hw_ops = &csid_ops_4_1, 89 .parent_dev_ops = &vfe_parent_dev_ops, 90 .formats = &csid_formats_4_1 91 } 92 }, 93 94 /* CSID1 */ 95 { 96 .regulators = { "vdda" }, 97 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", 98 "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, 99 .clock_rate = { { 0 }, 100 { 0 }, 101 { 0 }, 102 { 0 }, 103 { 100000000, 200000000 }, 104 { 0 }, 105 { 0 }, 106 { 0 } }, 107 .reg = { "csid1" }, 108 .interrupt = { "csid1" }, 109 .csid = { 110 .hw_ops = &csid_ops_4_1, 111 .parent_dev_ops = &vfe_parent_dev_ops, 112 .formats = &csid_formats_4_1 113 } 114 }, 115 }; 116 117 static const struct camss_subdev_resources ispif_res_8x16 = { 118 /* ISPIF */ 119 .clock = { "top_ahb", "ahb", "ispif_ahb", 120 "csi0", "csi0_pix", "csi0_rdi", 121 "csi1", "csi1_pix", "csi1_rdi" }, 122 .clock_for_reset = { "vfe0", "csi_vfe0" }, 123 .reg = { "ispif", "csi_clk_mux" }, 124 .interrupt = { "ispif" }, 125 }; 126 127 static const struct camss_subdev_resources vfe_res_8x16[] = { 128 /* VFE0 */ 129 { 130 .regulators = {}, 131 .clock = { "top_ahb", "vfe0", "csi_vfe0", 132 "vfe_ahb", "vfe_axi", "ahb" }, 133 .clock_rate = { { 0 }, 134 { 50000000, 80000000, 100000000, 160000000, 135 177780000, 200000000, 266670000, 320000000, 136 400000000, 465000000 }, 137 { 0 }, 138 { 0 }, 139 { 0 }, 140 { 0 }, 141 { 0 }, 142 { 0 }, 143 { 0 } }, 144 .reg = { "vfe0" }, 145 .interrupt = { "vfe0" }, 146 .vfe = { 147 .line_num = 3, 148 .hw_ops = &vfe_ops_4_1, 149 .formats_rdi = &vfe_formats_rdi_8x16, 150 .formats_pix = &vfe_formats_pix_8x16 151 } 152 } 153 }; 154 155 static const struct camss_subdev_resources csid_res_8x53[] = { 156 /* CSID0 */ 157 { 158 .regulators = { "vdda" }, 159 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", 160 "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, 161 .clock_rate = { { 0 }, 162 { 0 }, 163 { 0 }, 164 { 0 }, 165 { 100000000, 200000000, 310000000, 166 400000000, 465000000 }, 167 { 0 }, 168 { 0 }, 169 { 0 } }, 170 .reg = { "csid0" }, 171 .interrupt = { "csid0" }, 172 .csid = { 173 .hw_ops = &csid_ops_4_7, 174 .parent_dev_ops = &vfe_parent_dev_ops, 175 .formats = &csid_formats_4_7 176 } 177 }, 178 179 /* CSID1 */ 180 { 181 .regulators = { "vdda" }, 182 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", 183 "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, 184 .clock_rate = { { 0 }, 185 { 0 }, 186 { 0 }, 187 { 0 }, 188 { 100000000, 200000000, 310000000, 189 400000000, 465000000 }, 190 { 0 }, 191 { 0 }, 192 { 0 } }, 193 .reg = { "csid1" }, 194 .interrupt = { "csid1" }, 195 .csid = { 196 .hw_ops = &csid_ops_4_7, 197 .parent_dev_ops = &vfe_parent_dev_ops, 198 .formats = &csid_formats_4_7 199 } 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, 310000000, 212 400000000, 465000000 }, 213 { 0 }, 214 { 0 }, 215 { 0 } }, 216 .reg = { "csid2" }, 217 .interrupt = { "csid2" }, 218 .csid = { 219 .hw_ops = &csid_ops_4_7, 220 .parent_dev_ops = &vfe_parent_dev_ops, 221 .formats = &csid_formats_4_7 222 } 223 }, 224 }; 225 226 static const struct camss_subdev_resources ispif_res_8x53 = { 227 /* ISPIF */ 228 .clock = { "top_ahb", "ahb", "ispif_ahb", 229 "csi0", "csi0_pix", "csi0_rdi", 230 "csi1", "csi1_pix", "csi1_rdi", 231 "csi2", "csi2_pix", "csi2_rdi" }, 232 .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" }, 233 .reg = { "ispif", "csi_clk_mux" }, 234 .interrupt = { "ispif" }, 235 }; 236 237 static const struct camss_subdev_resources vfe_res_8x53[] = { 238 /* VFE0 */ 239 { 240 .regulators = {}, 241 .clock = { "top_ahb", "ahb", "ispif_ahb", 242 "vfe0", "csi_vfe0", "vfe0_ahb", "vfe0_axi" }, 243 .clock_rate = { { 0 }, 244 { 0 }, 245 { 0 }, 246 { 50000000, 100000000, 133330000, 247 160000000, 200000000, 266670000, 248 310000000, 400000000, 465000000 }, 249 { 0 }, 250 { 0 }, 251 { 0 } }, 252 .reg = { "vfe0" }, 253 .interrupt = { "vfe0" }, 254 .vfe = { 255 .line_num = 3, 256 .has_pd = true, 257 .pd_name = "vfe0", 258 .hw_ops = &vfe_ops_4_1, 259 .formats_rdi = &vfe_formats_rdi_8x16, 260 .formats_pix = &vfe_formats_pix_8x16 261 } 262 }, 263 264 /* VFE1 */ 265 { 266 .regulators = {}, 267 .clock = { "top_ahb", "ahb", "ispif_ahb", 268 "vfe1", "csi_vfe1", "vfe1_ahb", "vfe1_axi" }, 269 .clock_rate = { { 0 }, 270 { 0 }, 271 { 0 }, 272 { 50000000, 100000000, 133330000, 273 160000000, 200000000, 266670000, 274 310000000, 400000000, 465000000 }, 275 { 0 }, 276 { 0 }, 277 { 0 } }, 278 .reg = { "vfe1" }, 279 .interrupt = { "vfe1" }, 280 .vfe = { 281 .line_num = 3, 282 .has_pd = true, 283 .pd_name = "vfe1", 284 .hw_ops = &vfe_ops_4_1, 285 .formats_rdi = &vfe_formats_rdi_8x16, 286 .formats_pix = &vfe_formats_pix_8x16 287 } 288 } 289 }; 290 291 static const struct resources_icc icc_res_8x53[] = { 292 { 293 .name = "cam_ahb", 294 .icc_bw_tbl.avg = 38400, 295 .icc_bw_tbl.peak = 76800, 296 }, 297 { 298 .name = "cam_vfe0_mem", 299 .icc_bw_tbl.avg = 939524, 300 .icc_bw_tbl.peak = 1342177, 301 }, 302 { 303 .name = "cam_vfe1_mem", 304 .icc_bw_tbl.avg = 939524, 305 .icc_bw_tbl.peak = 1342177, 306 }, 307 }; 308 309 static const struct camss_subdev_resources csiphy_res_8x96[] = { 310 /* CSIPHY0 */ 311 { 312 .regulators = {}, 313 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" }, 314 .clock_rate = { { 0 }, 315 { 0 }, 316 { 0 }, 317 { 100000000, 200000000, 266666667 } }, 318 .reg = { "csiphy0", "csiphy0_clk_mux" }, 319 .interrupt = { "csiphy0" }, 320 .csiphy = { 321 .hw_ops = &csiphy_ops_3ph_1_0, 322 .formats = &csiphy_formats_8x96 323 } 324 }, 325 326 /* CSIPHY1 */ 327 { 328 .regulators = {}, 329 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" }, 330 .clock_rate = { { 0 }, 331 { 0 }, 332 { 0 }, 333 { 100000000, 200000000, 266666667 } }, 334 .reg = { "csiphy1", "csiphy1_clk_mux" }, 335 .interrupt = { "csiphy1" }, 336 .csiphy = { 337 .hw_ops = &csiphy_ops_3ph_1_0, 338 .formats = &csiphy_formats_8x96 339 } 340 }, 341 342 /* CSIPHY2 */ 343 { 344 .regulators = {}, 345 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer" }, 346 .clock_rate = { { 0 }, 347 { 0 }, 348 { 0 }, 349 { 100000000, 200000000, 266666667 } }, 350 .reg = { "csiphy2", "csiphy2_clk_mux" }, 351 .interrupt = { "csiphy2" }, 352 .csiphy = { 353 .hw_ops = &csiphy_ops_3ph_1_0, 354 .formats = &csiphy_formats_8x96 355 } 356 } 357 }; 358 359 static const struct camss_subdev_resources csid_res_8x96[] = { 360 /* CSID0 */ 361 { 362 .regulators = { "vdda" }, 363 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", 364 "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, 365 .clock_rate = { { 0 }, 366 { 0 }, 367 { 0 }, 368 { 0 }, 369 { 100000000, 200000000, 266666667 }, 370 { 0 }, 371 { 0 }, 372 { 0 } }, 373 .reg = { "csid0" }, 374 .interrupt = { "csid0" }, 375 .csid = { 376 .hw_ops = &csid_ops_4_7, 377 .parent_dev_ops = &vfe_parent_dev_ops, 378 .formats = &csid_formats_4_7 379 } 380 }, 381 382 /* CSID1 */ 383 { 384 .regulators = { "vdda" }, 385 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", 386 "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, 387 .clock_rate = { { 0 }, 388 { 0 }, 389 { 0 }, 390 { 0 }, 391 { 100000000, 200000000, 266666667 }, 392 { 0 }, 393 { 0 }, 394 { 0 } }, 395 .reg = { "csid1" }, 396 .interrupt = { "csid1" }, 397 .csid = { 398 .hw_ops = &csid_ops_4_7, 399 .parent_dev_ops = &vfe_parent_dev_ops, 400 .formats = &csid_formats_4_7 401 } 402 }, 403 404 /* CSID2 */ 405 { 406 .regulators = { "vdda" }, 407 .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb", 408 "csi2", "csi2_phy", "csi2_pix", "csi2_rdi" }, 409 .clock_rate = { { 0 }, 410 { 0 }, 411 { 0 }, 412 { 0 }, 413 { 100000000, 200000000, 266666667 }, 414 { 0 }, 415 { 0 }, 416 { 0 } }, 417 .reg = { "csid2" }, 418 .interrupt = { "csid2" }, 419 .csid = { 420 .hw_ops = &csid_ops_4_7, 421 .parent_dev_ops = &vfe_parent_dev_ops, 422 .formats = &csid_formats_4_7 423 } 424 }, 425 426 /* CSID3 */ 427 { 428 .regulators = { "vdda" }, 429 .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb", 430 "csi3", "csi3_phy", "csi3_pix", "csi3_rdi" }, 431 .clock_rate = { { 0 }, 432 { 0 }, 433 { 0 }, 434 { 0 }, 435 { 100000000, 200000000, 266666667 }, 436 { 0 }, 437 { 0 }, 438 { 0 } }, 439 .reg = { "csid3" }, 440 .interrupt = { "csid3" }, 441 .csid = { 442 .hw_ops = &csid_ops_4_7, 443 .parent_dev_ops = &vfe_parent_dev_ops, 444 .formats = &csid_formats_4_7 445 } 446 } 447 }; 448 449 static const struct camss_subdev_resources ispif_res_8x96 = { 450 /* ISPIF */ 451 .clock = { "top_ahb", "ahb", "ispif_ahb", 452 "csi0", "csi0_pix", "csi0_rdi", 453 "csi1", "csi1_pix", "csi1_rdi", 454 "csi2", "csi2_pix", "csi2_rdi", 455 "csi3", "csi3_pix", "csi3_rdi" }, 456 .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" }, 457 .reg = { "ispif", "csi_clk_mux" }, 458 .interrupt = { "ispif" }, 459 }; 460 461 static const struct camss_subdev_resources vfe_res_8x96[] = { 462 /* VFE0 */ 463 { 464 .regulators = {}, 465 .clock = { "top_ahb", "ahb", "vfe0", "csi_vfe0", "vfe_ahb", 466 "vfe0_ahb", "vfe_axi", "vfe0_stream"}, 467 .clock_rate = { { 0 }, 468 { 0 }, 469 { 75000000, 100000000, 300000000, 470 320000000, 480000000, 600000000 }, 471 { 0 }, 472 { 0 }, 473 { 0 }, 474 { 0 }, 475 { 0 } }, 476 .reg = { "vfe0" }, 477 .interrupt = { "vfe0" }, 478 .vfe = { 479 .line_num = 3, 480 .has_pd = true, 481 .hw_ops = &vfe_ops_4_7, 482 .formats_rdi = &vfe_formats_rdi_8x96, 483 .formats_pix = &vfe_formats_pix_8x96 484 } 485 }, 486 487 /* VFE1 */ 488 { 489 .regulators = {}, 490 .clock = { "top_ahb", "ahb", "vfe1", "csi_vfe1", "vfe_ahb", 491 "vfe1_ahb", "vfe_axi", "vfe1_stream"}, 492 .clock_rate = { { 0 }, 493 { 0 }, 494 { 75000000, 100000000, 300000000, 495 320000000, 480000000, 600000000 }, 496 { 0 }, 497 { 0 }, 498 { 0 }, 499 { 0 }, 500 { 0 } }, 501 .reg = { "vfe1" }, 502 .interrupt = { "vfe1" }, 503 .vfe = { 504 .line_num = 3, 505 .has_pd = true, 506 .hw_ops = &vfe_ops_4_7, 507 .formats_rdi = &vfe_formats_rdi_8x96, 508 .formats_pix = &vfe_formats_pix_8x96 509 } 510 } 511 }; 512 513 static const struct camss_subdev_resources csiphy_res_660[] = { 514 /* CSIPHY0 */ 515 { 516 .regulators = {}, 517 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer", 518 "csi0_phy", "csiphy_ahb2crif" }, 519 .clock_rate = { { 0 }, 520 { 0 }, 521 { 0 }, 522 { 100000000, 200000000, 269333333 }, 523 { 0 } }, 524 .reg = { "csiphy0", "csiphy0_clk_mux" }, 525 .interrupt = { "csiphy0" }, 526 .csiphy = { 527 .hw_ops = &csiphy_ops_3ph_1_0, 528 .formats = &csiphy_formats_8x96 529 } 530 }, 531 532 /* CSIPHY1 */ 533 { 534 .regulators = {}, 535 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer", 536 "csi1_phy", "csiphy_ahb2crif" }, 537 .clock_rate = { { 0 }, 538 { 0 }, 539 { 0 }, 540 { 100000000, 200000000, 269333333 }, 541 { 0 } }, 542 .reg = { "csiphy1", "csiphy1_clk_mux" }, 543 .interrupt = { "csiphy1" }, 544 .csiphy = { 545 .hw_ops = &csiphy_ops_3ph_1_0, 546 .formats = &csiphy_formats_8x96 547 } 548 }, 549 550 /* CSIPHY2 */ 551 { 552 .regulators = {}, 553 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer", 554 "csi2_phy", "csiphy_ahb2crif" }, 555 .clock_rate = { { 0 }, 556 { 0 }, 557 { 0 }, 558 { 100000000, 200000000, 269333333 }, 559 { 0 } }, 560 .reg = { "csiphy2", "csiphy2_clk_mux" }, 561 .interrupt = { "csiphy2" }, 562 .csiphy = { 563 .hw_ops = &csiphy_ops_3ph_1_0, 564 .formats = &csiphy_formats_8x96 565 } 566 } 567 }; 568 569 static const struct camss_subdev_resources csid_res_660[] = { 570 /* CSID0 */ 571 { 572 .regulators = { "vdda", "vdd_sec" }, 573 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", 574 "csi0", "csi0_phy", "csi0_pix", "csi0_rdi", 575 "cphy_csid0" }, 576 .clock_rate = { { 0 }, 577 { 0 }, 578 { 0 }, 579 { 0 }, 580 { 100000000, 200000000, 310000000, 581 404000000, 465000000 }, 582 { 0 }, 583 { 0 }, 584 { 0 }, 585 { 0 } }, 586 .reg = { "csid0" }, 587 .interrupt = { "csid0" }, 588 .csid = { 589 .hw_ops = &csid_ops_4_7, 590 .parent_dev_ops = &vfe_parent_dev_ops, 591 .formats = &csid_formats_4_7 592 } 593 }, 594 595 /* CSID1 */ 596 { 597 .regulators = { "vdda", "vdd_sec" }, 598 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", 599 "csi1", "csi1_phy", "csi1_pix", "csi1_rdi", 600 "cphy_csid1" }, 601 .clock_rate = { { 0 }, 602 { 0 }, 603 { 0 }, 604 { 0 }, 605 { 100000000, 200000000, 310000000, 606 404000000, 465000000 }, 607 { 0 }, 608 { 0 }, 609 { 0 }, 610 { 0 } }, 611 .reg = { "csid1" }, 612 .interrupt = { "csid1" }, 613 .csid = { 614 .hw_ops = &csid_ops_4_7, 615 .parent_dev_ops = &vfe_parent_dev_ops, 616 .formats = &csid_formats_4_7 617 } 618 }, 619 620 /* CSID2 */ 621 { 622 .regulators = { "vdda", "vdd_sec" }, 623 .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb", 624 "csi2", "csi2_phy", "csi2_pix", "csi2_rdi", 625 "cphy_csid2" }, 626 .clock_rate = { { 0 }, 627 { 0 }, 628 { 0 }, 629 { 0 }, 630 { 100000000, 200000000, 310000000, 631 404000000, 465000000 }, 632 { 0 }, 633 { 0 }, 634 { 0 }, 635 { 0 } }, 636 .reg = { "csid2" }, 637 .interrupt = { "csid2" }, 638 .csid = { 639 .hw_ops = &csid_ops_4_7, 640 .parent_dev_ops = &vfe_parent_dev_ops, 641 .formats = &csid_formats_4_7 642 } 643 }, 644 645 /* CSID3 */ 646 { 647 .regulators = { "vdda", "vdd_sec" }, 648 .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb", 649 "csi3", "csi3_phy", "csi3_pix", "csi3_rdi", 650 "cphy_csid3" }, 651 .clock_rate = { { 0 }, 652 { 0 }, 653 { 0 }, 654 { 0 }, 655 { 100000000, 200000000, 310000000, 656 404000000, 465000000 }, 657 { 0 }, 658 { 0 }, 659 { 0 }, 660 { 0 } }, 661 .reg = { "csid3" }, 662 .interrupt = { "csid3" }, 663 .csid = { 664 .hw_ops = &csid_ops_4_7, 665 .parent_dev_ops = &vfe_parent_dev_ops, 666 .formats = &csid_formats_4_7 667 } 668 } 669 }; 670 671 static const struct camss_subdev_resources ispif_res_660 = { 672 /* ISPIF */ 673 .clock = { "top_ahb", "ahb", "ispif_ahb", 674 "csi0", "csi0_pix", "csi0_rdi", 675 "csi1", "csi1_pix", "csi1_rdi", 676 "csi2", "csi2_pix", "csi2_rdi", 677 "csi3", "csi3_pix", "csi3_rdi" }, 678 .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" }, 679 .reg = { "ispif", "csi_clk_mux" }, 680 .interrupt = { "ispif" }, 681 }; 682 683 static const struct camss_subdev_resources vfe_res_660[] = { 684 /* VFE0 */ 685 { 686 .regulators = {}, 687 .clock = { "throttle_axi", "top_ahb", "ahb", "vfe0", 688 "csi_vfe0", "vfe_ahb", "vfe0_ahb", "vfe_axi", 689 "vfe0_stream"}, 690 .clock_rate = { { 0 }, 691 { 0 }, 692 { 0 }, 693 { 120000000, 200000000, 256000000, 694 300000000, 404000000, 480000000, 695 540000000, 576000000 }, 696 { 0 }, 697 { 0 }, 698 { 0 }, 699 { 0 }, 700 { 0 } }, 701 .reg = { "vfe0" }, 702 .interrupt = { "vfe0" }, 703 .vfe = { 704 .line_num = 3, 705 .has_pd = true, 706 .hw_ops = &vfe_ops_4_8, 707 .formats_rdi = &vfe_formats_rdi_8x96, 708 .formats_pix = &vfe_formats_pix_8x96 709 } 710 }, 711 712 /* VFE1 */ 713 { 714 .regulators = {}, 715 .clock = { "throttle_axi", "top_ahb", "ahb", "vfe1", 716 "csi_vfe1", "vfe_ahb", "vfe1_ahb", "vfe_axi", 717 "vfe1_stream"}, 718 .clock_rate = { { 0 }, 719 { 0 }, 720 { 0 }, 721 { 120000000, 200000000, 256000000, 722 300000000, 404000000, 480000000, 723 540000000, 576000000 }, 724 { 0 }, 725 { 0 }, 726 { 0 }, 727 { 0 }, 728 { 0 } }, 729 .reg = { "vfe1" }, 730 .interrupt = { "vfe1" }, 731 .vfe = { 732 .line_num = 3, 733 .has_pd = true, 734 .hw_ops = &vfe_ops_4_8, 735 .formats_rdi = &vfe_formats_rdi_8x96, 736 .formats_pix = &vfe_formats_pix_8x96 737 } 738 } 739 }; 740 741 static const struct camss_subdev_resources csiphy_res_845[] = { 742 /* CSIPHY0 */ 743 { 744 .regulators = {}, 745 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", 746 "cpas_ahb", "cphy_rx_src", "csiphy0", 747 "csiphy0_timer_src", "csiphy0_timer" }, 748 .clock_rate = { { 0 }, 749 { 0 }, 750 { 0 }, 751 { 0 }, 752 { 0 }, 753 { 0 }, 754 { 0 }, 755 { 19200000, 240000000, 269333333 } }, 756 .reg = { "csiphy0" }, 757 .interrupt = { "csiphy0" }, 758 .csiphy = { 759 .hw_ops = &csiphy_ops_3ph_1_0, 760 .formats = &csiphy_formats_sdm845 761 } 762 }, 763 764 /* CSIPHY1 */ 765 { 766 .regulators = {}, 767 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", 768 "cpas_ahb", "cphy_rx_src", "csiphy1", 769 "csiphy1_timer_src", "csiphy1_timer" }, 770 .clock_rate = { { 0 }, 771 { 0 }, 772 { 0 }, 773 { 0 }, 774 { 0 }, 775 { 0 }, 776 { 0 }, 777 { 19200000, 240000000, 269333333 } }, 778 .reg = { "csiphy1" }, 779 .interrupt = { "csiphy1" }, 780 .csiphy = { 781 .hw_ops = &csiphy_ops_3ph_1_0, 782 .formats = &csiphy_formats_sdm845 783 } 784 }, 785 786 /* CSIPHY2 */ 787 { 788 .regulators = {}, 789 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", 790 "cpas_ahb", "cphy_rx_src", "csiphy2", 791 "csiphy2_timer_src", "csiphy2_timer" }, 792 .clock_rate = { { 0 }, 793 { 0 }, 794 { 0 }, 795 { 0 }, 796 { 0 }, 797 { 0 }, 798 { 0 }, 799 { 19200000, 240000000, 269333333 } }, 800 .reg = { "csiphy2" }, 801 .interrupt = { "csiphy2" }, 802 .csiphy = { 803 .hw_ops = &csiphy_ops_3ph_1_0, 804 .formats = &csiphy_formats_sdm845 805 } 806 }, 807 808 /* CSIPHY3 */ 809 { 810 .regulators = {}, 811 .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", 812 "cpas_ahb", "cphy_rx_src", "csiphy3", 813 "csiphy3_timer_src", "csiphy3_timer" }, 814 .clock_rate = { { 0 }, 815 { 0 }, 816 { 0 }, 817 { 0 }, 818 { 0 }, 819 { 0 }, 820 { 0 }, 821 { 19200000, 240000000, 269333333 } }, 822 .reg = { "csiphy3" }, 823 .interrupt = { "csiphy3" }, 824 .csiphy = { 825 .hw_ops = &csiphy_ops_3ph_1_0, 826 .formats = &csiphy_formats_sdm845 827 } 828 } 829 }; 830 831 static const struct camss_subdev_resources csid_res_845[] = { 832 /* CSID0 */ 833 { 834 .regulators = { "vdda-phy", "vdda-pll" }, 835 .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", 836 "soc_ahb", "vfe0", "vfe0_src", 837 "vfe0_cphy_rx", "csi0", 838 "csi0_src" }, 839 .clock_rate = { { 0 }, 840 { 384000000 }, 841 { 80000000 }, 842 { 0 }, 843 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, 844 { 320000000 }, 845 { 0 }, 846 { 19200000, 75000000, 384000000, 538666667 }, 847 { 384000000 } }, 848 .reg = { "csid0" }, 849 .interrupt = { "csid0" }, 850 .csid = { 851 .hw_ops = &csid_ops_gen2, 852 .parent_dev_ops = &vfe_parent_dev_ops, 853 .formats = &csid_formats_gen2 854 } 855 }, 856 857 /* CSID1 */ 858 { 859 .regulators = { "vdda-phy", "vdda-pll" }, 860 .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", 861 "soc_ahb", "vfe1", "vfe1_src", 862 "vfe1_cphy_rx", "csi1", 863 "csi1_src" }, 864 .clock_rate = { { 0 }, 865 { 384000000 }, 866 { 80000000 }, 867 { 0 }, 868 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, 869 { 320000000 }, 870 { 0 }, 871 { 19200000, 75000000, 384000000, 538666667 }, 872 { 384000000 } }, 873 .reg = { "csid1" }, 874 .interrupt = { "csid1" }, 875 .csid = { 876 .hw_ops = &csid_ops_gen2, 877 .parent_dev_ops = &vfe_parent_dev_ops, 878 .formats = &csid_formats_gen2 879 } 880 }, 881 882 /* CSID2 */ 883 { 884 .regulators = { "vdda-phy", "vdda-pll" }, 885 .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", 886 "soc_ahb", "vfe_lite", "vfe_lite_src", 887 "vfe_lite_cphy_rx", "csi2", 888 "csi2_src" }, 889 .clock_rate = { { 0 }, 890 { 384000000 }, 891 { 80000000 }, 892 { 0 }, 893 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, 894 { 320000000 }, 895 { 0 }, 896 { 19200000, 75000000, 384000000, 538666667 }, 897 { 384000000 } }, 898 .reg = { "csid2" }, 899 .interrupt = { "csid2" }, 900 .csid = { 901 .is_lite = true, 902 .hw_ops = &csid_ops_gen2, 903 .parent_dev_ops = &vfe_parent_dev_ops, 904 .formats = &csid_formats_gen2 905 } 906 } 907 }; 908 909 static const struct camss_subdev_resources vfe_res_845[] = { 910 /* VFE0 */ 911 { 912 .regulators = {}, 913 .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src", 914 "soc_ahb", "vfe0", "vfe0_axi", 915 "vfe0_src", "csi0", 916 "csi0_src"}, 917 .clock_rate = { { 0 }, 918 { 0 }, 919 { 80000000 }, 920 { 0 }, 921 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, 922 { 0 }, 923 { 320000000 }, 924 { 19200000, 75000000, 384000000, 538666667 }, 925 { 384000000 } }, 926 .reg = { "vfe0" }, 927 .interrupt = { "vfe0" }, 928 .vfe = { 929 .line_num = 4, 930 .has_pd = true, 931 .hw_ops = &vfe_ops_170, 932 .formats_rdi = &vfe_formats_rdi_845, 933 .formats_pix = &vfe_formats_pix_845 934 } 935 }, 936 937 /* VFE1 */ 938 { 939 .regulators = {}, 940 .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src", 941 "soc_ahb", "vfe1", "vfe1_axi", 942 "vfe1_src", "csi1", 943 "csi1_src"}, 944 .clock_rate = { { 0 }, 945 { 0 }, 946 { 80000000 }, 947 { 0 }, 948 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, 949 { 0 }, 950 { 320000000 }, 951 { 19200000, 75000000, 384000000, 538666667 }, 952 { 384000000 } }, 953 .reg = { "vfe1" }, 954 .interrupt = { "vfe1" }, 955 .vfe = { 956 .line_num = 4, 957 .has_pd = true, 958 .hw_ops = &vfe_ops_170, 959 .formats_rdi = &vfe_formats_rdi_845, 960 .formats_pix = &vfe_formats_pix_845 961 } 962 }, 963 964 /* VFE-lite */ 965 { 966 .regulators = {}, 967 .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src", 968 "soc_ahb", "vfe_lite", 969 "vfe_lite_src", "csi2", 970 "csi2_src"}, 971 .clock_rate = { { 0 }, 972 { 0 }, 973 { 80000000 }, 974 { 0 }, 975 { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, 976 { 320000000 }, 977 { 19200000, 75000000, 384000000, 538666667 }, 978 { 384000000 } }, 979 .reg = { "vfe_lite" }, 980 .interrupt = { "vfe_lite" }, 981 .vfe = { 982 .is_lite = true, 983 .line_num = 4, 984 .hw_ops = &vfe_ops_170, 985 .formats_rdi = &vfe_formats_rdi_845, 986 .formats_pix = &vfe_formats_pix_845 987 } 988 } 989 }; 990 991 static const struct camss_subdev_resources csiphy_res_8250[] = { 992 /* CSIPHY0 */ 993 { 994 .regulators = { "vdda-phy", "vdda-pll" }, 995 .clock = { "csiphy0", "csiphy0_timer" }, 996 .clock_rate = { { 400000000 }, 997 { 300000000 } }, 998 .reg = { "csiphy0" }, 999 .interrupt = { "csiphy0" }, 1000 .csiphy = { 1001 .hw_ops = &csiphy_ops_3ph_1_0, 1002 .formats = &csiphy_formats_sdm845 1003 } 1004 }, 1005 /* CSIPHY1 */ 1006 { 1007 .regulators = { "vdda-phy", "vdda-pll" }, 1008 .clock = { "csiphy1", "csiphy1_timer" }, 1009 .clock_rate = { { 400000000 }, 1010 { 300000000 } }, 1011 .reg = { "csiphy1" }, 1012 .interrupt = { "csiphy1" }, 1013 .csiphy = { 1014 .hw_ops = &csiphy_ops_3ph_1_0, 1015 .formats = &csiphy_formats_sdm845 1016 } 1017 }, 1018 /* CSIPHY2 */ 1019 { 1020 .regulators = { "vdda-phy", "vdda-pll" }, 1021 .clock = { "csiphy2", "csiphy2_timer" }, 1022 .clock_rate = { { 400000000 }, 1023 { 300000000 } }, 1024 .reg = { "csiphy2" }, 1025 .interrupt = { "csiphy2" }, 1026 .csiphy = { 1027 .hw_ops = &csiphy_ops_3ph_1_0, 1028 .formats = &csiphy_formats_sdm845 1029 } 1030 }, 1031 /* CSIPHY3 */ 1032 { 1033 .regulators = { "vdda-phy", "vdda-pll" }, 1034 .clock = { "csiphy3", "csiphy3_timer" }, 1035 .clock_rate = { { 400000000 }, 1036 { 300000000 } }, 1037 .reg = { "csiphy3" }, 1038 .interrupt = { "csiphy3" }, 1039 .csiphy = { 1040 .hw_ops = &csiphy_ops_3ph_1_0, 1041 .formats = &csiphy_formats_sdm845 1042 } 1043 }, 1044 /* CSIPHY4 */ 1045 { 1046 .regulators = { "vdda-phy", "vdda-pll" }, 1047 .clock = { "csiphy4", "csiphy4_timer" }, 1048 .clock_rate = { { 400000000 }, 1049 { 300000000 } }, 1050 .reg = { "csiphy4" }, 1051 .interrupt = { "csiphy4" }, 1052 .csiphy = { 1053 .hw_ops = &csiphy_ops_3ph_1_0, 1054 .formats = &csiphy_formats_sdm845 1055 } 1056 }, 1057 /* CSIPHY5 */ 1058 { 1059 .regulators = { "vdda-phy", "vdda-pll" }, 1060 .clock = { "csiphy5", "csiphy5_timer" }, 1061 .clock_rate = { { 400000000 }, 1062 { 300000000 } }, 1063 .reg = { "csiphy5" }, 1064 .interrupt = { "csiphy5" }, 1065 .csiphy = { 1066 .hw_ops = &csiphy_ops_3ph_1_0, 1067 .formats = &csiphy_formats_sdm845 1068 } 1069 } 1070 }; 1071 1072 static const struct camss_subdev_resources csid_res_8250[] = { 1073 /* CSID0 */ 1074 { 1075 .regulators = {}, 1076 .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_areg", "vfe0_ahb" }, 1077 .clock_rate = { { 400000000 }, 1078 { 400000000 }, 1079 { 350000000, 475000000, 576000000, 720000000 }, 1080 { 100000000, 200000000, 300000000, 400000000 }, 1081 { 0 } }, 1082 .reg = { "csid0" }, 1083 .interrupt = { "csid0" }, 1084 .csid = { 1085 .hw_ops = &csid_ops_gen2, 1086 .parent_dev_ops = &vfe_parent_dev_ops, 1087 .formats = &csid_formats_gen2 1088 } 1089 }, 1090 /* CSID1 */ 1091 { 1092 .regulators = {}, 1093 .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_areg", "vfe1_ahb" }, 1094 .clock_rate = { { 400000000 }, 1095 { 400000000 }, 1096 { 350000000, 475000000, 576000000, 720000000 }, 1097 { 100000000, 200000000, 300000000, 400000000 }, 1098 { 0 } }, 1099 .reg = { "csid1" }, 1100 .interrupt = { "csid1" }, 1101 .csid = { 1102 .hw_ops = &csid_ops_gen2, 1103 .parent_dev_ops = &vfe_parent_dev_ops, 1104 .formats = &csid_formats_gen2 1105 } 1106 }, 1107 /* CSID2 */ 1108 { 1109 .regulators = {}, 1110 .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite", "vfe_lite_ahb" }, 1111 .clock_rate = { { 400000000 }, 1112 { 400000000 }, 1113 { 400000000, 480000000 }, 1114 { 0 } }, 1115 .reg = { "csid2" }, 1116 .interrupt = { "csid2" }, 1117 .csid = { 1118 .is_lite = true, 1119 .hw_ops = &csid_ops_gen2, 1120 .parent_dev_ops = &vfe_parent_dev_ops, 1121 .formats = &csid_formats_gen2 1122 } 1123 }, 1124 /* CSID3 */ 1125 { 1126 .regulators = {}, 1127 .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite", "vfe_lite_ahb" }, 1128 .clock_rate = { { 400000000 }, 1129 { 400000000 }, 1130 { 400000000, 480000000 }, 1131 { 0 } }, 1132 .reg = { "csid3" }, 1133 .interrupt = { "csid3" }, 1134 .csid = { 1135 .is_lite = true, 1136 .hw_ops = &csid_ops_gen2, 1137 .parent_dev_ops = &vfe_parent_dev_ops, 1138 .formats = &csid_formats_gen2 1139 } 1140 } 1141 }; 1142 1143 static const struct camss_subdev_resources vfe_res_8250[] = { 1144 /* VFE0 */ 1145 { 1146 .regulators = {}, 1147 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb", 1148 "camnoc_axi", "vfe0_ahb", "vfe0_areg", "vfe0", 1149 "vfe0_axi", "cam_hf_axi" }, 1150 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 }, 1151 { 19200000, 80000000 }, 1152 { 19200000 }, 1153 { 0 }, 1154 { 0 }, 1155 { 100000000, 200000000, 300000000, 400000000 }, 1156 { 350000000, 475000000, 576000000, 720000000 }, 1157 { 0 }, 1158 { 0 } }, 1159 .reg = { "vfe0" }, 1160 .interrupt = { "vfe0" }, 1161 .vfe = { 1162 .line_num = 3, 1163 .has_pd = true, 1164 .pd_name = "ife0", 1165 .hw_ops = &vfe_ops_480, 1166 .formats_rdi = &vfe_formats_rdi_845, 1167 .formats_pix = &vfe_formats_pix_845 1168 } 1169 }, 1170 /* VFE1 */ 1171 { 1172 .regulators = {}, 1173 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb", 1174 "camnoc_axi", "vfe1_ahb", "vfe1_areg", "vfe1", 1175 "vfe1_axi", "cam_hf_axi" }, 1176 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 }, 1177 { 19200000, 80000000 }, 1178 { 19200000 }, 1179 { 0 }, 1180 { 0 }, 1181 { 100000000, 200000000, 300000000, 400000000 }, 1182 { 350000000, 475000000, 576000000, 720000000 }, 1183 { 0 }, 1184 { 0 } }, 1185 .reg = { "vfe1" }, 1186 .interrupt = { "vfe1" }, 1187 .vfe = { 1188 .line_num = 3, 1189 .has_pd = true, 1190 .pd_name = "ife1", 1191 .hw_ops = &vfe_ops_480, 1192 .formats_rdi = &vfe_formats_rdi_845, 1193 .formats_pix = &vfe_formats_pix_845 1194 } 1195 }, 1196 /* VFE2 (lite) */ 1197 { 1198 .regulators = {}, 1199 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb", 1200 "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi", 1201 "vfe_lite", "cam_hf_axi" }, 1202 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 }, 1203 { 19200000, 80000000 }, 1204 { 19200000 }, 1205 { 0 }, 1206 { 0 }, 1207 { 0 }, 1208 { 400000000, 480000000 }, 1209 { 0 } }, 1210 .reg = { "vfe_lite0" }, 1211 .interrupt = { "vfe_lite0" }, 1212 .vfe = { 1213 .is_lite = true, 1214 .line_num = 4, 1215 .hw_ops = &vfe_ops_480, 1216 .formats_rdi = &vfe_formats_rdi_845, 1217 .formats_pix = &vfe_formats_pix_845 1218 } 1219 }, 1220 /* VFE3 (lite) */ 1221 { 1222 .regulators = {}, 1223 .clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb", 1224 "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi", 1225 "vfe_lite", "cam_hf_axi" }, 1226 .clock_rate = { { 19200000, 300000000, 400000000, 480000000 }, 1227 { 19200000, 80000000 }, 1228 { 19200000 }, 1229 { 0 }, 1230 { 0 }, 1231 { 0 }, 1232 { 400000000, 480000000 }, 1233 { 0 } }, 1234 .reg = { "vfe_lite1" }, 1235 .interrupt = { "vfe_lite1" }, 1236 .vfe = { 1237 .is_lite = true, 1238 .line_num = 4, 1239 .hw_ops = &vfe_ops_480, 1240 .formats_rdi = &vfe_formats_rdi_845, 1241 .formats_pix = &vfe_formats_pix_845 1242 } 1243 }, 1244 }; 1245 1246 static const struct resources_icc icc_res_sm8250[] = { 1247 { 1248 .name = "cam_ahb", 1249 .icc_bw_tbl.avg = 38400, 1250 .icc_bw_tbl.peak = 76800, 1251 }, 1252 { 1253 .name = "cam_hf_0_mnoc", 1254 .icc_bw_tbl.avg = 2097152, 1255 .icc_bw_tbl.peak = 2097152, 1256 }, 1257 { 1258 .name = "cam_sf_0_mnoc", 1259 .icc_bw_tbl.avg = 0, 1260 .icc_bw_tbl.peak = 2097152, 1261 }, 1262 { 1263 .name = "cam_sf_icp_mnoc", 1264 .icc_bw_tbl.avg = 2097152, 1265 .icc_bw_tbl.peak = 2097152, 1266 }, 1267 }; 1268 1269 static const struct camss_subdev_resources csiphy_res_sc8280xp[] = { 1270 /* CSIPHY0 */ 1271 { 1272 .regulators = {}, 1273 .clock = { "csiphy0", "csiphy0_timer" }, 1274 .clock_rate = { { 400000000 }, 1275 { 300000000 } }, 1276 .reg = { "csiphy0" }, 1277 .interrupt = { "csiphy0" }, 1278 .csiphy = { 1279 .hw_ops = &csiphy_ops_3ph_1_0, 1280 .formats = &csiphy_formats_sdm845 1281 } 1282 }, 1283 /* CSIPHY1 */ 1284 { 1285 .regulators = {}, 1286 .clock = { "csiphy1", "csiphy1_timer" }, 1287 .clock_rate = { { 400000000 }, 1288 { 300000000 } }, 1289 .reg = { "csiphy1" }, 1290 .interrupt = { "csiphy1" }, 1291 .csiphy = { 1292 .hw_ops = &csiphy_ops_3ph_1_0, 1293 .formats = &csiphy_formats_sdm845 1294 } 1295 }, 1296 /* CSIPHY2 */ 1297 { 1298 .regulators = {}, 1299 .clock = { "csiphy2", "csiphy2_timer" }, 1300 .clock_rate = { { 400000000 }, 1301 { 300000000 } }, 1302 .reg = { "csiphy2" }, 1303 .interrupt = { "csiphy2" }, 1304 .csiphy = { 1305 .hw_ops = &csiphy_ops_3ph_1_0, 1306 .formats = &csiphy_formats_sdm845 1307 } 1308 }, 1309 /* CSIPHY3 */ 1310 { 1311 .regulators = {}, 1312 .clock = { "csiphy3", "csiphy3_timer" }, 1313 .clock_rate = { { 400000000 }, 1314 { 300000000 } }, 1315 .reg = { "csiphy3" }, 1316 .interrupt = { "csiphy3" }, 1317 .csiphy = { 1318 .hw_ops = &csiphy_ops_3ph_1_0, 1319 .formats = &csiphy_formats_sdm845 1320 } 1321 }, 1322 }; 1323 1324 static const struct camss_subdev_resources csid_res_sc8280xp[] = { 1325 /* CSID0 */ 1326 { 1327 .regulators = { "vdda-phy", "vdda-pll" }, 1328 .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_axi" }, 1329 .clock_rate = { { 400000000, 480000000, 600000000 }, 1330 { 0 }, 1331 { 0 }, 1332 { 0 } }, 1333 .reg = { "csid0" }, 1334 .interrupt = { "csid0" }, 1335 .csid = { 1336 .hw_ops = &csid_ops_gen2, 1337 .parent_dev_ops = &vfe_parent_dev_ops, 1338 .formats = &csid_formats_gen2 1339 } 1340 }, 1341 /* CSID1 */ 1342 { 1343 .regulators = { "vdda-phy", "vdda-pll" }, 1344 .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_axi" }, 1345 .clock_rate = { { 400000000, 480000000, 600000000 }, 1346 { 0 }, 1347 { 0 }, 1348 { 0 } }, 1349 .reg = { "csid1" }, 1350 .interrupt = { "csid1" }, 1351 .csid = { 1352 .hw_ops = &csid_ops_gen2, 1353 .parent_dev_ops = &vfe_parent_dev_ops, 1354 .formats = &csid_formats_gen2 1355 } 1356 }, 1357 /* CSID2 */ 1358 { 1359 .regulators = { "vdda-phy", "vdda-pll" }, 1360 .clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2", "vfe2_axi" }, 1361 .clock_rate = { { 400000000, 480000000, 600000000 }, 1362 { 0 }, 1363 { 0 }, 1364 { 0 } }, 1365 .reg = { "csid2" }, 1366 .interrupt = { "csid2" }, 1367 .csid = { 1368 .hw_ops = &csid_ops_gen2, 1369 .parent_dev_ops = &vfe_parent_dev_ops, 1370 .formats = &csid_formats_gen2 1371 } 1372 }, 1373 /* CSID3 */ 1374 { 1375 .regulators = { "vdda-phy", "vdda-pll" }, 1376 .clock = { "vfe3_csid", "vfe3_cphy_rx", "vfe3", "vfe3_axi" }, 1377 .clock_rate = { { 400000000, 480000000, 600000000 }, 1378 { 0 }, 1379 { 0 }, 1380 { 0 } }, 1381 .reg = { "csid3" }, 1382 .interrupt = { "csid3" }, 1383 .csid = { 1384 .hw_ops = &csid_ops_gen2, 1385 .parent_dev_ops = &vfe_parent_dev_ops, 1386 .formats = &csid_formats_gen2 1387 } 1388 }, 1389 /* CSID_LITE0 */ 1390 { 1391 .regulators = { "vdda-phy", "vdda-pll" }, 1392 .clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" }, 1393 .clock_rate = { { 400000000, 480000000, 600000000 }, 1394 { 0 }, 1395 { 0 }, }, 1396 .reg = { "csid0_lite" }, 1397 .interrupt = { "csid0_lite" }, 1398 .csid = { 1399 .is_lite = true, 1400 .hw_ops = &csid_ops_gen2, 1401 .parent_dev_ops = &vfe_parent_dev_ops, 1402 .formats = &csid_formats_gen2 1403 } 1404 }, 1405 /* CSID_LITE1 */ 1406 { 1407 .regulators = { "vdda-phy", "vdda-pll" }, 1408 .clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" }, 1409 .clock_rate = { { 400000000, 480000000, 600000000 }, 1410 { 0 }, 1411 { 0 }, }, 1412 .reg = { "csid1_lite" }, 1413 .interrupt = { "csid1_lite" }, 1414 .csid = { 1415 .is_lite = true, 1416 .hw_ops = &csid_ops_gen2, 1417 .parent_dev_ops = &vfe_parent_dev_ops, 1418 .formats = &csid_formats_gen2 1419 } 1420 }, 1421 /* CSID_LITE2 */ 1422 { 1423 .regulators = { "vdda-phy", "vdda-pll" }, 1424 .clock = { "vfe_lite2_csid", "vfe_lite2_cphy_rx", "vfe_lite2" }, 1425 .clock_rate = { { 400000000, 480000000, 600000000 }, 1426 { 0 }, 1427 { 0 }, }, 1428 .reg = { "csid2_lite" }, 1429 .interrupt = { "csid2_lite" }, 1430 .csid = { 1431 .is_lite = true, 1432 .hw_ops = &csid_ops_gen2, 1433 .parent_dev_ops = &vfe_parent_dev_ops, 1434 .formats = &csid_formats_gen2 1435 } 1436 }, 1437 /* CSID_LITE3 */ 1438 { 1439 .regulators = { "vdda-phy", "vdda-pll" }, 1440 .clock = { "vfe_lite3_csid", "vfe_lite3_cphy_rx", "vfe_lite3" }, 1441 .clock_rate = { { 400000000, 480000000, 600000000 }, 1442 { 0 }, 1443 { 0 }, }, 1444 .reg = { "csid3_lite" }, 1445 .interrupt = { "csid3_lite" }, 1446 .csid = { 1447 .is_lite = true, 1448 .hw_ops = &csid_ops_gen2, 1449 .parent_dev_ops = &vfe_parent_dev_ops, 1450 .formats = &csid_formats_gen2 1451 } 1452 } 1453 }; 1454 1455 static const struct camss_subdev_resources vfe_res_sc8280xp[] = { 1456 /* VFE0 */ 1457 { 1458 .regulators = {}, 1459 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe0", "vfe0_axi" }, 1460 .clock_rate = { { 0 }, 1461 { 0 }, 1462 { 19200000, 80000000}, 1463 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, 1464 { 400000000, 558000000, 637000000, 760000000 }, 1465 { 0 }, }, 1466 .reg = { "vfe0" }, 1467 .interrupt = { "vfe0" }, 1468 .vfe = { 1469 .line_num = 4, 1470 .pd_name = "ife0", 1471 .hw_ops = &vfe_ops_170, 1472 .formats_rdi = &vfe_formats_rdi_845, 1473 .formats_pix = &vfe_formats_pix_845 1474 } 1475 }, 1476 /* VFE1 */ 1477 { 1478 .regulators = {}, 1479 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe1", "vfe1_axi" }, 1480 .clock_rate = { { 0 }, 1481 { 0 }, 1482 { 19200000, 80000000}, 1483 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, 1484 { 400000000, 558000000, 637000000, 760000000 }, 1485 { 0 }, }, 1486 .reg = { "vfe1" }, 1487 .interrupt = { "vfe1" }, 1488 .vfe = { 1489 .line_num = 4, 1490 .pd_name = "ife1", 1491 .hw_ops = &vfe_ops_170, 1492 .formats_rdi = &vfe_formats_rdi_845, 1493 .formats_pix = &vfe_formats_pix_845 1494 } 1495 }, 1496 /* VFE2 */ 1497 { 1498 .regulators = {}, 1499 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe2", "vfe2_axi" }, 1500 .clock_rate = { { 0 }, 1501 { 0 }, 1502 { 19200000, 80000000}, 1503 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, 1504 { 400000000, 558000000, 637000000, 760000000 }, 1505 { 0 }, }, 1506 .reg = { "vfe2" }, 1507 .interrupt = { "vfe2" }, 1508 .vfe = { 1509 .line_num = 4, 1510 .pd_name = "ife2", 1511 .hw_ops = &vfe_ops_170, 1512 .formats_rdi = &vfe_formats_rdi_845, 1513 .formats_pix = &vfe_formats_pix_845 1514 } 1515 }, 1516 /* VFE3 */ 1517 { 1518 .regulators = {}, 1519 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe3", "vfe3_axi" }, 1520 .clock_rate = { { 0 }, 1521 { 0 }, 1522 { 19200000, 80000000}, 1523 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, 1524 { 400000000, 558000000, 637000000, 760000000 }, 1525 { 0 }, }, 1526 .reg = { "vfe3" }, 1527 .interrupt = { "vfe3" }, 1528 .vfe = { 1529 .line_num = 4, 1530 .pd_name = "ife3", 1531 .hw_ops = &vfe_ops_170, 1532 .formats_rdi = &vfe_formats_rdi_845, 1533 .formats_pix = &vfe_formats_pix_845 1534 } 1535 }, 1536 /* VFE_LITE_0 */ 1537 { 1538 .regulators = {}, 1539 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite0" }, 1540 .clock_rate = { { 0 }, 1541 { 0 }, 1542 { 19200000, 80000000}, 1543 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, 1544 { 320000000, 400000000, 480000000, 600000000 }, }, 1545 .reg = { "vfe_lite0" }, 1546 .interrupt = { "vfe_lite0" }, 1547 .vfe = { 1548 .is_lite = true, 1549 .line_num = 4, 1550 .hw_ops = &vfe_ops_170, 1551 .formats_rdi = &vfe_formats_rdi_845, 1552 .formats_pix = &vfe_formats_pix_845 1553 } 1554 }, 1555 /* VFE_LITE_1 */ 1556 { 1557 .regulators = {}, 1558 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite1" }, 1559 .clock_rate = { { 0 }, 1560 { 0 }, 1561 { 19200000, 80000000}, 1562 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, 1563 { 320000000, 400000000, 480000000, 600000000 }, }, 1564 .reg = { "vfe_lite1" }, 1565 .interrupt = { "vfe_lite1" }, 1566 .vfe = { 1567 .is_lite = true, 1568 .line_num = 4, 1569 .hw_ops = &vfe_ops_170, 1570 .formats_rdi = &vfe_formats_rdi_845, 1571 .formats_pix = &vfe_formats_pix_845 1572 } 1573 }, 1574 /* VFE_LITE_2 */ 1575 { 1576 .regulators = {}, 1577 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite2" }, 1578 .clock_rate = { { 0 }, 1579 { 0 }, 1580 { 19200000, 80000000}, 1581 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, 1582 { 320000000, 400000000, 480000000, 600000000, }, }, 1583 .reg = { "vfe_lite2" }, 1584 .interrupt = { "vfe_lite2" }, 1585 .vfe = { 1586 .is_lite = true, 1587 .line_num = 4, 1588 .hw_ops = &vfe_ops_170, 1589 .formats_rdi = &vfe_formats_rdi_845, 1590 .formats_pix = &vfe_formats_pix_845 1591 } 1592 }, 1593 /* VFE_LITE_3 */ 1594 { 1595 .regulators = {}, 1596 .clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite3" }, 1597 .clock_rate = { { 0 }, 1598 { 0 }, 1599 { 19200000, 80000000}, 1600 { 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 }, 1601 { 320000000, 400000000, 480000000, 600000000 }, }, 1602 .reg = { "vfe_lite3" }, 1603 .interrupt = { "vfe_lite3" }, 1604 .vfe = { 1605 .is_lite = true, 1606 .line_num = 4, 1607 .hw_ops = &vfe_ops_170, 1608 .formats_rdi = &vfe_formats_rdi_845, 1609 .formats_pix = &vfe_formats_pix_845 1610 } 1611 }, 1612 }; 1613 1614 static const struct resources_icc icc_res_sc8280xp[] = { 1615 { 1616 .name = "cam_ahb", 1617 .icc_bw_tbl.avg = 150000, 1618 .icc_bw_tbl.peak = 300000, 1619 }, 1620 { 1621 .name = "cam_hf_mnoc", 1622 .icc_bw_tbl.avg = 2097152, 1623 .icc_bw_tbl.peak = 2097152, 1624 }, 1625 { 1626 .name = "cam_sf_mnoc", 1627 .icc_bw_tbl.avg = 2097152, 1628 .icc_bw_tbl.peak = 2097152, 1629 }, 1630 { 1631 .name = "cam_sf_icp_mnoc", 1632 .icc_bw_tbl.avg = 2097152, 1633 .icc_bw_tbl.peak = 2097152, 1634 }, 1635 }; 1636 1637 /* 1638 * camss_add_clock_margin - Add margin to clock frequency rate 1639 * @rate: Clock frequency rate 1640 * 1641 * When making calculations with physical clock frequency values 1642 * some safety margin must be added. Add it. 1643 */ 1644 inline void camss_add_clock_margin(u64 *rate) 1645 { 1646 *rate *= CAMSS_CLOCK_MARGIN_NUMERATOR; 1647 *rate = div_u64(*rate, CAMSS_CLOCK_MARGIN_DENOMINATOR); 1648 } 1649 1650 /* 1651 * camss_enable_clocks - Enable multiple clocks 1652 * @nclocks: Number of clocks in clock array 1653 * @clock: Clock array 1654 * @dev: Device 1655 * 1656 * Return 0 on success or a negative error code otherwise 1657 */ 1658 int camss_enable_clocks(int nclocks, struct camss_clock *clock, 1659 struct device *dev) 1660 { 1661 int ret; 1662 int i; 1663 1664 for (i = 0; i < nclocks; i++) { 1665 ret = clk_prepare_enable(clock[i].clk); 1666 if (ret) { 1667 dev_err(dev, "clock enable failed: %d\n", ret); 1668 goto error; 1669 } 1670 } 1671 1672 return 0; 1673 1674 error: 1675 for (i--; i >= 0; i--) 1676 clk_disable_unprepare(clock[i].clk); 1677 1678 return ret; 1679 } 1680 1681 /* 1682 * camss_disable_clocks - Disable multiple clocks 1683 * @nclocks: Number of clocks in clock array 1684 * @clock: Clock array 1685 */ 1686 void camss_disable_clocks(int nclocks, struct camss_clock *clock) 1687 { 1688 int i; 1689 1690 for (i = nclocks - 1; i >= 0; i--) 1691 clk_disable_unprepare(clock[i].clk); 1692 } 1693 1694 /* 1695 * camss_find_sensor - Find a linked media entity which represents a sensor 1696 * @entity: Media entity to start searching from 1697 * 1698 * Return a pointer to sensor media entity or NULL if not found 1699 */ 1700 struct media_entity *camss_find_sensor(struct media_entity *entity) 1701 { 1702 struct media_pad *pad; 1703 1704 while (1) { 1705 pad = &entity->pads[0]; 1706 if (!(pad->flags & MEDIA_PAD_FL_SINK)) 1707 return NULL; 1708 1709 pad = media_pad_remote_pad_first(pad); 1710 if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) 1711 return NULL; 1712 1713 entity = pad->entity; 1714 1715 if (entity->function == MEDIA_ENT_F_CAM_SENSOR) 1716 return entity; 1717 } 1718 } 1719 1720 /** 1721 * camss_get_link_freq - Get link frequency from sensor 1722 * @entity: Media entity in the current pipeline 1723 * @bpp: Number of bits per pixel for the current format 1724 * @lanes: Number of lanes in the link to the sensor 1725 * 1726 * Return link frequency on success or a negative error code otherwise 1727 */ 1728 s64 camss_get_link_freq(struct media_entity *entity, unsigned int bpp, 1729 unsigned int lanes) 1730 { 1731 struct media_entity *sensor; 1732 struct v4l2_subdev *subdev; 1733 1734 sensor = camss_find_sensor(entity); 1735 if (!sensor) 1736 return -ENODEV; 1737 1738 subdev = media_entity_to_v4l2_subdev(sensor); 1739 1740 return v4l2_get_link_freq(subdev->ctrl_handler, bpp, 2 * lanes); 1741 } 1742 1743 /* 1744 * camss_get_pixel_clock - Get pixel clock rate from sensor 1745 * @entity: Media entity in the current pipeline 1746 * @pixel_clock: Received pixel clock value 1747 * 1748 * Return 0 on success or a negative error code otherwise 1749 */ 1750 int camss_get_pixel_clock(struct media_entity *entity, u64 *pixel_clock) 1751 { 1752 struct media_entity *sensor; 1753 struct v4l2_subdev *subdev; 1754 struct v4l2_ctrl *ctrl; 1755 1756 sensor = camss_find_sensor(entity); 1757 if (!sensor) 1758 return -ENODEV; 1759 1760 subdev = media_entity_to_v4l2_subdev(sensor); 1761 1762 ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE); 1763 1764 if (!ctrl) 1765 return -EINVAL; 1766 1767 *pixel_clock = v4l2_ctrl_g_ctrl_int64(ctrl); 1768 1769 return 0; 1770 } 1771 1772 int camss_pm_domain_on(struct camss *camss, int id) 1773 { 1774 int ret = 0; 1775 1776 if (id < camss->res->vfe_num) { 1777 struct vfe_device *vfe = &camss->vfe[id]; 1778 1779 ret = vfe->res->hw_ops->pm_domain_on(vfe); 1780 } 1781 1782 return ret; 1783 } 1784 1785 void camss_pm_domain_off(struct camss *camss, int id) 1786 { 1787 if (id < camss->res->vfe_num) { 1788 struct vfe_device *vfe = &camss->vfe[id]; 1789 1790 vfe->res->hw_ops->pm_domain_off(vfe); 1791 } 1792 } 1793 1794 static int vfe_parent_dev_ops_get(struct camss *camss, int id) 1795 { 1796 int ret = -EINVAL; 1797 1798 if (id < camss->res->vfe_num) { 1799 struct vfe_device *vfe = &camss->vfe[id]; 1800 1801 ret = vfe_get(vfe); 1802 } 1803 1804 return ret; 1805 } 1806 1807 static int vfe_parent_dev_ops_put(struct camss *camss, int id) 1808 { 1809 if (id < camss->res->vfe_num) { 1810 struct vfe_device *vfe = &camss->vfe[id]; 1811 1812 vfe_put(vfe); 1813 } 1814 1815 return 0; 1816 } 1817 1818 static void __iomem 1819 *vfe_parent_dev_ops_get_base_address(struct camss *camss, int id) 1820 { 1821 if (id < camss->res->vfe_num) { 1822 struct vfe_device *vfe = &camss->vfe[id]; 1823 1824 return vfe->base; 1825 } 1826 1827 return NULL; 1828 } 1829 1830 static const struct parent_dev_ops vfe_parent_dev_ops = { 1831 .get = vfe_parent_dev_ops_get, 1832 .put = vfe_parent_dev_ops_put, 1833 .get_base_address = vfe_parent_dev_ops_get_base_address 1834 }; 1835 1836 /* 1837 * camss_of_parse_endpoint_node - Parse port endpoint node 1838 * @dev: Device 1839 * @node: Device node to be parsed 1840 * @csd: Parsed data from port endpoint node 1841 * 1842 * Return 0 on success or a negative error code on failure 1843 */ 1844 static int camss_of_parse_endpoint_node(struct device *dev, 1845 struct device_node *node, 1846 struct camss_async_subdev *csd) 1847 { 1848 struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg; 1849 struct v4l2_mbus_config_mipi_csi2 *mipi_csi2; 1850 struct v4l2_fwnode_endpoint vep = { { 0 } }; 1851 unsigned int i; 1852 int ret; 1853 1854 ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep); 1855 if (ret) 1856 return ret; 1857 1858 csd->interface.csiphy_id = vep.base.port; 1859 1860 mipi_csi2 = &vep.bus.mipi_csi2; 1861 lncfg->clk.pos = mipi_csi2->clock_lane; 1862 lncfg->clk.pol = mipi_csi2->lane_polarities[0]; 1863 lncfg->num_data = mipi_csi2->num_data_lanes; 1864 1865 lncfg->data = devm_kcalloc(dev, 1866 lncfg->num_data, sizeof(*lncfg->data), 1867 GFP_KERNEL); 1868 if (!lncfg->data) 1869 return -ENOMEM; 1870 1871 for (i = 0; i < lncfg->num_data; i++) { 1872 lncfg->data[i].pos = mipi_csi2->data_lanes[i]; 1873 lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1]; 1874 } 1875 1876 return 0; 1877 } 1878 1879 /* 1880 * camss_of_parse_ports - Parse ports node 1881 * @dev: Device 1882 * @notifier: v4l2_device notifier data 1883 * 1884 * Return number of "port" nodes found in "ports" node 1885 */ 1886 static int camss_of_parse_ports(struct camss *camss) 1887 { 1888 struct device *dev = camss->dev; 1889 struct device_node *node = NULL; 1890 struct device_node *remote = NULL; 1891 int ret, num_subdevs = 0; 1892 1893 for_each_endpoint_of_node(dev->of_node, node) { 1894 struct camss_async_subdev *csd; 1895 1896 if (!of_device_is_available(node)) 1897 continue; 1898 1899 remote = of_graph_get_remote_port_parent(node); 1900 if (!remote) { 1901 dev_err(dev, "Cannot get remote parent\n"); 1902 ret = -EINVAL; 1903 goto err_cleanup; 1904 } 1905 1906 csd = v4l2_async_nf_add_fwnode(&camss->notifier, 1907 of_fwnode_handle(remote), 1908 struct camss_async_subdev); 1909 of_node_put(remote); 1910 if (IS_ERR(csd)) { 1911 ret = PTR_ERR(csd); 1912 goto err_cleanup; 1913 } 1914 1915 ret = camss_of_parse_endpoint_node(dev, node, csd); 1916 if (ret < 0) 1917 goto err_cleanup; 1918 1919 num_subdevs++; 1920 } 1921 1922 return num_subdevs; 1923 1924 err_cleanup: 1925 of_node_put(node); 1926 return ret; 1927 } 1928 1929 /* 1930 * camss_init_subdevices - Initialize subdev structures and resources 1931 * @camss: CAMSS device 1932 * 1933 * Return 0 on success or a negative error code on failure 1934 */ 1935 static int camss_init_subdevices(struct camss *camss) 1936 { 1937 struct platform_device *pdev = to_platform_device(camss->dev); 1938 const struct camss_resources *res = camss->res; 1939 unsigned int i; 1940 int ret; 1941 1942 for (i = 0; i < camss->res->csiphy_num; i++) { 1943 ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i], 1944 &res->csiphy_res[i], i); 1945 if (ret < 0) { 1946 dev_err(camss->dev, 1947 "Failed to init csiphy%d sub-device: %d\n", 1948 i, ret); 1949 return ret; 1950 } 1951 } 1952 1953 /* note: SM8250 requires VFE to be initialized before CSID */ 1954 for (i = 0; i < camss->res->vfe_num; i++) { 1955 ret = msm_vfe_subdev_init(camss, &camss->vfe[i], 1956 &res->vfe_res[i], i); 1957 if (ret < 0) { 1958 dev_err(camss->dev, 1959 "Fail to init vfe%d sub-device: %d\n", i, ret); 1960 return ret; 1961 } 1962 } 1963 1964 /* Get optional CSID wrapper regs shared between CSID devices */ 1965 if (res->csid_wrapper_res) { 1966 char *reg = res->csid_wrapper_res->reg; 1967 void __iomem *base; 1968 1969 base = devm_platform_ioremap_resource_byname(pdev, reg); 1970 if (IS_ERR(base)) 1971 return PTR_ERR(base); 1972 camss->csid_wrapper_base = base; 1973 } 1974 1975 for (i = 0; i < camss->res->csid_num; i++) { 1976 ret = msm_csid_subdev_init(camss, &camss->csid[i], 1977 &res->csid_res[i], i); 1978 if (ret < 0) { 1979 dev_err(camss->dev, 1980 "Failed to init csid%d sub-device: %d\n", 1981 i, ret); 1982 return ret; 1983 } 1984 } 1985 1986 ret = msm_ispif_subdev_init(camss, res->ispif_res); 1987 if (ret < 0) { 1988 dev_err(camss->dev, "Failed to init ispif sub-device: %d\n", 1989 ret); 1990 return ret; 1991 } 1992 1993 return 0; 1994 } 1995 1996 /* 1997 * camss_link_entities - Register subdev nodes and create links 1998 * @camss: CAMSS device 1999 * 2000 * Return 0 on success or a negative error code on failure 2001 */ 2002 static int camss_link_entities(struct camss *camss) 2003 { 2004 int i, j, k; 2005 int ret; 2006 2007 for (i = 0; i < camss->res->csiphy_num; i++) { 2008 for (j = 0; j < camss->res->csid_num; j++) { 2009 ret = media_create_pad_link(&camss->csiphy[i].subdev.entity, 2010 MSM_CSIPHY_PAD_SRC, 2011 &camss->csid[j].subdev.entity, 2012 MSM_CSID_PAD_SINK, 2013 0); 2014 if (ret < 0) { 2015 dev_err(camss->dev, 2016 "Failed to link %s->%s entities: %d\n", 2017 camss->csiphy[i].subdev.entity.name, 2018 camss->csid[j].subdev.entity.name, 2019 ret); 2020 return ret; 2021 } 2022 } 2023 } 2024 2025 if (camss->ispif) { 2026 for (i = 0; i < camss->res->csid_num; i++) { 2027 for (j = 0; j < camss->ispif->line_num; j++) { 2028 ret = media_create_pad_link(&camss->csid[i].subdev.entity, 2029 MSM_CSID_PAD_SRC, 2030 &camss->ispif->line[j].subdev.entity, 2031 MSM_ISPIF_PAD_SINK, 2032 0); 2033 if (ret < 0) { 2034 dev_err(camss->dev, 2035 "Failed to link %s->%s entities: %d\n", 2036 camss->csid[i].subdev.entity.name, 2037 camss->ispif->line[j].subdev.entity.name, 2038 ret); 2039 return ret; 2040 } 2041 } 2042 } 2043 2044 for (i = 0; i < camss->ispif->line_num; i++) 2045 for (k = 0; k < camss->res->vfe_num; k++) 2046 for (j = 0; j < camss->vfe[k].res->line_num; j++) { 2047 struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev; 2048 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; 2049 2050 ret = media_create_pad_link(&ispif->entity, 2051 MSM_ISPIF_PAD_SRC, 2052 &vfe->entity, 2053 MSM_VFE_PAD_SINK, 2054 0); 2055 if (ret < 0) { 2056 dev_err(camss->dev, 2057 "Failed to link %s->%s entities: %d\n", 2058 ispif->entity.name, 2059 vfe->entity.name, 2060 ret); 2061 return ret; 2062 } 2063 } 2064 } else { 2065 for (i = 0; i < camss->res->csid_num; i++) 2066 for (k = 0; k < camss->res->vfe_num; k++) 2067 for (j = 0; j < camss->vfe[k].res->line_num; j++) { 2068 struct v4l2_subdev *csid = &camss->csid[i].subdev; 2069 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; 2070 2071 ret = media_create_pad_link(&csid->entity, 2072 MSM_CSID_PAD_FIRST_SRC + j, 2073 &vfe->entity, 2074 MSM_VFE_PAD_SINK, 2075 0); 2076 if (ret < 0) { 2077 dev_err(camss->dev, 2078 "Failed to link %s->%s entities: %d\n", 2079 csid->entity.name, 2080 vfe->entity.name, 2081 ret); 2082 return ret; 2083 } 2084 } 2085 } 2086 2087 return 0; 2088 } 2089 2090 /* 2091 * camss_register_entities - Register subdev nodes and create links 2092 * @camss: CAMSS device 2093 * 2094 * Return 0 on success or a negative error code on failure 2095 */ 2096 static int camss_register_entities(struct camss *camss) 2097 { 2098 int i; 2099 int ret; 2100 2101 for (i = 0; i < camss->res->csiphy_num; i++) { 2102 ret = msm_csiphy_register_entity(&camss->csiphy[i], 2103 &camss->v4l2_dev); 2104 if (ret < 0) { 2105 dev_err(camss->dev, 2106 "Failed to register csiphy%d entity: %d\n", 2107 i, ret); 2108 goto err_reg_csiphy; 2109 } 2110 } 2111 2112 for (i = 0; i < camss->res->csid_num; i++) { 2113 ret = msm_csid_register_entity(&camss->csid[i], 2114 &camss->v4l2_dev); 2115 if (ret < 0) { 2116 dev_err(camss->dev, 2117 "Failed to register csid%d entity: %d\n", 2118 i, ret); 2119 goto err_reg_csid; 2120 } 2121 } 2122 2123 ret = msm_ispif_register_entities(camss->ispif, 2124 &camss->v4l2_dev); 2125 if (ret < 0) { 2126 dev_err(camss->dev, "Failed to register ispif entities: %d\n", ret); 2127 goto err_reg_ispif; 2128 } 2129 2130 for (i = 0; i < camss->res->vfe_num; i++) { 2131 ret = msm_vfe_register_entities(&camss->vfe[i], 2132 &camss->v4l2_dev); 2133 if (ret < 0) { 2134 dev_err(camss->dev, 2135 "Failed to register vfe%d entities: %d\n", 2136 i, ret); 2137 goto err_reg_vfe; 2138 } 2139 } 2140 2141 return 0; 2142 2143 err_reg_vfe: 2144 for (i--; i >= 0; i--) 2145 msm_vfe_unregister_entities(&camss->vfe[i]); 2146 2147 err_reg_ispif: 2148 msm_ispif_unregister_entities(camss->ispif); 2149 2150 i = camss->res->csid_num; 2151 err_reg_csid: 2152 for (i--; i >= 0; i--) 2153 msm_csid_unregister_entity(&camss->csid[i]); 2154 2155 i = camss->res->csiphy_num; 2156 err_reg_csiphy: 2157 for (i--; i >= 0; i--) 2158 msm_csiphy_unregister_entity(&camss->csiphy[i]); 2159 2160 return ret; 2161 } 2162 2163 /* 2164 * camss_unregister_entities - Unregister subdev nodes 2165 * @camss: CAMSS device 2166 * 2167 * Return 0 on success or a negative error code on failure 2168 */ 2169 static void camss_unregister_entities(struct camss *camss) 2170 { 2171 unsigned int i; 2172 2173 for (i = 0; i < camss->res->csiphy_num; i++) 2174 msm_csiphy_unregister_entity(&camss->csiphy[i]); 2175 2176 for (i = 0; i < camss->res->csid_num; i++) 2177 msm_csid_unregister_entity(&camss->csid[i]); 2178 2179 msm_ispif_unregister_entities(camss->ispif); 2180 2181 for (i = 0; i < camss->res->vfe_num; i++) 2182 msm_vfe_unregister_entities(&camss->vfe[i]); 2183 } 2184 2185 static int camss_subdev_notifier_bound(struct v4l2_async_notifier *async, 2186 struct v4l2_subdev *subdev, 2187 struct v4l2_async_connection *asd) 2188 { 2189 struct camss *camss = container_of(async, struct camss, notifier); 2190 struct camss_async_subdev *csd = 2191 container_of(asd, struct camss_async_subdev, asd); 2192 u8 id = csd->interface.csiphy_id; 2193 struct csiphy_device *csiphy = &camss->csiphy[id]; 2194 2195 csiphy->cfg.csi2 = &csd->interface.csi2; 2196 subdev->host_priv = csiphy; 2197 2198 return 0; 2199 } 2200 2201 static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async) 2202 { 2203 struct camss *camss = container_of(async, struct camss, notifier); 2204 struct v4l2_device *v4l2_dev = &camss->v4l2_dev; 2205 struct v4l2_subdev *sd; 2206 int ret; 2207 2208 list_for_each_entry(sd, &v4l2_dev->subdevs, list) { 2209 if (sd->host_priv) { 2210 struct media_entity *sensor = &sd->entity; 2211 struct csiphy_device *csiphy = 2212 (struct csiphy_device *) sd->host_priv; 2213 struct media_entity *input = &csiphy->subdev.entity; 2214 unsigned int i; 2215 2216 for (i = 0; i < sensor->num_pads; i++) { 2217 if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE) 2218 break; 2219 } 2220 if (i == sensor->num_pads) { 2221 dev_err(camss->dev, 2222 "No source pad in external entity\n"); 2223 return -EINVAL; 2224 } 2225 2226 ret = media_create_pad_link(sensor, i, 2227 input, MSM_CSIPHY_PAD_SINK, 2228 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); 2229 if (ret < 0) { 2230 dev_err(camss->dev, 2231 "Failed to link %s->%s entities: %d\n", 2232 sensor->name, input->name, ret); 2233 return ret; 2234 } 2235 } 2236 } 2237 2238 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); 2239 if (ret < 0) 2240 return ret; 2241 2242 return media_device_register(&camss->media_dev); 2243 } 2244 2245 static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = { 2246 .bound = camss_subdev_notifier_bound, 2247 .complete = camss_subdev_notifier_complete, 2248 }; 2249 2250 static const struct media_device_ops camss_media_ops = { 2251 .link_notify = v4l2_pipeline_link_notify, 2252 }; 2253 2254 static int camss_configure_pd(struct camss *camss) 2255 { 2256 const struct camss_resources *res = camss->res; 2257 struct device *dev = camss->dev; 2258 int vfepd_num; 2259 int i; 2260 int ret; 2261 2262 camss->genpd_num = of_count_phandle_with_args(dev->of_node, 2263 "power-domains", 2264 "#power-domain-cells"); 2265 if (camss->genpd_num < 0) { 2266 dev_err(dev, "Power domains are not defined for camss\n"); 2267 return camss->genpd_num; 2268 } 2269 2270 /* 2271 * If a platform device has just one power domain, then it is attached 2272 * at platform_probe() level, thus there shall be no need and even no 2273 * option to attach it again, this is the case for CAMSS on MSM8916. 2274 */ 2275 if (camss->genpd_num == 1) 2276 return 0; 2277 2278 /* count the # of VFEs which have flagged power-domain */ 2279 for (vfepd_num = i = 0; i < camss->res->vfe_num; i++) { 2280 if (res->vfe_res[i].vfe.has_pd) 2281 vfepd_num++; 2282 } 2283 2284 /* 2285 * If the number of power-domains is greater than the number of VFEs 2286 * then the additional power-domain is for the entire CAMSS block. 2287 */ 2288 if (!(camss->genpd_num > vfepd_num)) 2289 return 0; 2290 2291 /* 2292 * If a power-domain name is defined try to use it. 2293 * It is possible we are running a new kernel with an old dtb so 2294 * fallback to indexes even if a pd_name is defined but not found. 2295 */ 2296 if (camss->res->pd_name) { 2297 camss->genpd = dev_pm_domain_attach_by_name(camss->dev, 2298 camss->res->pd_name); 2299 if (IS_ERR(camss->genpd)) 2300 return PTR_ERR(camss->genpd); 2301 } 2302 2303 if (!camss->genpd) { 2304 /* 2305 * Legacy magic index. TITAN_TOP GDSC must be the last 2306 * item in the power-domain list. 2307 */ 2308 camss->genpd = dev_pm_domain_attach_by_id(camss->dev, 2309 camss->genpd_num - 1); 2310 if (IS_ERR(camss->genpd)) 2311 return PTR_ERR(camss->genpd); 2312 } 2313 2314 if (!camss->genpd) 2315 return -ENODEV; 2316 2317 camss->genpd_link = device_link_add(camss->dev, camss->genpd, 2318 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | 2319 DL_FLAG_RPM_ACTIVE); 2320 if (!camss->genpd_link) { 2321 ret = -EINVAL; 2322 goto fail_pm; 2323 } 2324 2325 return 0; 2326 2327 fail_pm: 2328 dev_pm_domain_detach(camss->genpd, true); 2329 2330 return ret; 2331 } 2332 2333 static int camss_icc_get(struct camss *camss) 2334 { 2335 const struct resources_icc *icc_res; 2336 int i; 2337 2338 icc_res = camss->res->icc_res; 2339 2340 for (i = 0; i < camss->res->icc_path_num; i++) { 2341 camss->icc_path[i] = devm_of_icc_get(camss->dev, 2342 icc_res[i].name); 2343 if (IS_ERR(camss->icc_path[i])) 2344 return PTR_ERR(camss->icc_path[i]); 2345 } 2346 2347 return 0; 2348 } 2349 2350 static void camss_genpd_subdevice_cleanup(struct camss *camss) 2351 { 2352 int i; 2353 2354 for (i = 0; i < camss->res->vfe_num; i++) 2355 msm_vfe_genpd_cleanup(&camss->vfe[i]); 2356 } 2357 2358 static void camss_genpd_cleanup(struct camss *camss) 2359 { 2360 if (camss->genpd_num == 1) 2361 return; 2362 2363 camss_genpd_subdevice_cleanup(camss); 2364 2365 if (camss->genpd_link) 2366 device_link_del(camss->genpd_link); 2367 2368 dev_pm_domain_detach(camss->genpd, true); 2369 } 2370 2371 /* 2372 * camss_probe - Probe CAMSS platform device 2373 * @pdev: Pointer to CAMSS platform device 2374 * 2375 * Return 0 on success or a negative error code on failure 2376 */ 2377 static int camss_probe(struct platform_device *pdev) 2378 { 2379 struct device *dev = &pdev->dev; 2380 struct camss *camss; 2381 int num_subdevs; 2382 int ret; 2383 2384 camss = devm_kzalloc(dev, sizeof(*camss), GFP_KERNEL); 2385 if (!camss) 2386 return -ENOMEM; 2387 2388 camss->res = of_device_get_match_data(dev); 2389 2390 atomic_set(&camss->ref_count, 0); 2391 camss->dev = dev; 2392 platform_set_drvdata(pdev, camss); 2393 2394 camss->csiphy = devm_kcalloc(dev, camss->res->csiphy_num, 2395 sizeof(*camss->csiphy), GFP_KERNEL); 2396 if (!camss->csiphy) 2397 return -ENOMEM; 2398 2399 camss->csid = devm_kcalloc(dev, camss->res->csid_num, sizeof(*camss->csid), 2400 GFP_KERNEL); 2401 if (!camss->csid) 2402 return -ENOMEM; 2403 2404 if (camss->res->version == CAMSS_8x16 || 2405 camss->res->version == CAMSS_8x53 || 2406 camss->res->version == CAMSS_8x96) { 2407 camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL); 2408 if (!camss->ispif) 2409 return -ENOMEM; 2410 } 2411 2412 camss->vfe = devm_kcalloc(dev, camss->res->vfe_num, 2413 sizeof(*camss->vfe), GFP_KERNEL); 2414 if (!camss->vfe) 2415 return -ENOMEM; 2416 2417 ret = camss_icc_get(camss); 2418 if (ret < 0) 2419 return ret; 2420 2421 ret = camss_configure_pd(camss); 2422 if (ret < 0) { 2423 dev_err(dev, "Failed to configure power domains: %d\n", ret); 2424 return ret; 2425 } 2426 2427 ret = camss_init_subdevices(camss); 2428 if (ret < 0) 2429 goto err_genpd_cleanup; 2430 2431 ret = dma_set_mask_and_coherent(dev, 0xffffffff); 2432 if (ret) 2433 goto err_genpd_cleanup; 2434 2435 camss->media_dev.dev = camss->dev; 2436 strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem", 2437 sizeof(camss->media_dev.model)); 2438 camss->media_dev.ops = &camss_media_ops; 2439 media_device_init(&camss->media_dev); 2440 2441 camss->v4l2_dev.mdev = &camss->media_dev; 2442 ret = v4l2_device_register(camss->dev, &camss->v4l2_dev); 2443 if (ret < 0) { 2444 dev_err(dev, "Failed to register V4L2 device: %d\n", ret); 2445 goto err_genpd_cleanup; 2446 } 2447 2448 v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev); 2449 2450 pm_runtime_enable(dev); 2451 2452 num_subdevs = camss_of_parse_ports(camss); 2453 if (num_subdevs < 0) { 2454 ret = num_subdevs; 2455 goto err_v4l2_device_unregister; 2456 } 2457 2458 ret = camss_register_entities(camss); 2459 if (ret < 0) 2460 goto err_v4l2_device_unregister; 2461 2462 ret = camss->res->link_entities(camss); 2463 if (ret < 0) 2464 goto err_register_subdevs; 2465 2466 if (num_subdevs) { 2467 camss->notifier.ops = &camss_subdev_notifier_ops; 2468 2469 ret = v4l2_async_nf_register(&camss->notifier); 2470 if (ret) { 2471 dev_err(dev, 2472 "Failed to register async subdev nodes: %d\n", 2473 ret); 2474 goto err_register_subdevs; 2475 } 2476 } else { 2477 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); 2478 if (ret < 0) { 2479 dev_err(dev, "Failed to register subdev nodes: %d\n", 2480 ret); 2481 goto err_register_subdevs; 2482 } 2483 2484 ret = media_device_register(&camss->media_dev); 2485 if (ret < 0) { 2486 dev_err(dev, "Failed to register media device: %d\n", 2487 ret); 2488 goto err_register_subdevs; 2489 } 2490 } 2491 2492 return 0; 2493 2494 err_register_subdevs: 2495 camss_unregister_entities(camss); 2496 err_v4l2_device_unregister: 2497 v4l2_device_unregister(&camss->v4l2_dev); 2498 v4l2_async_nf_cleanup(&camss->notifier); 2499 pm_runtime_disable(dev); 2500 err_genpd_cleanup: 2501 camss_genpd_cleanup(camss); 2502 2503 return ret; 2504 } 2505 2506 void camss_delete(struct camss *camss) 2507 { 2508 v4l2_device_unregister(&camss->v4l2_dev); 2509 media_device_unregister(&camss->media_dev); 2510 media_device_cleanup(&camss->media_dev); 2511 2512 pm_runtime_disable(camss->dev); 2513 } 2514 2515 /* 2516 * camss_remove - Remove CAMSS platform device 2517 * @pdev: Pointer to CAMSS platform device 2518 * 2519 * Always returns 0. 2520 */ 2521 static void camss_remove(struct platform_device *pdev) 2522 { 2523 struct camss *camss = platform_get_drvdata(pdev); 2524 2525 v4l2_async_nf_unregister(&camss->notifier); 2526 v4l2_async_nf_cleanup(&camss->notifier); 2527 camss_unregister_entities(camss); 2528 2529 if (atomic_read(&camss->ref_count) == 0) 2530 camss_delete(camss); 2531 2532 camss_genpd_cleanup(camss); 2533 } 2534 2535 static const struct camss_resources msm8916_resources = { 2536 .version = CAMSS_8x16, 2537 .csiphy_res = csiphy_res_8x16, 2538 .csid_res = csid_res_8x16, 2539 .ispif_res = &ispif_res_8x16, 2540 .vfe_res = vfe_res_8x16, 2541 .csiphy_num = ARRAY_SIZE(csiphy_res_8x16), 2542 .csid_num = ARRAY_SIZE(csid_res_8x16), 2543 .vfe_num = ARRAY_SIZE(vfe_res_8x16), 2544 .link_entities = camss_link_entities 2545 }; 2546 2547 static const struct camss_resources msm8953_resources = { 2548 .version = CAMSS_8x53, 2549 .icc_res = icc_res_8x53, 2550 .icc_path_num = ARRAY_SIZE(icc_res_8x53), 2551 .csiphy_res = csiphy_res_8x96, 2552 .csid_res = csid_res_8x53, 2553 .ispif_res = &ispif_res_8x53, 2554 .vfe_res = vfe_res_8x53, 2555 .csiphy_num = ARRAY_SIZE(csiphy_res_8x96), 2556 .csid_num = ARRAY_SIZE(csid_res_8x53), 2557 .vfe_num = ARRAY_SIZE(vfe_res_8x53), 2558 .link_entities = camss_link_entities 2559 }; 2560 2561 static const struct camss_resources msm8996_resources = { 2562 .version = CAMSS_8x96, 2563 .csiphy_res = csiphy_res_8x96, 2564 .csid_res = csid_res_8x96, 2565 .ispif_res = &ispif_res_8x96, 2566 .vfe_res = vfe_res_8x96, 2567 .csiphy_num = ARRAY_SIZE(csiphy_res_8x96), 2568 .csid_num = ARRAY_SIZE(csid_res_8x96), 2569 .vfe_num = ARRAY_SIZE(vfe_res_8x96), 2570 .link_entities = camss_link_entities 2571 }; 2572 2573 static const struct camss_resources sdm660_resources = { 2574 .version = CAMSS_660, 2575 .csiphy_res = csiphy_res_660, 2576 .csid_res = csid_res_660, 2577 .ispif_res = &ispif_res_660, 2578 .vfe_res = vfe_res_660, 2579 .csiphy_num = ARRAY_SIZE(csiphy_res_660), 2580 .csid_num = ARRAY_SIZE(csid_res_660), 2581 .vfe_num = ARRAY_SIZE(vfe_res_660), 2582 .link_entities = camss_link_entities 2583 }; 2584 2585 static const struct camss_resources sdm845_resources = { 2586 .version = CAMSS_845, 2587 .csiphy_res = csiphy_res_845, 2588 .csid_res = csid_res_845, 2589 .vfe_res = vfe_res_845, 2590 .csiphy_num = ARRAY_SIZE(csiphy_res_845), 2591 .csid_num = ARRAY_SIZE(csid_res_845), 2592 .vfe_num = ARRAY_SIZE(vfe_res_845), 2593 .link_entities = camss_link_entities 2594 }; 2595 2596 static const struct camss_resources sm8250_resources = { 2597 .version = CAMSS_8250, 2598 .pd_name = "top", 2599 .csiphy_res = csiphy_res_8250, 2600 .csid_res = csid_res_8250, 2601 .vfe_res = vfe_res_8250, 2602 .icc_res = icc_res_sm8250, 2603 .icc_path_num = ARRAY_SIZE(icc_res_sm8250), 2604 .csiphy_num = ARRAY_SIZE(csiphy_res_8250), 2605 .csid_num = ARRAY_SIZE(csid_res_8250), 2606 .vfe_num = ARRAY_SIZE(vfe_res_8250), 2607 .link_entities = camss_link_entities 2608 }; 2609 2610 static const struct camss_resources sc8280xp_resources = { 2611 .version = CAMSS_8280XP, 2612 .pd_name = "top", 2613 .csiphy_res = csiphy_res_sc8280xp, 2614 .csid_res = csid_res_sc8280xp, 2615 .ispif_res = NULL, 2616 .vfe_res = vfe_res_sc8280xp, 2617 .icc_res = icc_res_sc8280xp, 2618 .icc_path_num = ARRAY_SIZE(icc_res_sc8280xp), 2619 .csiphy_num = ARRAY_SIZE(csiphy_res_sc8280xp), 2620 .csid_num = ARRAY_SIZE(csid_res_sc8280xp), 2621 .vfe_num = ARRAY_SIZE(vfe_res_sc8280xp), 2622 .link_entities = camss_link_entities 2623 }; 2624 2625 static const struct of_device_id camss_dt_match[] = { 2626 { .compatible = "qcom,msm8916-camss", .data = &msm8916_resources }, 2627 { .compatible = "qcom,msm8953-camss", .data = &msm8953_resources }, 2628 { .compatible = "qcom,msm8996-camss", .data = &msm8996_resources }, 2629 { .compatible = "qcom,sdm660-camss", .data = &sdm660_resources }, 2630 { .compatible = "qcom,sdm845-camss", .data = &sdm845_resources }, 2631 { .compatible = "qcom,sm8250-camss", .data = &sm8250_resources }, 2632 { .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources }, 2633 { } 2634 }; 2635 2636 MODULE_DEVICE_TABLE(of, camss_dt_match); 2637 2638 static int __maybe_unused camss_runtime_suspend(struct device *dev) 2639 { 2640 struct camss *camss = dev_get_drvdata(dev); 2641 int i; 2642 int ret; 2643 2644 for (i = 0; i < camss->res->icc_path_num; i++) { 2645 ret = icc_set_bw(camss->icc_path[i], 0, 0); 2646 if (ret) 2647 return ret; 2648 } 2649 2650 return 0; 2651 } 2652 2653 static int __maybe_unused camss_runtime_resume(struct device *dev) 2654 { 2655 struct camss *camss = dev_get_drvdata(dev); 2656 const struct resources_icc *icc_res = camss->res->icc_res; 2657 int i; 2658 int ret; 2659 2660 for (i = 0; i < camss->res->icc_path_num; i++) { 2661 ret = icc_set_bw(camss->icc_path[i], 2662 icc_res[i].icc_bw_tbl.avg, 2663 icc_res[i].icc_bw_tbl.peak); 2664 if (ret) 2665 return ret; 2666 } 2667 2668 return 0; 2669 } 2670 2671 static const struct dev_pm_ops camss_pm_ops = { 2672 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 2673 pm_runtime_force_resume) 2674 SET_RUNTIME_PM_OPS(camss_runtime_suspend, camss_runtime_resume, NULL) 2675 }; 2676 2677 static struct platform_driver qcom_camss_driver = { 2678 .probe = camss_probe, 2679 .remove = camss_remove, 2680 .driver = { 2681 .name = "qcom-camss", 2682 .of_match_table = camss_dt_match, 2683 .pm = &camss_pm_ops, 2684 }, 2685 }; 2686 2687 module_platform_driver(qcom_camss_driver); 2688 2689 MODULE_ALIAS("platform:qcom-camss"); 2690 MODULE_DESCRIPTION("Qualcomm Camera Subsystem driver"); 2691 MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>"); 2692 MODULE_LICENSE("GPL v2"); 2693