diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.h b/drivers/gpu/msm/adreno_a6xx_gmu.h index 130f0a617150..136ff37a1dcb 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.h +++ b/drivers/gpu/msm/adreno_a6xx_gmu.h @@ -205,6 +205,8 @@ struct a6xx_gmu_device { void __iomem *rdpm_cx_virt; /** @rdpm_mx_virt: Pointer where the RDPM MX block is mapped */ void __iomem *rdpm_mx_virt; + /** @log_stream_enable: GMU log streaming enable */ + bool log_stream_enable; }; /* Helper function to get to a6xx gmu device from adreno device */ diff --git a/drivers/gpu/msm/adreno_a6xx_hfi.c b/drivers/gpu/msm/adreno_a6xx_hfi.c index 3a7841c40407..59f69b60775e 100644 --- a/drivers/gpu/msm/adreno_a6xx_hfi.c +++ b/drivers/gpu/msm/adreno_a6xx_hfi.c @@ -439,6 +439,27 @@ int a6xx_hfi_send_feature_ctrl(struct adreno_device *adreno_dev, return ret; } +int a6xx_hfi_send_set_value(struct adreno_device *adreno_dev, + u32 type, u32 subtype, u32 data) +{ + struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev); + struct hfi_set_value_cmd cmd = { + .type = type, + .subtype = subtype, + .data = data, + }; + int ret; + + CMD_MSG_HDR(cmd, H2F_MSG_SET_VALUE); + + ret = a6xx_hfi_send_generic_req(adreno_dev, &cmd); + if (ret) + dev_err(&gmu->pdev->dev, + "Unable to set HFI Value %d, %d to %d, error = %d\n", + type, subtype, data, ret); + return ret; +} + static int a6xx_hfi_send_dcvstbl_v1(struct adreno_device *adreno_dev) { struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev); diff --git a/drivers/gpu/msm/adreno_a6xx_hfi.h b/drivers/gpu/msm/adreno_a6xx_hfi.h index f487e39dbc95..c9b3cea443b6 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_LOG_STREAM_ENABLE 119 #define HFI_VALUE_PREEMPT_COUNT 120 #define HFI_VALUE_GLOBAL_TOKEN 0xFFFFFFFF @@ -664,6 +665,18 @@ int a6xx_receive_ack_cmd(struct a6xx_gmu_device *gmu, void *rcvd, int a6xx_hfi_send_feature_ctrl(struct adreno_device *adreno_dev, u32 feature, u32 enable, u32 data); +/** + * a6xx_hfi_send_set_value - Send gmu set_values via hfi + * @adreno_dev: Pointer to the adreno device + * @type: GMU set_value type + * @subtype: GMU set_value subtype + * @data: Value to set + * + * Return: 0 on success or negative error on failure + */ +int a6xx_hfi_send_set_value(struct adreno_device *adreno_dev, + u32 type, u32 subtype, u32 data); + /** * a6xx_hfi_send_core_fw_start - Send the core fw start hfi * @adreno_dev: Pointer to the adreno device diff --git a/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.c b/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.c index 1fe5af4075c6..bb2d22021319 100644 --- a/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.c +++ b/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.c @@ -807,6 +807,10 @@ int a6xx_hwsched_hfi_start(struct adreno_device *adreno_dev) if (ret) goto err; + if (gmu->log_stream_enable) + a6xx_hfi_send_set_value(adreno_dev, + HFI_VALUE_LOG_STREAM_ENABLE, 0, 1); + ret = a6xx_hfi_send_core_fw_start(adreno_dev); if (ret) goto err; diff --git a/drivers/gpu/msm/adreno_hwsched.c b/drivers/gpu/msm/adreno_hwsched.c index b8f5b07dee52..7f59fc00ae57 100644 --- a/drivers/gpu/msm/adreno_hwsched.c +++ b/drivers/gpu/msm/adreno_hwsched.c @@ -1070,18 +1070,38 @@ static unsigned int _preempt_count_show(struct adreno_device *adreno_dev) return count < 0 ? 0 : count; } +static int _gmu_log_stream_enable_store(struct adreno_device *adreno_dev, + bool val) +{ + struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev); + + if (gmu->log_stream_enable == val) + return 0; + + return adreno_power_cycle_bool(adreno_dev, &gmu->log_stream_enable, val); +} + +static bool _gmu_log_stream_enable_show(struct adreno_device *adreno_dev) +{ + struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev); + + return gmu->log_stream_enable; +} + 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 ADRENO_SYSFS_BOOL(gmu_log_stream_enable); -static const struct attribute *_preempt_attr_list[] = { +static const struct attribute *_hwsched_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, + &adreno_attr_gmu_log_stream_enable.attr.attr, NULL, }; @@ -1092,7 +1112,7 @@ void adreno_hwsched_dispatcher_close(struct adreno_device *adreno_dev) kmem_cache_destroy(jobs_cache); kmem_cache_destroy(obj_cache); - sysfs_remove_files(&device->dev->kobj, _preempt_attr_list); + sysfs_remove_files(&device->dev->kobj, _hwsched_attr_list); } static void adreno_hwsched_init_replay(struct adreno_hwsched *hwsched) @@ -1336,7 +1356,7 @@ void adreno_hwsched_init(struct adreno_device *adreno_dev) init_llist_head(&hwsched->requeue[i]); } - sysfs_create_files(&device->dev->kobj, _preempt_attr_list); + sysfs_create_files(&device->dev->kobj, _hwsched_attr_list); } void adreno_hwsched_mark_drawobj(struct adreno_device *adreno_dev,