| .. | .. |
|---|
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note |
|---|
| 2 | 2 | /* |
|---|
| 3 | 3 | * |
|---|
| 4 | | - * (C) COPYRIGHT 2020-2021 ARM Limited. All rights reserved. |
|---|
| 4 | + * (C) COPYRIGHT 2020-2022 ARM Limited. All rights reserved. |
|---|
| 5 | 5 | * |
|---|
| 6 | 6 | * This program is free software and is provided to you under the terms of the |
|---|
| 7 | 7 | * GNU General Public License version 2 as published by the Free Software |
|---|
| .. | .. |
|---|
| 20 | 20 | */ |
|---|
| 21 | 21 | |
|---|
| 22 | 22 | #include <mali_kbase.h> |
|---|
| 23 | | -#include "mali_kbase_csf_firmware_cfg.h" |
|---|
| 24 | 23 | #include <mali_kbase_reset_gpu.h> |
|---|
| 24 | +#include <linux/version.h> |
|---|
| 25 | + |
|---|
| 26 | +#include "mali_kbase_csf_firmware_cfg.h" |
|---|
| 27 | +#include "mali_kbase_csf_firmware_log.h" |
|---|
| 25 | 28 | |
|---|
| 26 | 29 | #if CONFIG_SYSFS |
|---|
| 27 | 30 | #define CSF_FIRMWARE_CFG_SYSFS_DIR_NAME "firmware_config" |
|---|
| 28 | 31 | |
|---|
| 32 | +#define CSF_FIRMWARE_CFG_LOG_VERBOSITY_ENTRY_NAME "Log verbosity" |
|---|
| 33 | + |
|---|
| 29 | 34 | /** |
|---|
| 30 | 35 | * struct firmware_config - Configuration item within the MCU firmware |
|---|
| 31 | | - * |
|---|
| 32 | | - * The firmware may expose configuration options. Each option has a name, the |
|---|
| 33 | | - * address where the option is controlled and the minimum and maximum values |
|---|
| 34 | | - * that the option can take. |
|---|
| 35 | 36 | * |
|---|
| 36 | 37 | * @node: List head linking all options to |
|---|
| 37 | 38 | * kbase_device:csf.firmware_config |
|---|
| .. | .. |
|---|
| 47 | 48 | * @min: The lowest legal value of the configuration option |
|---|
| 48 | 49 | * @max: The maximum legal value of the configuration option |
|---|
| 49 | 50 | * @cur_val: The current value of the configuration option |
|---|
| 51 | + * |
|---|
| 52 | + * The firmware may expose configuration options. Each option has a name, the |
|---|
| 53 | + * address where the option is controlled and the minimum and maximum values |
|---|
| 54 | + * that the option can take. |
|---|
| 50 | 55 | */ |
|---|
| 51 | 56 | struct firmware_config { |
|---|
| 52 | 57 | struct list_head node; |
|---|
| .. | .. |
|---|
| 67 | 72 | .mode = VERIFY_OCTAL_PERMISSIONS(_mode), \ |
|---|
| 68 | 73 | } |
|---|
| 69 | 74 | |
|---|
| 70 | | -static FW_CFG_ATTR(min, S_IRUGO); |
|---|
| 71 | | -static FW_CFG_ATTR(max, S_IRUGO); |
|---|
| 72 | | -static FW_CFG_ATTR(cur, S_IRUGO | S_IWUSR); |
|---|
| 75 | +static FW_CFG_ATTR(min, 0444); |
|---|
| 76 | +static FW_CFG_ATTR(max, 0444); |
|---|
| 77 | +static FW_CFG_ATTR(cur, 0644); |
|---|
| 73 | 78 | |
|---|
| 74 | 79 | static void fw_cfg_kobj_release(struct kobject *kobj) |
|---|
| 75 | 80 | { |
|---|
| .. | .. |
|---|
| 124 | 129 | |
|---|
| 125 | 130 | if (attr == &fw_cfg_attr_cur) { |
|---|
| 126 | 131 | unsigned long flags; |
|---|
| 127 | | - u32 val; |
|---|
| 132 | + u32 val, cur_val; |
|---|
| 128 | 133 | int ret = kstrtouint(buf, 0, &val); |
|---|
| 129 | 134 | |
|---|
| 130 | 135 | if (ret) { |
|---|
| .. | .. |
|---|
| 139 | 144 | return -EINVAL; |
|---|
| 140 | 145 | |
|---|
| 141 | 146 | spin_lock_irqsave(&kbdev->hwaccess_lock, flags); |
|---|
| 142 | | - if (config->cur_val == val) { |
|---|
| 147 | + |
|---|
| 148 | + cur_val = config->cur_val; |
|---|
| 149 | + if (cur_val == val) { |
|---|
| 143 | 150 | spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags); |
|---|
| 144 | 151 | return count; |
|---|
| 145 | 152 | } |
|---|
| .. | .. |
|---|
| 176 | 183 | |
|---|
| 177 | 184 | spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags); |
|---|
| 178 | 185 | |
|---|
| 186 | + /* Enable FW logging only if Log verbosity is non-zero */ |
|---|
| 187 | + if (!strcmp(config->name, CSF_FIRMWARE_CFG_LOG_VERBOSITY_ENTRY_NAME) && |
|---|
| 188 | + (!cur_val || !val)) { |
|---|
| 189 | + ret = kbase_csf_firmware_log_toggle_logging_calls(kbdev, val); |
|---|
| 190 | + if (ret) { |
|---|
| 191 | + /* Undo FW configuration changes */ |
|---|
| 192 | + spin_lock_irqsave(&kbdev->hwaccess_lock, flags); |
|---|
| 193 | + config->cur_val = cur_val; |
|---|
| 194 | + kbase_csf_update_firmware_memory(kbdev, config->address, cur_val); |
|---|
| 195 | + spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags); |
|---|
| 196 | + return ret; |
|---|
| 197 | + } |
|---|
| 198 | + } |
|---|
| 199 | + |
|---|
| 179 | 200 | /* If we can update the config without firmware reset then |
|---|
| 180 | 201 | * we need to just trigger FIRMWARE_CONFIG_UPDATE. |
|---|
| 181 | 202 | */ |
|---|
| .. | .. |
|---|
| 209 | 230 | &fw_cfg_attr_cur, |
|---|
| 210 | 231 | NULL, |
|---|
| 211 | 232 | }; |
|---|
| 233 | +#if (KERNEL_VERSION(5, 2, 0) <= LINUX_VERSION_CODE) |
|---|
| 234 | +ATTRIBUTE_GROUPS(fw_cfg); |
|---|
| 235 | +#endif |
|---|
| 212 | 236 | |
|---|
| 213 | 237 | static struct kobj_type fw_cfg_kobj_type = { |
|---|
| 214 | 238 | .release = &fw_cfg_kobj_release, |
|---|
| 215 | 239 | .sysfs_ops = &fw_cfg_ops, |
|---|
| 240 | +#if (KERNEL_VERSION(5, 2, 0) <= LINUX_VERSION_CODE) |
|---|
| 241 | + .default_groups = fw_cfg_groups, |
|---|
| 242 | +#else |
|---|
| 216 | 243 | .default_attrs = fw_cfg_attrs, |
|---|
| 244 | +#endif |
|---|
| 217 | 245 | }; |
|---|
| 218 | 246 | |
|---|
| 219 | 247 | int kbase_csf_firmware_cfg_init(struct kbase_device *kbdev) |
|---|
| .. | .. |
|---|
| 273 | 301 | } |
|---|
| 274 | 302 | |
|---|
| 275 | 303 | int kbase_csf_firmware_cfg_option_entry_parse(struct kbase_device *kbdev, |
|---|
| 276 | | - const struct firmware *fw, |
|---|
| 277 | | - const u32 *entry, |
|---|
| 278 | | - unsigned int size, bool updatable) |
|---|
| 304 | + const struct kbase_csf_mcu_fw *const fw, |
|---|
| 305 | + const u32 *entry, unsigned int size, bool updatable) |
|---|
| 279 | 306 | { |
|---|
| 280 | 307 | const char *name = (char *)&entry[3]; |
|---|
| 281 | 308 | struct firmware_config *config; |
|---|
| .. | .. |
|---|
| 319 | 346 | } |
|---|
| 320 | 347 | |
|---|
| 321 | 348 | int kbase_csf_firmware_cfg_option_entry_parse(struct kbase_device *kbdev, |
|---|
| 322 | | - const struct firmware *fw, |
|---|
| 323 | | - const u32 *entry, unsigned int size) |
|---|
| 349 | + const struct kbase_csf_mcu_fw *const fw, |
|---|
| 350 | + const u32 *entry, unsigned int size) |
|---|
| 324 | 351 | { |
|---|
| 325 | 352 | return 0; |
|---|
| 326 | 353 | } |
|---|