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

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
# 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
......
......@@ -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)) {
......
......@@ -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);
......
......@@ -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);
}
/* -----------------------------------------------------------------------------
......
// 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,
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment