Merge "msm: kgsl: Add dedicated boolean functions for adreno sysfs"

This commit is contained in:
qctecmdr 2019-12-09 08:32:40 -08:00 • committed by Gerrit - the friendly Code Review server
commit 140cc17e9c
13 changed files with 188 additions and 274 deletions

View file

@ -605,7 +605,6 @@ enum adreno_regs {
ADRENO_REG_CP_RB_RPTR_ADDR_HI,
ADRENO_REG_CP_RB_RPTR,
ADRENO_REG_CP_RB_WPTR,
ADRENO_REG_CP_CNTL,
ADRENO_REG_CP_ME_CNTL,
ADRENO_REG_CP_RB_CNTL,
ADRENO_REG_CP_IB1_BASE,

View file

@ -1198,7 +1198,6 @@ static unsigned int a3xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_BASE_HI, ADRENO_REG_SKIP),
ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_RPTR, A3XX_CP_RB_RPTR),
ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_WPTR, A3XX_CP_RB_WPTR),
ADRENO_REG_DEFINE(ADRENO_REG_CP_CNTL, A3XX_CP_CNTL),
ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_CNTL, A3XX_CP_ME_CNTL),
ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_CNTL, A3XX_CP_RB_CNTL),
ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE, A3XX_CP_IB1_BASE),

View file

@ -2393,7 +2393,6 @@ static unsigned int a5xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
A5XX_CP_RB_RPTR_ADDR_HI),
ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_RPTR, A5XX_CP_RB_RPTR),
ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_WPTR, A5XX_CP_RB_WPTR),
ADRENO_REG_DEFINE(ADRENO_REG_CP_CNTL, A5XX_CP_CNTL),
ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_CNTL, A5XX_CP_ME_CNTL),
ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_CNTL, A5XX_CP_RB_CNTL),
ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE, A5XX_CP_IB1_BASE),

View file

@ -2264,7 +2264,6 @@ static unsigned int a6xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_WPTR, A6XX_CP_RB_WPTR),
ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_CNTL, A6XX_CP_RB_CNTL),
ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_CNTL, A6XX_CP_SQE_CNTL),
ADRENO_REG_DEFINE(ADRENO_REG_CP_CNTL, A6XX_CP_MISC_CNTL),
ADRENO_REG_DEFINE(ADRENO_REG_CP_HW_FAULT, A6XX_CP_HW_FAULT),
ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE, A6XX_CP_IB1_BASE),
ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE_HI, A6XX_CP_IB1_BASE_HI),

View file

@ -116,66 +116,36 @@ static unsigned int a3xx_tlbiall(struct adreno_device *adreno_dev,
return cmds - start;
}
/**
* _adreno_iommu_add_idle_cmds - Add pm4 packets for GPU idle
* @adreno_dev - Pointer to device structure
* @cmds - Pointer to memory where idle commands need to be added
*/
static inline int _adreno_iommu_add_idle_cmds(struct adreno_device *adreno_dev,
unsigned int *cmds)
{
unsigned int *start = cmds;
cmds += cp_wait_for_idle(adreno_dev, cmds);
if (adreno_is_a3xx(adreno_dev))
cmds += cp_wait_for_me(adreno_dev, cmds);
return cmds - start;
}
/**
* adreno_iommu_set_apriv() - Generate commands to set/reset the APRIV
* @adreno_dev: Device on which the commands will execute
* @cmds: The memory pointer where commands are generated
* @set: If set then APRIV is set else reset
*
* Returns the number of commands generated
*/
static unsigned int adreno_iommu_set_apriv(struct adreno_device *adreno_dev,
unsigned int *cmds, int set)
{
unsigned int *cmds_orig = cmds;
/* adreno 3xx doesn't have the CP_CNTL.APRIV field */
if (adreno_is_a3xx(adreno_dev))
return 0;
/* Targets with apriv control do not need to explicitly set the bit */
if (ADRENO_FEATURE(adreno_dev, ADRENO_APRIV))
return 0;
cmds += cp_wait_for_idle(adreno_dev, cmds);
cmds += cp_wait_for_me(adreno_dev, cmds);
*cmds++ = cp_register(adreno_dev, adreno_getreg(adreno_dev,
ADRENO_REG_CP_CNTL), 1);
if (set)
*cmds++ = 1;
else
*cmds++ = 0;
return cmds - cmds_orig;
}
/* offset at which a nop command is placed in setstate */
#define KGSL_IOMMU_SETSTATE_NOP_OFFSET 1024
static unsigned int _adreno_iommu_set_pt_v2_a3xx(struct kgsl_device *device,
unsigned int *cmds_orig,
u64 ttbr0, u32 contextidr)
{
struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
unsigned int *cmds = cmds_orig;
cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds);
/*
* Adding an indirect buffer ensures that the prefetch stalls until
* the commands in indirect buffer have completed. We need to stall
* prefetch with a nop indirect buffer when updating pagetables
* because it provides stabler synchronization.
*/
cmds += cp_wait_for_me(adreno_dev, cmds);
if (!IS_ERR_OR_NULL(iommu->setstate)) {
*cmds++ = cp_mem_packet(adreno_dev,
CP_INDIRECT_BUFFER_PFE, 2, 1);
cmds += cp_gpuaddr(adreno_dev, cmds, iommu->setstate->gpuaddr +
KGSL_IOMMU_SETSTATE_NOP_OFFSET);
*cmds++ = 2;
}
cmds += cp_wait_for_idle(adreno_dev, cmds);
cmds += cp_wait_for_me(adreno_dev, cmds);
cmds += a3xx_vbif_lock(adreno_dev, cmds);
@ -192,8 +162,11 @@ static unsigned int _adreno_iommu_set_pt_v2_a3xx(struct kgsl_device *device,
/* wait for me to finish the TLBI */
cmds += cp_wait_for_me(adreno_dev, cmds);
cmds += cp_wait_for_idle(adreno_dev, cmds);
cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds);
/* Invalidate the state */
*cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
*cmds++ = 0x7ffff;
return cmds - cmds_orig;
}
@ -206,9 +179,6 @@ static unsigned int _adreno_iommu_set_pt_v2_a5xx(struct kgsl_device *device,
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
unsigned int *cmds = cmds_orig;
cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds);
cmds += cp_wait_for_me(adreno_dev, cmds);
/* CP switches the pagetable and flushes the Caches */
*cmds++ = cp_packet(adreno_dev, CP_SMMU_TABLE_UPDATE, 3);
*cmds++ = lower_32_bits(ttbr0);
@ -222,11 +192,6 @@ static unsigned int _adreno_iommu_set_pt_v2_a5xx(struct kgsl_device *device,
*cmds++ = upper_32_bits(ttbr0);
*cmds++ = contextidr;
/* release all commands with wait_for_me */
cmds += cp_wait_for_me(adreno_dev, cmds);
cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds);
return cmds - cmds_orig;
}
@ -239,9 +204,6 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device,
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
unsigned int *cmds = cmds_orig;
cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds);
cmds += cp_wait_for_me(adreno_dev, cmds);
/* CP switches the pagetable and flushes the Caches */
*cmds++ = cp_packet(adreno_dev, CP_SMMU_TABLE_UPDATE, 4);
*cmds++ = lower_32_bits(ttbr0);
@ -256,11 +218,6 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device,
*cmds++ = upper_32_bits(ttbr0);
*cmds++ = contextidr;
/* release all commands with wait_for_me */
cmds += cp_wait_for_me(adreno_dev, cmds);
cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds);
return cmds - cmds_orig;
}
@ -281,42 +238,22 @@ unsigned int adreno_iommu_set_pt_generate_cmds(
struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
u64 ttbr0;
u32 contextidr;
unsigned int *cmds_orig = cmds;
ttbr0 = kgsl_mmu_pagetable_get_ttbr0(pt);
contextidr = kgsl_mmu_pagetable_get_contextidr(pt);
cmds += adreno_iommu_set_apriv(adreno_dev, cmds, 1);
/*
* Adding an indirect buffer ensures that the prefetch stalls until
* the commands in indirect buffer have completed. We need to stall
* prefetch with a nop indirect buffer when updating pagetables
* because it provides stabler synchronization.
*/
cmds += cp_wait_for_me(adreno_dev, cmds);
*cmds++ = cp_mem_packet(adreno_dev, CP_INDIRECT_BUFFER_PFE, 2, 1);
cmds += cp_gpuaddr(adreno_dev, cmds,
iommu->setstate->gpuaddr + KGSL_IOMMU_SETSTATE_NOP_OFFSET);
*cmds++ = 2;
cmds += cp_wait_for_idle(adreno_dev, cmds);
if (adreno_is_a6xx(adreno_dev))
cmds += _adreno_iommu_set_pt_v2_a6xx(device, cmds,
return _adreno_iommu_set_pt_v2_a6xx(device, cmds,
ttbr0, contextidr, rb,
ctx->cb_num);
else if (adreno_is_a5xx(adreno_dev))
cmds += _adreno_iommu_set_pt_v2_a5xx(device, cmds,
return _adreno_iommu_set_pt_v2_a5xx(device, cmds,
ttbr0, contextidr, rb);
else if (adreno_is_a3xx(adreno_dev))
cmds += _adreno_iommu_set_pt_v2_a3xx(device, cmds,
return _adreno_iommu_set_pt_v2_a3xx(device, cmds,
ttbr0, contextidr);
/* invalidate all base pointers */
cmds += cp_invalidate_state(adreno_dev, cmds);
cmds += adreno_iommu_set_apriv(adreno_dev, cmds, 0);
return cmds - cmds_orig;
return 0;
}
/**
@ -440,18 +377,23 @@ void adreno_iommu_init(struct adreno_device *adreno_dev)
if (kgsl_mmu_get_mmutype(device) == KGSL_MMU_TYPE_NONE)
return;
if (!adreno_is_a3xx(adreno_dev))
return;
/*
* A nop is required in an indirect buffer when switching
* 3xx requres a nop in an indirect buffer when switching
* pagetables in-stream
*/
if (IS_ERR_OR_NULL(iommu->setstate)) {
iommu->setstate = kgsl_allocate_global(device, PAGE_SIZE,
KGSL_MEMFLAGS_GPUREADONLY, 0, "setstate");
kgsl_sharedmem_writel(device, iommu->setstate,
KGSL_IOMMU_SETSTATE_NOP_OFFSET,
cp_packet(adreno_dev, CP_NOP, 1));
kgsl_sharedmem_writel(device, iommu->setstate,
KGSL_IOMMU_SETSTATE_NOP_OFFSET,
cp_type3_packet(CP_NOP, 1));
}
/* Enable guard page MMU feature for A3xx and A4xx targets only */
if (adreno_is_a3xx(adreno_dev))
device->mmu.features |= KGSL_MMU_NEED_GUARD_PAGE;
device->mmu.features |= KGSL_MMU_NEED_GUARD_PAGE;
}
/**

View file

@ -360,30 +360,6 @@ static inline uint cp_wait_for_idle(struct adreno_device *adreno_dev,
return cmds - start;
}
/**
* cp_invalidate_state - common function for invalidating cp
* state
* @adreno_dev: The adreno device
* @cmds: command pointer to add gpuaddr
*/
static inline uint cp_invalidate_state(struct adreno_device *adreno_dev,
uint *cmds)
{
uint *start = cmds;
if (ADRENO_GPUREV(adreno_dev) < 500) {
*cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
*cmds++ = 0x7fff;
} else {
*cmds++ = cp_type7_packet(CP_SET_DRAW_STATE, 3);
*cmds++ = 0x40000;
*cmds++ = 0;
*cmds++ = 0;
}
return cmds - start;
}
static inline u32 cp_protected_mode(struct adreno_device *adreno_dev,
u32 *cmds, int on)
{

View file

@ -208,18 +208,6 @@ static inline void parse_ib(struct kgsl_device *device,
}
static inline bool iommu_is_setstate_addr(struct kgsl_device *device,
uint64_t gpuaddr, uint64_t size)
{
struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
if (kgsl_mmu_get_mmutype(device) != KGSL_MMU_TYPE_IOMMU)
return false;
return kgsl_gpuaddr_in_memdesc(iommu->setstate, gpuaddr,
size);
}
static void dump_all_ibs(struct kgsl_device *device,
struct adreno_ringbuffer *rb,
struct kgsl_snapshot *snapshot)
@ -227,6 +215,7 @@ static void dump_all_ibs(struct kgsl_device *device,
int index = 0;
unsigned int *rbptr;
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
rbptr = rb->buffer_desc->hostptr;
@ -248,7 +237,8 @@ static void dump_all_ibs(struct kgsl_device *device,
}
/* Don't parse known global IBs */
if (iommu_is_setstate_addr(device, ibaddr, ibsize))
if (kgsl_gpuaddr_in_memdesc(iommu->setstate,
ibaddr, ibsize))
continue;
if (kgsl_gpuaddr_in_memdesc(adreno_dev->pwron_fixup,
@ -384,6 +374,7 @@ static void snapshot_rb_ibs(struct kgsl_device *device,
parse_ibs = 0;
if (parse_ibs && adreno_cmd_is_ib(adreno_dev, rbptr[index])) {
struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
uint64_t ibaddr;
uint64_t ibsize;
@ -399,7 +390,8 @@ static void snapshot_rb_ibs(struct kgsl_device *device,
index = (index + 1) % KGSL_RB_DWORDS;
/* Don't parse known global IBs */
if (iommu_is_setstate_addr(device, ibaddr, ibsize))
if (kgsl_gpuaddr_in_memdesc(iommu->setstate,
ibaddr, ibsize))
continue;
if (kgsl_gpuaddr_in_memdesc(adreno_dev->pwron_fixup,

View file

@ -7,28 +7,17 @@
#include "adreno.h"
struct adreno_sysfs_attribute {
struct adreno_sysfs_attribute_u32 {
struct device_attribute attr;
unsigned int (*show)(struct adreno_device *adreno_dev);
int (*store)(struct adreno_device *adreno_dev, unsigned int val);
u32 (*show)(struct adreno_device *adreno_dev);
int (*store)(struct adreno_device *adreno_dev, u32 val);
};
#define _ADRENO_SYSFS_ATTR(_name, __show, __store) \
struct adreno_sysfs_attribute adreno_attr_##_name = { \
.attr = __ATTR(_name, 0644, __show, __store), \
.show = _ ## _name ## _show, \
.store = _ ## _name ## _store, \
}
#define _ADRENO_SYSFS_ATTR_RO(_name, __show) \
struct adreno_sysfs_attribute adreno_attr_##_name = { \
.attr = __ATTR(_name, 0444, __show, NULL), \
.show = _ ## _name ## _show, \
.store = NULL, \
}
#define ADRENO_SYSFS_ATTR(_a) \
container_of((_a), struct adreno_sysfs_attribute, attr)
struct adreno_sysfs_attribute_bool {
struct device_attribute attr;
bool (*show)(struct adreno_device *adreno_dev);
int (*store)(struct adreno_device *adreno_dev, bool val);
};
static int _ft_policy_store(struct adreno_device *adreno_dev,
unsigned int val)
@ -54,13 +43,10 @@ static int _preempt_level_store(struct adreno_device *adreno_dev,
static unsigned int _preempt_level_show(struct adreno_device *adreno_dev)
{
struct adreno_preemption *preempt = &adreno_dev->preempt;
return preempt->preempt_level;
return adreno_dev->preempt.preempt_level;
}
static int _usesgmem_store(struct adreno_device *adreno_dev,
unsigned int val)
static int _usesgmem_store(struct adreno_device *adreno_dev, bool val)
{
struct adreno_preemption *preempt = &adreno_dev->preempt;
@ -68,15 +54,12 @@ static int _usesgmem_store(struct adreno_device *adreno_dev,
return 0;
}
static unsigned int _usesgmem_show(struct adreno_device *adreno_dev)
static bool _usesgmem_show(struct adreno_device *adreno_dev)
{
struct adreno_preemption *preempt = &adreno_dev->preempt;
return preempt->usesgmem;
return adreno_dev->preempt.usesgmem;
}
static int _skipsaverestore_store(struct adreno_device *adreno_dev,
unsigned int val)
static int _skipsaverestore_store(struct adreno_device *adreno_dev, bool val)
{
struct adreno_preemption *preempt = &adreno_dev->preempt;
@ -84,11 +67,9 @@ static int _skipsaverestore_store(struct adreno_device *adreno_dev,
return 0;
}
static unsigned int _skipsaverestore_show(struct adreno_device *adreno_dev)
static bool _skipsaverestore_show(struct adreno_device *adreno_dev)
{
struct adreno_preemption *preempt = &adreno_dev->preempt;
return preempt->skipsaverestore;
return adreno_dev->preempt.skipsaverestore;
}
static int _ft_pagefault_policy_store(struct adreno_device *adreno_dev,
@ -118,46 +99,44 @@ static unsigned int _ft_pagefault_policy_show(struct adreno_device *adreno_dev)
}
static int _gpu_llc_slice_enable_store(struct adreno_device *adreno_dev,
unsigned int val)
bool val)
{
adreno_dev->gpu_llc_slice_enable = val ? true : false;
adreno_dev->gpu_llc_slice_enable = val;
return 0;
}
static unsigned int _gpu_llc_slice_enable_show(struct adreno_device *adreno_dev)
static bool _gpu_llc_slice_enable_show(struct adreno_device *adreno_dev)
{
return adreno_dev->gpu_llc_slice_enable;
}
static int _gpuhtw_llc_slice_enable_store(struct adreno_device *adreno_dev,
unsigned int val)
bool val)
{
adreno_dev->gpuhtw_llc_slice_enable = val ? true : false;
adreno_dev->gpuhtw_llc_slice_enable = val;
return 0;
}
static unsigned int
_gpuhtw_llc_slice_enable_show(struct adreno_device *adreno_dev)
static bool _gpuhtw_llc_slice_enable_show(struct adreno_device *adreno_dev)
{
return adreno_dev->gpuhtw_llc_slice_enable;
}
static int _ft_long_ib_detect_store(struct adreno_device *adreno_dev,
unsigned int val)
static int _ft_long_ib_detect_store(struct adreno_device *adreno_dev, bool val)
{
adreno_dev->long_ib_detect = val;
return 0;
}
static unsigned int _ft_long_ib_detect_show(struct adreno_device *adreno_dev)
static bool _ft_long_ib_detect_show(struct adreno_device *adreno_dev)
{
return adreno_dev->long_ib_detect;
}
static unsigned int _ft_hang_intr_status_show(struct adreno_device *adreno_dev)
static bool _ft_hang_intr_status_show(struct adreno_device *adreno_dev)
{
/* Hang interrupt is always on on all targets */
return 1;
return true;
}
static int _pwrctrl_store(struct adreno_device *adreno_dev,
@ -180,8 +159,7 @@ static int _pwrctrl_store(struct adreno_device *adreno_dev,
return 0;
}
static int _preemption_store(struct adreno_device *adreno_dev,
unsigned int val)
static int _preemption_store(struct adreno_device *adreno_dev, bool val)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
struct kgsl_context *context;
@ -216,60 +194,57 @@ static int _preemption_store(struct adreno_device *adreno_dev,
return 0;
}
static unsigned int _preemption_show(struct adreno_device *adreno_dev)
static bool _preemption_show(struct adreno_device *adreno_dev)
{
return adreno_is_preemption_enabled(adreno_dev);
}
static int _hwcg_store(struct adreno_device *adreno_dev,
unsigned int val)
static int _hwcg_store(struct adreno_device *adreno_dev, bool val)
{
return _pwrctrl_store(adreno_dev, val, ADRENO_HWCG_CTRL);
}
static unsigned int _hwcg_show(struct adreno_device *adreno_dev)
static bool _hwcg_show(struct adreno_device *adreno_dev)
{
return test_bit(ADRENO_HWCG_CTRL, &adreno_dev->pwrctrl_flag);
}
static int _throttling_store(struct adreno_device *adreno_dev,
unsigned int val)
static int _throttling_store(struct adreno_device *adreno_dev, bool val)
{
return _pwrctrl_store(adreno_dev, val, ADRENO_THROTTLING_CTRL);
}
static unsigned int _throttling_show(struct adreno_device *adreno_dev)
static bool _throttling_show(struct adreno_device *adreno_dev)
{
return test_bit(ADRENO_THROTTLING_CTRL, &adreno_dev->pwrctrl_flag);
}
static int _sptp_pc_store(struct adreno_device *adreno_dev,
unsigned int val)
static int _sptp_pc_store(struct adreno_device *adreno_dev, bool val)
{
return _pwrctrl_store(adreno_dev, val, ADRENO_SPTP_PC_CTRL);
}
static unsigned int _sptp_pc_show(struct adreno_device *adreno_dev)
static bool _sptp_pc_show(struct adreno_device *adreno_dev)
{
return test_bit(ADRENO_SPTP_PC_CTRL, &adreno_dev->pwrctrl_flag);
}
static int _lm_store(struct adreno_device *adreno_dev, unsigned int val)
static int _lm_store(struct adreno_device *adreno_dev, bool val)
{
return _pwrctrl_store(adreno_dev, val, ADRENO_LM_CTRL);
}
static unsigned int _lm_show(struct adreno_device *adreno_dev)
static bool _lm_show(struct adreno_device *adreno_dev)
{
return test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag);
}
static int _ifpc_store(struct adreno_device *adreno_dev, unsigned int val)
static int _ifpc_store(struct adreno_device *adreno_dev, bool val)
{
return gmu_core_dev_ifpc_store(KGSL_DEVICE(adreno_dev), val);
}
static unsigned int _ifpc_show(struct adreno_device *adreno_dev)
static bool _ifpc_show(struct adreno_device *adreno_dev)
{
return gmu_core_dev_ifpc_show(KGSL_DEVICE(adreno_dev));
}
@ -286,12 +261,12 @@ static unsigned int _preempt_count_show(struct adreno_device *adreno_dev)
return preempt->count;
}
static unsigned int _acd_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);
}
static int _acd_store(struct adreno_device *adreno_dev, unsigned int val)
static int _acd_store(struct adreno_device *adreno_dev, bool val)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
@ -306,16 +281,20 @@ static ssize_t _sysfs_store_u32(struct device *dev,
const char *buf, size_t count)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_get_drvdata(dev));
struct adreno_sysfs_attribute *_attr = ADRENO_SYSFS_ATTR(attr);
unsigned int val = 0;
struct adreno_sysfs_attribute_u32 *_attr =
container_of(attr, struct adreno_sysfs_attribute_u32, attr);
u32 val;
int ret;
ret = kgsl_sysfs_store(buf, &val);
ret = kstrtou32(buf, 0, &val);
if (ret)
return ret;
if (!ret && _attr->store)
ret = _attr->store(adreno_dev, val);
ret = _attr->store(adreno_dev, val);
if (ret)
return ret;
return (ssize_t) ret < 0 ? ret : count;
return count;
}
static ssize_t _sysfs_show_u32(struct device *dev,
@ -323,13 +302,10 @@ static ssize_t _sysfs_show_u32(struct device *dev,
char *buf)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_get_drvdata(dev));
struct adreno_sysfs_attribute *_attr = ADRENO_SYSFS_ATTR(attr);
unsigned int val = 0;
struct adreno_sysfs_attribute_u32 *_attr =
container_of(attr, struct adreno_sysfs_attribute_u32, attr);
if (_attr->show)
val = _attr->show(adreno_dev);
return scnprintf(buf, PAGE_SIZE, "0x%X\n", val);
return scnprintf(buf, PAGE_SIZE, "0x%X\n", _attr->show(adreno_dev));
}
static ssize_t _sysfs_store_bool(struct device *dev,
@ -337,16 +313,20 @@ static ssize_t _sysfs_store_bool(struct device *dev,
const char *buf, size_t count)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_get_drvdata(dev));
struct adreno_sysfs_attribute *_attr = ADRENO_SYSFS_ATTR(attr);
unsigned int val = 0;
struct adreno_sysfs_attribute_bool *_attr =
container_of(attr, struct adreno_sysfs_attribute_bool, attr);
bool val;
int ret;
ret = kgsl_sysfs_store(buf, &val);
ret = kstrtobool(buf, &val);
if (ret)
return ret;
if (!ret && _attr->store)
ret = _attr->store(adreno_dev, val ? 1 : 0);
ret = _attr->store(adreno_dev, val);
if (ret)
return ret;
return (ssize_t) ret < 0 ? ret : count;
return count;
}
static ssize_t _sysfs_show_bool(struct device *dev,
@ -354,26 +334,37 @@ static ssize_t _sysfs_show_bool(struct device *dev,
char *buf)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_get_drvdata(dev));
struct adreno_sysfs_attribute *_attr = ADRENO_SYSFS_ATTR(attr);
unsigned int val = 0;
struct adreno_sysfs_attribute_bool *_attr =
container_of(attr, struct adreno_sysfs_attribute_bool, attr);
if (_attr->show)
val = _attr->show(adreno_dev);
return scnprintf(buf, PAGE_SIZE, "%d\n", val);
return scnprintf(buf, PAGE_SIZE, "%d\n", _attr->show(adreno_dev));
}
#define ADRENO_SYSFS_BOOL(_name) \
_ADRENO_SYSFS_ATTR(_name, _sysfs_show_bool, _sysfs_store_bool)
struct adreno_sysfs_attribute_bool adreno_attr_##_name = { \
.attr = __ATTR(_name, 0644, _sysfs_show_bool, _sysfs_store_bool), \
.show = _ ## _name ## _show, \
.store = _ ## _name ## _store, \
}
#define ADRENO_SYSFS_RO_BOOL(_name) \
_ADRENO_SYSFS_ATTR_RO(_name, _sysfs_show_bool)
struct adreno_sysfs_attribute_bool adreno_attr_##_name = { \
.attr = __ATTR(_name, 0444, _sysfs_show_bool, NULL), \
.show = _ ## _name ## _show, \
}
#define ADRENO_SYSFS_U32(_name) \
_ADRENO_SYSFS_ATTR(_name, _sysfs_show_u32, _sysfs_store_u32)
struct adreno_sysfs_attribute_u32 adreno_attr_##_name = { \
.attr = __ATTR(_name, 0644, _sysfs_show_u32, _sysfs_store_u32), \
.show = _ ## _name ## _show, \
.store = _ ## _name ## _store, \
}
#define ADRENO_SYSFS_RO_U32(_name) \
_ADRENO_SYSFS_ATTR_RO(_name, _sysfs_show_u32)
struct adreno_sysfs_attribute_u32 adreno_attr_##_name = { \
.attr = __ATTR(_name, 0444, _sysfs_show_u32, NULL), \
.show = _ ## _name ## _show, \
}
static ADRENO_SYSFS_U32(ft_policy);
static ADRENO_SYSFS_U32(ft_pagefault_policy);

View file

@ -4972,9 +4972,6 @@ int kgsl_device_platform_probe(struct kgsl_device *device)
if (status)
goto error_close_mmu;
/* Initialize the memory pools */
kgsl_init_page_pools(device->pdev);
device->events_wq = alloc_workqueue("kgsl-events",
WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS, 0);
@ -5000,8 +4997,6 @@ void kgsl_device_platform_remove(struct kgsl_device *device)
kgsl_device_snapshot_close(device);
kgsl_exit_page_pools();
kobject_put(device->gpu_sysfs_kobj);
idr_destroy(&device->context_idr);
@ -5022,6 +5017,8 @@ void kgsl_device_platform_remove(struct kgsl_device *device)
void kgsl_core_exit(void)
{
kgsl_exit_page_pools();
kgsl_events_exit();
kgsl_core_debugfs_close();
@ -5111,6 +5108,9 @@ int __init kgsl_core_init(void)
kgsl_sharedmem_init_sysfs();
/* Initialize the memory pools */
kgsl_probe_page_pools();
INIT_LIST_HEAD(&kgsl_driver.process_list);
INIT_LIST_HEAD(&kgsl_driver.pagetable_list);

View file

@ -1209,7 +1209,7 @@ static int kgsl_iommu_init(struct kgsl_mmu *mmu)
struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
int status;
int status = 0;
mmu->features |= KGSL_MMU_PAGED;
@ -1236,13 +1236,6 @@ static int kgsl_iommu_init(struct kgsl_mmu *mmu)
}
}
iommu->setstate = kgsl_allocate_global(device, PAGE_SIZE,
KGSL_MEMFLAGS_GPUREADONLY, 0, "setstate");
status = PTR_ERR_OR_ZERO(iommu->setstate);
if (status)
goto done;
device->qdss_desc = kgsl_allocate_global_fixed(device,
"qcom,gpu-qdss-stm", "gpu-qdss");

View file

@ -57,20 +57,36 @@ _kgsl_get_pool_from_order(int order)
return index >= 0 ? &kgsl_pools[index] : NULL;
}
static void kgsl_pool_sync_for_device(struct device *dev, struct page *page,
size_t size)
{
struct scatterlist sg;
/* The caller may choose not to specify a device on purpose */
if (!dev)
return;
sg_init_table(&sg, 1);
sg_set_page(&sg, page, size, 0);
sg_dma_address(&sg) = page_to_phys(page);
dma_sync_sg_for_device(dev, &sg, 1, DMA_BIDIRECTIONAL);
}
/* Map the page into kernel and zero it out */
static void
_kgsl_pool_zero_page(struct page *p, unsigned int pool_order)
_kgsl_pool_zero_page(struct page *p, unsigned int pool_order,
struct device *dev)
{
int i;
for (i = 0; i < (1 << pool_order); i++) {
struct page *page = nth_page(p, i);
void *addr = kmap_atomic(page);
memset(addr, 0, PAGE_SIZE);
dmac_flush_range(addr, addr + PAGE_SIZE);
kunmap_atomic(addr);
clear_highpage(page);
}
kgsl_pool_sync_for_device(dev, p, PAGE_SIZE << pool_order);
}
/* Add a page to specified pool */
@ -80,8 +96,6 @@ _kgsl_pool_add_page(struct kgsl_page_pool *pool, struct page *p)
if (!p)
return;
_kgsl_pool_zero_page(p, pool->pool_order);
spin_lock(&pool->list_lock);
list_add_tail(&p->lru, &pool->page_list);
pool->page_count++;
@ -327,7 +341,8 @@ static int kgsl_get_page_size(size_t size, unsigned int align)
* Return total page count on success and negative value on failure
*/
static int kgsl_pool_alloc_page(int *page_size, struct page **pages,
unsigned int pages_len, unsigned int *align)
unsigned int pages_len, unsigned int *align,
struct device *dev)
{
int j;
int pcount = 0;
@ -355,7 +370,6 @@ static int kgsl_pool_alloc_page(int *page_size, struct page **pages,
} else
return -ENOMEM;
}
_kgsl_pool_zero_page(page, order);
goto done;
}
@ -375,7 +389,6 @@ static int kgsl_pool_alloc_page(int *page_size, struct page **pages,
page = alloc_pages(gfp_mask, order);
if (page == NULL)
return -ENOMEM;
_kgsl_pool_zero_page(page, order);
goto done;
}
}
@ -405,11 +418,11 @@ static int kgsl_pool_alloc_page(int *page_size, struct page **pages,
} else
return -ENOMEM;
}
_kgsl_pool_zero_page(page, order);
}
done:
_kgsl_pool_zero_page(page, order, dev);
for (j = 0; j < (*page_size >> PAGE_SHIFT); j++) {
p = nth_page(page, j);
pages[pcount] = p;
@ -426,7 +439,7 @@ eagain:
return -EAGAIN;
}
int kgsl_pool_alloc_pages(u64 size, struct page ***pages)
int kgsl_pool_alloc_pages(u64 size, struct page ***pages, struct device *dev)
{
int count = 0;
int npages = size >> PAGE_SHIFT;
@ -444,7 +457,7 @@ int kgsl_pool_alloc_pages(u64 size, struct page ***pages)
while (len) {
int ret = kgsl_pool_alloc_page(&page_size, &local[count],
npages, &align);
npages, &align, dev);
if (ret == -EAGAIN)
continue;
@ -586,12 +599,12 @@ static int kgsl_of_parse_mempool(struct kgsl_page_pool *pool,
return 0;
}
static void kgsl_of_get_mempools(struct device_node *parent)
void kgsl_probe_page_pools(void)
{
struct device_node *node, *child;
int index = 0;
node = of_find_compatible_node(parent, NULL, "qcom,gpu-mempools");
node = of_find_compatible_node(NULL, NULL, "qcom,gpu-mempools");
if (!node)
return;
@ -611,12 +624,6 @@ static void kgsl_of_get_mempools(struct device_node *parent)
kgsl_num_pools = index;
of_node_put(node);
}
void kgsl_init_page_pools(struct platform_device *pdev)
{
/* Get GPU mempools data and configure pools */
kgsl_of_get_mempools(pdev->dev.of_node);
/* Initialize shrinker */
register_shrinker(&kgsl_pool_shrinker);

View file

@ -11,12 +11,17 @@ void kgsl_pool_free_sgt(struct sg_table *sgt);
* kgsl_pool_alloc_pages - Allocate an array of pages from the pool
* @size: Size of the allocation
* @pages: Pointer to an array of pages
* @dev: A &struct device pointer
*
* Allocate a list of pages and store it in the pointer pointed to by @pages.
* @dev specifies a &struct device that is used to call dma_sync_sg_for_device
* to synchronize the caches. If @dev isn't specified, no cache maintenance
* will be performed.
*
* Return: The number of entries in the array pointed to by @page or negative
* on error.
*/
int kgsl_pool_alloc_pages(u64 size, struct page ***pages);
int kgsl_pool_alloc_pages(u64 size, struct page ***pages, struct device *dev);
/**
* kgsl_pool_free_pages - Free pages in an pages array
@ -28,7 +33,15 @@ int kgsl_pool_alloc_pages(u64 size, struct page ***pages);
* otherwise they are given back to system.
*/
void kgsl_pool_free_pages(struct page **pages, unsigned int page_count);
void kgsl_init_page_pools(struct platform_device *pdev);
/**
* kgsl_probe_page_pools - Initialize the memory pools pools
*/
void kgsl_probe_page_pools(void);
/**
* kgsl_exit_page_pools - Free outstanding pooled memory
*/
void kgsl_exit_page_pools(void);
#endif /* __KGSL_POOL_H */

View file

@ -812,7 +812,11 @@ kgsl_sharedmem_writel(struct kgsl_device *device,
{
uint32_t *dst;
if (WARN_ON(memdesc == NULL || memdesc->hostptr == NULL))
/* Quietly return if the memdesc isn't valid */
if (IS_ERR_OR_NULL(memdesc))
return -EINVAL;
if (WARN_ON(memdesc->hostptr == NULL))
return -EINVAL;
WARN_ON(offsetbytes % sizeof(uint32_t) != 0);
@ -1074,7 +1078,7 @@ static int kgsl_alloc_secure_pages(struct kgsl_device *device,
memdesc->priv |= priv;
memdesc->ops = &kgsl_secure_pool_ops;
count = kgsl_pool_alloc_pages(size, &pages);
count = kgsl_pool_alloc_pages(size, &pages, device->dev);
if (count < 0)
return count;
@ -1129,7 +1133,7 @@ static int kgsl_alloc_pages(struct kgsl_device *device,
memdesc->priv |= priv;
memdesc->ops = &kgsl_pool_ops;
count = kgsl_pool_alloc_pages(size, &pages);
count = kgsl_pool_alloc_pages(size, &pages, device->dev);
if (count < 0)
return count;