msm: eva: mmap firmware debug memory
For user mode to save into a dump file. It helps FW debugging. Change-Id: I1c9c52d27d0dfd20e3eeb54b203416f6df095c8d Signed-off-by: George Shen <quic_sqiao@quicinc.com>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
aafc38db81
commit
ea94318515
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#ifndef __MSM_EVA_PRIVATE_H__
|
||||
#define __MSM_EVA_PRIVATE_H__
|
||||
@@ -139,6 +140,7 @@ struct eva_kmd_hfi_packet {
|
||||
#define EVA_KMD_PROP_SESSION_DSPMASK 6
|
||||
#define EVA_KMD_PROP_SESSION_DUMPOFFSET 7
|
||||
#define EVA_KMD_PROP_SESSION_DUMPSIZE 8
|
||||
#define EVA_KMD_PROP_SESSION_ERROR 9
|
||||
|
||||
#define EVA_KMD_PROP_PWR_FDU 0x10
|
||||
#define EVA_KMD_PROP_PWR_ICA 0x11
|
||||
|
@@ -2531,8 +2531,8 @@ static int iris_debug_hook(void *device)
|
||||
dprintk(CVP_ERR, "%s Invalid device\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
__write_register(dev, CVP_WRAPPER_CORE_CLOCK_CONFIG, 0x11);
|
||||
__write_register(dev, CVP_WRAPPER_TZ_CPU_CLOCK_CONFIG, 0x1);
|
||||
//__write_register(dev, CVP_WRAPPER_CORE_CLOCK_CONFIG, 0x11);
|
||||
//__write_register(dev, CVP_WRAPPER_TZ_CPU_CLOCK_CONFIG, 0x1);
|
||||
dprintk(CVP_ERR, "Halt Tensilica and core and axi\n");
|
||||
return 0;
|
||||
|
||||
|
@@ -207,7 +207,7 @@ static int msm_cvp_session_process_hfi(
|
||||
}
|
||||
|
||||
if (is_config_pkt)
|
||||
pr_info(CVP_DBG_TAG "inst %pK config %s\n", "sess",
|
||||
pr_info_ratelimited(CVP_DBG_TAG "inst %pK config %s\n", "sess",
|
||||
inst, cvp_hfi_defs[pkt_idx].name);
|
||||
|
||||
if (signal == HAL_NO_RESP) {
|
||||
@@ -657,7 +657,7 @@ static int cvp_enqueue_pkt(struct msm_cvp_inst* inst,
|
||||
if (map_type == MAP_PERSIST)
|
||||
rc = msm_cvp_map_user_persist(inst, in_pkt, in_offset, in_buf_num);
|
||||
else if (map_type == UNMAP_PERSIST)
|
||||
rc = msm_cvp_mark_user_persist(inst, in_pkt, in_offset, in_buf_num);
|
||||
rc = msm_cvp_unmap_user_persist(inst, in_pkt, in_offset, in_buf_num);
|
||||
else
|
||||
rc = msm_cvp_map_frame(inst, in_pkt, in_offset, in_buf_num);
|
||||
|
||||
@@ -893,7 +893,8 @@ int msm_cvp_session_start(struct msm_cvp_inst *inst,
|
||||
goto stop_thread;
|
||||
}
|
||||
|
||||
dprintk(CVP_SESS, "session %llx (%#x) started\n", inst, hash32_ptr(inst->session));
|
||||
pr_info_ratelimited(CVP_DBG_TAG "session %llx (%#x) started\n",
|
||||
"sess", inst, hash32_ptr(inst->session));
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -942,8 +943,8 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst,
|
||||
}
|
||||
sq->state = QUEUE_STOP;
|
||||
|
||||
dprintk(CVP_SESS, "Stop session: %pK session_id = %d\n",
|
||||
inst, hash32_ptr(inst->session));
|
||||
pr_info_ratelimited(CVP_DBG_TAG "Stop session: %pK session_id = %d\n",
|
||||
"sess", inst, hash32_ptr(inst->session));
|
||||
spin_unlock(&sq->lock);
|
||||
|
||||
hdev = inst->core->device;
|
||||
@@ -1076,6 +1077,18 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst,
|
||||
session_prop->dump_size;
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_PROP_SESSION_ERROR:
|
||||
{
|
||||
rc = dma_buf_fd(hfi->mem_addr.mem_data.dma_buf, O_RDONLY | O_CLOEXEC);
|
||||
if (rc < 0) {
|
||||
dprintk(CVP_WARN, "Failed get dma_buf fd %d\n", rc);
|
||||
break;
|
||||
}
|
||||
|
||||
props->prop_data[i].data = rc;
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_PROP_PWR_FDU:
|
||||
{
|
||||
props->prop_data[i].data =
|
||||
|
@@ -1418,16 +1418,67 @@ exit:
|
||||
return smem;
|
||||
}
|
||||
|
||||
static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst,
|
||||
static int msm_cvp_unmap_user_persist_buf(struct msm_cvp_inst *inst,
|
||||
struct cvp_buf_type *buf,
|
||||
u32 pkt_type, u32 buf_idx)
|
||||
u32 pkt_type, u32 buf_idx, u32 *iova)
|
||||
{
|
||||
struct msm_cvp_smem *smem = NULL;
|
||||
struct list_head *ptr;
|
||||
struct list_head *next;
|
||||
struct cvp_internal_buf *pbuf;
|
||||
struct dma_buf *dma_buf;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dma_buf = msm_cvp_smem_get_dma_buf(buf->fd);
|
||||
if (!dma_buf)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&inst->persistbufs.lock);
|
||||
list_for_each_safe(ptr, next, &inst->persistbufs.list) {
|
||||
if (!ptr) {
|
||||
mutex_unlock(&inst->persistbufs.lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
pbuf = list_entry(ptr, struct cvp_internal_buf, list);
|
||||
if (dma_buf == pbuf->smem->dma_buf && (pbuf->smem->flags & SMEM_PERSIST)) {
|
||||
*iova = pbuf->smem->device_addr;
|
||||
dprintk(CVP_MEM,
|
||||
"Unmap persist fd %d, dma_buf %#llx iova %#x\n",
|
||||
pbuf->fd, pbuf->smem->dma_buf, *iova);
|
||||
list_del(&pbuf->list);
|
||||
if (*iova) {
|
||||
msm_cvp_unmap_smem(inst, pbuf->smem, "unmap user persist");
|
||||
msm_cvp_smem_put_dma_buf(pbuf->smem->dma_buf);
|
||||
pbuf->smem->device_addr = 0;
|
||||
}
|
||||
cvp_kmem_cache_free(&cvp_driver->smem_cache, smem);
|
||||
pbuf->smem = NULL;
|
||||
cvp_kmem_cache_free(&cvp_driver->buf_cache, pbuf);
|
||||
mutex_unlock(&inst->persistbufs.lock);
|
||||
dma_buf_put(dma_buf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&inst->persistbufs.lock);
|
||||
dma_buf_put(dma_buf);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst,
|
||||
struct cvp_buf_type *buf,
|
||||
u32 pkt_type, u32 buf_idx, u32 *iova)
|
||||
{
|
||||
u32 iova = 0;
|
||||
struct msm_cvp_smem *smem = NULL;
|
||||
struct list_head *ptr;
|
||||
struct list_head *next;
|
||||
struct cvp_internal_buf *pbuf;
|
||||
struct dma_buf *dma_buf;
|
||||
int ret;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
@@ -1441,24 +1492,24 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst,
|
||||
mutex_lock(&inst->persistbufs.lock);
|
||||
if (!inst->persistbufs.list.next) {
|
||||
mutex_unlock(&inst->persistbufs.lock);
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
list_for_each_safe(ptr, next, &inst->persistbufs.list) {
|
||||
if (!ptr)
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
pbuf = list_entry(ptr, struct cvp_internal_buf, list);
|
||||
if (dma_buf == pbuf->smem->dma_buf) {
|
||||
pbuf->size =
|
||||
(pbuf->size >= buf->size) ?
|
||||
pbuf->size : buf->size;
|
||||
iova = pbuf->smem->device_addr + buf->offset;
|
||||
*iova = pbuf->smem->device_addr + buf->offset;
|
||||
mutex_unlock(&inst->persistbufs.lock);
|
||||
atomic_inc(&pbuf->smem->refcount);
|
||||
dma_buf_put(dma_buf);
|
||||
dprintk(CVP_MEM,
|
||||
"map persist Reuse fd %d, dma_buf %#llx\n",
|
||||
pbuf->fd, pbuf->smem->dma_buf);
|
||||
return iova;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&inst->persistbufs.lock);
|
||||
@@ -1469,7 +1520,7 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst,
|
||||
if (!pbuf) {
|
||||
dprintk(CVP_ERR, "%s failed to allocate kmem obj\n",
|
||||
__func__);
|
||||
return 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (is_params_pkt(pkt_type))
|
||||
@@ -1477,8 +1528,10 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst,
|
||||
else
|
||||
smem = msm_cvp_session_get_smem(inst, buf, true, pkt_type);
|
||||
|
||||
if (!smem)
|
||||
if (!smem) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
smem->pkt_type = pkt_type;
|
||||
smem->buf_idx = buf_idx;
|
||||
@@ -1495,13 +1548,13 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst,
|
||||
|
||||
print_internal_buffer(CVP_MEM, "map persist", inst, pbuf);
|
||||
|
||||
iova = smem->device_addr + buf->offset;
|
||||
*iova = smem->device_addr + buf->offset;
|
||||
|
||||
return iova;
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
cvp_kmem_cache_free(&cvp_driver->buf_cache, pbuf);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst,
|
||||
@@ -1651,21 +1704,18 @@ void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid)
|
||||
dprintk(CVP_WARN, "%s frame %llu not found!\n", __func__, ktid);
|
||||
}
|
||||
|
||||
int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_hfi_packet *in_pkt,
|
||||
unsigned int offset, unsigned int buf_num)
|
||||
{
|
||||
dprintk(CVP_ERR, "Unexpected user persistent buffer release\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_cvp_map_user_persist(struct msm_cvp_inst *inst,
|
||||
/*
|
||||
* Unmap persistent buffer before sending RELEASE_PERSIST_BUFFERS to FW
|
||||
* This packet is sent after SESSION_STOP. The assumption is FW/HW will
|
||||
* NOT access any of the 3 persist buffer.
|
||||
*/
|
||||
int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_hfi_packet *in_pkt,
|
||||
unsigned int offset, unsigned int buf_num)
|
||||
{
|
||||
struct cvp_buf_type *buf;
|
||||
struct cvp_hfi_cmd_session_hdr *cmd_hdr;
|
||||
int i;
|
||||
int i, ret;
|
||||
u32 iova;
|
||||
|
||||
if (!offset || !buf_num)
|
||||
@@ -1679,14 +1729,48 @@ int msm_cvp_map_user_persist(struct msm_cvp_inst *inst,
|
||||
if (buf->fd < 0 || !buf->size)
|
||||
continue;
|
||||
|
||||
iova = msm_cvp_map_user_persist_buf(inst, buf,
|
||||
cmd_hdr->packet_type, i);
|
||||
if (!iova) {
|
||||
ret = msm_cvp_unmap_user_persist_buf(inst, buf,
|
||||
cmd_hdr->packet_type, i, &iova);
|
||||
if (ret) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: buf %d register failed.\n",
|
||||
"%s: buf %d unmap failed.\n",
|
||||
__func__, i);
|
||||
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
buf->fd = iova;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_cvp_map_user_persist(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_hfi_packet *in_pkt,
|
||||
unsigned int offset, unsigned int buf_num)
|
||||
{
|
||||
struct cvp_buf_type *buf;
|
||||
struct cvp_hfi_cmd_session_hdr *cmd_hdr;
|
||||
int i, ret;
|
||||
u32 iova;
|
||||
|
||||
if (!offset || !buf_num)
|
||||
return 0;
|
||||
|
||||
cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt;
|
||||
for (i = 0; i < buf_num; i++) {
|
||||
buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset];
|
||||
offset += sizeof(*buf) >> 2;
|
||||
|
||||
if (buf->fd < 0 || !buf->size)
|
||||
continue;
|
||||
|
||||
ret = msm_cvp_map_user_persist_buf(inst, buf,
|
||||
cmd_hdr->packet_type, i, &iova);
|
||||
if (ret) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: buf %d map failed.\n",
|
||||
__func__, i);
|
||||
|
||||
return ret;
|
||||
}
|
||||
buf->fd = iova;
|
||||
}
|
||||
|
@@ -113,11 +113,11 @@ static inline void DEINIT_DMAMAP_CACHE(struct cvp_dmamap_cache *cache)
|
||||
#define INPUT_FENCE_BITMASK 0x1
|
||||
#define OUTPUT_FENCE_BITMASK 0x2
|
||||
|
||||
/* Track source of dma_buf allocator/owner */
|
||||
enum buffer_owner {
|
||||
DRIVER,
|
||||
FIRMWARE,
|
||||
CLIENT,
|
||||
DSP,
|
||||
DRIVER, /* Allocated by KMD, for CPU driver */
|
||||
CLIENT, /* Allocated by Client (DSP or CPU) */
|
||||
DSP, /* Allocated by KMD, for DSP driver */
|
||||
MAX_OWNER
|
||||
};
|
||||
|
||||
@@ -219,7 +219,7 @@ int msm_cvp_proc_oob(struct msm_cvp_inst* inst,
|
||||
struct eva_kmd_hfi_packet* in_pkt);
|
||||
void msm_cvp_cache_operations(struct msm_cvp_smem *smem,
|
||||
u32 type, u32 offset, u32 size);
|
||||
int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst,
|
||||
int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_hfi_packet *in_pkt,
|
||||
unsigned int offset, unsigned int buf_num);
|
||||
int msm_cvp_map_user_persist(struct msm_cvp_inst *inst,
|
||||
|
Reference in New Issue
Block a user