[v3,3/3] media: nxp: imx8-isi: add ISI support for i.MX93
Commit Message
From: "Guoniu.zhou" <guoniu.zhou@nxp.com>
i.MX93 use a different gasket which has different register definition
compared with i.MX8. Hence implement the gasket callbacks in order to
add ISI support for i.MX93.
Signed-off-by: Guoniu.zhou <guoniu.zhou@nxp.com>
---
.../platform/nxp/imx8-isi/imx8-isi-core.c | 20 ++++++++++++++++++
.../platform/nxp/imx8-isi/imx8-isi-core.h | 12 +++++++++++
.../platform/nxp/imx8-isi/imx8-isi-gasket.c | 21 +++++++++++++++++++
3 files changed, 53 insertions(+)
Comments
Hi Guoniu,
Thank you for the patch.
On Tue, Jun 27, 2023 at 02:20:17PM +0800, guoniu.zhou@oss.nxp.com wrote:
> From: "Guoniu.zhou" <guoniu.zhou@nxp.com>
>
> i.MX93 use a different gasket which has different register definition
> compared with i.MX8. Hence implement the gasket callbacks in order to
> add ISI support for i.MX93.
>
> Signed-off-by: Guoniu.zhou <guoniu.zhou@nxp.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> .../platform/nxp/imx8-isi/imx8-isi-core.c | 20 ++++++++++++++++++
> .../platform/nxp/imx8-isi/imx8-isi-core.h | 12 +++++++++++
> .../platform/nxp/imx8-isi/imx8-isi-gasket.c | 21 +++++++++++++++++++
> 3 files changed, 53 insertions(+)
>
> diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
> index d645b2f6fa5a..24c40e4cfef5 100644
> --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
> +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
> @@ -313,6 +313,25 @@ static const struct mxc_isi_plat_data mxc_imx8mp_data = {
> .has_36bit_dma = true,
> };
>
> +static const struct mxc_gasket_ops mxc_imx93_gasket_ops = {
> + .enable = mxc_imx93_gasket_enable,
> + .disable = mxc_imx93_gasket_disable,
> +};
> +
> +static const struct mxc_isi_plat_data mxc_imx93_data = {
> + .model = MXC_ISI_IMX93,
> + .num_ports = 1,
> + .num_channels = 1,
> + .reg_offset = 0,
> + .ier_reg = &mxc_imx8_isi_ier_v2,
> + .set_thd = &mxc_imx8_isi_thd_v1,
> + .clks = mxc_imx8mn_clks,
> + .num_clks = ARRAY_SIZE(mxc_imx8mn_clks),
> + .buf_active_reverse = true,
> + .gasket_ops = &mxc_imx93_gasket_ops,
> + .has_36bit_dma = false,
> +};
> +
> /* -----------------------------------------------------------------------------
> * Power management
> */
> @@ -524,6 +543,7 @@ static int mxc_isi_remove(struct platform_device *pdev)
> static const struct of_device_id mxc_isi_of_match[] = {
> { .compatible = "fsl,imx8mn-isi", .data = &mxc_imx8mn_data },
> { .compatible = "fsl,imx8mp-isi", .data = &mxc_imx8mp_data },
> + { .compatible = "fsl,imx93-isi", .data = &mxc_imx93_data },
> { /* sentinel */ },
> };
> MODULE_DEVICE_TABLE(of, mxc_isi_of_match);
> diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h
> index 4f920d650153..f5be5394981e 100644
> --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h
> +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h
> @@ -73,6 +73,11 @@ struct v4l2_m2m_dev;
> #define GASKET_HSIZE 0x0004
> #define GASKET_VSIZE 0x0008
>
> +/* dispmix_GPR register (i.MX93 only) */
> +#define DISP_MIX_CAMERA_MUX 0x30
> +#define DISP_MIX_CAMERA_MUX_DATA_TYPE(x) (((x) & 0x3f) << 3)
> +#define DISP_MIX_CAMERA_MUX_GASKET_ENABLE BIT(16)
> +
> struct mxc_isi_dev;
> struct mxc_isi_m2m_ctx;
>
> @@ -172,6 +177,7 @@ struct mxc_gasket_ops {
> enum model {
> MXC_ISI_IMX8MN,
> MXC_ISI_IMX8MP,
> + MXC_ISI_IMX93,
> };
>
> struct mxc_isi_plat_data {
> @@ -407,6 +413,12 @@ int mxc_imx8_gasket_enable(struct mxc_isi_dev *isi,
> const unsigned int port);
> void mxc_imx8_gasket_disable(struct mxc_isi_dev *isi, const unsigned int port);
>
> +int mxc_imx93_gasket_enable(struct mxc_isi_dev *isi,
> + const struct v4l2_mbus_frame_desc *fd,
> + const struct v4l2_mbus_framefmt *fmt,
> + const unsigned int port);
> +void mxc_imx93_gasket_disable(struct mxc_isi_dev *isi, const unsigned int port);
> +
> #if IS_ENABLED(CONFIG_DEBUG_FS)
> void mxc_isi_debug_init(struct mxc_isi_dev *isi);
> void mxc_isi_debug_cleanup(struct mxc_isi_dev *isi);
> diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-gasket.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-gasket.c
> index 39f8d0e8b15d..a81c4249a26f 100644
> --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-gasket.c
> +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-gasket.c
> @@ -30,3 +30,24 @@ void mxc_imx8_gasket_disable(struct mxc_isi_dev *isi, const unsigned int port)
> {
> regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_CTRL, 0);
> }
> +
> +/* Configure and enable gasket for i.MX93 */
> +int mxc_imx93_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;
> +
> + val = DISP_MIX_CAMERA_MUX_DATA_TYPE(fd->entry[0].bus.csi2.dt);
> + val |= DISP_MIX_CAMERA_MUX_GASKET_ENABLE;
> + regmap_write(isi->gasket, DISP_MIX_CAMERA_MUX, val);
> +
> + return 0;
> +}
> +
> +void mxc_imx93_gasket_disable(struct mxc_isi_dev *isi,
> + unsigned int port)
> +{
> + regmap_write(isi->gasket, DISP_MIX_CAMERA_MUX, 0);
> +}
@@ -313,6 +313,25 @@ static const struct mxc_isi_plat_data mxc_imx8mp_data = {
.has_36bit_dma = true,
};
+static const struct mxc_gasket_ops mxc_imx93_gasket_ops = {
+ .enable = mxc_imx93_gasket_enable,
+ .disable = mxc_imx93_gasket_disable,
+};
+
+static const struct mxc_isi_plat_data mxc_imx93_data = {
+ .model = MXC_ISI_IMX93,
+ .num_ports = 1,
+ .num_channels = 1,
+ .reg_offset = 0,
+ .ier_reg = &mxc_imx8_isi_ier_v2,
+ .set_thd = &mxc_imx8_isi_thd_v1,
+ .clks = mxc_imx8mn_clks,
+ .num_clks = ARRAY_SIZE(mxc_imx8mn_clks),
+ .buf_active_reverse = true,
+ .gasket_ops = &mxc_imx93_gasket_ops,
+ .has_36bit_dma = false,
+};
+
/* -----------------------------------------------------------------------------
* Power management
*/
@@ -524,6 +543,7 @@ static int mxc_isi_remove(struct platform_device *pdev)
static const struct of_device_id mxc_isi_of_match[] = {
{ .compatible = "fsl,imx8mn-isi", .data = &mxc_imx8mn_data },
{ .compatible = "fsl,imx8mp-isi", .data = &mxc_imx8mp_data },
+ { .compatible = "fsl,imx93-isi", .data = &mxc_imx93_data },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, mxc_isi_of_match);
@@ -73,6 +73,11 @@ struct v4l2_m2m_dev;
#define GASKET_HSIZE 0x0004
#define GASKET_VSIZE 0x0008
+/* dispmix_GPR register (i.MX93 only) */
+#define DISP_MIX_CAMERA_MUX 0x30
+#define DISP_MIX_CAMERA_MUX_DATA_TYPE(x) (((x) & 0x3f) << 3)
+#define DISP_MIX_CAMERA_MUX_GASKET_ENABLE BIT(16)
+
struct mxc_isi_dev;
struct mxc_isi_m2m_ctx;
@@ -172,6 +177,7 @@ struct mxc_gasket_ops {
enum model {
MXC_ISI_IMX8MN,
MXC_ISI_IMX8MP,
+ MXC_ISI_IMX93,
};
struct mxc_isi_plat_data {
@@ -407,6 +413,12 @@ int mxc_imx8_gasket_enable(struct mxc_isi_dev *isi,
const unsigned int port);
void mxc_imx8_gasket_disable(struct mxc_isi_dev *isi, const unsigned int port);
+int mxc_imx93_gasket_enable(struct mxc_isi_dev *isi,
+ const struct v4l2_mbus_frame_desc *fd,
+ const struct v4l2_mbus_framefmt *fmt,
+ const unsigned int port);
+void mxc_imx93_gasket_disable(struct mxc_isi_dev *isi, const unsigned int port);
+
#if IS_ENABLED(CONFIG_DEBUG_FS)
void mxc_isi_debug_init(struct mxc_isi_dev *isi);
void mxc_isi_debug_cleanup(struct mxc_isi_dev *isi);
@@ -30,3 +30,24 @@ void mxc_imx8_gasket_disable(struct mxc_isi_dev *isi, const unsigned int port)
{
regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_CTRL, 0);
}
+
+/* Configure and enable gasket for i.MX93 */
+int mxc_imx93_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;
+
+ val = DISP_MIX_CAMERA_MUX_DATA_TYPE(fd->entry[0].bus.csi2.dt);
+ val |= DISP_MIX_CAMERA_MUX_GASKET_ENABLE;
+ regmap_write(isi->gasket, DISP_MIX_CAMERA_MUX, val);
+
+ return 0;
+}
+
+void mxc_imx93_gasket_disable(struct mxc_isi_dev *isi,
+ unsigned int port)
+{
+ regmap_write(isi->gasket, DISP_MIX_CAMERA_MUX, 0);
+}