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
 286/*
 287 * camss_add_clock_margin - Add margin to clock frequency rate
 288 * @rate: Clock frequency rate
 289 *
 290 * When making calculations with physical clock frequency values
 291 * some safety margin must be added. Add it.
 292 */
 293inline void camss_add_clock_margin(u64 *rate)
 294{
 295        *rate *= CAMSS_CLOCK_MARGIN_NUMERATOR;
 296        *rate = div_u64(*rate, CAMSS_CLOCK_MARGIN_DENOMINATOR);
 297}
 298
 299/*
 300 * camss_enable_clocks - Enable multiple clocks
 301 * @nclocks: Number of clocks in clock array
 302 * @clock: Clock array
 303 * @dev: Device
 304 *
 305 * Return 0 on success or a negative error code otherwise
 306 */
 307int camss_enable_clocks(int nclocks, struct camss_clock *clock,
 308                        struct device *dev)
 309{
 310        int ret;
 311        int i;
 312
 313        for (i = 0; i < nclocks; i++) {
 314                ret = clk_prepare_enable(clock[i].clk);
 315                if (ret) {
 316                        dev_err(dev, "clock enable failed: %d\n", ret);
 317                        goto error;
 318                }
 319        }
 320
 321        return 0;
 322
 323error:
 324        for (i--; i >= 0; i--)
 325                clk_disable_unprepare(clock[i].clk);
 326
 327        return ret;
 328}
 329
 330/*
 331 * camss_disable_clocks - Disable multiple clocks
 332 * @nclocks: Number of clocks in clock array
 333 * @clock: Clock array
 334 */
 335void camss_disable_clocks(int nclocks, struct camss_clock *clock)
 336{
 337        int i;
 338
 339        for (i = nclocks - 1; i >= 0; i--)
 340                clk_disable_unprepare(clock[i].clk);
 341}
 342
 343/*
 344 * camss_find_sensor - Find a linked media entity which represents a sensor
 345 * @entity: Media entity to start searching from
 346 *
 347 * Return a pointer to sensor media entity or NULL if not found
 348 */
 349static struct media_entity *camss_find_sensor(struct media_entity *entity)
 350{
 351        struct media_pad *pad;
 352
 353        while (1) {
 354                pad = &entity->pads[0];
 355                if (!(pad->flags & MEDIA_PAD_FL_SINK))
 356                        return NULL;
 357
 358                pad = media_entity_remote_pad(pad);
 359                if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 360                        return NULL;
 361
 362                entity = pad->entity;
 363
 364                if (entity->function == MEDIA_ENT_F_CAM_SENSOR)
 365                        return entity;
 366        }
 367}
 368
 369/*
 370 * camss_get_pixel_clock - Get pixel clock rate from sensor
 371 * @entity: Media entity in the current pipeline
 372 * @pixel_clock: Received pixel clock value
 373 *
 374 * Return 0 on success or a negative error code otherwise
 375 */
 376int camss_get_pixel_clock(struct media_entity *entity, u32 *pixel_clock)
 377{
 378        struct media_entity *sensor;
 379        struct v4l2_subdev *subdev;
 380        struct v4l2_ctrl *ctrl;
 381
 382        sensor = camss_find_sensor(entity);
 383        if (!sensor)
 384                return -ENODEV;
 385
 386        subdev = media_entity_to_v4l2_subdev(sensor);
 387
 388        ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE);
 389
 390        if (!ctrl)
 391                return -EINVAL;
 392
 393        *pixel_clock = v4l2_ctrl_g_ctrl_int64(ctrl);
 394
 395        return 0;
 396}
 397
 398int camss_pm_domain_on(struct camss *camss, int id)
 399{
 400        if (camss->version == CAMSS_8x96) {
 401                camss->genpd_link[id] = device_link_add(camss->dev,
 402                                camss->genpd[id], DL_FLAG_STATELESS |
 403                                DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
 404
 405                if (!camss->genpd_link[id])
 406                        return -EINVAL;
 407        }
 408
 409        return 0;
 410}
 411
 412void camss_pm_domain_off(struct camss *camss, int id)
 413{
 414        if (camss->version == CAMSS_8x96)
 415                device_link_del(camss->genpd_link[id]);
 416}
 417
 418/*
 419 * camss_of_parse_endpoint_node - Parse port endpoint node
 420 * @dev: Device
 421 * @node: Device node to be parsed
 422 * @csd: Parsed data from port endpoint node
 423 *
 424 * Return 0 on success or a negative error code on failure
 425 */
 426static int camss_of_parse_endpoint_node(struct device *dev,
 427                                        struct device_node *node,
 428                                        struct camss_async_subdev *csd)
 429{
 430        struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg;
 431        struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2;
 432        struct v4l2_fwnode_endpoint vep = { { 0 } };
 433        unsigned int i;
 434
 435        v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
 436
 437        csd->interface.csiphy_id = vep.base.port;
 438
 439        mipi_csi2 = &vep.bus.mipi_csi2;
 440        lncfg->clk.pos = mipi_csi2->clock_lane;
 441        lncfg->clk.pol = mipi_csi2->lane_polarities[0];
 442        lncfg->num_data = mipi_csi2->num_data_lanes;
 443
 444        lncfg->data = devm_kcalloc(dev,
 445                                   lncfg->num_data, sizeof(*lncfg->data),
 446                                   GFP_KERNEL);
 447        if (!lncfg->data)
 448                return -ENOMEM;
 449
 450        for (i = 0; i < lncfg->num_data; i++) {
 451                lncfg->data[i].pos = mipi_csi2->data_lanes[i];
 452                lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1];
 453        }
 454
 455        return 0;
 456}
 457
 458/*
 459 * camss_of_parse_ports - Parse ports node
 460 * @dev: Device
 461 * @notifier: v4l2_device notifier data
 462 *
 463 * Return number of "port" nodes found in "ports" node
 464 */
 465static int camss_of_parse_ports(struct device *dev,
 466                                struct v4l2_async_notifier *notifier)
 467{
 468        struct device_node *node = NULL;
 469        struct device_node *remote = NULL;
 470        unsigned int size, i;
 471        int ret;
 472
 473        while ((node = of_graph_get_next_endpoint(dev->of_node, node)))
 474                if (of_device_is_available(node))
 475                        notifier->num_subdevs++;
 476
 477        of_node_put(node);
 478        size = sizeof(*notifier->subdevs) * notifier->num_subdevs;
 479        notifier->subdevs = devm_kzalloc(dev, size, GFP_KERNEL);
 480        if (!notifier->subdevs) {
 481                dev_err(dev, "Failed to allocate memory\n");
 482                return -ENOMEM;
 483        }
 484
 485        i = 0;
 486        while ((node = of_graph_get_next_endpoint(dev->of_node, node))) {
 487                struct camss_async_subdev *csd;
 488
 489                if (!of_device_is_available(node))
 490                        continue;
 491
 492                csd = devm_kzalloc(dev, sizeof(*csd), GFP_KERNEL);
 493                if (!csd) {
 494                        of_node_put(node);
 495                        dev_err(dev, "Failed to allocate memory\n");
 496                        return -ENOMEM;
 497                }
 498
 499                notifier->subdevs[i++] = &csd->asd;
 500
 501                ret = camss_of_parse_endpoint_node(dev, node, csd);
 502                if (ret < 0) {
 503                        of_node_put(node);
 504                        return ret;
 505                }
 506
 507                remote = of_graph_get_remote_port_parent(node);
 508                if (!remote) {
 509                        dev_err(dev, "Cannot get remote parent\n");
 510                        of_node_put(node);
 511                        return -EINVAL;
 512                }
 513
 514                csd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
 515                csd->asd.match.fwnode = of_fwnode_handle(remote);
 516        }
 517        of_node_put(node);
 518
 519        return notifier->num_subdevs;
 520}
 521
 522/*
 523 * camss_init_subdevices - Initialize subdev structures and resources
 524 * @camss: CAMSS device
 525 *
 526 * Return 0 on success or a negative error code on failure
 527 */
 528static int camss_init_subdevices(struct camss *camss)
 529{
 530        const struct resources *csiphy_res;
 531        const struct resources *csid_res;
 532        const struct resources_ispif *ispif_res;
 533        const struct resources *vfe_res;
 534        unsigned int i;
 535        int ret;
 536
 537        if (camss->version == CAMSS_8x16) {
 538                csiphy_res = csiphy_res_8x16;
 539                csid_res = csid_res_8x16;
 540                ispif_res = &ispif_res_8x16;
 541                vfe_res = vfe_res_8x16;
 542        } else if (camss->version == CAMSS_8x96) {
 543                csiphy_res = csiphy_res_8x96;
 544                csid_res = csid_res_8x96;
 545                ispif_res = &ispif_res_8x96;
 546                vfe_res = vfe_res_8x96;
 547        } else {
 548                return -EINVAL;
 549        }
 550
 551        for (i = 0; i < camss->csiphy_num; i++) {
 552                ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i],
 553                                             &csiphy_res[i], i);
 554                if (ret < 0) {
 555                        dev_err(camss->dev,
 556                                "Failed to init csiphy%d sub-device: %d\n",
 557                                i, ret);
 558                        return ret;
 559                }
 560        }
 561
 562        for (i = 0; i < camss->csid_num; i++) {
 563                ret = msm_csid_subdev_init(camss, &camss->csid[i],
 564                                           &csid_res[i], i);
 565                if (ret < 0) {
 566                        dev_err(camss->dev,
 567                                "Failed to init csid%d sub-device: %d\n",
 568                                i, ret);
 569                        return ret;
 570                }
 571        }
 572
 573        ret = msm_ispif_subdev_init(&camss->ispif, ispif_res);
 574        if (ret < 0) {
 575                dev_err(camss->dev, "Failed to init ispif sub-device: %d\n",
 576                        ret);
 577                return ret;
 578        }
 579
 580        for (i = 0; i < camss->vfe_num; i++) {
 581                ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
 582                                          &vfe_res[i], i);
 583                if (ret < 0) {
 584                        dev_err(camss->dev,
 585                                "Fail to init vfe%d sub-device: %d\n", i, ret);
 586                        return ret;
 587                }
 588        }
 589
 590        return 0;
 591}
 592
 593/*
 594 * camss_register_entities - Register subdev nodes and create links
 595 * @camss: CAMSS device
 596 *
 597 * Return 0 on success or a negative error code on failure
 598 */
 599static int camss_register_entities(struct camss *camss)
 600{
 601        int i, j, k;
 602        int ret;
 603
 604        for (i = 0; i < camss->csiphy_num; i++) {
 605                ret = msm_csiphy_register_entity(&camss->csiphy[i],
 606                                                 &camss->v4l2_dev);
 607                if (ret < 0) {
 608                        dev_err(camss->dev,
 609                                "Failed to register csiphy%d entity: %d\n",
 610                                i, ret);
 611                        goto err_reg_csiphy;
 612                }
 613        }
 614
 615        for (i = 0; i < camss->csid_num; i++) {
 616                ret = msm_csid_register_entity(&camss->csid[i],
 617                                               &camss->v4l2_dev);
 618                if (ret < 0) {
 619                        dev_err(camss->dev,
 620                                "Failed to register csid%d entity: %d\n",
 621                                i, ret);
 622                        goto err_reg_csid;
 623                }
 624        }
 625
 626        ret = msm_ispif_register_entities(&camss->ispif, &camss->v4l2_dev);
 627        if (ret < 0) {
 628                dev_err(camss->dev, "Failed to register ispif entities: %d\n",
 629                        ret);
 630                goto err_reg_ispif;
 631        }
 632
 633        for (i = 0; i < camss->vfe_num; i++) {
 634                ret = msm_vfe_register_entities(&camss->vfe[i],
 635                                                &camss->v4l2_dev);
 636                if (ret < 0) {
 637                        dev_err(camss->dev,
 638                                "Failed to register vfe%d entities: %d\n",
 639                                i, ret);
 640                        goto err_reg_vfe;
 641                }
 642        }
 643
 644        for (i = 0; i < camss->csiphy_num; i++) {
 645                for (j = 0; j < camss->csid_num; j++) {
 646                        ret = media_create_pad_link(
 647                                &camss->csiphy[i].subdev.entity,
 648                                MSM_CSIPHY_PAD_SRC,
 649                                &camss->csid[j].subdev.entity,
 650                                MSM_CSID_PAD_SINK,
 651                                0);
 652                        if (ret < 0) {
 653                                dev_err(camss->dev,
 654                                        "Failed to link %s->%s entities: %d\n",
 655                                        camss->csiphy[i].subdev.entity.name,
 656                                        camss->csid[j].subdev.entity.name,
 657                                        ret);
 658                                goto err_link;
 659                        }
 660                }
 661        }
 662
 663        for (i = 0; i < camss->csid_num; i++) {
 664                for (j = 0; j < camss->ispif.line_num; j++) {
 665                        ret = media_create_pad_link(
 666                                &camss->csid[i].subdev.entity,
 667                                MSM_CSID_PAD_SRC,
 668                                &camss->ispif.line[j].subdev.entity,
 669                                MSM_ISPIF_PAD_SINK,
 670                                0);
 671                        if (ret < 0) {
 672                                dev_err(camss->dev,
 673                                        "Failed to link %s->%s entities: %d\n",
 674                                        camss->csid[i].subdev.entity.name,
 675                                        camss->ispif.line[j].subdev.entity.name,
 676                                        ret);
 677                                goto err_link;
 678                        }
 679                }
 680        }
 681
 682        for (i = 0; i < camss->ispif.line_num; i++)
 683                for (k = 0; k < camss->vfe_num; k++)
 684                        for (j = 0; j < ARRAY_SIZE(camss->vfe[k].line); j++) {
 685                                ret = media_create_pad_link(
 686                                        &camss->ispif.line[i].subdev.entity,
 687                                        MSM_ISPIF_PAD_SRC,
 688                                        &camss->vfe[k].line[j].subdev.entity,
 689                                        MSM_VFE_PAD_SINK,
 690                                        0);
 691                                if (ret < 0) {
 692                                        dev_err(camss->dev,
 693                                                "Failed to link %s->%s entities: %d\n",
 694                                                camss->ispif.line[i].subdev.entity.name,
 695                                                camss->vfe[k].line[j].subdev.entity.name,
 696                                                ret);
 697                                        goto err_link;
 698                                }
 699                        }
 700
 701        return 0;
 702
 703err_link:
 704        i = camss->vfe_num;
 705err_reg_vfe:
 706        for (i--; i >= 0; i--)
 707                msm_vfe_unregister_entities(&camss->vfe[i]);
 708
 709        msm_ispif_unregister_entities(&camss->ispif);
 710err_reg_ispif:
 711
 712        i = camss->csid_num;
 713err_reg_csid:
 714        for (i--; i >= 0; i--)
 715                msm_csid_unregister_entity(&camss->csid[i]);
 716
 717        i = camss->csiphy_num;
 718err_reg_csiphy:
 719        for (i--; i >= 0; i--)
 720                msm_csiphy_unregister_entity(&camss->csiphy[i]);
 721
 722        return ret;
 723}
 724
 725/*
 726 * camss_unregister_entities - Unregister subdev nodes
 727 * @camss: CAMSS device
 728 *
 729 * Return 0 on success or a negative error code on failure
 730 */
 731static void camss_unregister_entities(struct camss *camss)
 732{
 733        unsigned int i;
 734
 735        for (i = 0; i < camss->csiphy_num; i++)
 736                msm_csiphy_unregister_entity(&camss->csiphy[i]);
 737
 738        for (i = 0; i < camss->csid_num; i++)
 739                msm_csid_unregister_entity(&camss->csid[i]);
 740
 741        msm_ispif_unregister_entities(&camss->ispif);
 742
 743        for (i = 0; i < camss->vfe_num; i++)
 744                msm_vfe_unregister_entities(&camss->vfe[i]);
 745}
 746
 747static int camss_subdev_notifier_bound(struct v4l2_async_notifier *async,
 748                                       struct v4l2_subdev *subdev,
 749                                       struct v4l2_async_subdev *asd)
 750{
 751        struct camss *camss = container_of(async, struct camss, notifier);
 752        struct camss_async_subdev *csd =
 753                container_of(asd, struct camss_async_subdev, asd);
 754        u8 id = csd->interface.csiphy_id;
 755        struct csiphy_device *csiphy = &camss->csiphy[id];
 756
 757        csiphy->cfg.csi2 = &csd->interface.csi2;
 758        subdev->host_priv = csiphy;
 759
 760        return 0;
 761}
 762
 763static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async)
 764{
 765        struct camss *camss = container_of(async, struct camss, notifier);
 766        struct v4l2_device *v4l2_dev = &camss->v4l2_dev;
 767        struct v4l2_subdev *sd;
 768        int ret;
 769
 770        list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
 771                if (sd->host_priv) {
 772                        struct media_entity *sensor = &sd->entity;
 773                        struct csiphy_device *csiphy =
 774                                        (struct csiphy_device *) sd->host_priv;
 775                        struct media_entity *input = &csiphy->subdev.entity;
 776                        unsigned int i;
 777
 778                        for (i = 0; i < sensor->num_pads; i++) {
 779                                if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
 780                                        break;
 781                        }
 782                        if (i == sensor->num_pads) {
 783                                dev_err(camss->dev,
 784                                        "No source pad in external entity\n");
 785                                return -EINVAL;
 786                        }
 787
 788                        ret = media_create_pad_link(sensor, i,
 789                                input, MSM_CSIPHY_PAD_SINK,
 790                                MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 791                        if (ret < 0) {
 792                                dev_err(camss->dev,
 793                                        "Failed to link %s->%s entities: %d\n",
 794                                        sensor->name, input->name, ret);
 795                                return ret;
 796                        }
 797                }
 798        }
 799
 800        ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
 801        if (ret < 0)
 802                return ret;
 803
 804        return media_device_register(&camss->media_dev);
 805}
 806
 807static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = {
 808        .bound = camss_subdev_notifier_bound,
 809        .complete = camss_subdev_notifier_complete,
 810};
 811
 812static const struct media_device_ops camss_media_ops = {
 813        .link_notify = v4l2_pipeline_link_notify,
 814};
 815
 816/*
 817 * camss_probe - Probe CAMSS platform device
 818 * @pdev: Pointer to CAMSS platform device
 819 *
 820 * Return 0 on success or a negative error code on failure
 821 */
 822static int camss_probe(struct platform_device *pdev)
 823{
 824        struct device *dev = &pdev->dev;
 825        struct camss *camss;
 826        int ret;
 827
 828        camss = kzalloc(sizeof(*camss), GFP_KERNEL);
 829        if (!camss)
 830                return -ENOMEM;
 831
 832        atomic_set(&camss->ref_count, 0);
 833        camss->dev = dev;
 834        platform_set_drvdata(pdev, camss);
 835
 836        if (of_device_is_compatible(dev->of_node, "qcom,msm8916-camss")) {
 837                camss->version = CAMSS_8x16;
 838                camss->csiphy_num = 2;
 839                camss->csid_num = 2;
 840                camss->vfe_num = 1;
 841        } else if (of_device_is_compatible(dev->of_node,
 842                                           "qcom,msm8996-camss")) {
 843                camss->version = CAMSS_8x96;
 844                camss->csiphy_num = 3;
 845                camss->csid_num = 4;
 846                camss->vfe_num = 2;
 847        } else {
 848                return -EINVAL;
 849        }
 850
 851        camss->csiphy = devm_kcalloc(dev, camss->csiphy_num,
 852                                     sizeof(*camss->csiphy), GFP_KERNEL);
 853        if (!camss->csiphy)
 854                return -ENOMEM;
 855
 856        camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid),
 857                                   GFP_KERNEL);
 858        if (!camss->csid)
 859                return -ENOMEM;
 860
 861        camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe),
 862                                  GFP_KERNEL);
 863        if (!camss->vfe)
 864                return -ENOMEM;
 865
 866        ret = camss_of_parse_ports(dev, &camss->notifier);
 867        if (ret < 0)
 868                return ret;
 869
 870        ret = camss_init_subdevices(camss);
 871        if (ret < 0)
 872                return ret;
 873
 874        ret = dma_set_mask_and_coherent(dev, 0xffffffff);
 875        if (ret)
 876                return ret;
 877
 878        camss->media_dev.dev = camss->dev;
 879        strlcpy(camss->media_dev.model, "Qualcomm Camera Subsystem",
 880                sizeof(camss->media_dev.model));
 881        camss->media_dev.ops = &camss_media_ops;
 882        media_device_init(&camss->media_dev);
 883
 884        camss->v4l2_dev.mdev = &camss->media_dev;
 885        ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
 886        if (ret < 0) {
 887                dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
 888                return ret;
 889        }
 890
 891        ret = camss_register_entities(camss);
 892        if (ret < 0)
 893                goto err_register_entities;
 894
 895        if (camss->notifier.num_subdevs) {
 896                camss->notifier.ops = &camss_subdev_notifier_ops;
 897
 898                ret = v4l2_async_notifier_register(&camss->v4l2_dev,
 899                                                   &camss->notifier);
 900                if (ret) {
 901                        dev_err(dev,
 902                                "Failed to register async subdev nodes: %d\n",
 903                                ret);
 904                        goto err_register_subdevs;
 905                }
 906        } else {
 907                ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
 908                if (ret < 0) {
 909                        dev_err(dev, "Failed to register subdev nodes: %d\n",
 910                                ret);
 911                        goto err_register_subdevs;
 912                }
 913
 914                ret = media_device_register(&camss->media_dev);
 915                if (ret < 0) {
 916                        dev_err(dev, "Failed to register media device: %d\n",
 917                                ret);
 918                        goto err_register_subdevs;
 919                }
 920        }
 921
 922        if (camss->version == CAMSS_8x96) {
 923                camss->genpd[PM_DOMAIN_VFE0] = dev_pm_domain_attach_by_id(
 924                                                camss->dev, PM_DOMAIN_VFE0);
 925                if (IS_ERR(camss->genpd[PM_DOMAIN_VFE0]))
 926                        return PTR_ERR(camss->genpd[PM_DOMAIN_VFE0]);
 927
 928                camss->genpd[PM_DOMAIN_VFE1] = dev_pm_domain_attach_by_id(
 929                                                camss->dev, PM_DOMAIN_VFE1);
 930                if (IS_ERR(camss->genpd[PM_DOMAIN_VFE1])) {
 931                        dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE0],
 932                                             true);
 933                        return PTR_ERR(camss->genpd[PM_DOMAIN_VFE1]);
 934                }
 935        }
 936
 937        pm_runtime_enable(dev);
 938
 939        return 0;
 940
 941err_register_subdevs:
 942        camss_unregister_entities(camss);
 943err_register_entities:
 944        v4l2_device_unregister(&camss->v4l2_dev);
 945
 946        return ret;
 947}
 948
 949void camss_delete(struct camss *camss)
 950{
 951        v4l2_device_unregister(&camss->v4l2_dev);
 952        media_device_unregister(&camss->media_dev);
 953        media_device_cleanup(&camss->media_dev);
 954
 955        pm_runtime_disable(camss->dev);
 956
 957        if (camss->version == CAMSS_8x96) {
 958                dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE0], true);
 959                dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE1], true);
 960        }
 961
 962        kfree(camss);
 963}
 964
 965/*
 966 * camss_remove - Remove CAMSS platform device
 967 * @pdev: Pointer to CAMSS platform device
 968 *
 969 * Always returns 0.
 970 */
 971static int camss_remove(struct platform_device *pdev)
 972{
 973        unsigned int i;
 974
 975        struct camss *camss = platform_get_drvdata(pdev);
 976
 977        for (i = 0; i < camss->vfe_num; i++)
 978                msm_vfe_stop_streaming(&camss->vfe[i]);
 979
 980        v4l2_async_notifier_unregister(&camss->notifier);
 981        camss_unregister_entities(camss);
 982
 983        if (atomic_read(&camss->ref_count) == 0)
 984                camss_delete(camss);
 985
 986        return 0;
 987}
 988
 989static const struct of_device_id camss_dt_match[] = {
 990        { .compatible = "qcom,msm8916-camss" },
 991        { .compatible = "qcom,msm8996-camss" },
 992        { }
 993};
 994
 995MODULE_DEVICE_TABLE(of, camss_dt_match);
 996
 997static int __maybe_unused camss_runtime_suspend(struct device *dev)
 998{
 999        return 0;
1000}
1001
1002static int __maybe_unused camss_runtime_resume(struct device *dev)
1003{
1004        return 0;
1005}
1006
1007static const struct dev_pm_ops camss_pm_ops = {
1008        SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1009                                pm_runtime_force_resume)
1010        SET_RUNTIME_PM_OPS(camss_runtime_suspend, camss_runtime_resume, NULL)
1011};
1012
1013static struct platform_driver qcom_camss_driver = {
1014        .probe = camss_probe,
1015        .remove = camss_remove,
1016        .driver = {
1017                .name = "qcom-camss",
1018                .of_match_table = camss_dt_match,
1019                .pm = &camss_pm_ops,
1020        },
1021};
1022
1023module_platform_driver(qcom_camss_driver);
1024
1025MODULE_ALIAS("platform:qcom-camss");
1026MODULE_DESCRIPTION("Qualcomm Camera Subsystem driver");
1027MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>");
1028MODULE_LICENSE("GPL v2");
1029