.. | .. |
---|
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 | } |
---|