From: Guoniu Zhou <guoniu.zhou@xxxxxxx> Add suspend/resume support for ISI when work at memory to memory mode. Signed-off-by: Guoniu Zhou <guoniu.zhou@xxxxxxx> --- .../platform/nxp/imx8-isi/imx8-isi-core.c | 8 ++++ .../platform/nxp/imx8-isi/imx8-isi-core.h | 11 +++++ .../platform/nxp/imx8-isi/imx8-isi-m2m.c | 48 +++++++++++++++++++ 3 files changed, 67 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 528e723114d5..35a771714614 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c @@ -347,6 +347,7 @@ static int mxc_isi_pm_suspend(struct device *dev) struct mxc_isi_pipe *pipe = &isi->pipes[i]; mxc_isi_video_suspend(pipe); + mxc_isi_m2m_suspend(pipe); } return pm_runtime_force_suspend(dev); @@ -376,6 +377,13 @@ static int mxc_isi_pm_resume(struct device *dev) */ err = ret; } + + ret = mxc_isi_m2m_resume(pipe); + if (ret) { + dev_err(dev, "Failed to resume ISI%u (%d) for m2m\n", i, + ret); + err = ret; + } } return err; 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 9c7fe9e5f941..895b47ef4658 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h @@ -343,6 +343,8 @@ int mxc_isi_video_buffer_prepare(struct mxc_isi_dev *isi, struct vb2_buffer *vb2 #ifdef CONFIG_VIDEO_IMX8_ISI_M2M int mxc_isi_m2m_register(struct mxc_isi_dev *isi, struct v4l2_device *v4l2_dev); int mxc_isi_m2m_unregister(struct mxc_isi_dev *isi); +void mxc_isi_m2m_suspend(struct mxc_isi_pipe *pipe); +int mxc_isi_m2m_resume(struct mxc_isi_pipe *pipe); #else static inline int mxc_isi_m2m_register(struct mxc_isi_dev *isi, struct v4l2_device *v4l2_dev) @@ -353,6 +355,15 @@ static inline int mxc_isi_m2m_unregister(struct mxc_isi_dev *isi) { return 0; } + +static inline void mxc_isi_m2m_suspend(struct mxc_isi_pipe *pipe) +{ +} + +static inline int mxc_isi_m2m_resume(struct mxc_isi_pipe *pipe) +{ + return 0; +} #endif int mxc_isi_channel_acquire(struct mxc_isi_pipe *pipe, diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c index 9745d6219a16..2d10c0639096 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c @@ -722,6 +722,54 @@ static const struct v4l2_file_operations mxc_isi_m2m_fops = { .mmap = v4l2_m2m_fop_mmap, }; +/* ----------------------------------------------------------------------------- + * Suspend & resume + */ + +void mxc_isi_m2m_suspend(struct mxc_isi_pipe *pipe) +{ + struct mxc_isi_m2m *m2m = &pipe->isi->m2m; + struct mxc_isi_m2m_ctx *ctx = m2m->last_ctx; + + /* + * Check pipe for ISI memory to memory since only + * channel 0 support this feature. + */ + if (m2m->pipe != pipe || m2m->usage_count == 0) + return; + + v4l2_m2m_suspend(m2m->m2m_dev); + + if (ctx->chained) + mxc_isi_channel_unchain(pipe); + + mxc_isi_channel_disable(pipe); + mxc_isi_channel_put(pipe); +} + +int mxc_isi_m2m_resume(struct mxc_isi_pipe *pipe) +{ + struct mxc_isi_m2m *m2m = &pipe->isi->m2m; + struct mxc_isi_m2m_ctx *ctx = m2m->last_ctx; + + /* + * Check pipe for ISI memory to memory since only + * channel 0 support this feature. + */ + if (m2m->pipe != pipe || m2m->usage_count == 0) + return 0; + + mxc_isi_channel_get(pipe); + + if (ctx->chained) + mxc_isi_channel_chain(pipe, false); + + m2m->last_ctx = NULL; + v4l2_m2m_resume(m2m->m2m_dev); + + return 0; +} + /* ----------------------------------------------------------------------------- * Registration */ -- 2.34.1