diff --git a/drivers/gpu/msm/adreno_a6xx_hfi.h b/drivers/gpu/msm/adreno_a6xx_hfi.h index f43efe6e1d6c..f487e39dbc95 100644 --- a/drivers/gpu/msm/adreno_a6xx_hfi.h +++ b/drivers/gpu/msm/adreno_a6xx_hfi.h @@ -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 diff --git a/drivers/gpu/msm/adreno_a6xx_hwsched.c b/drivers/gpu/msm/adreno_a6xx_hwsched.c index 81d6f8e1a779..185d53386f2c 100644 --- a/drivers/gpu/msm/adreno_a6xx_hwsched.c +++ b/drivers/gpu/msm/adreno_a6xx_hwsched.c @@ -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); diff --git a/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.c b/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.c index e91b2fe93d4a..2c5dfc0d95ad 100644 --- a/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.c +++ b/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.c @@ -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]; +} diff --git a/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.h b/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.h index 5dc4be971baa..027833709421 100644 --- a/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.h +++ b/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.h @@ -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 diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c index f6c3853e4ca2..88d4e734f377 100644 --- a/drivers/gpu/msm/adreno_dispatch.c +++ b/drivers/gpu/msm/adreno_dispatch.c @@ -4,8 +4,10 @@ */ #include +#include #include #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); diff --git a/drivers/gpu/msm/adreno_hwsched.c b/drivers/gpu/msm/adreno_hwsched.c index 402fe2a02bec..643acbdf0da3 100644 --- a/drivers/gpu/msm/adreno_hwsched.c +++ b/drivers/gpu/msm/adreno_hwsched.c @@ -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, diff --git a/drivers/gpu/msm/adreno_sysfs.c b/drivers/gpu/msm/adreno_sysfs.c index be8ef6db3d74..b926438c9391 100644 --- a/drivers/gpu/msm/adreno_sysfs.c +++ b/drivers/gpu/msm/adreno_sysfs.c @@ -6,18 +6,7 @@ #include #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, diff --git a/drivers/gpu/msm/adreno_sysfs.h b/drivers/gpu/msm/adreno_sysfs.h new file mode 100644 index 000000000000..66212d34dbc8 --- /dev/null +++ b/drivers/gpu/msm/adreno_sysfs.h @@ -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 diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c index 94e7639fbcda..bdffbd47e403 100644 --- a/drivers/gpu/msm/kgsl_debugfs.c +++ b/drivers/gpu/msm/kgsl_debugfs.c @@ -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); }