msm: camera: jpeg: Add mechanism to verify IRQ lines

IRQ line verification can now be triggerred from JPEG HW manager by
writing to a debugfs file as follows:
    echo 1 > /d/camera/jpeg/test_irq_line

IRQ line verification can also be done at probe if
CONFIG_CAM_TEST_IRQ_LINE_AT_PROBE is set to true during compilation.
Both debugfs and probe-time verifications are only active if
CONFIG_CAM_TEST_IRQ_LINE is set to true during compilation.

CRs-Fixed: 3071027
Change-Id: Ib24022a12e3aa3ac529c7bc925fd4df1f2a96310
Signed-off-by: Anand Ravi <quic_ananravi@quicinc.com>
This commit is contained in:
Anand Ravi
2021-12-20 12:43:44 -08:00
parent af9072bcc6
commit 4355ad8cb4
7 changed files with 158 additions and 8 deletions

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/uaccess.h>
@@ -43,6 +44,8 @@
#define CAM_JPEG_PARAM_CMD_BUFF_IDX 2
#define CAM_JPEG_THUBMNAIL_SIZE_CMD_BUFF_IDX 3
#define CAM_JPEG_DEV_TYPE(type) ((type) == CAM_JPEG_DEV_TYPE_ENC ? "ENC" : "DMA")
static struct cam_jpeg_hw_mgr g_jpeg_hw_mgr;
static int32_t cam_jpeg_hw_mgr_sched_bottom_half(uint32_t irq_status,
@@ -324,7 +327,7 @@ static int cam_jpeg_process_next_hw_update(void *priv, void *data,
}
CAM_TRACE(CAM_JPEG, "Start JPEG %s ctx %lld Req %llu Pass %d",
(dev_type == CAM_JPEG_DEV_TYPE_ENC) ? "ENC" : "DMA",
CAM_JPEG_DEV_TYPE(dev_type),
(uint64_t) ctx_data,
config_args->request_id, pass_num);
@@ -2122,6 +2125,69 @@ static int cam_jpeg_get_bug_on_misr(void *data, u64 *val)
DEFINE_DEBUGFS_ATTRIBUTE(bug_on_misr_mismatch, cam_jpeg_get_bug_on_misr,
cam_jpeg_set_bug_on_misr, "%08llu");
#ifdef CONFIG_CAM_TEST_IRQ_LINE
static int cam_jpeg_test_irq_line(void)
{
struct cam_hw_intf *hw_intf;
int rc = -EINVAL, i, j;
for (i = 0; i < CAM_JPEG_DEV_PER_TYPE_MAX; i++) {
for (j = 0; j < CAM_JPEG_DEV_MAX; j++) {
hw_intf = g_jpeg_hw_mgr.devices[j][i];
if (hw_intf && hw_intf->hw_ops.test_irq_line) {
rc = hw_intf->hw_ops.test_irq_line(hw_intf->hw_priv);
if (rc)
CAM_ERR(CAM_JPEG,
"failed to verify IRQ line for JPEG-%s[%d]",
CAM_JPEG_DEV_TYPE(j), i);
}
}
}
return rc;
}
#else
static int cam_jpeg_test_irq_line(void)
{
CAM_ERR(CAM_JPEG, "IRQ line verification disabled!");
return -EPERM;
}
#endif
#if (defined(CONFIG_CAM_TEST_IRQ_LINE) && defined(CONFIG_CAM_TEST_IRQ_LINE_AT_PROBE))
static int cam_jpeg_test_irq_line_at_probe(void)
{
return cam_jpeg_test_irq_line();
}
#else
static int cam_jpeg_test_irq_line_at_probe(void)
{
return 0;
}
#endif
static int cam_jpeg_set_irq_line_test(void *data, u64 val)
{
cam_jpeg_test_irq_line();
return 0;
}
static int cam_jpeg_get_irq_line_test(void *data, u64 *val)
{
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(cam_jpeg_irq_line_test, cam_jpeg_get_irq_line_test,
cam_jpeg_set_irq_line_test, "%08llu");
static int cam_jpeg_mgr_create_debugfs_entry(void)
{
int rc = 0;
@@ -2144,6 +2210,9 @@ static int cam_jpeg_mgr_create_debugfs_entry(void)
debugfs_create_file("bug_on_misr_mismatch", 0644, g_jpeg_hw_mgr.dentry,
NULL, &bug_on_misr_mismatch);
debugfs_create_file("test_irq_line", 0644, g_jpeg_hw_mgr.dentry,
NULL, &cam_jpeg_irq_line_test);
return rc;
}
@@ -2236,10 +2305,10 @@ int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
*iommu_hdl = g_jpeg_hw_mgr.iommu_hdl;
cam_common_register_mini_dump_cb(cam_jpeg_hw_mgr_mini_dump_cb, "CAM_JPEG");
cam_jpeg_mgr_create_debugfs_entry();
cam_jpeg_test_irq_line_at_probe();
rc = cam_jpeg_mgr_create_debugfs_entry();
if (!rc)
return rc;
return 0;
cdm_iommu_failed:
cam_smmu_destroy_handle(g_jpeg_hw_mgr.iommu_hdl);

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/of.h>
@@ -200,6 +200,8 @@ irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data)
if (core_info->core_state == CAM_JPEG_DMA_CORE_RESETTING) {
core_info->core_state = CAM_JPEG_DMA_CORE_READY;
complete(&jpeg_dma_dev->hw_complete);
CAM_DBG(CAM_JPEG, "JPEG DMA %s reset done",
jpeg_dma_dev->soc_info.dev_name);
} else if (core_info->core_state == CAM_JPEG_DMA_CORE_RESETTING_ON_DONE) {
if (core_info->irq_cb.jpeg_hw_mgr_cb) {
core_info->irq_cb.jpeg_hw_mgr_cb(irq_status, 1,
@@ -241,6 +243,7 @@ int cam_jpeg_dma_reset_hw(void *data,
struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
void __iomem *mem_base;
unsigned long rem_jiffies;
int rc = 0;
if (!jpeg_dma_dev) {
CAM_ERR(CAM_JPEG, "Invalid args");
@@ -282,9 +285,43 @@ int cam_jpeg_dma_reset_hw(void *data,
if (!rem_jiffies) {
CAM_ERR(CAM_JPEG, "dma error Reset Timeout");
core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
rc = -ETIMEDOUT;
}
mutex_unlock(&core_info->core_mutex);
return rc;
}
int cam_jpeg_dma_test_irq_line(void *data)
{
struct cam_hw_info *jpeg_dma_dev = data;
struct cam_jpeg_dma_device_core_info *core_info = NULL;
int rc;
if (!data) {
CAM_ERR(CAM_JPEG, "invalid args");
return -EINVAL;
}
core_info = jpeg_dma_dev->core_info;
rc = cam_jpeg_dma_init_hw(data, NULL, 0);
if (rc) {
CAM_ERR(CAM_JPEG, "failed to init hw (rc=%d)", rc);
return rc;
}
rc = cam_jpeg_dma_reset_hw(data, NULL, 0);
if (rc)
CAM_ERR(CAM_JPEG, "failed to trigger reset irq (rc=%d)", rc);
else
CAM_INFO(CAM_JPEG, "verified JPEG DMA (%s) IRQ line",
jpeg_dma_dev->soc_info.dev_name);
rc = cam_jpeg_dma_deinit_hw(data, NULL, 0);
if (rc)
CAM_ERR(CAM_JPEG, "failed to de-init hw (rc=%d)", rc);
return 0;
}

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef CAM_JPEG_DMA_CORE_H
@@ -118,6 +119,7 @@ int cam_jpeg_dma_reset_hw(void *device_priv,
void *reset_hw_args, uint32_t arg_size);
int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
void *cmd_args, uint32_t arg_size);
int cam_jpeg_dma_test_irq_line(void *data);
irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data);
/**

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@@ -97,6 +97,7 @@ static int cam_jpeg_dma_component_bind(struct device *dev,
jpeg_dma_dev_intf->hw_ops.stop = cam_jpeg_dma_stop_hw;
jpeg_dma_dev_intf->hw_ops.reset = cam_jpeg_dma_reset_hw;
jpeg_dma_dev_intf->hw_ops.process_cmd = cam_jpeg_dma_process_cmd;
jpeg_dma_dev_intf->hw_ops.test_irq_line = cam_jpeg_dma_test_irq_line;
jpeg_dma_dev_intf->hw_type = CAM_JPEG_DEV_DMA;
platform_set_drvdata(pdev, jpeg_dma_dev_intf);

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/of.h>
@@ -227,6 +227,8 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data)
if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) {
core_info->core_state = CAM_JPEG_ENC_CORE_READY;
complete(&jpeg_enc_dev->hw_complete);
CAM_DBG(CAM_JPEG, "JPEG ENC (%s) reset done",
jpeg_enc_dev->soc_info.dev_name);
} else {
CAM_ERR(CAM_JPEG, "unexpected reset irq");
}
@@ -274,6 +276,7 @@ int cam_jpeg_enc_reset_hw(void *data,
void __iomem *mem_base;
unsigned long rem_jiffies;
unsigned long flags;
int rc = 0;
if (!jpeg_enc_dev) {
CAM_ERR(CAM_JPEG, "Invalid args");
@@ -320,9 +323,43 @@ int cam_jpeg_enc_reset_hw(void *data,
if (!rem_jiffies) {
CAM_ERR(CAM_JPEG, "error Reset Timeout");
core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
rc = -ETIMEDOUT;
}
mutex_unlock(&core_info->core_mutex);
return rc;
}
int cam_jpeg_enc_test_irq_line(void *data)
{
struct cam_hw_info *jpeg_enc_dev = data;
struct cam_jpeg_enc_device_core_info *core_info = NULL;
int rc;
if (!data) {
CAM_ERR(CAM_JPEG, "invalid args");
return -EINVAL;
}
core_info = jpeg_enc_dev->core_info;
rc = cam_jpeg_enc_init_hw(data, NULL, 0);
if (rc) {
CAM_ERR(CAM_JPEG, "failed to init hw (rc=%d)", rc);
return rc;
}
rc = cam_jpeg_enc_reset_hw(data, NULL, 0);
if (rc)
CAM_ERR(CAM_JPEG, "failed to trigger reset irq (rc=%d)", rc);
else
CAM_INFO(CAM_JPEG, "verified JPEG DMA (%s) IRQ line",
jpeg_enc_dev->soc_info.dev_name);
rc = cam_jpeg_enc_deinit_hw(data, NULL, 0);
if (rc)
CAM_ERR(CAM_JPEG, "failed to de-init hw (rc=%d)", rc);
return 0;
}

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef CAM_JPEG_ENC_CORE_H
@@ -117,6 +118,8 @@ int cam_jpeg_enc_reset_hw(void *device_priv,
void *reset_hw_args, uint32_t arg_size);
int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type,
void *cmd_args, uint32_t arg_size);
int cam_jpeg_enc_test_irq_line(void *data);
irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data);
/**

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@@ -98,6 +98,7 @@ static int cam_jpeg_enc_component_bind(struct device *dev,
jpeg_enc_dev_intf->hw_ops.stop = cam_jpeg_enc_stop_hw;
jpeg_enc_dev_intf->hw_ops.reset = cam_jpeg_enc_reset_hw;
jpeg_enc_dev_intf->hw_ops.process_cmd = cam_jpeg_enc_process_cmd;
jpeg_enc_dev_intf->hw_ops.test_irq_line = cam_jpeg_enc_test_irq_line;
jpeg_enc_dev_intf->hw_type = CAM_JPEG_DEV_ENC;
platform_set_drvdata(pdev, jpeg_enc_dev_intf);