summaryrefslogtreecommitdiff
path: root/drivers/media/platform/qcom/camss/camss-csid-gen2.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-04-26 02:27:13 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2023-04-26 02:27:13 +0300
commit4ea956963f4fca59050a22fcc65f00a85d586e63 (patch)
tree6fc32daed4499e7b98b9ce465a884f56882905de /drivers/media/platform/qcom/camss/camss-csid-gen2.c
parentc8cc58e289ed3b5bc50258f52776cf3dfa3bad66 (diff)
parent73b41dc51fbeffa4a216b20193274cfe92b5d95b (diff)
downloadlinux-4ea956963f4fca59050a22fcc65f00a85d586e63.tar.xz
Merge tag 'media/v6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - Removal of some old unused sensor drivers: ad9389b, m5mols, mt9m032, mt9t001, noon010pc30, s5k6aa, sr030pc30 and vs6624 - New i.MX8 image sensor interface driver - Some new RC keymaps - lots of cleanups at atomisp driver to make it support standard features present on other webcam drivers - the cx18 and saa7146 now uses VB2 - lots of cleanups and driver improvements * tag 'media/v6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (460 commits) media: ov5670: Fix probe on ACPI media: nxp: imx8-isi: Remove 300ms sleep after enabling channel media: nxp: imx8-isi: Replace udelay() with fsleep() media: nxp: imx8-isi: Drop partial support for i.MX8QM and i.MX8QXP media: nxp: Add i.MX8 ISI driver media: dt-bindings: media: Add i.MX8 ISI DT bindings media: atomisp: gmin_platform: Add Lenovo Ideapad Miix 310 gmin_vars media: atomisp: gmin_platform: Make DMI quirks take precedence over the _DSM table media: atomisp: Remove struct atomisp_sub_device index field media: atomisp: Drop support for streaming from 2 sensors at once media: atomisp: Remove atomisp_try_fmt() call from atomisp_set_fmt() media: atomisp: Remove unused ATOM_ISP_MAX_WIDTH_TMP and ATOM_ISP_MAX_HEIGHT_TMP media: atomisp: Remove snr_mbus_fmt local var from atomisp_try_fmt() media: atomisp: Remove custom V4L2_CID_FMT_AUTO control media: atomisp: Remove continuous mode related code from atomisp_set_fmt() media: atomisp: Remove duplicate atomisp_[start|stop]_streaming() prototypes media: atomisp: gc0310: Switch over to ACPI powermanagement media: atomisp: gc0310: Use devm_kzalloc() for data struct media: atomisp: gc0310: Add runtime-pm support media: atomisp: gc0310: Delay power-on till streaming is started ...
Diffstat (limited to 'drivers/media/platform/qcom/camss/camss-csid-gen2.c')
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid-gen2.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen2.c b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
index 2031bde13a93..0f8ac29d038d 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-gen2.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
@@ -334,13 +334,14 @@ static const struct csid_format csid_formats[] = {
},
};
-static void csid_configure_stream(struct csid_device *csid, u8 enable)
+static void __csid_configure_stream(struct csid_device *csid, u8 enable, u8 vc)
{
struct csid_testgen_config *tg = &csid->testgen;
u32 val;
u32 phy_sel = 0;
u8 lane_cnt = csid->phy.lane_cnt;
- struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_SRC];
+ /* Source pads matching RDI channels on hardware. Pad 1 -> RDI0, Pad 2 -> RDI1, etc. */
+ struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc];
const struct csid_format *format = csid_get_fmt_entry(csid->formats, csid->nformats,
input_format->code);
@@ -351,8 +352,7 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
phy_sel = csid->phy.csiphy_id;
if (enable) {
- u8 vc = 0; /* Virtual Channel 0 */
- u8 dt_id = vc * 4;
+ u8 dt_id = vc;
if (tg->enabled) {
/* Config Test Generator */
@@ -395,42 +395,42 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
val |= format->data_type << RDI_CFG0_DATA_TYPE;
val |= vc << RDI_CFG0_VIRTUAL_CHANNEL;
val |= dt_id << RDI_CFG0_DT_ID;
- writel_relaxed(val, csid->base + CSID_RDI_CFG0(0));
+ writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
/* CSID_TIMESTAMP_STB_POST_IRQ */
val = 2 << RDI_CFG1_TIMESTAMP_STB_SEL;
- writel_relaxed(val, csid->base + CSID_RDI_CFG1(0));
+ writel_relaxed(val, csid->base + CSID_RDI_CFG1(vc));
val = 1;
- writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PERIOD(0));
+ writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PERIOD(vc));
val = 0;
- writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PATTERN(0));
+ writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PATTERN(vc));
val = 1;
- writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(0));
+ writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(vc));
val = 0;
- writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PATTERN(0));
+ writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PATTERN(vc));
val = 1;
- writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PERIOD(0));
+ writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PERIOD(vc));
val = 0;
- writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PATTERN(0));
+ writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PATTERN(vc));
val = 1;
- writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PERIOD(0));
+ writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PERIOD(vc));
val = 0;
- writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PATTERN(0));
+ writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PATTERN(vc));
val = 0;
- writel_relaxed(val, csid->base + CSID_RDI_CTRL(0));
+ writel_relaxed(val, csid->base + CSID_RDI_CTRL(vc));
- val = readl_relaxed(csid->base + CSID_RDI_CFG0(0));
+ val = readl_relaxed(csid->base + CSID_RDI_CFG0(vc));
val |= 1 << RDI_CFG0_ENABLE;
- writel_relaxed(val, csid->base + CSID_RDI_CFG0(0));
+ writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
}
if (tg->enabled) {
@@ -456,7 +456,16 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
val = HALT_CMD_RESUME_AT_FRAME_BOUNDARY << RDI_CTRL_HALT_CMD;
else
val = HALT_CMD_HALT_AT_FRAME_BOUNDARY << RDI_CTRL_HALT_CMD;
- writel_relaxed(val, csid->base + CSID_RDI_CTRL(0));
+ writel_relaxed(val, csid->base + CSID_RDI_CTRL(vc));
+}
+
+static void csid_configure_stream(struct csid_device *csid, u8 enable)
+{
+ u8 i;
+ /* Loop through all enabled VCs and configure stream for each */
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
+ if (csid->phy.en_vc & BIT(i))
+ __csid_configure_stream(csid, enable, i);
}
static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)
@@ -502,6 +511,7 @@ static irqreturn_t csid_isr(int irq, void *dev)
struct csid_device *csid = dev;
u32 val;
u8 reset_done;
+ int i;
val = readl_relaxed(csid->base + CSID_TOP_IRQ_STATUS);
writel_relaxed(val, csid->base + CSID_TOP_IRQ_CLEAR);
@@ -510,8 +520,12 @@ static irqreturn_t csid_isr(int irq, void *dev)
val = readl_relaxed(csid->base + CSID_CSI2_RX_IRQ_STATUS);
writel_relaxed(val, csid->base + CSID_CSI2_RX_IRQ_CLEAR);
- val = readl_relaxed(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(0));
- writel_relaxed(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(0));
+ /* Read and clear IRQ status for each enabled RDI channel */
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
+ if (csid->phy.en_vc & BIT(i)) {
+ val = readl_relaxed(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i));
+ writel_relaxed(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
+ }
val = 1 << IRQ_CMD_CLEAR;
writel_relaxed(val, csid->base + CSID_IRQ_CMD);