adreno_tz: Fix GPU target frequency calculation for HFR

It seems that the black-box GPU frequency selection algorithm is unaware
of high refresh rates, and assumes a refresh rate of 60 Hz for its
target frequencies. This results in frequencies that are too low being
selected when a higher refresh rate, such as 90 Hz, is used.

To remedy this, multiply the GPU's busy time by a ratio of the current
refresh rate to 60 Hz. This makes msm-adreno-tz select the right
frequencies needed to avoid stuttering.

Change-Id: Id8b2f025ce9f74faa20ecbee42f27d69fd74f7de
[ghostrider-reborn: support dfps]
Signed-off-by: Adithya R <gh0strider.2k18.reborn@gmail.com>
This commit is contained in:
Sultan Alsawaf
2021-07-15 15:48:55 +09:00
committed by Wiktor Rudzki
parent ace35293c8
commit d429f1b5c0
3 changed files with 29 additions and 0 deletions

View File

@@ -15,6 +15,9 @@
#include <linux/mm.h>
#include <linux/qcom_scm.h>
#include <asm/cacheflush.h>
#ifdef CONFIG_QGKI
#include <drm/drm_refresh_rate.h>
#endif
#include <linux/qtee_shmbridge.h>
#include "../../devfreq/governor.h"
@@ -408,6 +411,13 @@ static int tz_get_target_freq(struct devfreq *devfreq, unsigned long *freq)
priv->bin.busy_time > CEILING) {
val = -1 * level;
} else {
#ifdef CONFIG_QGKI
unsigned int refresh_rate = dsi_panel_get_refresh_rate();
if (refresh_rate > 60)
priv->bin.busy_time = priv->bin.busy_time * refresh_rate / 60;
#endif
val = __secure_tz_update_entry3(level, priv->bin.total_time,
priv->bin.busy_time, context_count, priv);
}

View File

@@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020 Sultan Alsawaf <sultan@kerneltoast.com>.
*/
unsigned int dsi_panel_get_refresh_rate(void);

View File

@@ -63,6 +63,8 @@ bool is_skip_op_required(struct dsi_display *display)
return (display->is_cont_splash_enabled || display->trusted_vm_env);
}
static unsigned int cur_refresh_rate = 60;
static void dsi_display_mask_ctrl_error_interrupts(struct dsi_display *display,
u32 mask, bool enable)
{
@@ -7391,6 +7393,10 @@ int dsi_display_validate_mode_change(struct dsi_display *display,
cur_mode->timing.v_front_porch,
adj_mode->timing.v_front_porch);
}
if (cur_mode->timing.refresh_rate != adj_mode->timing.refresh_rate) {
WRITE_ONCE(cur_refresh_rate, adj_mode->timing.refresh_rate);
DSI_DEBUG("cur_refresh_rate set to %d\n", adj_mode->timing.refresh_rate);
}
}
/* dynamic clk change use case */
@@ -8338,6 +8344,11 @@ static void dsi_display_panel_id_notification(struct dsi_display *display)
}
}
unsigned int dsi_panel_get_refresh_rate(void)
{
return READ_ONCE(cur_refresh_rate);
}
int dsi_display_enable(struct dsi_display *display)
{
int rc = 0;
@@ -8380,6 +8391,8 @@ int dsi_display_enable(struct dsi_display *display)
mode = display->panel->cur_mode;
WRITE_ONCE(cur_refresh_rate, mode->timing.refresh_rate);
if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) {
rc = dsi_panel_post_switch(display->panel);
if (rc) {