replace common qcom sources with samsung ones
This commit is contained in:
@@ -1,12 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2010-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2025, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk/qcom.h>
|
||||
#include <linux/interconnect.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/version.h>
|
||||
#if (KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE)
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#else
|
||||
#include <linux/qcom_scm.h>
|
||||
#endif
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
@@ -16,10 +22,10 @@
|
||||
#include <linux/msm_kgsl.h>
|
||||
#include <linux/units.h>
|
||||
#include <soc/qcom/dcvs.h>
|
||||
#include <linux/cx_gdsc_debug.h>
|
||||
|
||||
#include "kgsl_device.h"
|
||||
#include "kgsl_bus.h"
|
||||
#include "kgsl_power_trace.h"
|
||||
#include "kgsl_pwrscale.h"
|
||||
#include "kgsl_sysfs.h"
|
||||
#include "kgsl_trace.h"
|
||||
@@ -31,6 +37,8 @@
|
||||
|
||||
#define GX_GDSC_TIMEOUT_MS 200
|
||||
|
||||
#define BUF_SIZE 1000
|
||||
|
||||
/* Order deeply matters here because reasons. New entries go on the end */
|
||||
static const char * const clocks[KGSL_MAX_CLKS] = {
|
||||
"src_clk",
|
||||
@@ -250,7 +258,7 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device,
|
||||
pwr->previous_pwrlevel,
|
||||
pwr->pwrlevels[old_level].gpu_freq);
|
||||
|
||||
KGSL_TRACE_GPU_FREQ(pwrlevel->gpu_freq/1000, 0);
|
||||
trace_gpu_frequency(pwrlevel->gpu_freq/1000, 0);
|
||||
|
||||
/* Update the bus after GPU clock decreases. */
|
||||
if (new_level > old_level)
|
||||
@@ -421,7 +429,7 @@ static void kgsl_pwrctrl_min_pwrlevel_set(struct kgsl_device *device,
|
||||
|
||||
if (level > pwr->min_render_pwrlevel)
|
||||
level = pwr->min_render_pwrlevel;
|
||||
|
||||
|
||||
mutex_lock(&device->mutex);
|
||||
|
||||
/* You can't set a minimum power level lower than the maximum */
|
||||
@@ -1060,6 +1068,91 @@ static ssize_t temp_show(struct device *dev,
|
||||
return _gpu_tmu_show(device, buf);
|
||||
}
|
||||
|
||||
struct reg_pairs {
|
||||
u32 address;
|
||||
char *str;
|
||||
bool secure;
|
||||
};
|
||||
|
||||
static struct reg_pairs pairs[] = {
|
||||
{ 0x3D99080, "GPUCC_GPU_CC_CX_GDSCR", false },
|
||||
{ 0x3D99084, "GPUCC_GPU_CC_CX_CFG_GDSCR", false },
|
||||
{ 0x3D99094, "GPUCC_GPU_CC_CX_HW_CTRL_CFG1_GDSR", false },
|
||||
{ 0x3D99098, "GPUCC_GPU_CC_CX_HW_CTRL_CFG2_GDSR", false },
|
||||
{ 0x3D9909C, "GPUCC_GPU_CC_CX_HW_CTRL_DVM_STATUS_GDSR", false },
|
||||
{ 0x3D990A0, "GPUCC_GPU_CC_CX_HW_CTRL_HALT1_STATUS_GDSR", false },
|
||||
{ 0x3D990A4, "GPUCC_GPU_CC_CX_HW_CTRL_HALT2_STATUS_GDSR", false },
|
||||
{ 0x3D990A8, "GPUCC_GPU_CC_CX_HW_CTRL_REQ_SW_GDSR", false },
|
||||
{ 0x3D990AC, "GPUCC_GPU_CC_CX_HW_CTRL_IRQ_STATUS_GDSR", false },
|
||||
{ 0x3D99550, "GPUCC_GPU_CC_CX_GDS_HW_CTL_SMMU_HALT_STATUS", false },
|
||||
{ 0x3D95004, "GPUCC_GPU_CC_TZ_VOTE_GPU_SMMU_GDS", false },
|
||||
{ 0x3D96004, "GPUCC_GPU_CC_HYP_VOTE_GPU_SMMU_GDS", false },
|
||||
{ 0x3D97004, "GPUCC_GPU_CC_HLOS1_VOTE_GPU_SMMU_GDS", false },
|
||||
{ 0x3D98004, "GPUCC_GPU_CC_SPARE_VOTE_GPU_SMMU_GDS", false },
|
||||
{ 0x3D99088, "GPUCC_GPU_CC_CX_CFG2_GDSCR", false },
|
||||
{ 0x3D9908C, "GPUCC_GPU_CC_CX_CFG3_GDSCR", false },
|
||||
{ 0x3D99090, "GPUCC_GPU_CC_CX_CFG4_GDSCR", false },
|
||||
};
|
||||
|
||||
static void log_debug_data(void)
|
||||
{
|
||||
int i;
|
||||
u32 val;
|
||||
|
||||
for (i = 0; i < (sizeof(pairs) / sizeof(struct reg_pairs)); i++) {
|
||||
void __iomem *tmp;
|
||||
|
||||
if (pairs[i].secure) {
|
||||
qcom_scm_io_readl(pairs[i].address, &val);
|
||||
} else {
|
||||
tmp = ioremap(pairs[i].address, 4);
|
||||
val = __raw_readl(tmp);
|
||||
iounmap(tmp);
|
||||
}
|
||||
|
||||
pr_err("kgsl: register: %s, address: 0x%x, value 0x%x",
|
||||
pairs[i].str, pairs[i].address, val);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t _gpu_info_store(struct kgsl_device *device,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
if (buf == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if ((buf[0] == 'c') && ((buf[1] == '\0') || (buf[1] == '\n'))) {
|
||||
atomic_set(&device->gpu_exception_count[GPU_HANG], 0);
|
||||
atomic_set(&device->gpu_exception_count[GPU_PAGE_FAULT], 0);
|
||||
atomic_set(&device->gpu_exception_count[GPU_TIMEOUT], 0);
|
||||
atomic_set(&device->gpu_exception_count[GPU_PREEMPTION_FAULT], 0);
|
||||
atomic_set(&device->gpu_exception_count[GPU_CXWAIT_TIMEOUT], 0);
|
||||
atomic_set(&device->gpu_exception_count[GPU_HFI_ERROR], 0);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t _gpu_info_show(struct kgsl_device *device,
|
||||
char *buf)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
|
||||
if(buf == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
ret += scnprintf(buf+ret, BUF_SIZE-ret, "\"GHG_Q\":\"%d\",", atomic_read(&device->gpu_exception_count[GPU_HANG]));
|
||||
ret += scnprintf(buf+ret, BUF_SIZE-ret, "\"GPF_Q\":\"%d\",", atomic_read(&device->gpu_exception_count[GPU_PAGE_FAULT]));
|
||||
ret += scnprintf(buf+ret, BUF_SIZE-ret, "\"GTO_Q\":\"%d\",", atomic_read(&device->gpu_exception_count[GPU_TIMEOUT]));
|
||||
ret += scnprintf(buf+ret, BUF_SIZE-ret, "\"PFT_Q\":\"%d\",", atomic_read(&device->gpu_exception_count[GPU_PREEMPTION_FAULT]));
|
||||
ret += scnprintf(buf+ret, BUF_SIZE-ret, "\"CXT_Q\":\"%d\",", atomic_read(&device->gpu_exception_count[GPU_CXWAIT_TIMEOUT]));
|
||||
ret += scnprintf(buf+ret, BUF_SIZE-ret, "\"GHE_Q\":\"%d\"", atomic_read(&device->gpu_exception_count[GPU_HFI_ERROR]));
|
||||
|
||||
buf[ret++] = '\n';
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t pwrscale_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
@@ -1160,6 +1253,7 @@ static GPU_SYSFS_ATTR(gpu_max_clock, 0644, _max_clock_mhz_show,
|
||||
static GPU_SYSFS_ATTR(gpu_clock, 0444, _clock_mhz_show, NULL);
|
||||
static GPU_SYSFS_ATTR(gpu_freq_table, 0444, _freq_table_mhz_show, NULL);
|
||||
static GPU_SYSFS_ATTR(gpu_tmu, 0444, _gpu_tmu_show, NULL);
|
||||
static GPU_SYSFS_ATTR(gpu_info, 0660, _gpu_info_show, _gpu_info_store);
|
||||
|
||||
static const struct attribute *gpu_sysfs_attr_list[] = {
|
||||
&gpu_sysfs_attr_gpu_busy.attr,
|
||||
@@ -1168,6 +1262,7 @@ static const struct attribute *gpu_sysfs_attr_list[] = {
|
||||
&gpu_sysfs_attr_gpu_clock.attr,
|
||||
&gpu_sysfs_attr_gpu_freq_table.attr,
|
||||
&gpu_sysfs_attr_gpu_tmu.attr,
|
||||
&gpu_sysfs_attr_gpu_info.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -1369,12 +1464,18 @@ int kgsl_pwrctrl_enable_cx_gdsc(struct kgsl_device *device)
|
||||
|
||||
ret = wait_for_completion_timeout(&pwr->cx_gdsc_gate, msecs_to_jiffies(5000));
|
||||
if (!ret) {
|
||||
atomic_inc(&device->gpu_exception_count[GPU_CXWAIT_TIMEOUT]);
|
||||
/* Dump the cx regulator consumer list */
|
||||
if (pwr->cx_regulator) {
|
||||
dev_err(device->dev, "GPU CX wait timeout. Dumping CX votes:\n");
|
||||
qcom_clk_dump(NULL, pwr->cx_regulator, false);
|
||||
} else {
|
||||
dev_err(device->dev, "GPU CX wait timeout\n");
|
||||
dev_err(device->dev, "GPU CX wait timeout, Dumping CX votes:\n");
|
||||
print_cx_gdsc_log();
|
||||
qcom_gdsc_pd_dump(pwr->cx_pd);
|
||||
|
||||
/* Dump GPUCC registers */
|
||||
log_debug_data();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1580,8 +1681,18 @@ static int kgsl_cx_gdsc_event(struct notifier_block *nb,
|
||||
|
||||
if (pwr->cx_cfg_gdsc_offset) {
|
||||
if (kgsl_regmap_read_poll_timeout(&device->regmap, pwr->cx_cfg_gdsc_offset,
|
||||
val, (val & BIT(15)), 100, 100 * 1000))
|
||||
val, (val & BIT(15)), 100, 100 * 1000)) {
|
||||
atomic_inc(&device->gpu_exception_count[GPU_CXWAIT_TIMEOUT]);
|
||||
dev_err(device->dev, "GPU CX wait timeout.\n");
|
||||
|
||||
/* Dump GPUCC registers */
|
||||
log_debug_data();
|
||||
|
||||
/* Dump SMMU registers */
|
||||
val = qcom_scm_io_writel(0xdeaddead, 0xdeaddead);
|
||||
if (val)
|
||||
dev_err(device->dev, "SCM write failed, ret = %d", val);
|
||||
}
|
||||
}
|
||||
|
||||
pwr->cx_gdsc_wait = false;
|
||||
@@ -2257,7 +2368,7 @@ static int _wake(struct kgsl_device *device)
|
||||
kgsl_pwrctrl_axi(device, true);
|
||||
kgsl_pwrscale_wake(device);
|
||||
kgsl_pwrctrl_irq(device, true);
|
||||
KGSL_TRACE_GPU_FREQ(
|
||||
trace_gpu_frequency(
|
||||
pwr->pwrlevels[pwr->active_pwrlevel].gpu_freq/1000, 0);
|
||||
|
||||
kgsl_bus_update(device, KGSL_BUS_VOTE_ON);
|
||||
@@ -2348,7 +2459,7 @@ _slumber(struct kgsl_device *device)
|
||||
device->ftbl->stop(device);
|
||||
kgsl_pwrctrl_disable(device);
|
||||
kgsl_pwrscale_sleep(device);
|
||||
KGSL_TRACE_GPU_FREQ(0, 0);
|
||||
trace_gpu_frequency(0, 0);
|
||||
kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
|
||||
break;
|
||||
case KGSL_STATE_SUSPEND:
|
||||
@@ -2358,7 +2469,7 @@ _slumber(struct kgsl_device *device)
|
||||
break;
|
||||
case KGSL_STATE_AWARE:
|
||||
kgsl_pwrctrl_disable(device);
|
||||
KGSL_TRACE_GPU_FREQ(0, 0);
|
||||
trace_gpu_frequency(0, 0);
|
||||
kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
|
||||
break;
|
||||
default:
|
||||
@@ -2460,6 +2571,7 @@ void kgsl_pwrctrl_set_state(struct kgsl_device *device,
|
||||
device->state = state;
|
||||
device->requested_state = KGSL_STATE_NONE;
|
||||
|
||||
cx_gdsc_log("%s: name: %s, state : %d\n", __func__, device->name, state);
|
||||
if (state == KGSL_STATE_SLUMBER)
|
||||
device->pwrctrl.wake_on_touch = false;
|
||||
|
||||
@@ -2474,8 +2586,10 @@ void kgsl_pwrctrl_set_state(struct kgsl_device *device,
|
||||
void kgsl_pwrctrl_request_state(struct kgsl_device *device,
|
||||
unsigned int state)
|
||||
{
|
||||
if (state != KGSL_STATE_NONE && state != device->requested_state)
|
||||
if (state != KGSL_STATE_NONE && state != device->requested_state) {
|
||||
cx_gdsc_log("%s: name: %s, state : %d\n", __func__, device->name, state);
|
||||
trace_kgsl_pwr_request_state(device, state);
|
||||
}
|
||||
device->requested_state = state;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user