drm/msm: support backoff time update only in sde rsc
SDE RSC driver updates the complete RSC configuration when
client requests for only timer updates like static wrapper
or pdc/rsc backoff time. This may reset unintentional settings
on SDE rsc while client calls it during dynamic resolution
switch or inline rotation. This patch adds a new API to update
only timer configuration on sde rsc with new client settings.
Change-Id: I15c0e75cc4008431dc622dcf29085e9839dee15d
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/sde_rsc.c b/drivers/gpu/drm/msm/sde_rsc.c
index 0418644..7a52ece 100644
--- a/drivers/gpu/drm/msm/sde_rsc.c
+++ b/drivers/gpu/drm/msm/sde_rsc.c
@@ -404,7 +404,13 @@
/* mode 2 is infinite */
rsc->timer_config.rsc_time_slot_2_ns = 0xFFFFFFFF;
- if (rsc->hw_ops.init) {
+ /* timer update should be called with client call */
+ if (cmd_config && rsc->hw_ops.timer_update) {
+ ret = rsc->hw_ops.timer_update(rsc);
+ if (ret)
+ pr_err("sde rsc: hw timer update failed ret:%d\n", ret);
+ /* rsc init should be called during rsc probe - one time only */
+ } else if (rsc->hw_ops.init) {
ret = rsc->hw_ops.init(rsc);
if (ret)
pr_err("sde rsc: hw init failed ret:%d\n", ret);
@@ -917,7 +923,7 @@
end:
mutex_unlock(&rsc->client_lock);
- if (blen < 0)
+ if (blen <= 0)
return 0;
if (copy_to_user(buf, buffer, blen))
@@ -1009,7 +1015,7 @@
end:
mutex_unlock(&rsc->client_lock);
- if (blen < 0)
+ if (blen <= 0)
return 0;
if (copy_to_user(buf, buffer, blen))
diff --git a/drivers/gpu/drm/msm/sde_rsc_hw.c b/drivers/gpu/drm/msm/sde_rsc_hw.c
index 4b61def..b474d21 100644
--- a/drivers/gpu/drm/msm/sde_rsc_hw.c
+++ b/drivers/gpu/drm/msm/sde_rsc_hw.c
@@ -296,6 +296,47 @@
return 0;
}
+static int rsc_hw_timer_update(struct sde_rsc_priv *rsc)
+{
+ if (!rsc) {
+ pr_debug("invalid input param\n");
+ return -EINVAL;
+ }
+
+ pr_debug("rsc hw timer update\n");
+
+ dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_1_DRV0,
+ rsc->timer_config.rsc_time_slot_0_ns, rsc->debug_mode);
+ dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_2_DRV0,
+ rsc->timer_config.rsc_time_slot_1_ns, rsc->debug_mode);
+ dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_3_DRV0,
+ rsc->timer_config.rsc_time_slot_2_ns, rsc->debug_mode);
+
+ dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM2_DRV0_MODE0,
+ rsc->timer_config.rsc_backoff_time_ns, rsc->debug_mode);
+ dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM3_DRV0_MODE0,
+ rsc->timer_config.pdc_backoff_time_ns, rsc->debug_mode);
+
+ dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM2_DRV0_MODE1,
+ rsc->timer_config.rsc_backoff_time_ns, rsc->debug_mode);
+ dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM3_DRV0_MODE1,
+ rsc->timer_config.pdc_backoff_time_ns, rsc->debug_mode);
+
+ dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM3_DRV0_MODE2,
+ rsc->timer_config.pdc_backoff_time_ns, rsc->debug_mode);
+
+ dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_STATIC_WAKEUP_0,
+ rsc->timer_config.static_wakeup_time_ns, rsc->debug_mode);
+
+ dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_RSCC_MODE_THRESHOLD,
+ rsc->timer_config.rsc_mode_threshold_time_ns, rsc->debug_mode);
+
+ /* make sure that hw timers are updated */
+ wmb();
+
+ return 0;
+}
+
static int sde_rsc_mode2_exit(struct sde_rsc_priv *rsc,
enum sde_rsc_state state)
{
@@ -755,6 +796,7 @@
pr_debug("rsc hardware register\n");
rsc->hw_ops.init = rsc_hw_init;
+ rsc->hw_ops.timer_update = rsc_hw_timer_update;
rsc->hw_ops.tcs_wait = rsc_hw_tcs_wait;
rsc->hw_ops.tcs_use_ok = rsc_hw_tcs_use_ok;
diff --git a/drivers/gpu/drm/msm/sde_rsc_priv.h b/drivers/gpu/drm/msm/sde_rsc_priv.h
index fe338d37..c96ce75 100644
--- a/drivers/gpu/drm/msm/sde_rsc_priv.h
+++ b/drivers/gpu/drm/msm/sde_rsc_priv.h
@@ -66,6 +66,8 @@
* struct sde_rsc_hw_ops - sde resource state coordinator hardware ops
* @init: Initialize the sequencer, solver, qtimer,
etc. hardware blocks on RSC.
+ * @timer_update: update the static wrapper time and pdc/rsc
+ backoff time.
* @tcs_wait: Waits for TCS block OK to allow sending a
* TCS command.
* @hw_vsync: Enables the vsync on RSC block.
@@ -79,6 +81,7 @@
struct sde_rsc_hw_ops {
int (*init)(struct sde_rsc_priv *rsc);
+ int (*timer_update)(struct sde_rsc_priv *rsc);
int (*tcs_wait)(struct sde_rsc_priv *rsc);
int (*hw_vsync)(struct sde_rsc_priv *rsc, enum rsc_vsync_req request,
char *buffer, int buffer_size, u32 mode);