mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
Merge "msm: kgsl: Add support for gmu wrapper memory region"
This commit is contained in:
commit
deefc4a259
4 changed files with 171 additions and 8 deletions
|
|
@ -3004,6 +3004,33 @@ static void adreno_regwrite(struct kgsl_device *device,
|
|||
__raw_writel(value, reg);
|
||||
}
|
||||
|
||||
void adreno_read_gmu_wrapper(struct adreno_device *adreno_dev,
|
||||
u32 offsetwords, u32 *val)
|
||||
{
|
||||
if (!adreno_dev->gmu_wrapper_virt)
|
||||
return;
|
||||
|
||||
*val = __raw_readl(adreno_dev->gmu_wrapper_virt +
|
||||
(offsetwords << 2) - adreno_dev->gmu_wrapper_base);
|
||||
/* Order this read with respect to the following memory accesses */
|
||||
rmb();
|
||||
}
|
||||
|
||||
void adreno_write_gmu_wrapper(struct adreno_device *adreno_dev,
|
||||
u32 offsetwords, u32 value)
|
||||
{
|
||||
if (!adreno_dev->gmu_wrapper_virt)
|
||||
return;
|
||||
|
||||
/*
|
||||
* ensure previous writes post before this one,
|
||||
* i.e. act like normal writel()
|
||||
*/
|
||||
wmb();
|
||||
__raw_writel(value, adreno_dev->gmu_wrapper_virt +
|
||||
(offsetwords << 2) - adreno_dev->gmu_wrapper_base);
|
||||
}
|
||||
|
||||
/*
|
||||
* adreno_gmu_fenced_write() - Check if there is a GMU and it is enabled
|
||||
* @adreno_dev: Pointer to the Adreno device that owns the GMU
|
||||
|
|
@ -3378,12 +3405,22 @@ static void adreno_power_stats(struct kgsl_device *device,
|
|||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
struct adreno_busy_data *busy = &adreno_dev->busy_data;
|
||||
int64_t adj = 0;
|
||||
u64 gpu_busy;
|
||||
u64 gpu_busy = 0;
|
||||
unsigned int val;
|
||||
|
||||
memset(stats, 0, sizeof(*stats));
|
||||
|
||||
gpu_busy = counter_delta(device, adreno_dev->perfctr_pwr_lo,
|
||||
&busy->gpu_busy);
|
||||
if (adreno_is_a619_holi(adreno_dev))
|
||||
adreno_read_gmu_wrapper(adreno_dev,
|
||||
adreno_dev->perfctr_pwr_lo, &val);
|
||||
else
|
||||
kgsl_regread(device, adreno_dev->perfctr_pwr_lo, &val);
|
||||
|
||||
if (busy->gpu_busy)
|
||||
gpu_busy = (val >= busy->gpu_busy) ? val - busy->gpu_busy :
|
||||
(~0UL - busy->gpu_busy) + val;
|
||||
|
||||
busy->gpu_busy = val;
|
||||
|
||||
if (gpudev->read_throttling_counters) {
|
||||
adj = gpudev->read_throttling_counters(adreno_dev);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#ifndef __ADRENO_H
|
||||
#define __ADRENO_H
|
||||
|
||||
#include <linux/of.h>
|
||||
#include "adreno_coresight.h"
|
||||
#include "adreno_dispatch.h"
|
||||
#include "adreno_drawctxt.h"
|
||||
|
|
@ -487,6 +488,8 @@ struct adreno_device {
|
|||
unsigned long isense_base;
|
||||
unsigned int isense_len;
|
||||
void __iomem *isense_virt;
|
||||
unsigned long gmu_wrapper_base;
|
||||
void __iomem *gmu_wrapper_virt;
|
||||
const struct adreno_gpu_core *gpucore;
|
||||
struct adreno_firmware fw[2];
|
||||
size_t gpmu_cmds_size;
|
||||
|
|
@ -1124,6 +1127,12 @@ static inline int adreno_is_a650_family(struct adreno_device *adreno_dev)
|
|||
rev == ADRENO_REV_A660);
|
||||
}
|
||||
|
||||
static inline int adreno_is_a619_holi(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return of_device_is_compatible(adreno_dev->dev.pdev->dev.of_node,
|
||||
"qcom,adreno-gpu-a619-holi");
|
||||
}
|
||||
|
||||
static inline int adreno_is_a620v1(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return (ADRENO_GPUREV(adreno_dev) == ADRENO_REV_A620) &&
|
||||
|
|
@ -1252,6 +1261,24 @@ static inline void adreno_write_gmureg(struct adreno_device *adreno_dev,
|
|||
gpudev->reg_offsets[offset_name], val);
|
||||
}
|
||||
|
||||
/**
|
||||
* adreno_read_gmu_wrapper() - Read a GMU wrapper register
|
||||
* @adreno_dev: Pointer to the the adreno device
|
||||
* @offsetwords: Offset of the wrapper register
|
||||
* @val: Register value read is placed here
|
||||
*/
|
||||
void adreno_read_gmu_wrapper(struct adreno_device *adreno_dev,
|
||||
u32 offsetwords, u32 *val);
|
||||
|
||||
/**
|
||||
* adreno_write_gmu_wrapper() - write on a GMU wrapper register
|
||||
* @adreno_dev: Pointer to the the adreno device
|
||||
* @offsetwords: Offset of the wrapper register
|
||||
* @val: value to write on wrapper register
|
||||
*/
|
||||
void adreno_write_gmu_wrapper(struct adreno_device *adreno_dev,
|
||||
u32 offsetwords, u32 value);
|
||||
|
||||
/**
|
||||
* adreno_gpu_fault() - Return the current state of the GPU
|
||||
* @adreno_dev: A pointer to the adreno_device to query
|
||||
|
|
|
|||
|
|
@ -121,10 +121,32 @@ static u32 a615_pwrup_reglist[] = {
|
|||
|
||||
static int a6xx_get_cp_init_cmds(struct adreno_device *adreno_dev);
|
||||
|
||||
static void a6xx_gmu_wrapper_init(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct resource *res;
|
||||
|
||||
if (adreno_dev->gmu_wrapper_virt)
|
||||
return;
|
||||
|
||||
res = platform_get_resource_byname(device->pdev,
|
||||
IORESOURCE_MEM, "gmu_wrapper");
|
||||
if (!res)
|
||||
return;
|
||||
|
||||
adreno_dev->gmu_wrapper_base = res->start - device->reg_phys;
|
||||
adreno_dev->gmu_wrapper_virt = devm_ioremap(&device->pdev->dev,
|
||||
res->start, resource_size(res));
|
||||
|
||||
if (!adreno_dev->gmu_wrapper_virt)
|
||||
dev_warn(device->dev, "gmu_wrapper ioremap failed\n");
|
||||
}
|
||||
|
||||
int a6xx_init(struct adreno_device *adreno_dev)
|
||||
{
|
||||
const struct adreno_a6xx_core *a6xx_core = to_a6xx_core(adreno_dev);
|
||||
|
||||
a6xx_gmu_wrapper_init(adreno_dev);
|
||||
adreno_dev->highest_bank_bit = a6xx_core->highest_bank_bit;
|
||||
|
||||
/* If the memory type is DDR 4, override the existing configuration */
|
||||
|
|
@ -605,10 +627,27 @@ void a6xx_start(struct adreno_device *adreno_dev)
|
|||
* Enable GMU power counter 0 to count GPU busy. This is applicable to
|
||||
* all a6xx targets
|
||||
*/
|
||||
kgsl_regwrite(device, A6XX_GPU_GMU_AO_GPU_CX_BUSY_MASK, 0xff000000);
|
||||
kgsl_regrmw(device, A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0, 0xff, 0x20);
|
||||
kgsl_regwrite(device, A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 0x1);
|
||||
if (adreno_is_a619_holi(adreno_dev)) {
|
||||
unsigned int val;
|
||||
|
||||
adreno_write_gmu_wrapper(adreno_dev,
|
||||
A6XX_GPU_GMU_AO_GPU_CX_BUSY_MASK, 0xff000000);
|
||||
adreno_read_gmu_wrapper(adreno_dev,
|
||||
A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0, &val);
|
||||
adreno_write_gmu_wrapper(adreno_dev,
|
||||
A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0,
|
||||
(val & 0xff) | 0x20);
|
||||
adreno_write_gmu_wrapper(adreno_dev,
|
||||
A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 0x1);
|
||||
|
||||
} else {
|
||||
kgsl_regwrite(device, A6XX_GPU_GMU_AO_GPU_CX_BUSY_MASK,
|
||||
0xff000000);
|
||||
kgsl_regrmw(device, A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0,
|
||||
0xff, 0x20);
|
||||
kgsl_regwrite(device, A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE,
|
||||
0x1);
|
||||
}
|
||||
a6xx_protect_init(adreno_dev);
|
||||
/*
|
||||
* We start LM here because we want all the following to be up
|
||||
|
|
|
|||
|
|
@ -923,6 +923,32 @@ int a6xx_gmu_sptprac_enable(struct adreno_device *adreno_dev)
|
|||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);
|
||||
|
||||
if (adreno_is_a619_holi(adreno_dev)) {
|
||||
u32 val;
|
||||
void __iomem *addr = adreno_dev->gmu_wrapper_virt +
|
||||
(A6XX_GMU_SPTPRAC_PWR_CLK_STATUS << 2) -
|
||||
adreno_dev->gmu_wrapper_base;
|
||||
|
||||
if (!adreno_dev->gmu_wrapper_virt) {
|
||||
dev_err(device->dev,
|
||||
"invalid gmu_wrapper addr, power on SPTPRAC fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
adreno_write_gmu_wrapper(adreno_dev,
|
||||
A6XX_GMU_GX_SPTPRAC_POWER_CONTROL,
|
||||
SPTPRAC_POWERON_CTRL_MASK);
|
||||
|
||||
if (readl_poll_timeout(addr, val,
|
||||
(val & SPTPRAC_POWERON_STATUS_MASK) ==
|
||||
SPTPRAC_POWERON_STATUS_MASK, 10,
|
||||
10 * 1000)) {
|
||||
dev_err(device->dev, "power on SPTPRAC fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!gmu_core_gpmu_isenabled(device) ||
|
||||
!adreno_has_sptprac_gdsc(adreno_dev))
|
||||
return 0;
|
||||
|
|
@ -952,6 +978,35 @@ void a6xx_gmu_sptprac_disable(struct adreno_device *adreno_dev)
|
|||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);
|
||||
|
||||
if (adreno_is_a619_holi(adreno_dev)) {
|
||||
u32 val;
|
||||
void __iomem *addr = adreno_dev->gmu_wrapper_virt +
|
||||
(A6XX_GMU_SPTPRAC_PWR_CLK_STATUS << 2) -
|
||||
adreno_dev->gmu_wrapper_base;
|
||||
|
||||
if (!adreno_dev->gmu_wrapper_virt) {
|
||||
dev_err(device->dev,
|
||||
"invalid gmu_wrapper addr, power off SPTPRAC fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ensure that retention is on */
|
||||
adreno_read_gmu_wrapper(adreno_dev,
|
||||
A6XX_GPU_CC_GX_GDSCR, &val);
|
||||
adreno_write_gmu_wrapper(adreno_dev,
|
||||
A6XX_GPU_CC_GX_GDSCR,
|
||||
(val | A6XX_RETAIN_FF_ENABLE_ENABLE_MASK));
|
||||
adreno_write_gmu_wrapper(adreno_dev,
|
||||
A6XX_GMU_GX_SPTPRAC_POWER_CONTROL,
|
||||
SPTPRAC_POWEROFF_CTRL_MASK);
|
||||
if (readl_poll_timeout(addr, val,
|
||||
(val & SPTPRAC_POWEROFF_STATUS_MASK) ==
|
||||
SPTPRAC_POWEROFF_STATUS_MASK, 10,
|
||||
10 * 1000))
|
||||
dev_err(device->dev, "power off SPTPRAC fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gmu_core_gpmu_isenabled(device) ||
|
||||
!adreno_has_sptprac_gdsc(adreno_dev))
|
||||
return;
|
||||
|
|
@ -996,10 +1051,15 @@ bool a6xx_gmu_sptprac_is_on(struct adreno_device *adreno_dev)
|
|||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
unsigned int val;
|
||||
|
||||
if (!gmu_core_isenabled(device))
|
||||
if (gmu_core_isenabled(device))
|
||||
gmu_core_regread(device, A6XX_GMU_SPTPRAC_PWR_CLK_STATUS,
|
||||
&val);
|
||||
else if (adreno_is_a619_holi(adreno_dev))
|
||||
adreno_read_gmu_wrapper(adreno_dev,
|
||||
A6XX_GMU_SPTPRAC_PWR_CLK_STATUS, &val);
|
||||
else
|
||||
return true;
|
||||
|
||||
gmu_core_regread(device, A6XX_GMU_SPTPRAC_PWR_CLK_STATUS, &val);
|
||||
return !(val & (SPTPRAC_POWER_OFF | SP_CLK_OFF));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue