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
 468/*
 469 * camss_add_clock_margin - Add margin to clock frequency rate
 470 * @rate: Clock frequency rate
 471 *
 472 * When making calculations with physical clock frequency values
 473 * some safety margin must be added. Add it.
 474 */
 475inline void camss_add_clock_margin(u64 *rate)
 476{
 477        *rate *= CAMSS_CLOCK_MARGIN_NUMERATOR;
 478        *rate = div_u64(*rate, CAMSS_CLOCK_MARGIN_DENOMINATOR);
 479}
 480
 481/*
 482 * camss_enable_clocks - Enable multiple clocks
 483 * @nclocks: Number of clocks in clock array
 484 * @clock: Clock array
 485 * @dev: Device
 486 *
 487 * Return 0 on success or a negative error code otherwise
 488 */
 489int camss_enable_clocks(int nclocks, struct camss_clock *clock,
 490                        struct device *dev)
 491{
 492        int ret;
 493        int i;
 494
 495        for (i = 0; i < nclocks; i++) {
 496                ret = clk_prepare_enable(clock[i].clk);
 497                if (ret) {
 498                        dev_err(dev, "clock enable failed: %d\n", ret);
 499                        goto error;
 500                }
 501        }
 502
 503        return 0;
 504
 505error:
 506        for (i--; i >= 0; i--)
 507                clk_disable_unprepare(clock[i].clk);
 508
 509        return ret;
 510}
 511
 512/*
 513 * camss_disable_clocks - Disable multiple clocks
 514 * @nclocks: Number of clocks in clock array
 515 * @clock: Clock array
 516 */
 517void camss_disable_clocks(int nclocks, struct camss_clock *clock)
 518{
 519        int i;
 520
 521        for (i = nclocks - 1; i >= 0; i--)
 522                clk_disable_unprepare(clock[i].clk);
 523}
 524
 525/*
 526 * camss_find_sensor - Find a linked media entity which represents a sensor
 527 * @entity: Media entity to start searching from
 528 *
 529 * Return a pointer to sensor media entity or NULL if not found
 530 */
 531struct media_entity *camss_find_sensor(struct media_entity *entity)
 532{
 533        struct media_pad *pad;
 534
 535        while (1) {
 536                pad = &entity->pads[0];
 537                if (!(pad->flags & MEDIA_PAD_FL_SINK))
 538                        return NULL;
 539
 540                pad = media_entity_remote_pad(pad);
 541                if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 542                        return NULL;
 543
 544                entity = pad->entity;
 545
 546                if (entity->function == MEDIA_ENT_F_CAM_SENSOR)
 547                        return entity;
 548        }
 549}
 550
 551/*
 552 * camss_get_pixel_clock - Get pixel clock rate from sensor
 553 * @entity: Media entity in the current pipeline
 554 * @pixel_clock: Received pixel clock value
 555 *
 556 * Return 0 on success or a negative error code otherwise
 557 */
 558int camss_get_pixel_clock(struct media_entity *entity, u32 *pixel_clock)
 559{
 560        struct media_entity *sensor;
 561        struct v4l2_subdev *subdev;
 562        struct v4l2_ctrl *ctrl;
 563
 564        sensor = camss_find_sensor(entity);
 565        if (!sensor)
 566                return -ENODEV;
 567
 568        subdev = media_entity_to_v4l2_subdev(sensor);
 569
 570        ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE);
 571
 572        if (!ctrl)
 573                return -EINVAL;
 574
 575        *pixel_clock = v4l2_ctrl_g_ctrl_int64(ctrl);
 576
 577        return 0;
 578}
 579
 580int camss_pm_domain_on(struct camss *camss, int id)
 581{
 582        if (camss->version == CAMSS_8x96 ||
 583            camss->version == CAMSS_660) {
 584                camss->genpd_link[id] = device_link_add(camss->dev,
 585                                camss->genpd[id], DL_FLAG_STATELESS |
 586                                DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
 587
 588                if (!camss->genpd_link[id])
 589                        return -EINVAL;
 590        }
 591
 592        return 0;
 593}
 594
 595void camss_pm_domain_off(struct camss *camss, int id)
 596{
 597        if (camss->version == CAMSS_8x96 ||
 598            camss->version == CAMSS_660)
 599                device_link_del(camss->genpd_link[id]);
 600}
 601
 602/*
 603 * camss_of_parse_endpoint_node - Parse port endpoint node
 604 * @dev: Device
 605 * @node: Device node to be parsed
 606 * @csd: Parsed data from port endpoint node
 607 *
 608 * Return 0 on success or a negative error code on failure
 609 */
 610static int camss_of_parse_endpoint_node(struct device *dev,
 611                                        struct device_node *node,
 612                                        struct camss_async_subdev *csd)
 613{
 614        struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg;
 615        struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2;
 616        struct v4l2_fwnode_endpoint vep = { { 0 } };
 617        unsigned int i;
 618
 619        v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
 620
 621        csd->interface.csiphy_id = vep.base.port;
 622
 623        mipi_csi2 = &vep.bus.mipi_csi2;
 624        lncfg->clk.pos = mipi_csi2->clock_lane;
 625        lncfg->clk.pol = mipi_csi2->lane_polarities[0];
 626        lncfg->num_data = mipi_csi2->num_data_lanes;
 627
 628        lncfg->data = devm_kcalloc(dev,
 629                                   lncfg->num_data, sizeof(*lncfg->data),
 630                                   GFP_KERNEL);
 631        if (!lncfg->data)
 632                return -ENOMEM;
 633
 634        for (i = 0; i < lncfg->num_data; i++) {
 635                lncfg->data[i].pos = mipi_csi2->data_lanes[i];
 636                lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1];
 637        }
 638
 639        return 0;
 640}
 641
 642/*
 643 * camss_of_parse_ports - Parse ports node
 644 * @dev: Device
 645 * @notifier: v4l2_device notifier data
 646 *
 647 * Return number of "port" nodes found in "ports" node
 648 */
 649static int camss_of_parse_ports(struct camss *camss)
 650{
 651        struct device *dev = camss->dev;
 652        struct device_node *node = NULL;
 653        struct device_node *remote = NULL;
 654        int ret, num_subdevs = 0;
 655
 656        for_each_endpoint_of_node(dev->of_node, node) {
 657                struct camss_async_subdev *csd;
 658                struct v4l2_async_subdev *asd;
 659
 660                if (!of_device_is_available(node))
 661                        continue;
 662
 663                remote = of_graph_get_remote_port_parent(node);
 664                if (!remote) {
 665                        dev_err(dev, "Cannot get remote parent\n");
 666                        ret = -EINVAL;
 667                        goto err_cleanup;
 668                }
 669
 670                asd = v4l2_async_notifier_add_fwnode_subdev(
 671                        &camss->notifier, of_fwnode_handle(remote),
 672                        sizeof(*csd));
 673                of_node_put(remote);
 674                if (IS_ERR(asd)) {
 675                        ret = PTR_ERR(asd);
 676                        goto err_cleanup;
 677                }
 678
 679                csd = container_of(asd, struct camss_async_subdev, asd);
 680
 681                ret = camss_of_parse_endpoint_node(dev, node, csd);
 682                if (ret < 0)
 683                        goto err_cleanup;
 684
 685                num_subdevs++;
 686        }
 687
 688        return num_subdevs;
 689
 690err_cleanup:
 691        of_node_put(node);
 692        return ret;
 693}
 694
 695/*
 696 * camss_init_subdevices - Initialize subdev structures and resources
 697 * @camss: CAMSS device
 698 *
 699 * Return 0 on success or a negative error code on failure
 700 */
 701static int camss_init_subdevices(struct camss *camss)
 702{
 703        const struct resources *csiphy_res;
 704        const struct resources *csid_res;
 705        const struct resources_ispif *ispif_res;
 706        const struct resources *vfe_res;
 707        unsigned int i;
 708        int ret;
 709
 710        if (camss->version == CAMSS_8x16) {
 711                csiphy_res = csiphy_res_8x16;
 712                csid_res = csid_res_8x16;
 713                ispif_res = &ispif_res_8x16;
 714                vfe_res = vfe_res_8x16;
 715        } else if (camss->version == CAMSS_8x96) {
 716                csiphy_res = csiphy_res_8x96;
 717                csid_res = csid_res_8x96;
 718                ispif_res = &ispif_res_8x96;
 719                vfe_res = vfe_res_8x96;
 720        } else if (camss->version == CAMSS_660) {
 721                csiphy_res = csiphy_res_660;
 722                csid_res = csid_res_660;
 723                ispif_res = &ispif_res_660;
 724                vfe_res = vfe_res_660;
 725        } else {
 726                return -EINVAL;
 727        }
 728
 729        for (i = 0; i < camss->csiphy_num; i++) {
 730                ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i],
 731                                             &csiphy_res[i], i);
 732                if (ret < 0) {
 733                        dev_err(camss->dev,
 734                                "Failed to init csiphy%d sub-device: %d\n",
 735                                i, ret);
 736                        return ret;
 737                }
 738        }
 739
 740        for (i = 0; i < camss->csid_num; i++) {
 741                ret = msm_csid_subdev_init(camss, &camss->csid[i],
 742                                           &csid_res[i], i);
 743                if (ret < 0) {
 744                        dev_err(camss->dev,
 745                                "Failed to init csid%d sub-device: %d\n",
 746                                i, ret);
 747                        return ret;
 748                }
 749        }
 750
 751        ret = msm_ispif_subdev_init(&camss->ispif, ispif_res);
 752        if (ret < 0) {
 753                dev_err(camss->dev, "Failed to init ispif sub-device: %d\n",
 754                        ret);
 755                return ret;
 756        }
 757
 758        for (i = 0; i < camss->vfe_num; i++) {
 759                ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
 760                                          &vfe_res[i], i);
 761                if (ret < 0) {
 762                        dev_err(camss->dev,
 763                                "Fail to init vfe%d sub-device: %d\n", i, ret);
 764                        return ret;
 765                }
 766        }
 767
 768        return 0;
 769}
 770
 771/*
 772 * camss_register_entities - Register subdev nodes and create links
 773 * @camss: CAMSS device
 774 *
 775 * Return 0 on success or a negative error code on failure
 776 */
 777static int camss_register_entities(struct camss *camss)
 778{
 779        int i, j, k;
 780        int ret;
 781
 782        for (i = 0; i < camss->csiphy_num; i++) {
 783                ret = msm_csiphy_register_entity(&camss->csiphy[i],
 784                                                 &camss->v4l2_dev);
 785                if (ret < 0) {
 786                        dev_err(camss->dev,
 787                                "Failed to register csiphy%d entity: %d\n",
 788                                i, ret);
 789                        goto err_reg_csiphy;
 790                }
 791        }
 792
 793        for (i = 0; i < camss->csid_num; i++) {
 794                ret = msm_csid_register_entity(&camss->csid[i],
 795                                               &camss->v4l2_dev);
 796                if (ret < 0) {
 797                        dev_err(camss->dev,
 798                                "Failed to register csid%d entity: %d\n",
 799                                i, ret);
 800                        goto err_reg_csid;
 801                }
 802        }
 803
 804        ret = msm_ispif_register_entities(&camss->ispif, &camss->v4l2_dev);
 805        if (ret < 0) {
 806                dev_err(camss->dev, "Failed to register ispif entities: %d\n",
 807                        ret);
 808                goto err_reg_ispif;
 809        }
 810
 811        for (i = 0; i < camss->vfe_num; i++) {
 812                ret = msm_vfe_register_entities(&camss->vfe[i],
 813                                                &camss->v4l2_dev);
 814                if (ret < 0) {
 815                        dev_err(camss->dev,
 816                                "Failed to register vfe%d entities: %d\n",
 817                                i, ret);
 818                        goto err_reg_vfe;
 819                }
 820        }
 821
 822        for (i = 0; i < camss->csiphy_num; i++) {
 823                for (j = 0; j < camss->csid_num; j++) {
 824                        ret = media_create_pad_link(
 825                                &camss->csiphy[i].subdev.entity,
 826                                MSM_CSIPHY_PAD_SRC,
 827                                &camss->csid[j].subdev.entity,
 828                                MSM_CSID_PAD_SINK,
 829                                0);
 830                        if (ret < 0) {
 831                                dev_err(camss->dev,
 832                                        "Failed to link %s->%s entities: %d\n",
 833                                        camss->csiphy[i].subdev.entity.name,
 834                                        camss->csid[j].subdev.entity.name,
 835                                        ret);
 836                                goto err_link;
 837                        }
 838                }
 839        }
 840
 841        for (i = 0; i < camss->csid_num; i++) {
 842                for (j = 0; j < camss->ispif.line_num; j++) {
 843                        ret = media_create_pad_link(
 844                                &camss->csid[i].subdev.entity,
 845                                MSM_CSID_PAD_SRC,
 846                                &camss->ispif.line[j].subdev.entity,
 847                                MSM_ISPIF_PAD_SINK,
 848                                0);
 849                        if (ret < 0) {
 850                                dev_err(camss->dev,
 851                                        "Failed to link %s->%s entities: %d\n",
 852                                        camss->csid[i].subdev.entity.name,
 853                                        camss->ispif.line[j].subdev.entity.name,
 854                                        ret);
 855                                goto err_link;
 856                        }
 857                }
 858        }
 859
 860        for (i = 0; i < camss->ispif.line_num; i++)
 861                for (k = 0; k < camss->vfe_num; k++)
 862                        for (j = 0; j < ARRAY_SIZE(camss->vfe[k].line); j++) {
 863                                ret = media_create_pad_link(
 864                                        &camss->ispif.line[i].subdev.entity,
 865                                        MSM_ISPIF_PAD_SRC,
 866                                        &camss->vfe[k].line[j].subdev.entity,
 867                                        MSM_VFE_PAD_SINK,
 868                                        0);
 869                                if (ret < 0) {
 870                                        dev_err(camss->dev,
 871                                                "Failed to link %s->%s entities: %d\n",
 872                                                camss->ispif.line[i].subdev.entity.name,
 873                                                camss->vfe[k].line[j].subdev.entity.name,
 874                                                ret);
 875                                        goto err_link;
 876                                }
 877                        }
 878
 879        return 0;
 880
 881err_link:
 882        i = camss->vfe_num;
 883err_reg_vfe:
 884        for (i--; i >= 0; i--)
 885                msm_vfe_unregister_entities(&camss->vfe[i]);
 886
 887        msm_ispif_unregister_entities(&camss->ispif);
 888err_reg_ispif:
 889
 890        i = camss->csid_num;
 891err_reg_csid:
 892        for (i--; i >= 0; i--)
 893                msm_csid_unregister_entity(&camss->csid[i]);
 894
 895        i = camss->csiphy_num;
 896err_reg_csiphy:
 897        for (i--; i >= 0; i--)
 898                msm_csiphy_unregister_entity(&camss->csiphy[i]);
 899
 900        return ret;
 901}
 902
 903/*
 904 * camss_unregister_entities - Unregister subdev nodes
 905 * @camss: CAMSS device
 906 *
 907 * Return 0 on success or a negative error code on failure
 908 */
 909static void camss_unregister_entities(struct camss *camss)
 910{
 911        unsigned int i;
 912
 913        for (i = 0; i < camss->csiphy_num; i++)
 914                msm_csiphy_unregister_entity(&camss->csiphy[i]);
 915
 916        for (i = 0; i < camss->csid_num; i++)
 917                msm_csid_unregister_entity(&camss->csid[i]);
 918
 919        msm_ispif_unregister_entities(&camss->ispif);
 920
 921        for (i = 0; i < camss->vfe_num; i++)
 922                msm_vfe_unregister_entities(&camss->vfe[i]);
 923}
 924
 925static int camss_subdev_notifier_bound(struct v4l2_async_notifier *async,
 926                                       struct v4l2_subdev *subdev,
 927                                       struct v4l2_async_subdev *asd)
 928{
 929        struct camss *camss = container_of(async, struct camss, notifier);
 930        struct camss_async_subdev *csd =
 931                container_of(asd, struct camss_async_subdev, asd);
 932        u8 id = csd->interface.csiphy_id;
 933        struct csiphy_device *csiphy = &camss->csiphy[id];
 934
 935        csiphy->cfg.csi2 = &csd->interface.csi2;
 936        subdev->host_priv = csiphy;
 937
 938        return 0;
 939}
 940
 941static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async)
 942{
 943        struct camss *camss = container_of(async, struct camss, notifier);
 944        struct v4l2_device *v4l2_dev = &camss->v4l2_dev;
 945        struct v4l2_subdev *sd;
 946        int ret;
 947
 948        list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
 949                if (sd->host_priv) {
 950                        struct media_entity *sensor = &sd->entity;
 951                        struct csiphy_device *csiphy =
 952                                        (struct csiphy_device *) sd->host_priv;
 953                        struct media_entity *input = &csiphy->subdev.entity;
 954                        unsigned int i;
 955
 956                        for (i = 0; i < sensor->num_pads; i++) {
 957                                if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
 958                                        break;
 959                        }
 960                        if (i == sensor->num_pads) {
 961                                dev_err(camss->dev,
 962                                        "No source pad in external entity\n");
 963                                return -EINVAL;
 964                        }
 965
 966                        ret = media_create_pad_link(sensor, i,
 967                                input, MSM_CSIPHY_PAD_SINK,
 968                                MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 969                        if (ret < 0) {
 970                                dev_err(camss->dev,
 971                                        "Failed to link %s->%s entities: %d\n",
 972                                        sensor->name, input->name, ret);
 973                                return ret;
 974                        }
 975                }
 976        }
 977
 978        ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
 979        if (ret < 0)
 980                return ret;
 981
 982        return media_device_register(&camss->media_dev);
 983}
 984
 985static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = {
 986        .bound = camss_subdev_notifier_bound,
 987        .complete = camss_subdev_notifier_complete,
 988};
 989
 990static const struct media_device_ops camss_media_ops = {
 991        .link_notify = v4l2_pipeline_link_notify,
 992};
 993
 994/*
 995 * camss_probe - Probe CAMSS platform device
 996 * @pdev: Pointer to CAMSS platform device
 997 *
 998 * Return 0 on success or a negative error code on failure
 999 */
1000static int camss_probe(struct platform_device *pdev)
1001{
1002        struct device *dev = &pdev->dev;
1003        struct camss *camss;
1004        int num_subdevs, ret;
1005
1006        camss = kzalloc(sizeof(*camss), GFP_KERNEL);
1007        if (!camss)
1008                return -ENOMEM;
1009
1010        atomic_set(&camss->ref_count, 0);
1011        camss->dev = dev;
1012        platform_set_drvdata(pdev, camss);
1013
1014        if (of_device_is_compatible(dev->of_node, "qcom,msm8916-camss")) {
1015                camss->version = CAMSS_8x16;
1016                camss->csiphy_num = 2;
1017                camss->csid_num = 2;
1018                camss->vfe_num = 1;
1019        } else if (of_device_is_compatible(dev->of_node,
1020                                           "qcom,msm8996-camss")) {
1021                camss->version = CAMSS_8x96;
1022                camss->csiphy_num = 3;
1023                camss->csid_num = 4;
1024                camss->vfe_num = 2;
1025        } else if (of_device_is_compatible(dev->of_node,
1026                                           "qcom,sdm660-camss")) {
1027                camss->version = CAMSS_660;
1028                camss->csiphy_num = 3;
1029                camss->csid_num = 4;
1030                camss->vfe_num = 2;
1031        } else {
1032                ret = -EINVAL;
1033                goto err_free;
1034        }
1035
1036        camss->csiphy = devm_kcalloc(dev, camss->csiphy_num,
1037                                     sizeof(*camss->csiphy), GFP_KERNEL);
1038        if (!camss->csiphy) {
1039                ret = -ENOMEM;
1040                goto err_free;
1041        }
1042
1043        camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid),
1044                                   GFP_KERNEL);
1045        if (!camss->csid) {
1046                ret = -ENOMEM;
1047                goto err_free;
1048        }
1049
1050        camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe),
1051                                  GFP_KERNEL);
1052        if (!camss->vfe) {
1053                ret = -ENOMEM;
1054                goto err_free;
1055        }
1056
1057        v4l2_async_notifier_init(&camss->notifier);
1058
1059        num_subdevs = camss_of_parse_ports(camss);
1060        if (num_subdevs < 0) {
1061                ret = num_subdevs;
1062                goto err_cleanup;
1063        }
1064
1065        ret = camss_init_subdevices(camss);
1066        if (ret < 0)
1067                goto err_cleanup;
1068
1069        ret = dma_set_mask_and_coherent(dev, 0xffffffff);
1070        if (ret)
1071                goto err_cleanup;
1072
1073        camss->media_dev.dev = camss->dev;
1074        strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem",
1075                sizeof(camss->media_dev.model));
1076        camss->media_dev.ops = &camss_media_ops;
1077        media_device_init(&camss->media_dev);
1078
1079        camss->v4l2_dev.mdev = &camss->media_dev;
1080        ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
1081        if (ret < 0) {
1082                dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
1083                goto err_cleanup;
1084        }
1085
1086        ret = camss_register_entities(camss);
1087        if (ret < 0)
1088                goto err_register_entities;
1089
1090        if (num_subdevs) {
1091                camss->notifier.ops = &camss_subdev_notifier_ops;
1092
1093                ret = v4l2_async_notifier_register(&camss->v4l2_dev,
1094                                                   &camss->notifier);
1095                if (ret) {
1096                        dev_err(dev,
1097                                "Failed to register async subdev nodes: %d\n",
1098                                ret);
1099                        goto err_register_subdevs;
1100                }
1101        } else {
1102                ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
1103                if (ret < 0) {
1104                        dev_err(dev, "Failed to register subdev nodes: %d\n",
1105                                ret);
1106                        goto err_register_subdevs;
1107                }
1108
1109                ret = media_device_register(&camss->media_dev);
1110                if (ret < 0) {
1111                        dev_err(dev, "Failed to register media device: %d\n",
1112                                ret);
1113                        goto err_register_subdevs;
1114                }
1115        }
1116
1117        if (camss->version == CAMSS_8x96 ||
1118            camss->version == CAMSS_660) {
1119                camss->genpd[PM_DOMAIN_VFE0] = dev_pm_domain_attach_by_id(
1120                                                camss->dev, PM_DOMAIN_VFE0);
1121                if (IS_ERR(camss->genpd[PM_DOMAIN_VFE0]))
1122                        return PTR_ERR(camss->genpd[PM_DOMAIN_VFE0]);
1123
1124                camss->genpd[PM_DOMAIN_VFE1] = dev_pm_domain_attach_by_id(
1125                                                camss->dev, PM_DOMAIN_VFE1);
1126                if (IS_ERR(camss->genpd[PM_DOMAIN_VFE1])) {
1127                        dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE0],
1128                                             true);
1129                        return PTR_ERR(camss->genpd[PM_DOMAIN_VFE1]);
1130                }
1131        }
1132
1133        pm_runtime_enable(dev);
1134
1135        return 0;
1136
1137err_register_subdevs:
1138        camss_unregister_entities(camss);
1139err_register_entities:
1140        v4l2_device_unregister(&camss->v4l2_dev);
1141err_cleanup:
1142        v4l2_async_notifier_cleanup(&camss->notifier);
1143err_free:
1144        kfree(camss);
1145
1146        return ret;
1147}
1148
1149void camss_delete(struct camss *camss)
1150{
1151        v4l2_device_unregister(&camss->v4l2_dev);
1152        media_device_unregister(&camss->media_dev);
1153        media_device_cleanup(&camss->media_dev);
1154
1155        pm_runtime_disable(camss->dev);
1156
1157        if (camss->version == CAMSS_8x96 ||
1158            camss->version == CAMSS_660) {
1159                dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE0], true);
1160                dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE1], true);
1161        }
1162
1163        kfree(camss);
1164}
1165
1166/*
1167 * camss_remove - Remove CAMSS platform device
1168 * @pdev: Pointer to CAMSS platform device
1169 *
1170 * Always returns 0.
1171 */
1172static int camss_remove(struct platform_device *pdev)
1173{
1174        struct camss *camss = platform_get_drvdata(pdev);
1175
1176        v4l2_async_notifier_unregister(&camss->notifier);
1177        v4l2_async_notifier_cleanup(&camss->notifier);
1178        camss_unregister_entities(camss);
1179
1180        if (atomic_read(&camss->ref_count) == 0)
1181                camss_delete(camss);
1182
1183        return 0;
1184}
1185
1186static const struct of_device_id camss_dt_match[] = {
1187        { .compatible = "qcom,msm8916-camss" },
1188        { .compatible = "qcom,msm8996-camss" },
1189        { .compatible = "qcom,sdm660-camss" },
1190        { }
1191};
1192
1193MODULE_DEVICE_TABLE(of, camss_dt_match);
1194
1195static int __maybe_unused camss_runtime_suspend(struct device *dev)
1196{
1197        return 0;
1198}
1199
1200static int __maybe_unused camss_runtime_resume(struct device *dev)
1201{
1202        return 0;
1203}
1204
1205static const struct dev_pm_ops camss_pm_ops = {
1206        SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1207                                pm_runtime_force_resume)
1208        SET_RUNTIME_PM_OPS(camss_runtime_suspend, camss_runtime_resume, NULL)
1209};
1210
1211static struct platform_driver qcom_camss_driver = {
1212        .probe = camss_probe,
1213        .remove = camss_remove,
1214        .driver = {
1215                .name = "qcom-camss",
1216                .of_match_table = camss_dt_match,
1217                .pm = &camss_pm_ops,
1218        },
1219};
1220
1221module_platform_driver(qcom_camss_driver);
1222
1223MODULE_ALIAS("platform:qcom-camss");
1224MODULE_DESCRIPTION("Qualcomm Camera Subsystem driver");
1225MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>");
1226MODULE_LICENSE("GPL v2");
1227