diff --git a/drivers/media/platform/rockchip/isp/csi.c b/drivers/media/platform/rockchip/isp/csi.c index a747d6737010..c7a288c71f59 100644 --- a/drivers/media/platform/rockchip/isp/csi.c +++ b/drivers/media/platform/rockchip/isp/csi.c @@ -15,7 +15,7 @@ #include "isp_external.h" #include "regs.h" -static void get_remote_mipi_sensor(struct rkisp_device *dev, +void rkisp_get_remote_mipi_sensor(struct rkisp_device *dev, struct v4l2_subdev **sensor_sd, u32 function) { struct media_graph graph; @@ -210,7 +210,7 @@ static int csi_config(struct rkisp_csi_device *csi) emd_vc = 0xFF; emd_dt = 0; dev->hdr.sensor = NULL; - get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR); + rkisp_get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR); if (mipi_sensor) { ctrl = v4l2_ctrl_find(mipi_sensor->ctrl_handler, CIFISP_CID_EMB_VC); @@ -546,7 +546,7 @@ int rkisp_csi_get_hdr_cfg(struct rkisp_device *dev, void *arg) } return 0; } - get_remote_mipi_sensor(dev, &sd, type); + rkisp_get_remote_mipi_sensor(dev, &sd, type); if (!sd) { v4l2_err(&dev->v4l2_dev, "%s don't find subdev\n", __func__); return -EINVAL; @@ -577,7 +577,7 @@ int rkisp_csi_config_patch(struct rkisp_device *dev) memset(&mode, 0, sizeof(mode)); mode.name = dev->name; - get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_PROC_VIDEO_COMPOSER); + rkisp_get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_PROC_VIDEO_COMPOSER); if (!mipi_sensor) return -EINVAL; dev->hdr.op_mode = HDR_NORMAL; diff --git a/drivers/media/platform/rockchip/isp/csi.h b/drivers/media/platform/rockchip/isp/csi.h index 98bf2511088c..9fbdc35b4405 100644 --- a/drivers/media/platform/rockchip/isp/csi.h +++ b/drivers/media/platform/rockchip/isp/csi.h @@ -80,4 +80,6 @@ void rkisp_unregister_csi_subdev(struct rkisp_device *dev); int rkisp_csi_get_hdr_cfg(struct rkisp_device *dev, void *arg); int rkisp_csi_config_patch(struct rkisp_device *dev); void rkisp_csi_sof(struct rkisp_device *dev, u8 id); +void rkisp_get_remote_mipi_sensor(struct rkisp_device *dev, + struct v4l2_subdev **sensor_sd, u32 function); #endif diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index ed427c7ce3bf..b27522df25fe 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -52,6 +52,7 @@ #include "regs.h" #include "rkisp.h" #include "version.h" +#include "csi.h" #define RKISP_VERNO_LEN 10 @@ -1014,13 +1015,21 @@ static int rkisp_pm_prepare(struct device *dev) unsigned long lock_flags = 0; int i, on = 0, time = 100; - if (isp_dev->isp_state & ISP_STOP) + if (isp_dev->isp_state & ISP_STOP) { + if (pm_runtime_active(dev) && + rkisp_link_sensor(isp_dev->isp_inp)) { + struct v4l2_subdev *mipi_sensor = NULL; + + rkisp_get_remote_mipi_sensor(isp_dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR); + if (mipi_sensor) + v4l2_subdev_call(mipi_sensor, core, s_power, 0); + } return 0; + } isp_dev->suspend_sync = false; isp_dev->is_suspend = true; - if (isp_dev->isp_inp & INP_CSI || - isp_dev->isp_inp & INP_DVP || isp_dev->isp_inp & INP_LVDS) { + if (rkisp_link_sensor(isp_dev->isp_inp)) { for (i = p->num_subdevs - 1; i >= 0; i--) v4l2_subdev_call(p->subdevs[i], video, s_stream, on); } else if (isp_dev->isp_inp & INP_CIF && !(IS_HDR_RDBK(isp_dev->rd_mode))) { @@ -1042,6 +1051,11 @@ static int rkisp_pm_prepare(struct device *dev) wait_for_completion_timeout(&isp_dev->pm_cmpl, msecs_to_jiffies(time)); isp_dev->suspend_sync = false; } + + if (rkisp_link_sensor(isp_dev->isp_inp)) { + for (i = p->num_subdevs - 1; i >= 0; i--) + v4l2_subdev_call(p->subdevs[i], core, s_power, 0); + } return 0; } @@ -1053,8 +1067,17 @@ static void rkisp_pm_complete(struct device *dev) struct rkisp_stream *stream; int i, on = 1; - if (isp_dev->isp_state & ISP_STOP) + if (isp_dev->isp_state & ISP_STOP) { + if (pm_runtime_active(dev) && + rkisp_link_sensor(isp_dev->isp_inp)) { + struct v4l2_subdev *mipi_sensor = NULL; + + rkisp_get_remote_mipi_sensor(isp_dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR); + if (mipi_sensor) + v4l2_subdev_call(mipi_sensor, core, s_power, 1); + } return; + } isp_dev->is_suspend = false; isp_dev->isp_state = ISP_START | ISP_FRAME_END; @@ -1066,8 +1089,10 @@ static void rkisp_pm_complete(struct device *dev) } if (hw->cur_dev_id == isp_dev->dev_id) rkisp_rdbk_trigger_event(isp_dev, T_CMD_QUEUE, NULL); - if (isp_dev->isp_inp & INP_CSI || - isp_dev->isp_inp & INP_DVP || isp_dev->isp_inp & INP_LVDS) { + + if (rkisp_link_sensor(isp_dev->isp_inp)) { + for (i = 0; i < p->num_subdevs; i++) + v4l2_subdev_call(p->subdevs[i], core, s_power, 1); for (i = 0; i < p->num_subdevs; i++) v4l2_subdev_call(p->subdevs[i], video, s_stream, on); } else if (isp_dev->isp_inp & INP_CIF && !(IS_HDR_RDBK(isp_dev->rd_mode))) { diff --git a/drivers/media/platform/rockchip/isp/dev.h b/drivers/media/platform/rockchip/isp/dev.h index fbd1b49e22a0..b5cd72d21bb9 100644 --- a/drivers/media/platform/rockchip/isp/dev.h +++ b/drivers/media/platform/rockchip/isp/dev.h @@ -308,4 +308,8 @@ rkisp_unite_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, rkisp_next_clear_bits(dev, reg, mask, is_direct); } +static inline bool rkisp_link_sensor(u32 isp_inp) +{ + return isp_inp & (INP_CSI | INP_DVP | INP_LVDS); +} #endif