2018-07-25 12:38:14 -04:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2017-08-08 09:30:07 -04:00
|
|
|
/*
|
|
|
|
* camss.c
|
|
|
|
*
|
|
|
|
* Qualcomm MSM Camera Subsystem - Core
|
|
|
|
*
|
|
|
|
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
2018-07-25 12:38:13 -04:00
|
|
|
* Copyright (C) 2015-2018 Linaro Ltd.
|
2017-08-08 09:30:07 -04:00
|
|
|
*/
|
|
|
|
#include <linux/clk.h>
|
2021-12-22 01:37:49 +01:00
|
|
|
#include <linux/interconnect.h>
|
2017-08-08 09:30:07 -04:00
|
|
|
#include <linux/media-bus-format.h>
|
|
|
|
#include <linux/media.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
#include <linux/of.h>
|
2023-09-25 16:46:53 +01:00
|
|
|
#include <linux/of_device.h>
|
2017-08-08 09:30:07 -04:00
|
|
|
#include <linux/of_graph.h>
|
2018-07-25 12:38:27 -04:00
|
|
|
#include <linux/pm_runtime.h>
|
|
|
|
#include <linux/pm_domain.h>
|
2017-08-08 09:30:07 -04:00
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/videodev2.h>
|
|
|
|
|
|
|
|
#include <media/media-device.h>
|
|
|
|
#include <media/v4l2-async.h>
|
|
|
|
#include <media/v4l2-device.h>
|
|
|
|
#include <media/v4l2-mc.h>
|
|
|
|
#include <media/v4l2-fwnode.h>
|
|
|
|
|
|
|
|
#include "camss.h"
|
|
|
|
|
2017-08-08 09:30:17 -04:00
|
|
|
#define CAMSS_CLOCK_MARGIN_NUMERATOR 105
|
|
|
|
#define CAMSS_CLOCK_MARGIN_DENOMINATOR 100
|
|
|
|
|
2024-05-22 18:46:59 +03:00
|
|
|
static const struct parent_dev_ops vfe_parent_dev_ops;
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources csiphy_res_8x16[] = {
|
2017-08-08 09:30:07 -04:00
|
|
|
/* CSIPHY0 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2018-07-25 12:38:18 -04:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" },
|
2017-08-08 09:30:17 -04:00
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000 } },
|
2017-08-08 09:30:07 -04:00
|
|
|
.reg = { "csiphy0", "csiphy0_clk_mux" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_2ph_1_0,
|
|
|
|
.formats = &csiphy_formats_8x16
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2017-08-08 09:30:07 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSIPHY1 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2018-07-25 12:38:18 -04:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" },
|
2017-08-08 09:30:17 -04:00
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000 } },
|
2017-08-08 09:30:07 -04:00
|
|
|
.reg = { "csiphy1", "csiphy1_clk_mux" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_2ph_1_0,
|
|
|
|
.formats = &csiphy_formats_8x16
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2017-08-08 09:30:07 -04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources csid_res_8x16[] = {
|
2017-08-08 09:30:07 -04:00
|
|
|
/* CSID0 */
|
|
|
|
{
|
2022-01-11 13:52:09 +01:00
|
|
|
.regulators = { "vdda" },
|
2018-07-25 12:38:18 -04:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
|
2017-08-08 09:30:07 -04:00
|
|
|
"csi0", "csi0_phy", "csi0_pix", "csi0_rdi" },
|
2017-08-08 09:30:17 -04:00
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
2017-08-08 09:30:07 -04:00
|
|
|
.reg = { "csid0" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_4_1,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_4_1
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2017-08-08 09:30:07 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSID1 */
|
|
|
|
{
|
2022-01-11 13:52:09 +01:00
|
|
|
.regulators = { "vdda" },
|
2018-07-25 12:38:18 -04:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
|
2017-08-08 09:30:07 -04:00
|
|
|
"csi1", "csi1_phy", "csi1_pix", "csi1_rdi" },
|
2017-08-08 09:30:17 -04:00
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
2017-08-08 09:30:07 -04:00
|
|
|
.reg = { "csid1" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_4_1,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_4_1
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2017-08-08 09:30:07 -04:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources ispif_res_8x16 = {
|
2017-08-08 09:30:07 -04:00
|
|
|
/* ISPIF */
|
2018-07-25 12:38:18 -04:00
|
|
|
.clock = { "top_ahb", "ahb", "ispif_ahb",
|
2017-08-08 09:30:07 -04:00
|
|
|
"csi0", "csi0_pix", "csi0_rdi",
|
|
|
|
"csi1", "csi1_pix", "csi1_rdi" },
|
2018-07-25 12:38:18 -04:00
|
|
|
.clock_for_reset = { "vfe0", "csi_vfe0" },
|
2017-08-08 09:30:07 -04:00
|
|
|
.reg = { "ispif", "csi_clk_mux" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.interrupt = { "ispif" },
|
2017-08-08 09:30:07 -04:00
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources vfe_res_8x16[] = {
|
2017-08-08 09:30:07 -04:00
|
|
|
/* VFE0 */
|
2018-07-25 12:38:26 -04:00
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2018-07-25 12:38:26 -04:00
|
|
|
.clock = { "top_ahb", "vfe0", "csi_vfe0",
|
|
|
|
"vfe_ahb", "vfe_axi", "ahb" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 50000000, 80000000, 100000000, 160000000,
|
|
|
|
177780000, 200000000, 266670000, 320000000,
|
|
|
|
400000000, 465000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "vfe0" },
|
2023-09-25 16:46:56 +01:00
|
|
|
.interrupt = { "vfe0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 3,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_4_1,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_8x16,
|
|
|
|
.formats_pix = &vfe_formats_pix_8x16
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2018-07-25 12:38:26 -04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources csiphy_res_8x96[] = {
|
2018-07-25 12:38:26 -04:00
|
|
|
/* CSIPHY0 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2018-07-25 12:38:26 -04:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 266666667 } },
|
|
|
|
.reg = { "csiphy0", "csiphy0_clk_mux" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_8x96
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2018-07-25 12:38:26 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSIPHY1 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2018-07-25 12:38:26 -04:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 266666667 } },
|
|
|
|
.reg = { "csiphy1", "csiphy1_clk_mux" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_8x96
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2018-07-25 12:38:26 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSIPHY2 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2018-07-25 12:38:26 -04:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 266666667 } },
|
|
|
|
.reg = { "csiphy2", "csiphy2_clk_mux" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy2" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_8x96
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2018-07-25 12:38:26 -04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources csid_res_8x96[] = {
|
2018-07-25 12:38:26 -04:00
|
|
|
/* CSID0 */
|
|
|
|
{
|
2022-01-11 13:52:09 +01:00
|
|
|
.regulators = { "vdda" },
|
2018-07-25 12:38:26 -04:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
|
|
|
|
"csi0", "csi0_phy", "csi0_pix", "csi0_rdi" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 266666667 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid0" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_4_7,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_4_7
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2018-07-25 12:38:26 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSID1 */
|
|
|
|
{
|
2022-01-11 13:52:09 +01:00
|
|
|
.regulators = { "vdda" },
|
2018-07-25 12:38:26 -04:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
|
|
|
|
"csi1", "csi1_phy", "csi1_pix", "csi1_rdi" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 266666667 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid1" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_4_7,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_4_7
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2018-07-25 12:38:26 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSID2 */
|
|
|
|
{
|
2022-01-11 13:52:09 +01:00
|
|
|
.regulators = { "vdda" },
|
2018-07-25 12:38:26 -04:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
|
|
|
|
"csi2", "csi2_phy", "csi2_pix", "csi2_rdi" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 266666667 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid2" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid2" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_4_7,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_4_7
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2018-07-25 12:38:26 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSID3 */
|
|
|
|
{
|
2022-01-11 13:52:09 +01:00
|
|
|
.regulators = { "vdda" },
|
2018-07-25 12:38:26 -04:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb",
|
|
|
|
"csi3", "csi3_phy", "csi3_pix", "csi3_rdi" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 266666667 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid3" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid3" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_4_7,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_4_7
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2018-07-25 12:38:26 -04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources ispif_res_8x96 = {
|
2018-07-25 12:38:26 -04:00
|
|
|
/* ISPIF */
|
|
|
|
.clock = { "top_ahb", "ahb", "ispif_ahb",
|
|
|
|
"csi0", "csi0_pix", "csi0_rdi",
|
|
|
|
"csi1", "csi1_pix", "csi1_rdi",
|
|
|
|
"csi2", "csi2_pix", "csi2_rdi",
|
|
|
|
"csi3", "csi3_pix", "csi3_rdi" },
|
|
|
|
.clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
|
|
|
|
.reg = { "ispif", "csi_clk_mux" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.interrupt = { "ispif" },
|
2018-07-25 12:38:26 -04:00
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources vfe_res_8x96[] = {
|
2018-07-25 12:38:26 -04:00
|
|
|
/* VFE0 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2018-07-25 12:38:26 -04:00
|
|
|
.clock = { "top_ahb", "ahb", "vfe0", "csi_vfe0", "vfe_ahb",
|
|
|
|
"vfe0_ahb", "vfe_axi", "vfe0_stream"},
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 75000000, 100000000, 300000000,
|
|
|
|
320000000, 480000000, 600000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "vfe0" },
|
2023-09-25 16:46:56 +01:00
|
|
|
.interrupt = { "vfe0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 3,
|
|
|
|
.has_pd = true,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_4_7,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_8x96,
|
|
|
|
.formats_pix = &vfe_formats_pix_8x96
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2018-07-25 12:38:26 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
/* VFE1 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2018-07-25 12:38:26 -04:00
|
|
|
.clock = { "top_ahb", "ahb", "vfe1", "csi_vfe1", "vfe_ahb",
|
|
|
|
"vfe1_ahb", "vfe_axi", "vfe1_stream"},
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 75000000, 100000000, 300000000,
|
|
|
|
320000000, 480000000, 600000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "vfe1" },
|
2023-09-25 16:46:56 +01:00
|
|
|
.interrupt = { "vfe1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 3,
|
|
|
|
.has_pd = true,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_4_7,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_8x96,
|
|
|
|
.formats_pix = &vfe_formats_pix_8x96
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2018-07-25 12:38:26 -04:00
|
|
|
}
|
2017-08-08 09:30:07 -04:00
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources csiphy_res_660[] = {
|
2020-10-22 19:47:03 +02:00
|
|
|
/* CSIPHY0 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2020-10-22 19:47:03 +02:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer",
|
|
|
|
"csi0_phy", "csiphy_ahb2crif" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 269333333 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csiphy0", "csiphy0_clk_mux" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_8x96
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2020-10-22 19:47:03 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSIPHY1 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2020-10-22 19:47:03 +02:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer",
|
|
|
|
"csi1_phy", "csiphy_ahb2crif" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 269333333 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csiphy1", "csiphy1_clk_mux" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_8x96
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2020-10-22 19:47:03 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSIPHY2 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2020-10-22 19:47:03 +02:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer",
|
|
|
|
"csi2_phy", "csiphy_ahb2crif" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 269333333 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csiphy2", "csiphy2_clk_mux" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy2" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_8x96
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2020-10-22 19:47:03 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources csid_res_660[] = {
|
2020-10-22 19:47:03 +02:00
|
|
|
/* CSID0 */
|
|
|
|
{
|
2022-01-11 13:52:09 +01:00
|
|
|
.regulators = { "vdda", "vdd_sec" },
|
2020-10-22 19:47:03 +02:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
|
|
|
|
"csi0", "csi0_phy", "csi0_pix", "csi0_rdi",
|
|
|
|
"cphy_csid0" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 310000000,
|
|
|
|
404000000, 465000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid0" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_4_7,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_4_7
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2020-10-22 19:47:03 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSID1 */
|
|
|
|
{
|
2022-01-11 13:52:09 +01:00
|
|
|
.regulators = { "vdda", "vdd_sec" },
|
2020-10-22 19:47:03 +02:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
|
|
|
|
"csi1", "csi1_phy", "csi1_pix", "csi1_rdi",
|
|
|
|
"cphy_csid1" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 310000000,
|
|
|
|
404000000, 465000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid1" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_4_7,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_4_7
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2020-10-22 19:47:03 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSID2 */
|
|
|
|
{
|
2022-01-11 13:52:09 +01:00
|
|
|
.regulators = { "vdda", "vdd_sec" },
|
2020-10-22 19:47:03 +02:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
|
|
|
|
"csi2", "csi2_phy", "csi2_pix", "csi2_rdi",
|
|
|
|
"cphy_csid2" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 310000000,
|
|
|
|
404000000, 465000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid2" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid2" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_4_7,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_4_7
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2020-10-22 19:47:03 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSID3 */
|
|
|
|
{
|
2022-01-11 13:52:09 +01:00
|
|
|
.regulators = { "vdda", "vdd_sec" },
|
2020-10-22 19:47:03 +02:00
|
|
|
.clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb",
|
|
|
|
"csi3", "csi3_phy", "csi3_pix", "csi3_rdi",
|
|
|
|
"cphy_csid3" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 310000000,
|
|
|
|
404000000, 465000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid3" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid3" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_4_7,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_4_7
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2020-10-22 19:47:03 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources ispif_res_660 = {
|
2020-10-22 19:47:03 +02:00
|
|
|
/* ISPIF */
|
|
|
|
.clock = { "top_ahb", "ahb", "ispif_ahb",
|
|
|
|
"csi0", "csi0_pix", "csi0_rdi",
|
|
|
|
"csi1", "csi1_pix", "csi1_rdi",
|
|
|
|
"csi2", "csi2_pix", "csi2_rdi",
|
|
|
|
"csi3", "csi3_pix", "csi3_rdi" },
|
|
|
|
.clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
|
|
|
|
.reg = { "ispif", "csi_clk_mux" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.interrupt = { "ispif" },
|
2020-10-22 19:47:03 +02:00
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources vfe_res_660[] = {
|
2020-10-22 19:47:03 +02:00
|
|
|
/* VFE0 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2020-10-22 19:47:03 +02:00
|
|
|
.clock = { "throttle_axi", "top_ahb", "ahb", "vfe0",
|
|
|
|
"csi_vfe0", "vfe_ahb", "vfe0_ahb", "vfe_axi",
|
|
|
|
"vfe0_stream"},
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 120000000, 200000000, 256000000,
|
|
|
|
300000000, 404000000, 480000000,
|
|
|
|
540000000, 576000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "vfe0" },
|
2023-09-25 16:46:56 +01:00
|
|
|
.interrupt = { "vfe0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 3,
|
|
|
|
.has_pd = true,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_4_8,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_8x96,
|
|
|
|
.formats_pix = &vfe_formats_pix_8x96
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2020-10-22 19:47:03 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
/* VFE1 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2020-10-22 19:47:03 +02:00
|
|
|
.clock = { "throttle_axi", "top_ahb", "ahb", "vfe1",
|
|
|
|
"csi_vfe1", "vfe_ahb", "vfe1_ahb", "vfe_axi",
|
|
|
|
"vfe1_stream"},
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 120000000, 200000000, 256000000,
|
|
|
|
300000000, 404000000, 480000000,
|
|
|
|
540000000, 576000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "vfe1" },
|
2023-09-25 16:46:56 +01:00
|
|
|
.interrupt = { "vfe1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 3,
|
|
|
|
.has_pd = true,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_4_8,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_8x96,
|
|
|
|
.formats_pix = &vfe_formats_pix_8x96
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2020-10-22 19:47:03 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources csiphy_res_845[] = {
|
2021-03-16 18:19:20 +01:00
|
|
|
/* CSIPHY0 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-03-16 18:19:20 +01:00
|
|
|
.clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
|
|
|
|
"cpas_ahb", "cphy_rx_src", "csiphy0",
|
|
|
|
"csiphy0_timer_src", "csiphy0_timer" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 240000000, 269333333 } },
|
|
|
|
.reg = { "csiphy0" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-03-16 18:19:20 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSIPHY1 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-03-16 18:19:20 +01:00
|
|
|
.clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
|
|
|
|
"cpas_ahb", "cphy_rx_src", "csiphy1",
|
|
|
|
"csiphy1_timer_src", "csiphy1_timer" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 240000000, 269333333 } },
|
|
|
|
.reg = { "csiphy1" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-03-16 18:19:20 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSIPHY2 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-03-16 18:19:20 +01:00
|
|
|
.clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
|
|
|
|
"cpas_ahb", "cphy_rx_src", "csiphy2",
|
|
|
|
"csiphy2_timer_src", "csiphy2_timer" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 240000000, 269333333 } },
|
|
|
|
.reg = { "csiphy2" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy2" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-03-16 18:19:20 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSIPHY3 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-03-16 18:19:20 +01:00
|
|
|
.clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src",
|
|
|
|
"cpas_ahb", "cphy_rx_src", "csiphy3",
|
|
|
|
"csiphy3_timer_src", "csiphy3_timer" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 240000000, 269333333 } },
|
|
|
|
.reg = { "csiphy3" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy3" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-03-16 18:19:20 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources csid_res_845[] = {
|
2021-03-16 18:19:19 +01:00
|
|
|
/* CSID0 */
|
|
|
|
{
|
2022-01-11 13:52:11 +01:00
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
2021-03-16 18:19:19 +01:00
|
|
|
.clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
|
|
|
|
"soc_ahb", "vfe0", "vfe0_src",
|
|
|
|
"vfe0_cphy_rx", "csi0",
|
|
|
|
"csi0_src" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 384000000 },
|
|
|
|
{ 80000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
|
|
|
|
{ 320000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 75000000, 384000000, 538666667 },
|
|
|
|
{ 384000000 } },
|
|
|
|
.reg = { "csid0" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-03-16 18:19:19 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSID1 */
|
|
|
|
{
|
2022-01-11 13:52:11 +01:00
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
2021-03-16 18:19:19 +01:00
|
|
|
.clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
|
|
|
|
"soc_ahb", "vfe1", "vfe1_src",
|
|
|
|
"vfe1_cphy_rx", "csi1",
|
|
|
|
"csi1_src" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 384000000 },
|
|
|
|
{ 80000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
|
|
|
|
{ 320000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 75000000, 384000000, 538666667 },
|
|
|
|
{ 384000000 } },
|
|
|
|
.reg = { "csid1" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-03-16 18:19:19 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
/* CSID2 */
|
|
|
|
{
|
2022-01-11 13:52:11 +01:00
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
2021-03-16 18:19:19 +01:00
|
|
|
.clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
|
|
|
|
"soc_ahb", "vfe_lite", "vfe_lite_src",
|
|
|
|
"vfe_lite_cphy_rx", "csi2",
|
|
|
|
"csi2_src" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 384000000 },
|
|
|
|
{ 80000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
|
|
|
|
{ 320000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 75000000, 384000000, 538666667 },
|
|
|
|
{ 384000000 } },
|
|
|
|
.reg = { "csid2" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid2" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
|
|
|
.is_lite = true,
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-03-16 18:19:19 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources vfe_res_845[] = {
|
2021-03-16 18:19:16 +01:00
|
|
|
/* VFE0 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-03-16 18:19:16 +01:00
|
|
|
.clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
|
|
|
|
"soc_ahb", "vfe0", "vfe0_axi",
|
|
|
|
"vfe0_src", "csi0",
|
|
|
|
"csi0_src"},
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 80000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 320000000 },
|
|
|
|
{ 19200000, 75000000, 384000000, 538666667 },
|
|
|
|
{ 384000000 } },
|
|
|
|
.reg = { "vfe0" },
|
2023-09-25 16:46:56 +01:00
|
|
|
.interrupt = { "vfe0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 4,
|
|
|
|
.has_pd = true,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_170,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-03-16 18:19:16 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
/* VFE1 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-03-16 18:19:16 +01:00
|
|
|
.clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
|
|
|
|
"soc_ahb", "vfe1", "vfe1_axi",
|
|
|
|
"vfe1_src", "csi1",
|
|
|
|
"csi1_src"},
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 80000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 320000000 },
|
|
|
|
{ 19200000, 75000000, 384000000, 538666667 },
|
|
|
|
{ 384000000 } },
|
|
|
|
.reg = { "vfe1" },
|
2023-09-25 16:46:56 +01:00
|
|
|
.interrupt = { "vfe1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 4,
|
|
|
|
.has_pd = true,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_170,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-03-16 18:19:16 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
/* VFE-lite */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-03-16 18:19:16 +01:00
|
|
|
.clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
|
|
|
|
"soc_ahb", "vfe_lite",
|
|
|
|
"vfe_lite_src", "csi2",
|
|
|
|
"csi2_src"},
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 80000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
|
|
|
|
{ 320000000 },
|
|
|
|
{ 19200000, 75000000, 384000000, 538666667 },
|
|
|
|
{ 384000000 } },
|
|
|
|
.reg = { "vfe_lite" },
|
2023-09-25 16:46:56 +01:00
|
|
|
.interrupt = { "vfe_lite" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.is_lite = true,
|
|
|
|
.line_num = 4,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_170,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-03-16 18:19:16 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources csiphy_res_8250[] = {
|
2021-12-22 01:37:48 +01:00
|
|
|
/* CSIPHY0 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "csiphy0", "csiphy0_timer" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 300000000 } },
|
|
|
|
.reg = { "csiphy0" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
},
|
|
|
|
/* CSIPHY1 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "csiphy1", "csiphy1_timer" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 300000000 } },
|
|
|
|
.reg = { "csiphy1" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
},
|
|
|
|
/* CSIPHY2 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "csiphy2", "csiphy2_timer" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 300000000 } },
|
|
|
|
.reg = { "csiphy2" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy2" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
},
|
|
|
|
/* CSIPHY3 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "csiphy3", "csiphy3_timer" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 300000000 } },
|
|
|
|
.reg = { "csiphy3" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy3" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
},
|
|
|
|
/* CSIPHY4 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "csiphy4", "csiphy4_timer" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 300000000 } },
|
|
|
|
.reg = { "csiphy4" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy4" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
},
|
|
|
|
/* CSIPHY5 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "csiphy5", "csiphy5_timer" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 300000000 } },
|
|
|
|
.reg = { "csiphy5" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csiphy5" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources csid_res_8250[] = {
|
2021-12-22 01:37:48 +01:00
|
|
|
/* CSID0 */
|
|
|
|
{
|
2022-01-11 13:52:12 +01:00
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_areg", "vfe0_ahb" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 400000000 },
|
|
|
|
{ 350000000, 475000000, 576000000, 720000000 },
|
|
|
|
{ 100000000, 200000000, 300000000, 400000000 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid0" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
},
|
|
|
|
/* CSID1 */
|
|
|
|
{
|
2022-01-11 13:52:12 +01:00
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_areg", "vfe1_ahb" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 400000000 },
|
|
|
|
{ 350000000, 475000000, 576000000, 720000000 },
|
|
|
|
{ 100000000, 200000000, 300000000, 400000000 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid1" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
},
|
|
|
|
/* CSID2 */
|
|
|
|
{
|
2022-01-11 13:52:12 +01:00
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite", "vfe_lite_ahb" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 400000000 },
|
|
|
|
{ 400000000, 480000000 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid2" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid2" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
|
|
|
.is_lite = true,
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
},
|
|
|
|
/* CSID3 */
|
|
|
|
{
|
2022-01-11 13:52:12 +01:00
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite", "vfe_lite_ahb" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 400000000 },
|
|
|
|
{ 400000000, 480000000 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid3" },
|
2023-09-25 16:46:57 +01:00
|
|
|
.interrupt = { "csid3" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
|
|
|
.is_lite = true,
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-25 16:46:52 +01:00
|
|
|
static const struct camss_subdev_resources vfe_res_8250[] = {
|
2021-12-22 01:37:48 +01:00
|
|
|
/* VFE0 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
|
|
|
|
"camnoc_axi", "vfe0_ahb", "vfe0_areg", "vfe0",
|
|
|
|
"vfe0_axi", "cam_hf_axi" },
|
|
|
|
.clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
|
|
|
|
{ 19200000, 80000000 },
|
|
|
|
{ 19200000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 300000000, 400000000 },
|
|
|
|
{ 350000000, 475000000, 576000000, 720000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "vfe0" },
|
2023-09-25 16:46:56 +01:00
|
|
|
.interrupt = { "vfe0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 3,
|
|
|
|
.has_pd = true,
|
|
|
|
.pd_name = "ife0",
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_480,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
},
|
|
|
|
/* VFE1 */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
|
|
|
|
"camnoc_axi", "vfe1_ahb", "vfe1_areg", "vfe1",
|
|
|
|
"vfe1_axi", "cam_hf_axi" },
|
|
|
|
.clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
|
|
|
|
{ 19200000, 80000000 },
|
|
|
|
{ 19200000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 100000000, 200000000, 300000000, 400000000 },
|
|
|
|
{ 350000000, 475000000, 576000000, 720000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "vfe1" },
|
2023-09-25 16:46:56 +01:00
|
|
|
.interrupt = { "vfe1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 3,
|
|
|
|
.has_pd = true,
|
|
|
|
.pd_name = "ife1",
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_480,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
},
|
|
|
|
/* VFE2 (lite) */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
|
|
|
|
"camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi",
|
|
|
|
"vfe_lite", "cam_hf_axi" },
|
|
|
|
.clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
|
|
|
|
{ 19200000, 80000000 },
|
|
|
|
{ 19200000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 400000000, 480000000 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "vfe_lite0" },
|
2023-09-25 16:46:56 +01:00
|
|
|
.interrupt = { "vfe_lite0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.is_lite = true,
|
|
|
|
.line_num = 4,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_480,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
},
|
|
|
|
/* VFE3 (lite) */
|
|
|
|
{
|
2022-01-11 13:52:10 +01:00
|
|
|
.regulators = {},
|
2021-12-22 01:37:48 +01:00
|
|
|
.clock = { "camnoc_axi_src", "slow_ahb_src", "cpas_ahb",
|
|
|
|
"camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi",
|
|
|
|
"vfe_lite", "cam_hf_axi" },
|
|
|
|
.clock_rate = { { 19200000, 300000000, 400000000, 480000000 },
|
|
|
|
{ 19200000, 80000000 },
|
|
|
|
{ 19200000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 400000000, 480000000 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "vfe_lite1" },
|
2023-09-25 16:46:56 +01:00
|
|
|
.interrupt = { "vfe_lite1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.is_lite = true,
|
|
|
|
.line_num = 4,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_480,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2021-12-22 01:37:48 +01:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-12-22 01:37:49 +01:00
|
|
|
static const struct resources_icc icc_res_sm8250[] = {
|
|
|
|
{
|
|
|
|
.name = "cam_ahb",
|
|
|
|
.icc_bw_tbl.avg = 38400,
|
|
|
|
.icc_bw_tbl.peak = 76800,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "cam_hf_0_mnoc",
|
|
|
|
.icc_bw_tbl.avg = 2097152,
|
|
|
|
.icc_bw_tbl.peak = 2097152,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "cam_sf_0_mnoc",
|
|
|
|
.icc_bw_tbl.avg = 0,
|
|
|
|
.icc_bw_tbl.peak = 2097152,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "cam_sf_icp_mnoc",
|
|
|
|
.icc_bw_tbl.avg = 2097152,
|
|
|
|
.icc_bw_tbl.peak = 2097152,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2024-02-22 17:17:02 +00:00
|
|
|
static const struct camss_subdev_resources csiphy_res_sc8280xp[] = {
|
|
|
|
/* CSIPHY0 */
|
|
|
|
{
|
|
|
|
.regulators = {},
|
|
|
|
.clock = { "csiphy0", "csiphy0_timer" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 300000000 } },
|
|
|
|
.reg = { "csiphy0" },
|
|
|
|
.interrupt = { "csiphy0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* CSIPHY1 */
|
|
|
|
{
|
|
|
|
.regulators = {},
|
|
|
|
.clock = { "csiphy1", "csiphy1_timer" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 300000000 } },
|
|
|
|
.reg = { "csiphy1" },
|
|
|
|
.interrupt = { "csiphy1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* CSIPHY2 */
|
|
|
|
{
|
|
|
|
.regulators = {},
|
|
|
|
.clock = { "csiphy2", "csiphy2_timer" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 300000000 } },
|
|
|
|
.reg = { "csiphy2" },
|
|
|
|
.interrupt = { "csiphy2" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* CSIPHY3 */
|
|
|
|
{
|
|
|
|
.regulators = {},
|
|
|
|
.clock = { "csiphy3", "csiphy3_timer" },
|
|
|
|
.clock_rate = { { 400000000 },
|
|
|
|
{ 300000000 } },
|
|
|
|
.reg = { "csiphy3" },
|
|
|
|
.interrupt = { "csiphy3" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csiphy = {
|
2024-05-22 18:46:55 +03:00
|
|
|
.hw_ops = &csiphy_ops_3ph_1_0,
|
|
|
|
.formats = &csiphy_formats_sdm845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct camss_subdev_resources csid_res_sc8280xp[] = {
|
|
|
|
/* CSID0 */
|
|
|
|
{
|
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
|
|
|
.clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_axi" },
|
|
|
|
.clock_rate = { { 400000000, 480000000, 600000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid0" },
|
|
|
|
.interrupt = { "csid0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* CSID1 */
|
|
|
|
{
|
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
|
|
|
.clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_axi" },
|
|
|
|
.clock_rate = { { 400000000, 480000000, 600000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid1" },
|
|
|
|
.interrupt = { "csid1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* CSID2 */
|
|
|
|
{
|
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
|
|
|
.clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2", "vfe2_axi" },
|
|
|
|
.clock_rate = { { 400000000, 480000000, 600000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid2" },
|
|
|
|
.interrupt = { "csid2" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* CSID3 */
|
|
|
|
{
|
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
|
|
|
.clock = { "vfe3_csid", "vfe3_cphy_rx", "vfe3", "vfe3_axi" },
|
|
|
|
.clock_rate = { { 400000000, 480000000, 600000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 } },
|
|
|
|
.reg = { "csid3" },
|
|
|
|
.interrupt = { "csid3" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* CSID_LITE0 */
|
|
|
|
{
|
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
|
|
|
.clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" },
|
|
|
|
.clock_rate = { { 400000000, 480000000, 600000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 }, },
|
|
|
|
.reg = { "csid0_lite" },
|
|
|
|
.interrupt = { "csid0_lite" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
|
|
|
.is_lite = true,
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* CSID_LITE1 */
|
|
|
|
{
|
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
|
|
|
.clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" },
|
|
|
|
.clock_rate = { { 400000000, 480000000, 600000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 }, },
|
|
|
|
.reg = { "csid1_lite" },
|
|
|
|
.interrupt = { "csid1_lite" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
|
|
|
.is_lite = true,
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* CSID_LITE2 */
|
|
|
|
{
|
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
|
|
|
.clock = { "vfe_lite2_csid", "vfe_lite2_cphy_rx", "vfe_lite2" },
|
|
|
|
.clock_rate = { { 400000000, 480000000, 600000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 }, },
|
|
|
|
.reg = { "csid2_lite" },
|
|
|
|
.interrupt = { "csid2_lite" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
|
|
|
.is_lite = true,
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* CSID_LITE3 */
|
|
|
|
{
|
|
|
|
.regulators = { "vdda-phy", "vdda-pll" },
|
|
|
|
.clock = { "vfe_lite3_csid", "vfe_lite3_cphy_rx", "vfe_lite3" },
|
|
|
|
.clock_rate = { { 400000000, 480000000, 600000000 },
|
|
|
|
{ 0 },
|
|
|
|
{ 0 }, },
|
|
|
|
.reg = { "csid3_lite" },
|
|
|
|
.interrupt = { "csid3_lite" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.csid = {
|
|
|
|
.is_lite = true,
|
2024-05-22 18:46:54 +03:00
|
|
|
.hw_ops = &csid_ops_gen2,
|
2024-05-22 18:46:59 +03:00
|
|
|
.parent_dev_ops = &vfe_parent_dev_ops,
|
2024-05-22 18:46:54 +03:00
|
|
|
.formats = &csid_formats_gen2
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct camss_subdev_resources vfe_res_sc8280xp[] = {
|
|
|
|
/* VFE0 */
|
|
|
|
{
|
|
|
|
.regulators = {},
|
|
|
|
.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe0", "vfe0_axi" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 80000000},
|
|
|
|
{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
|
|
|
|
{ 400000000, 558000000, 637000000, 760000000 },
|
|
|
|
{ 0 }, },
|
|
|
|
.reg = { "vfe0" },
|
|
|
|
.interrupt = { "vfe0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 4,
|
|
|
|
.pd_name = "ife0",
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_170,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* VFE1 */
|
|
|
|
{
|
|
|
|
.regulators = {},
|
|
|
|
.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe1", "vfe1_axi" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 80000000},
|
|
|
|
{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
|
|
|
|
{ 400000000, 558000000, 637000000, 760000000 },
|
|
|
|
{ 0 }, },
|
|
|
|
.reg = { "vfe1" },
|
|
|
|
.interrupt = { "vfe1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 4,
|
|
|
|
.pd_name = "ife1",
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_170,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* VFE2 */
|
|
|
|
{
|
|
|
|
.regulators = {},
|
|
|
|
.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe2", "vfe2_axi" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 80000000},
|
|
|
|
{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
|
|
|
|
{ 400000000, 558000000, 637000000, 760000000 },
|
|
|
|
{ 0 }, },
|
|
|
|
.reg = { "vfe2" },
|
|
|
|
.interrupt = { "vfe2" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 4,
|
|
|
|
.pd_name = "ife2",
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_170,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* VFE3 */
|
|
|
|
{
|
|
|
|
.regulators = {},
|
|
|
|
.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe3", "vfe3_axi" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 80000000},
|
|
|
|
{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
|
|
|
|
{ 400000000, 558000000, 637000000, 760000000 },
|
|
|
|
{ 0 }, },
|
|
|
|
.reg = { "vfe3" },
|
|
|
|
.interrupt = { "vfe3" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.line_num = 4,
|
|
|
|
.pd_name = "ife3",
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_170,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* VFE_LITE_0 */
|
|
|
|
{
|
|
|
|
.regulators = {},
|
|
|
|
.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite0" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 80000000},
|
|
|
|
{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
|
|
|
|
{ 320000000, 400000000, 480000000, 600000000 }, },
|
|
|
|
.reg = { "vfe_lite0" },
|
|
|
|
.interrupt = { "vfe_lite0" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.is_lite = true,
|
|
|
|
.line_num = 4,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_170,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* VFE_LITE_1 */
|
|
|
|
{
|
|
|
|
.regulators = {},
|
|
|
|
.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite1" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 80000000},
|
|
|
|
{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
|
|
|
|
{ 320000000, 400000000, 480000000, 600000000 }, },
|
|
|
|
.reg = { "vfe_lite1" },
|
|
|
|
.interrupt = { "vfe_lite1" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.is_lite = true,
|
|
|
|
.line_num = 4,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_170,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* VFE_LITE_2 */
|
|
|
|
{
|
|
|
|
.regulators = {},
|
|
|
|
.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite2" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 80000000},
|
|
|
|
{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
|
|
|
|
{ 320000000, 400000000, 480000000, 600000000, }, },
|
|
|
|
.reg = { "vfe_lite2" },
|
|
|
|
.interrupt = { "vfe_lite2" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.is_lite = true,
|
|
|
|
.line_num = 4,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_170,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
/* VFE_LITE_3 */
|
|
|
|
{
|
|
|
|
.regulators = {},
|
|
|
|
.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite3" },
|
|
|
|
.clock_rate = { { 0 },
|
|
|
|
{ 0 },
|
|
|
|
{ 19200000, 80000000},
|
|
|
|
{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
|
|
|
|
{ 320000000, 400000000, 480000000, 600000000 }, },
|
|
|
|
.reg = { "vfe_lite3" },
|
|
|
|
.interrupt = { "vfe_lite3" },
|
2024-05-22 18:46:52 +03:00
|
|
|
.vfe = {
|
|
|
|
.is_lite = true,
|
|
|
|
.line_num = 4,
|
2024-05-22 18:46:53 +03:00
|
|
|
.hw_ops = &vfe_ops_170,
|
|
|
|
.formats_rdi = &vfe_formats_rdi_845,
|
|
|
|
.formats_pix = &vfe_formats_pix_845
|
2024-05-22 18:46:52 +03:00
|
|
|
}
|
2024-02-22 17:17:02 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct resources_icc icc_res_sc8280xp[] = {
|
|
|
|
{
|
|
|
|
.name = "cam_ahb",
|
|
|
|
.icc_bw_tbl.avg = 150000,
|
|
|
|
.icc_bw_tbl.peak = 300000,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "cam_hf_mnoc",
|
|
|
|
.icc_bw_tbl.avg = 2097152,
|
|
|
|
.icc_bw_tbl.peak = 2097152,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "cam_sf_mnoc",
|
|
|
|
.icc_bw_tbl.avg = 2097152,
|
|
|
|
.icc_bw_tbl.peak = 2097152,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "cam_sf_icp_mnoc",
|
|
|
|
.icc_bw_tbl.avg = 2097152,
|
|
|
|
.icc_bw_tbl.peak = 2097152,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2017-08-08 09:30:17 -04:00
|
|
|
/*
|
|
|
|
* camss_add_clock_margin - Add margin to clock frequency rate
|
|
|
|
* @rate: Clock frequency rate
|
|
|
|
*
|
|
|
|
* When making calculations with physical clock frequency values
|
|
|
|
* some safety margin must be added. Add it.
|
|
|
|
*/
|
|
|
|
inline void camss_add_clock_margin(u64 *rate)
|
|
|
|
{
|
|
|
|
*rate *= CAMSS_CLOCK_MARGIN_NUMERATOR;
|
|
|
|
*rate = div_u64(*rate, CAMSS_CLOCK_MARGIN_DENOMINATOR);
|
|
|
|
}
|
|
|
|
|
2017-08-08 09:30:07 -04:00
|
|
|
/*
|
|
|
|
* camss_enable_clocks - Enable multiple clocks
|
|
|
|
* @nclocks: Number of clocks in clock array
|
|
|
|
* @clock: Clock array
|
|
|
|
* @dev: Device
|
|
|
|
*
|
|
|
|
* Return 0 on success or a negative error code otherwise
|
|
|
|
*/
|
2017-08-08 09:30:17 -04:00
|
|
|
int camss_enable_clocks(int nclocks, struct camss_clock *clock,
|
|
|
|
struct device *dev)
|
2017-08-08 09:30:07 -04:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < nclocks; i++) {
|
2017-08-08 09:30:17 -04:00
|
|
|
ret = clk_prepare_enable(clock[i].clk);
|
2017-08-08 09:30:07 -04:00
|
|
|
if (ret) {
|
|
|
|
dev_err(dev, "clock enable failed: %d\n", ret);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
for (i--; i >= 0; i--)
|
2017-08-08 09:30:17 -04:00
|
|
|
clk_disable_unprepare(clock[i].clk);
|
2017-08-08 09:30:07 -04:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* camss_disable_clocks - Disable multiple clocks
|
|
|
|
* @nclocks: Number of clocks in clock array
|
|
|
|
* @clock: Clock array
|
|
|
|
*/
|
2017-08-08 09:30:17 -04:00
|
|
|
void camss_disable_clocks(int nclocks, struct camss_clock *clock)
|
2017-08-08 09:30:07 -04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = nclocks - 1; i >= 0; i--)
|
2017-08-08 09:30:17 -04:00
|
|
|
clk_disable_unprepare(clock[i].clk);
|
2017-08-08 09:30:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* camss_find_sensor - Find a linked media entity which represents a sensor
|
|
|
|
* @entity: Media entity to start searching from
|
|
|
|
*
|
|
|
|
* Return a pointer to sensor media entity or NULL if not found
|
|
|
|
*/
|
2018-11-13 09:03:07 -05:00
|
|
|
struct media_entity *camss_find_sensor(struct media_entity *entity)
|
2017-08-08 09:30:07 -04:00
|
|
|
{
|
|
|
|
struct media_pad *pad;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
pad = &entity->pads[0];
|
|
|
|
if (!(pad->flags & MEDIA_PAD_FL_SINK))
|
|
|
|
return NULL;
|
|
|
|
|
2022-06-25 18:02:24 +01:00
|
|
|
pad = media_pad_remote_pad_first(pad);
|
2017-08-08 09:30:07 -04:00
|
|
|
if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
entity = pad->entity;
|
|
|
|
|
|
|
|
if (entity->function == MEDIA_ENT_F_CAM_SENSOR)
|
|
|
|
return entity;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-17 23:11:33 +01:00
|
|
|
/**
|
|
|
|
* camss_get_link_freq - Get link frequency from sensor
|
|
|
|
* @entity: Media entity in the current pipeline
|
|
|
|
* @bpp: Number of bits per pixel for the current format
|
|
|
|
* @lanes: Number of lanes in the link to the sensor
|
|
|
|
*
|
|
|
|
* Return link frequency on success or a negative error code otherwise
|
|
|
|
*/
|
|
|
|
s64 camss_get_link_freq(struct media_entity *entity, unsigned int bpp,
|
|
|
|
unsigned int lanes)
|
|
|
|
{
|
|
|
|
struct media_entity *sensor;
|
|
|
|
struct v4l2_subdev *subdev;
|
|
|
|
|
|
|
|
sensor = camss_find_sensor(entity);
|
|
|
|
if (!sensor)
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
subdev = media_entity_to_v4l2_subdev(sensor);
|
|
|
|
|
|
|
|
return v4l2_get_link_freq(subdev->ctrl_handler, bpp, 2 * lanes);
|
|
|
|
}
|
|
|
|
|
2017-08-08 09:30:07 -04:00
|
|
|
/*
|
|
|
|
* camss_get_pixel_clock - Get pixel clock rate from sensor
|
|
|
|
* @entity: Media entity in the current pipeline
|
|
|
|
* @pixel_clock: Received pixel clock value
|
|
|
|
*
|
|
|
|
* Return 0 on success or a negative error code otherwise
|
|
|
|
*/
|
2021-02-17 23:11:34 +01:00
|
|
|
int camss_get_pixel_clock(struct media_entity *entity, u64 *pixel_clock)
|
2017-08-08 09:30:07 -04:00
|
|
|
{
|
|
|
|
struct media_entity *sensor;
|
|
|
|
struct v4l2_subdev *subdev;
|
|
|
|
struct v4l2_ctrl *ctrl;
|
|
|
|
|
|
|
|
sensor = camss_find_sensor(entity);
|
|
|
|
if (!sensor)
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
subdev = media_entity_to_v4l2_subdev(sensor);
|
|
|
|
|
|
|
|
ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE);
|
|
|
|
|
|
|
|
if (!ctrl)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
*pixel_clock = v4l2_ctrl_g_ctrl_int64(ctrl);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-07-25 12:38:27 -04:00
|
|
|
int camss_pm_domain_on(struct camss *camss, int id)
|
|
|
|
{
|
2021-03-16 18:19:21 +01:00
|
|
|
int ret = 0;
|
|
|
|
|
2023-09-25 16:46:55 +01:00
|
|
|
if (id < camss->res->vfe_num) {
|
2021-03-16 18:19:21 +01:00
|
|
|
struct vfe_device *vfe = &camss->vfe[id];
|
2018-07-25 12:38:27 -04:00
|
|
|
|
2024-05-22 18:46:52 +03:00
|
|
|
ret = vfe->res->hw_ops->pm_domain_on(vfe);
|
2018-07-25 12:38:27 -04:00
|
|
|
}
|
|
|
|
|
2021-03-16 18:19:21 +01:00
|
|
|
return ret;
|
2018-07-25 12:38:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void camss_pm_domain_off(struct camss *camss, int id)
|
|
|
|
{
|
2023-09-25 16:46:55 +01:00
|
|
|
if (id < camss->res->vfe_num) {
|
2021-03-16 18:19:21 +01:00
|
|
|
struct vfe_device *vfe = &camss->vfe[id];
|
|
|
|
|
2024-05-22 18:46:52 +03:00
|
|
|
vfe->res->hw_ops->pm_domain_off(vfe);
|
2021-03-16 18:19:21 +01:00
|
|
|
}
|
2018-07-25 12:38:27 -04:00
|
|
|
}
|
|
|
|
|
2024-05-22 18:46:59 +03:00
|
|
|
static int vfe_parent_dev_ops_get(struct camss *camss, int id)
|
|
|
|
{
|
|
|
|
int ret = -EINVAL;
|
|
|
|
|
|
|
|
if (id < camss->res->vfe_num) {
|
|
|
|
struct vfe_device *vfe = &camss->vfe[id];
|
|
|
|
|
|
|
|
ret = vfe_get(vfe);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vfe_parent_dev_ops_put(struct camss *camss, int id)
|
|
|
|
{
|
|
|
|
if (id < camss->res->vfe_num) {
|
|
|
|
struct vfe_device *vfe = &camss->vfe[id];
|
|
|
|
|
|
|
|
vfe_put(vfe);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __iomem
|
|
|
|
*vfe_parent_dev_ops_get_base_address(struct camss *camss, int id)
|
|
|
|
{
|
|
|
|
if (id < camss->res->vfe_num) {
|
|
|
|
struct vfe_device *vfe = &camss->vfe[id];
|
|
|
|
|
|
|
|
return vfe->base;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct parent_dev_ops vfe_parent_dev_ops = {
|
|
|
|
.get = vfe_parent_dev_ops_get,
|
|
|
|
.put = vfe_parent_dev_ops_put,
|
|
|
|
.get_base_address = vfe_parent_dev_ops_get_base_address
|
|
|
|
};
|
|
|
|
|
2017-08-08 09:30:07 -04:00
|
|
|
/*
|
|
|
|
* camss_of_parse_endpoint_node - Parse port endpoint node
|
|
|
|
* @dev: Device
|
|
|
|
* @node: Device node to be parsed
|
|
|
|
* @csd: Parsed data from port endpoint node
|
|
|
|
*
|
|
|
|
* Return 0 on success or a negative error code on failure
|
|
|
|
*/
|
|
|
|
static int camss_of_parse_endpoint_node(struct device *dev,
|
|
|
|
struct device_node *node,
|
|
|
|
struct camss_async_subdev *csd)
|
|
|
|
{
|
|
|
|
struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg;
|
2022-01-03 17:24:10 +01:00
|
|
|
struct v4l2_mbus_config_mipi_csi2 *mipi_csi2;
|
2017-08-08 09:30:07 -04:00
|
|
|
struct v4l2_fwnode_endpoint vep = { { 0 } };
|
|
|
|
unsigned int i;
|
2024-06-21 09:35:22 +08:00
|
|
|
int ret;
|
2017-08-08 09:30:07 -04:00
|
|
|
|
2024-06-21 09:35:22 +08:00
|
|
|
ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
2017-08-08 09:30:07 -04:00
|
|
|
|
|
|
|
csd->interface.csiphy_id = vep.base.port;
|
|
|
|
|
|
|
|
mipi_csi2 = &vep.bus.mipi_csi2;
|
|
|
|
lncfg->clk.pos = mipi_csi2->clock_lane;
|
|
|
|
lncfg->clk.pol = mipi_csi2->lane_polarities[0];
|
|
|
|
lncfg->num_data = mipi_csi2->num_data_lanes;
|
|
|
|
|
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 14:07:58 -07:00
|
|
|
lncfg->data = devm_kcalloc(dev,
|
|
|
|
lncfg->num_data, sizeof(*lncfg->data),
|
2017-08-08 09:30:07 -04:00
|
|
|
GFP_KERNEL);
|
|
|
|
if (!lncfg->data)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
for (i = 0; i < lncfg->num_data; i++) {
|
|
|
|
lncfg->data[i].pos = mipi_csi2->data_lanes[i];
|
|
|
|
lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* camss_of_parse_ports - Parse ports node
|
|
|
|
* @dev: Device
|
|
|
|
* @notifier: v4l2_device notifier data
|
|
|
|
*
|
|
|
|
* Return number of "port" nodes found in "ports" node
|
|
|
|
*/
|
2018-09-29 15:54:18 -04:00
|
|
|
static int camss_of_parse_ports(struct camss *camss)
|
2017-08-08 09:30:07 -04:00
|
|
|
{
|
2018-09-29 15:54:18 -04:00
|
|
|
struct device *dev = camss->dev;
|
2017-08-08 09:30:07 -04:00
|
|
|
struct device_node *node = NULL;
|
|
|
|
struct device_node *remote = NULL;
|
2018-09-29 15:54:18 -04:00
|
|
|
int ret, num_subdevs = 0;
|
2017-08-08 09:30:07 -04:00
|
|
|
|
2018-09-29 15:54:18 -04:00
|
|
|
for_each_endpoint_of_node(dev->of_node, node) {
|
2017-08-08 09:30:07 -04:00
|
|
|
struct camss_async_subdev *csd;
|
|
|
|
|
|
|
|
if (!of_device_is_available(node))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
remote = of_graph_get_remote_port_parent(node);
|
|
|
|
if (!remote) {
|
|
|
|
dev_err(dev, "Cannot get remote parent\n");
|
2018-09-29 15:54:18 -04:00
|
|
|
ret = -EINVAL;
|
|
|
|
goto err_cleanup;
|
2017-08-08 09:30:07 -04:00
|
|
|
}
|
|
|
|
|
2021-03-05 18:13:12 +01:00
|
|
|
csd = v4l2_async_nf_add_fwnode(&camss->notifier,
|
|
|
|
of_fwnode_handle(remote),
|
|
|
|
struct camss_async_subdev);
|
2019-04-04 19:43:29 -04:00
|
|
|
of_node_put(remote);
|
2021-01-18 02:52:58 +01:00
|
|
|
if (IS_ERR(csd)) {
|
|
|
|
ret = PTR_ERR(csd);
|
2018-09-29 15:54:18 -04:00
|
|
|
goto err_cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = camss_of_parse_endpoint_node(dev, node, csd);
|
|
|
|
if (ret < 0)
|
|
|
|
goto err_cleanup;
|
|
|
|
|
|
|
|
num_subdevs++;
|
2017-08-08 09:30:07 -04:00
|
|
|
}
|
|
|
|
|
2018-09-29 15:54:18 -04:00
|
|
|
return num_subdevs;
|
|
|
|
|
|
|
|
err_cleanup:
|
|
|
|
of_node_put(node);
|
|
|
|
return ret;
|
2017-08-08 09:30:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* camss_init_subdevices - Initialize subdev structures and resources
|
|
|
|
* @camss: CAMSS device
|
|
|
|
*
|
|
|
|
* Return 0 on success or a negative error code on failure
|
|
|
|
*/
|
|
|
|
static int camss_init_subdevices(struct camss *camss)
|
|
|
|
{
|
2023-09-25 16:46:53 +01:00
|
|
|
const struct camss_resources *res = camss->res;
|
2017-08-08 09:30:07 -04:00
|
|
|
unsigned int i;
|
|
|
|
int ret;
|
|
|
|
|
2023-09-25 16:46:55 +01:00
|
|
|
for (i = 0; i < camss->res->csiphy_num; i++) {
|
2018-07-25 12:38:26 -04:00
|
|
|
ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i],
|
2023-09-25 16:46:53 +01:00
|
|
|
&res->csiphy_res[i], i);
|
2017-08-08 09:30:07 -04:00
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev,
|
|
|
|
"Failed to init csiphy%d sub-device: %d\n",
|
|
|
|
i, ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-22 01:37:48 +01:00
|
|
|
/* note: SM8250 requires VFE to be initialized before CSID */
|
2023-11-23 17:03:05 +00:00
|
|
|
for (i = 0; i < camss->res->vfe_num; i++) {
|
2021-12-22 01:37:48 +01:00
|
|
|
ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
|
2023-09-25 16:46:53 +01:00
|
|
|
&res->vfe_res[i], i);
|
2021-12-22 01:37:48 +01:00
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev,
|
|
|
|
"Fail to init vfe%d sub-device: %d\n", i, ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-25 16:46:55 +01:00
|
|
|
for (i = 0; i < camss->res->csid_num; i++) {
|
2018-07-25 12:38:26 -04:00
|
|
|
ret = msm_csid_subdev_init(camss, &camss->csid[i],
|
2023-09-25 16:46:53 +01:00
|
|
|
&res->csid_res[i], i);
|
2017-08-08 09:30:07 -04:00
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev,
|
|
|
|
"Failed to init csid%d sub-device: %d\n",
|
|
|
|
i, ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-25 16:46:53 +01:00
|
|
|
ret = msm_ispif_subdev_init(camss, res->ispif_res);
|
2017-08-08 09:30:07 -04:00
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev, "Failed to init ispif sub-device: %d\n",
|
2021-03-16 18:19:14 +01:00
|
|
|
ret);
|
2017-08-08 09:30:07 -04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2024-05-22 18:46:58 +03:00
|
|
|
* camss_link_entities - Register subdev nodes and create links
|
2017-08-08 09:30:07 -04:00
|
|
|
* @camss: CAMSS device
|
|
|
|
*
|
|
|
|
* Return 0 on success or a negative error code on failure
|
|
|
|
*/
|
2024-05-22 18:46:58 +03:00
|
|
|
static int camss_link_entities(struct camss *camss)
|
2017-08-08 09:30:07 -04:00
|
|
|
{
|
2018-07-25 12:38:26 -04:00
|
|
|
int i, j, k;
|
2017-08-08 09:30:07 -04:00
|
|
|
int ret;
|
|
|
|
|
2023-09-25 16:46:55 +01:00
|
|
|
for (i = 0; i < camss->res->csiphy_num; i++) {
|
|
|
|
for (j = 0; j < camss->res->csid_num; j++) {
|
2024-05-22 18:46:58 +03:00
|
|
|
ret = media_create_pad_link(&camss->csiphy[i].subdev.entity,
|
|
|
|
MSM_CSIPHY_PAD_SRC,
|
|
|
|
&camss->csid[j].subdev.entity,
|
|
|
|
MSM_CSID_PAD_SINK,
|
|
|
|
0);
|
2017-08-08 09:30:07 -04:00
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev,
|
|
|
|
"Failed to link %s->%s entities: %d\n",
|
|
|
|
camss->csiphy[i].subdev.entity.name,
|
|
|
|
camss->csid[j].subdev.entity.name,
|
|
|
|
ret);
|
2024-05-22 18:46:58 +03:00
|
|
|
return ret;
|
2017-08-08 09:30:07 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-16 18:19:14 +01:00
|
|
|
if (camss->ispif) {
|
2023-09-25 16:46:55 +01:00
|
|
|
for (i = 0; i < camss->res->csid_num; i++) {
|
2021-03-16 18:19:14 +01:00
|
|
|
for (j = 0; j < camss->ispif->line_num; j++) {
|
2024-05-22 18:46:58 +03:00
|
|
|
ret = media_create_pad_link(&camss->csid[i].subdev.entity,
|
|
|
|
MSM_CSID_PAD_SRC,
|
|
|
|
&camss->ispif->line[j].subdev.entity,
|
|
|
|
MSM_ISPIF_PAD_SINK,
|
|
|
|
0);
|
2018-07-25 12:38:26 -04:00
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev,
|
|
|
|
"Failed to link %s->%s entities: %d\n",
|
2021-03-16 18:19:14 +01:00
|
|
|
camss->csid[i].subdev.entity.name,
|
|
|
|
camss->ispif->line[j].subdev.entity.name,
|
2018-07-25 12:38:26 -04:00
|
|
|
ret);
|
2024-05-22 18:46:58 +03:00
|
|
|
return ret;
|
2018-07-25 12:38:26 -04:00
|
|
|
}
|
2017-08-08 09:30:07 -04:00
|
|
|
}
|
2021-03-16 18:19:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < camss->ispif->line_num; i++)
|
2023-09-25 16:46:55 +01:00
|
|
|
for (k = 0; k < camss->res->vfe_num; k++)
|
2024-05-22 18:46:52 +03:00
|
|
|
for (j = 0; j < camss->vfe[k].res->line_num; j++) {
|
2021-03-16 18:19:14 +01:00
|
|
|
struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev;
|
|
|
|
struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
|
|
|
|
|
|
|
|
ret = media_create_pad_link(&ispif->entity,
|
|
|
|
MSM_ISPIF_PAD_SRC,
|
|
|
|
&vfe->entity,
|
|
|
|
MSM_VFE_PAD_SINK,
|
|
|
|
0);
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev,
|
|
|
|
"Failed to link %s->%s entities: %d\n",
|
|
|
|
ispif->entity.name,
|
|
|
|
vfe->entity.name,
|
|
|
|
ret);
|
2024-05-22 18:46:58 +03:00
|
|
|
return ret;
|
2021-03-16 18:19:14 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2023-09-25 16:46:55 +01:00
|
|
|
for (i = 0; i < camss->res->csid_num; i++)
|
2023-11-23 17:03:05 +00:00
|
|
|
for (k = 0; k < camss->res->vfe_num; k++)
|
2024-05-22 18:46:52 +03:00
|
|
|
for (j = 0; j < camss->vfe[k].res->line_num; j++) {
|
2021-03-16 18:19:14 +01:00
|
|
|
struct v4l2_subdev *csid = &camss->csid[i].subdev;
|
|
|
|
struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
|
|
|
|
|
|
|
|
ret = media_create_pad_link(&csid->entity,
|
2022-12-09 11:40:35 +02:00
|
|
|
MSM_CSID_PAD_FIRST_SRC + j,
|
2021-03-16 18:19:14 +01:00
|
|
|
&vfe->entity,
|
|
|
|
MSM_VFE_PAD_SINK,
|
|
|
|
0);
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev,
|
|
|
|
"Failed to link %s->%s entities: %d\n",
|
|
|
|
csid->entity.name,
|
|
|
|
vfe->entity.name,
|
|
|
|
ret);
|
2024-05-22 18:46:58 +03:00
|
|
|
return ret;
|
2021-03-16 18:19:14 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-08-08 09:30:07 -04:00
|
|
|
|
2024-05-22 18:46:58 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* camss_register_entities - Register subdev nodes and create links
|
|
|
|
* @camss: CAMSS device
|
|
|
|
*
|
|
|
|
* Return 0 on success or a negative error code on failure
|
|
|
|
*/
|
|
|
|
static int camss_register_entities(struct camss *camss)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
for (i = 0; i < camss->res->csiphy_num; i++) {
|
|
|
|
ret = msm_csiphy_register_entity(&camss->csiphy[i],
|
|
|
|
&camss->v4l2_dev);
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev,
|
|
|
|
"Failed to register csiphy%d entity: %d\n",
|
|
|
|
i, ret);
|
|
|
|
goto err_reg_csiphy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < camss->res->csid_num; i++) {
|
|
|
|
ret = msm_csid_register_entity(&camss->csid[i],
|
|
|
|
&camss->v4l2_dev);
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev,
|
|
|
|
"Failed to register csid%d entity: %d\n",
|
|
|
|
i, ret);
|
|
|
|
goto err_reg_csid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = msm_ispif_register_entities(camss->ispif,
|
|
|
|
&camss->v4l2_dev);
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev, "Failed to register ispif entities: %d\n", ret);
|
|
|
|
goto err_reg_ispif;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < camss->res->vfe_num; i++) {
|
|
|
|
ret = msm_vfe_register_entities(&camss->vfe[i],
|
|
|
|
&camss->v4l2_dev);
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev,
|
|
|
|
"Failed to register vfe%d entities: %d\n",
|
|
|
|
i, ret);
|
|
|
|
goto err_reg_vfe;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-08 09:30:07 -04:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_reg_vfe:
|
2018-07-25 12:38:26 -04:00
|
|
|
for (i--; i >= 0; i--)
|
|
|
|
msm_vfe_unregister_entities(&camss->vfe[i]);
|
|
|
|
|
2017-08-08 09:30:07 -04:00
|
|
|
err_reg_ispif:
|
2021-03-16 18:19:14 +01:00
|
|
|
msm_ispif_unregister_entities(camss->ispif);
|
2017-08-08 09:30:07 -04:00
|
|
|
|
2023-09-25 16:46:55 +01:00
|
|
|
i = camss->res->csid_num;
|
2017-08-08 09:30:07 -04:00
|
|
|
err_reg_csid:
|
|
|
|
for (i--; i >= 0; i--)
|
|
|
|
msm_csid_unregister_entity(&camss->csid[i]);
|
|
|
|
|
2023-09-25 16:46:55 +01:00
|
|
|
i = camss->res->csiphy_num;
|
2017-08-08 09:30:07 -04:00
|
|
|
err_reg_csiphy:
|
|
|
|
for (i--; i >= 0; i--)
|
|
|
|
msm_csiphy_unregister_entity(&camss->csiphy[i]);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* camss_unregister_entities - Unregister subdev nodes
|
|
|
|
* @camss: CAMSS device
|
|
|
|
*
|
|
|
|
* Return 0 on success or a negative error code on failure
|
|
|
|
*/
|
|
|
|
static void camss_unregister_entities(struct camss *camss)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
2023-09-25 16:46:55 +01:00
|
|
|
for (i = 0; i < camss->res->csiphy_num; i++)
|
2017-08-08 09:30:07 -04:00
|
|
|
msm_csiphy_unregister_entity(&camss->csiphy[i]);
|
|
|
|
|
2023-09-25 16:46:55 +01:00
|
|
|
for (i = 0; i < camss->res->csid_num; i++)
|
2017-08-08 09:30:07 -04:00
|
|
|
msm_csid_unregister_entity(&camss->csid[i]);
|
|
|
|
|
2021-03-16 18:19:14 +01:00
|
|
|
msm_ispif_unregister_entities(camss->ispif);
|
2018-07-25 12:38:26 -04:00
|
|
|
|
2023-11-23 17:03:05 +00:00
|
|
|
for (i = 0; i < camss->res->vfe_num; i++)
|
2018-07-25 12:38:26 -04:00
|
|
|
msm_vfe_unregister_entities(&camss->vfe[i]);
|
2017-08-08 09:30:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static int camss_subdev_notifier_bound(struct v4l2_async_notifier *async,
|
|
|
|
struct v4l2_subdev *subdev,
|
2023-02-16 14:54:53 +01:00
|
|
|
struct v4l2_async_connection *asd)
|
2017-08-08 09:30:07 -04:00
|
|
|
{
|
|
|
|
struct camss *camss = container_of(async, struct camss, notifier);
|
|
|
|
struct camss_async_subdev *csd =
|
|
|
|
container_of(asd, struct camss_async_subdev, asd);
|
|
|
|
u8 id = csd->interface.csiphy_id;
|
|
|
|
struct csiphy_device *csiphy = &camss->csiphy[id];
|
|
|
|
|
|
|
|
csiphy->cfg.csi2 = &csd->interface.csi2;
|
|
|
|
subdev->host_priv = csiphy;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async)
|
|
|
|
{
|
|
|
|
struct camss *camss = container_of(async, struct camss, notifier);
|
|
|
|
struct v4l2_device *v4l2_dev = &camss->v4l2_dev;
|
|
|
|
struct v4l2_subdev *sd;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
|
|
|
|
if (sd->host_priv) {
|
|
|
|
struct media_entity *sensor = &sd->entity;
|
|
|
|
struct csiphy_device *csiphy =
|
|
|
|
(struct csiphy_device *) sd->host_priv;
|
|
|
|
struct media_entity *input = &csiphy->subdev.entity;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < sensor->num_pads; i++) {
|
|
|
|
if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i == sensor->num_pads) {
|
|
|
|
dev_err(camss->dev,
|
|
|
|
"No source pad in external entity\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = media_create_pad_link(sensor, i,
|
|
|
|
input, MSM_CSIPHY_PAD_SINK,
|
|
|
|
MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(camss->dev,
|
|
|
|
"Failed to link %s->%s entities: %d\n",
|
|
|
|
sensor->name, input->name, ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
return media_device_register(&camss->media_dev);
|
|
|
|
}
|
|
|
|
|
2017-08-30 13:18:04 -04:00
|
|
|
static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = {
|
|
|
|
.bound = camss_subdev_notifier_bound,
|
|
|
|
.complete = camss_subdev_notifier_complete,
|
|
|
|
};
|
|
|
|
|
2017-08-08 09:30:07 -04:00
|
|
|
static const struct media_device_ops camss_media_ops = {
|
|
|
|
.link_notify = v4l2_pipeline_link_notify,
|
|
|
|
};
|
|
|
|
|
2021-03-16 18:19:21 +01:00
|
|
|
static int camss_configure_pd(struct camss *camss)
|
|
|
|
{
|
2023-11-23 17:03:03 +00:00
|
|
|
const struct camss_resources *res = camss->res;
|
2022-05-12 09:23:18 +01:00
|
|
|
struct device *dev = camss->dev;
|
2023-11-23 17:03:03 +00:00
|
|
|
int vfepd_num;
|
2021-03-16 18:19:21 +01:00
|
|
|
int i;
|
|
|
|
int ret;
|
|
|
|
|
2022-05-12 09:23:18 +01:00
|
|
|
camss->genpd_num = of_count_phandle_with_args(dev->of_node,
|
|
|
|
"power-domains",
|
|
|
|
"#power-domain-cells");
|
|
|
|
if (camss->genpd_num < 0) {
|
|
|
|
dev_err(dev, "Power domains are not defined for camss\n");
|
|
|
|
return camss->genpd_num;
|
|
|
|
}
|
|
|
|
|
2022-07-04 23:08:14 +01:00
|
|
|
/*
|
|
|
|
* If a platform device has just one power domain, then it is attached
|
|
|
|
* at platform_probe() level, thus there shall be no need and even no
|
|
|
|
* option to attach it again, this is the case for CAMSS on MSM8916.
|
|
|
|
*/
|
|
|
|
if (camss->genpd_num == 1)
|
|
|
|
return 0;
|
|
|
|
|
2023-11-23 17:03:03 +00:00
|
|
|
/* count the # of VFEs which have flagged power-domain */
|
2023-11-23 17:03:05 +00:00
|
|
|
for (vfepd_num = i = 0; i < camss->res->vfe_num; i++) {
|
2024-05-22 18:46:52 +03:00
|
|
|
if (res->vfe_res[i].vfe.has_pd)
|
2023-11-23 17:03:03 +00:00
|
|
|
vfepd_num++;
|
|
|
|
}
|
2021-03-16 18:19:21 +01:00
|
|
|
|
2023-11-23 17:03:03 +00:00
|
|
|
/*
|
|
|
|
* If the number of power-domains is greater than the number of VFEs
|
|
|
|
* then the additional power-domain is for the entire CAMSS block.
|
|
|
|
*/
|
|
|
|
if (!(camss->genpd_num > vfepd_num))
|
|
|
|
return 0;
|
2022-05-12 09:23:18 +01:00
|
|
|
|
media: camss: Split power domain management
There are three cases of power domain management on supported platforms:
1) CAMSS on MSM8916, where a single VFE power domain is operated outside
of the camss device driver,
2) CAMSS on MSM8996 and SDM630/SDM660, where two VFE power domains are
managed separately by the camss device driver, the power domains are
linked and unlinked on demand by their functions vfe_pm_domain_on()
and vfe_pm_domain_off() respectively,
3) CAMSS on SDM845 and SM8250 platforms, and there are two VFE power
domains and their parent power domain TITAN_TOP, the latter one
shall be turned on prior to turning on any of VFE power domains.
Due to a previously missing link between TITAN_TOP and VFEx power domains
in the latter case, which is now fixed by [1], it was decided always to
turn on all found VFE power domains and TITAN_TOP power domain, even if
just one particular VFE is needed to be enabled or none of VFE power
domains are required, for instance the latter case is when vfe_lite is in
use. This misusage becomes more incovenient and clumsy, if next generations
are to be supported, for instance CAMSS on SM8450 has three VFE power
domains.
The change splits the power management support for platforms with TITAN_TOP
parent power domain, and, since 'power-domain-names' property is not
present in camss device tree nodes, the assumption is that the first
N power domains from the 'power-domains' list correspond to VFE power
domains, and, if the number of power domains is greater than number of
non-lite VFEs, then the last power domain from the list is the TITAN_TOP
power domain.
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2022-07-04 23:15:48 +01:00
|
|
|
/*
|
2023-12-06 13:25:00 +01:00
|
|
|
* If a power-domain name is defined try to use it.
|
|
|
|
* It is possible we are running a new kernel with an old dtb so
|
|
|
|
* fallback to indexes even if a pd_name is defined but not found.
|
media: camss: Split power domain management
There are three cases of power domain management on supported platforms:
1) CAMSS on MSM8916, where a single VFE power domain is operated outside
of the camss device driver,
2) CAMSS on MSM8996 and SDM630/SDM660, where two VFE power domains are
managed separately by the camss device driver, the power domains are
linked and unlinked on demand by their functions vfe_pm_domain_on()
and vfe_pm_domain_off() respectively,
3) CAMSS on SDM845 and SM8250 platforms, and there are two VFE power
domains and their parent power domain TITAN_TOP, the latter one
shall be turned on prior to turning on any of VFE power domains.
Due to a previously missing link between TITAN_TOP and VFEx power domains
in the latter case, which is now fixed by [1], it was decided always to
turn on all found VFE power domains and TITAN_TOP power domain, even if
just one particular VFE is needed to be enabled or none of VFE power
domains are required, for instance the latter case is when vfe_lite is in
use. This misusage becomes more incovenient and clumsy, if next generations
are to be supported, for instance CAMSS on SM8450 has three VFE power
domains.
The change splits the power management support for platforms with TITAN_TOP
parent power domain, and, since 'power-domain-names' property is not
present in camss device tree nodes, the assumption is that the first
N power domains from the 'power-domains' list correspond to VFE power
domains, and, if the number of power domains is greater than number of
non-lite VFEs, then the last power domain from the list is the TITAN_TOP
power domain.
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2022-07-04 23:15:48 +01:00
|
|
|
*/
|
2023-12-06 13:25:00 +01:00
|
|
|
if (camss->res->pd_name) {
|
|
|
|
camss->genpd = dev_pm_domain_attach_by_name(camss->dev,
|
|
|
|
camss->res->pd_name);
|
|
|
|
if (IS_ERR(camss->genpd)) {
|
|
|
|
ret = PTR_ERR(camss->genpd);
|
|
|
|
goto fail_pm;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!camss->genpd) {
|
|
|
|
/*
|
|
|
|
* Legacy magic index. TITAN_TOP GDSC must be the last
|
|
|
|
* item in the power-domain list.
|
|
|
|
*/
|
|
|
|
camss->genpd = dev_pm_domain_attach_by_id(camss->dev,
|
|
|
|
camss->genpd_num - 1);
|
|
|
|
}
|
|
|
|
if (IS_ERR_OR_NULL(camss->genpd)) {
|
|
|
|
if (!camss->genpd)
|
|
|
|
ret = -ENODEV;
|
|
|
|
else
|
|
|
|
ret = PTR_ERR(camss->genpd);
|
2023-11-23 17:03:03 +00:00
|
|
|
goto fail_pm;
|
media: camss: Split power domain management
There are three cases of power domain management on supported platforms:
1) CAMSS on MSM8916, where a single VFE power domain is operated outside
of the camss device driver,
2) CAMSS on MSM8996 and SDM630/SDM660, where two VFE power domains are
managed separately by the camss device driver, the power domains are
linked and unlinked on demand by their functions vfe_pm_domain_on()
and vfe_pm_domain_off() respectively,
3) CAMSS on SDM845 and SM8250 platforms, and there are two VFE power
domains and their parent power domain TITAN_TOP, the latter one
shall be turned on prior to turning on any of VFE power domains.
Due to a previously missing link between TITAN_TOP and VFEx power domains
in the latter case, which is now fixed by [1], it was decided always to
turn on all found VFE power domains and TITAN_TOP power domain, even if
just one particular VFE is needed to be enabled or none of VFE power
domains are required, for instance the latter case is when vfe_lite is in
use. This misusage becomes more incovenient and clumsy, if next generations
are to be supported, for instance CAMSS on SM8450 has three VFE power
domains.
The change splits the power management support for platforms with TITAN_TOP
parent power domain, and, since 'power-domain-names' property is not
present in camss device tree nodes, the assumption is that the first
N power domains from the 'power-domains' list correspond to VFE power
domains, and, if the number of power domains is greater than number of
non-lite VFEs, then the last power domain from the list is the TITAN_TOP
power domain.
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2022-07-04 23:15:48 +01:00
|
|
|
}
|
2023-11-23 17:03:03 +00:00
|
|
|
camss->genpd_link = device_link_add(camss->dev, camss->genpd,
|
|
|
|
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
|
|
|
|
DL_FLAG_RPM_ACTIVE);
|
|
|
|
if (!camss->genpd_link) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto fail_pm;
|
2021-03-16 18:19:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fail_pm:
|
2023-11-23 17:03:03 +00:00
|
|
|
dev_pm_domain_detach(camss->genpd, true);
|
2021-03-16 18:19:21 +01:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2021-12-22 01:37:49 +01:00
|
|
|
static int camss_icc_get(struct camss *camss)
|
|
|
|
{
|
|
|
|
const struct resources_icc *icc_res;
|
|
|
|
int i;
|
|
|
|
|
2023-09-25 16:46:54 +01:00
|
|
|
icc_res = camss->res->icc_res;
|
2021-12-22 01:37:49 +01:00
|
|
|
|
2023-09-25 16:46:54 +01:00
|
|
|
for (i = 0; i < camss->res->icc_path_num; i++) {
|
2021-12-22 01:37:49 +01:00
|
|
|
camss->icc_path[i] = devm_of_icc_get(camss->dev,
|
|
|
|
icc_res[i].name);
|
|
|
|
if (IS_ERR(camss->icc_path[i]))
|
|
|
|
return PTR_ERR(camss->icc_path[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-11-23 17:03:03 +00:00
|
|
|
static void camss_genpd_subdevice_cleanup(struct camss *camss)
|
2023-08-30 16:16:08 +01:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2023-11-23 17:03:05 +00:00
|
|
|
for (i = 0; i < camss->res->vfe_num; i++)
|
2023-11-23 17:03:03 +00:00
|
|
|
msm_vfe_genpd_cleanup(&camss->vfe[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void camss_genpd_cleanup(struct camss *camss)
|
|
|
|
{
|
2023-08-30 16:16:08 +01:00
|
|
|
if (camss->genpd_num == 1)
|
|
|
|
return;
|
|
|
|
|
2023-11-23 17:03:03 +00:00
|
|
|
camss_genpd_subdevice_cleanup(camss);
|
|
|
|
|
|
|
|
if (camss->genpd_link)
|
|
|
|
device_link_del(camss->genpd_link);
|
2023-08-30 16:16:08 +01:00
|
|
|
|
2023-11-23 17:03:03 +00:00
|
|
|
dev_pm_domain_detach(camss->genpd, true);
|
2023-08-30 16:16:08 +01:00
|
|
|
}
|
|
|
|
|
2017-08-08 09:30:07 -04:00
|
|
|
/*
|
|
|
|
* camss_probe - Probe CAMSS platform device
|
|
|
|
* @pdev: Pointer to CAMSS platform device
|
|
|
|
*
|
|
|
|
* Return 0 on success or a negative error code on failure
|
|
|
|
*/
|
|
|
|
static int camss_probe(struct platform_device *pdev)
|
|
|
|
{
|
|
|
|
struct device *dev = &pdev->dev;
|
|
|
|
struct camss *camss;
|
2023-09-25 16:46:55 +01:00
|
|
|
int num_subdevs;
|
|
|
|
int ret;
|
2017-08-08 09:30:07 -04:00
|
|
|
|
2022-05-19 06:14:15 +01:00
|
|
|
camss = devm_kzalloc(dev, sizeof(*camss), GFP_KERNEL);
|
2017-08-08 09:30:07 -04:00
|
|
|
if (!camss)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2023-09-25 16:46:53 +01:00
|
|
|
camss->res = of_device_get_match_data(dev);
|
|
|
|
|
2017-08-08 09:30:07 -04:00
|
|
|
atomic_set(&camss->ref_count, 0);
|
|
|
|
camss->dev = dev;
|
|
|
|
platform_set_drvdata(pdev, camss);
|
|
|
|
|
2023-09-25 16:46:55 +01:00
|
|
|
camss->csiphy = devm_kcalloc(dev, camss->res->csiphy_num,
|
2018-08-14 11:57:35 -04:00
|
|
|
sizeof(*camss->csiphy), GFP_KERNEL);
|
2022-05-19 06:14:15 +01:00
|
|
|
if (!camss->csiphy)
|
|
|
|
return -ENOMEM;
|
2018-07-25 12:38:26 -04:00
|
|
|
|
2023-09-25 16:46:55 +01:00
|
|
|
camss->csid = devm_kcalloc(dev, camss->res->csid_num, sizeof(*camss->csid),
|
2018-08-14 11:57:35 -04:00
|
|
|
GFP_KERNEL);
|
2022-05-19 06:14:15 +01:00
|
|
|
if (!camss->csid)
|
|
|
|
return -ENOMEM;
|
2018-07-25 12:38:26 -04:00
|
|
|
|
2023-09-25 16:46:55 +01:00
|
|
|
if (camss->res->version == CAMSS_8x16 ||
|
|
|
|
camss->res->version == CAMSS_8x96) {
|
2021-03-16 18:19:14 +01:00
|
|
|
camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL);
|
2022-05-19 06:14:15 +01:00
|
|
|
if (!camss->ispif)
|
|
|
|
return -ENOMEM;
|
2021-03-16 18:19:14 +01:00
|
|
|
}
|
|
|
|
|
2023-11-23 17:03:05 +00:00
|
|
|
camss->vfe = devm_kcalloc(dev, camss->res->vfe_num,
|
2022-07-04 23:15:47 +01:00
|
|
|
sizeof(*camss->vfe), GFP_KERNEL);
|
2022-05-19 06:14:15 +01:00
|
|
|
if (!camss->vfe)
|
|
|
|
return -ENOMEM;
|
2018-07-25 12:38:26 -04:00
|
|
|
|
2021-12-22 01:37:49 +01:00
|
|
|
ret = camss_icc_get(camss);
|
|
|
|
if (ret < 0)
|
2023-08-30 16:16:07 +01:00
|
|
|
return ret;
|
2021-12-22 01:37:49 +01:00
|
|
|
|
2023-08-30 16:16:06 +01:00
|
|
|
ret = camss_configure_pd(camss);
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(dev, "Failed to configure power domains: %d\n", ret);
|
2023-08-30 16:16:07 +01:00
|
|
|
return ret;
|
2023-08-30 16:16:06 +01:00
|
|
|
}
|
|
|
|
|
2017-08-08 09:30:07 -04:00
|
|
|
ret = camss_init_subdevices(camss);
|
|
|
|
if (ret < 0)
|
2023-08-30 16:16:08 +01:00
|
|
|
goto err_genpd_cleanup;
|
2017-08-08 09:30:07 -04:00
|
|
|
|
|
|
|
ret = dma_set_mask_and_coherent(dev, 0xffffffff);
|
|
|
|
if (ret)
|
2023-08-30 16:16:08 +01:00
|
|
|
goto err_genpd_cleanup;
|
2017-08-08 09:30:07 -04:00
|
|
|
|
|
|
|
camss->media_dev.dev = camss->dev;
|
2018-09-10 08:19:14 -04:00
|
|
|
strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem",
|
2017-08-08 09:30:07 -04:00
|
|
|
sizeof(camss->media_dev.model));
|
|
|
|
camss->media_dev.ops = &camss_media_ops;
|
|
|
|
media_device_init(&camss->media_dev);
|
|
|
|
|
|
|
|
camss->v4l2_dev.mdev = &camss->media_dev;
|
|
|
|
ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
|
2023-08-30 16:16:08 +01:00
|
|
|
goto err_genpd_cleanup;
|
2017-08-08 09:30:07 -04:00
|
|
|
}
|
|
|
|
|
2023-02-23 16:24:48 +01:00
|
|
|
v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev);
|
2023-03-30 11:37:02 +02:00
|
|
|
|
2024-07-29 13:42:03 +01:00
|
|
|
pm_runtime_enable(dev);
|
|
|
|
|
2023-03-30 11:37:02 +02:00
|
|
|
num_subdevs = camss_of_parse_ports(camss);
|
|
|
|
if (num_subdevs < 0) {
|
|
|
|
ret = num_subdevs;
|
2023-08-30 16:16:07 +01:00
|
|
|
goto err_v4l2_device_unregister;
|
2023-03-30 11:37:02 +02:00
|
|
|
}
|
|
|
|
|
2017-08-08 09:30:07 -04:00
|
|
|
ret = camss_register_entities(camss);
|
|
|
|
if (ret < 0)
|
2023-08-30 16:16:07 +01:00
|
|
|
goto err_v4l2_device_unregister;
|
2017-08-08 09:30:07 -04:00
|
|
|
|
2024-05-22 18:46:58 +03:00
|
|
|
ret = camss->res->link_entities(camss);
|
|
|
|
if (ret < 0)
|
|
|
|
goto err_register_subdevs;
|
|
|
|
|
2018-09-29 15:54:18 -04:00
|
|
|
if (num_subdevs) {
|
2017-08-30 13:18:04 -04:00
|
|
|
camss->notifier.ops = &camss_subdev_notifier_ops;
|
2017-08-08 09:30:07 -04:00
|
|
|
|
2023-02-23 16:24:48 +01:00
|
|
|
ret = v4l2_async_nf_register(&camss->notifier);
|
2017-08-08 09:30:07 -04:00
|
|
|
if (ret) {
|
|
|
|
dev_err(dev,
|
|
|
|
"Failed to register async subdev nodes: %d\n",
|
|
|
|
ret);
|
|
|
|
goto err_register_subdevs;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(dev, "Failed to register subdev nodes: %d\n",
|
|
|
|
ret);
|
|
|
|
goto err_register_subdevs;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = media_device_register(&camss->media_dev);
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(dev, "Failed to register media device: %d\n",
|
|
|
|
ret);
|
|
|
|
goto err_register_subdevs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_register_subdevs:
|
|
|
|
camss_unregister_entities(camss);
|
2023-08-30 16:16:07 +01:00
|
|
|
err_v4l2_device_unregister:
|
2023-03-30 11:37:02 +02:00
|
|
|
v4l2_device_unregister(&camss->v4l2_dev);
|
2021-03-05 18:13:12 +01:00
|
|
|
v4l2_async_nf_cleanup(&camss->notifier);
|
2024-07-29 13:42:03 +01:00
|
|
|
pm_runtime_disable(dev);
|
2023-08-30 16:16:08 +01:00
|
|
|
err_genpd_cleanup:
|
|
|
|
camss_genpd_cleanup(camss);
|
2017-08-08 09:30:07 -04:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void camss_delete(struct camss *camss)
|
|
|
|
{
|
|
|
|
v4l2_device_unregister(&camss->v4l2_dev);
|
|
|
|
media_device_unregister(&camss->media_dev);
|
|
|
|
media_device_cleanup(&camss->media_dev);
|
|
|
|
|
2018-07-25 12:38:27 -04:00
|
|
|
pm_runtime_disable(camss->dev);
|
2017-08-08 09:30:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* camss_remove - Remove CAMSS platform device
|
|
|
|
* @pdev: Pointer to CAMSS platform device
|
|
|
|
*
|
|
|
|
* Always returns 0.
|
|
|
|
*/
|
2023-03-26 16:31:09 +02:00
|
|
|
static void camss_remove(struct platform_device *pdev)
|
2017-08-08 09:30:07 -04:00
|
|
|
{
|
|
|
|
struct camss *camss = platform_get_drvdata(pdev);
|
|
|
|
|
2021-03-05 18:13:12 +01:00
|
|
|
v4l2_async_nf_unregister(&camss->notifier);
|
|
|
|
v4l2_async_nf_cleanup(&camss->notifier);
|
2017-08-08 09:30:07 -04:00
|
|
|
camss_unregister_entities(camss);
|
|
|
|
|
|
|
|
if (atomic_read(&camss->ref_count) == 0)
|
|
|
|
camss_delete(camss);
|
2023-08-30 16:16:08 +01:00
|
|
|
|
|
|
|
camss_genpd_cleanup(camss);
|
2017-08-08 09:30:07 -04:00
|
|
|
}
|
|
|
|
|
2023-09-25 16:46:53 +01:00
|
|
|
static const struct camss_resources msm8916_resources = {
|
2023-09-25 16:46:55 +01:00
|
|
|
.version = CAMSS_8x16,
|
2023-09-25 16:46:53 +01:00
|
|
|
.csiphy_res = csiphy_res_8x16,
|
|
|
|
.csid_res = csid_res_8x16,
|
|
|
|
.ispif_res = &ispif_res_8x16,
|
|
|
|
.vfe_res = vfe_res_8x16,
|
2023-09-25 16:46:55 +01:00
|
|
|
.csiphy_num = ARRAY_SIZE(csiphy_res_8x16),
|
|
|
|
.csid_num = ARRAY_SIZE(csid_res_8x16),
|
|
|
|
.vfe_num = ARRAY_SIZE(vfe_res_8x16),
|
2024-05-22 18:46:58 +03:00
|
|
|
.link_entities = camss_link_entities
|
2023-09-25 16:46:53 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct camss_resources msm8996_resources = {
|
2023-09-25 16:46:55 +01:00
|
|
|
.version = CAMSS_8x96,
|
2023-09-25 16:46:53 +01:00
|
|
|
.csiphy_res = csiphy_res_8x96,
|
|
|
|
.csid_res = csid_res_8x96,
|
|
|
|
.ispif_res = &ispif_res_8x96,
|
|
|
|
.vfe_res = vfe_res_8x96,
|
2023-09-25 16:46:55 +01:00
|
|
|
.csiphy_num = ARRAY_SIZE(csiphy_res_8x96),
|
|
|
|
.csid_num = ARRAY_SIZE(csid_res_8x96),
|
|
|
|
.vfe_num = ARRAY_SIZE(vfe_res_8x96),
|
2024-05-22 18:46:58 +03:00
|
|
|
.link_entities = camss_link_entities
|
2023-09-25 16:46:53 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct camss_resources sdm660_resources = {
|
2023-09-25 16:46:55 +01:00
|
|
|
.version = CAMSS_660,
|
2023-09-25 16:46:53 +01:00
|
|
|
.csiphy_res = csiphy_res_660,
|
|
|
|
.csid_res = csid_res_660,
|
|
|
|
.ispif_res = &ispif_res_660,
|
|
|
|
.vfe_res = vfe_res_660,
|
2023-09-25 16:46:55 +01:00
|
|
|
.csiphy_num = ARRAY_SIZE(csiphy_res_660),
|
|
|
|
.csid_num = ARRAY_SIZE(csid_res_660),
|
|
|
|
.vfe_num = ARRAY_SIZE(vfe_res_660),
|
2024-05-22 18:46:58 +03:00
|
|
|
.link_entities = camss_link_entities
|
2023-09-25 16:46:53 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct camss_resources sdm845_resources = {
|
2023-09-25 16:46:55 +01:00
|
|
|
.version = CAMSS_845,
|
2023-09-25 16:46:53 +01:00
|
|
|
.csiphy_res = csiphy_res_845,
|
|
|
|
.csid_res = csid_res_845,
|
|
|
|
.vfe_res = vfe_res_845,
|
2023-09-25 16:46:55 +01:00
|
|
|
.csiphy_num = ARRAY_SIZE(csiphy_res_845),
|
|
|
|
.csid_num = ARRAY_SIZE(csid_res_845),
|
2023-11-23 17:03:05 +00:00
|
|
|
.vfe_num = ARRAY_SIZE(vfe_res_845),
|
2024-05-22 18:46:58 +03:00
|
|
|
.link_entities = camss_link_entities
|
2023-09-25 16:46:53 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct camss_resources sm8250_resources = {
|
2023-09-25 16:46:55 +01:00
|
|
|
.version = CAMSS_8250,
|
2023-11-23 17:03:07 +00:00
|
|
|
.pd_name = "top",
|
2023-09-25 16:46:53 +01:00
|
|
|
.csiphy_res = csiphy_res_8250,
|
|
|
|
.csid_res = csid_res_8250,
|
|
|
|
.vfe_res = vfe_res_8250,
|
2023-09-25 16:46:54 +01:00
|
|
|
.icc_res = icc_res_sm8250,
|
|
|
|
.icc_path_num = ARRAY_SIZE(icc_res_sm8250),
|
2023-09-25 16:46:55 +01:00
|
|
|
.csiphy_num = ARRAY_SIZE(csiphy_res_8250),
|
|
|
|
.csid_num = ARRAY_SIZE(csid_res_8250),
|
2023-11-23 17:03:05 +00:00
|
|
|
.vfe_num = ARRAY_SIZE(vfe_res_8250),
|
2024-05-22 18:46:58 +03:00
|
|
|
.link_entities = camss_link_entities
|
2023-09-25 16:46:53 +01:00
|
|
|
};
|
|
|
|
|
2024-02-22 17:17:02 +00:00
|
|
|
static const struct camss_resources sc8280xp_resources = {
|
|
|
|
.version = CAMSS_8280XP,
|
|
|
|
.pd_name = "top",
|
|
|
|
.csiphy_res = csiphy_res_sc8280xp,
|
|
|
|
.csid_res = csid_res_sc8280xp,
|
|
|
|
.ispif_res = NULL,
|
|
|
|
.vfe_res = vfe_res_sc8280xp,
|
|
|
|
.icc_res = icc_res_sc8280xp,
|
|
|
|
.icc_path_num = ARRAY_SIZE(icc_res_sc8280xp),
|
|
|
|
.csiphy_num = ARRAY_SIZE(csiphy_res_sc8280xp),
|
|
|
|
.csid_num = ARRAY_SIZE(csid_res_sc8280xp),
|
|
|
|
.vfe_num = ARRAY_SIZE(vfe_res_sc8280xp),
|
2024-05-22 18:46:58 +03:00
|
|
|
.link_entities = camss_link_entities
|
2024-02-22 17:17:02 +00:00
|
|
|
};
|
|
|
|
|
2017-08-08 09:30:07 -04:00
|
|
|
static const struct of_device_id camss_dt_match[] = {
|
2023-09-25 16:46:53 +01:00
|
|
|
{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
|
|
|
|
{ .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
|
|
|
|
{ .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
|
|
|
|
{ .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
|
|
|
|
{ .compatible = "qcom,sm8250-camss", .data = &sm8250_resources },
|
2024-02-22 17:17:02 +00:00
|
|
|
{ .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
|
2017-08-08 09:30:07 -04:00
|
|
|
{ }
|
|
|
|
};
|
|
|
|
|
|
|
|
MODULE_DEVICE_TABLE(of, camss_dt_match);
|
|
|
|
|
2018-08-17 05:53:42 -04:00
|
|
|
static int __maybe_unused camss_runtime_suspend(struct device *dev)
|
2018-07-25 12:38:27 -04:00
|
|
|
{
|
2021-12-22 01:37:49 +01:00
|
|
|
struct camss *camss = dev_get_drvdata(dev);
|
|
|
|
int i;
|
|
|
|
int ret;
|
|
|
|
|
2023-09-25 16:46:54 +01:00
|
|
|
for (i = 0; i < camss->res->icc_path_num; i++) {
|
2021-12-22 01:37:49 +01:00
|
|
|
ret = icc_set_bw(camss->icc_path[i], 0, 0);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-07-25 12:38:27 -04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-08-17 05:53:42 -04:00
|
|
|
static int __maybe_unused camss_runtime_resume(struct device *dev)
|
2018-07-25 12:38:27 -04:00
|
|
|
{
|
2021-12-22 01:37:49 +01:00
|
|
|
struct camss *camss = dev_get_drvdata(dev);
|
2023-09-25 16:46:54 +01:00
|
|
|
const struct resources_icc *icc_res = camss->res->icc_res;
|
2021-12-22 01:37:49 +01:00
|
|
|
int i;
|
|
|
|
int ret;
|
|
|
|
|
2023-09-25 16:46:54 +01:00
|
|
|
for (i = 0; i < camss->res->icc_path_num; i++) {
|
2021-12-22 01:37:49 +01:00
|
|
|
ret = icc_set_bw(camss->icc_path[i],
|
2023-09-25 16:46:54 +01:00
|
|
|
icc_res[i].icc_bw_tbl.avg,
|
|
|
|
icc_res[i].icc_bw_tbl.peak);
|
2021-12-22 01:37:49 +01:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-07-25 12:38:27 -04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct dev_pm_ops camss_pm_ops = {
|
|
|
|
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
|
|
|
|
pm_runtime_force_resume)
|
|
|
|
SET_RUNTIME_PM_OPS(camss_runtime_suspend, camss_runtime_resume, NULL)
|
|
|
|
};
|
|
|
|
|
2017-08-08 09:30:07 -04:00
|
|
|
static struct platform_driver qcom_camss_driver = {
|
|
|
|
.probe = camss_probe,
|
2023-03-26 16:31:09 +02:00
|
|
|
.remove_new = camss_remove,
|
2017-08-08 09:30:07 -04:00
|
|
|
.driver = {
|
|
|
|
.name = "qcom-camss",
|
|
|
|
.of_match_table = camss_dt_match,
|
2018-07-25 12:38:27 -04:00
|
|
|
.pm = &camss_pm_ops,
|
2017-08-08 09:30:07 -04:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
module_platform_driver(qcom_camss_driver);
|
|
|
|
|
|
|
|
MODULE_ALIAS("platform:qcom-camss");
|
|
|
|
MODULE_DESCRIPTION("Qualcomm Camera Subsystem driver");
|
|
|
|
MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>");
|
|
|
|
MODULE_LICENSE("GPL v2");
|