msm: eva: Add SSR counter
Support configurable number of SSR tolerance before calling BUG_ON in SMMU fault scenario. Change-Id: I19dabbeaa1cf5be86f42a6ace62ef5da12743e79 Signed-off-by: George Shen <sqiao@codeaurora.org>
This commit is contained in:
@@ -148,6 +148,7 @@ static int msm_cvp_initialize_core(struct platform_device *pdev,
|
|||||||
INIT_DELAYED_WORK(&core->fw_unload_work, msm_cvp_fw_unload_handler);
|
INIT_DELAYED_WORK(&core->fw_unload_work, msm_cvp_fw_unload_handler);
|
||||||
INIT_WORK(&core->ssr_work, msm_cvp_ssr_handler);
|
INIT_WORK(&core->ssr_work, msm_cvp_ssr_handler);
|
||||||
init_cycle_info(&core->dyn_clk);
|
init_cycle_info(&core->dyn_clk);
|
||||||
|
core->ssr_count = 0;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@@ -1889,7 +1889,7 @@ static int iris_hfi_core_release(void *dev)
|
|||||||
__func__, rc);
|
__func__, rc);
|
||||||
} else {
|
} else {
|
||||||
dprintk(CVP_PWR,
|
dprintk(CVP_PWR,
|
||||||
"%s: Succeed mmrm_client_deregister for mmrm_cvp:%p, type:%d, uid:%ld\n",
|
"%s: Succeed mmrm_client_deregister for mmrm_cvp:%pK, type:%d, uid:%ld\n",
|
||||||
__func__, device->mmrm_cvp, device->mmrm_cvp->client_type,
|
__func__, device->mmrm_cvp, device->mmrm_cvp->client_type,
|
||||||
device->mmrm_cvp->client_uid);
|
device->mmrm_cvp->client_uid);
|
||||||
device->mmrm_cvp = NULL;
|
device->mmrm_cvp = NULL;
|
||||||
@@ -2736,7 +2736,7 @@ static int __response_handler(struct iris_hfi_device *device)
|
|||||||
|
|
||||||
if (!raw_packet || !packets) {
|
if (!raw_packet || !packets) {
|
||||||
dprintk(CVP_ERR,
|
dprintk(CVP_ERR,
|
||||||
"%s: Invalid args : Res packet = %p, Raw packet = %p\n",
|
"%s: Invalid args : Res pkt = %pK, Raw pkt = %pK\n",
|
||||||
__func__, packets, raw_packet);
|
__func__, packets, raw_packet);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -4226,9 +4226,6 @@ static int iris_hfi_get_core_capabilities(void *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 cvp_arp_test_regs[16];
|
|
||||||
static u32 cvp_dma_test_regs[512];
|
|
||||||
|
|
||||||
static const char * const mid_names[16] = {
|
static const char * const mid_names[16] = {
|
||||||
"CVP_FW",
|
"CVP_FW",
|
||||||
"ARP_DATA",
|
"ARP_DATA",
|
||||||
@@ -4258,63 +4255,108 @@ static void __print_reg_details(u32 val)
|
|||||||
dprintk(CVP_ERR, "Sub-client:%s, SID: %d\n", mid_names[mid], sid);
|
dprintk(CVP_ERR, "Sub-client:%s, SID: %d\n", mid_names[mid], sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __err_log(bool logging, u32 *data, const char *name, u32 val)
|
||||||
|
{
|
||||||
|
if (logging)
|
||||||
|
*data = val;
|
||||||
|
|
||||||
|
dprintk(CVP_ERR, "%s: %#x\n", name, val);
|
||||||
|
}
|
||||||
|
|
||||||
static void __noc_error_info_iris2(struct iris_hfi_device *device)
|
static void __noc_error_info_iris2(struct iris_hfi_device *device)
|
||||||
{
|
{
|
||||||
|
struct msm_cvp_core *core;
|
||||||
|
struct cvp_noc_log *noc_log;
|
||||||
u32 val = 0, regi, i;
|
u32 val = 0, regi, i;
|
||||||
|
bool log_required = false;
|
||||||
|
|
||||||
|
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
|
||||||
|
|
||||||
|
if (!core->ssr_count && core->resources.max_ssr_allowed > 1)
|
||||||
|
log_required = true;
|
||||||
|
|
||||||
|
noc_log = &core->log.noc_log;
|
||||||
|
|
||||||
val = __read_register(device, CVP_NOC_ERR_SWID_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_SWID_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_SWID_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_swid_low,
|
||||||
|
"CVP_NOC_ERL_MAIN_SWID_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_ERR_SWID_HIGH_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_SWID_HIGH_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_swid_high,
|
||||||
|
"CVP_NOC_ERL_MAIN_SWID_HIGH", val);
|
||||||
val = __read_register(device, CVP_NOC_ERR_MAINCTL_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_MAINCTL_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_mainctl_low,
|
||||||
|
"CVP_NOC_ERL_MAIN_MAINCTL_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_ERR_ERRVLD_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_ERRVLD_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_errvld_low,
|
||||||
|
"CVP_NOC_ERL_MAIN_ERRVLD_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_ERR_ERRCLR_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_ERRCLR_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_errclr_low,
|
||||||
|
"CVP_NOC_ERL_MAIN_ERRCLR_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_ERR_ERRLOG0_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_ERRLOG0_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_errlog0_low,
|
||||||
|
"CVP_NOC_ERL_MAIN_ERRLOG0_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_ERR_ERRLOG0_HIGH_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_ERRLOG0_HIGH_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_errlog0_high,
|
||||||
|
"CVP_NOC_ERL_MAIN_ERRLOG0_HIGH", val);
|
||||||
val = __read_register(device, CVP_NOC_ERR_ERRLOG1_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_ERRLOG1_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_errlog1_low,
|
||||||
|
"CVP_NOC_ERL_MAIN_ERRLOG1_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_ERR_ERRLOG1_HIGH_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_ERRLOG1_HIGH_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_errlog1_high,
|
||||||
|
"CVP_NOC_ERL_MAIN_ERRLOG1_HIGH", val);
|
||||||
val = __read_register(device, CVP_NOC_ERR_ERRLOG2_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_ERRLOG2_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_errlog2_low,
|
||||||
|
"CVP_NOC_ERL_MAIN_ERRLOG2_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_ERR_ERRLOG2_HIGH_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_ERRLOG2_HIGH_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_errlog2_high,
|
||||||
|
"CVP_NOC_ERL_MAIN_ERRLOG2_HIGH", val);
|
||||||
val = __read_register(device, CVP_NOC_ERR_ERRLOG3_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_ERRLOG3_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_errlog3_low,
|
||||||
|
"CVP_NOC_ERL_MAIN_ERRLOG3_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_ERR_ERRLOG3_HIGH_OFFS);
|
val = __read_register(device, CVP_NOC_ERR_ERRLOG3_HIGH_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val);
|
__err_log(log_required, &noc_log->err_ctrl_errlog3_high,
|
||||||
|
"CVP_NOC_ERL_MAIN_ERRLOG3_HIGH", val);
|
||||||
|
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC__CORE_ERL_MAIN_SWID_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_core_swid_low,
|
||||||
|
"CVP_NOC__CORE_ERL_MAIN_SWID_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_SWID_HIGH: %#x\n", val);
|
__err_log(log_required, &noc_log->err_core_swid_high,
|
||||||
|
"CVP_NOC_CORE_ERL_MAIN_SWID_HIGH", val);
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_core_mainctl_low,
|
||||||
|
"CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_core_errvld_low,
|
||||||
|
"CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_core_errclr_low,
|
||||||
|
"CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_core_errlog0_low,
|
||||||
|
"CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val);
|
__err_log(log_required, &noc_log->err_core_errlog0_high,
|
||||||
|
"CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH", val);
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_core_errlog1_low,
|
||||||
|
"CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val);
|
__err_log(log_required, &noc_log->err_core_errlog1_high,
|
||||||
|
"CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH", val);
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW: %#x\n", val);
|
__err_log(log_required, &noc_log->err_core_errlog2_low,
|
||||||
|
"CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW", val);
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val);
|
__err_log(log_required, &noc_log->err_core_errlog2_high,
|
||||||
|
"CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH", val);
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS);
|
||||||
|
__err_log(log_required, &noc_log->err_core_errlog3_low,
|
||||||
|
"CORE ERRLOG3_LOW, below details", val);
|
||||||
__print_reg_details(val);
|
__print_reg_details(val);
|
||||||
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS);
|
val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS);
|
||||||
dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val);
|
__err_log(log_required, &noc_log->err_core_errlog3_high,
|
||||||
|
"CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH", val);
|
||||||
#define CVP_SS_CLK_HALT 0x8
|
#define CVP_SS_CLK_HALT 0x8
|
||||||
#define CVP_SS_CLK_EN 0xC
|
#define CVP_SS_CLK_EN 0xC
|
||||||
#define CVP_SS_ARP_TEST_BUS_CONTROL 0x700
|
#define CVP_SS_ARP_TEST_BUS_CONTROL 0x700
|
||||||
@@ -4330,7 +4372,7 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device)
|
|||||||
regi = 0xC0000000 + i;
|
regi = 0xC0000000 + i;
|
||||||
__write_register(device, CVP_SS_ARP_TEST_BUS_CONTROL, regi);
|
__write_register(device, CVP_SS_ARP_TEST_BUS_CONTROL, regi);
|
||||||
val = __read_register(device, CVP_SS_ARP_TEST_BUS_REGISTER);
|
val = __read_register(device, CVP_SS_ARP_TEST_BUS_REGISTER);
|
||||||
cvp_arp_test_regs[i] = val;
|
noc_log->arp_test_bus[i] = val;
|
||||||
dprintk(CVP_ERR, "ARP_CTL:%x - %x\n", regi, val);
|
dprintk(CVP_ERR, "ARP_CTL:%x - %x\n", regi, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4338,7 +4380,7 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device)
|
|||||||
regi = 0x40000000 + i;
|
regi = 0x40000000 + i;
|
||||||
__write_register(device, CVP_DMA_TEST_BUS_CONTROL, regi);
|
__write_register(device, CVP_DMA_TEST_BUS_CONTROL, regi);
|
||||||
val = __read_register(device, CVP_DMA_TEST_BUS_REGISTER);
|
val = __read_register(device, CVP_DMA_TEST_BUS_REGISTER);
|
||||||
cvp_dma_test_regs[i] = val;
|
noc_log->dma_test_bus[i] = val;
|
||||||
dprintk(CVP_ERR, "DMA_CTL:%x - %x\n", regi, val);
|
dprintk(CVP_ERR, "DMA_CTL:%x - %x\n", regi, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -74,6 +74,51 @@ void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst,
|
|||||||
cbuf->smem->device_addr, cbuf->size);
|
cbuf->smem->device_addr, cbuf->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _log_smem(struct inst_snapshot *snapshot, struct msm_cvp_inst *inst,
|
||||||
|
struct msm_cvp_smem *smem, bool logging)
|
||||||
|
{
|
||||||
|
print_smem(CVP_ERR, "bufdump", inst, smem);
|
||||||
|
if (!logging || !snapshot)
|
||||||
|
return;
|
||||||
|
if (snapshot && snapshot->smem_index < MAX_ENTRIES) {
|
||||||
|
struct smem_data *s;
|
||||||
|
s = &snapshot->smem_log[snapshot->smem_index];
|
||||||
|
snapshot->smem_index++;
|
||||||
|
s->size = smem->size;
|
||||||
|
s->flags = smem->flags;
|
||||||
|
s->device_addr = smem->device_addr;
|
||||||
|
s->bitmap_index = smem->bitmap_index;
|
||||||
|
s->refcount = atomic_read(&smem->refcount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _log_buf(struct inst_snapshot *snapshot, enum smem_prop prop,
|
||||||
|
struct msm_cvp_inst *inst, struct cvp_internal_buf *cbuf,
|
||||||
|
bool logging)
|
||||||
|
{
|
||||||
|
struct cvp_buf_data *buf = NULL;
|
||||||
|
u32 index;
|
||||||
|
print_cvp_buffer(CVP_ERR, "bufdump", inst, cbuf);
|
||||||
|
if (!logging)
|
||||||
|
return;
|
||||||
|
if (snapshot) {
|
||||||
|
if (prop == SMEM_ADSP && snapshot->dsp_index < MAX_ENTRIES) {
|
||||||
|
index = snapshot->dsp_index;
|
||||||
|
buf = &snapshot->dsp_buf_log[index];
|
||||||
|
snapshot->dsp_index++;
|
||||||
|
} else if (prop == SMEM_PERSIST &&
|
||||||
|
snapshot->persist_index < MAX_ENTRIES) {
|
||||||
|
index = snapshot->persist_index;
|
||||||
|
buf = &snapshot->persist_buf_log[index];
|
||||||
|
snapshot->persist_index++;
|
||||||
|
}
|
||||||
|
if (buf) {
|
||||||
|
buf->device_addr = cbuf->smem->device_addr;
|
||||||
|
buf->size = cbuf->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void print_client_buffer(u32 tag, const char *str,
|
void print_client_buffer(u32 tag, const char *str,
|
||||||
struct msm_cvp_inst *inst, struct eva_kmd_buffer *cbuf)
|
struct msm_cvp_inst *inst, struct eva_kmd_buffer *cbuf)
|
||||||
{
|
{
|
||||||
@@ -863,11 +908,20 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst)
|
void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log)
|
||||||
{
|
{
|
||||||
struct cvp_internal_buf *buf;
|
struct cvp_internal_buf *buf;
|
||||||
|
struct msm_cvp_core *core;
|
||||||
|
struct inst_snapshot *snap = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
|
||||||
|
if (log && core->log.snapshot_index < 16) {
|
||||||
|
snap = &core->log.snapshot[core->log.snapshot_index];
|
||||||
|
snap->session = inst->session;
|
||||||
|
core->log.snapshot_index++;
|
||||||
|
}
|
||||||
|
|
||||||
if (!inst) {
|
if (!inst) {
|
||||||
dprintk(CVP_ERR, "%s - invalid param %pK\n",
|
dprintk(CVP_ERR, "%s - invalid param %pK\n",
|
||||||
__func__, inst);
|
__func__, inst);
|
||||||
@@ -882,20 +936,19 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst)
|
|||||||
dprintk(CVP_ERR, "dma cache:\n");
|
dprintk(CVP_ERR, "dma cache:\n");
|
||||||
if (inst->dma_cache.nr <= MAX_DMABUF_NUMS)
|
if (inst->dma_cache.nr <= MAX_DMABUF_NUMS)
|
||||||
for (i = 0; i < inst->dma_cache.nr; i++)
|
for (i = 0; i < inst->dma_cache.nr; i++)
|
||||||
print_smem(CVP_ERR, "bufdump", inst,
|
_log_smem(snap, inst, inst->dma_cache.entries[i], log);
|
||||||
inst->dma_cache.entries[i]);
|
|
||||||
mutex_unlock(&inst->dma_cache.lock);
|
mutex_unlock(&inst->dma_cache.lock);
|
||||||
|
|
||||||
mutex_lock(&inst->cvpdspbufs.lock);
|
mutex_lock(&inst->cvpdspbufs.lock);
|
||||||
dprintk(CVP_ERR, "dsp buffer list:\n");
|
dprintk(CVP_ERR, "dsp buffer list:\n");
|
||||||
list_for_each_entry(buf, &inst->cvpdspbufs.list, list)
|
list_for_each_entry(buf, &inst->cvpdspbufs.list, list)
|
||||||
print_cvp_buffer(CVP_ERR, "bufdump", inst, buf);
|
_log_buf(snap, SMEM_ADSP, inst, buf, log);
|
||||||
mutex_unlock(&inst->cvpdspbufs.lock);
|
mutex_unlock(&inst->cvpdspbufs.lock);
|
||||||
|
|
||||||
mutex_lock(&inst->persistbufs.lock);
|
mutex_lock(&inst->persistbufs.lock);
|
||||||
dprintk(CVP_ERR, "persist buffer list:\n");
|
dprintk(CVP_ERR, "persist buffer list:\n");
|
||||||
list_for_each_entry(buf, &inst->persistbufs.list, list)
|
list_for_each_entry(buf, &inst->persistbufs.list, list)
|
||||||
print_cvp_buffer(CVP_ERR, "bufdump", inst, buf);
|
_log_buf(snap, SMEM_PERSIST, inst, buf, log);
|
||||||
mutex_unlock(&inst->persistbufs.lock);
|
mutex_unlock(&inst->persistbufs.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -209,7 +209,7 @@ int msm_cvp_register_buffer(struct msm_cvp_inst *inst,
|
|||||||
int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst,
|
int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst,
|
||||||
struct eva_kmd_buffer *buf);
|
struct eva_kmd_buffer *buf);
|
||||||
int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst);
|
int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst);
|
||||||
void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst);
|
void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log);
|
||||||
int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst,
|
int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst,
|
||||||
struct cvp_internal_buf *buf,
|
struct cvp_internal_buf *buf,
|
||||||
u32 buffer_size,
|
u32 buffer_size,
|
||||||
|
@@ -670,7 +670,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!core->trigger_ssr)
|
if (!core->trigger_ssr)
|
||||||
msm_cvp_print_inst_bufs(inst);
|
msm_cvp_print_inst_bufs(inst, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle the hw error before core released to get full debug info */
|
/* handle the hw error before core released to get full debug info */
|
||||||
@@ -1036,7 +1036,6 @@ static int msm_comm_init_core(struct msm_cvp_inst *inst)
|
|||||||
goto fail_core_init;
|
goto fail_core_init;
|
||||||
}
|
}
|
||||||
core->state = CVP_CORE_INIT;
|
core->state = CVP_CORE_INIT;
|
||||||
core->smmu_fault_handled = false;
|
|
||||||
core->trigger_ssr = false;
|
core->trigger_ssr = false;
|
||||||
|
|
||||||
core_already_inited:
|
core_already_inited:
|
||||||
@@ -1304,6 +1303,7 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
|
|||||||
int msm_cvp_noc_error_info(struct msm_cvp_core *core)
|
int msm_cvp_noc_error_info(struct msm_cvp_core *core)
|
||||||
{
|
{
|
||||||
struct cvp_hfi_device *hdev;
|
struct cvp_hfi_device *hdev;
|
||||||
|
static u32 last_fault_count = 0;
|
||||||
|
|
||||||
if (!core || !core->device) {
|
if (!core || !core->device) {
|
||||||
dprintk(CVP_WARN, "%s: Invalid parameters: %pK\n",
|
dprintk(CVP_WARN, "%s: Invalid parameters: %pK\n",
|
||||||
@@ -1311,13 +1311,20 @@ int msm_cvp_noc_error_info(struct msm_cvp_core *core)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!core->smmu_fault_handled)
|
if (!core->smmu_fault_count ||
|
||||||
|
core->smmu_fault_count == last_fault_count)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
last_fault_count = core->smmu_fault_count;
|
||||||
|
core->ssr_count++;
|
||||||
|
dprintk(CVP_ERR, "cvp ssr count %d %d\n", core->ssr_count,
|
||||||
|
core->resources.max_ssr_allowed);
|
||||||
hdev = core->device;
|
hdev = core->device;
|
||||||
call_hfi_op(hdev, noc_error_info, hdev->hfi_device_data);
|
call_hfi_op(hdev, noc_error_info, hdev->hfi_device_data);
|
||||||
|
|
||||||
BUG_ON(!core->resources.non_fatal_pagefaults);
|
if (core->ssr_count >= core->resources.max_ssr_allowed)
|
||||||
|
BUG_ON(!core->resources.non_fatal_pagefaults);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -358,6 +358,33 @@ static int _dsp_dbg_get(void *data, u64 *val)
|
|||||||
|
|
||||||
DEFINE_DEBUGFS_ATTRIBUTE(dsp_debug_fops, _dsp_dbg_get, _dsp_dbg_set, "%llu\n");
|
DEFINE_DEBUGFS_ATTRIBUTE(dsp_debug_fops, _dsp_dbg_get, _dsp_dbg_set, "%llu\n");
|
||||||
|
|
||||||
|
static int _max_ssr_set(void *data, u64 val)
|
||||||
|
{
|
||||||
|
struct msm_cvp_core *core;
|
||||||
|
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
|
||||||
|
if (core) {
|
||||||
|
if (val < 1) {
|
||||||
|
dprintk(CVP_WARN,
|
||||||
|
"Invalid max_ssr_allowed value %llx\n", val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
core->resources.max_ssr_allowed = (unsigned int)val;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _max_ssr_get(void *data, u64 *val)
|
||||||
|
{
|
||||||
|
struct msm_cvp_core *core;
|
||||||
|
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
|
||||||
|
if (core)
|
||||||
|
*val = core->resources.max_ssr_allowed;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_DEBUGFS_ATTRIBUTE(max_ssr_fops, _max_ssr_get, _max_ssr_set, "%llu\n");
|
||||||
|
|
||||||
struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core,
|
struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core,
|
||||||
struct dentry *parent)
|
struct dentry *parent)
|
||||||
@@ -397,6 +424,12 @@ struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core,
|
|||||||
goto failed_create_dir;
|
goto failed_create_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!debugfs_create_file("max_ssr_allowed", 0644, dir,
|
||||||
|
NULL, &max_ssr_fops)) {
|
||||||
|
dprintk(CVP_ERR, "debugfs_create: max_ssr_allowed fail\n");
|
||||||
|
goto failed_create_dir;
|
||||||
|
}
|
||||||
|
|
||||||
failed_create_dir:
|
failed_create_dir:
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
@@ -512,7 +545,7 @@ struct dentry *msm_cvp_debugfs_init_inst(struct msm_cvp_inst *inst,
|
|||||||
dprintk(CVP_ERR, "Invalid params, inst: %pK\n", inst);
|
dprintk(CVP_ERR, "Invalid params, inst: %pK\n", inst);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst);
|
snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst);
|
||||||
|
|
||||||
idata = kzalloc(sizeof(*idata), GFP_KERNEL);
|
idata = kzalloc(sizeof(*idata), GFP_KERNEL);
|
||||||
if (!idata) {
|
if (!idata) {
|
||||||
|
@@ -270,6 +270,68 @@ struct cvp_session_event {
|
|||||||
wait_queue_head_t wq;
|
wait_queue_head_t wq;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_ENTRIES 64
|
||||||
|
|
||||||
|
struct smem_data {
|
||||||
|
u32 size;
|
||||||
|
u32 flags;
|
||||||
|
u32 device_addr;
|
||||||
|
u32 bitmap_index;
|
||||||
|
u32 refcount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cvp_buf_data {
|
||||||
|
u32 device_addr;
|
||||||
|
u32 size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct inst_snapshot {
|
||||||
|
void *session;
|
||||||
|
u32 smem_index;
|
||||||
|
u32 dsp_index;
|
||||||
|
u32 persist_index;
|
||||||
|
struct smem_data smem_log[MAX_ENTRIES];
|
||||||
|
struct cvp_buf_data dsp_buf_log[MAX_ENTRIES];
|
||||||
|
struct cvp_buf_data persist_buf_log[MAX_ENTRIES];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cvp_noc_log {
|
||||||
|
u32 err_ctrl_swid_low;
|
||||||
|
u32 err_ctrl_swid_high;
|
||||||
|
u32 err_ctrl_mainctl_low;
|
||||||
|
u32 err_ctrl_errvld_low;
|
||||||
|
u32 err_ctrl_errclr_low;
|
||||||
|
u32 err_ctrl_errlog0_low;
|
||||||
|
u32 err_ctrl_errlog0_high;
|
||||||
|
u32 err_ctrl_errlog1_low;
|
||||||
|
u32 err_ctrl_errlog1_high;
|
||||||
|
u32 err_ctrl_errlog2_low;
|
||||||
|
u32 err_ctrl_errlog2_high;
|
||||||
|
u32 err_ctrl_errlog3_low;
|
||||||
|
u32 err_ctrl_errlog3_high;
|
||||||
|
u32 err_core_swid_low;
|
||||||
|
u32 err_core_swid_high;
|
||||||
|
u32 err_core_mainctl_low;
|
||||||
|
u32 err_core_errvld_low;
|
||||||
|
u32 err_core_errclr_low;
|
||||||
|
u32 err_core_errlog0_low;
|
||||||
|
u32 err_core_errlog0_high;
|
||||||
|
u32 err_core_errlog1_low;
|
||||||
|
u32 err_core_errlog1_high;
|
||||||
|
u32 err_core_errlog2_low;
|
||||||
|
u32 err_core_errlog2_high;
|
||||||
|
u32 err_core_errlog3_low;
|
||||||
|
u32 err_core_errlog3_high;
|
||||||
|
u32 arp_test_bus[16];
|
||||||
|
u32 dma_test_bus[512];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cvp_debug_log {
|
||||||
|
struct cvp_noc_log noc_log;
|
||||||
|
u32 snapshot_index;
|
||||||
|
struct inst_snapshot snapshot[16];
|
||||||
|
};
|
||||||
|
|
||||||
struct msm_cvp_core {
|
struct msm_cvp_core {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
@@ -291,12 +353,14 @@ struct msm_cvp_core {
|
|||||||
struct delayed_work fw_unload_work;
|
struct delayed_work fw_unload_work;
|
||||||
struct work_struct ssr_work;
|
struct work_struct ssr_work;
|
||||||
enum hal_ssr_trigger_type ssr_type;
|
enum hal_ssr_trigger_type ssr_type;
|
||||||
bool smmu_fault_handled;
|
u32 smmu_fault_count;
|
||||||
u32 last_fault_addr;
|
u32 last_fault_addr;
|
||||||
|
u32 ssr_count;
|
||||||
bool trigger_ssr;
|
bool trigger_ssr;
|
||||||
unsigned long curr_freq;
|
unsigned long curr_freq;
|
||||||
struct cvp_cycle_info dyn_clk;
|
struct cvp_cycle_info dyn_clk;
|
||||||
atomic64_t kernel_trans_id;
|
atomic64_t kernel_trans_id;
|
||||||
|
struct cvp_debug_log log;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msm_cvp_inst {
|
struct msm_cvp_inst {
|
||||||
|
@@ -72,12 +72,9 @@ static struct msm_cvp_common_data sm8450_common_data[] = {
|
|||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.key = "qcom,max-hw-load",
|
.key = "qcom,max-ssr-allowed",
|
||||||
.value = 3916800, /*
|
.value = 1, /*
|
||||||
* 1920x1088/256 MBs@480fps. It is less
|
* Maxinum number of SSR before BUG_ON
|
||||||
* any other usecases (ex:
|
|
||||||
* 3840x2160@120fps, 4096x2160@96ps,
|
|
||||||
* 7680x4320@30fps)
|
|
||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -771,8 +771,8 @@ int cvp_read_platform_resources_from_drv_data(
|
|||||||
res->dsp_enabled = find_key_value(platform_data,
|
res->dsp_enabled = find_key_value(platform_data,
|
||||||
"qcom,dsp-enabled");
|
"qcom,dsp-enabled");
|
||||||
|
|
||||||
res->max_load = find_key_value(platform_data,
|
res->max_ssr_allowed = find_key_value(platform_data,
|
||||||
"qcom,max-hw-load");
|
"qcom,max-ssr-allowed");
|
||||||
|
|
||||||
res->sw_power_collapsible = find_key_value(platform_data,
|
res->sw_power_collapsible = find_key_value(platform_data,
|
||||||
"qcom,sw-power-collapse");
|
"qcom,sw-power-collapse");
|
||||||
@@ -952,7 +952,7 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain,
|
|||||||
{
|
{
|
||||||
struct msm_cvp_core *core = token;
|
struct msm_cvp_core *core = token;
|
||||||
struct msm_cvp_inst *inst;
|
struct msm_cvp_inst *inst;
|
||||||
u32 *pfaddr = &core->last_fault_addr;
|
bool log = false;
|
||||||
|
|
||||||
if (!domain || !core) {
|
if (!domain || !core) {
|
||||||
dprintk(CVP_ERR, "%s - invalid param %pK %pK\n",
|
dprintk(CVP_ERR, "%s - invalid param %pK %pK\n",
|
||||||
@@ -960,22 +960,15 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (core->smmu_fault_handled) {
|
core->smmu_fault_count++;
|
||||||
if (core->resources.non_fatal_pagefaults) {
|
dprintk(CVP_ERR, "%s - faulting address: %lx, %d\n",
|
||||||
WARN_ONCE(1, "%s: non-fatal pagefault address: %lx\n",
|
__func__, iova, core->smmu_fault_count);
|
||||||
__func__, iova);
|
|
||||||
*pfaddr = (*pfaddr == 0) ? iova : (*pfaddr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintk(CVP_ERR, "%s - faulting address: %lx\n", __func__, iova);
|
|
||||||
|
|
||||||
mutex_lock(&core->lock);
|
mutex_lock(&core->lock);
|
||||||
|
log = (core->log.snapshot_index > 0)? false : true;
|
||||||
list_for_each_entry(inst, &core->instances, list) {
|
list_for_each_entry(inst, &core->instances, list) {
|
||||||
msm_cvp_print_inst_bufs(inst);
|
msm_cvp_print_inst_bufs(inst, log);
|
||||||
}
|
}
|
||||||
core->smmu_fault_handled = true;
|
|
||||||
mutex_unlock(&core->lock);
|
mutex_unlock(&core->lock);
|
||||||
/*
|
/*
|
||||||
* Return -EINVAL to elicit the default behaviour of smmu driver.
|
* Return -EINVAL to elicit the default behaviour of smmu driver.
|
||||||
|
@@ -152,7 +152,7 @@ struct msm_cvp_platform_resources {
|
|||||||
struct subcache_set subcache_set;
|
struct subcache_set subcache_set;
|
||||||
struct reg_set reg_set;
|
struct reg_set reg_set;
|
||||||
struct addr_set qdss_addr_set;
|
struct addr_set qdss_addr_set;
|
||||||
uint32_t max_load;
|
uint32_t max_ssr_allowed;
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
struct regulator_set regulator_set;
|
struct regulator_set regulator_set;
|
||||||
struct clock_set clock_set;
|
struct clock_set clock_set;
|
||||||
|
Reference in New Issue
Block a user