cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

camss.c (42008B)


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