|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
| 2 | +// |
| 3 | +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. |
| 4 | +// |
| 5 | +// Authors: Cezary Rojewski <cezary.rojewski@intel.com> |
| 6 | +// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com> |
| 7 | +// |
| 8 | + |
| 9 | +#include <linux/devcoredump.h> |
| 10 | +#include <linux/slab.h> |
| 11 | +#include <sound/hdaudio_ext.h> |
| 12 | +#include "avs.h" |
| 13 | +#include "messages.h" |
| 14 | + |
| 15 | +static int skl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period, |
| 16 | + u32 fifo_full_period, unsigned long resource_mask, u32 *priorities) |
| 17 | +{ |
| 18 | + struct skl_log_state_info *info; |
| 19 | + u32 size, num_cores = adev->hw_cfg.dsp_cores; |
| 20 | + int ret, i; |
| 21 | + |
| 22 | + if (fls_long(resource_mask) > num_cores) |
| 23 | + return -EINVAL; |
| 24 | + size = struct_size(info, logs_core, num_cores); |
| 25 | + info = kzalloc(size, GFP_KERNEL); |
| 26 | + if (!info) |
| 27 | + return -ENOMEM; |
| 28 | + |
| 29 | + info->core_mask = resource_mask; |
| 30 | + if (enable) |
| 31 | + for_each_set_bit(i, &resource_mask, GENMASK(num_cores, 0)) { |
| 32 | + info->logs_core[i].enable = enable; |
| 33 | + info->logs_core[i].min_priority = *priorities++; |
| 34 | + } |
| 35 | + else |
| 36 | + for_each_set_bit(i, &resource_mask, GENMASK(num_cores, 0)) |
| 37 | + info->logs_core[i].enable = enable; |
| 38 | + |
| 39 | + ret = avs_ipc_set_enable_logs(adev, (u8 *)info, size); |
| 40 | + kfree(info); |
| 41 | + if (ret) |
| 42 | + return AVS_IPC_RET(ret); |
| 43 | + |
| 44 | + return 0; |
| 45 | +} |
| 46 | + |
| 47 | +int skl_log_buffer_offset(struct avs_dev *adev, u32 core) |
| 48 | +{ |
| 49 | + return core * avs_log_buffer_size(adev); |
| 50 | +} |
| 51 | + |
| 52 | +/* fw DbgLogWp registers */ |
| 53 | +#define FW_REGS_DBG_LOG_WP(core) (0x30 + 0x4 * core) |
| 54 | + |
| 55 | +static int |
| 56 | +skl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg) |
| 57 | +{ |
| 58 | + unsigned long flags; |
| 59 | + void __iomem *buf; |
| 60 | + u16 size, write, offset; |
| 61 | + |
| 62 | + spin_lock_irqsave(&adev->dbg.trace_lock, flags); |
| 63 | + if (!kfifo_initialized(&adev->dbg.trace_fifo)) { |
| 64 | + spin_unlock_irqrestore(&adev->dbg.trace_lock, flags); |
| 65 | + return 0; |
| 66 | + } |
| 67 | + |
| 68 | + size = avs_log_buffer_size(adev) / 2; |
| 69 | + write = readl(avs_sram_addr(adev, AVS_FW_REGS_WINDOW) + FW_REGS_DBG_LOG_WP(msg->log.core)); |
| 70 | + /* determine buffer half */ |
| 71 | + offset = (write < size) ? size : 0; |
| 72 | + |
| 73 | + /* Address is guaranteed to exist in SRAM2. */ |
| 74 | + buf = avs_log_buffer_addr(adev, msg->log.core) + offset; |
| 75 | + __kfifo_fromio_locked(&adev->dbg.trace_fifo, buf, size, &adev->dbg.fifo_lock); |
| 76 | + wake_up(&adev->dbg.trace_waitq); |
| 77 | + spin_unlock_irqrestore(&adev->dbg.trace_lock, flags); |
| 78 | + |
| 79 | + return 0; |
| 80 | +} |
| 81 | + |
| 82 | +static int skl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) |
| 83 | +{ |
| 84 | + u8 *dump; |
| 85 | + |
| 86 | + dump = vzalloc(AVS_FW_REGS_SIZE); |
| 87 | + if (!dump) |
| 88 | + return -ENOMEM; |
| 89 | + |
| 90 | + memcpy_fromio(dump, avs_sram_addr(adev, AVS_FW_REGS_WINDOW), AVS_FW_REGS_SIZE); |
| 91 | + dev_coredumpv(adev->dev, dump, AVS_FW_REGS_SIZE, GFP_KERNEL); |
| 92 | + |
| 93 | + return 0; |
| 94 | +} |
| 95 | + |
| 96 | +static bool |
| 97 | +skl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake) |
| 98 | +{ |
| 99 | + /* unsupported on cAVS 1.5 hw */ |
| 100 | + return false; |
| 101 | +} |
| 102 | + |
| 103 | +static int skl_set_d0ix(struct avs_dev *adev, bool enable) |
| 104 | +{ |
| 105 | + /* unsupported on cAVS 1.5 hw */ |
| 106 | + return 0; |
| 107 | +} |
| 108 | + |
| 109 | +const struct avs_dsp_ops skl_dsp_ops = { |
| 110 | + .power = avs_dsp_core_power, |
| 111 | + .reset = avs_dsp_core_reset, |
| 112 | + .stall = avs_dsp_core_stall, |
| 113 | + .irq_handler = avs_dsp_irq_handler, |
| 114 | + .irq_thread = avs_dsp_irq_thread, |
| 115 | + .int_control = avs_dsp_interrupt_control, |
| 116 | + .load_basefw = avs_cldma_load_basefw, |
| 117 | + .load_lib = avs_cldma_load_library, |
| 118 | + .transfer_mods = avs_cldma_transfer_modules, |
| 119 | + .enable_logs = skl_enable_logs, |
| 120 | + .log_buffer_offset = skl_log_buffer_offset, |
| 121 | + .log_buffer_status = skl_log_buffer_status, |
| 122 | + .coredump = skl_coredump, |
| 123 | + .d0ix_toggle = skl_d0ix_toggle, |
| 124 | + .set_d0ix = skl_set_d0ix, |
| 125 | +}; |
0 commit comments