Commit f48498ad authored by Guoniu.zhou's avatar Guoniu.zhou Committed by Mauro Carvalho Chehab
Browse files

media: nxp: imx8-isi: Move i.MX8 gasket configuration to an ops structure



The i.MX93 includes an ISI instance compatible with the imx8-isi
driver, but with a different gasket. To prepare for this, make the
gasket configuration modular by moving the code to an ops structure.

Signed-off-by: default avatarGuoniu.zhou <guoniu.zhou@nxp.com>
Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent 0ac186e3
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
# 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

+3 −3
Original line number Diff line number Diff line
@@ -289,7 +289,7 @@ static const struct mxc_isi_plat_data mxc_imx8mn_data = {
	.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,
};

@@ -303,7 +303,7 @@ static const struct mxc_isi_plat_data mxc_imx8mp_data = {
	.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,
};

@@ -443,7 +443,7 @@ static int mxc_isi_probe(struct platform_device *pdev)
		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)) {
+11 −1
Original line number Diff line number Diff line
@@ -147,6 +147,14 @@ struct mxc_isi_set_thd {
	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,
@@ -159,10 +167,10 @@ struct mxc_isi_plat_data {
	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;
};

@@ -286,6 +294,8 @@ struct mxc_isi_dev {
	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);
+6 −30
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@
#include <linux/types.h>

#include <media/media-entity.h>
#include <media/mipi-csi2.h>
#include <media/v4l2-subdev.h>

#include "imx8-isi-core.h"
@@ -25,32 +24,18 @@ static inline struct mxc_isi_crossbar *to_isi_crossbar(struct v4l2_subdev *sd)
	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;

	/*
@@ -77,17 +62,7 @@ static int mxc_isi_crossbar_gasket_enable(struct mxc_isi_crossbar *xbar,
	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;
}

@@ -95,11 +70,12 @@ static void mxc_isi_crossbar_gasket_disable(struct mxc_isi_crossbar *xbar,
					    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);
}

/* -----------------------------------------------------------------------------
+54 −0
Original line number Diff line number Diff line
// 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,
};