123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
- */
- #include <linux/sysfs.h>
- #include "adreno.h"
- #include "adreno_sysfs.h"
- #include "kgsl_sysfs.h"
- static ssize_t _gpu_model_show(struct kgsl_device *device, char *buf)
- {
- return scnprintf(buf, PAGE_SIZE, adreno_get_gpu_model(device));
- }
- static ssize_t gpu_model_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct kgsl_device *device = dev_get_drvdata(dev);
- return _gpu_model_show(device, buf);
- }
- static int _l3_vote_store(struct adreno_device *adreno_dev, bool val)
- {
- struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
- if (ADRENO_FEATURE(adreno_dev, ADRENO_L3_VOTE))
- device->l3_vote = val;
- return 0;
- }
- static bool _l3_vote_show(struct adreno_device *adreno_dev)
- {
- struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
- return device->l3_vote;
- }
- static int _ft_policy_store(struct adreno_device *adreno_dev,
- unsigned int val)
- {
- adreno_dev->ft_policy = val & KGSL_FT_POLICY_MASK;
- return 0;
- }
- static unsigned int _ft_policy_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->ft_policy;
- }
- static int _ft_pagefault_policy_store(struct adreno_device *adreno_dev,
- unsigned int val)
- {
- struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
- int ret = 0;
- mutex_lock(&device->mutex);
- val &= KGSL_FT_PAGEFAULT_MASK;
- if (device->state == KGSL_STATE_ACTIVE)
- ret = kgsl_mmu_set_pagefault_policy(&device->mmu,
- (unsigned long) val);
- if (ret == 0)
- device->mmu.pfpolicy = val;
- mutex_unlock(&device->mutex);
- return 0;
- }
- static unsigned int _ft_pagefault_policy_show(struct adreno_device *adreno_dev)
- {
- struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
- return device->mmu.pfpolicy;
- }
- static int _rt_bus_hint_store(struct adreno_device *adreno_dev, u32 val)
- {
- struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
- struct kgsl_pwrctrl *pwrctrl = &device->pwrctrl;
- if (val > pwrctrl->pwrlevels[0].bus_max)
- return -EINVAL;
- adreno_power_cycle_u32(adreno_dev, &pwrctrl->rt_bus_hint, val);
- return 0;
- }
- static u32 _rt_bus_hint_show(struct adreno_device *adreno_dev)
- {
- struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
- return device->pwrctrl.rt_bus_hint;
- }
- static int _gpu_llc_slice_enable_store(struct adreno_device *adreno_dev,
- bool val)
- {
- if (IS_ERR_OR_NULL(adreno_dev->gpu_llc_slice) ||
- (adreno_dev->gpu_llc_slice_enable == val))
- return 0;
- return adreno_power_cycle_bool(adreno_dev, &adreno_dev->gpu_llc_slice_enable, val);
- }
- 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,
- bool val)
- {
- if (IS_ERR_OR_NULL(adreno_dev->gpuhtw_llc_slice) ||
- (adreno_dev->gpuhtw_llc_slice_enable == val))
- return 0;
- return adreno_power_cycle_bool(adreno_dev, &adreno_dev->gpuhtw_llc_slice_enable, val);
- }
- static bool _gpuhtw_llc_slice_enable_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->gpuhtw_llc_slice_enable;
- }
- static bool _ft_hang_intr_status_show(struct adreno_device *adreno_dev)
- {
- /* Hang interrupt is always on on all targets */
- return true;
- }
- static int _hwcg_store(struct adreno_device *adreno_dev, bool val)
- {
- if (adreno_dev->hwcg_enabled == val)
- return 0;
- return adreno_power_cycle_bool(adreno_dev, &adreno_dev->hwcg_enabled,
- val);
- }
- static bool _hwcg_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->hwcg_enabled;
- }
- static int _throttling_store(struct adreno_device *adreno_dev, bool val)
- {
- if (!adreno_is_a540(adreno_dev) ||
- adreno_dev->throttling_enabled == val)
- return 0;
- return adreno_power_cycle_bool(adreno_dev,
- &adreno_dev->throttling_enabled, val);
- }
- static bool _throttling_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->throttling_enabled;
- }
- static int _sptp_pc_store(struct adreno_device *adreno_dev, bool val)
- {
- if (!ADRENO_FEATURE(adreno_dev, ADRENO_SPTP_PC) ||
- adreno_dev->sptp_pc_enabled == val)
- return 0;
- return adreno_power_cycle_bool(adreno_dev, &adreno_dev->sptp_pc_enabled,
- val);
- }
- static bool _sptp_pc_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->sptp_pc_enabled;
- }
- static int _lm_store(struct adreno_device *adreno_dev, bool val)
- {
- if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM) ||
- adreno_dev->lm_enabled == val)
- return 0;
- return adreno_power_cycle_bool(adreno_dev, &adreno_dev->lm_enabled,
- val);
- }
- static bool _lm_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->lm_enabled;
- }
- static int _ifpc_store(struct adreno_device *adreno_dev, bool val)
- {
- return gmu_core_dev_ifpc_store(KGSL_DEVICE(adreno_dev), val);
- }
- static bool _ifpc_show(struct adreno_device *adreno_dev)
- {
- return gmu_core_dev_ifpc_isenabled(KGSL_DEVICE(adreno_dev));
- }
- static int _touch_wake_store(struct adreno_device *adreno_dev, bool val)
- {
- if (val)
- adreno_touch_wake(KGSL_DEVICE(adreno_dev));
- return 0;
- }
- static bool _touch_wake_show(struct adreno_device *adreno_dev)
- {
- return false;
- }
- static unsigned int _ifpc_count_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->ifpc_count;
- }
- static bool _acd_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->acd_enabled;
- }
- static int _acd_store(struct adreno_device *adreno_dev, bool val)
- {
- return gmu_core_dev_acd_set(KGSL_DEVICE(adreno_dev), val);
- }
- static bool _gmu_ab_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->gmu_ab;
- }
- static int _gmu_ab_store(struct adreno_device *adreno_dev, bool val)
- {
- if (!test_bit(ADRENO_DEVICE_GMU_AB, &adreno_dev->priv) ||
- (adreno_dev->gmu_ab == val))
- return 0;
- /* Power cycle the GPU for changes to take effect */
- return adreno_power_cycle_bool(adreno_dev, &adreno_dev->gmu_ab, val);
- }
- static bool _bcl_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->bcl_enabled;
- }
- static int _bcl_store(struct adreno_device *adreno_dev, bool val)
- {
- if (!ADRENO_FEATURE(adreno_dev, ADRENO_BCL) ||
- adreno_dev->bcl_enabled == val)
- return 0;
- return adreno_power_cycle_bool(adreno_dev, &adreno_dev->bcl_enabled,
- val);
- }
- static bool _clx_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->clx_enabled;
- }
- static int _clx_store(struct adreno_device *adreno_dev, bool val)
- {
- if (!ADRENO_FEATURE(adreno_dev, ADRENO_CLX) || adreno_dev->clx_enabled == val)
- return 0;
- return adreno_power_cycle_bool(adreno_dev, &adreno_dev->clx_enabled, val);
- }
- static bool _dms_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->dms_enabled;
- }
- static int _dms_store(struct adreno_device *adreno_dev, bool val)
- {
- if (!test_bit(ADRENO_DEVICE_DMS, &adreno_dev->priv) ||
- adreno_dev->dms_enabled == val)
- return 0;
- return adreno_power_cycle_bool(adreno_dev, &adreno_dev->dms_enabled, val);
- }
- static bool _perfcounter_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->perfcounter;
- }
- static int _perfcounter_store(struct adreno_device *adreno_dev, bool val)
- {
- if (adreno_dev->perfcounter == val)
- return 0;
- return adreno_power_cycle_bool(adreno_dev, &adreno_dev->perfcounter, val);
- }
- static bool _lpac_show(struct adreno_device *adreno_dev)
- {
- return adreno_dev->lpac_enabled;
- }
- static int _lpac_store(struct adreno_device *adreno_dev, bool val)
- {
- const struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
- if (gpudev->lpac_store)
- return gpudev->lpac_store(adreno_dev, val);
- else
- return -EINVAL;
- }
- 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));
- const struct adreno_sysfs_attribute_u32 *_attr =
- container_of(attr, struct adreno_sysfs_attribute_u32, attr);
- u32 val;
- int ret;
- ret = kstrtou32(buf, 0, &val);
- if (ret)
- return ret;
- ret = _attr->store(adreno_dev, val);
- if (ret)
- return ret;
- return count;
- }
- 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));
- const struct adreno_sysfs_attribute_u32 *_attr =
- container_of(attr, struct adreno_sysfs_attribute_u32, attr);
- return scnprintf(buf, PAGE_SIZE, "0x%X\n", _attr->show(adreno_dev));
- }
- 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));
- const struct adreno_sysfs_attribute_bool *_attr =
- container_of(attr, struct adreno_sysfs_attribute_bool, attr);
- bool val;
- int ret;
- ret = kstrtobool(buf, &val);
- if (ret)
- return ret;
- ret = _attr->store(adreno_dev, val);
- if (ret)
- return ret;
- return count;
- }
- 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));
- const struct adreno_sysfs_attribute_bool *_attr =
- container_of(attr, struct adreno_sysfs_attribute_bool, attr);
- return scnprintf(buf, PAGE_SIZE, "%d\n", _attr->show(adreno_dev));
- }
- static ADRENO_SYSFS_U32(ft_policy);
- static ADRENO_SYSFS_U32(ft_pagefault_policy);
- static ADRENO_SYSFS_U32(rt_bus_hint);
- static ADRENO_SYSFS_RO_BOOL(ft_hang_intr_status);
- static ADRENO_SYSFS_BOOL(gpu_llc_slice_enable);
- static ADRENO_SYSFS_BOOL(gpuhtw_llc_slice_enable);
- static DEVICE_INT_ATTR(wake_nice, 0644, adreno_wake_nice);
- 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(hwcg);
- static ADRENO_SYSFS_BOOL(throttling);
- static ADRENO_SYSFS_BOOL(ifpc);
- static ADRENO_SYSFS_RO_U32(ifpc_count);
- static ADRENO_SYSFS_BOOL(acd);
- static ADRENO_SYSFS_BOOL(bcl);
- static ADRENO_SYSFS_BOOL(clx);
- static ADRENO_SYSFS_BOOL(l3_vote);
- static ADRENO_SYSFS_BOOL(perfcounter);
- static ADRENO_SYSFS_BOOL(lpac);
- static ADRENO_SYSFS_BOOL(dms);
- static ADRENO_SYSFS_BOOL(touch_wake);
- static ADRENO_SYSFS_BOOL(gmu_ab);
- static DEVICE_ATTR_RO(gpu_model);
- static const struct attribute *_attr_list[] = {
- &adreno_attr_ft_policy.attr.attr,
- &adreno_attr_ft_pagefault_policy.attr.attr,
- &adreno_attr_rt_bus_hint.attr.attr,
- &adreno_attr_ft_hang_intr_status.attr.attr,
- &dev_attr_wake_nice.attr.attr,
- &dev_attr_wake_timeout.attr.attr,
- &adreno_attr_sptp_pc.attr.attr,
- &adreno_attr_lm.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_ifpc.attr.attr,
- &adreno_attr_ifpc_count.attr.attr,
- &adreno_attr_acd.attr.attr,
- &adreno_attr_bcl.attr.attr,
- &dev_attr_gpu_model.attr,
- &adreno_attr_l3_vote.attr.attr,
- &adreno_attr_perfcounter.attr.attr,
- &adreno_attr_lpac.attr.attr,
- &adreno_attr_dms.attr.attr,
- &adreno_attr_touch_wake.attr.attr,
- &adreno_attr_gmu_ab.attr.attr,
- &adreno_attr_clx.attr.attr,
- NULL,
- };
- static GPU_SYSFS_ATTR(gpu_model, 0444, _gpu_model_show, NULL);
- /**
- * adreno_sysfs_init() - Initialize adreno sysfs files
- * @adreno_dev: Pointer to the adreno device
- *
- * Initialize many of the adreno specific sysfs files especially for fault
- * tolerance and power control
- */
- int adreno_sysfs_init(struct adreno_device *adreno_dev)
- {
- struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
- int ret;
- ret = sysfs_create_files(&device->dev->kobj, _attr_list);
- if (!ret) {
- /* Notify userspace */
- kobject_uevent(&device->dev->kobj, KOBJ_ADD);
- ret = sysfs_create_file(&device->gpu_sysfs_kobj,
- &gpu_sysfs_attr_gpu_model.attr);
- }
- return ret;
- }
|