# SPDX-License-Identifier: GPL-2.0-only
-imx8-isi-y := imx8-isi-core.o imx8-isi-crossbar.o imx8-isi-hw.o \
- imx8-isi-pipe.o imx8-isi-video.o
+imx8-isi-y := imx8-isi-core.o imx8-isi-crossbar.o imx8-isi-gasket.o \
+ imx8-isi-hw.o imx8-isi-pipe.o imx8-isi-video.o
imx8-isi-$(CONFIG_DEBUG_FS) += imx8-isi-debug.o
imx8-isi-$(CONFIG_VIDEO_IMX8_ISI_M2M) += imx8-isi-m2m.o
.clks = mxc_imx8mn_clks,
.num_clks = ARRAY_SIZE(mxc_imx8mn_clks),
.buf_active_reverse = false,
- .has_gasket = true,
+ .gasket_ops = &mxc_imx8_gasket_ops,
.has_36bit_dma = false,
};
.clks = mxc_imx8mn_clks,
.num_clks = ARRAY_SIZE(mxc_imx8mn_clks),
.buf_active_reverse = true,
- .has_gasket = true,
+ .gasket_ops = &mxc_imx8_gasket_ops,
.has_36bit_dma = true,
};
return PTR_ERR(isi->regs);
}
- if (isi->pdata->has_gasket) {
+ if (isi->pdata->gasket_ops) {
isi->gasket = syscon_regmap_lookup_by_phandle(dev->of_node,
"fsl,blk-ctrl");
if (IS_ERR(isi->gasket)) {
struct mxc_isi_panic_thd panic_set_thd_v;
};
+struct mxc_gasket_ops {
+ void (*enable)(struct mxc_isi_dev *isi,
+ const struct v4l2_mbus_frame_desc *fd,
+ const struct v4l2_mbus_framefmt *fmt,
+ const unsigned int port);
+ void (*disable)(struct mxc_isi_dev *isi, const unsigned int port);
+};
+
enum model {
MXC_ISI_IMX8MN,
MXC_ISI_IMX8MP,
unsigned int reg_offset;
const struct mxc_isi_ier_reg *ier_reg;
const struct mxc_isi_set_thd *set_thd;
+ const struct mxc_gasket_ops *gasket_ops;
const struct clk_bulk_data *clks;
unsigned int num_clks;
bool buf_active_reverse;
- bool has_gasket;
bool has_36bit_dma;
};
struct dentry *debugfs_root;
};
+extern const struct mxc_gasket_ops mxc_imx8_gasket_ops;
+
int mxc_isi_crossbar_init(struct mxc_isi_dev *isi);
void mxc_isi_crossbar_cleanup(struct mxc_isi_crossbar *xbar);
int mxc_isi_crossbar_register(struct mxc_isi_crossbar *xbar);
#include <linux/types.h>
#include <media/media-entity.h>
-#include <media/mipi-csi2.h>
#include <media/v4l2-subdev.h>
#include "imx8-isi-core.h"
return container_of(sd, struct mxc_isi_crossbar, sd);
}
-/* -----------------------------------------------------------------------------
- * Media block control (i.MX8MN and i.MX8MP only)
- */
-#define GASKET_BASE(n) (0x0060 + (n) * 0x30)
-
-#define GASKET_CTRL 0x0000
-#define GASKET_CTRL_DATA_TYPE(dt) ((dt) << 8)
-#define GASKET_CTRL_DATA_TYPE_MASK (0x3f << 8)
-#define GASKET_CTRL_DUAL_COMP_ENABLE BIT(1)
-#define GASKET_CTRL_ENABLE BIT(0)
-
-#define GASKET_HSIZE 0x0004
-#define GASKET_VSIZE 0x0008
-
static int mxc_isi_crossbar_gasket_enable(struct mxc_isi_crossbar *xbar,
struct v4l2_subdev_state *state,
struct v4l2_subdev *remote_sd,
u32 remote_pad, unsigned int port)
{
struct mxc_isi_dev *isi = xbar->isi;
+ const struct mxc_gasket_ops *gasket_ops = isi->pdata->gasket_ops;
const struct v4l2_mbus_framefmt *fmt;
struct v4l2_mbus_frame_desc fd;
- u32 val;
int ret;
- if (!isi->pdata->has_gasket)
+ if (!gasket_ops)
return 0;
/*
if (!fmt)
return -EINVAL;
- regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_HSIZE, fmt->width);
- regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_VSIZE, fmt->height);
-
- val = GASKET_CTRL_DATA_TYPE(fd.entry[0].bus.csi2.dt)
- | GASKET_CTRL_ENABLE;
-
- if (fd.entry[0].bus.csi2.dt == MIPI_CSI2_DT_YUV422_8B)
- val |= GASKET_CTRL_DUAL_COMP_ENABLE;
-
- regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_CTRL, val);
-
+ gasket_ops->enable(isi, &fd, fmt, port);
return 0;
}
unsigned int port)
{
struct mxc_isi_dev *isi = xbar->isi;
+ const struct mxc_gasket_ops *gasket_ops = isi->pdata->gasket_ops;
- if (!isi->pdata->has_gasket)
+ if (!gasket_ops)
return;
- regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_CTRL, 0);
+ gasket_ops->disable(isi, port);
}
/* -----------------------------------------------------------------------------
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019-2023 NXP
+ */
+
+#include <linux/regmap.h>
+
+#include <media/mipi-csi2.h>
+
+#include "imx8-isi-core.h"
+
+/* -----------------------------------------------------------------------------
+ * i.MX8MN and i.MX8MP gasket
+ */
+
+#define GASKET_BASE(n) (0x0060 + (n) * 0x30)
+
+#define GASKET_CTRL 0x0000
+#define GASKET_CTRL_DATA_TYPE(dt) ((dt) << 8)
+#define GASKET_CTRL_DATA_TYPE_MASK (0x3f << 8)
+#define GASKET_CTRL_DUAL_COMP_ENABLE BIT(1)
+#define GASKET_CTRL_ENABLE BIT(0)
+
+#define GASKET_HSIZE 0x0004
+#define GASKET_VSIZE 0x0008
+
+static void mxc_imx8_gasket_enable(struct mxc_isi_dev *isi,
+ const struct v4l2_mbus_frame_desc *fd,
+ const struct v4l2_mbus_framefmt *fmt,
+ const unsigned int port)
+{
+ u32 val;
+
+ regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_HSIZE, fmt->width);
+ regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_VSIZE, fmt->height);
+
+ val = GASKET_CTRL_DATA_TYPE(fd->entry[0].bus.csi2.dt);
+ if (fd->entry[0].bus.csi2.dt == MIPI_CSI2_DT_YUV422_8B)
+ val |= GASKET_CTRL_DUAL_COMP_ENABLE;
+
+ val |= GASKET_CTRL_ENABLE;
+ regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_CTRL, val);
+}
+
+static void mxc_imx8_gasket_disable(struct mxc_isi_dev *isi,
+ const unsigned int port)
+{
+ regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_CTRL, 0);
+}
+
+const struct mxc_gasket_ops mxc_imx8_gasket_ops = {
+ .enable = mxc_imx8_gasket_enable,
+ .disable = mxc_imx8_gasket_disable,
+};