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