^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * skl-sst-ipc.c - Intel skl IPC Support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2014-15, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "../common/sst-dsp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "../common/sst-dsp-priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "skl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "skl-sst-dsp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "skl-sst-ipc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "sound/hdaudio_ext.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define IPC_IXC_STATUS_BITS 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* Global Message - Generic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define IPC_GLB_TYPE_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define IPC_GLB_TYPE_MASK (0xf << IPC_GLB_TYPE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define IPC_GLB_TYPE(x) ((x) << IPC_GLB_TYPE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* Global Message - Reply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define IPC_GLB_REPLY_STATUS_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define IPC_GLB_REPLY_STATUS_MASK ((0x1 << IPC_GLB_REPLY_STATUS_SHIFT) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define IPC_GLB_REPLY_STATUS(x) ((x) << IPC_GLB_REPLY_STATUS_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define IPC_GLB_REPLY_TYPE_SHIFT 29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define IPC_GLB_REPLY_TYPE_MASK 0x1F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define IPC_GLB_REPLY_TYPE(x) (((x) >> IPC_GLB_REPLY_TYPE_SHIFT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) & IPC_GLB_RPLY_TYPE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define IPC_TIMEOUT_MSECS 3000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define IPC_EMPTY_LIST_SIZE 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define IPC_MSG_TARGET_SHIFT 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define IPC_MSG_TARGET_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define IPC_MSG_TARGET(x) (((x) & IPC_MSG_TARGET_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) << IPC_MSG_TARGET_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define IPC_MSG_DIR_SHIFT 29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define IPC_MSG_DIR_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define IPC_MSG_DIR(x) (((x) & IPC_MSG_DIR_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) << IPC_MSG_DIR_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* Global Notification Message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define IPC_GLB_NOTIFY_TYPE_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define IPC_GLB_NOTIFY_TYPE_MASK 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define IPC_GLB_NOTIFY_TYPE(x) (((x) >> IPC_GLB_NOTIFY_TYPE_SHIFT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) & IPC_GLB_NOTIFY_TYPE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define IPC_GLB_NOTIFY_MSG_TYPE_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define IPC_GLB_NOTIFY_MSG_TYPE_MASK 0x1F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define IPC_GLB_NOTIFY_MSG_TYPE(x) (((x) >> IPC_GLB_NOTIFY_MSG_TYPE_SHIFT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) & IPC_GLB_NOTIFY_MSG_TYPE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define IPC_GLB_NOTIFY_RSP_SHIFT 29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define IPC_GLB_NOTIFY_RSP_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define IPC_GLB_NOTIFY_RSP_TYPE(x) (((x) >> IPC_GLB_NOTIFY_RSP_SHIFT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) & IPC_GLB_NOTIFY_RSP_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Pipeline operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Create pipeline message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define IPC_PPL_MEM_SIZE_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define IPC_PPL_MEM_SIZE_MASK 0x7FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define IPC_PPL_MEM_SIZE(x) (((x) & IPC_PPL_MEM_SIZE_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) << IPC_PPL_MEM_SIZE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define IPC_PPL_TYPE_SHIFT 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define IPC_PPL_TYPE_MASK 0x1F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define IPC_PPL_TYPE(x) (((x) & IPC_PPL_TYPE_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) << IPC_PPL_TYPE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define IPC_INSTANCE_ID_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define IPC_INSTANCE_ID_MASK 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define IPC_INSTANCE_ID(x) (((x) & IPC_INSTANCE_ID_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) << IPC_INSTANCE_ID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define IPC_PPL_LP_MODE_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define IPC_PPL_LP_MODE_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define IPC_PPL_LP_MODE(x) (((x) & IPC_PPL_LP_MODE_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) << IPC_PPL_LP_MODE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* Set pipeline state message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define IPC_PPL_STATE_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define IPC_PPL_STATE_MASK 0x1F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define IPC_PPL_STATE(x) (((x) & IPC_PPL_STATE_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) << IPC_PPL_STATE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Module operations primary register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define IPC_MOD_ID_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define IPC_MOD_ID_MASK 0xFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define IPC_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) << IPC_MOD_ID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define IPC_MOD_INSTANCE_ID_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define IPC_MOD_INSTANCE_ID_MASK 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define IPC_MOD_INSTANCE_ID(x) (((x) & IPC_MOD_INSTANCE_ID_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) << IPC_MOD_INSTANCE_ID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* Init instance message extension register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define IPC_PARAM_BLOCK_SIZE_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define IPC_PARAM_BLOCK_SIZE_MASK 0xFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define IPC_PARAM_BLOCK_SIZE(x) (((x) & IPC_PARAM_BLOCK_SIZE_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) << IPC_PARAM_BLOCK_SIZE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define IPC_PPL_INSTANCE_ID_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define IPC_PPL_INSTANCE_ID_MASK 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define IPC_PPL_INSTANCE_ID(x) (((x) & IPC_PPL_INSTANCE_ID_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) << IPC_PPL_INSTANCE_ID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define IPC_CORE_ID_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define IPC_CORE_ID_MASK 0x1F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) << IPC_CORE_ID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define IPC_DOMAIN_SHIFT 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define IPC_DOMAIN_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define IPC_DOMAIN(x) (((x) & IPC_DOMAIN_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) << IPC_DOMAIN_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Bind/Unbind message extension register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define IPC_DST_MOD_ID_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) << IPC_DST_MOD_ID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define IPC_DST_MOD_INSTANCE_ID_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define IPC_DST_MOD_INSTANCE_ID(x) (((x) & IPC_MOD_INSTANCE_ID_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) << IPC_DST_MOD_INSTANCE_ID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define IPC_DST_QUEUE_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define IPC_DST_QUEUE_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define IPC_DST_QUEUE(x) (((x) & IPC_DST_QUEUE_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) << IPC_DST_QUEUE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define IPC_SRC_QUEUE_SHIFT 27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define IPC_SRC_QUEUE_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define IPC_SRC_QUEUE(x) (((x) & IPC_SRC_QUEUE_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) << IPC_SRC_QUEUE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* Load Module count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define IPC_LOAD_MODULE_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define IPC_LOAD_MODULE_MASK 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define IPC_LOAD_MODULE_CNT(x) (((x) & IPC_LOAD_MODULE_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) << IPC_LOAD_MODULE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* Save pipeline messgae extension register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define IPC_DMA_ID_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define IPC_DMA_ID_MASK 0x1F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define IPC_DMA_ID(x) (((x) & IPC_DMA_ID_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) << IPC_DMA_ID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Large Config message extension register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define IPC_DATA_OFFSET_SZ_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define IPC_DATA_OFFSET_SZ_MASK 0xFFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define IPC_DATA_OFFSET_SZ(x) (((x) & IPC_DATA_OFFSET_SZ_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) << IPC_DATA_OFFSET_SZ_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define IPC_DATA_OFFSET_SZ_CLEAR ~(IPC_DATA_OFFSET_SZ_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) << IPC_DATA_OFFSET_SZ_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define IPC_LARGE_PARAM_ID_SHIFT 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define IPC_LARGE_PARAM_ID_MASK 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define IPC_LARGE_PARAM_ID(x) (((x) & IPC_LARGE_PARAM_ID_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) << IPC_LARGE_PARAM_ID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define IPC_FINAL_BLOCK_SHIFT 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define IPC_FINAL_BLOCK_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define IPC_FINAL_BLOCK(x) (((x) & IPC_FINAL_BLOCK_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) << IPC_FINAL_BLOCK_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define IPC_INITIAL_BLOCK_SHIFT 29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define IPC_INITIAL_BLOCK_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define IPC_INITIAL_BLOCK(x) (((x) & IPC_INITIAL_BLOCK_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) << IPC_INITIAL_BLOCK_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define IPC_INITIAL_BLOCK_CLEAR ~(IPC_INITIAL_BLOCK_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) << IPC_INITIAL_BLOCK_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* Set D0ix IPC extension register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define IPC_D0IX_WAKE_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define IPC_D0IX_WAKE_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define IPC_D0IX_WAKE(x) (((x) & IPC_D0IX_WAKE_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) << IPC_D0IX_WAKE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define IPC_D0IX_STREAMING_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define IPC_D0IX_STREAMING_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define IPC_D0IX_STREAMING(x) (((x) & IPC_D0IX_STREAMING_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) << IPC_D0IX_STREAMING_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) enum skl_ipc_msg_target {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) IPC_FW_GEN_MSG = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) IPC_MOD_MSG = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) enum skl_ipc_msg_direction {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) IPC_MSG_REQUEST = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) IPC_MSG_REPLY = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* Global Message Types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) enum skl_ipc_glb_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) IPC_GLB_GET_FW_VERSION = 0, /* Retrieves firmware version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) IPC_GLB_LOAD_MULTIPLE_MODS = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) IPC_GLB_UNLOAD_MULTIPLE_MODS = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) IPC_GLB_CREATE_PPL = 17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) IPC_GLB_DELETE_PPL = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) IPC_GLB_SET_PPL_STATE = 19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) IPC_GLB_GET_PPL_STATE = 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) IPC_GLB_GET_PPL_CONTEXT_SIZE = 21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) IPC_GLB_SAVE_PPL = 22,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) IPC_GLB_RESTORE_PPL = 23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) IPC_GLB_LOAD_LIBRARY = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) IPC_GLB_NOTIFY = 26,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) enum skl_ipc_glb_reply {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) IPC_GLB_REPLY_SUCCESS = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) IPC_GLB_REPLY_UNKNOWN_MSG_TYPE = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) IPC_GLB_REPLY_ERROR_INVALID_PARAM = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) IPC_GLB_REPLY_BUSY = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) IPC_GLB_REPLY_PENDING = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) IPC_GLB_REPLY_FAILURE = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) IPC_GLB_REPLY_INVALID_REQUEST = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) IPC_GLB_REPLY_OUT_OF_MEMORY = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) IPC_GLB_REPLY_OUT_OF_MIPS = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) IPC_GLB_REPLY_INVALID_RESOURCE_ID = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) IPC_GLB_REPLY_INVALID_RESOURCE_STATE = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) IPC_GLB_REPLY_MOD_MGMT_ERROR = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) IPC_GLB_REPLY_MOD_LOAD_CL_FAILED = 101,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) IPC_GLB_REPLY_MOD_LOAD_INVALID_HASH = 102,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) IPC_GLB_REPLY_MOD_UNLOAD_INST_EXIST = 103,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) IPC_GLB_REPLY_MOD_NOT_INITIALIZED = 104,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) IPC_GLB_REPLY_INVALID_CONFIG_PARAM_ID = 120,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) IPC_GLB_REPLY_INVALID_CONFIG_DATA_LEN = 121,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) IPC_GLB_REPLY_GATEWAY_NOT_INITIALIZED = 140,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) IPC_GLB_REPLY_GATEWAY_NOT_EXIST = 141,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) IPC_GLB_REPLY_SCLK_ALREADY_RUNNING = 150,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) IPC_GLB_REPLY_MCLK_ALREADY_RUNNING = 151,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) IPC_GLB_REPLY_PPL_NOT_INITIALIZED = 160,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) IPC_GLB_REPLY_PPL_NOT_EXIST = 161,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) IPC_GLB_REPLY_PPL_SAVE_FAILED = 162,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) IPC_GLB_REPLY_PPL_RESTORE_FAILED = 163,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) IPC_MAX_STATUS = ((1<<IPC_IXC_STATUS_BITS)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) enum skl_ipc_notification_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) IPC_GLB_NOTIFY_GLITCH = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) IPC_GLB_NOTIFY_OVERRUN = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) IPC_GLB_NOTIFY_UNDERRUN = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) IPC_GLB_NOTIFY_END_STREAM = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) IPC_GLB_NOTIFY_PHRASE_DETECTED = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) IPC_GLB_NOTIFY_RESOURCE_EVENT = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) IPC_GLB_NOTIFY_LOG_BUFFER_STATUS = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) IPC_GLB_NOTIFY_TIMESTAMP_CAPTURED = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) IPC_GLB_NOTIFY_FW_READY = 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /* Module Message Types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) enum skl_ipc_module_msg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) IPC_MOD_INIT_INSTANCE = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) IPC_MOD_CONFIG_GET = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) IPC_MOD_CONFIG_SET = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) IPC_MOD_LARGE_CONFIG_GET = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) IPC_MOD_LARGE_CONFIG_SET = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) IPC_MOD_BIND = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) IPC_MOD_UNBIND = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) IPC_MOD_SET_DX = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) IPC_MOD_SET_D0IX = 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) size_t tx_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (tx_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) memcpy(msg->tx.data, tx_data, tx_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) u32 hipci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) hipci = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return (hipci & SKL_ADSP_REG_HIPCI_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* Lock to be held by caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (msg->tx.size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) header->extension);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) header->primary | SKL_ADSP_REG_HIPCI_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) int skl_ipc_check_D0i0(struct sst_dsp *dsp, bool state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* check D0i3 support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (!dsp->fw_ops.set_state_D0i0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /* Attempt D0i0 or D0i3 based on state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ret = dsp->fw_ops.set_state_D0i0(dsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ret = dsp->fw_ops.set_state_D0i3(dsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static struct ipc_message *skl_ipc_reply_get_msg(struct sst_generic_ipc *ipc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) u64 ipc_header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct ipc_message *msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct skl_ipc_header *header = (struct skl_ipc_header *)(&ipc_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (list_empty(&ipc->rx_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) dev_err(ipc->dev, "ipc: rx list is empty but received 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) header->primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) msg = list_first_entry(&ipc->rx_list, struct ipc_message, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) list_del(&msg->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct skl_ipc_header header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct skl_dev *skl = container_of(ipc, struct skl_dev, ipc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) switch (IPC_GLB_NOTIFY_TYPE(header.primary)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) case IPC_GLB_NOTIFY_UNDERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) dev_err(ipc->dev, "FW Underrun %x\n", header.primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) case IPC_GLB_NOTIFY_RESOURCE_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) dev_err(ipc->dev, "MCPS Budget Violation: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) header.primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case IPC_GLB_NOTIFY_FW_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) skl->boot_complete = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) wake_up(&skl->boot_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case IPC_GLB_NOTIFY_PHRASE_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) dev_dbg(ipc->dev, "***** Phrase Detected **********\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * Per HW recomendation, After phrase detection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * clear the CGCTL.MISCBDCGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * This will be set back on stream closure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) skl->enable_miscbdcge(ipc->dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) skl->miscbdcg_disabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) dev_err(ipc->dev, "ipc: Unhandled error msg=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) header.primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct skl_ipc_err_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) const char *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) enum skl_ipc_glb_reply reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static struct skl_ipc_err_map skl_err_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {"DSP out of memory", IPC_GLB_REPLY_OUT_OF_MEMORY, -ENOMEM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {"DSP busy", IPC_GLB_REPLY_BUSY, -EBUSY},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {"SCLK already running", IPC_GLB_REPLY_SCLK_ALREADY_RUNNING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) IPC_GLB_REPLY_SCLK_ALREADY_RUNNING},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {"MCLK already running", IPC_GLB_REPLY_MCLK_ALREADY_RUNNING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) IPC_GLB_REPLY_MCLK_ALREADY_RUNNING},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static int skl_ipc_set_reply_error_code(struct sst_generic_ipc *ipc, u32 reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) for (i = 0; i < ARRAY_SIZE(skl_err_map); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (skl_err_map[i].reply == reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (i == ARRAY_SIZE(skl_err_map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) dev_err(ipc->dev, "ipc FW reply: %d FW Error Code: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (skl_err_map[i].err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) dev_err(ipc->dev, "ipc FW reply: %s FW Error Code: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) skl_err_map[i].msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) dev_info(ipc->dev, "ipc FW reply: %s FW Error Code: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) skl_err_map[i].msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return skl_err_map[i].err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct skl_ipc_header header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct ipc_message *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) u64 *ipc_header = (u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct skl_dev *skl = container_of(ipc, struct skl_dev, ipc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) spin_lock_irqsave(&ipc->dsp->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) msg = skl_ipc_reply_get_msg(ipc, *ipc_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (msg == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) dev_dbg(ipc->dev, "ipc: rx list is empty\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) msg->rx.header = *ipc_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /* first process the header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (reply == IPC_GLB_REPLY_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* copy the rx data from the mailbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) sst_dsp_inbox_read(ipc->dsp, msg->rx.data, msg->rx.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) case IPC_GLB_LOAD_MULTIPLE_MODS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) case IPC_GLB_LOAD_LIBRARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) skl->mod_load_complete = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) skl->mod_load_status = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) wake_up(&skl->mod_load_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) msg->errno = skl_ipc_set_reply_error_code(ipc, reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) case IPC_GLB_LOAD_MULTIPLE_MODS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) case IPC_GLB_LOAD_LIBRARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) skl->mod_load_complete = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) skl->mod_load_status = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) wake_up(&skl->mod_load_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) spin_lock_irqsave(&ipc->dsp->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) sst_ipc_tx_msg_reply_complete(ipc, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct sst_dsp *dsp = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct skl_dev *skl = dsp->thread_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct sst_generic_ipc *ipc = &skl->ipc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) u32 hipcie, hipct, hipcte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) int ipc_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (dsp->intr_status & SKL_ADSPIS_CL_DMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) skl_cldma_process_intr(dsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* Here we handle IPC interrupts only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (!(dsp->intr_status & SKL_ADSPIS_IPC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) hipcie = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) hipct = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* reply message from DSP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (hipcie & SKL_ADSP_REG_HIPCIE_DONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) sst_dsp_shim_update_bits(dsp, SKL_ADSP_REG_HIPCCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) SKL_ADSP_REG_HIPCCTL_DONE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /* clear DONE bit - tell DSP we have completed the operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) sst_dsp_shim_update_bits_forced(dsp, SKL_ADSP_REG_HIPCIE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) SKL_ADSP_REG_HIPCIE_DONE, SKL_ADSP_REG_HIPCIE_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ipc_irq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* unmask Done interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) sst_dsp_shim_update_bits(dsp, SKL_ADSP_REG_HIPCCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) SKL_ADSP_REG_HIPCCTL_DONE, SKL_ADSP_REG_HIPCCTL_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* New message from DSP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (hipct & SKL_ADSP_REG_HIPCT_BUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) header.primary = hipct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) header.extension = hipcte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) header.primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) header.extension);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* Handle Immediate reply from DSP Core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) skl_ipc_process_reply(ipc, header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) dev_dbg(dsp->dev, "IPC irq: Notification from firmware\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) skl_ipc_process_notification(ipc, header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* clear busy interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) sst_dsp_shim_update_bits_forced(dsp, SKL_ADSP_REG_HIPCT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) SKL_ADSP_REG_HIPCT_BUSY, SKL_ADSP_REG_HIPCT_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ipc_irq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (ipc_irq == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) skl_ipc_int_enable(dsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* continue to send any remaining messages... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) schedule_work(&ipc->kwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) void skl_ipc_int_enable(struct sst_dsp *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_ADSPIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) SKL_ADSPIC_IPC, SKL_ADSPIC_IPC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) void skl_ipc_int_disable(struct sst_dsp *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) SKL_ADSPIC_IPC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) void skl_ipc_op_int_enable(struct sst_dsp *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /* enable IPC DONE interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_HIPCCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) SKL_ADSP_REG_HIPCCTL_DONE, SKL_ADSP_REG_HIPCCTL_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /* Enable IPC BUSY interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_HIPCCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) SKL_ADSP_REG_HIPCCTL_BUSY, SKL_ADSP_REG_HIPCCTL_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) void skl_ipc_op_int_disable(struct sst_dsp *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /* disable IPC DONE interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) SKL_ADSP_REG_HIPCCTL_DONE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /* Disable IPC BUSY interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) SKL_ADSP_REG_HIPCCTL_BUSY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) bool skl_ipc_int_status(struct sst_dsp *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return sst_dsp_shim_read_unlocked(ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) SKL_ADSP_REG_ADSPIS) & SKL_ADSPIS_IPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) int skl_ipc_init(struct device *dev, struct skl_dev *skl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct sst_generic_ipc *ipc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ipc = &skl->ipc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) ipc->dsp = skl->dsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ipc->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ipc->tx_data_max_size = SKL_ADSP_W1_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ipc->rx_data_max_size = SKL_ADSP_W0_UP_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) err = sst_ipc_init(ipc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ipc->ops.tx_msg = skl_ipc_tx_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) ipc->ops.tx_data_copy = skl_ipc_tx_data_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) ipc->ops.is_dsp_busy = skl_ipc_is_dsp_busy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) void skl_ipc_free(struct sst_generic_ipc *ipc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /* Disable IPC DONE interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) sst_dsp_shim_update_bits(ipc->dsp, SKL_ADSP_REG_HIPCCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) SKL_ADSP_REG_HIPCCTL_DONE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /* Disable IPC BUSY interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) sst_dsp_shim_update_bits(ipc->dsp, SKL_ADSP_REG_HIPCCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) SKL_ADSP_REG_HIPCCTL_BUSY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) sst_ipc_fini(ipc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct sst_ipc_message request = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) header.primary |= IPC_GLB_TYPE(IPC_GLB_CREATE_PPL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) header.primary |= IPC_INSTANCE_ID(instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) header.primary |= IPC_PPL_TYPE(ppl_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) header.extension = IPC_PPL_LP_MODE(lp_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) ret = sst_ipc_tx_message_wait(ipc, request, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) EXPORT_SYMBOL_GPL(skl_ipc_create_pipeline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct sst_ipc_message request = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) header.primary |= IPC_INSTANCE_ID(instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ret = sst_ipc_tx_message_wait(ipc, request, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) EXPORT_SYMBOL_GPL(skl_ipc_delete_pipeline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) u8 instance_id, enum skl_ipc_pipeline_state state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct sst_ipc_message request = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) header.primary |= IPC_INSTANCE_ID(instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) header.primary |= IPC_PPL_STATE(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ret = sst_ipc_tx_message_wait(ipc, request, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) EXPORT_SYMBOL_GPL(skl_ipc_set_pipeline_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct sst_ipc_message request = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) header.primary |= IPC_GLB_TYPE(IPC_GLB_SAVE_PPL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) header.primary |= IPC_INSTANCE_ID(instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) header.extension = IPC_DMA_ID(dma_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) ret = sst_ipc_tx_message_wait(ipc, request, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) EXPORT_SYMBOL_GPL(skl_ipc_save_pipeline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) struct sst_ipc_message request = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) header.primary |= IPC_INSTANCE_ID(instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) ret = sst_ipc_tx_message_wait(ipc, request, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) dev_err(ipc->dev, "ipc: restore pipeline failed, err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) EXPORT_SYMBOL_GPL(skl_ipc_restore_pipeline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) u16 module_id, struct skl_ipc_dxstate_info *dx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct sst_ipc_message request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) header.primary |= IPC_GLB_TYPE(IPC_MOD_SET_DX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) header.primary |= IPC_MOD_INSTANCE_ID(instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) header.primary |= IPC_MOD_ID(module_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) request.data = dx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) request.size = sizeof(*dx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) header.primary, header.extension);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) ret = sst_ipc_tx_message_wait(ipc, request, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) EXPORT_SYMBOL_GPL(skl_ipc_set_dx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct skl_ipc_init_instance_msg *msg, void *param_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct sst_ipc_message request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) u32 *buffer = (u32 *)param_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /* param_block_size must be in dwords */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) u16 param_block_size = msg->param_data_size / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) print_hex_dump_debug("Param data:", DUMP_PREFIX_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 16, 4, buffer, param_block_size, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) header.primary |= IPC_GLB_TYPE(IPC_MOD_INIT_INSTANCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) header.primary |= IPC_MOD_ID(msg->module_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) header.extension = IPC_CORE_ID(msg->core_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) header.extension |= IPC_DOMAIN(msg->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) request.data = param_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) request.size = msg->param_data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) header.primary, header.extension);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ret = sst_ipc_tx_message_wait(ipc, request, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) dev_err(ipc->dev, "ipc: init instance failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) EXPORT_SYMBOL_GPL(skl_ipc_init_instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct skl_ipc_bind_unbind_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) struct sst_ipc_message request = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) header.primary |= IPC_GLB_TYPE(bind_unbind);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) header.primary |= IPC_MOD_ID(msg->module_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) header.extension = IPC_DST_MOD_ID(msg->dst_module_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) header.extension |= IPC_DST_QUEUE(msg->dst_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) header.extension |= IPC_SRC_QUEUE(msg->src_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) header.extension);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) ret = sst_ipc_tx_message_wait(ipc, request, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) dev_err(ipc->dev, "ipc: bind/unbind failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) EXPORT_SYMBOL_GPL(skl_ipc_bind_unbind);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) * In order to load a module we need to send IPC to initiate that. DMA will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) * performed to load the module memory. The FW supports multiple module load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * at single shot, so we can send IPC with N modules represented by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) * module_cnt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) u8 module_cnt, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) struct sst_ipc_message request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) request.data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) request.size = sizeof(u16) * module_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) ret = sst_ipc_tx_message_nowait(ipc, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) EXPORT_SYMBOL_GPL(skl_ipc_load_modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) struct sst_ipc_message request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) request.data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) request.size = sizeof(u16) * module_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ret = sst_ipc_tx_message_wait(ipc, request, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) EXPORT_SYMBOL_GPL(skl_ipc_unload_modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct skl_ipc_large_config_msg *msg, u32 *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct sst_ipc_message request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) size_t sz_remaining, tx_size, data_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) header.primary |= IPC_GLB_TYPE(IPC_MOD_LARGE_CONFIG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) header.primary |= IPC_MOD_ID(msg->module_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) header.extension = IPC_DATA_OFFSET_SZ(msg->param_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) header.extension |= IPC_LARGE_PARAM_ID(msg->large_param_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) header.extension |= IPC_FINAL_BLOCK(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) header.extension |= IPC_INITIAL_BLOCK(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) sz_remaining = msg->param_data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) data_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) while (sz_remaining != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) tx_size = sz_remaining > SKL_ADSP_W1_SZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) ? SKL_ADSP_W1_SZ : sz_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (tx_size == sz_remaining)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) header.extension |= IPC_FINAL_BLOCK(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) dev_dbg(ipc->dev, "In %s primary=%#x ext=%#x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) header.primary, header.extension);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) (unsigned)data_offset, (unsigned)tx_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) request.data = ((char *)param) + data_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) request.size = tx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ret = sst_ipc_tx_message_wait(ipc, request, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) dev_err(ipc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) "ipc: set large config fail, err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) sz_remaining -= tx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) data_offset = msg->param_data_size - sz_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) /* clear the fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) header.extension &= IPC_INITIAL_BLOCK_CLEAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) header.extension &= IPC_DATA_OFFSET_SZ_CLEAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) /* fill the fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) header.extension |= IPC_INITIAL_BLOCK(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) header.extension |= IPC_DATA_OFFSET_SZ(data_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) EXPORT_SYMBOL_GPL(skl_ipc_set_large_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct skl_ipc_large_config_msg *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) u32 **payload, size_t *bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct sst_ipc_message request, reply = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) unsigned int *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) reply.data = kzalloc(SKL_ADSP_W1_SZ, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (!reply.data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) header.primary |= IPC_GLB_TYPE(IPC_MOD_LARGE_CONFIG_GET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) header.primary |= IPC_MOD_ID(msg->module_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) header.extension = IPC_DATA_OFFSET_SZ(msg->param_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) header.extension |= IPC_LARGE_PARAM_ID(msg->large_param_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) header.extension |= IPC_FINAL_BLOCK(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) header.extension |= IPC_INITIAL_BLOCK(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) request.header = *(u64 *)&header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) request.data = *payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) request.size = *bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) reply.size = SKL_ADSP_W1_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) ret = sst_ipc_tx_message_wait(ipc, request, &reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) dev_err(ipc->dev, "ipc: get large config fail, err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) reply.size = (reply.header >> 32) & IPC_DATA_OFFSET_SZ_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) buf = krealloc(reply.data, reply.size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) *payload = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) *bytes = reply.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) u8 dma_id, u8 table_id, bool wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) struct sst_ipc_message request = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) header.primary |= IPC_MOD_INSTANCE_ID(table_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) header.primary |= IPC_MOD_ID(dma_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) ret = sst_ipc_tx_message_wait(ipc, request, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) ret = sst_ipc_tx_message_nowait(ipc, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) dev_err(ipc->dev, "ipc: load lib failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct skl_ipc_header header = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) struct sst_ipc_message request = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) header.primary |= IPC_GLB_TYPE(IPC_MOD_SET_D0IX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) header.primary |= IPC_MOD_ID(msg->module_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) header.extension = IPC_D0IX_WAKE(msg->wake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) header.extension |= IPC_D0IX_STREAMING(msg->streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) request.header = *(u64 *)(&header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) header.primary, header.extension);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) * Use the nopm IPC here as we dont want it checking for D0iX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) ret = sst_ipc_tx_message_nopm(ipc, request, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) EXPORT_SYMBOL_GPL(skl_ipc_set_d0ix);