brintos

brintos / linux-shallow public Read only

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