Merge "msm: kgsl: Use booleans for power control features"

This commit is contained in:
qctecmdr 2020-03-17 13:33:01 -07:00 • committed by Gerrit - the friendly Code Review server
commit 262793ca89
19 changed files with 335 additions and 529 deletions

View file

@ -28,7 +28,6 @@ static const struct adreno_a3xx_core adreno_gpu_core_a306 = {
.gpudev = &adreno_a3xx_gpudev,
.gmem_base = 0,
.gmem_size = SZ_128K,
.busy_mask = 0x7ffffffe,
.bus_width = 0,
.snapshot_size = 600 * SZ_1K,
},
@ -51,7 +50,6 @@ static const struct adreno_a3xx_core adreno_gpu_core_a306a = {
.gpudev = &adreno_a3xx_gpudev,
.gmem_base = 0,
.gmem_size = SZ_128K,
.busy_mask = 0x7ffffffe,
.bus_width = 16,
.snapshot_size = 600 * SZ_1K,
},
@ -72,7 +70,6 @@ static const struct adreno_a3xx_core adreno_gpu_core_a304 = {
.gpudev = &adreno_a3xx_gpudev,
.gmem_base = 0,
.gmem_size = (SZ_64K + SZ_32K),
.busy_mask = 0x7ffffffe,
.bus_width = 0,
.snapshot_size = 600 * SZ_1K,
},
@ -197,7 +194,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a530v2 = {
.gpudev = &adreno_a5xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = SZ_1M,
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = SZ_1M,
},
@ -224,7 +220,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a530v3 = {
.gpudev = &adreno_a5xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = SZ_1M,
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = SZ_1M,
},
@ -291,7 +286,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a505 = {
.gpudev = &adreno_a5xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = (SZ_128K + SZ_8K),
.busy_mask = 0xfffffffe,
.bus_width = 16,
.snapshot_size = SZ_1M,
},
@ -311,7 +305,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a506 = {
.gpudev = &adreno_a5xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = (SZ_128K + SZ_8K),
.busy_mask = 0xfffffffe,
.bus_width = 16,
.snapshot_size = SZ_1M,
},
@ -390,7 +383,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a510 = {
.gpudev = &adreno_a5xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = SZ_256K,
.busy_mask = 0xfffffffe,
.bus_width = 16,
.snapshot_size = SZ_1M,
},
@ -516,7 +508,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a540v2 = {
.gpudev = &adreno_a5xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = SZ_1M,
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = SZ_1M,
},
@ -600,7 +591,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a512 = {
.gpudev = &adreno_a5xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = (SZ_256K + SZ_16K),
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = SZ_1M,
},
@ -620,7 +610,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a508 = {
.gpudev = &adreno_a5xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = (SZ_128K + SZ_8K),
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = SZ_1M,
},
@ -796,7 +785,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a630v2 = {
.gpudev = &adreno_a6xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = SZ_1M,
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = SZ_1M,
},
@ -897,7 +885,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a615 = {
.gpudev = &adreno_a6xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = SZ_512K,
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = 600 * SZ_1K,
},
@ -926,7 +913,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a618 = {
.gpudev = &adreno_a6xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = SZ_512K,
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = SZ_1M,
},
@ -1056,7 +1042,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a620 = {
.gpudev = &adreno_a6xx_gpudev,
.gmem_base = 0,
.gmem_size = SZ_512K,
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = 2 * SZ_1M,
},
@ -1148,7 +1133,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a640 = {
.gpudev = &adreno_a6xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = SZ_1M, //Verified 1MB
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = 2 * SZ_1M,
},
@ -1230,7 +1214,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a650 = {
.gpudev = &adreno_a6xx_gpudev,
.gmem_base = 0,
.gmem_size = SZ_1M + SZ_128K, /* verified 1152kB */
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = 2 * SZ_1M,
},
@ -1261,7 +1244,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a650v2 = {
.gpudev = &adreno_a6xx_gpudev,
.gmem_base = 0,
.gmem_size = SZ_1M + SZ_128K, /* verified 1152kB */
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = 2 * SZ_1M,
},
@ -1289,7 +1271,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a680 = {
.gpudev = &adreno_a6xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = SZ_2M,
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = SZ_1M,
},
@ -1368,7 +1349,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a612 = {
.gpudev = &adreno_a6xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = (SZ_128K + SZ_4K),
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = SZ_1M,
},
@ -1395,7 +1375,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a616 = {
.gpudev = &adreno_a6xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = SZ_512K,
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = SZ_1M,
},
@ -1423,7 +1402,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a610 = {
.gpudev = &adreno_a6xx_gpudev,
.gmem_base = 0x100000,
.gmem_size = (SZ_128K + SZ_4K),
.busy_mask = 0xfffffffe,
.bus_width = 32,
},
.prim_fifo_threshold = 0x00080000,
@ -1537,7 +1515,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a660 = {
.gpudev = &adreno_a6xx_gpudev,
.gmem_base = 0,
.gmem_size = SZ_1M + SZ_512K,
.busy_mask = 0xfffffffe,
.bus_width = 32,
.snapshot_size = SZ_1M,
},

View file

@ -31,6 +31,7 @@
#include "adreno-gpulist.h"
static void adreno_input_work(struct work_struct *work);
static int adreno_soft_reset(struct kgsl_device *device);
static unsigned int counter_delta(struct kgsl_device *device,
unsigned int reg, unsigned int *counter);
@ -500,7 +501,7 @@ static struct input_handler adreno_input_handler = {
* all the HW logic, restores GPU registers to default state and
* flushes out pending VBIF transactions.
*/
static int _soft_reset(struct adreno_device *adreno_dev)
static void _soft_reset(struct adreno_device *adreno_dev)
{
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
unsigned int reg;
@ -517,8 +518,6 @@ static int _soft_reset(struct adreno_device *adreno_dev)
if (gpudev->regulator_enable)
gpudev->regulator_enable(adreno_dev);
return 0;
}
/**
@ -986,7 +985,7 @@ static void adreno_of_get_limits(struct adreno_device *adreno_dev,
pwrctrl->throttle_mask = GENMASK(pwrctrl->num_pwrlevels - 1,
pwrctrl->num_pwrlevels - 1 - throttle_level);
set_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag);
adreno_dev->lm_enabled = true;
}
static int adreno_of_get_legacy_pwrlevels(struct adreno_device *adreno_dev,
@ -1364,13 +1363,6 @@ static void adreno_setup_device(struct adreno_device *adreno_dev)
INIT_WORK(&adreno_dev->input_work, adreno_input_work);
/*
* Enable SPTP power collapse, throttling and hardware clock gating by
* default where applicable
*/
adreno_dev->pwrctrl_flag = BIT(ADRENO_SPTP_PC_CTRL) |
BIT(ADRENO_THROTTLING_CTRL) | BIT(ADRENO_HWCG_CTRL);
INIT_LIST_HEAD(&adreno_dev->active_list);
spin_lock_init(&adreno_dev->active_list_lock);
@ -2315,28 +2307,21 @@ no_gx_power:
int adreno_reset(struct kgsl_device *device, int fault)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
int ret = -EINVAL;
int i = 0;
int i;
if (gpudev->reset)
return gpudev->reset(device, fault);
/*
* Try soft reset first Do not do soft reset for a IOMMU fault (because
* the IOMMU hardware needs a reset too) or for the A304 because it
* can't do SMMU programming of any kind after a soft reset
* the IOMMU hardware needs a reset too)
*/
if (!(fault & ADRENO_IOMMU_PAGE_FAULT) && !adreno_is_a304(adreno_dev)
&& !adreno_is_a612(adreno_dev) && !adreno_is_a610(adreno_dev)) {
/* Make sure VBIF is cleared before resetting */
ret = adreno_clear_pending_transactions(device);
if (!(fault & ADRENO_IOMMU_PAGE_FAULT))
ret = adreno_soft_reset(device);
if (ret == 0) {
ret = adreno_soft_reset(device);
if (ret)
dev_err(device->dev,
"Device soft reset failed: ret=%d\n",
ret);
}
}
if (ret) {
/* If soft reset failed/skipped, then pull the power */
kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);
@ -2346,22 +2331,18 @@ int adreno_reset(struct kgsl_device *device, int fault)
/* Try to reset the device */
ret = adreno_start(device, 0);
/* On some GPUS, keep trying until it works */
if (ret && ADRENO_GPUREV(adreno_dev) < 600) {
for (i = 0; i < NUM_TIMES_RESET_RETRY; i++) {
msleep(20);
ret = adreno_start(device, 0);
if (!ret)
break;
}
for (i = 0; ret && i < NUM_TIMES_RESET_RETRY; i++) {
msleep(20);
ret = adreno_start(device, 0);
}
}
if (ret)
return ret;
if (i != 0)
dev_warn(device->dev,
if (ret)
return ret;
if (i != 0)
dev_warn(device->dev,
"Device hard reset tried %d tries\n", i);
}
/*
* If active_cnt is non-zero then the system was active before
@ -2752,7 +2733,7 @@ static int adreno_setproperty(struct kgsl_device_private *dev_priv,
*
* Returns true if interrupts are pending from device else 0.
*/
inline unsigned int adreno_irq_pending(struct adreno_device *adreno_dev)
bool adreno_irq_pending(struct adreno_device *adreno_dev)
{
unsigned int status;
@ -2767,67 +2748,37 @@ inline unsigned int adreno_irq_pending(struct adreno_device *adreno_dev)
*/
if ((status & adreno_dev->irq_mask) ||
atomic_read(&adreno_dev->pending_irq_refcnt))
return 1;
else
return 0;
return true;
return false;
}
/**
* adreno_hw_isidle() - Check if the GPU core is idle
* @adreno_dev: Pointer to the Adreno device structure for the GPU
*
* Return true if the RBBM status register for the GPU type indicates that the
* hardware is idle
*/
bool adreno_hw_isidle(struct adreno_device *adreno_dev)
{
const struct adreno_gpu_core *gpucore = adreno_dev->gpucore;
unsigned int reg_rbbm_status;
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
/* if hw driver implements idle check - use it */
if (gpudev->hw_isidle)
return gpudev->hw_isidle(adreno_dev);
if (adreno_is_a540(adreno_dev))
/**
* Due to CRC idle throttling GPU
* idle hysteresys can take up to
* 3usec for expire - account for it
*/
udelay(5);
adreno_readreg(adreno_dev, ADRENO_REG_RBBM_STATUS,
&reg_rbbm_status);
if (reg_rbbm_status & gpucore->busy_mask)
return false;
/* Don't consider ourselves idle if there is an IRQ pending */
if (adreno_irq_pending(adreno_dev))
return false;
return true;
}
/**
* adreno_soft_reset() - Do a soft reset of the GPU hardware
/*
* adreno_soft_reset - Do a soft reset of the GPU hardware
* @device: KGSL device to soft reset
*
* "soft reset" the GPU hardware - this is a fast path GPU reset
* The GPU hardware is reset but we never pull power so we can skip
* a lot of the standard adreno_stop/adreno_start sequence
*/
int adreno_soft_reset(struct kgsl_device *device)
static int adreno_soft_reset(struct kgsl_device *device)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
int ret;
ret = gmu_core_dev_oob_set(device, oob_gpu);
if (ret)
/*
* Don't allow a soft reset for a304 because the SMMU needs to be hard
* reset
*/
if (adreno_is_a304(adreno_dev))
return -ENODEV;
ret = adreno_clear_pending_transactions(device);
if (ret) {
dev_err(device->dev, "Timed out while clearing the VBIF\n");
return ret;
}
kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE);
adreno_set_active_ctxs_null(adreno_dev);
@ -2841,15 +2792,7 @@ int adreno_soft_reset(struct kgsl_device *device)
/* save physical performance counter values before GPU soft reset */
adreno_perfcounter_save(adreno_dev);
/* Reset the GPU */
if (gpudev->soft_reset)
ret = gpudev->soft_reset(adreno_dev);
else
ret = _soft_reset(adreno_dev);
if (ret) {
gmu_core_dev_oob_clear(device, oob_gpu);
return ret;
}
_soft_reset(adreno_dev);
/* Clear the busy_data stats - we're starting over from scratch */
adreno_dev->busy_data.gpu_busy = 0;
@ -2889,25 +2832,19 @@ int adreno_soft_reset(struct kgsl_device *device)
/* Restore physical performance counter values after soft reset */
adreno_perfcounter_restore(adreno_dev);
gmu_core_dev_oob_clear(device, oob_gpu);
if (ret)
dev_err(device->dev, "Device soft reset failed: %d\n", ret);
return ret;
}
/*
* adreno_isidle() - return true if the GPU hardware is idle
* @device: Pointer to the KGSL device structure for the GPU
*
* Return true if the GPU hardware is idle and there are no commands pending in
* the ringbuffer
*/
bool adreno_isidle(struct kgsl_device *device)
static bool adreno_isidle(struct adreno_device *adreno_dev)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
struct adreno_ringbuffer *rb;
int i;
if (!kgsl_state_is_awake(device))
if (!kgsl_state_is_awake(KGSL_DEVICE(adreno_dev)))
return true;
/*
@ -2926,7 +2863,7 @@ bool adreno_isidle(struct kgsl_device *device)
return false;
}
return adreno_hw_isidle(adreno_dev);
return gpudev->hw_isidle(adreno_dev);
}
/* Print some key registers if a spin-for-idle times out */
@ -2987,7 +2924,7 @@ int adreno_spin_idle(struct adreno_device *adreno_dev, unsigned int timeout)
if (adreno_gpu_fault(adreno_dev) != 0)
return -EDEADLK;
if (adreno_isidle(KGSL_DEVICE(adreno_dev)))
if (adreno_isidle(adreno_dev))
return 0;
} while (time_before(jiffies, wait));
@ -3000,7 +2937,7 @@ int adreno_spin_idle(struct adreno_device *adreno_dev, unsigned int timeout)
if (adreno_gpu_fault(adreno_dev) != 0)
return -EDEADLK;
if (adreno_isidle(KGSL_DEVICE(adreno_dev)))
if (adreno_isidle(adreno_dev))
return 0;
return -ETIMEDOUT;
@ -3028,7 +2965,7 @@ int adreno_idle(struct kgsl_device *device)
return -EDEADLK;
/* Check if we are already idle before idling dispatcher */
if (adreno_isidle(device))
if (adreno_isidle(adreno_dev))
return 0;
/*
* Wait for dispatcher to finish completing commands
@ -3725,7 +3662,7 @@ static bool adreno_is_hw_collapsible(struct kgsl_device *device)
device->pwrctrl.ctrl_flags)
return false;
return adreno_isidle(device) && (gpudev->is_sptp_idle ?
return adreno_isidle(adreno_dev) && (gpudev->is_sptp_idle ?
gpudev->is_sptp_idle(adreno_dev) : true);
}
@ -3789,7 +3726,7 @@ static bool adreno_is_hwcg_on(struct kgsl_device *device)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
return test_bit(ADRENO_HWCG_CTRL, &adreno_dev->pwrctrl_flag);
return adreno_dev->hwcg_enabled;
}
static int adreno_queue_cmds(struct kgsl_device_private *dev_priv,
@ -3811,7 +3748,6 @@ static const struct kgsl_functable adreno_functable = {
.regread = adreno_regread,
.regwrite = adreno_regwrite,
.idle = adreno_idle,
.isidle = adreno_isidle,
.suspend_context = adreno_suspend_context,
.first_open = adreno_first_open,
.start = adreno_start,

View file

@ -206,12 +206,6 @@ enum adreno_gpurev {
#define ADRENO_CTX_DETATCH_TIMEOUT_FAULT BIT(6)
#define ADRENO_GMU_FAULT_SKIP_SNAPSHOT BIT(7)
#define ADRENO_SPTP_PC_CTRL 0
#define ADRENO_LM_CTRL 1
#define ADRENO_HWCG_CTRL 2
#define ADRENO_THROTTLING_CTRL 3
#define ADRENO_ACD_CTRL 4
/* VBIF, GBIF halt request and ack mask */
#define GBIF_HALT_REQUEST 0x1E0
#define VBIF_RESET_ACK_MASK 0x00f0
@ -340,7 +334,6 @@ struct adreno_reglist {
* @gpudev: Pointer to the GPU family specific functions for this core
* @gmem_base: Base address of binning memory (GMEM/OCMEM)
* @gmem_size: Amount of binning memory (GMEM/OCMEM) to reserve for the core
* @busy_mask: mask to check if GPU is busy in RBBM_STATUS
* @bus_width: Bytes transferred in 1 cycle
*/
struct adreno_gpu_core {
@ -350,7 +343,6 @@ struct adreno_gpu_core {
struct adreno_gpudev *gpudev;
unsigned long gmem_base;
size_t gmem_size;
unsigned int busy_mask;
u32 bus_width;
/** @snapshot_size: Size of the static snapshot region in bytes */
u32 snapshot_size;
@ -413,7 +405,6 @@ struct adreno_gpu_core {
* @halt: Atomic variable to check whether the GPU is currently halted
* @pending_irq_refcnt: Atomic variable to keep track of running IRQ handlers
* @ctx_d_debugfs: Context debugfs node
* @pwrctrl_flag: Flag to hold adreno specific power attributes
* @profile_buffer: Memdesc holding the drawobj profiling buffer
* @profile_index: Index to store the start/stop ticks in the profiling
* buffer
@ -485,8 +476,16 @@ struct adreno_device {
atomic_t halt;
atomic_t pending_irq_refcnt;
struct dentry *ctx_d_debugfs;
unsigned long pwrctrl_flag;
/** @lm_enabled: True if limits management is enabled for this target */
bool lm_enabled;
/** @acd_enabled: True if acd is enabled for this target */
bool acd_enabled;
/** @hwcg_enabled: True if hardware clock gating is enabled */
bool hwcg_enabled;
/** @throttling_enabled: True if LM throttling is enabled on a5xx */
bool throttling_enabled;
/** @sptp_pc_enabled: True if SPTP power collapse is enabled on a5xx */
bool sptp_pc_enabled;
struct kgsl_memdesc *profile_buffer;
unsigned int profile_index;
struct kgsl_memdesc *pwrup_reglist;
@ -643,8 +642,6 @@ enum adreno_regs {
ADRENO_REG_RBBM_INT_0_STATUS,
ADRENO_REG_RBBM_PM_OVERRIDE2,
ADRENO_REG_RBBM_SW_RESET_CMD,
ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD,
ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD2,
ADRENO_REG_RBBM_CLOCK_CTL,
ADRENO_REG_PA_SC_AA_CONFIG,
ADRENO_REG_SQ_GPR_MANAGEMENT,
@ -789,7 +786,6 @@ struct adreno_gpudev {
const char *(*iommu_fault_block)(struct kgsl_device *device,
unsigned int fsynr1);
int (*reset)(struct kgsl_device *device, int fault);
int (*soft_reset)(struct adreno_device *adreno_dev);
bool (*sptprac_is_on)(struct adreno_device *adreno_dev);
unsigned int (*ccu_invalidate)(struct adreno_device *adreno_dev,
unsigned int *cmds);
@ -871,7 +867,6 @@ extern int adreno_wake_nice;
extern unsigned int adreno_wake_timeout;
int adreno_start(struct kgsl_device *device, int priority);
int adreno_soft_reset(struct kgsl_device *device);
long adreno_ioctl(struct kgsl_device_private *dev_priv,
unsigned int cmd, unsigned long arg);
@ -893,7 +888,6 @@ int adreno_switch_to_unsecure_mode(struct adreno_device *adreno_dev,
void adreno_spin_idle_debug(struct adreno_device *adreno_dev, const char *str);
int adreno_spin_idle(struct adreno_device *device, unsigned int timeout);
int adreno_idle(struct kgsl_device *device);
bool adreno_isidle(struct kgsl_device *device);
int adreno_set_constraint(struct kgsl_device *device,
struct kgsl_context *context,
@ -909,8 +903,6 @@ void adreno_fault_skipcmd_detached(struct adreno_device *adreno_dev,
struct adreno_context *drawctxt,
struct kgsl_drawobj *drawobj);
bool adreno_hw_isidle(struct adreno_device *adreno_dev);
void adreno_fault_detect_start(struct adreno_device *adreno_dev);
void adreno_fault_detect_stop(struct adreno_device *adreno_dev);
@ -950,6 +942,13 @@ void adreno_rscc_regread(struct adreno_device *adreno_dev,
void adreno_isense_regread(struct adreno_device *adreno_dev,
unsigned int offsetwords, unsigned int *value);
/**
* adreno_irq_pending - Return true if an interrupt is pending
* @adreno_dev: An Adreno GPU device handle
*
* Returns: true if interrupts are pending on the device
*/
bool adreno_irq_pending(struct adreno_device *adreno_dev);
#define ADRENO_TARGET(_name, _id) \
static inline int adreno_is_##_name(struct adreno_device *adreno_dev) \

View file

@ -1381,6 +1381,19 @@ static irqreturn_t a3xx_irq_handler(struct adreno_device *adreno_dev)
return ret;
}
static bool a3xx_hw_isidle(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
u32 status;
kgsl_regread(device, A3XX_RBBM_STATUS, &status);
if (status & 0x7ffffffe)
return false;
return adreno_irq_pending(adreno_dev) ? false : true;
}
struct adreno_gpudev adreno_a3xx_gpudev = {
.reg_offsets = a3xx_register_offsets,
.ft_perf_counters = a3xx_ft_perf_counters,
@ -1399,4 +1412,5 @@ struct adreno_gpudev adreno_a3xx_gpudev = {
#endif
.clk_set_options = a3xx_clk_set_options,
.read_alwayson = a3xx_read_alwayson,
.hw_isidle = a3xx_hw_isidle,
};

View file

@ -89,7 +89,15 @@ static void a530_efuse_leakage(struct adreno_device *adreno_dev)
static void a5xx_platform_setup(struct adreno_device *adreno_dev)
{
set_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag);
adreno_dev->sptp_pc_enabled =
ADRENO_FEATURE(adreno_dev, ADRENO_SPTP_PC);
if (adreno_is_a540(adreno_dev))
adreno_dev->throttling_enabled = true;
adreno_dev->hwcg_enabled = true;
adreno_dev->lm_enabled =
ADRENO_FEATURE(adreno_dev, ADRENO_LM);
/* Set the GPU busy counter to use for frequency scaling */
adreno_dev->perfctr_pwr_lo = A5XX_RBBM_PERFCTR_RBBM_0_LO;
@ -261,8 +269,7 @@ static bool a5xx_is_sptp_idle(struct adreno_device *adreno_dev)
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
/* If feature is not supported or enabled, no worry */
if (!ADRENO_FEATURE(adreno_dev, ADRENO_SPTP_PC) ||
!test_bit(ADRENO_SPTP_PC_CTRL, &adreno_dev->pwrctrl_flag))
if (!adreno_dev->sptp_pc_enabled)
return true;
kgsl_regread(device, A5XX_GPMU_SP_PWR_CLK_STATUS, &reg);
if (reg & BIT(20))
@ -404,8 +411,7 @@ static void a5xx_regulator_disable(struct adreno_device *adreno_dev)
return;
/* If feature is not supported or not enabled */
if (!ADRENO_FEATURE(adreno_dev, ADRENO_SPTP_PC) ||
!test_bit(ADRENO_SPTP_PC_CTRL, &adreno_dev->pwrctrl_flag)) {
if (!adreno_dev->sptp_pc_enabled) {
/* Set the default register values; set SW_COLLAPSE to 1 */
kgsl_regwrite(device, A5XX_GPMU_SP_POWER_CNTL, 0x778001);
/*
@ -456,8 +462,7 @@ static void a5xx_enable_pc(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
if (!ADRENO_FEATURE(adreno_dev, ADRENO_SPTP_PC) ||
!test_bit(ADRENO_SPTP_PC_CTRL, &adreno_dev->pwrctrl_flag))
if (!adreno_dev->sptp_pc_enabled)
return;
kgsl_regwrite(device, A5XX_GPMU_PWR_COL_INTER_FRAME_CTRL, 0x0000007F);
@ -701,7 +706,7 @@ void a5xx_hwcg_set(struct adreno_device *adreno_dev, bool on)
const struct adreno_a5xx_core *a5xx_core = to_a5xx_core(adreno_dev);
int i;
if (!test_bit(ADRENO_HWCG_CTRL, &adreno_dev->pwrctrl_flag))
if (!adreno_dev->hwcg_enabled)
return;
for (i = 0; i < a5xx_core->hwcg_count; i++)
@ -934,8 +939,7 @@ static void a530_lm_init(struct adreno_device *adreno_dev)
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
const struct adreno_a5xx_core *a5xx_core = to_a5xx_core(adreno_dev);
if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM) ||
!test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
if (!adreno_dev->lm_enabled)
return;
/* If something was wrong with the sequence file, return */
@ -985,8 +989,7 @@ static void a530_lm_enable(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM) ||
!test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
if (!adreno_dev->lm_enabled)
return;
/* If no sequence properly initialized, return */
@ -1015,10 +1018,10 @@ static void a540_lm_init(struct adreno_device *adreno_dev)
<< AGC_GPU_VERSION_SHIFT);
unsigned int r;
if (!test_bit(ADRENO_THROTTLING_CTRL, &adreno_dev->pwrctrl_flag))
if (!adreno_dev->throttling_enabled)
agc_lm_config |= AGC_THROTTLE_DISABLE;
if (lm_on(adreno_dev)) {
if (adreno_dev->lm_enabled) {
agc_lm_config |=
AGC_LM_CONFIG_ENABLE_GPMU_ADAPTIVE |
AGC_LM_CONFIG_ISENSE_ENABLE;
@ -1096,20 +1099,11 @@ static void a5xx_pwrlevel_change_settings(struct adreno_device *adreno_dev,
unsigned int prelevel, unsigned int postlevel,
bool post)
{
int on = 0;
/* On pre A540 HW only call through if LMx is supported and enabled */
if (ADRENO_FEATURE(adreno_dev, ADRENO_LM) &&
test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
on = ADRENO_LM;
/* On 540+ HW call through unconditionally as long as GPMU is enabled */
if (ADRENO_FEATURE(adreno_dev, ADRENO_GPMU)) {
if (adreno_is_a540(adreno_dev))
on = ADRENO_GPMU;
}
if (!on)
/*
* On pre A540 HW only call through if LMx is supported and enabled, and
* always call through for a540
*/
if (!adreno_is_a540(adreno_dev) && !adreno_dev->lm_enabled)
return;
if (!post) {
@ -1158,13 +1152,7 @@ static int64_t a5xx_read_throttling_counters(struct adreno_device *adreno_dev)
uint32_t th[ADRENO_GPMU_THROTTLE_COUNTERS];
struct adreno_busy_data *busy = &adreno_dev->busy_data;
if (!adreno_is_a540(adreno_dev))
return 0;
if (!ADRENO_FEATURE(adreno_dev, ADRENO_GPMU))
return 0;
if (!test_bit(ADRENO_THROTTLING_CTRL, &adreno_dev->pwrctrl_flag))
if (!adreno_dev->throttling_enabled)
return 0;
for (i = 0; i < ADRENO_GPMU_THROTTLE_COUNTERS; i++) {
@ -2378,10 +2366,6 @@ static unsigned int a5xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_INT_0_STATUS, A5XX_RBBM_INT_0_STATUS),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_CLOCK_CTL, A5XX_RBBM_CLOCK_CNTL),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_SW_RESET_CMD, A5XX_RBBM_SW_RESET_CMD),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD,
A5XX_RBBM_BLOCK_SW_RESET_CMD),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD2,
A5XX_RBBM_BLOCK_SW_RESET_CMD2),
ADRENO_REG_DEFINE(ADRENO_REG_UCHE_INVALIDATE0, A5XX_UCHE_INVALIDATE0),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_LO,
A5XX_RBBM_PERFCTR_RBBM_0_LO),
@ -2756,6 +2740,26 @@ static irqreturn_t a5xx_irq_handler(struct adreno_device *adreno_dev)
return ret;
}
static bool a5xx_hw_isidle(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
u32 status;
/*
* Due to CRC idle throttling the GPU idle hysteresis on a540 can take
* up to 5uS to expire
*/
if (adreno_is_a540(adreno_dev))
udelay(5);
kgsl_regread(device, A5XX_RBBM_STATUS, &status);
if (status & 0xfffffffe)
return false;
return adreno_irq_pending(adreno_dev) ? false : true;
}
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
static struct adreno_coresight_register a5xx_coresight_registers[] = {
{ A5XX_RBBM_CFG_DBGBUS_SEL_A },
@ -2982,4 +2986,5 @@ struct adreno_gpudev adreno_a5xx_gpudev = {
.preemption_schedule = a5xx_preemption_schedule,
.clk_set_options = a5xx_clk_set_options,
.read_alwayson = a5xx_read_alwayson,
.hw_isidle = a5xx_hw_isidle,
};

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015-2017,2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2017,2019-2020 The Linux Foundation. All rights reserved.
*/
#ifndef _ADRENO_A5XX_H_
@ -205,12 +205,6 @@ void a5xx_hwcg_set(struct adreno_device *adreno_dev, bool on);
#define LM_DEFAULT_LIMIT 6000
#define A530_DEFAULT_LEAKAGE 0x004E001A
static inline bool lm_on(struct adreno_device *adreno_dev)
{
return ADRENO_FEATURE(adreno_dev, ADRENO_LM) &&
test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag);
}
/**
* to_a5xx_core - return the a5xx specific GPU core struct
* @adreno_dev: An Adreno GPU device handle

View file

@ -238,7 +238,7 @@ static void a6xx_hwcg_set(struct adreno_device *adreno_dev, bool on)
unsigned int value;
int i;
if (!test_bit(ADRENO_HWCG_CTRL, &adreno_dev->pwrctrl_flag))
if (!adreno_dev->hwcg_enabled)
on = false;
if (gmu_core_isenabled(device)) {
@ -405,10 +405,6 @@ static void a6xx_start(struct adreno_device *adreno_dev)
adreno_dev->irq_mask = A6XX_INT_MASK;
/* runtime adjust callbacks based on feature sets */
if (!gmu_core_isenabled(device))
/* Legacy idle management if gmu is disabled */
ADRENO_GPU_DEVICE(adreno_dev)->hw_isidle = NULL;
/* enable hardware clockgating */
a6xx_hwcg_set(adreno_dev, true);
@ -986,17 +982,24 @@ static void a6xx_gpu_keepalive(struct adreno_device *adreno_dev,
ADRENO_REG_GMU_PWR_COL_KEEPALIVE, state);
}
/* Bitmask for GPU idle status check */
#define GPUBUSYIGNAHB BIT(23)
static bool a6xx_hw_isidle(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
unsigned int reg;
gmu_core_regread(KGSL_DEVICE(adreno_dev),
A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS, &reg);
if (reg & GPUBUSYIGNAHB)
return false;
return true;
/* Non GMU devices monitor the RBBM status */
if (!gmu_core_isenabled(device)) {
kgsl_regread(device, A6XX_RBBM_STATUS, &reg);
if (reg & 0xfffffffe)
return false;
return adreno_irq_pending(adreno_dev) ? false : true;
}
gmu_core_regread(device, A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS, &reg);
/* Bit 23 is GPUBUSYIGNAHB */
return (reg & BIT(23)) ? false : true;
}
/*
@ -1011,30 +1014,6 @@ static int a6xx_microcode_read(struct adreno_device *adreno_dev)
return adreno_get_firmware(adreno_dev, a6xx_core->sqefw_name, sqe_fw);
}
static int a6xx_soft_reset(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
unsigned int reg;
if (gmu_core_isenabled(device))
return 0;
adreno_writereg(adreno_dev, ADRENO_REG_RBBM_SW_RESET_CMD, 1);
/*
* Do a dummy read to get a brief read cycle delay for the
* reset to take effect
*/
adreno_readreg(adreno_dev, ADRENO_REG_RBBM_SW_RESET_CMD, &reg);
adreno_writereg(adreno_dev, ADRENO_REG_RBBM_SW_RESET_CMD, 0);
/* Clear GBIF client halt and CX arbiter halt */
adreno_deassert_gbif_halt(adreno_dev);
a6xx_sptprac_enable(adreno_dev);
return 0;
}
static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
@ -1042,8 +1021,7 @@ static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev)
u32 a, b, c;
struct adreno_busy_data *busy = &adreno_dev->busy_data;
if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM) ||
!test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
if (!adreno_dev->lm_enabled)
return 0;
/* The counters are selected in a6xx_gmu_enable_lm() */
@ -1098,12 +1076,14 @@ static int a6xx_reset(struct kgsl_device *device, int fault)
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
int ret;
/* Use the regular reset sequence for No GMU */
if (!gmu_core_isenabled(device))
return adreno_reset(device, fault);
/* Transition from ACTIVE to RESET state */
kgsl_pwrctrl_change_state(device, KGSL_STATE_RESET);
/*
* GMU devices transition to KGSL_STATE_RESET, non GMU devices go
* directly to KGSL_STATE_INIT
*/
if (gmu_core_isenabled(device))
kgsl_pwrctrl_change_state(device, KGSL_STATE_RESET);
else
kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);
/* since device is officially off now clear start bit */
clear_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);
@ -2300,6 +2280,8 @@ static void a6xx_platform_setup(struct adreno_device *adreno_dev)
{
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
adreno_dev->hwcg_enabled = true;
adreno_dev->preempt.preempt_level = 1;
adreno_dev->preempt.skipsaverestore = true;
adreno_dev->preempt.usesgmem = true;
@ -2407,11 +2389,6 @@ static unsigned int a6xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_INT_0_MASK, A6XX_RBBM_INT_0_MASK),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_INT_0_STATUS, A6XX_RBBM_INT_0_STATUS),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_CLOCK_CTL, A6XX_RBBM_CLOCK_CNTL),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_SW_RESET_CMD, A6XX_RBBM_SW_RESET_CMD),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD,
A6XX_RBBM_BLOCK_SW_RESET_CMD),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD2,
A6XX_RBBM_BLOCK_SW_RESET_CMD2),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_LO,
A6XX_RBBM_PERFCTR_LOAD_VALUE_LO),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_HI,
@ -2612,10 +2589,9 @@ struct adreno_gpudev adreno_a6xx_gpudev = {
.read_throttling_counters = a6xx_read_throttling_counters,
.microcode_read = a6xx_microcode_read,
.gpu_keepalive = a6xx_gpu_keepalive,
.hw_isidle = a6xx_hw_isidle, /* Replaced by NULL if GMU is disabled */
.hw_isidle = a6xx_hw_isidle,
.iommu_fault_block = a6xx_iommu_fault_block,
.reset = a6xx_reset,
.soft_reset = a6xx_soft_reset,
.preemption_pre_ibsubmit = a6xx_preemption_pre_ibsubmit,
.preemption_post_ibsubmit = a6xx_preemption_post_ibsubmit,
.preemption_init = a6xx_preemption_init,

View file

@ -487,8 +487,7 @@ static int a6xx_rpmh_power_off_gpu(struct kgsl_device *device)
gmu_core_regwrite(device, A6XX_GMU_RSCC_CONTROL_REQ, 0);
if (ADRENO_FEATURE(adreno_dev, ADRENO_LM) &&
test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
if (adreno_dev->lm_enabled)
gmu_core_regwrite(device, A6XX_GMU_AO_SPARE_CNTL, 0);
set_bit(GMU_RSCC_SLEEP_SEQ_DONE, &device->gmu_core.flags);
@ -1409,8 +1408,7 @@ static void a6xx_gmu_enable_lm(struct kgsl_device *device)
memset(adreno_dev->busy_data.throttle_cycles, 0,
sizeof(adreno_dev->busy_data.throttle_cycles));
if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM) ||
!test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
if (!adreno_dev->lm_enabled)
return;
/*

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2002,2008-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2002,2008-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/debugfs.h>
@ -59,7 +59,7 @@ static int _lm_limit_set(void *data, u64 val)
adreno_dev->lm_limit = val;
if (test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag)) {
if (adreno_dev->lm_enabled) {
mutex_lock(&device->mutex);
kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND);
kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER);

View file

@ -175,8 +175,8 @@ static void fault_detect_read(struct adreno_device *adreno_dev)
*/
static inline bool _isidle(struct adreno_device *adreno_dev)
{
const struct adreno_gpu_core *gpucore = adreno_dev->gpucore;
unsigned int reg_rbbm_status;
u32 mask;
if (!kgsl_state_is_awake(KGSL_DEVICE(adreno_dev)))
goto ret;
@ -187,7 +187,12 @@ static inline bool _isidle(struct adreno_device *adreno_dev)
/* only check rbbm status to determine if GPU is idle */
adreno_readreg(adreno_dev, ADRENO_REG_RBBM_STATUS, &reg_rbbm_status);
if (reg_rbbm_status & gpucore->busy_mask)
if (adreno_is_a3xx(adreno_dev))
mask = 0x7ffffffe;
else
mask = 0xfffffffe;
if (reg_rbbm_status & mask)
return false;
ret:
@ -2197,10 +2202,7 @@ static int dispatcher_do_fault(struct adreno_device *adreno_dev)
kgsl_process_event_group(device, &hung_rb->events);
}
if (gpudev->reset)
ret = gpudev->reset(device, fault);
else
ret = adreno_reset(device, fault);
ret = adreno_reset(device, fault);
mutex_unlock(&device->mutex);
/* if any other fault got in until reset then ignore */

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/sysfs.h>
@ -139,19 +139,19 @@ static bool _ft_hang_intr_status_show(struct adreno_device *adreno_dev)
return true;
}
static int _pwrctrl_store(struct adreno_device *adreno_dev,
unsigned int val, unsigned int flag)
static int pwrflag_store(struct adreno_device *adreno_dev,
unsigned int val, bool *flag)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
if (val == test_bit(flag, &adreno_dev->pwrctrl_flag))
if (*flag == val)
return 0;
mutex_lock(&device->mutex);
/* Power down the GPU before changing the state */
kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND);
change_bit(flag, &adreno_dev->pwrctrl_flag);
*flag = val;
kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER);
mutex_unlock(&device->mutex);
@ -201,42 +201,51 @@ static bool _preemption_show(struct adreno_device *adreno_dev)
static int _hwcg_store(struct adreno_device *adreno_dev, bool val)
{
return _pwrctrl_store(adreno_dev, val, ADRENO_HWCG_CTRL);
return pwrflag_store(adreno_dev, val, &adreno_dev->hwcg_enabled);
}
static bool _hwcg_show(struct adreno_device *adreno_dev)
{
return test_bit(ADRENO_HWCG_CTRL, &adreno_dev->pwrctrl_flag);
return adreno_dev->hwcg_enabled;
}
static int _throttling_store(struct adreno_device *adreno_dev, bool val)
{
return _pwrctrl_store(adreno_dev, val, ADRENO_THROTTLING_CTRL);
if (!adreno_is_a540(adreno_dev))
return 0;
return pwrflag_store(adreno_dev, val, &adreno_dev->throttling_enabled);
}
static bool _throttling_show(struct adreno_device *adreno_dev)
{
return test_bit(ADRENO_THROTTLING_CTRL, &adreno_dev->pwrctrl_flag);
return adreno_dev->throttling_enabled;
}
static int _sptp_pc_store(struct adreno_device *adreno_dev, bool val)
{
return _pwrctrl_store(adreno_dev, val, ADRENO_SPTP_PC_CTRL);
if (!ADRENO_FEATURE(adreno_dev, ADRENO_SPTP_PC))
return 0;
return pwrflag_store(adreno_dev, val, &adreno_dev->sptp_pc_enabled);
}
static bool _sptp_pc_show(struct adreno_device *adreno_dev)
{
return test_bit(ADRENO_SPTP_PC_CTRL, &adreno_dev->pwrctrl_flag);
return adreno_dev->sptp_pc_enabled;
}
static int _lm_store(struct adreno_device *adreno_dev, bool val)
{
return _pwrctrl_store(adreno_dev, val, ADRENO_LM_CTRL);
if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM))
return 0;
return pwrflag_store(adreno_dev, val, &adreno_dev->lm_enabled);
}
static bool _lm_show(struct adreno_device *adreno_dev)
{
return test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag);
return adreno_dev->lm_enabled;
}
static int _ifpc_store(struct adreno_device *adreno_dev, bool val)
@ -263,17 +272,12 @@ static unsigned int _preempt_count_show(struct adreno_device *adreno_dev)
static bool _acd_show(struct adreno_device *adreno_dev)
{
return test_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag);
return adreno_dev->acd_enabled;
}
static int _acd_store(struct adreno_device *adreno_dev, bool val)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
if (test_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag) == val)
return 0;
return gmu_core_acd_set(device, val);
return gmu_core_acd_set(KGSL_DEVICE(adreno_dev), val);
}
static ssize_t _sysfs_store_u32(struct device *dev,

View file

@ -97,7 +97,6 @@ struct kgsl_functable {
void (*regwrite)(struct kgsl_device *device,
unsigned int offsetwords, unsigned int value);
int (*idle)(struct kgsl_device *device);
bool (*isidle)(struct kgsl_device *device);
int (*suspend_context)(struct kgsl_device *device);
int (*first_open)(struct kgsl_device *device);
int (*last_close)(struct kgsl_device *device);

View file

@ -25,7 +25,7 @@
struct gmu_iommu_context {
const char *name;
struct device *dev;
struct platform_device *pdev;
struct iommu_domain *domain;
};
@ -277,48 +277,57 @@ static struct gmu_memdesc *allocate_gmu_kmem(struct gmu_device *gmu,
}
static int gmu_iommu_cb_probe(struct gmu_device *gmu,
struct gmu_iommu_context *ctx,
struct device_node *node)
const char *name, struct gmu_iommu_context *ctx,
struct device_node *parent, iommu_fault_handler_t handler)
{
struct platform_device *pdev = of_find_device_by_node(node);
struct device *dev;
struct device_node *node = of_get_child_by_name(parent, name);
struct platform_device *pdev;
int ret;
dev = &pdev->dev;
of_dma_configure(dev, node, true);
if (!node)
return -ENODEV;
ctx->dev = dev;
pdev = of_find_device_by_node(node);
of_dma_configure(&pdev->dev, node, true);
of_node_put(node);
ctx->pdev = pdev;
ctx->domain = iommu_domain_alloc(&platform_bus_type);
if (ctx->domain == NULL) {
dev_err(&gmu->pdev->dev, "gmu iommu fail to alloc %s domain\n",
ctx->name);
platform_device_put(pdev);
return -ENODEV;
}
ret = iommu_attach_device(ctx->domain, dev);
if (ret) {
dev_err(&gmu->pdev->dev, "gmu iommu fail to attach %s device\n",
ctx->name);
iommu_domain_free(ctx->domain);
ret = iommu_attach_device(ctx->domain, &pdev->dev);
if (!ret) {
iommu_set_fault_handler(ctx->domain, handler, ctx);
return 0;
}
dev_err(&gmu->pdev->dev,
"gmu iommu fail to attach %s device\n", ctx->name);
iommu_domain_free(ctx->domain);
ctx->domain = NULL;
platform_device_put(pdev);
return ret;
}
static struct {
const char *compatible;
int index;
iommu_fault_handler_t hdlr;
} cbs[] = {
{ "qcom,smmu-gmu-user-cb",
GMU_CONTEXT_USER,
gmu_user_fault_handler,
},
{ "qcom,smmu-gmu-kernel-cb",
GMU_CONTEXT_KERNEL,
gmu_kernel_fault_handler,
},
};
static void gmu_iommu_cb_close(struct gmu_iommu_context *ctx)
{
if (!ctx->domain)
return;
iommu_detach_device(ctx->domain, &ctx->pdev->dev);
iommu_domain_free(ctx->domain);
platform_device_put(ctx->pdev);
memset(ctx, 0, sizeof(*ctx));
}
/*
* gmu_iommu_init() - probe IOMMU context banks used by GMU
@ -328,34 +337,17 @@ static struct {
*/
static int gmu_iommu_init(struct gmu_device *gmu, struct device_node *node)
{
struct device_node *child;
struct gmu_iommu_context *ctx = NULL;
int ret, i;
int ret;
of_platform_populate(node, NULL, NULL, &gmu->pdev->dev);
devm_of_platform_populate(&gmu->pdev->dev);
for (i = 0; i < ARRAY_SIZE(cbs); i++) {
child = of_find_compatible_node(node, NULL, cbs[i].compatible);
if (child) {
ctx = &gmu_ctx[cbs[i].index];
ret = gmu_iommu_cb_probe(gmu, ctx, child);
if (ret)
return ret;
iommu_set_fault_handler(ctx->domain,
cbs[i].hdlr, ctx);
}
}
ret = gmu_iommu_cb_probe(gmu, "gmu_user",
&gmu_ctx[GMU_CONTEXT_USER], node, gmu_user_fault_handler);
if (ret)
return ret;
for (i = 0; i < ARRAY_SIZE(gmu_ctx); i++) {
if (gmu_ctx[i].domain == NULL) {
dev_err(&gmu->pdev->dev,
"Missing GMU %s context bank node\n",
gmu_ctx[i].name);
return -EINVAL;
}
}
return 0;
return gmu_iommu_cb_probe(gmu, "gmu_kernel",
&gmu_ctx[GMU_CONTEXT_KERNEL], node, gmu_kernel_fault_handler);
}
/*
@ -394,14 +386,8 @@ static void gmu_memory_close(struct gmu_device *gmu)
clear_bit(i, &gmu->kmem_bitmap);
}
for (i = 0; i < ARRAY_SIZE(gmu_ctx); i++) {
ctx = &gmu_ctx[i];
if (ctx->domain) {
iommu_detach_device(ctx->domain, ctx->dev);
iommu_domain_free(ctx->domain);
}
}
gmu_iommu_cb_close(&gmu_ctx[GMU_CONTEXT_USER]);
gmu_iommu_cb_close(&gmu_ctx[GMU_CONTEXT_KERNEL]);
}
static enum gmu_mem_type gmu_get_blk_memtype(struct gmu_device *gmu,
@ -1061,60 +1047,44 @@ static int gmu_reg_probe(struct kgsl_device *device)
res = platform_get_resource_byname(gmu->pdev, IORESOURCE_MEM,
"kgsl_gmu_reg");
if (res == NULL) {
dev_err(&gmu->pdev->dev,
"platform_get_resource kgsl_gmu_reg failed\n");
return -EINVAL;
}
if (res->start == 0 || resource_size(res) == 0) {
dev_err(&gmu->pdev->dev,
"dev %d kgsl_gmu_reg invalid register region\n",
gmu->pdev->dev.id);
return -EINVAL;
}
gmu->reg_phys = res->start;
gmu->reg_len = resource_size(res);
device->gmu_core.reg_virt = devm_ioremap(&gmu->pdev->dev,
res->start, resource_size(res));
if (device->gmu_core.reg_virt == NULL) {
dev_err(&gmu->pdev->dev, "kgsl_gmu_reg ioremap failed\n");
if (!res) {
dev_err(&gmu->pdev->dev, "The GMU register region isn't defined\n");
return -ENODEV;
}
device->gmu_core.gmu2gpu_offset = (res->start - device->reg_phys) >> 2;
device->gmu_core.reg_len = resource_size(res);
/*
* We can't use devm_ioremap_resource here because we purposely double
* map the gpu_cc registers for debugging purposes
*/
device->gmu_core.reg_virt = devm_ioremap(&gmu->pdev->dev, res->start,
resource_size(res));
if (!device->gmu_core.reg_virt) {
dev_err(&gmu->pdev->dev, "Unable to map the GMU registers\n");
return -ENOMEM;
}
return 0;
}
static int gmu_regulators_probe(struct gmu_device *gmu,
struct device_node *node)
struct platform_device *pdev)
{
const char *name;
struct property *prop;
struct device *dev = &gmu->pdev->dev;
int ret = 0;
gmu->cx_gdsc = devm_regulator_get(&pdev->dev, "vddcx");
if (IS_ERR(gmu->cx_gdsc)) {
if (PTR_ERR(gmu->cx_gdsc) != -EPROBE_DEFER)
dev_err(&pdev->dev, "Couldn't get the vddcx gdsc\n");
return PTR_ERR(gmu->cx_gdsc);
}
of_property_for_each_string(node, "regulator-names", prop, name) {
if (!strcmp(name, "vddcx")) {
gmu->cx_gdsc = devm_regulator_get(dev, name);
if (IS_ERR(gmu->cx_gdsc)) {
ret = PTR_ERR(gmu->cx_gdsc);
dev_err(dev, "dt: GMU couldn't get CX gdsc\n");
gmu->cx_gdsc = NULL;
return ret;
}
} else if (!strcmp(name, "vdd")) {
gmu->gx_gdsc = devm_regulator_get(dev, name);
if (IS_ERR(gmu->gx_gdsc)) {
ret = PTR_ERR(gmu->gx_gdsc);
dev_err(dev, "dt: GMU couldn't get GX gdsc\n");
gmu->gx_gdsc = NULL;
return ret;
}
} else {
dev_err(dev, "dt: Unknown GMU regulator: %s\n", name);
return -ENODEV;
}
gmu->gx_gdsc = devm_regulator_get(&pdev->dev, "vdd");
if (IS_ERR(gmu->gx_gdsc)) {
if (PTR_ERR(gmu->gx_gdsc) != -EPROBE_DEFER)
dev_err(&pdev->dev, "Couldn't get the vdd gdsc\n");
return PTR_ERR(gmu->gx_gdsc);
}
return 0;
@ -1160,11 +1130,11 @@ static int gmu_aop_mailbox_init(struct kgsl_device *device,
if (IS_ERR(mailbox->channel))
return PTR_ERR(mailbox->channel);
set_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag);
adreno_dev->acd_enabled = true;
return 0;
}
static int gmu_acd_set(struct kgsl_device *device, unsigned int val)
static int gmu_acd_set(struct kgsl_device *device, bool val)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct gmu_device *gmu = KGSL_GMU_DEVICE(device);
@ -1173,7 +1143,7 @@ static int gmu_acd_set(struct kgsl_device *device, unsigned int val)
return -EINVAL;
/* Don't do any unneeded work if ACD is already in the correct state */
if (val == test_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag))
if (adreno_dev->acd_enabled == val)
return 0;
mutex_lock(&device->mutex);
@ -1181,13 +1151,8 @@ static int gmu_acd_set(struct kgsl_device *device, unsigned int val)
/* Power down the GPU before enabling or disabling ACD */
kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND);
if (val) {
set_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag);
gmu_aop_send_acd_state(device, true);
} else {
clear_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag);
gmu_aop_send_acd_state(device, false);
}
adreno_dev->acd_enabled = val;
gmu_aop_send_acd_state(device, val);
kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER);
@ -1321,7 +1286,7 @@ static int gmu_probe(struct kgsl_device *device, struct platform_device *pdev)
gmu->pdev = pdev;
device->gmu_core.ptr = (void *)gmu;
device->gmu_core.ptr = gmu;
hfi = &gmu->hfi;
gmu->load_mode = TCM_BOOT;
@ -1330,11 +1295,11 @@ static int gmu_probe(struct kgsl_device *device, struct platform_device *pdev)
set_dma_ops(&gmu->pdev->dev, NULL);
/* Set up GMU regulators */
ret = gmu_regulators_probe(gmu, pdev->dev.of_node);
ret = gmu_regulators_probe(gmu, pdev);
if (ret)
return ret;
ret = devm_clk_bulk_get_all(&gmu->pdev->dev, &gmu->clks);
ret = devm_clk_bulk_get_all(&pdev->dev, &gmu->clks);
if (ret < 0)
return ret;
@ -1343,8 +1308,9 @@ static int gmu_probe(struct kgsl_device *device, struct platform_device *pdev)
/* Get a pointer to the GMU clock */
gmu->gmu_clk = kgsl_of_clk_by_name(gmu->clks, gmu->num_clks, "gmu_clk");
if (!gmu->gmu_clk) {
dev_err(&gmu->pdev->dev, "Couldn't get gmu_clk\n");
return -ENODEV;
dev_err(&pdev->dev, "Couldn't get gmu_clk\n");
ret = -ENODEV;
goto error;
}
/* Set up GMU IOMMU and shared memory with GMU */
@ -1366,10 +1332,6 @@ static int gmu_probe(struct kgsl_device *device, struct platform_device *pdev)
if (ret)
goto error;
device->gmu_core.gmu2gpu_offset =
(gmu->reg_phys - device->reg_phys) >> 2;
device->gmu_core.reg_len = gmu->reg_len;
/* Initialize HFI and GMU interrupts */
hfi->hfi_interrupt_num = kgsl_request_irq(gmu->pdev, "kgsl_hfi_irq",
hfi_irq_handler, device);
@ -1474,9 +1436,6 @@ static int gmu_enable_gdsc(struct gmu_device *gmu)
{
int ret;
if (IS_ERR_OR_NULL(gmu->cx_gdsc))
return 0;
ret = regulator_enable(gmu->cx_gdsc);
if (ret)
dev_err(&gmu->pdev->dev,
@ -1598,8 +1557,7 @@ static int gmu_start(struct kgsl_device *device)
switch (device->state) {
case KGSL_STATE_INIT:
gmu_aop_send_acd_state(device, test_bit(ADRENO_ACD_CTRL,
&adreno_dev->pwrctrl_flag));
gmu_aop_send_acd_state(device, adreno_dev->acd_enabled);
/* Fall-thru */
case KGSL_STATE_SUSPEND:
WARN_ON(test_bit(GMU_CLK_ON, &device->gmu_core.flags));
@ -1738,21 +1696,15 @@ static void gmu_remove(struct kgsl_device *device)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct gmu_device *gmu = KGSL_GMU_DEVICE(device);
struct kgsl_hfi *hfi;
if (gmu == NULL || gmu->pdev == NULL)
return;
hfi = &gmu->hfi;
tasklet_kill(&hfi->tasklet);
tasklet_kill(&gmu->hfi.tasklet);
gmu_stop(device);
if (!IS_ERR_OR_NULL(gmu->mailbox.channel))
mbox_free_channel(gmu->mailbox.channel);
clear_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag);
adreno_dev->acd_enabled = false;
if (gmu->fw_image)
release_firmware(gmu->fw_image);

View file

@ -141,8 +141,6 @@ struct icc_path;
/**
* struct gmu_device - GMU device structure
* @ver: GMU Version information
* @reg_phys: GMU CSR physical address
* @reg_len: GMU CSR range
* @gmu_interrupt_num: GMU interrupt number
* @fw_image: GMU FW image
* @hfi_mem: pointer to HFI shared memory
@ -174,8 +172,6 @@ struct gmu_device {
u32 hfi;
} ver;
struct platform_device *pdev;
unsigned long reg_phys;
unsigned int reg_len;
int gmu_interrupt_num;
const struct firmware *fw_image;
struct gmu_memdesc *hfi_mem;

View file

@ -142,7 +142,7 @@ int gmu_core_dcvs_set(struct kgsl_device *device, int gpu_pwrlevel,
return -EINVAL;
}
int gmu_core_acd_set(struct kgsl_device *device, unsigned int val)
int gmu_core_acd_set(struct kgsl_device *device, bool val)
{
struct gmu_core_ops *gmu_core_ops = GMU_CORE_OPS(device);

View file

@ -109,7 +109,7 @@ struct gmu_core_ops {
void (*snapshot)(struct kgsl_device *device);
bool (*regulator_isenabled)(struct kgsl_device *device);
int (*suspend)(struct kgsl_device *device);
int (*acd_set)(struct kgsl_device *device, unsigned int val);
int (*acd_set)(struct kgsl_device *device, bool val);
};
struct gmu_dev_ops {
@ -179,7 +179,7 @@ bool gmu_core_scales_bandwidth(struct kgsl_device *device);
bool gmu_core_isenabled(struct kgsl_device *device);
int gmu_core_dcvs_set(struct kgsl_device *device, int gpu_pwrlevel,
int bus_level);
int gmu_core_acd_set(struct kgsl_device *device, unsigned int val);
int gmu_core_acd_set(struct kgsl_device *device, bool val);
bool gmu_core_regulator_isenabled(struct kgsl_device *device);
bool gmu_core_is_register_offset(struct kgsl_device *device,
unsigned int offsetwords);

View file

@ -653,7 +653,7 @@ static int hfi_send_lm_feature_ctrl(struct gmu_device *gmu,
u32 slope = 0;
int ret;
if (!test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
if (!adreno_dev->lm_enabled)
return 0;
memset(&req, 0, sizeof(req));
@ -678,7 +678,7 @@ static int hfi_send_acd_feature_ctrl(struct gmu_device *gmu,
{
int ret = 0;
if (test_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag)) {
if (adreno_dev->acd_enabled) {
ret = hfi_send_acd_tbl(gmu);
if (!ret)
ret = hfi_send_feature_ctrl(gmu, HFI_FEATURE_ACD, 1, 0);

View file

@ -23,88 +23,65 @@ static int rgmu_irq_probe(struct kgsl_device *device)
struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
int ret;
rgmu->oob_interrupt_num = platform_get_irq_byname(rgmu->pdev,
"kgsl_oob");
ret = devm_request_irq(&rgmu->pdev->dev,
rgmu->oob_interrupt_num,
oob_irq_handler, IRQF_TRIGGER_HIGH,
"kgsl-oob", device);
if (ret) {
dev_err(&rgmu->pdev->dev,
"Request kgsl-oob interrupt failed:%d\n", ret);
ret = kgsl_request_irq(rgmu->pdev, "kgsl_oob", oob_irq_handler, device);
if (ret < 0)
return ret;
}
rgmu->rgmu_interrupt_num = platform_get_irq_byname(rgmu->pdev,
"kgsl_rgmu");
rgmu->oob_interrupt_num = ret;
ret = devm_request_irq(&rgmu->pdev->dev,
rgmu->rgmu_interrupt_num,
rgmu_irq_handler, IRQF_TRIGGER_HIGH,
"kgsl-rgmu", device);
if (ret)
dev_err(&rgmu->pdev->dev,
"Request kgsl-rgmu interrupt failed:%d\n", ret);
ret = kgsl_request_irq(rgmu->pdev,
"kgsl_rgmu", rgmu_irq_handler, device);
if (ret < 0)
return ret;
return ret;
rgmu->rgmu_interrupt_num = ret;
return 0;
}
static int rgmu_regulators_probe(struct rgmu_device *rgmu,
struct device_node *node)
static int rgmu_regulators_probe(struct rgmu_device *rgmu)
{
int ret;
int ret = 0;
rgmu->cx_gdsc = devm_regulator_get(&rgmu->pdev->dev, "vddcx");
if (IS_ERR_OR_NULL(rgmu->cx_gdsc)) {
if (IS_ERR(rgmu->cx_gdsc)) {
ret = PTR_ERR(rgmu->cx_gdsc);
dev_err(&rgmu->pdev->dev,
if (ret != -EPROBE_DEFER)
dev_err(&rgmu->pdev->dev,
"Couldn't get CX gdsc error:%d\n", ret);
rgmu->cx_gdsc = NULL;
return ret;
}
rgmu->gx_gdsc = devm_regulator_get(&rgmu->pdev->dev, "vdd");
if (IS_ERR_OR_NULL(rgmu->gx_gdsc)) {
if (IS_ERR(rgmu->gx_gdsc)) {
ret = PTR_ERR(rgmu->gx_gdsc);
dev_err(&rgmu->pdev->dev,
if (ret != -EPROBE_DEFER)
dev_err(&rgmu->pdev->dev,
"Couldn't get GX gdsc error:%d\n", ret);
rgmu->gx_gdsc = NULL;
return ret;
}
return 0;
return ret;
}
static int rgmu_clocks_probe(struct rgmu_device *rgmu, struct device_node *node)
{
const char *cname;
struct property *prop;
struct clk *c;
int i = 0;
int ret;
of_property_for_each_string(node, "clock-names", prop, cname) {
ret = devm_clk_bulk_get_all(&rgmu->pdev->dev, &rgmu->clks);
if (ret < 0)
return ret;
if (i >= ARRAY_SIZE(rgmu->clks)) {
dev_err(&rgmu->pdev->dev,
"dt: too many RGMU clocks defined\n");
return -EINVAL;
}
rgmu->num_clks = ret;
c = devm_clk_get(&rgmu->pdev->dev, cname);
if (IS_ERR_OR_NULL(c)) {
dev_err(&rgmu->pdev->dev,
"dt: Couldn't get clock: %s\n", cname);
return PTR_ERR(c);
}
rgmu->gpu_clk = kgsl_of_clk_by_name(rgmu->clks, ret, "core");
if (!rgmu->gpu_clk) {
dev_err(&rgmu->pdev->dev, "The GPU clock isn't defined\n");
return -ENODEV;
}
/* Remember the key clocks that we need to control later */
if (!strcmp(cname, "core"))
rgmu->gpu_clk = c;
else if (!strcmp(cname, "gmu"))
rgmu->rgmu_clk = c;
rgmu->clks[i++] = c;
rgmu->rgmu_clk = kgsl_of_clk_by_name(rgmu->clks, ret, "gmu");
if (!rgmu->rgmu_clk) {
dev_err(&rgmu->pdev->dev, "The RGMU clock isn't defined\n");
return -ENODEV;
}
return 0;
@ -114,7 +91,7 @@ static void rgmu_disable_clks(struct kgsl_device *device)
{
struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
struct gmu_dev_ops *gmu_dev_ops = GMU_DEVICE_OPS(device);
int j = 0, ret;
int ret;
/* Check GX GDSC is status */
if (gmu_dev_ops->gx_is_on(device)) {
@ -141,22 +118,17 @@ static void rgmu_disable_clks(struct kgsl_device *device)
dev_err(&rgmu->pdev->dev, "gx is stuck on\n");
}
for (j = 0; j < ARRAY_SIZE(rgmu->clks); j++)
clk_disable_unprepare(rgmu->clks[j]);
clk_bulk_disable_unprepare(rgmu->num_clks, rgmu->clks);
clear_bit(GMU_CLK_ON, &device->gmu_core.flags);
}
static int rgmu_enable_clks(struct kgsl_device *device)
{
int ret, j = 0;
int ret;
struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
if (IS_ERR_OR_NULL(rgmu->rgmu_clk) ||
IS_ERR_OR_NULL(rgmu->gpu_clk))
return -EINVAL;
ret = clk_set_rate(rgmu->rgmu_clk, RGMU_CLK_FREQ);
if (ret) {
dev_err(&rgmu->pdev->dev, "Couldn't set the RGMU clock\n");
@ -170,14 +142,10 @@ static int rgmu_enable_clks(struct kgsl_device *device)
return ret;
}
for (j = 0; j < ARRAY_SIZE(rgmu->clks); j++) {
ret = clk_prepare_enable(rgmu->clks[j]);
if (ret) {
dev_err(&rgmu->pdev->dev,
"Fail(%d) to enable gpucc clk idx %d\n",
ret, j);
return ret;
}
ret = clk_bulk_prepare_enable(rgmu->num_clks, rgmu->clks);
if (ret) {
dev_err(&rgmu->pdev->dev, "Failed to enable RGMU clocks\n");
return ret;
}
set_bit(GMU_CLK_ON, &device->gmu_core.flags);
@ -289,42 +257,31 @@ static int rgmu_probe(struct kgsl_device *device, struct platform_device *pdev)
rgmu->pdev = pdev;
/* Set up RGMU regulators */
ret = rgmu_regulators_probe(rgmu, pdev->dev.of_node);
ret = rgmu_regulators_probe(rgmu);
if (ret)
return ret;
/* Set up RGMU clocks */
ret = rgmu_clocks_probe(rgmu, pdev->dev.of_node);
if (ret)
return ret;
/* Map and reserve RGMU CSRs registers */
res = platform_get_resource_byname(rgmu->pdev,
IORESOURCE_MEM, "kgsl_rgmu");
if (res == NULL) {
dev_err(&rgmu->pdev->dev,
"platform_get_resource failed\n");
return -EINVAL;
}
if (res->start == 0 || resource_size(res) == 0) {
dev_err(&rgmu->pdev->dev,
"Register region is invalid\n");
return -EINVAL;
}
rgmu->reg_phys = res->start;
rgmu->reg_len = resource_size(res);
device->gmu_core.reg_virt = devm_ioremap(&rgmu->pdev->dev, res->start,
resource_size(res));
if (device->gmu_core.reg_virt == NULL) {
dev_err(&rgmu->pdev->dev, "Unable to remap rgmu registers\n");
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "kgsl_rgmu");
if (!res) {
dev_err(&pdev->dev, "The RGMU register region isn't defined\n");
return -ENODEV;
}
device->gmu_core.gmu2gpu_offset =
(rgmu->reg_phys - device->reg_phys) >> 2;
device->gmu_core.reg_len = rgmu->reg_len;
device->gmu_core.gmu2gpu_offset = (res->start - device->reg_phys) >> 2;
device->gmu_core.reg_len = resource_size(res);
device->gmu_core.reg_virt = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(device->gmu_core.reg_virt)) {
dev_err(&pdev->dev, "Unable to map the RGMU registers\n");
return PTR_ERR(device->gmu_core.reg_virt);
}
device->gmu_core.ptr = (void *)rgmu;
/* Initialize OOB and RGMU interrupts */

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#ifndef __KGSL_RGMU_H
#define __KGSL_RGMU_H
@ -18,9 +18,6 @@
/**
* struct rgmu_device - rGMU device structure
* @ver: RGMU firmware version
* @reg_phys: RGMU CSR physical address
* @reg_virt: RGMU CSR virtual address
* @reg_len: RGMU CSR range
* @rgmu_interrupt_num: RGMU interrupt number
* @oob_interrupt_num: number of RGMU asserted OOB interrupt
* @fw_hostptr: Buffer which holds the RGMU firmware
@ -37,15 +34,15 @@
struct rgmu_device {
u32 ver;
struct platform_device *pdev;
unsigned long reg_phys;
unsigned int reg_len;
unsigned int rgmu_interrupt_num;
unsigned int oob_interrupt_num;
unsigned int *fw_hostptr;
uint32_t fw_size;
struct regulator *cx_gdsc;
struct regulator *gx_gdsc;
struct clk *clks[MAX_RGMU_CLKS];
struct clk_bulk_data *clks;
/** @num_clks: Number of clocks in @clks */
int num_clks;
struct clk *gpu_clk;
struct clk *rgmu_clk;
unsigned int idle_level;