From f95fc01a9b1b7decbf56d8faca9dfa60d4beae20 Mon Sep 17 00:00:00 2001 From: Narendra Muppalla Date: Wed, 2 Feb 2022 14:26:05 -0800 Subject: [PATCH] disp: msm: avoid BW_INDICATION write if BW does not change This change avoids writing of BW_INDICATION registers on each frame, instead it updates only when there is a change in bandwidth. Change-Id: Iae32ceb065d2e49e81c2febbbac5508a624d090e Signed-off-by: Narendra Muppalla --- msm/sde_rsc.c | 12 +++++++++--- msm/sde_rsc_hw_v3.c | 24 +++++++++++++++++++++++- msm/sde_rsc_priv.h | 20 +++++++++++++++++++- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/msm/sde_rsc.c b/msm/sde_rsc.c index eb2cdd3fd0..8d0b695431 100644 --- a/msm/sde_rsc.c +++ b/msm/sde_rsc.c @@ -1039,7 +1039,6 @@ int sde_rsc_client_trigger_vote(struct sde_rsc_client *caller_client, { int rc = 0, rsc_index, i; struct sde_rsc_priv *rsc; - bool bw_increase = false; if (caller_client && caller_client->rsc_index >= MAX_RSC_COUNT) { pr_err("invalid rsc index\n"); @@ -1051,6 +1050,9 @@ int sde_rsc_client_trigger_vote(struct sde_rsc_client *caller_client, if (!rsc) return -EINVAL; + if (rsc->bwi_update == BW_NO_CHANGE && !delta_vote && rsc->version >= SDE_RSC_REV_5) + return 0; + pr_debug("client:%s trigger bw delta vote:%d\n", caller_client ? caller_client->name : "unknown", delta_vote); @@ -1060,10 +1062,11 @@ int sde_rsc_client_trigger_vote(struct sde_rsc_client *caller_client, (rsc->current_state == SDE_RSC_CLK_STATE)) goto end; + rsc->bwi_update = BW_HIGH_TO_LOW; for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX && delta_vote; i++) { if (rsc->bw_config.new_ab_vote[i] > rsc->bw_config.ab_vote[i] || rsc->bw_config.new_ib_vote[i] > rsc->bw_config.ib_vote[i]) - bw_increase = true; + rsc->bwi_update = BW_LOW_TO_HIGH; rsc->bw_config.ab_vote[i] = rsc->bw_config.new_ab_vote[i]; rsc->bw_config.ib_vote[i] = rsc->bw_config.new_ib_vote[i]; @@ -1092,10 +1095,13 @@ int sde_rsc_client_trigger_vote(struct sde_rsc_client *caller_client, rpmh_write_sleep_and_wake(rsc->rpmh_dev); } + if (rsc->version >= SDE_RSC_REV_5 && !delta_vote) + rsc->bwi_update = BW_NO_CHANGE; + if (rsc->hw_ops.bwi_status && (rsc->current_state == SDE_RSC_CMD_STATE || rsc->current_state == SDE_RSC_VID_STATE)) - rsc->hw_ops.bwi_status(rsc, bw_increase); + rsc->hw_ops.bwi_status(rsc); else if (rsc->hw_ops.tcs_use_ok) rsc->hw_ops.tcs_use_ok(rsc); diff --git a/msm/sde_rsc_hw_v3.c b/msm/sde_rsc_hw_v3.c index 5ab985d8ea..8af4ded6ed 100644 --- a/msm/sde_rsc_hw_v3.c +++ b/msm/sde_rsc_hw_v3.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ @@ -13,6 +14,11 @@ #include "sde_rsc_hw.h" #include "sde_dbg.h" +#define BWI_HIGH_TO_LOW 0x00 +#define BWI_LOW_TO_HIGH 0x01 +#define BWI_NO_CHANGE 0x10 + + static int _rsc_hw_qtimer_init(struct sde_rsc_priv *rsc) { pr_debug("rsc hardware qtimer init\n"); @@ -539,10 +545,26 @@ end: return rc; } -int rsc_hw_bwi_status_v3(struct sde_rsc_priv *rsc, bool bw_indication) +int rsc_hw_bwi_status_v3(struct sde_rsc_priv *rsc) { int count, bw_ack; int rc = 0; + u32 bw_indication = 0; + + switch (rsc->bwi_update) { + case BW_HIGH_TO_LOW: + bw_indication = BWI_HIGH_TO_LOW; + break; + case BW_LOW_TO_HIGH: + bw_indication = BWI_LOW_TO_HIGH; + break; + case BW_NO_CHANGE: + bw_indication = BWI_NO_CHANGE; + break; + default: + pr_err("unsupported bwi data\n"); + break; + } dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_BW_INDICATION, bw_indication, rsc->debug_mode); diff --git a/msm/sde_rsc_priv.h b/msm/sde_rsc_priv.h index 155cd3dc62..5f148e2482 100644 --- a/msm/sde_rsc_priv.h +++ b/msm/sde_rsc_priv.h @@ -94,7 +94,7 @@ struct sde_rsc_hw_ops { int (*hw_vsync)(struct sde_rsc_priv *rsc, enum rsc_vsync_req request, char *buffer, int buffer_size, u32 mode); int (*tcs_use_ok)(struct sde_rsc_priv *rsc); - int (*bwi_status)(struct sde_rsc_priv *rsc, bool bw_indication); + int (*bwi_status)(struct sde_rsc_priv *rsc); bool (*is_amc_mode)(struct sde_rsc_priv *rsc); void (*debug_dump)(struct sde_rsc_priv *rsc, u32 mux_sel); int (*state_update)(struct sde_rsc_priv *rsc, enum sde_rsc_state state); @@ -149,6 +149,22 @@ struct sde_rsc_bw_config { u64 new_ab_vote[SDE_POWER_HANDLE_DBUS_ID_MAX]; u64 new_ib_vote[SDE_POWER_HANDLE_DBUS_ID_MAX]; }; + +/** + * enum sde_rsc_bw_delta bandwidth change + * + * @BW_HIGH_TO_LOW: Bandwidth vote from high to low + * @BW_LOW_TO_HIGH: Bandwidth vote from low to high + * @BW_NO_CHANGE: No change in Bandwidth vote + * @BW_DELTA_MAX: Maximum value + */ +enum sde_rsc_bw_delta { + BW_HIGH_TO_LOW, + BW_LOW_TO_HIGH, + BW_NO_CHANGE, + BW_DELTA_MAX, +}; + /** * struct sde_rsc_priv: sde resource state coordinator(rsc) private handle * @version: rsc sequence version @@ -196,6 +212,7 @@ struct sde_rsc_bw_config { * profiling_supp: Indicates if HW has support for profiling counters * profiling_en: Flag for rsc lpm profiling counters, true=enabled * post_poms: bool if a panel mode change occurred + * bwi_update: enum to indidate a bandwitdh vote change */ struct sde_rsc_priv { u32 version; @@ -241,6 +258,7 @@ struct sde_rsc_priv { bool profiling_en; bool post_poms; + enum sde_rsc_bw_delta bwi_update; }; /**