summaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/qcom
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-11-07 00:06:06 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2023-11-07 00:06:06 +0100
commitbe3ca57cfb777ad820c6659d52e60bbdd36bf5ff (patch)
tree2aec9aa9c20d3a82bce9d3df93a049058c3bca4e /drivers/media/platform/qcom
parentMerge tag 'rtc-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni... (diff)
parentmedia: nuvoton: VIDEO_NPCM_VCD_ECE should depend on ARCH_NPCM (diff)
downloadlinux-be3ca57cfb777ad820c6659d52e60bbdd36bf5ff.tar.xz
linux-be3ca57cfb777ad820c6659d52e60bbdd36bf5ff.zip
Merge tag 'media/v6.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - the old V4L2 core videobuf kAPI was finally removed. All media drivers should now be using VB2 kAPI - new automotive driver: mgb4 - new platform video driver: npcm-video - new sensor driver: mt9m114 - new TI driver used in conjunction with Cadence CSI2RX IP to bridge TI-specific parts - ir-rx51 was removed and the N900 DT binding was moved to the pwm-ir-tx generic driver - drop atomisp-specific ov5693, using the upstream driver instead - the camss driver has gained RDI3 support for VFE 17x - the atomisp driver now detects ISP2400 or ISP2401 at run time. No need to set it up at build time anymore - lots of driver fixes, cleanups and improvements * tag 'media/v6.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (377 commits) media: nuvoton: VIDEO_NPCM_VCD_ECE should depend on ARCH_NPCM media: venus: Fix firmware path for resources media: venus: hfi_cmds: Replace one-element array with flex-array member and use __counted_by media: venus: hfi_parser: Add check to keep the number of codecs within range media: venus: hfi: add checks to handle capabilities from firmware media: venus: hfi: fix the check to handle session buffer requirement media: venus: hfi: add checks to perform sanity on queue pointers media: platform: cadence: select MIPI_DPHY dependency media: MAINTAINERS: Fix path for J721E CSI2RX bindings media: cec: meson: always include meson sub-directory in Makefile media: videobuf2: Fix IS_ERR checking in vb2_dc_put_userptr() media: platform: mtk-mdp3: fix uninitialized variable in mdp_path_config() media: mediatek: vcodec: using encoder device to alloc/free encoder memory media: imx-jpeg: notify source chagne event when the first picture parsed media: cx231xx: Use EP5_BUF_SIZE macro media: siano: Drop unnecessary error check for debugfs_create_dir/file() media: mediatek: vcodec: Handle invalid encoder vsi media: aspeed: Drop unnecessary error check for debugfs_create_file() Documentation: media: buffer.rst: fix V4L2_BUF_FLAG_PREPARED Documentation: media: gen-errors.rst: fix confusing ENOTTY description ...
Diffstat (limited to 'drivers/media/platform/qcom')
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid-4-1.c8
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid-4-7.c8
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid-gen2.c33
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid.c39
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid.h4
-rw-r--r--drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c10
-rw-r--r--drivers/media/platform/qcom/camss/camss-csiphy.c95
-rw-r--r--drivers/media/platform/qcom/camss/camss-csiphy.h4
-rw-r--r--drivers/media/platform/qcom/camss/camss-ispif.c52
-rw-r--r--drivers/media/platform/qcom/camss/camss-ispif.h4
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-170.c73
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-4-1.c18
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-4-7.c18
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-4-8.c18
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-480.c61
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe.c228
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe.h15
-rw-r--r--drivers/media/platform/qcom/camss/camss-video.c81
-rw-r--r--drivers/media/platform/qcom/camss/camss.c482
-rw-r--r--drivers/media/platform/qcom/camss/camss.h34
-rw-r--r--drivers/media/platform/qcom/venus/core.c10
-rw-r--r--drivers/media/platform/qcom/venus/hfi_cmds.h2
-rw-r--r--drivers/media/platform/qcom/venus/hfi_msgs.c2
-rw-r--r--drivers/media/platform/qcom/venus/hfi_parser.c15
-rw-r--r--drivers/media/platform/qcom/venus/hfi_venus.c10
-rw-r--r--drivers/media/platform/qcom/venus/pm_helpers.c2
26 files changed, 678 insertions, 648 deletions
diff --git a/drivers/media/platform/qcom/camss/camss-csid-4-1.c b/drivers/media/platform/qcom/camss/camss-csid-4-1.c
index d2aec0679dfc..dd49a40e6a70 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-4-1.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-4-1.c
@@ -47,28 +47,28 @@
static const struct csid_format csid_formats[] = {
{
- MEDIA_BUS_FMT_UYVY8_2X8,
+ MEDIA_BUS_FMT_UYVY8_1X16,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
- MEDIA_BUS_FMT_VYUY8_2X8,
+ MEDIA_BUS_FMT_VYUY8_1X16,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
- MEDIA_BUS_FMT_YUYV8_2X8,
+ MEDIA_BUS_FMT_YUYV8_1X16,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
- MEDIA_BUS_FMT_YVYU8_2X8,
+ MEDIA_BUS_FMT_YVYU8_1X16,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
diff --git a/drivers/media/platform/qcom/camss/camss-csid-4-7.c b/drivers/media/platform/qcom/camss/camss-csid-4-7.c
index e7436ec6d02b..6b26e036294e 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-4-7.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-4-7.c
@@ -46,28 +46,28 @@
static const struct csid_format csid_formats[] = {
{
- MEDIA_BUS_FMT_UYVY8_2X8,
+ MEDIA_BUS_FMT_UYVY8_1X16,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
- MEDIA_BUS_FMT_VYUY8_2X8,
+ MEDIA_BUS_FMT_VYUY8_1X16,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
- MEDIA_BUS_FMT_YUYV8_2X8,
+ MEDIA_BUS_FMT_YUYV8_1X16,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
- MEDIA_BUS_FMT_YVYU8_2X8,
+ MEDIA_BUS_FMT_YVYU8_1X16,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen2.c b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
index 0f8ac29d038d..05ff5fa8095a 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-gen2.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
@@ -179,28 +179,28 @@
static const struct csid_format csid_formats[] = {
{
- MEDIA_BUS_FMT_UYVY8_2X8,
+ MEDIA_BUS_FMT_UYVY8_1X16,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
- MEDIA_BUS_FMT_VYUY8_2X8,
+ MEDIA_BUS_FMT_VYUY8_1X16,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
- MEDIA_BUS_FMT_YUYV8_2X8,
+ MEDIA_BUS_FMT_YUYV8_1X16,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
- MEDIA_BUS_FMT_YVYU8_2X8,
+ MEDIA_BUS_FMT_YVYU8_1X16,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
@@ -352,12 +352,21 @@ static void __csid_configure_stream(struct csid_device *csid, u8 enable, u8 vc)
phy_sel = csid->phy.csiphy_id;
if (enable) {
- u8 dt_id = vc;
+ /*
+ * DT_ID is a two bit bitfield that is concatenated with
+ * the four least significant bits of the five bit VC
+ * bitfield to generate an internal CID value.
+ *
+ * CSID_RDI_CFG0(vc)
+ * DT_ID : 28:27
+ * VC : 26:22
+ * DT : 21:16
+ *
+ * CID : VC 3:0 << 2 | DT_ID 1:0
+ */
+ u8 dt_id = vc & 0x03;
if (tg->enabled) {
- /* Config Test Generator */
- vc = 0xa;
-
/* configure one DT, infinite frames */
val = vc << TPG_VC_CFG0_VC_NUM;
val |= INTELEAVING_MODE_ONE_SHOT << TPG_VC_CFG0_LINE_INTERLEAVING_MODE;
@@ -370,14 +379,14 @@ static void __csid_configure_stream(struct csid_device *csid, u8 enable, u8 vc)
writel_relaxed(0x12345678, csid->base + CSID_TPG_LFSR_SEED);
- val = input_format->height & 0x1fff << TPG_DT_n_CFG_0_FRAME_HEIGHT;
- val |= input_format->width & 0x1fff << TPG_DT_n_CFG_0_FRAME_WIDTH;
+ val = (input_format->height & 0x1fff) << TPG_DT_n_CFG_0_FRAME_HEIGHT;
+ val |= (input_format->width & 0x1fff) << TPG_DT_n_CFG_0_FRAME_WIDTH;
writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_0(0));
val = format->data_type << TPG_DT_n_CFG_1_DATA_TYPE;
writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_1(0));
- val = tg->mode << TPG_DT_n_CFG_2_PAYLOAD_MODE;
+ val = (tg->mode - 1) << TPG_DT_n_CFG_2_PAYLOAD_MODE;
val |= 0xBE << TPG_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD;
val |= format->decode_format << TPG_DT_n_CFG_2_ENCODE_FORMAT;
writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_2(0));
@@ -449,6 +458,8 @@ static void __csid_configure_stream(struct csid_device *csid, u8 enable, u8 vc)
writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG0);
val = 1 << CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN;
+ if (vc > 3)
+ val |= 1 << CSI2_RX_CFG1_VC_MODE;
val |= 1 << CSI2_RX_CFG1_MISR_EN;
writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1);
diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index 6360314f04a6..95873f988f7e 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -159,15 +159,17 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
struct camss *camss = csid->camss;
struct device *dev = camss->dev;
struct vfe_device *vfe = &camss->vfe[csid->id];
- u32 version = camss->version;
int ret = 0;
if (on) {
- if (version == CAMSS_8250 || version == CAMSS_845) {
- ret = vfe_get(vfe);
- if (ret < 0)
- return ret;
- }
+ /*
+ * From SDM845 onwards, the VFE needs to be powered on before
+ * switching on the CSID. Do so unconditionally, as there is no
+ * drawback in following the same powering order on older SoCs.
+ */
+ ret = vfe_get(vfe);
+ if (ret < 0)
+ return ret;
ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
@@ -217,8 +219,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
regulator_bulk_disable(csid->num_supplies,
csid->supplies);
pm_runtime_put_sync(dev);
- if (version == CAMSS_8250 || version == CAMSS_845)
- vfe_put(vfe);
+ vfe_put(vfe);
}
return ret;
@@ -307,7 +308,7 @@ static void csid_try_format(struct csid_device *csid,
/* If not found, use UYVY as default */
if (i >= csid->nformats)
- fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
+ fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
fmt->width = clamp_t(u32, fmt->width, 1, 8191);
fmt->height = clamp_t(u32, fmt->height, 1, 8191);
@@ -336,7 +337,7 @@ static void csid_try_format(struct csid_device *csid,
/* If not found, use UYVY as default */
if (i >= csid->nformats)
- fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
+ fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
fmt->width = clamp_t(u32, fmt->width, 1, 8191);
fmt->height = clamp_t(u32, fmt->height, 1, 8191);
@@ -503,7 +504,7 @@ static int csid_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
.which = fh ? V4L2_SUBDEV_FORMAT_TRY :
V4L2_SUBDEV_FORMAT_ACTIVE,
.format = {
- .code = MEDIA_BUS_FMT_UYVY8_2X8,
+ .code = MEDIA_BUS_FMT_UYVY8_1X16,
.width = 1920,
.height = 1080
}
@@ -566,7 +567,7 @@ static const struct v4l2_ctrl_ops csid_ctrl_ops = {
* Return 0 on success or a negative error code otherwise
*/
int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
- const struct resources *res, u8 id)
+ const struct camss_subdev_resources *res, u8 id)
{
struct device *dev = camss->dev;
struct platform_device *pdev = to_platform_device(dev);
@@ -575,23 +576,13 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
csid->camss = camss;
csid->id = id;
+ csid->ops = res->ops;
- if (camss->version == CAMSS_8x16) {
- csid->ops = &csid_ops_4_1;
- } else if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660) {
- csid->ops = &csid_ops_4_7;
- } else if (camss->version == CAMSS_845 ||
- camss->version == CAMSS_8250) {
- csid->ops = &csid_ops_gen2;
- } else {
- return -EINVAL;
- }
csid->ops->subdev_init(csid);
/* Memory */
- if (camss->version == CAMSS_8250) {
+ if (camss->res->version == CAMSS_8250) {
/* for titan 480, CSID registers are inside the VFE region,
* between the VFE "top" and "bus" registers. this requires
* VFE to be initialized before CSID
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index d4b48432a097..30d94eb2eb04 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -172,7 +172,7 @@ struct csid_device {
const struct csid_hw_ops *ops;
};
-struct resources;
+struct camss_subdev_resources;
/*
* csid_find_code - Find a format code in an array using array index or format code
@@ -200,7 +200,7 @@ const struct csid_format *csid_get_fmt_entry(const struct csid_format *formats,
u32 code);
int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
- const struct resources *res, u8 id);
+ const struct camss_subdev_resources *res, u8 id);
int msm_csid_register_entity(struct csid_device *csid,
struct v4l2_device *v4l2_dev);
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
index 04baa80494c6..f50e2235c37f 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
@@ -402,7 +402,7 @@ static void csiphy_gen1_config_lanes(struct csiphy_device *csiphy,
val = CSIPHY_3PH_LNn_CFG1_SWI_REC_DLY_PRG;
writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG1(l));
- if (csiphy->camss->version == CAMSS_660)
+ if (csiphy->camss->res->version == CAMSS_660)
val = CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS_660;
else
val = CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS;
@@ -419,7 +419,7 @@ static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy,
int i, l, array_size;
u32 val;
- switch (csiphy->camss->version) {
+ switch (csiphy->camss->res->version) {
case CAMSS_845:
r = &lane_regs_sdm845[0][0];
array_size = ARRAY_SIZE(lane_regs_sdm845[0]);
@@ -468,15 +468,15 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy,
s64 link_freq, u8 lane_mask)
{
struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg;
- bool is_gen2 = (csiphy->camss->version == CAMSS_845 ||
- csiphy->camss->version == CAMSS_8250);
+ bool is_gen2 = (csiphy->camss->res->version == CAMSS_845 ||
+ csiphy->camss->res->version == CAMSS_8250);
u8 settle_cnt;
u8 val;
int i;
settle_cnt = csiphy_settle_cnt_calc(link_freq, csiphy->timer_clk_rate);
- val = is_gen2 ? BIT(7) : CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE;
+ val = CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE;
for (i = 0; i < c->num_data; i++)
val |= BIT(c->data[i].pos * 2);
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index 3f726a7237f5..edd573606a6a 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -30,10 +30,10 @@ struct csiphy_format {
};
static const struct csiphy_format csiphy_formats_8x16[] = {
- { MEDIA_BUS_FMT_UYVY8_2X8, 8 },
- { MEDIA_BUS_FMT_VYUY8_2X8, 8 },
- { MEDIA_BUS_FMT_YUYV8_2X8, 8 },
- { MEDIA_BUS_FMT_YVYU8_2X8, 8 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
+ { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
+ { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
+ { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
{ MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
{ MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
{ MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
@@ -50,10 +50,10 @@ static const struct csiphy_format csiphy_formats_8x16[] = {
};
static const struct csiphy_format csiphy_formats_8x96[] = {
- { MEDIA_BUS_FMT_UYVY8_2X8, 8 },
- { MEDIA_BUS_FMT_VYUY8_2X8, 8 },
- { MEDIA_BUS_FMT_YUYV8_2X8, 8 },
- { MEDIA_BUS_FMT_YVYU8_2X8, 8 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
+ { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
+ { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
+ { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
{ MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
{ MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
{ MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
@@ -74,10 +74,10 @@ static const struct csiphy_format csiphy_formats_8x96[] = {
};
static const struct csiphy_format csiphy_formats_sdm845[] = {
- { MEDIA_BUS_FMT_UYVY8_2X8, 8 },
- { MEDIA_BUS_FMT_VYUY8_2X8, 8 },
- { MEDIA_BUS_FMT_YUYV8_2X8, 8 },
- { MEDIA_BUS_FMT_YVYU8_2X8, 8 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
+ { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
+ { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
+ { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
{ MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
{ MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
{ MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
@@ -357,7 +357,7 @@ static void csiphy_try_format(struct csiphy_device *csiphy,
/* If not found, use UYVY as default */
if (i >= csiphy->nformats)
- fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
+ fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
fmt->width = clamp_t(u32, fmt->width, 1, 8191);
fmt->height = clamp_t(u32, fmt->height, 1, 8191);
@@ -527,7 +527,7 @@ static int csiphy_init_formats(struct v4l2_subdev *sd,
.which = fh ? V4L2_SUBDEV_FORMAT_TRY :
V4L2_SUBDEV_FORMAT_ACTIVE,
.format = {
- .code = MEDIA_BUS_FMT_UYVY8_2X8,
+ .code = MEDIA_BUS_FMT_UYVY8_1X16,
.width = 1920,
.height = 1080
}
@@ -536,6 +536,15 @@ static int csiphy_init_formats(struct v4l2_subdev *sd,
return csiphy_set_format(sd, fh ? fh->state : NULL, &format);
}
+static bool csiphy_match_clock_name(const char *clock_name, const char *format,
+ int index)
+{
+ char name[16]; /* csiphyXXX_timer\0 */
+
+ snprintf(name, sizeof(name), format, index);
+ return !strcmp(clock_name, name);
+}
+
/*
* msm_csiphy_subdev_init - Initialize CSIPHY device structure and resources
* @csiphy: CSIPHY device
@@ -546,33 +555,33 @@ static int csiphy_init_formats(struct v4l2_subdev *sd,
*/
int msm_csiphy_subdev_init(struct camss *camss,
struct csiphy_device *csiphy,
- const struct resources *res, u8 id)
+ const struct camss_subdev_resources *res, u8 id)
{
struct device *dev = camss->dev;
struct platform_device *pdev = to_platform_device(dev);
- int i, j;
+ int i, j, k;
int ret;
csiphy->camss = camss;
csiphy->id = id;
csiphy->cfg.combo_mode = 0;
+ csiphy->ops = res->ops;
- if (camss->version == CAMSS_8x16) {
- csiphy->ops = &csiphy_ops_2ph_1_0;
+ switch (camss->res->version) {
+ case CAMSS_8x16:
csiphy->formats = csiphy_formats_8x16;
csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x16);
- } else if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660) {
- csiphy->ops = &csiphy_ops_3ph_1_0;
+ break;
+ case CAMSS_8x96:
+ case CAMSS_660:
csiphy->formats = csiphy_formats_8x96;
csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x96);
- } else if (camss->version == CAMSS_845 ||
- camss->version == CAMSS_8250) {
- csiphy->ops = &csiphy_ops_3ph_1_0;
+ break;
+ case CAMSS_845:
+ case CAMSS_8250:
csiphy->formats = csiphy_formats_sdm845;
csiphy->nformats = ARRAY_SIZE(csiphy_formats_sdm845);
- } else {
- return -EINVAL;
+ break;
}
/* Memory */
@@ -581,8 +590,8 @@ int msm_csiphy_subdev_init(struct camss *camss,
if (IS_ERR(csiphy->base))
return PTR_ERR(csiphy->base);
- if (camss->version == CAMSS_8x16 ||
- camss->version == CAMSS_8x96) {
+ if (camss->res->version == CAMSS_8x16 ||
+ camss->res->version == CAMSS_8x96) {
csiphy->base_clk_mux =
devm_platform_ioremap_resource_byname(pdev, res->reg[1]);
if (IS_ERR(csiphy->base_clk_mux))
@@ -656,19 +665,23 @@ int msm_csiphy_subdev_init(struct camss *camss,
for (j = 0; j < clock->nfreqs; j++)
clock->freq[j] = res->clock_rate[i][j];
- if (!strcmp(clock->name, "csiphy0_timer") ||
- !strcmp(clock->name, "csiphy1_timer") ||
- !strcmp(clock->name, "csiphy2_timer") ||
- !strcmp(clock->name, "csiphy3_timer") ||
- !strcmp(clock->name, "csiphy4_timer") ||
- !strcmp(clock->name, "csiphy5_timer"))
- csiphy->rate_set[i] = true;
-
- if (camss->version == CAMSS_660 &&
- (!strcmp(clock->name, "csi0_phy") ||
- !strcmp(clock->name, "csi1_phy") ||
- !strcmp(clock->name, "csi2_phy")))
- csiphy->rate_set[i] = true;
+ for (k = 0; k < camss->res->csiphy_num; k++) {
+ csiphy->rate_set[i] = csiphy_match_clock_name(clock->name,
+ "csiphy%d_timer", k);
+ if (csiphy->rate_set[i])
+ break;
+
+ if (camss->res->version == CAMSS_660) {
+ csiphy->rate_set[i] = csiphy_match_clock_name(clock->name,
+ "csi%d_phy", k);
+ if (csiphy->rate_set[i])
+ break;
+ }
+
+ csiphy->rate_set[i] = csiphy_match_clock_name(clock->name, "csiphy%d", k);
+ if (csiphy->rate_set[i])
+ break;
+ }
}
return 0;
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
index 1c14947f92d3..c9b7fe82b1f0 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.h
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
@@ -83,11 +83,11 @@ struct csiphy_device {
unsigned int nformats;
};
-struct resources;
+struct camss_subdev_resources;
int msm_csiphy_subdev_init(struct camss *camss,
struct csiphy_device *csiphy,
- const struct resources *res, u8 id);
+ const struct camss_subdev_resources *res, u8 id);
int msm_csiphy_register_entity(struct csiphy_device *csiphy,
struct v4l2_device *v4l2_dev);
diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c
index b713f5b86aba..be9d2f0a10c1 100644
--- a/drivers/media/platform/qcom/camss/camss-ispif.c
+++ b/drivers/media/platform/qcom/camss/camss-ispif.c
@@ -106,10 +106,10 @@ enum ispif_intf_cmd {
};
static const u32 ispif_formats_8x16[] = {
- MEDIA_BUS_FMT_UYVY8_2X8,
- MEDIA_BUS_FMT_VYUY8_2X8,
- MEDIA_BUS_FMT_YUYV8_2X8,
- MEDIA_BUS_FMT_YVYU8_2X8,
+ MEDIA_BUS_FMT_UYVY8_1X16,
+ MEDIA_BUS_FMT_VYUY8_1X16,
+ MEDIA_BUS_FMT_YUYV8_1X16,
+ MEDIA_BUS_FMT_YVYU8_1X16,
MEDIA_BUS_FMT_SBGGR8_1X8,
MEDIA_BUS_FMT_SGBRG8_1X8,
MEDIA_BUS_FMT_SGRBG8_1X8,
@@ -126,10 +126,10 @@ static const u32 ispif_formats_8x16[] = {
};
static const u32 ispif_formats_8x96[] = {
- MEDIA_BUS_FMT_UYVY8_2X8,
- MEDIA_BUS_FMT_VYUY8_2X8,
- MEDIA_BUS_FMT_YUYV8_2X8,
- MEDIA_BUS_FMT_YVYU8_2X8,
+ MEDIA_BUS_FMT_UYVY8_1X16,
+ MEDIA_BUS_FMT_VYUY8_1X16,
+ MEDIA_BUS_FMT_YUYV8_1X16,
+ MEDIA_BUS_FMT_YVYU8_1X16,
MEDIA_BUS_FMT_SBGGR8_1X8,
MEDIA_BUS_FMT_SGBRG8_1X8,
MEDIA_BUS_FMT_SGRBG8_1X8,
@@ -270,7 +270,7 @@ static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id)
unsigned long time;
u32 val;
- if (vfe_id > (camss->vfe_num - 1)) {
+ if (vfe_id > camss->res->vfe_num - 1) {
dev_err(camss->dev,
"Error: asked reset for invalid VFE%d\n", vfe_id);
return -ENOENT;
@@ -829,8 +829,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable)
ispif_select_csid(ispif, intf, csid, vfe, 1);
ispif_select_cid(ispif, intf, cid, vfe, 1);
ispif_config_irq(ispif, intf, vfe, 1);
- if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660)
+ if (camss->res->version == CAMSS_8x96 ||
+ camss->res->version == CAMSS_660)
ispif_config_pack(ispif,
line->fmt[MSM_ISPIF_PAD_SINK].code,
intf, cid, vfe, 1);
@@ -847,8 +847,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable)
return ret;
mutex_lock(&ispif->config_lock);
- if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660)
+ if (camss->res->version == CAMSS_8x96 ||
+ camss->res->version == CAMSS_660)
ispif_config_pack(ispif,
line->fmt[MSM_ISPIF_PAD_SINK].code,
intf, cid, vfe, 0);
@@ -911,7 +911,7 @@ static void ispif_try_format(struct ispif_line *line,
/* If not found, use UYVY as default */
if (i >= line->nformats)
- fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
+ fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
fmt->width = clamp_t(u32, fmt->width, 1, 8191);
fmt->height = clamp_t(u32, fmt->height, 1, 8191);
@@ -1078,7 +1078,7 @@ static int ispif_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
.which = fh ? V4L2_SUBDEV_FORMAT_TRY :
V4L2_SUBDEV_FORMAT_ACTIVE,
.format = {
- .code = MEDIA_BUS_FMT_UYVY8_2X8,
+ .code = MEDIA_BUS_FMT_UYVY8_1X16,
.width = 1920,
.height = 1080
}
@@ -1095,7 +1095,7 @@ static int ispif_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
* Return 0 on success or a negative error code otherwise
*/
int msm_ispif_subdev_init(struct camss *camss,
- const struct resources_ispif *res)
+ const struct camss_subdev_resources *res)
{
struct device *dev = camss->dev;
struct ispif_device *ispif = camss->ispif;
@@ -1109,10 +1109,10 @@ int msm_ispif_subdev_init(struct camss *camss,
ispif->camss = camss;
/* Number of ISPIF lines - same as number of CSID hardware modules */
- if (camss->version == CAMSS_8x16)
+ if (camss->res->version == CAMSS_8x16)
ispif->line_num = 2;
- else if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660)
+ else if (camss->res->version == CAMSS_8x96 ||
+ camss->res->version == CAMSS_660)
ispif->line_num = 4;
else
return -EINVAL;
@@ -1126,12 +1126,12 @@ int msm_ispif_subdev_init(struct camss *camss,
ispif->line[i].ispif = ispif;
ispif->line[i].id = i;
- if (camss->version == CAMSS_8x16) {
+ if (camss->res->version == CAMSS_8x16) {
ispif->line[i].formats = ispif_formats_8x16;
ispif->line[i].nformats =
ARRAY_SIZE(ispif_formats_8x16);
- } else if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660) {
+ } else if (camss->res->version == CAMSS_8x96 ||
+ camss->res->version == CAMSS_660) {
ispif->line[i].formats = ispif_formats_8x96;
ispif->line[i].nformats =
ARRAY_SIZE(ispif_formats_8x96);
@@ -1152,18 +1152,18 @@ int msm_ispif_subdev_init(struct camss *camss,
/* Interrupt */
- ret = platform_get_irq_byname(pdev, res->interrupt);
+ ret = platform_get_irq_byname(pdev, res->interrupt[0]);
if (ret < 0)
return ret;
ispif->irq = ret;
snprintf(ispif->irq_name, sizeof(ispif->irq_name), "%s_%s",
dev_name(dev), MSM_ISPIF_NAME);
- if (camss->version == CAMSS_8x16)
+ if (camss->res->version == CAMSS_8x16)
ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x16,
IRQF_TRIGGER_RISING, ispif->irq_name, ispif);
- else if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660)
+ else if (camss->res->version == CAMSS_8x96 ||
+ camss->res->version == CAMSS_660)
ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x96,
IRQF_TRIGGER_RISING, ispif->irq_name, ispif);
else
diff --git a/drivers/media/platform/qcom/camss/camss-ispif.h b/drivers/media/platform/qcom/camss/camss-ispif.h
index fdf28e68cc7d..dff6d5b35c72 100644
--- a/drivers/media/platform/qcom/camss/camss-ispif.h
+++ b/drivers/media/platform/qcom/camss/camss-ispif.h
@@ -66,10 +66,10 @@ struct ispif_device {
struct camss *camss;
};
-struct resources_ispif;
+struct camss_subdev_resources;
int msm_ispif_subdev_init(struct camss *camss,
- const struct resources_ispif *res);
+ const struct camss_subdev_resources *res);
int msm_ispif_register_entities(struct ispif_device *ispif,
struct v4l2_device *v4l2_dev);
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c
index 02494c89da91..0b211fed1276 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-170.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c
@@ -7,7 +7,6 @@
* Copyright (C) 2020-2021 Linaro Ltd.
*/
-#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
@@ -210,7 +209,8 @@ static void vfe_global_reset(struct vfe_device *vfe)
GLOBAL_RESET_CMD_IDLE_CGC |
GLOBAL_RESET_CMD_RDI0 |
GLOBAL_RESET_CMD_RDI1 |
- GLOBAL_RESET_CMD_RDI2;
+ GLOBAL_RESET_CMD_RDI2 |
+ GLOBAL_RESET_CMD_RDI3;
writel_relaxed(BIT(31), vfe->base + VFE_IRQ_MASK_0);
@@ -344,7 +344,7 @@ static void vfe_violation_read(struct vfe_device *vfe)
static irqreturn_t vfe_isr(int irq, void *dev)
{
struct vfe_device *vfe = dev;
- u32 status0, status1, vfe_bus_status[3];
+ u32 status0, status1, vfe_bus_status[VFE_LINE_NUM_MAX];
int i, wm;
status0 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_0);
@@ -353,7 +353,7 @@ static irqreturn_t vfe_isr(int irq, void *dev)
writel_relaxed(status0, vfe->base + VFE_IRQ_CLEAR_0);
writel_relaxed(status1, vfe->base + VFE_IRQ_CLEAR_1);
- for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) {
+ for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
vfe_bus_status[i] = readl_relaxed(vfe->base + VFE_BUS_IRQ_STATUS(i));
writel_relaxed(vfe_bus_status[i], vfe->base + VFE_BUS_IRQ_CLEAR(i));
}
@@ -367,11 +367,11 @@ static irqreturn_t vfe_isr(int irq, void *dev)
if (status0 & STATUS_0_RESET_ACK)
vfe->isr_ops.reset_ack(vfe);
- for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
+ for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
if (status0 & STATUS_0_RDI_REG_UPDATE(i))
vfe->isr_ops.reg_update(vfe, i);
- for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
+ for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
if (status0 & STATUS_1_RDI_SOF(i))
vfe->isr_ops.sof(vfe, i);
@@ -494,37 +494,6 @@ static int vfe_enable_output(struct vfe_line *line)
return 0;
}
-static int vfe_disable_output(struct vfe_line *line)
-{
- struct vfe_device *vfe = to_vfe(line);
- struct vfe_output *output = &line->output;
- unsigned long flags;
- unsigned int i;
- bool done;
- int timeout = 0;
-
- do {
- spin_lock_irqsave(&vfe->output_lock, flags);
- done = !output->gen2.active_num;
- spin_unlock_irqrestore(&vfe->output_lock, flags);
- usleep_range(10000, 20000);
-
- if (timeout++ == 100) {
- dev_err(vfe->camss->dev, "VFE idle timeout - resetting\n");
- vfe_reset(vfe);
- output->gen2.active_num = 0;
- return 0;
- }
- } while (!done);
-
- spin_lock_irqsave(&vfe->output_lock, flags);
- for (i = 0; i < output->wm_num; i++)
- vfe_wm_stop(vfe, output->wm_idx[i]);
- spin_unlock_irqrestore(&vfe->output_lock, flags);
-
- return 0;
-}
-
/*
* vfe_enable - Enable streaming on VFE line
* @line: VFE line
@@ -571,29 +540,6 @@ error_get_output:
}
/*
- * vfe_disable - Disable streaming on VFE line
- * @line: VFE line
- *
- * Return 0 on success or a negative error code otherwise
- */
-static int vfe_disable(struct vfe_line *line)
-{
- struct vfe_device *vfe = to_vfe(line);
-
- vfe_disable_output(line);
-
- vfe_put_output(line);
-
- mutex_lock(&vfe->stream_lock);
-
- vfe->stream_count--;
-
- mutex_unlock(&vfe->stream_lock);
-
- return 0;
-}
-
-/*
* vfe_isr_sof - Process start of frame interrupt
* @vfe: VFE Device
* @line_id: VFE line
@@ -689,7 +635,7 @@ static void vfe_pm_domain_off(struct vfe_device *vfe)
{
struct camss *camss = vfe->camss;
- if (vfe->id >= camss->vfe_num)
+ if (vfe->id >= camss->res->vfe_num)
return;
device_link_del(camss->genpd_link[vfe->id]);
@@ -704,7 +650,7 @@ static int vfe_pm_domain_on(struct vfe_device *vfe)
struct camss *camss = vfe->camss;
enum vfe_line_id id = vfe->id;
- if (id >= camss->vfe_num)
+ if (id >= camss->res->vfe_num)
return 0;
camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id],
@@ -769,8 +715,6 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
{
vfe->isr_ops = vfe_isr_ops_170;
vfe->video_ops = vfe_video_ops_170;
-
- vfe->line_num = VFE_LINE_NUM_GEN2;
}
const struct vfe_hw_ops vfe_ops_170 = {
@@ -787,4 +731,5 @@ const struct vfe_hw_ops vfe_ops_170 = {
.vfe_enable = vfe_enable,
.vfe_halt = vfe_halt,
.violation_read = vfe_violation_read,
+ .vfe_wm_stop = vfe_wm_stop,
};
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
index 42047b11ba52..2911e4126e7a 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
@@ -614,20 +614,20 @@ static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line)
writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1);
switch (line->fmt[MSM_VFE_PAD_SINK].code) {
- case MEDIA_BUS_FMT_YUYV8_2X8:
+ case MEDIA_BUS_FMT_YUYV8_1X16:
even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV;
odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV;
break;
- case MEDIA_BUS_FMT_YVYU8_2X8:
+ case MEDIA_BUS_FMT_YVYU8_1X16:
even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU;
odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU;
break;
- case MEDIA_BUS_FMT_UYVY8_2X8:
+ case MEDIA_BUS_FMT_UYVY8_1X16:
default:
even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY;
odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY;
break;
- case MEDIA_BUS_FMT_VYUY8_2X8:
+ case MEDIA_BUS_FMT_VYUY8_1X16:
even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY;
odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY;
break;
@@ -775,17 +775,17 @@ static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line)
u32 val;
switch (line->fmt[MSM_VFE_PAD_SINK].code) {
- case MEDIA_BUS_FMT_YUYV8_2X8:
+ case MEDIA_BUS_FMT_YUYV8_1X16:
val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR;
break;
- case MEDIA_BUS_FMT_YVYU8_2X8:
+ case MEDIA_BUS_FMT_YVYU8_1X16:
val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB;
break;
- case MEDIA_BUS_FMT_UYVY8_2X8:
+ case MEDIA_BUS_FMT_UYVY8_1X16:
default:
val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY;
break;
- case MEDIA_BUS_FMT_VYUY8_2X8:
+ case MEDIA_BUS_FMT_VYUY8_1X16:
val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY;
break;
}
@@ -992,8 +992,6 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
vfe->isr_ops = vfe_isr_ops_gen1;
vfe->ops_gen1 = &vfe_ops_gen1_4_1;
vfe->video_ops = vfe_video_ops_gen1;
-
- vfe->line_num = VFE_LINE_NUM_GEN1;
}
const struct vfe_hw_ops vfe_ops_4_1 = {
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
index ab2d57bdf5e7..b65ed0fef595 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
@@ -768,20 +768,20 @@ static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line)
writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1);
switch (line->fmt[MSM_VFE_PAD_SINK].code) {
- case MEDIA_BUS_FMT_YUYV8_2X8:
+ case MEDIA_BUS_FMT_YUYV8_1X16:
even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV;
odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV;
break;
- case MEDIA_BUS_FMT_YVYU8_2X8:
+ case MEDIA_BUS_FMT_YVYU8_1X16:
even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU;
odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU;
break;
- case MEDIA_BUS_FMT_UYVY8_2X8:
+ case MEDIA_BUS_FMT_UYVY8_1X16:
default:
even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY;
odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY;
break;
- case MEDIA_BUS_FMT_VYUY8_2X8:
+ case MEDIA_BUS_FMT_VYUY8_1X16:
even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY;
odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY;
break;
@@ -941,17 +941,17 @@ static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line)
u32 val;
switch (line->fmt[MSM_VFE_PAD_SINK].code) {
- case MEDIA_BUS_FMT_YUYV8_2X8:
+ case MEDIA_BUS_FMT_YUYV8_1X16:
val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR;
break;
- case MEDIA_BUS_FMT_YVYU8_2X8:
+ case MEDIA_BUS_FMT_YVYU8_1X16:
val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB;
break;
- case MEDIA_BUS_FMT_UYVY8_2X8:
+ case MEDIA_BUS_FMT_UYVY8_1X16:
default:
val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY;
break;
- case MEDIA_BUS_FMT_VYUY8_2X8:
+ case MEDIA_BUS_FMT_VYUY8_1X16:
val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY;
break;
}
@@ -1188,8 +1188,6 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
vfe->isr_ops = vfe_isr_ops_gen1;
vfe->ops_gen1 = &vfe_ops_gen1_4_7;
vfe->video_ops = vfe_video_ops_gen1;
-
- vfe->line_num = VFE_LINE_NUM_GEN1;
}
const struct vfe_hw_ops vfe_ops_4_7 = {
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
index 7e6b62c930ac..7b3805177f03 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
@@ -739,20 +739,20 @@ static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line)
writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1);
switch (line->fmt[MSM_VFE_PAD_SINK].code) {
- case MEDIA_BUS_FMT_YUYV8_2X8:
+ case MEDIA_BUS_FMT_YUYV8_1X16:
even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV;
odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV;
break;
- case MEDIA_BUS_FMT_YVYU8_2X8:
+ case MEDIA_BUS_FMT_YVYU8_1X16:
even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU;
odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU;
break;
- case MEDIA_BUS_FMT_UYVY8_2X8:
+ case MEDIA_BUS_FMT_UYVY8_1X16:
default:
even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY;
odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY;
break;
- case MEDIA_BUS_FMT_VYUY8_2X8:
+ case MEDIA_BUS_FMT_VYUY8_1X16:
even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY;
odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY;
break;
@@ -873,17 +873,17 @@ static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line)
u32 val;
switch (line->fmt[MSM_VFE_PAD_SINK].code) {
- case MEDIA_BUS_FMT_YUYV8_2X8:
+ case MEDIA_BUS_FMT_YUYV8_1X16:
val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR;
break;
- case MEDIA_BUS_FMT_YVYU8_2X8:
+ case MEDIA_BUS_FMT_YVYU8_1X16:
val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB;
break;
- case MEDIA_BUS_FMT_UYVY8_2X8:
+ case MEDIA_BUS_FMT_UYVY8_1X16:
default:
val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY;
break;
- case MEDIA_BUS_FMT_VYUY8_2X8:
+ case MEDIA_BUS_FMT_VYUY8_1X16:
val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY;
break;
}
@@ -1173,8 +1173,6 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
vfe->isr_ops = vfe_isr_ops_gen1;
vfe->ops_gen1 = &vfe_ops_gen1_4_8;
vfe->video_ops = vfe_video_ops_gen1;
-
- vfe->line_num = VFE_LINE_NUM_GEN1;
}
const struct vfe_hw_ops vfe_ops_4_8 = {
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-480.c b/drivers/media/platform/qcom/camss/camss-vfe-480.c
index f70aad2e8c23..f2368b77fc6d 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-480.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-480.c
@@ -8,7 +8,6 @@
* Copyright (C) 2021 Jonathan Marek
*/
-#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
@@ -328,37 +327,6 @@ static int vfe_enable_output(struct vfe_line *line)
return 0;
}
-static int vfe_disable_output(struct vfe_line *line)
-{
- struct vfe_device *vfe = to_vfe(line);
- struct vfe_output *output = &line->output;
- unsigned long flags;
- unsigned int i;
- bool done;
- int timeout = 0;
-
- do {
- spin_lock_irqsave(&vfe->output_lock, flags);
- done = !output->gen2.active_num;
- spin_unlock_irqrestore(&vfe->output_lock, flags);
- usleep_range(10000, 20000);
-
- if (timeout++ == 100) {
- dev_err(vfe->camss->dev, "VFE idle timeout - resetting\n");
- vfe_reset(vfe);
- output->gen2.active_num = 0;
- return 0;
- }
- } while (!done);
-
- spin_lock_irqsave(&vfe->output_lock, flags);
- for (i = 0; i < output->wm_num; i++)
- vfe_wm_stop(vfe, output->wm_idx[i]);
- spin_unlock_irqrestore(&vfe->output_lock, flags);
-
- return 0;
-}
-
/*
* vfe_enable - Enable streaming on VFE line
* @line: VFE line
@@ -407,29 +375,6 @@ error_get_output:
}
/*
- * vfe_disable - Disable streaming on VFE line
- * @line: VFE line
- *
- * Return 0 on success or a negative error code otherwise
- */
-static int vfe_disable(struct vfe_line *line)
-{
- struct vfe_device *vfe = to_vfe(line);
-
- vfe_disable_output(line);
-
- vfe_put_output(line);
-
- mutex_lock(&vfe->stream_lock);
-
- vfe->stream_count--;
-
- mutex_unlock(&vfe->stream_lock);
-
- return 0;
-}
-
-/*
* vfe_isr_reg_update - Process reg update interrupt
* @vfe: VFE Device
* @line_id: VFE line
@@ -515,7 +460,7 @@ static void vfe_pm_domain_off(struct vfe_device *vfe)
{
struct camss *camss = vfe->camss;
- if (vfe->id >= camss->vfe_num)
+ if (vfe->id >= camss->res->vfe_num)
return;
device_link_del(camss->genpd_link[vfe->id]);
@@ -530,7 +475,7 @@ static int vfe_pm_domain_on(struct vfe_device *vfe)
struct camss *camss = vfe->camss;
enum vfe_line_id id = vfe->id;
- if (id >= camss->vfe_num)
+ if (id >= camss->res->vfe_num)
return 0;
camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id],
@@ -585,7 +530,6 @@ static const struct camss_video_ops vfe_video_ops_480 = {
static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
{
vfe->video_ops = vfe_video_ops_480;
- vfe->line_num = MAX_VFE_OUTPUT_LINES;
}
const struct vfe_hw_ops vfe_ops_480 = {
@@ -598,4 +542,5 @@ const struct vfe_hw_ops vfe_ops_480 = {
.vfe_disable = vfe_disable,
.vfe_enable = vfe_enable,
.vfe_halt = vfe_halt,
+ .vfe_wm_stop = vfe_wm_stop,
};
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 06c95568e5af..4839e2cedfe5 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -37,10 +37,10 @@ struct vfe_format {
};
static const struct vfe_format formats_rdi_8x16[] = {
- { MEDIA_BUS_FMT_UYVY8_2X8, 8 },
- { MEDIA_BUS_FMT_VYUY8_2X8, 8 },
- { MEDIA_BUS_FMT_YUYV8_2X8, 8 },
- { MEDIA_BUS_FMT_YVYU8_2X8, 8 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
+ { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
+ { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
+ { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
{ MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
{ MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
{ MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
@@ -57,17 +57,17 @@ static const struct vfe_format formats_rdi_8x16[] = {
};
static const struct vfe_format formats_pix_8x16[] = {
- { MEDIA_BUS_FMT_UYVY8_2X8, 8 },
- { MEDIA_BUS_FMT_VYUY8_2X8, 8 },
- { MEDIA_BUS_FMT_YUYV8_2X8, 8 },
- { MEDIA_BUS_FMT_YVYU8_2X8, 8 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
+ { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
+ { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
+ { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
};
static const struct vfe_format formats_rdi_8x96[] = {
- { MEDIA_BUS_FMT_UYVY8_2X8, 8 },
- { MEDIA_BUS_FMT_VYUY8_2X8, 8 },
- { MEDIA_BUS_FMT_YUYV8_2X8, 8 },
- { MEDIA_BUS_FMT_YVYU8_2X8, 8 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
+ { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
+ { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
+ { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
{ MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
{ MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
{ MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
@@ -90,17 +90,17 @@ static const struct vfe_format formats_rdi_8x96[] = {
};
static const struct vfe_format formats_pix_8x96[] = {
- { MEDIA_BUS_FMT_UYVY8_2X8, 8 },
- { MEDIA_BUS_FMT_VYUY8_2X8, 8 },
- { MEDIA_BUS_FMT_YUYV8_2X8, 8 },
- { MEDIA_BUS_FMT_YVYU8_2X8, 8 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
+ { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
+ { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
+ { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
};
static const struct vfe_format formats_rdi_845[] = {
- { MEDIA_BUS_FMT_UYVY8_2X8, 8 },
- { MEDIA_BUS_FMT_VYUY8_2X8, 8 },
- { MEDIA_BUS_FMT_YUYV8_2X8, 8 },
- { MEDIA_BUS_FMT_YVYU8_2X8, 8 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, 8 },
+ { MEDIA_BUS_FMT_VYUY8_1X16, 8 },
+ { MEDIA_BUS_FMT_YUYV8_1X16, 8 },
+ { MEDIA_BUS_FMT_YVYU8_1X16, 8 },
{ MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
{ MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
{ MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
@@ -170,42 +170,43 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
{
struct vfe_device *vfe = to_vfe(line);
- if (vfe->camss->version == CAMSS_8x16)
+ switch (vfe->camss->res->version) {
+ case CAMSS_8x16:
switch (sink_code) {
- case MEDIA_BUS_FMT_YUYV8_2X8:
+ case MEDIA_BUS_FMT_YUYV8_1X16:
{
u32 src_code[] = {
- MEDIA_BUS_FMT_YUYV8_2X8,
+ MEDIA_BUS_FMT_YUYV8_1X16,
MEDIA_BUS_FMT_YUYV8_1_5X8,
};
return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
- case MEDIA_BUS_FMT_YVYU8_2X8:
+ case MEDIA_BUS_FMT_YVYU8_1X16:
{
u32 src_code[] = {
- MEDIA_BUS_FMT_YVYU8_2X8,
+ MEDIA_BUS_FMT_YVYU8_1X16,
MEDIA_BUS_FMT_YVYU8_1_5X8,
};
return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
- case MEDIA_BUS_FMT_UYVY8_2X8:
+ case MEDIA_BUS_FMT_UYVY8_1X16:
{
u32 src_code[] = {
- MEDIA_BUS_FMT_UYVY8_2X8,
+ MEDIA_BUS_FMT_UYVY8_1X16,
MEDIA_BUS_FMT_UYVY8_1_5X8,
};
return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
- case MEDIA_BUS_FMT_VYUY8_2X8:
+ case MEDIA_BUS_FMT_VYUY8_1X16:
{
u32 src_code[] = {
- MEDIA_BUS_FMT_VYUY8_2X8,
+ MEDIA_BUS_FMT_VYUY8_1X16,
MEDIA_BUS_FMT_VYUY8_1_5X8,
};
@@ -218,57 +219,58 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
return sink_code;
}
- else if (vfe->camss->version == CAMSS_8x96 ||
- vfe->camss->version == CAMSS_660 ||
- vfe->camss->version == CAMSS_845 ||
- vfe->camss->version == CAMSS_8250)
+ break;
+ case CAMSS_8x96:
+ case CAMSS_660:
+ case CAMSS_845:
+ case CAMSS_8250:
switch (sink_code) {
- case MEDIA_BUS_FMT_YUYV8_2X8:
+ case MEDIA_BUS_FMT_YUYV8_1X16:
{
u32 src_code[] = {
- MEDIA_BUS_FMT_YUYV8_2X8,
- MEDIA_BUS_FMT_YVYU8_2X8,
- MEDIA_BUS_FMT_UYVY8_2X8,
- MEDIA_BUS_FMT_VYUY8_2X8,
+ MEDIA_BUS_FMT_YUYV8_1X16,
+ MEDIA_BUS_FMT_YVYU8_1X16,
+ MEDIA_BUS_FMT_UYVY8_1X16,
+ MEDIA_BUS_FMT_VYUY8_1X16,
MEDIA_BUS_FMT_YUYV8_1_5X8,
};
return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
- case MEDIA_BUS_FMT_YVYU8_2X8:
+ case MEDIA_BUS_FMT_YVYU8_1X16:
{
u32 src_code[] = {
- MEDIA_BUS_FMT_YVYU8_2X8,
- MEDIA_BUS_FMT_YUYV8_2X8,
- MEDIA_BUS_FMT_UYVY8_2X8,
- MEDIA_BUS_FMT_VYUY8_2X8,
+ MEDIA_BUS_FMT_YVYU8_1X16,
+ MEDIA_BUS_FMT_YUYV8_1X16,
+ MEDIA_BUS_FMT_UYVY8_1X16,
+ MEDIA_BUS_FMT_VYUY8_1X16,
MEDIA_BUS_FMT_YVYU8_1_5X8,
};
return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
- case MEDIA_BUS_FMT_UYVY8_2X8:
+ case MEDIA_BUS_FMT_UYVY8_1X16:
{
u32 src_code[] = {
- MEDIA_BUS_FMT_UYVY8_2X8,
- MEDIA_BUS_FMT_YUYV8_2X8,
- MEDIA_BUS_FMT_YVYU8_2X8,
- MEDIA_BUS_FMT_VYUY8_2X8,
+ MEDIA_BUS_FMT_UYVY8_1X16,
+ MEDIA_BUS_FMT_YUYV8_1X16,
+ MEDIA_BUS_FMT_YVYU8_1X16,
+ MEDIA_BUS_FMT_VYUY8_1X16,
MEDIA_BUS_FMT_UYVY8_1_5X8,
};
return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
- case MEDIA_BUS_FMT_VYUY8_2X8:
+ case MEDIA_BUS_FMT_VYUY8_1X16:
{
u32 src_code[] = {
- MEDIA_BUS_FMT_VYUY8_2X8,
- MEDIA_BUS_FMT_YUYV8_2X8,
- MEDIA_BUS_FMT_YVYU8_2X8,
- MEDIA_BUS_FMT_UYVY8_2X8,
+ MEDIA_BUS_FMT_VYUY8_1X16,
+ MEDIA_BUS_FMT_YUYV8_1X16,
+ MEDIA_BUS_FMT_YVYU8_1X16,
+ MEDIA_BUS_FMT_UYVY8_1X16,
MEDIA_BUS_FMT_VYUY8_1_5X8,
};
@@ -281,8 +283,9 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
return sink_code;
}
- else
- return 0;
+ break;
+ }
+ return 0;
}
int vfe_reset(struct vfe_device *vfe)
@@ -407,6 +410,49 @@ int vfe_put_output(struct vfe_line *line)
return 0;
}
+static int vfe_disable_output(struct vfe_line *line)
+{
+ struct vfe_device *vfe = to_vfe(line);
+ struct vfe_output *output = &line->output;
+ unsigned long flags;
+ unsigned int i;
+
+ spin_lock_irqsave(&vfe->output_lock, flags);
+ for (i = 0; i < output->wm_num; i++)
+ vfe->ops->vfe_wm_stop(vfe, output->wm_idx[i]);
+ output->gen2.active_num = 0;
+ spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+ return vfe_reset(vfe);
+}
+
+/*
+ * vfe_disable - Disable streaming on VFE line
+ * @line: VFE line
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+int vfe_disable(struct vfe_line *line)
+{
+ struct vfe_device *vfe = to_vfe(line);
+ int ret;
+
+ ret = vfe_disable_output(line);
+ if (ret)
+ goto error;
+
+ vfe_put_output(line);
+
+ mutex_lock(&vfe->stream_lock);
+
+ vfe->stream_count--;
+
+ mutex_unlock(&vfe->stream_lock);
+
+error:
+ return ret;
+}
+
/**
* vfe_isr_comp_done() - Process composite image done interrupt
* @vfe: VFE Device
@@ -428,6 +474,20 @@ void vfe_isr_reset_ack(struct vfe_device *vfe)
complete(&vfe->reset_complete);
}
+static int vfe_match_clock_names(struct vfe_device *vfe,
+ struct camss_clock *clock)
+{
+ char vfe_name[7]; /* vfeXXX\0 */
+ char vfe_lite_name[12]; /* vfe_liteXXX\0 */
+
+ snprintf(vfe_name, sizeof(vfe_name), "vfe%d", vfe->id);
+ snprintf(vfe_lite_name, sizeof(vfe_lite_name), "vfe_lite%d", vfe->id);
+
+ return (!strcmp(clock->name, vfe_name) ||
+ !strcmp(clock->name, vfe_lite_name) ||
+ !strcmp(clock->name, "vfe_lite"));
+}
+
/*
* vfe_set_clock_rates - Calculate and set clock rates on VFE module
* @vfe: VFE device
@@ -451,9 +511,7 @@ static int vfe_set_clock_rates(struct vfe_device *vfe)
for (i = 0; i < vfe->nclocks; i++) {
struct camss_clock *clock = &vfe->clock[i];
- if (!strcmp(clock->name, "vfe0") ||
- !strcmp(clock->name, "vfe1") ||
- !strcmp(clock->name, "vfe_lite")) {
+ if (vfe_match_clock_names(vfe, clock)) {
u64 min_rate = 0;
long rate;
@@ -534,8 +592,7 @@ static int vfe_check_clock_rates(struct vfe_device *vfe)
for (i = 0; i < vfe->nclocks; i++) {
struct camss_clock *clock = &vfe->clock[i];
- if (!strcmp(clock->name, "vfe0") ||
- !strcmp(clock->name, "vfe1")) {
+ if (vfe_match_clock_names(vfe, clock)) {
u64 min_rate = 0;
unsigned long rate;
@@ -611,7 +668,7 @@ int vfe_get(struct vfe_device *vfe)
} else {
ret = vfe_check_clock_rates(vfe);
if (ret < 0)
- goto error_pm_runtime_get;
+ goto error_pm_domain;
}
vfe->power_count++;
@@ -844,7 +901,7 @@ static void vfe_try_format(struct vfe_line *line,
/* If not found, use UYVY as default */
if (i >= line->nformats)
- fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
+ fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
fmt->width = clamp_t(u32, fmt->width, 1, 8191);
fmt->height = clamp_t(u32, fmt->height, 1, 8191);
@@ -1261,7 +1318,7 @@ static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
.which = fh ? V4L2_SUBDEV_FORMAT_TRY :
V4L2_SUBDEV_FORMAT_ACTIVE,
.format = {
- .code = MEDIA_BUS_FMT_UYVY8_2X8,
+ .code = MEDIA_BUS_FMT_UYVY8_1X16,
.width = 1920,
.height = 1080
}
@@ -1278,32 +1335,19 @@ static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
* Return 0 on success or a negative error code otherwise
*/
int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
- const struct resources *res, u8 id)
+ const struct camss_subdev_resources *res, u8 id)
{
struct device *dev = camss->dev;
struct platform_device *pdev = to_platform_device(dev);
int i, j;
int ret;
- switch (camss->version) {
- case CAMSS_8x16:
- vfe->ops = &vfe_ops_4_1;
- break;
- case CAMSS_8x96:
- vfe->ops = &vfe_ops_4_7;
- break;
- case CAMSS_660:
- vfe->ops = &vfe_ops_4_8;
- break;
- case CAMSS_845:
- vfe->ops = &vfe_ops_170;
- break;
- case CAMSS_8250:
- vfe->ops = &vfe_ops_480;
- break;
- default:
+ vfe->ops = res->ops;
+
+ if (!res->line_num)
return -EINVAL;
- }
+
+ vfe->line_num = res->line_num;
vfe->ops->subdev_init(dev, vfe);
/* Memory */
@@ -1391,7 +1435,8 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
init_completion(&l->output.sof);
init_completion(&l->output.reg_update);
- if (camss->version == CAMSS_8x16) {
+ switch (camss->res->version) {
+ case CAMSS_8x16:
if (i == VFE_LINE_PIX) {
l->formats = formats_pix_8x16;
l->nformats = ARRAY_SIZE(formats_pix_8x16);
@@ -1399,8 +1444,9 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
l->formats = formats_rdi_8x16;
l->nformats = ARRAY_SIZE(formats_rdi_8x16);
}
- } else if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660) {
+ break;
+ case CAMSS_8x96:
+ case CAMSS_660:
if (i == VFE_LINE_PIX) {
l->formats = formats_pix_8x96;
l->nformats = ARRAY_SIZE(formats_pix_8x96);
@@ -1408,12 +1454,12 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
l->formats = formats_rdi_8x96;
l->nformats = ARRAY_SIZE(formats_rdi_8x96);
}
- } else if (camss->version == CAMSS_845 ||
- camss->version == CAMSS_8250) {
+ break;
+ case CAMSS_845:
+ case CAMSS_8250:
l->formats = formats_rdi_845;
l->nformats = ARRAY_SIZE(formats_rdi_845);
- } else {
- return -EINVAL;
+ break;
}
}
@@ -1541,8 +1587,8 @@ int msm_vfe_register_entities(struct vfe_device *vfe,
}
video_out->ops = &vfe->video_ops;
- if (vfe->camss->version == CAMSS_845 ||
- vfe->camss->version == CAMSS_8250)
+ if (vfe->camss->res->version == CAMSS_845 ||
+ vfe->camss->res->version == CAMSS_8250)
video_out->bpl_alignment = 16;
else
video_out->bpl_alignment = 8;
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index cbc314c4e244..09baded0dcdd 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -52,9 +52,7 @@ enum vfe_line_id {
VFE_LINE_RDI0 = 0,
VFE_LINE_RDI1 = 1,
VFE_LINE_RDI2 = 2,
- VFE_LINE_NUM_GEN2 = 3,
VFE_LINE_PIX = 3,
- VFE_LINE_NUM_GEN1 = 4,
VFE_LINE_NUM_MAX = 4
};
@@ -116,6 +114,7 @@ struct vfe_hw_ops {
int (*vfe_enable)(struct vfe_line *line);
int (*vfe_halt)(struct vfe_device *vfe);
void (*violation_read)(struct vfe_device *vfe);
+ void (*vfe_wm_stop)(struct vfe_device *vfe, u8 wm);
};
struct vfe_isr_ops {
@@ -153,10 +152,10 @@ struct vfe_device {
struct camss_video_ops video_ops;
};
-struct resources;
+struct camss_subdev_resources;
int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
- const struct resources *res, u8 id);
+ const struct camss_subdev_resources *res, u8 id);
int msm_vfe_register_entities(struct vfe_device *vfe,
struct v4l2_device *v4l2_dev);
@@ -194,6 +193,14 @@ int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id);
*/
int vfe_reset(struct vfe_device *vfe);
+/*
+ * vfe_disable - Disable streaming on VFE line
+ * @line: VFE line
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+int vfe_disable(struct vfe_line *line);
+
extern const struct vfe_hw_ops vfe_ops_4_1;
extern const struct vfe_hw_ops vfe_ops_4_7;
extern const struct vfe_hw_ops vfe_ops_4_8;
diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
index 8640db306026..a89da5ef4710 100644
--- a/drivers/media/platform/qcom/camss/camss-video.c
+++ b/drivers/media/platform/qcom/camss/camss-video.c
@@ -48,13 +48,13 @@ struct camss_format_info {
};
static const struct camss_format_info formats_rdi_8x16[] = {
- { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 1,
+ { MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
- { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 1,
+ { MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_VYUY, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
- { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
+ { MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
- { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 1,
+ { MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_YVYU, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
{ MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 8 } },
@@ -85,13 +85,13 @@ static const struct camss_format_info formats_rdi_8x16[] = {
};
static const struct camss_format_info formats_rdi_8x96[] = {
- { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 1,
+ { MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
- { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 1,
+ { MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_VYUY, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
- { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
+ { MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
- { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 1,
+ { MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_YVYU, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
{ MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 8 } },
@@ -134,13 +134,13 @@ static const struct camss_format_info formats_rdi_8x96[] = {
};
static const struct camss_format_info formats_rdi_845[] = {
- { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 1,
+ { MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
- { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 1,
+ { MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_VYUY, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
- { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
+ { MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
- { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 1,
+ { MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_YVYU, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
{ MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 8 } },
@@ -201,21 +201,21 @@ static const struct camss_format_info formats_pix_8x16[] = {
{ { 1, 1 } }, { { 2, 3 } }, { 8 } },
{ MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV21, 1,
{ { 1, 1 } }, { { 2, 3 } }, { 8 } },
- { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_NV16, 1,
+ { MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_NV16, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_NV16, 1,
+ { MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_NV16, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_NV16, 1,
+ { MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_NV16, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_NV16, 1,
+ { MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_NV16, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_NV61, 1,
+ { MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_NV61, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_NV61, 1,
+ { MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_NV61, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_NV61, 1,
+ { MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_NV61, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_NV61, 1,
+ { MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_NV61, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
};
@@ -236,29 +236,29 @@ static const struct camss_format_info formats_pix_8x96[] = {
{ { 1, 1 } }, { { 2, 3 } }, { 8 } },
{ MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV21, 1,
{ { 1, 1 } }, { { 2, 3 } }, { 8 } },
- { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_NV16, 1,
+ { MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_NV16, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_NV16, 1,
+ { MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_NV16, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_NV16, 1,
+ { MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_NV16, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_NV16, 1,
+ { MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_NV16, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_NV61, 1,
+ { MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_NV61, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_NV61, 1,
+ { MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_NV61, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_NV61, 1,
+ { MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_NV61, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_NV61, 1,
+ { MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_NV61, 1,
{ { 1, 1 } }, { { 1, 2 } }, { 8 } },
- { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 1,
+ { MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
- { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 1,
+ { MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_VYUY, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
- { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
+ { MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
- { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 1,
+ { MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_YVYU, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
};
@@ -1006,7 +1006,8 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
mutex_init(&video->lock);
- if (video->camss->version == CAMSS_8x16) {
+ switch (video->camss->res->version) {
+ case CAMSS_8x16:
if (is_pix) {
video->formats = formats_pix_8x16;
video->nformats = ARRAY_SIZE(formats_pix_8x16);
@@ -1014,8 +1015,9 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
video->formats = formats_rdi_8x16;
video->nformats = ARRAY_SIZE(formats_rdi_8x16);
}
- } else if (video->camss->version == CAMSS_8x96 ||
- video->camss->version == CAMSS_660) {
+ break;
+ case CAMSS_8x96:
+ case CAMSS_660:
if (is_pix) {
video->formats = formats_pix_8x96;
video->nformats = ARRAY_SIZE(formats_pix_8x96);
@@ -1023,13 +1025,12 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
video->formats = formats_rdi_8x96;
video->nformats = ARRAY_SIZE(formats_rdi_8x96);
}
- } else if (video->camss->version == CAMSS_845 ||
- video->camss->version == CAMSS_8250) {
+ break;
+ case CAMSS_845:
+ case CAMSS_8250:
video->formats = formats_rdi_845;
video->nformats = ARRAY_SIZE(formats_rdi_845);
- } else {
- ret = -EINVAL;
- goto error_video_register;
+ break;
}
ret = msm_video_init_format(video);
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index f11dc59135a5..8e78dd8d5961 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/pm_runtime.h>
#include <linux/pm_domain.h>
@@ -31,7 +32,7 @@
#define CAMSS_CLOCK_MARGIN_NUMERATOR 105
#define CAMSS_CLOCK_MARGIN_DENOMINATOR 100
-static const struct resources csiphy_res_8x16[] = {
+static const struct camss_subdev_resources csiphy_res_8x16[] = {
/* CSIPHY0 */
{
.regulators = {},
@@ -41,7 +42,8 @@ static const struct resources csiphy_res_8x16[] = {
{ 0 },
{ 100000000, 200000000 } },
.reg = { "csiphy0", "csiphy0_clk_mux" },
- .interrupt = { "csiphy0" }
+ .interrupt = { "csiphy0" },
+ .ops = &csiphy_ops_2ph_1_0
},
/* CSIPHY1 */
@@ -53,11 +55,12 @@ static const struct resources csiphy_res_8x16[] = {
{ 0 },
{ 100000000, 200000000 } },
.reg = { "csiphy1", "csiphy1_clk_mux" },
- .interrupt = { "csiphy1" }
+ .interrupt = { "csiphy1" },
+ .ops = &csiphy_ops_2ph_1_0
}
};
-static const struct resources csid_res_8x16[] = {
+static const struct camss_subdev_resources csid_res_8x16[] = {
/* CSID0 */
{
.regulators = { "vdda" },
@@ -72,7 +75,8 @@ static const struct resources csid_res_8x16[] = {
{ 0 },
{ 0 } },
.reg = { "csid0" },
- .interrupt = { "csid0" }
+ .interrupt = { "csid0" },
+ .ops = &csid_ops_4_1,
},
/* CSID1 */
@@ -89,22 +93,23 @@ static const struct resources csid_res_8x16[] = {
{ 0 },
{ 0 } },
.reg = { "csid1" },
- .interrupt = { "csid1" }
+ .interrupt = { "csid1" },
+ .ops = &csid_ops_4_1,
},
};
-static const struct resources_ispif ispif_res_8x16 = {
+static const struct camss_subdev_resources ispif_res_8x16 = {
/* ISPIF */
.clock = { "top_ahb", "ahb", "ispif_ahb",
"csi0", "csi0_pix", "csi0_rdi",
"csi1", "csi1_pix", "csi1_rdi" },
.clock_for_reset = { "vfe0", "csi_vfe0" },
.reg = { "ispif", "csi_clk_mux" },
- .interrupt = "ispif"
+ .interrupt = { "ispif" }
};
-static const struct resources vfe_res_8x16[] = {
+static const struct camss_subdev_resources vfe_res_8x16[] = {
/* VFE0 */
{
.regulators = {},
@@ -122,11 +127,13 @@ static const struct resources vfe_res_8x16[] = {
{ 0 },
{ 0 } },
.reg = { "vfe0" },
- .interrupt = { "vfe0" }
+ .interrupt = { "vfe0" },
+ .line_num = 3,
+ .ops = &vfe_ops_4_1
}
};
-static const struct resources csiphy_res_8x96[] = {
+static const struct camss_subdev_resources csiphy_res_8x96[] = {
/* CSIPHY0 */
{
.regulators = {},
@@ -136,7 +143,8 @@ static const struct resources csiphy_res_8x96[] = {
{ 0 },
{ 100000000, 200000000, 266666667 } },
.reg = { "csiphy0", "csiphy0_clk_mux" },
- .interrupt = { "csiphy0" }
+ .interrupt = { "csiphy0" },
+ .ops = &csiphy_ops_3ph_1_0
},
/* CSIPHY1 */
@@ -148,7 +156,8 @@ static const struct resources csiphy_res_8x96[] = {
{ 0 },
{ 100000000, 200000000, 266666667 } },
.reg = { "csiphy1", "csiphy1_clk_mux" },
- .interrupt = { "csiphy1" }
+ .interrupt = { "csiphy1" },
+ .ops = &csiphy_ops_3ph_1_0
},
/* CSIPHY2 */
@@ -160,11 +169,12 @@ static const struct resources csiphy_res_8x96[] = {
{ 0 },
{ 100000000, 200000000, 266666667 } },
.reg = { "csiphy2", "csiphy2_clk_mux" },
- .interrupt = { "csiphy2" }
+ .interrupt = { "csiphy2" },
+ .ops = &csiphy_ops_3ph_1_0
}
};
-static const struct resources csid_res_8x96[] = {
+static const struct camss_subdev_resources csid_res_8x96[] = {
/* CSID0 */
{
.regulators = { "vdda" },
@@ -179,7 +189,8 @@ static const struct resources csid_res_8x96[] = {
{ 0 },
{ 0 } },
.reg = { "csid0" },
- .interrupt = { "csid0" }
+ .interrupt = { "csid0" },
+ .ops = &csid_ops_4_7,
},
/* CSID1 */
@@ -196,7 +207,8 @@ static const struct resources csid_res_8x96[] = {
{ 0 },
{ 0 } },
.reg = { "csid1" },
- .interrupt = { "csid1" }
+ .interrupt = { "csid1" },
+ .ops = &csid_ops_4_7,
},
/* CSID2 */
@@ -213,7 +225,8 @@ static const struct resources csid_res_8x96[] = {
{ 0 },
{ 0 } },
.reg = { "csid2" },
- .interrupt = { "csid2" }
+ .interrupt = { "csid2" },
+ .ops = &csid_ops_4_7,
},
/* CSID3 */
@@ -230,11 +243,12 @@ static const struct resources csid_res_8x96[] = {
{ 0 },
{ 0 } },
.reg = { "csid3" },
- .interrupt = { "csid3" }
+ .interrupt = { "csid3" },
+ .ops = &csid_ops_4_7,
}
};
-static const struct resources_ispif ispif_res_8x96 = {
+static const struct camss_subdev_resources ispif_res_8x96 = {
/* ISPIF */
.clock = { "top_ahb", "ahb", "ispif_ahb",
"csi0", "csi0_pix", "csi0_rdi",
@@ -243,10 +257,10 @@ static const struct resources_ispif ispif_res_8x96 = {
"csi3", "csi3_pix", "csi3_rdi" },
.clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
.reg = { "ispif", "csi_clk_mux" },
- .interrupt = "ispif"
+ .interrupt = { "ispif" }
};
-static const struct resources vfe_res_8x96[] = {
+static const struct camss_subdev_resources vfe_res_8x96[] = {
/* VFE0 */
{
.regulators = {},
@@ -262,7 +276,9 @@ static const struct resources vfe_res_8x96[] = {
{ 0 },
{ 0 } },
.reg = { "vfe0" },
- .interrupt = { "vfe0" }
+ .interrupt = { "vfe0" },
+ .line_num = 3,
+ .ops = &vfe_ops_4_7
},
/* VFE1 */
@@ -280,11 +296,13 @@ static const struct resources vfe_res_8x96[] = {
{ 0 },
{ 0 } },
.reg = { "vfe1" },
- .interrupt = { "vfe1" }
+ .interrupt = { "vfe1" },
+ .line_num = 3,
+ .ops = &vfe_ops_4_7
}
};
-static const struct resources csiphy_res_660[] = {
+static const struct camss_subdev_resources csiphy_res_660[] = {
/* CSIPHY0 */
{
.regulators = {},
@@ -296,7 +314,8 @@ static const struct resources csiphy_res_660[] = {
{ 100000000, 200000000, 269333333 },
{ 0 } },
.reg = { "csiphy0", "csiphy0_clk_mux" },
- .interrupt = { "csiphy0" }
+ .interrupt = { "csiphy0" },
+ .ops = &csiphy_ops_3ph_1_0
},
/* CSIPHY1 */
@@ -310,7 +329,8 @@ static const struct resources csiphy_res_660[] = {
{ 100000000, 200000000, 269333333 },
{ 0 } },
.reg = { "csiphy1", "csiphy1_clk_mux" },
- .interrupt = { "csiphy1" }
+ .interrupt = { "csiphy1" },
+ .ops = &csiphy_ops_3ph_1_0
},
/* CSIPHY2 */
@@ -324,11 +344,12 @@ static const struct resources csiphy_res_660[] = {
{ 100000000, 200000000, 269333333 },
{ 0 } },
.reg = { "csiphy2", "csiphy2_clk_mux" },
- .interrupt = { "csiphy2" }
+ .interrupt = { "csiphy2" },
+ .ops = &csiphy_ops_3ph_1_0
}
};
-static const struct resources csid_res_660[] = {
+static const struct camss_subdev_resources csid_res_660[] = {
/* CSID0 */
{
.regulators = { "vdda", "vdd_sec" },
@@ -346,7 +367,8 @@ static const struct resources csid_res_660[] = {
{ 0 },
{ 0 } },
.reg = { "csid0" },
- .interrupt = { "csid0" }
+ .interrupt = { "csid0" },
+ .ops = &csid_ops_4_7,
},
/* CSID1 */
@@ -366,7 +388,8 @@ static const struct resources csid_res_660[] = {
{ 0 },
{ 0 } },
.reg = { "csid1" },
- .interrupt = { "csid1" }
+ .interrupt = { "csid1" },
+ .ops = &csid_ops_4_7,
},
/* CSID2 */
@@ -386,7 +409,8 @@ static const struct resources csid_res_660[] = {
{ 0 },
{ 0 } },
.reg = { "csid2" },
- .interrupt = { "csid2" }
+ .interrupt = { "csid2" },
+ .ops = &csid_ops_4_7,
},
/* CSID3 */
@@ -406,11 +430,12 @@ static const struct resources csid_res_660[] = {
{ 0 },
{ 0 } },
.reg = { "csid3" },
- .interrupt = { "csid3" }
+ .interrupt = { "csid3" },
+ .ops = &csid_ops_4_7,
}
};
-static const struct resources_ispif ispif_res_660 = {
+static const struct camss_subdev_resources ispif_res_660 = {
/* ISPIF */
.clock = { "top_ahb", "ahb", "ispif_ahb",
"csi0", "csi0_pix", "csi0_rdi",
@@ -419,10 +444,10 @@ static const struct resources_ispif ispif_res_660 = {
"csi3", "csi3_pix", "csi3_rdi" },
.clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
.reg = { "ispif", "csi_clk_mux" },
- .interrupt = "ispif"
+ .interrupt = { "ispif" }
};
-static const struct resources vfe_res_660[] = {
+static const struct camss_subdev_resources vfe_res_660[] = {
/* VFE0 */
{
.regulators = {},
@@ -441,7 +466,9 @@ static const struct resources vfe_res_660[] = {
{ 0 },
{ 0 } },
.reg = { "vfe0" },
- .interrupt = { "vfe0" }
+ .interrupt = { "vfe0" },
+ .line_num = 3,
+ .ops = &vfe_ops_4_8
},
/* VFE1 */
@@ -462,11 +489,13 @@ static const struct resources vfe_res_660[] = {
{ 0 },
{ 0 } },
.reg = { "vfe1" },
- .interrupt = { "vfe1" }
+ .interrupt = { "vfe1" },
+ .line_num = 3,
+ .ops = &vfe_ops_4_8
}
};
-static const struct resources csiphy_res_845[] = {
+static const struct camss_subdev_resources csiphy_res_845[] = {
/* CSIPHY0 */
{
.regulators = {},
@@ -482,7 +511,8 @@ static const struct resources csiphy_res_845[] = {
{ 0 },
{ 19200000, 240000000, 269333333 } },
.reg = { "csiphy0" },
- .interrupt = { "csiphy0" }
+ .interrupt = { "csiphy0" },
+ .ops = &csiphy_ops_3ph_1_0
},
/* CSIPHY1 */
@@ -500,7 +530,8 @@ static const struct resources csiphy_res_845[] = {
{ 0 },
{ 19200000, 240000000, 269333333 } },
.reg = { "csiphy1" },
- .interrupt = { "csiphy1" }
+ .interrupt = { "csiphy1" },
+ .ops = &csiphy_ops_3ph_1_0
},
/* CSIPHY2 */
@@ -518,7 +549,8 @@ static const struct resources csiphy_res_845[] = {
{ 0 },
{ 19200000, 240000000, 269333333 } },
.reg = { "csiphy2" },
- .interrupt = { "csiphy2" }
+ .interrupt = { "csiphy2" },
+ .ops = &csiphy_ops_3ph_1_0
},
/* CSIPHY3 */
@@ -536,11 +568,12 @@ static const struct resources csiphy_res_845[] = {
{ 0 },
{ 19200000, 240000000, 269333333 } },
.reg = { "csiphy3" },
- .interrupt = { "csiphy3" }
+ .interrupt = { "csiphy3" },
+ .ops = &csiphy_ops_3ph_1_0
}
};
-static const struct resources csid_res_845[] = {
+static const struct camss_subdev_resources csid_res_845[] = {
/* CSID0 */
{
.regulators = { "vdda-phy", "vdda-pll" },
@@ -558,7 +591,8 @@ static const struct resources csid_res_845[] = {
{ 19200000, 75000000, 384000000, 538666667 },
{ 384000000 } },
.reg = { "csid0" },
- .interrupt = { "csid0" }
+ .interrupt = { "csid0" },
+ .ops = &csid_ops_gen2
},
/* CSID1 */
@@ -578,7 +612,8 @@ static const struct resources csid_res_845[] = {
{ 19200000, 75000000, 384000000, 538666667 },
{ 384000000 } },
.reg = { "csid1" },
- .interrupt = { "csid1" }
+ .interrupt = { "csid1" },
+ .ops = &csid_ops_gen2
},
/* CSID2 */
@@ -598,11 +633,12 @@ static const struct resources csid_res_845[] = {
{ 19200000, 75000000, 384000000, 538666667 },
{ 384000000 } },
.reg = { "csid2" },
- .interrupt = { "csid2" }
+ .interrupt = { "csid2" },
+ .ops = &csid_ops_gen2
}
};
-static const struct resources vfe_res_845[] = {
+static const struct camss_subdev_resources vfe_res_845[] = {
/* VFE0 */
{
.regulators = {},
@@ -620,7 +656,9 @@ static const struct resources vfe_res_845[] = {
{ 19200000, 75000000, 384000000, 538666667 },
{ 384000000 } },
.reg = { "vfe0" },
- .interrupt = { "vfe0" }
+ .interrupt = { "vfe0" },
+ .line_num = 4,
+ .ops = &vfe_ops_170
},
/* VFE1 */
@@ -640,7 +678,9 @@ static const struct resources vfe_res_845[] = {
{ 19200000, 75000000, 384000000, 538666667 },
{ 384000000 } },
.reg = { "vfe1" },
- .interrupt = { "vfe1" }
+ .interrupt = { "vfe1" },
+ .line_num = 4,
+ .ops = &vfe_ops_170
},
/* VFE-lite */
@@ -659,11 +699,13 @@ static const struct resources vfe_res_845[] = {
{ 19200000, 75000000, 384000000, 538666667 },
{ 384000000 } },
.reg = { "vfe_lite" },
- .interrupt = { "vfe_lite" }
+ .interrupt = { "vfe_lite" },
+ .line_num = 4,
+ .ops = &vfe_ops_170
}
};
-static const struct resources csiphy_res_8250[] = {
+static const struct camss_subdev_resources csiphy_res_8250[] = {
/* CSIPHY0 */
{
.regulators = {},
@@ -671,7 +713,8 @@ static const struct resources csiphy_res_8250[] = {
.clock_rate = { { 400000000 },
{ 300000000 } },
.reg = { "csiphy0" },
- .interrupt = { "csiphy0" }
+ .interrupt = { "csiphy0" },
+ .ops = &csiphy_ops_3ph_1_0
},
/* CSIPHY1 */
{
@@ -680,7 +723,8 @@ static const struct resources csiphy_res_8250[] = {
.clock_rate = { { 400000000 },
{ 300000000 } },
.reg = { "csiphy1" },
- .interrupt = { "csiphy1" }
+ .interrupt = { "csiphy1" },
+ .ops = &csiphy_ops_3ph_1_0
},
/* CSIPHY2 */
{
@@ -689,7 +733,8 @@ static const struct resources csiphy_res_8250[] = {
.clock_rate = { { 400000000 },
{ 300000000 } },
.reg = { "csiphy2" },
- .interrupt = { "csiphy2" }
+ .interrupt = { "csiphy2" },
+ .ops = &csiphy_ops_3ph_1_0
},
/* CSIPHY3 */
{
@@ -698,7 +743,8 @@ static const struct resources csiphy_res_8250[] = {
.clock_rate = { { 400000000 },
{ 300000000 } },
.reg = { "csiphy3" },
- .interrupt = { "csiphy3" }
+ .interrupt = { "csiphy3" },
+ .ops = &csiphy_ops_3ph_1_0
},
/* CSIPHY4 */
{
@@ -707,7 +753,8 @@ static const struct resources csiphy_res_8250[] = {
.clock_rate = { { 400000000 },
{ 300000000 } },
.reg = { "csiphy4" },
- .interrupt = { "csiphy4" }
+ .interrupt = { "csiphy4" },
+ .ops = &csiphy_ops_3ph_1_0
},
/* CSIPHY5 */
{
@@ -716,11 +763,12 @@ static const struct resources csiphy_res_8250[] = {
.clock_rate = { { 400000000 },
{ 300000000 } },
.reg = { "csiphy5" },
- .interrupt = { "csiphy5" }
+ .interrupt = { "csiphy5" },
+ .ops = &csiphy_ops_3ph_1_0
}
};
-static const struct resources csid_res_8250[] = {
+static const struct camss_subdev_resources csid_res_8250[] = {
/* CSID0 */
{
.regulators = { "vdda-phy", "vdda-pll" },
@@ -731,7 +779,8 @@ static const struct resources csid_res_8250[] = {
{ 100000000, 200000000, 300000000, 400000000 },
{ 0 } },
.reg = { "csid0" },
- .interrupt = { "csid0" }
+ .interrupt = { "csid0" },
+ .ops = &csid_ops_gen2
},
/* CSID1 */
{
@@ -743,7 +792,8 @@ static const struct resources csid_res_8250[] = {
{ 100000000, 200000000, 300000000, 400000000 },
{ 0 } },
.reg = { "csid1" },
- .interrupt = { "csid1" }
+ .interrupt = { "csid1" },
+ .ops = &csid_ops_gen2
},
/* CSID2 */
{
@@ -754,7 +804,8 @@ static const struct resources csid_res_8250[] = {
{ 400000000, 480000000 },
{ 0 } },
.reg = { "csid2" },
- .interrupt = { "csid2" }
+ .interrupt = { "csid2" },
+ .ops = &csid_ops_gen2
},
/* CSID3 */
{
@@ -765,11 +816,12 @@ static const struct resources csid_res_8250[] = {
{ 400000000, 480000000 },
{ 0 } },
.reg = { "csid3" },
- .interrupt = { "csid3" }
+ .interrupt = { "csid3" },
+ .ops = &csid_ops_gen2
}
};
-static const struct resources vfe_res_8250[] = {
+static const struct camss_subdev_resources vfe_res_8250[] = {
/* VFE0 */
{
.regulators = {},
@@ -786,7 +838,9 @@ static const struct resources vfe_res_8250[] = {
{ 0 },
{ 0 } },
.reg = { "vfe0" },
- .interrupt = { "vfe0" }
+ .interrupt = { "vfe0" },
+ .line_num = 3,
+ .ops = &vfe_ops_480
},
/* VFE1 */
{
@@ -804,7 +858,9 @@ static const struct resources vfe_res_8250[] = {
{ 0 },
{ 0 } },
.reg = { "vfe1" },
- .interrupt = { "vfe1" }
+ .interrupt = { "vfe1" },
+ .line_num = 3,
+ .ops = &vfe_ops_480
},
/* VFE2 (lite) */
{
@@ -821,7 +877,9 @@ static const struct resources vfe_res_8250[] = {
{ 400000000, 480000000 },
{ 0 } },
.reg = { "vfe_lite0" },
- .interrupt = { "vfe_lite0" }
+ .interrupt = { "vfe_lite0" },
+ .line_num = 4,
+ .ops = &vfe_ops_480
},
/* VFE3 (lite) */
{
@@ -838,7 +896,9 @@ static const struct resources vfe_res_8250[] = {
{ 400000000, 480000000 },
{ 0 } },
.reg = { "vfe_lite1" },
- .interrupt = { "vfe_lite1" }
+ .interrupt = { "vfe_lite1" },
+ .line_num = 4,
+ .ops = &vfe_ops_480
},
};
@@ -1004,7 +1064,7 @@ int camss_pm_domain_on(struct camss *camss, int id)
{
int ret = 0;
- if (id < camss->vfe_num) {
+ if (id < camss->res->vfe_num) {
struct vfe_device *vfe = &camss->vfe[id];
ret = vfe->ops->pm_domain_on(vfe);
@@ -1015,7 +1075,7 @@ int camss_pm_domain_on(struct camss *camss, int id)
void camss_pm_domain_off(struct camss *camss, int id)
{
- if (id < camss->vfe_num) {
+ if (id < camss->res->vfe_num) {
struct vfe_device *vfe = &camss->vfe[id];
vfe->ops->pm_domain_off(vfe);
@@ -1120,47 +1180,13 @@ err_cleanup:
*/
static int camss_init_subdevices(struct camss *camss)
{
- const struct resources *csiphy_res;
- const struct resources *csid_res;
- const struct resources_ispif *ispif_res;
- const struct resources *vfe_res;
+ const struct camss_resources *res = camss->res;
unsigned int i;
int ret;
- if (camss->version == CAMSS_8x16) {
- csiphy_res = csiphy_res_8x16;
- csid_res = csid_res_8x16;
- ispif_res = &ispif_res_8x16;
- vfe_res = vfe_res_8x16;
- } else if (camss->version == CAMSS_8x96) {
- csiphy_res = csiphy_res_8x96;
- csid_res = csid_res_8x96;
- ispif_res = &ispif_res_8x96;
- vfe_res = vfe_res_8x96;
- } else if (camss->version == CAMSS_660) {
- csiphy_res = csiphy_res_660;
- csid_res = csid_res_660;
- ispif_res = &ispif_res_660;
- vfe_res = vfe_res_660;
- } else if (camss->version == CAMSS_845) {
- csiphy_res = csiphy_res_845;
- csid_res = csid_res_845;
- /* Titan VFEs don't have an ISPIF */
- ispif_res = NULL;
- vfe_res = vfe_res_845;
- } else if (camss->version == CAMSS_8250) {
- csiphy_res = csiphy_res_8250;
- csid_res = csid_res_8250;
- /* Titan VFEs don't have an ISPIF */
- ispif_res = NULL;
- vfe_res = vfe_res_8250;
- } else {
- return -EINVAL;
- }
-
- for (i = 0; i < camss->csiphy_num; i++) {
+ for (i = 0; i < camss->res->csiphy_num; i++) {
ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i],
- &csiphy_res[i], i);
+ &res->csiphy_res[i], i);
if (ret < 0) {
dev_err(camss->dev,
"Failed to init csiphy%d sub-device: %d\n",
@@ -1170,9 +1196,9 @@ static int camss_init_subdevices(struct camss *camss)
}
/* note: SM8250 requires VFE to be initialized before CSID */
- for (i = 0; i < camss->vfe_num + camss->vfe_lite_num; i++) {
+ for (i = 0; i < camss->vfe_total_num; i++) {
ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
- &vfe_res[i], i);
+ &res->vfe_res[i], i);
if (ret < 0) {
dev_err(camss->dev,
"Fail to init vfe%d sub-device: %d\n", i, ret);
@@ -1180,9 +1206,9 @@ static int camss_init_subdevices(struct camss *camss)
}
}
- for (i = 0; i < camss->csid_num; i++) {
+ for (i = 0; i < camss->res->csid_num; i++) {
ret = msm_csid_subdev_init(camss, &camss->csid[i],
- &csid_res[i], i);
+ &res->csid_res[i], i);
if (ret < 0) {
dev_err(camss->dev,
"Failed to init csid%d sub-device: %d\n",
@@ -1191,7 +1217,7 @@ static int camss_init_subdevices(struct camss *camss)
}
}
- ret = msm_ispif_subdev_init(camss, ispif_res);
+ ret = msm_ispif_subdev_init(camss, res->ispif_res);
if (ret < 0) {
dev_err(camss->dev, "Failed to init ispif sub-device: %d\n",
ret);
@@ -1212,7 +1238,7 @@ static int camss_register_entities(struct camss *camss)
int i, j, k;
int ret;
- for (i = 0; i < camss->csiphy_num; i++) {
+ for (i = 0; i < camss->res->csiphy_num; i++) {
ret = msm_csiphy_register_entity(&camss->csiphy[i],
&camss->v4l2_dev);
if (ret < 0) {
@@ -1223,7 +1249,7 @@ static int camss_register_entities(struct camss *camss)
}
}
- for (i = 0; i < camss->csid_num; i++) {
+ for (i = 0; i < camss->res->csid_num; i++) {
ret = msm_csid_register_entity(&camss->csid[i],
&camss->v4l2_dev);
if (ret < 0) {
@@ -1242,7 +1268,7 @@ static int camss_register_entities(struct camss *camss)
goto err_reg_ispif;
}
- for (i = 0; i < camss->vfe_num + camss->vfe_lite_num; i++) {
+ for (i = 0; i < camss->vfe_total_num; i++) {
ret = msm_vfe_register_entities(&camss->vfe[i],
&camss->v4l2_dev);
if (ret < 0) {
@@ -1253,8 +1279,8 @@ static int camss_register_entities(struct camss *camss)
}
}
- for (i = 0; i < camss->csiphy_num; i++) {
- for (j = 0; j < camss->csid_num; j++) {
+ for (i = 0; i < camss->res->csiphy_num; i++) {
+ for (j = 0; j < camss->res->csid_num; j++) {
ret = media_create_pad_link(
&camss->csiphy[i].subdev.entity,
MSM_CSIPHY_PAD_SRC,
@@ -1273,7 +1299,7 @@ static int camss_register_entities(struct camss *camss)
}
if (camss->ispif) {
- for (i = 0; i < camss->csid_num; i++) {
+ for (i = 0; i < camss->res->csid_num; i++) {
for (j = 0; j < camss->ispif->line_num; j++) {
ret = media_create_pad_link(
&camss->csid[i].subdev.entity,
@@ -1293,7 +1319,7 @@ static int camss_register_entities(struct camss *camss)
}
for (i = 0; i < camss->ispif->line_num; i++)
- for (k = 0; k < camss->vfe_num; k++)
+ for (k = 0; k < camss->res->vfe_num; k++)
for (j = 0; j < camss->vfe[k].line_num; j++) {
struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev;
struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
@@ -1313,8 +1339,8 @@ static int camss_register_entities(struct camss *camss)
}
}
} else {
- for (i = 0; i < camss->csid_num; i++)
- for (k = 0; k < camss->vfe_num + camss->vfe_lite_num; k++)
+ for (i = 0; i < camss->res->csid_num; i++)
+ for (k = 0; k < camss->vfe_total_num; k++)
for (j = 0; j < camss->vfe[k].line_num; j++) {
struct v4l2_subdev *csid = &camss->csid[i].subdev;
struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
@@ -1338,7 +1364,7 @@ static int camss_register_entities(struct camss *camss)
return 0;
err_link:
- i = camss->vfe_num + camss->vfe_lite_num;
+ i = camss->vfe_total_num;
err_reg_vfe:
for (i--; i >= 0; i--)
msm_vfe_unregister_entities(&camss->vfe[i]);
@@ -1346,12 +1372,12 @@ err_reg_vfe:
err_reg_ispif:
msm_ispif_unregister_entities(camss->ispif);
- i = camss->csid_num;
+ i = camss->res->csid_num;
err_reg_csid:
for (i--; i >= 0; i--)
msm_csid_unregister_entity(&camss->csid[i]);
- i = camss->csiphy_num;
+ i = camss->res->csiphy_num;
err_reg_csiphy:
for (i--; i >= 0; i--)
msm_csiphy_unregister_entity(&camss->csiphy[i]);
@@ -1369,15 +1395,15 @@ static void camss_unregister_entities(struct camss *camss)
{
unsigned int i;
- for (i = 0; i < camss->csiphy_num; i++)
+ for (i = 0; i < camss->res->csiphy_num; i++)
msm_csiphy_unregister_entity(&camss->csiphy[i]);
- for (i = 0; i < camss->csid_num; i++)
+ for (i = 0; i < camss->res->csid_num; i++)
msm_csid_unregister_entity(&camss->csid[i]);
msm_ispif_unregister_entities(camss->ispif);
- for (i = 0; i < camss->vfe_num + camss->vfe_lite_num; i++)
+ for (i = 0; i < camss->vfe_total_num; i++)
msm_vfe_unregister_entities(&camss->vfe[i]);
}
@@ -1496,7 +1522,7 @@ static int camss_configure_pd(struct camss *camss)
}
}
- if (i > camss->vfe_num) {
+ if (i > camss->res->vfe_num) {
camss->genpd_link[i - 1] = device_link_add(camss->dev, camss->genpd[i - 1],
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
DL_FLAG_RPM_ACTIVE);
@@ -1518,26 +1544,34 @@ fail_pm:
static int camss_icc_get(struct camss *camss)
{
const struct resources_icc *icc_res;
- int nbr_icc_paths = 0;
int i;
- if (camss->version == CAMSS_8250) {
- icc_res = &icc_res_sm8250[0];
- nbr_icc_paths = ICC_SM8250_COUNT;
- }
+ icc_res = camss->res->icc_res;
- for (i = 0; i < nbr_icc_paths; i++) {
+ for (i = 0; i < camss->res->icc_path_num; i++) {
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]);
-
- camss->icc_bw_tbl[i] = icc_res[i].icc_bw_tbl;
}
return 0;
}
+static void camss_genpd_cleanup(struct camss *camss)
+{
+ int i;
+
+ if (camss->genpd_num == 1)
+ return;
+
+ if (camss->genpd_num > camss->res->vfe_num)
+ device_link_del(camss->genpd_link[camss->genpd_num - 1]);
+
+ for (i = 0; i < camss->genpd_num; i++)
+ dev_pm_domain_detach(camss->genpd[i], true);
+}
+
/*
* camss_probe - Probe CAMSS platform device
* @pdev: Pointer to CAMSS platform device
@@ -1548,84 +1582,59 @@ static int camss_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct camss *camss;
- int num_subdevs, ret;
+ int num_subdevs;
+ int ret;
camss = devm_kzalloc(dev, sizeof(*camss), GFP_KERNEL);
if (!camss)
return -ENOMEM;
+ camss->res = of_device_get_match_data(dev);
+
atomic_set(&camss->ref_count, 0);
camss->dev = dev;
platform_set_drvdata(pdev, camss);
- if (of_device_is_compatible(dev->of_node, "qcom,msm8916-camss")) {
- camss->version = CAMSS_8x16;
- camss->csiphy_num = 2;
- camss->csid_num = 2;
- camss->vfe_num = 1;
- } else if (of_device_is_compatible(dev->of_node,
- "qcom,msm8996-camss")) {
- camss->version = CAMSS_8x96;
- camss->csiphy_num = 3;
- camss->csid_num = 4;
- camss->vfe_num = 2;
- } else if (of_device_is_compatible(dev->of_node,
- "qcom,sdm660-camss")) {
- camss->version = CAMSS_660;
- camss->csiphy_num = 3;
- camss->csid_num = 4;
- camss->vfe_num = 2;
- } else if (of_device_is_compatible(dev->of_node,
- "qcom,sdm845-camss")) {
- camss->version = CAMSS_845;
- camss->csiphy_num = 4;
- camss->csid_num = 3;
- camss->vfe_num = 2;
- camss->vfe_lite_num = 1;
- } else if (of_device_is_compatible(dev->of_node,
- "qcom,sm8250-camss")) {
- camss->version = CAMSS_8250;
- camss->csiphy_num = 6;
- camss->csid_num = 4;
- camss->vfe_num = 2;
- camss->vfe_lite_num = 2;
- } else {
- return -EINVAL;
- }
-
- camss->csiphy = devm_kcalloc(dev, camss->csiphy_num,
+ camss->csiphy = devm_kcalloc(dev, camss->res->csiphy_num,
sizeof(*camss->csiphy), GFP_KERNEL);
if (!camss->csiphy)
return -ENOMEM;
- camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid),
+ camss->csid = devm_kcalloc(dev, camss->res->csid_num, sizeof(*camss->csid),
GFP_KERNEL);
if (!camss->csid)
return -ENOMEM;
- if (camss->version == CAMSS_8x16 ||
- camss->version == CAMSS_8x96) {
+ if (camss->res->version == CAMSS_8x16 ||
+ camss->res->version == CAMSS_8x96) {
camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL);
if (!camss->ispif)
return -ENOMEM;
}
- camss->vfe = devm_kcalloc(dev, camss->vfe_num + camss->vfe_lite_num,
+ camss->vfe_total_num = camss->res->vfe_num + camss->res->vfe_lite_num;
+ camss->vfe = devm_kcalloc(dev, camss->vfe_total_num,
sizeof(*camss->vfe), GFP_KERNEL);
if (!camss->vfe)
return -ENOMEM;
ret = camss_icc_get(camss);
if (ret < 0)
- goto err_cleanup;
+ return ret;
+
+ ret = camss_configure_pd(camss);
+ if (ret < 0) {
+ dev_err(dev, "Failed to configure power domains: %d\n", ret);
+ return ret;
+ }
ret = camss_init_subdevices(camss);
if (ret < 0)
- goto err_cleanup;
+ goto err_genpd_cleanup;
ret = dma_set_mask_and_coherent(dev, 0xffffffff);
if (ret)
- goto err_cleanup;
+ goto err_genpd_cleanup;
camss->media_dev.dev = camss->dev;
strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem",
@@ -1637,7 +1646,7 @@ static int camss_probe(struct platform_device *pdev)
ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
if (ret < 0) {
dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
- goto err_cleanup;
+ goto err_genpd_cleanup;
}
v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev);
@@ -1645,12 +1654,12 @@ static int camss_probe(struct platform_device *pdev)
num_subdevs = camss_of_parse_ports(camss);
if (num_subdevs < 0) {
ret = num_subdevs;
- goto err_cleanup;
+ goto err_v4l2_device_unregister;
}
ret = camss_register_entities(camss);
if (ret < 0)
- goto err_cleanup;
+ goto err_v4l2_device_unregister;
if (num_subdevs) {
camss->notifier.ops = &camss_subdev_notifier_ops;
@@ -1678,43 +1687,28 @@ static int camss_probe(struct platform_device *pdev)
}
}
- ret = camss_configure_pd(camss);
- if (ret < 0) {
- dev_err(dev, "Failed to configure power domains: %d\n", ret);
- return ret;
- }
-
pm_runtime_enable(dev);
return 0;
err_register_subdevs:
camss_unregister_entities(camss);
-err_cleanup:
+err_v4l2_device_unregister:
v4l2_device_unregister(&camss->v4l2_dev);
v4l2_async_nf_cleanup(&camss->notifier);
+err_genpd_cleanup:
+ camss_genpd_cleanup(camss);
return ret;
}
void camss_delete(struct camss *camss)
{
- int i;
-
v4l2_device_unregister(&camss->v4l2_dev);
media_device_unregister(&camss->media_dev);
media_device_cleanup(&camss->media_dev);
pm_runtime_disable(camss->dev);
-
- if (camss->genpd_num == 1)
- return;
-
- if (camss->genpd_num > camss->vfe_num)
- device_link_del(camss->genpd_link[camss->genpd_num - 1]);
-
- for (i = 0; i < camss->genpd_num; i++)
- dev_pm_domain_detach(camss->genpd[i], true);
}
/*
@@ -1733,14 +1727,73 @@ static void camss_remove(struct platform_device *pdev)
if (atomic_read(&camss->ref_count) == 0)
camss_delete(camss);
+
+ camss_genpd_cleanup(camss);
}
+static const struct camss_resources msm8916_resources = {
+ .version = CAMSS_8x16,
+ .csiphy_res = csiphy_res_8x16,
+ .csid_res = csid_res_8x16,
+ .ispif_res = &ispif_res_8x16,
+ .vfe_res = vfe_res_8x16,
+ .csiphy_num = ARRAY_SIZE(csiphy_res_8x16),
+ .csid_num = ARRAY_SIZE(csid_res_8x16),
+ .vfe_num = ARRAY_SIZE(vfe_res_8x16),
+};
+
+static const struct camss_resources msm8996_resources = {
+ .version = CAMSS_8x96,
+ .csiphy_res = csiphy_res_8x96,
+ .csid_res = csid_res_8x96,
+ .ispif_res = &ispif_res_8x96,
+ .vfe_res = vfe_res_8x96,
+ .csiphy_num = ARRAY_SIZE(csiphy_res_8x96),
+ .csid_num = ARRAY_SIZE(csid_res_8x96),
+ .vfe_num = ARRAY_SIZE(vfe_res_8x96),
+};
+
+static const struct camss_resources sdm660_resources = {
+ .version = CAMSS_660,
+ .csiphy_res = csiphy_res_660,
+ .csid_res = csid_res_660,
+ .ispif_res = &ispif_res_660,
+ .vfe_res = vfe_res_660,
+ .csiphy_num = ARRAY_SIZE(csiphy_res_660),
+ .csid_num = ARRAY_SIZE(csid_res_660),
+ .vfe_num = ARRAY_SIZE(vfe_res_660),
+};
+
+static const struct camss_resources sdm845_resources = {
+ .version = CAMSS_845,
+ .csiphy_res = csiphy_res_845,
+ .csid_res = csid_res_845,
+ .vfe_res = vfe_res_845,
+ .csiphy_num = ARRAY_SIZE(csiphy_res_845),
+ .csid_num = ARRAY_SIZE(csid_res_845),
+ .vfe_num = 2,
+ .vfe_lite_num = 1,
+};
+
+static const struct camss_resources sm8250_resources = {
+ .version = CAMSS_8250,
+ .csiphy_res = csiphy_res_8250,
+ .csid_res = csid_res_8250,
+ .vfe_res = vfe_res_8250,
+ .icc_res = icc_res_sm8250,
+ .icc_path_num = ARRAY_SIZE(icc_res_sm8250),
+ .csiphy_num = ARRAY_SIZE(csiphy_res_8250),
+ .csid_num = ARRAY_SIZE(csid_res_8250),
+ .vfe_num = 2,
+ .vfe_lite_num = 2,
+};
+
static const struct of_device_id camss_dt_match[] = {
- { .compatible = "qcom,msm8916-camss" },
- { .compatible = "qcom,msm8996-camss" },
- { .compatible = "qcom,sdm660-camss" },
- { .compatible = "qcom,sdm845-camss" },
- { .compatible = "qcom,sm8250-camss" },
+ { .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 },
{ }
};
@@ -1749,14 +1802,10 @@ MODULE_DEVICE_TABLE(of, camss_dt_match);
static int __maybe_unused camss_runtime_suspend(struct device *dev)
{
struct camss *camss = dev_get_drvdata(dev);
- int nbr_icc_paths = 0;
int i;
int ret;
- if (camss->version == CAMSS_8250)
- nbr_icc_paths = ICC_SM8250_COUNT;
-
- for (i = 0; i < nbr_icc_paths; i++) {
+ for (i = 0; i < camss->res->icc_path_num; i++) {
ret = icc_set_bw(camss->icc_path[i], 0, 0);
if (ret)
return ret;
@@ -1768,17 +1817,14 @@ static int __maybe_unused camss_runtime_suspend(struct device *dev)
static int __maybe_unused camss_runtime_resume(struct device *dev)
{
struct camss *camss = dev_get_drvdata(dev);
- int nbr_icc_paths = 0;
+ const struct resources_icc *icc_res = camss->res->icc_res;
int i;
int ret;
- if (camss->version == CAMSS_8250)
- nbr_icc_paths = ICC_SM8250_COUNT;
-
- for (i = 0; i < nbr_icc_paths; i++) {
+ for (i = 0; i < camss->res->icc_path_num; i++) {
ret = icc_set_bw(camss->icc_path[i],
- camss->icc_bw_tbl[i].avg,
- camss->icc_bw_tbl[i].peak);
+ icc_res[i].icc_bw_tbl.avg,
+ icc_res[i].icc_bw_tbl.peak);
if (ret)
return ret;
}
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index f6c326cb853b..8acad7321c09 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -41,19 +41,15 @@
#define CAMSS_RES_MAX 17
-struct resources {
+struct camss_subdev_resources {
char *regulators[CAMSS_RES_MAX];
char *clock[CAMSS_RES_MAX];
+ char *clock_for_reset[CAMSS_RES_MAX];
u32 clock_rate[CAMSS_RES_MAX][CAMSS_RES_MAX];
char *reg[CAMSS_RES_MAX];
char *interrupt[CAMSS_RES_MAX];
-};
-
-struct resources_ispif {
- char *clock[CAMSS_RES_MAX];
- char *clock_for_reset[CAMSS_RES_MAX];
- char *reg[CAMSS_RES_MAX];
- char *interrupt;
+ u8 line_num;
+ const void *ops;
};
struct icc_bw_tbl {
@@ -85,26 +81,36 @@ enum icc_count {
ICC_SM8250_COUNT = 4,
};
-struct camss {
+struct camss_resources {
enum camss_version version;
+ const struct camss_subdev_resources *csiphy_res;
+ const struct camss_subdev_resources *csid_res;
+ const struct camss_subdev_resources *ispif_res;
+ const struct camss_subdev_resources *vfe_res;
+ const struct resources_icc *icc_res;
+ const unsigned int icc_path_num;
+ const unsigned int csiphy_num;
+ const unsigned int csid_num;
+ const unsigned int vfe_num;
+ const unsigned int vfe_lite_num;
+};
+
+struct camss {
struct v4l2_device v4l2_dev;
struct v4l2_async_notifier notifier;
struct media_device media_dev;
struct device *dev;
- int csiphy_num;
struct csiphy_device *csiphy;
- int csid_num;
struct csid_device *csid;
struct ispif_device *ispif;
- int vfe_num;
- int vfe_lite_num;
struct vfe_device *vfe;
atomic_t ref_count;
int genpd_num;
struct device **genpd;
struct device_link **genpd_link;
struct icc_path *icc_path[ICC_SM8250_COUNT];
- struct icc_bw_tbl icc_bw_tbl[ICC_SM8250_COUNT];
+ const struct camss_resources *res;
+ unsigned int vfe_total_num;
};
struct camss_camera_interface {
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 054b8e74ba4f..9cffe975581b 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -549,7 +549,7 @@ static const struct venus_resources msm8916_res = {
.vmem_size = 0,
.vmem_addr = 0,
.dma_mask = 0xddc00000 - 1,
- .fwname = "qcom/venus-1.8/venus.mdt",
+ .fwname = "qcom/venus-1.8/venus.mbn",
};
static const struct freq_tbl msm8996_freq_table[] = {
@@ -582,7 +582,7 @@ static const struct venus_resources msm8996_res = {
.vmem_size = 0,
.vmem_addr = 0,
.dma_mask = 0xddc00000 - 1,
- .fwname = "qcom/venus-4.2/venus.mdt",
+ .fwname = "qcom/venus-4.2/venus.mbn",
};
static const struct freq_tbl sdm660_freq_table[] = {
@@ -690,7 +690,7 @@ static const struct venus_resources sdm845_res = {
.vmem_size = 0,
.vmem_addr = 0,
.dma_mask = 0xe0000000 - 1,
- .fwname = "qcom/venus-5.2/venus.mdt",
+ .fwname = "qcom/venus-5.2/venus.mbn",
};
static const struct venus_resources sdm845_res_v2 = {
@@ -720,7 +720,7 @@ static const struct venus_resources sdm845_res_v2 = {
.cp_size = 0x70800000,
.cp_nonpixel_start = 0x1000000,
.cp_nonpixel_size = 0x24800000,
- .fwname = "qcom/venus-5.2/venus.mdt",
+ .fwname = "qcom/venus-5.2/venus.mbn",
};
static const struct freq_tbl sc7180_freq_table[] = {
@@ -768,7 +768,7 @@ static const struct venus_resources sc7180_res = {
.cp_size = 0x70800000,
.cp_nonpixel_start = 0x1000000,
.cp_nonpixel_size = 0x24800000,
- .fwname = "qcom/venus-5.4/venus.mdt",
+ .fwname = "qcom/venus-5.4/venus.mbn",
};
static const struct freq_tbl sm8250_freq_table[] = {
diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.h b/drivers/media/platform/qcom/venus/hfi_cmds.h
index dd9c5066442d..20acd412ee7b 100644
--- a/drivers/media/platform/qcom/venus/hfi_cmds.h
+++ b/drivers/media/platform/qcom/venus/hfi_cmds.h
@@ -242,7 +242,7 @@ struct hfi_session_parse_sequence_header_pkt {
struct hfi_sfr {
u32 buf_size;
- u8 data[1];
+ u8 data[] __counted_by(buf_size);
};
struct hfi_sys_test_ssr_pkt {
diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c
index 7cab685a2ec8..0a041b4db9ef 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.c
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c
@@ -398,7 +398,7 @@ session_get_prop_buf_req(struct hfi_msg_session_property_info_pkt *pkt,
memcpy(&bufreq[idx], buf_req, sizeof(*bufreq));
idx++;
- if (idx > HFI_BUFFER_TYPE_MAX)
+ if (idx >= HFI_BUFFER_TYPE_MAX)
return HFI_ERR_SESSION_INVALID_PARAMETER;
req_bytes -= sizeof(struct hfi_buffer_requirements);
diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c
index 6cf74b2bc5ae..c43839539d4d 100644
--- a/drivers/media/platform/qcom/venus/hfi_parser.c
+++ b/drivers/media/platform/qcom/venus/hfi_parser.c
@@ -19,6 +19,9 @@ static void init_codecs(struct venus_core *core)
struct hfi_plat_caps *caps = core->caps, *cap;
unsigned long bit;
+ if (hweight_long(core->dec_codecs) + hweight_long(core->enc_codecs) > MAX_CODEC_NUM)
+ return;
+
for_each_set_bit(bit, &core->dec_codecs, MAX_CODEC_NUM) {
cap = &caps[core->codecs_count++];
cap->codec = BIT(bit);
@@ -86,6 +89,9 @@ static void fill_profile_level(struct hfi_plat_caps *cap, const void *data,
{
const struct hfi_profile_level *pl = data;
+ if (cap->num_pl + num >= HFI_MAX_PROFILE_COUNT)
+ return;
+
memcpy(&cap->pl[cap->num_pl], pl, num * sizeof(*pl));
cap->num_pl += num;
}
@@ -111,6 +117,9 @@ fill_caps(struct hfi_plat_caps *cap, const void *data, unsigned int num)
{
const struct hfi_capability *caps = data;
+ if (cap->num_caps + num >= MAX_CAP_ENTRIES)
+ return;
+
memcpy(&cap->caps[cap->num_caps], caps, num * sizeof(*caps));
cap->num_caps += num;
}
@@ -137,6 +146,9 @@ static void fill_raw_fmts(struct hfi_plat_caps *cap, const void *fmts,
{
const struct raw_formats *formats = fmts;
+ if (cap->num_fmts + num_fmts >= MAX_FMT_ENTRIES)
+ return;
+
memcpy(&cap->fmts[cap->num_fmts], formats, num_fmts * sizeof(*formats));
cap->num_fmts += num_fmts;
}
@@ -159,6 +171,9 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
rawfmts[i].buftype = fmt->buffer_type;
i++;
+ if (i >= MAX_FMT_ENTRIES)
+ return;
+
if (pinfo->num_planes > MAX_PLANES)
break;
diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
index 19fc6575a489..f9437b6412b9 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -205,6 +205,11 @@ static int venus_write_queue(struct venus_hfi_device *hdev,
new_wr_idx = wr_idx + dwords;
wr_ptr = (u32 *)(queue->qmem.kva + (wr_idx << 2));
+
+ if (wr_ptr < (u32 *)queue->qmem.kva ||
+ wr_ptr > (u32 *)(queue->qmem.kva + queue->qmem.size - sizeof(*wr_ptr)))
+ return -EINVAL;
+
if (new_wr_idx < qsize) {
memcpy(wr_ptr, packet, dwords << 2);
} else {
@@ -272,6 +277,11 @@ static int venus_read_queue(struct venus_hfi_device *hdev,
}
rd_ptr = (u32 *)(queue->qmem.kva + (rd_idx << 2));
+
+ if (rd_ptr < (u32 *)queue->qmem.kva ||
+ rd_ptr > (u32 *)(queue->qmem.kva + queue->qmem.size - sizeof(*rd_ptr)))
+ return -EINVAL;
+
dwords = *rd_ptr >> 2;
if (!dwords)
return -EINVAL;
diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
index 48c9084bb4db..a1b127caa90a 100644
--- a/drivers/media/platform/qcom/venus/pm_helpers.c
+++ b/drivers/media/platform/qcom/venus/pm_helpers.c
@@ -870,7 +870,7 @@ static int vcodec_domains_get(struct venus_core *core)
pd = dev_pm_domain_attach_by_name(dev,
res->vcodec_pmdomains[i]);
if (IS_ERR_OR_NULL(pd))
- return PTR_ERR(pd) ? : -ENODATA;
+ return pd ? PTR_ERR(pd) : -ENODATA;
core->pmdomains[i] = pd;
}