mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 13:49:24 -04:00
Merge "msm: kgsl: Hook preemption sysfs nodes to hwscheduling"
This commit is contained in:
commit
689186736c
9 changed files with 401 additions and 176 deletions
|
|
@ -78,6 +78,7 @@
|
|||
#define HFI_VALUE_LOG_EVENT_OFF 113
|
||||
#define HFI_VALUE_DCVS_OBJ 114
|
||||
#define HFI_VALUE_LM_CS0 115
|
||||
#define HFI_VALUE_PREEMPT_COUNT 120
|
||||
|
||||
#define HFI_VALUE_GLOBAL_TOKEN 0xFFFFFFFF
|
||||
|
||||
|
|
|
|||
|
|
@ -987,18 +987,23 @@ static int a6xx_hwsched_bind(struct device *dev, struct device *master,
|
|||
void *data)
|
||||
{
|
||||
struct kgsl_device *device = dev_get_drvdata(master);
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
|
||||
int ret;
|
||||
|
||||
ret = a6xx_gmu_probe(device, to_platform_device(dev));
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ret = a6xx_hwsched_hfi_probe(ADRENO_DEVICE(device));
|
||||
ret = a6xx_hwsched_hfi_probe(adreno_dev);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (!ret) {
|
||||
set_bit(GMU_DISPATCH, &device->gmu_core.flags);
|
||||
return 0;
|
||||
}
|
||||
set_bit(GMU_DISPATCH, &device->gmu_core.flags);
|
||||
|
||||
if (ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION))
|
||||
set_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
a6xx_gmu_remove(device);
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ static irqreturn_t a6xx_hwsched_hfi_handler(int irq, void *data)
|
|||
}
|
||||
|
||||
/* Ignore OOB bits */
|
||||
status &= GENMASK(31, 31 - (oob_max - 1));
|
||||
status &= GENMASK(31 - (oob_max - 1), 0);
|
||||
|
||||
if (status & ~hfi->irq_mask)
|
||||
dev_err_ratelimited(&gmu->pdev->dev,
|
||||
|
|
@ -545,6 +545,9 @@ static struct mem_alloc_entry *get_mem_alloc_entry(
|
|||
if (!(desc->flags & MEMFLAG_GFX_WRITEABLE))
|
||||
flags |= KGSL_MEMFLAGS_GPUREADONLY;
|
||||
|
||||
if (desc->flags & MEMFLAG_GFX_SECURE)
|
||||
flags |= KGSL_MEMFLAGS_SECURE;
|
||||
|
||||
entry->gpu_md = kgsl_allocate_global(device, desc->size, flags, priv,
|
||||
memkind_string);
|
||||
if (IS_ERR(entry->gpu_md)) {
|
||||
|
|
@ -730,6 +733,26 @@ static void enable_async_hfi(struct adreno_device *adreno_dev)
|
|||
(u32)~hfi->irq_mask);
|
||||
}
|
||||
|
||||
static int enable_preemption(struct adreno_device *adreno_dev)
|
||||
{
|
||||
u32 data;
|
||||
|
||||
if (!adreno_is_preemption_enabled(adreno_dev))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Bits [0:1] contains the preemption level
|
||||
* Bit 2 is to enable/disable gmem save/restore
|
||||
* Bit 3 is to enable/disable skipsaverestore
|
||||
*/
|
||||
data = FIELD_PREP(GENMASK(1, 0), adreno_dev->preempt.preempt_level) |
|
||||
FIELD_PREP(BIT(2), adreno_dev->preempt.usesgmem) |
|
||||
FIELD_PREP(BIT(3), adreno_dev->preempt.skipsaverestore);
|
||||
|
||||
return a6xx_hfi_send_feature_ctrl(adreno_dev, HFI_FEATURE_PREEMPTION, 1,
|
||||
data);
|
||||
}
|
||||
|
||||
int a6xx_hwsched_hfi_start(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);
|
||||
|
|
@ -766,7 +789,11 @@ int a6xx_hwsched_hfi_start(struct adreno_device *adreno_dev)
|
|||
|
||||
ret = a6xx_hfi_send_feature_ctrl(adreno_dev, HFI_FEATURE_KPROF, 1, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
ret = enable_preemption(adreno_dev);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = a6xx_hfi_send_core_fw_start(adreno_dev);
|
||||
if (ret)
|
||||
|
|
@ -1326,3 +1353,40 @@ void a6xx_hwsched_context_detach(struct adreno_context *drawctxt)
|
|||
|
||||
mutex_unlock(&device->mutex);
|
||||
}
|
||||
|
||||
int a6xx_hwsched_preempt_count_get(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct hfi_get_value_cmd cmd;
|
||||
struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);
|
||||
struct a6xx_hwsched_hfi *hfi = to_a6xx_hwsched_hfi(adreno_dev);
|
||||
u32 seqnum = atomic_inc_return(&gmu->hfi.seqnum);
|
||||
struct pending_cmd pending_ack;
|
||||
int rc;
|
||||
|
||||
if (device->state != KGSL_STATE_ACTIVE)
|
||||
return 0;
|
||||
|
||||
CMD_MSG_HDR(cmd, H2F_MSG_GET_VALUE);
|
||||
|
||||
cmd.hdr = MSG_HDR_SET_SEQNUM(cmd.hdr, seqnum);
|
||||
cmd.type = HFI_VALUE_PREEMPT_COUNT;
|
||||
cmd.subtype = 0;
|
||||
|
||||
add_waiter(hfi, cmd.hdr, &pending_ack);
|
||||
|
||||
rc = a6xx_hfi_cmdq_write(adreno_dev, (u32 *)&cmd);
|
||||
if (rc)
|
||||
goto done;
|
||||
|
||||
rc = wait_ack_completion(adreno_dev, &pending_ack);
|
||||
if (rc)
|
||||
goto done;
|
||||
|
||||
rc = check_ack_failure(adreno_dev, &pending_ack);
|
||||
|
||||
done:
|
||||
del_waiter(hfi, &pending_ack);
|
||||
|
||||
return rc ? rc : pending_ack.results[2];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,9 @@ enum mem_kind {
|
|||
/* Host initializes the buffer */
|
||||
#define MEMFLAG_HOST_INIT BIT(9)
|
||||
|
||||
/* Gfx buffer needs to be secure */
|
||||
#define MEMFLAG_GFX_SECURE BIT(12)
|
||||
|
||||
struct mem_alloc_entry {
|
||||
struct hfi_mem_alloc_desc desc;
|
||||
struct kgsl_memdesc *gpu_md;
|
||||
|
|
@ -214,4 +217,15 @@ void a6xx_hwsched_context_detach(struct adreno_context *drawctxt);
|
|||
|
||||
/* Helper function to get to a6xx hwsched hfi device from adreno device */
|
||||
struct a6xx_hwsched_hfi *to_a6xx_hwsched_hfi(struct adreno_device *adreno_dev);
|
||||
|
||||
/**
|
||||
* a6xx_hwsched_preempt_count_get - Get preemption count from GMU
|
||||
* @adreno_dev: Pointer to adreno device
|
||||
*
|
||||
* This function sends a GET_VALUE HFI packet to get the number of
|
||||
* preemptions completed since last SLUMBER exit.
|
||||
*
|
||||
* Return: Preemption count on success or negative error on failure
|
||||
*/
|
||||
int a6xx_hwsched_preempt_count_get(struct adreno_device *adreno_dev);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <soc/qcom/msm_performance.h>
|
||||
#include "adreno.h"
|
||||
#include "adreno_sysfs.h"
|
||||
#include "adreno_trace.h"
|
||||
#include "kgsl_gmu_core.h"
|
||||
#include "kgsl_timeline.h"
|
||||
|
|
@ -858,8 +860,7 @@ static void dispatcher_handle_jobs_list(struct adreno_device *adreno_dev,
|
|||
llist_for_each_entry_safe(job, next, list, node) {
|
||||
int ret;
|
||||
|
||||
if (adreno_gpu_stopped(adreno_dev) ||
|
||||
adreno_drawctxt_bad(job->drawctxt)) {
|
||||
if (adreno_drawctxt_bad(job->drawctxt)) {
|
||||
kgsl_context_put(&job->drawctxt->base);
|
||||
kmem_cache_free(jobs_cache, job);
|
||||
continue;
|
||||
|
|
@ -879,6 +880,16 @@ static void dispatcher_handle_jobs_list(struct adreno_device *adreno_dev,
|
|||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If gpu is in fault or dispatcher is halted, add back the jobs
|
||||
* so that they are processed after recovery or when dispatcher
|
||||
* is resumed.
|
||||
*/
|
||||
if (adreno_gpu_stopped(adreno_dev)) {
|
||||
llist_add(&job->node, &dispatcher->jobs[id]);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = dispatcher_context_sendcmds(adreno_dev, job->drawctxt);
|
||||
|
||||
/*
|
||||
|
|
@ -2649,6 +2660,116 @@ void adreno_dispatcher_stop_fault_timer(struct kgsl_device *device)
|
|||
del_timer_sync(&dispatcher->fault_timer);
|
||||
}
|
||||
|
||||
static int _skipsaverestore_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
adreno_dev->preempt.skipsaverestore = val ? true : false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool _skipsaverestore_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.skipsaverestore;
|
||||
}
|
||||
|
||||
static int _usesgmem_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
adreno_dev->preempt.usesgmem = val ? true : false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool _usesgmem_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.usesgmem;
|
||||
}
|
||||
|
||||
static int _preempt_level_store(struct adreno_device *adreno_dev,
|
||||
unsigned int val)
|
||||
{
|
||||
adreno_dev->preempt.preempt_level = min_t(unsigned int, val, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int _preempt_level_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.preempt_level;
|
||||
}
|
||||
|
||||
static void change_preemption(struct adreno_device *adreno_dev, void *priv)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct kgsl_context *context;
|
||||
struct adreno_context *drawctxt;
|
||||
struct adreno_ringbuffer *rb;
|
||||
int id, i, ret;
|
||||
|
||||
/* Make sure all ringbuffers are finished */
|
||||
FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
|
||||
ret = adreno_ringbuffer_waittimestamp(rb, rb->timestamp,
|
||||
2 * 1000);
|
||||
if (ret) {
|
||||
dev_err(device->dev,
|
||||
"Cannot disable preemption because couldn't idle ringbuffer[%d] ret: %d\n",
|
||||
rb->id, ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
change_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv);
|
||||
adreno_dev->cur_rb = &adreno_dev->ringbuffers[0];
|
||||
adreno_dev->next_rb = NULL;
|
||||
adreno_dev->prev_rb = NULL;
|
||||
|
||||
/* Update the ringbuffer for each draw context */
|
||||
write_lock(&device->context_lock);
|
||||
idr_for_each_entry(&device->context_idr, context, id) {
|
||||
drawctxt = ADRENO_CONTEXT(context);
|
||||
drawctxt->rb = adreno_ctx_get_rb(adreno_dev, drawctxt);
|
||||
|
||||
/*
|
||||
* Make sure context destroy checks against the correct
|
||||
* ringbuffer's timestamp.
|
||||
*/
|
||||
adreno_rb_readtimestamp(adreno_dev, drawctxt->rb,
|
||||
KGSL_TIMESTAMP_RETIRED, &drawctxt->internal_timestamp);
|
||||
}
|
||||
write_unlock(&device->context_lock);
|
||||
}
|
||||
|
||||
static int _preemption_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
if (!(ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) ||
|
||||
(test_bit(ADRENO_DEVICE_PREEMPTION,
|
||||
&adreno_dev->priv) == val))
|
||||
return 0;
|
||||
|
||||
return adreno_power_cycle(adreno_dev, change_preemption, NULL);
|
||||
}
|
||||
|
||||
static bool _preemption_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_is_preemption_enabled(adreno_dev);
|
||||
}
|
||||
|
||||
static unsigned int _preempt_count_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.count;
|
||||
}
|
||||
|
||||
static ADRENO_SYSFS_BOOL(preemption);
|
||||
static ADRENO_SYSFS_U32(preempt_level);
|
||||
static ADRENO_SYSFS_BOOL(usesgmem);
|
||||
static ADRENO_SYSFS_BOOL(skipsaverestore);
|
||||
static ADRENO_SYSFS_RO_U32(preempt_count);
|
||||
|
||||
static const struct attribute *_preempt_attr_list[] = {
|
||||
&adreno_attr_preemption.attr.attr,
|
||||
&adreno_attr_preempt_level.attr.attr,
|
||||
&adreno_attr_usesgmem.attr.attr,
|
||||
&adreno_attr_skipsaverestore.attr.attr,
|
||||
&adreno_attr_preempt_count.attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* adreno_dispatcher_close() - close the dispatcher
|
||||
* @adreno_dev: pointer to the adreno device structure
|
||||
|
|
@ -2660,6 +2781,7 @@ void adreno_dispatcher_close(struct adreno_device *adreno_dev)
|
|||
struct adreno_dispatcher *dispatcher = &adreno_dev->dispatcher;
|
||||
int i;
|
||||
struct adreno_ringbuffer *rb;
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
|
||||
mutex_lock(&dispatcher->mutex);
|
||||
del_timer_sync(&dispatcher->timer);
|
||||
|
|
@ -2681,6 +2803,8 @@ void adreno_dispatcher_close(struct adreno_device *adreno_dev)
|
|||
kobject_put(&dispatcher->kobj);
|
||||
|
||||
kmem_cache_destroy(jobs_cache);
|
||||
|
||||
sysfs_remove_files(&device->dev->kobj, _preempt_attr_list);
|
||||
}
|
||||
|
||||
struct dispatcher_attribute {
|
||||
|
|
@ -2830,6 +2954,8 @@ int adreno_dispatcher_init(struct adreno_device *adreno_dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
sysfs_create_files(&device->dev->kobj, _preempt_attr_list);
|
||||
|
||||
mutex_init(&dispatcher->mutex);
|
||||
|
||||
timer_setup(&dispatcher->timer, adreno_dispatcher_timer, 0);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "adreno_a6xx.h"
|
||||
#include "adreno_a6xx_hwsched.h"
|
||||
#include "adreno_snapshot.h"
|
||||
#include "adreno_sysfs.h"
|
||||
#include "adreno_trace.h"
|
||||
|
||||
/* This structure represents inflight command object */
|
||||
|
|
@ -1006,10 +1007,91 @@ void adreno_hwsched_start(struct adreno_device *adreno_dev)
|
|||
adreno_hwsched_trigger(adreno_dev);
|
||||
}
|
||||
|
||||
static int _skipsaverestore_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
return adreno_power_cycle_bool(adreno_dev,
|
||||
&adreno_dev->preempt.skipsaverestore, val);
|
||||
}
|
||||
|
||||
static bool _skipsaverestore_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.skipsaverestore;
|
||||
}
|
||||
|
||||
static int _usesgmem_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
return adreno_power_cycle_bool(adreno_dev,
|
||||
&adreno_dev->preempt.usesgmem, val);
|
||||
}
|
||||
|
||||
static bool _usesgmem_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.usesgmem;
|
||||
}
|
||||
|
||||
static int _preempt_level_store(struct adreno_device *adreno_dev,
|
||||
unsigned int val)
|
||||
{
|
||||
return adreno_power_cycle_u32(adreno_dev,
|
||||
&adreno_dev->preempt.preempt_level,
|
||||
min_t(unsigned int, val, 2));
|
||||
}
|
||||
|
||||
static unsigned int _preempt_level_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.preempt_level;
|
||||
}
|
||||
|
||||
static void change_preemption(struct adreno_device *adreno_dev, void *priv)
|
||||
{
|
||||
change_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv);
|
||||
}
|
||||
|
||||
static int _preemption_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
if (!(ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) ||
|
||||
(test_bit(ADRENO_DEVICE_PREEMPTION,
|
||||
&adreno_dev->priv) == val))
|
||||
return 0;
|
||||
|
||||
return adreno_power_cycle(adreno_dev, change_preemption, NULL);
|
||||
}
|
||||
|
||||
static bool _preemption_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_is_preemption_enabled(adreno_dev);
|
||||
}
|
||||
|
||||
static unsigned int _preempt_count_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
int count = a6xx_hwsched_preempt_count_get(adreno_dev);
|
||||
|
||||
return count < 0 ? 0 : count;
|
||||
}
|
||||
|
||||
static ADRENO_SYSFS_BOOL(preemption);
|
||||
static ADRENO_SYSFS_U32(preempt_level);
|
||||
static ADRENO_SYSFS_BOOL(usesgmem);
|
||||
static ADRENO_SYSFS_BOOL(skipsaverestore);
|
||||
static ADRENO_SYSFS_RO_U32(preempt_count);
|
||||
|
||||
static const struct attribute *_preempt_attr_list[] = {
|
||||
&adreno_attr_preemption.attr.attr,
|
||||
&adreno_attr_preempt_level.attr.attr,
|
||||
&adreno_attr_usesgmem.attr.attr,
|
||||
&adreno_attr_skipsaverestore.attr.attr,
|
||||
&adreno_attr_preempt_count.attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
void adreno_hwsched_dispatcher_close(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
|
||||
kmem_cache_destroy(jobs_cache);
|
||||
kmem_cache_destroy(obj_cache);
|
||||
|
||||
sysfs_remove_files(&device->dev->kobj, _preempt_attr_list);
|
||||
}
|
||||
|
||||
static void adreno_hwsched_init_replay(struct adreno_hwsched *hwsched)
|
||||
|
|
@ -1231,6 +1313,7 @@ static void adreno_hwsched_work(struct kthread_work *work)
|
|||
|
||||
void adreno_hwsched_init(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct adreno_hwsched *hwsched = to_hwsched(adreno_dev);
|
||||
int i;
|
||||
|
||||
|
|
@ -1249,6 +1332,8 @@ void adreno_hwsched_init(struct adreno_device *adreno_dev)
|
|||
init_llist_head(&hwsched->jobs[i]);
|
||||
init_llist_head(&hwsched->requeue[i]);
|
||||
}
|
||||
|
||||
sysfs_create_files(&device->dev->kobj, _preempt_attr_list);
|
||||
}
|
||||
|
||||
void adreno_hwsched_mark_drawobj(struct adreno_device *adreno_dev,
|
||||
|
|
|
|||
|
|
@ -6,18 +6,7 @@
|
|||
#include <linux/sysfs.h>
|
||||
|
||||
#include "adreno.h"
|
||||
|
||||
struct adreno_sysfs_attribute_u32 {
|
||||
struct device_attribute attr;
|
||||
u32 (*show)(struct adreno_device *adreno_dev);
|
||||
int (*store)(struct adreno_device *adreno_dev, u32 val);
|
||||
};
|
||||
|
||||
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);
|
||||
};
|
||||
#include "adreno_sysfs.h"
|
||||
|
||||
static int _ft_policy_store(struct adreno_device *adreno_dev,
|
||||
unsigned int val)
|
||||
|
|
@ -31,47 +20,6 @@ static unsigned int _ft_policy_show(struct adreno_device *adreno_dev)
|
|||
return adreno_dev->ft_policy;
|
||||
}
|
||||
|
||||
static int _preempt_level_store(struct adreno_device *adreno_dev,
|
||||
unsigned int val)
|
||||
{
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
if (val <= 2)
|
||||
preempt->preempt_level = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int _preempt_level_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.preempt_level;
|
||||
}
|
||||
|
||||
static int _usesgmem_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
preempt->usesgmem = val ? true : false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool _usesgmem_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.usesgmem;
|
||||
}
|
||||
|
||||
static int _skipsaverestore_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
preempt->skipsaverestore = val ? true : false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool _skipsaverestore_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.skipsaverestore;
|
||||
}
|
||||
|
||||
static int _ft_pagefault_policy_store(struct adreno_device *adreno_dev,
|
||||
unsigned int val)
|
||||
{
|
||||
|
|
@ -139,62 +87,6 @@ static bool _ft_hang_intr_status_show(struct adreno_device *adreno_dev)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void change_preemption(struct adreno_device *adreno_dev, void *priv)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct kgsl_context *context;
|
||||
struct adreno_context *drawctxt;
|
||||
struct adreno_ringbuffer *rb;
|
||||
int id, i, ret;
|
||||
|
||||
/* Make sure all ringbuffers are finished */
|
||||
FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
|
||||
ret = adreno_ringbuffer_waittimestamp(rb, rb->timestamp,
|
||||
2 * 1000);
|
||||
if (ret) {
|
||||
dev_err(device->dev,
|
||||
"Cannot disable preemption because couldn't idle ringbuffer[%d] ret: %d\n",
|
||||
rb->id, ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
change_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv);
|
||||
adreno_dev->cur_rb = &adreno_dev->ringbuffers[0];
|
||||
adreno_dev->next_rb = NULL;
|
||||
adreno_dev->prev_rb = NULL;
|
||||
|
||||
/* Update the ringbuffer for each draw context */
|
||||
write_lock(&device->context_lock);
|
||||
idr_for_each_entry(&device->context_idr, context, id) {
|
||||
drawctxt = ADRENO_CONTEXT(context);
|
||||
drawctxt->rb = adreno_ctx_get_rb(adreno_dev, drawctxt);
|
||||
|
||||
/*
|
||||
* Make sure context destroy checks against the correct
|
||||
* ringbuffer's timestamp.
|
||||
*/
|
||||
adreno_rb_readtimestamp(adreno_dev, drawctxt->rb,
|
||||
KGSL_TIMESTAMP_RETIRED, &drawctxt->internal_timestamp);
|
||||
}
|
||||
write_unlock(&device->context_lock);
|
||||
}
|
||||
|
||||
static int _preemption_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
if (!(ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) ||
|
||||
(test_bit(ADRENO_DEVICE_PREEMPTION,
|
||||
&adreno_dev->priv) == val))
|
||||
return 0;
|
||||
|
||||
return adreno_power_cycle(adreno_dev, change_preemption, NULL);
|
||||
}
|
||||
|
||||
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, bool val)
|
||||
{
|
||||
if (adreno_dev->hwcg_enabled == val)
|
||||
|
|
@ -269,13 +161,6 @@ static unsigned int _ifpc_count_show(struct adreno_device *adreno_dev)
|
|||
return adreno_dev->ifpc_count;
|
||||
}
|
||||
|
||||
static unsigned int _preempt_count_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
return preempt->count;
|
||||
}
|
||||
|
||||
static bool _acd_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->acd_enabled;
|
||||
|
|
@ -301,9 +186,8 @@ static int _bcl_store(struct adreno_device *adreno_dev, bool val)
|
|||
val);
|
||||
}
|
||||
|
||||
static ssize_t _sysfs_store_u32(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
ssize_t adreno_sysfs_store_u32(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_get_drvdata(dev));
|
||||
struct adreno_sysfs_attribute_u32 *_attr =
|
||||
|
|
@ -322,9 +206,8 @@ static ssize_t _sysfs_store_u32(struct device *dev,
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t _sysfs_show_u32(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
ssize_t adreno_sysfs_show_u32(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_get_drvdata(dev));
|
||||
struct adreno_sysfs_attribute_u32 *_attr =
|
||||
|
|
@ -333,9 +216,8 @@ static ssize_t _sysfs_show_u32(struct device *dev,
|
|||
return scnprintf(buf, PAGE_SIZE, "0x%X\n", _attr->show(adreno_dev));
|
||||
}
|
||||
|
||||
static ssize_t _sysfs_store_bool(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
ssize_t adreno_sysfs_store_bool(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_get_drvdata(dev));
|
||||
struct adreno_sysfs_attribute_bool *_attr =
|
||||
|
|
@ -354,9 +236,8 @@ static ssize_t _sysfs_store_bool(struct device *dev,
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t _sysfs_show_bool(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
ssize_t adreno_sysfs_show_bool(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_get_drvdata(dev));
|
||||
struct adreno_sysfs_attribute_bool *_attr =
|
||||
|
|
@ -364,39 +245,8 @@ static ssize_t _sysfs_show_bool(struct device *dev,
|
|||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", _attr->show(adreno_dev));
|
||||
}
|
||||
|
||||
#define ADRENO_SYSFS_BOOL(_name) \
|
||||
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) \
|
||||
struct adreno_sysfs_attribute_bool adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0444, _sysfs_show_bool, NULL), \
|
||||
.show = _ ## _name ## _show, \
|
||||
}
|
||||
|
||||
#define ADRENO_SYSFS_U32(_name) \
|
||||
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) \
|
||||
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);
|
||||
static ADRENO_SYSFS_U32(preempt_level);
|
||||
static ADRENO_SYSFS_RO_U32(preempt_count);
|
||||
static ADRENO_SYSFS_BOOL(usesgmem);
|
||||
static ADRENO_SYSFS_BOOL(skipsaverestore);
|
||||
static ADRENO_SYSFS_BOOL(ft_long_ib_detect);
|
||||
static ADRENO_SYSFS_RO_BOOL(ft_hang_intr_status);
|
||||
static ADRENO_SYSFS_BOOL(gpu_llc_slice_enable);
|
||||
|
|
@ -407,7 +257,6 @@ static DEVICE_INT_ATTR(wake_timeout, 0644, adreno_wake_timeout);
|
|||
|
||||
static ADRENO_SYSFS_BOOL(sptp_pc);
|
||||
static ADRENO_SYSFS_BOOL(lm);
|
||||
static ADRENO_SYSFS_BOOL(preemption);
|
||||
static ADRENO_SYSFS_BOOL(hwcg);
|
||||
static ADRENO_SYSFS_BOOL(throttling);
|
||||
static ADRENO_SYSFS_BOOL(ifpc);
|
||||
|
|
@ -425,17 +274,12 @@ static const struct attribute *_attr_list[] = {
|
|||
&dev_attr_wake_timeout.attr.attr,
|
||||
&adreno_attr_sptp_pc.attr.attr,
|
||||
&adreno_attr_lm.attr.attr,
|
||||
&adreno_attr_preemption.attr.attr,
|
||||
&adreno_attr_hwcg.attr.attr,
|
||||
&adreno_attr_throttling.attr.attr,
|
||||
&adreno_attr_gpu_llc_slice_enable.attr.attr,
|
||||
&adreno_attr_gpuhtw_llc_slice_enable.attr.attr,
|
||||
&adreno_attr_preempt_level.attr.attr,
|
||||
&adreno_attr_usesgmem.attr.attr,
|
||||
&adreno_attr_skipsaverestore.attr.attr,
|
||||
&adreno_attr_ifpc.attr.attr,
|
||||
&adreno_attr_ifpc_count.attr.attr,
|
||||
&adreno_attr_preempt_count.attr.attr,
|
||||
&adreno_attr_acd.attr.attr,
|
||||
&adreno_attr_bcl.attr.attr,
|
||||
NULL,
|
||||
|
|
|
|||
78
drivers/gpu/msm/adreno_sysfs.h
Normal file
78
drivers/gpu/msm/adreno_sysfs.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ADRENO_SYSFS_H_
|
||||
#define _ADRENO_SYSFS_H_
|
||||
|
||||
/*
|
||||
* struct adreno_sysfs_attribute_u32 - Container for accessing and modifying
|
||||
* integers in kgsl via sysfs
|
||||
*/
|
||||
struct adreno_sysfs_attribute_u32 {
|
||||
/** #attr: The device attribute corresponding to the sysfs node */
|
||||
struct device_attribute attr;
|
||||
/** @show: Function to show the value of the integer */
|
||||
u32 (*show)(struct adreno_device *adreno_dev);
|
||||
/** @store: Function to store the value of the integer */
|
||||
int (*store)(struct adreno_device *adreno_dev, u32 val);
|
||||
};
|
||||
|
||||
/*
|
||||
* struct adreno_sysfs_attribute_bool - Container for accessing and modifying
|
||||
* booleans in kgsl via sysfs
|
||||
*/
|
||||
struct adreno_sysfs_attribute_bool {
|
||||
/** #attr: The device attribute corresponding to the sysfs node */
|
||||
struct device_attribute attr;
|
||||
/** @show: Function to show the value of the boolean */
|
||||
bool (*show)(struct adreno_device *adreno_dev);
|
||||
/** @store: Function to store the value of the boolean */
|
||||
int (*store)(struct adreno_device *adreno_dev, bool val);
|
||||
};
|
||||
|
||||
/* Helper function to modify an integer in kgsl */
|
||||
ssize_t adreno_sysfs_store_u32(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count);
|
||||
|
||||
/* Helper function to read an integer in kgsl */
|
||||
ssize_t adreno_sysfs_show_u32(struct device *dev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
|
||||
/* Helper function to modify a boolean in kgsl */
|
||||
ssize_t adreno_sysfs_store_bool(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count);
|
||||
|
||||
/* Helper function to read a boolean in kgsl */
|
||||
ssize_t adreno_sysfs_show_bool(struct device *dev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
|
||||
#define ADRENO_SYSFS_BOOL(_name) \
|
||||
struct adreno_sysfs_attribute_bool adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0644, adreno_sysfs_show_bool, \
|
||||
adreno_sysfs_store_bool), \
|
||||
.show = _ ## _name ## _show, \
|
||||
.store = _ ## _name ## _store, \
|
||||
}
|
||||
|
||||
#define ADRENO_SYSFS_RO_BOOL(_name) \
|
||||
struct adreno_sysfs_attribute_bool adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0444, adreno_sysfs_show_bool, NULL), \
|
||||
.show = _ ## _name ## _show, \
|
||||
}
|
||||
|
||||
#define ADRENO_SYSFS_U32(_name) \
|
||||
struct adreno_sysfs_attribute_u32 adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0644, adreno_sysfs_show_u32, \
|
||||
adreno_sysfs_store_u32), \
|
||||
.show = _ ## _name ## _show, \
|
||||
.store = _ ## _name ## _store, \
|
||||
}
|
||||
|
||||
#define ADRENO_SYSFS_RO_U32(_name) \
|
||||
struct adreno_sysfs_attribute_u32 adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0444, adreno_sysfs_show_u32, NULL), \
|
||||
.show = _ ## _name ## _show, \
|
||||
}
|
||||
#endif
|
||||
|
|
@ -72,11 +72,19 @@ static int globals_print(struct seq_file *s, void *unused)
|
|||
|
||||
list_for_each_entry(md, &device->globals, node) {
|
||||
struct kgsl_memdesc *memdesc = &md->memdesc;
|
||||
char flags[6];
|
||||
|
||||
seq_printf(s, "0x%pK-0x%pK %16llu %s\n",
|
||||
flags[0] = memdesc->priv & KGSL_MEMDESC_PRIVILEGED ? 'p' : '-';
|
||||
flags[1] = !(memdesc->flags & KGSL_MEMFLAGS_GPUREADONLY) ? 'w' : '-';
|
||||
flags[2] = kgsl_memdesc_is_secured(memdesc) ? 's' : '-';
|
||||
flags[3] = memdesc->priv & KGSL_MEMDESC_RANDOM ? 'r' : '-';
|
||||
flags[4] = memdesc->priv & KGSL_MEMDESC_UCODE ? 'u' : '-';
|
||||
flags[5] = '\0';
|
||||
|
||||
seq_printf(s, "0x%pK-0x%pK %16llu %5s %s\n",
|
||||
(u64 *)(uintptr_t) memdesc->gpuaddr,
|
||||
(u64 *)(uintptr_t) (memdesc->gpuaddr +
|
||||
memdesc->size - 1), memdesc->size,
|
||||
memdesc->size - 1), memdesc->size, flags,
|
||||
md->name);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue