diff --git a/drivers/media/platform/rockchip/isp/hw.c b/drivers/media/platform/rockchip/isp/hw.c index 548e49703a8e..9c391d0e3f6d 100644 --- a/drivers/media/platform/rockchip/isp/hw.c +++ b/drivers/media/platform/rockchip/isp/hw.c @@ -350,6 +350,9 @@ static const struct isp_clk_info rk3568_isp_clk_rate[] = { static const struct isp_clk_info rv1126_isp_clk_rate[] = { { + .clk_rate = 20, + .refer_data = 0, + }, { .clk_rate = 300, .refer_data = 1920, //width }, { @@ -601,6 +604,8 @@ static int enable_sys_clk(struct rkisp_hw_dev *dev) } } + clk_set_rate(dev->clks[0], dev->clk_rate_tbl[0].clk_rate * 1000000UL); + rkisp_soft_reset(dev); isp_config_clk(dev, true); diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 94d9f43f8b2c..1d1bd0349efd 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -972,9 +972,6 @@ static int rkisp_isp_stop(struct rkisp_device *dev) udelay(100); } rkisp_soft_reset(dev->hw_dev); - /* restore the old ispclk after reset */ - if (old_rate != safe_rate) - clk_set_rate(dev->hw_dev->clks[0], old_rate); } rkisp_write(dev, CTRL_VI_ISP_CLK_CTRL, val, true); diff --git a/drivers/media/platform/rockchip/ispp/fec.c b/drivers/media/platform/rockchip/ispp/fec.c index fcf301ea7d60..372b5a43be85 100644 --- a/drivers/media/platform/rockchip/ispp/fec.c +++ b/drivers/media/platform/rockchip/ispp/fec.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd. */ +#include #include #include #include @@ -39,6 +40,10 @@ static int fec_running(struct rkispp_fec_dev *fec, buf->in_fourcc >> 16, buf->in_fourcc >> 24, buf->out_fourcc, buf->out_fourcc >> 8, buf->out_fourcc >> 16, buf->out_fourcc >> 24); + + if (clk_get_rate(fec->hw->clks[0]) <= fec->hw->core_clk_min) + clk_set_rate(fec->hw->clks[0], fec->hw->core_clk_max); + init_completion(&fec->cmpl); density = w > 1920 ? SW_MESH_DENSITY : 0; mesh_size = cal_fec_mesh(w, h, !!density); diff --git a/drivers/media/platform/rockchip/ispp/hw.c b/drivers/media/platform/rockchip/ispp/hw.c index a71765d391c9..6d9842c8e130 100644 --- a/drivers/media/platform/rockchip/ispp/hw.c +++ b/drivers/media/platform/rockchip/ispp/hw.c @@ -108,7 +108,9 @@ static int enable_sys_clk(struct rkispp_hw_dev *dev) i++; if (i > dev->clk_rate_tbl_num - 1) i = dev->clk_rate_tbl_num - 1; - clk_set_rate(dev->clks[0], dev->clk_rate_tbl[i].clk_rate * 1000000UL); + dev->core_clk_max = dev->clk_rate_tbl[i].clk_rate * 1000000; + dev->core_clk_min = dev->clk_rate_tbl[0].clk_rate * 1000000; + clk_set_rate(dev->clks[0], dev->core_clk_min); dev_dbg(dev->dev, "set ispp clk:%luHz\n", clk_get_rate(dev->clks[0])); return 0; err: @@ -149,6 +151,9 @@ static const char * const rv1126_ispp_clks[] = { static const struct ispp_clk_info rv1126_ispp_clk_rate[] = { { + .clk_rate = 20, + .refer_data = 0, + }, { .clk_rate = 250, .refer_data = 1920 //width }, { diff --git a/drivers/media/platform/rockchip/ispp/hw.h b/drivers/media/platform/rockchip/ispp/hw.h index ffc22f2e194a..8600aa019851 100644 --- a/drivers/media/platform/rockchip/ispp/hw.h +++ b/drivers/media/platform/rockchip/ispp/hw.h @@ -41,6 +41,8 @@ struct rkispp_hw_dev { int clks_num; int dev_num; int cur_dev_id; + unsigned long core_clk_min; + unsigned long core_clk_max; enum rkispp_ver ispp_ver; /* lock for irq */ spinlock_t irq_lock; diff --git a/drivers/media/platform/rockchip/ispp/stream.c b/drivers/media/platform/rockchip/ispp/stream.c index 008d9f37f87c..5308b472764e 100644 --- a/drivers/media/platform/rockchip/ispp/stream.c +++ b/drivers/media/platform/rockchip/ispp/stream.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd. */ +#include #include #include #include @@ -1591,6 +1592,7 @@ static void rkispp_stop_streaming(struct vb2_queue *queue) { struct rkispp_stream *stream = queue->drv_priv; struct rkispp_device *dev = stream->isppdev; + struct rkispp_hw_dev *hw = dev->hw_dev; v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev, "%s id:%d enter\n", __func__, stream->id); @@ -1619,6 +1621,9 @@ static void rkispp_stop_streaming(struct vb2_queue *queue) rkispp_free_common_dummy_buf(dev); atomic_dec(&dev->stream_vdev.refcnt); + if (!atomic_read(&hw->refcnt) && + !atomic_read(&dev->stream_vdev.refcnt)) + clk_set_rate(hw->clks[0], hw->core_clk_min); v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev, "%s id:%d exit\n", __func__, stream->id); } @@ -1687,6 +1692,7 @@ static int rkispp_start_streaming(struct vb2_queue *queue, { struct rkispp_stream *stream = queue->drv_priv; struct rkispp_device *dev = stream->isppdev; + struct rkispp_hw_dev *hw = dev->hw_dev; int ret = -1; v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev, @@ -1715,6 +1721,11 @@ static int rkispp_start_streaming(struct vb2_queue *queue, return ret; } + if (!atomic_read(&hw->refcnt) && + !atomic_read(&dev->stream_vdev.refcnt) && + clk_get_rate(hw->clks[0]) <= hw->core_clk_min) + clk_set_rate(hw->clks[0], hw->core_clk_max); + stream->is_upd = false; stream->is_cfg = false; atomic_inc(&dev->stream_vdev.refcnt);