msm: camera: common: Add Minidump changes for NRT devices

Based on targets, in case of device crash, in place
of complete memory dump, mini dump can be extracted.
This commit adds changes in context utils for NRT devices
and in ICP, JPEG drivers.

CRs-Fixed: 2993116
Change-Id: I7c4af2cdf44713f741d3d772316080124e8a9a7f
Signed-off-by: Gaurav Jindal <gjindal@codeaurora.org>
Bu işleme şunda yer alıyor:
Gaurav Jindal
2021-05-31 20:39:26 +05:30
işlemeyi yapan: Gerrit - the friendly Code Review server
ebeveyn d266ac8813
işleme 2f5933b075
23 değiştirilmiş dosya ile 889 ekleme ve 7 silme

Dosyayı Görüntüle

@@ -56,6 +56,24 @@ static int cam_jpeg_context_dump_active_request(void *data,
return rc;
}
static int cam_jpeg_context_mini_dump(void *priv, void *args)
{
int rc;
struct cam_context *ctx;
if (!priv || args) {
CAM_ERR(CAM_ICP, "Invalid param priv %pK args %pK", priv, args);
return -EINVAL;
}
ctx = (struct cam_context *)priv;
rc = cam_context_mini_dump(ctx, args);
if (rc)
CAM_ERR(CAM_JPEG, "Mini Dump failed %d", rc);
return rc;
}
static int __cam_jpeg_ctx_acquire_dev_in_available(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd)
{
@@ -151,6 +169,7 @@ static struct cam_ctx_ops
},
.crm_ops = { },
.irq_ops = NULL,
.mini_dump_ops = cam_jpeg_context_mini_dump,
},
/* Acquired */
{
@@ -164,6 +183,7 @@ static struct cam_ctx_ops
.crm_ops = { },
.irq_ops = __cam_jpeg_ctx_handle_buf_done_in_acquired,
.pagefault_ops = cam_jpeg_context_dump_active_request,
.mini_dump_ops = cam_jpeg_context_mini_dump,
},
/* Ready */
{

Dosyayı Görüntüle

@@ -38,6 +38,19 @@ static void cam_jpeg_dev_iommu_fault_handler(
cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
}
static void cam_jpeg_dev_mini_dump_cb(void *priv, void *args)
{
struct cam_context *ctx = NULL;
if (!priv || !args) {
CAM_ERR(CAM_JPEG, "Invalid param priv %pK %pK args", priv, args);
return;
}
ctx = (struct cam_context *)priv;
cam_context_mini_dump_from_hw(ctx, args);
}
static const struct of_device_id cam_jpeg_dt_match[] = {
{
.compatible = "qcom,cam-jpeg"
@@ -123,7 +136,8 @@ static int cam_jpeg_dev_component_bind(struct device *dev,
node = (struct cam_node *)g_jpeg_dev.sd.token;
rc = cam_jpeg_hw_mgr_init(pdev->dev.of_node,
(uint64_t *)&hw_mgr_intf, &iommu_hdl);
(uint64_t *)&hw_mgr_intf, &iommu_hdl,
cam_jpeg_dev_mini_dump_cb);
if (rc) {
CAM_ERR(CAM_JPEG, "Can not initialize JPEG HWmanager %d", rc);
goto unregister;

Dosyayı Görüntüle

@@ -1421,7 +1421,7 @@ static int cam_jpeg_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
mutex_unlock(&ctx_data->ctx_mutex);
hw_mgr->ctx_data[ctx_id].ctxt_event_cb = args->event_cb;
hw_mgr->ctx_data[ctx_id].mini_dump_cb = args->mini_dump_cb;
if (copy_to_user((void __user *)args->acquire_info,
&jpeg_dev_acquire_info,
@@ -1971,8 +1971,83 @@ static int cam_jpeg_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
return rc;
}
static unsigned long cam_jpeg_hw_mgr_mini_dump_cb(void *dst, unsigned long len)
{
struct cam_jpeg_hw_mini_dump_req *md_req;
struct cam_jpeg_hw_mgr_mini_dump *md;
struct cam_jpeg_hw_ctx_mini_dump *ctx_md;
struct cam_jpeg_hw_ctx_data *ctx;
struct cam_jpeg_hw_mgr *hw_mgr;
struct cam_jpeg_hw_cfg_req *req;
struct cam_hw_mini_dump_args hw_dump_args;
uint32_t dev_type;
uint32_t i = 0;
unsigned long dumped_len = 0;
unsigned long remain_len = len;
if (!dst || len < sizeof(*md)) {
CAM_ERR(CAM_JPEG, "Invalid params dst %pk len %lu", dst, len);
return 0;
}
md = (struct cam_jpeg_hw_mgr_mini_dump *)dst;
md->num_context = 0;
hw_mgr = &g_jpeg_hw_mgr;
for (i = 0; i < CAM_JPEG_RES_TYPE_MAX; i++) {
if (hw_mgr->devices[i][0]->hw_ops.process_cmd) {
hw_mgr->devices[i][0]->hw_ops.process_cmd(
hw_mgr->devices[i][0]->hw_priv,
CAM_JPEG_CMD_MINI_DUMP,
&md->core[i],
sizeof(struct cam_jpeg_mini_dump_core_info));
}
}
dumped_len += sizeof(*md);
remain_len = len - dumped_len;
for (i = 0; i < CAM_JPEG_CTX_MAX; i++) {
ctx = &hw_mgr->ctx_data[i];
if (!ctx->in_use)
continue;
if (remain_len < sizeof(*ctx_md))
goto end;
md->num_context++;
ctx_md = (struct cam_jpeg_hw_ctx_mini_dump *)
((uint8_t *)dst + dumped_len);
md->ctx[i] = ctx_md;
ctx_md->in_use = ctx->in_use;
memcpy(&ctx_md->acquire_info, &ctx->jpeg_dev_acquire_info,
sizeof(struct cam_jpeg_acquire_dev_info));
dev_type = ctx->jpeg_dev_acquire_info.dev_type;
req = hw_mgr->dev_hw_cfg_args[dev_type][0];
if (req) {
md_req = &md->cfg_req[dev_type];
memcpy(&md_req->submit_timestamp, &req->submit_timestamp,
sizeof(ktime_t));
md_req->req_id = req->req_id;
md_req->dev_type = req->dev_type;
md_req->num_hw_entry_processed = req->num_hw_entry_processed;
}
hw_dump_args.len = remain_len;
hw_dump_args.bytes_written = 0;
hw_dump_args.start_addr = (void *)((uint8_t *)dst + dumped_len);
hw_mgr->mini_dump_cb(ctx->context_priv, &hw_dump_args);
if (dumped_len + hw_dump_args.bytes_written >= len)
goto end;
dumped_len += hw_dump_args.bytes_written;
remain_len = len - dumped_len;
}
end:
return dumped_len;
}
int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
int *iommu_hdl)
int *iommu_hdl, cam_jpeg_mini_dump_cb mini_dump_cb)
{
int i, rc;
uint32_t num_dev;
@@ -2048,6 +2123,8 @@ int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
g_jpeg_hw_mgr.jpeg_caps.dev_ver[CAM_JPEG_DEV_DMA].hw_ver.incr = 0;
g_jpeg_hw_mgr.jpeg_caps.dev_ver[CAM_JPEG_DEV_DMA].hw_ver.reserved = 0;
g_jpeg_hw_mgr.mini_dump_cb = mini_dump_cb;
rc = cam_jpeg_setup_workqs();
if (rc) {
CAM_ERR(CAM_JPEG, "setup work qs failed %d", rc);
@@ -2057,6 +2134,8 @@ int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
if (iommu_hdl)
*iommu_hdl = g_jpeg_hw_mgr.iommu_hdl;
cam_common_register_mini_dump_cb(cam_jpeg_hw_mgr_mini_dump_cb, "CAM_JPEG");
return rc;
cdm_iommu_failed:

Dosyayı Görüntüle

@@ -103,6 +103,7 @@ struct cam_jpeg_hw_cfg_req {
* @in_use: Flag for context usage
* @wait_complete: Completion info
* @cdm_cmd: Cdm cmd submitted for that context.
* @mini_dump_cb: Mini dump cb
*/
struct cam_jpeg_hw_ctx_data {
void *context_priv;
@@ -112,6 +113,7 @@ struct cam_jpeg_hw_ctx_data {
bool in_use;
struct completion wait_complete;
struct cam_cdm_bl_request *cdm_cmd;
cam_ctx_mini_dump_cb_func mini_dump_cb;
};
/**
@@ -138,6 +140,7 @@ struct cam_jpeg_hw_ctx_data {
* @free_req_list: Free nodes for above list
* @req_list: Nodes of hw update list
* @num_pid: num of pids supported in the device
* @mini_dump_cb: Mini dump cb
*/
struct cam_jpeg_hw_mgr {
struct mutex hw_mgr_mutex;
@@ -167,6 +170,49 @@ struct cam_jpeg_hw_mgr {
struct list_head free_req_list;
struct cam_jpeg_hw_cfg_req req_list[CAM_JPEG_HW_CFG_Q_MAX];
uint32_t num_pid[CAM_JPEG_DEV_TYPE_MAX];
cam_jpeg_mini_dump_cb mini_dump_cb;
};
/**
* struct cam_jpeg_hw_mini_dump_req
*
* @submit_timestamp: Time stamp of request submit
* @req_id: Request Id
* @dev_type: Dev type
* @num_hw_entry_processed: Num of hw entry processed
*/
struct cam_jpeg_hw_mini_dump_req {
ktime_t submit_timestamp;
uintptr_t req_id;
uint32_t dev_type;
uint32_t num_hw_entry_processed;
};
/**
* struct cam_jpeg_hw_ctx_mini_dump
*
* @acquire_info: Acquire info
* @hw_ctx: hw context info
* @in_use: flag to indicate if in use
*/
struct cam_jpeg_hw_ctx_mini_dump {
struct cam_jpeg_acquire_dev_info acquire_info;
struct cam_hw_mini_dump_info hw_ctx;
bool in_use;
};
/**
* struct cam_jpeg_hw_mgr_mini_dump
*
* @ctx: Context info array
* @cfg_req: Cfg req
* @core: core info
* @num_context: Num of context
*/
struct cam_jpeg_hw_mgr_mini_dump {
struct cam_jpeg_hw_ctx_mini_dump *ctx[CAM_JPEG_CTX_MAX];
struct cam_jpeg_hw_mini_dump_req cfg_req[CAM_JPEG_DEV_TYPE_MAX];
struct cam_jpeg_mini_dump_core_info core[CAM_JPEG_RES_TYPE_MAX];
uint32_t num_context;
};
#endif /* CAM_JPEG_HW_MGR_H */

Dosyayı Görüntüle

@@ -56,12 +56,24 @@ struct cam_jpeg_match_pid_args {
uint32_t match_res;
};
struct cam_jpeg_mini_dump_core_info {
uint32_t framedone;
uint32_t resetdone;
uint32_t iserror;
uint32_t stopdone;
uint32_t open_count;
int32_t ref_count;
uint32_t core_state;
uint32_t hw_state;
};
enum cam_jpeg_cmd_type {
CAM_JPEG_CMD_CDM_CFG,
CAM_JPEG_CMD_SET_IRQ_CB,
CAM_JPEG_CMD_HW_DUMP,
CAM_JPEG_CMD_GET_NUM_PID,
CAM_JPEG_CMD_MATCH_PID_MID,
CAM_JPEG_CMD_MINI_DUMP,
CAM_JPEG_CMD_MAX,
};

Dosyayı Görüntüle

@@ -33,7 +33,10 @@ struct cam_jpeg_request_data {
uint32_t thumbnail_threshold_size;
};
typedef void (*cam_jpeg_mini_dump_cb)(void *priv, void *dst);
int cam_jpeg_hw_mgr_init(struct device_node *of_node,
uint64_t *hw_mgr_hdl, int *iommu_hdl);
uint64_t *hw_mgr_hdl, int *iommu_hdl,
cam_jpeg_mini_dump_cb mini_dump_cb);
#endif /* CAM_JPEG_HW_MGR_INTF_H */

Dosyayı Görüntüle

@@ -369,6 +369,32 @@ int cam_jpeg_dma_stop_hw(void *data,
return 0;
}
static int cam_jpeg_dma_mini_dump(struct cam_hw_info *dev, void *args) {
struct cam_jpeg_mini_dump_core_info *md;
struct cam_jpeg_dma_device_hw_info *hw_info;
struct cam_jpeg_dma_device_core_info *core_info;
if (!dev || !args) {
CAM_ERR(CAM_JPEG, "Invalid params dev %pK args %pK", dev, args);
return -EINVAL;
}
core_info = (struct cam_jpeg_dma_device_core_info *)dev->core_info;
hw_info = core_info->jpeg_dma_hw_info;
md = (struct cam_jpeg_mini_dump_core_info *)args;
md->framedone = hw_info->int_status.framedone;
md->resetdone = hw_info->int_status.resetdone;
md->iserror = hw_info->int_status.iserror;
md->stopdone = hw_info->int_status.stopdone;
md->open_count = dev->open_count;
md->hw_state = dev->hw_state;
md->ref_count = core_info->ref_count;
md->core_state = core_info->core_state;
return 0;
}
int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
void *cmd_args, uint32_t arg_size)
{
@@ -456,6 +482,9 @@ int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
match_pid_mid->pid_match_found = false;
}
break;
case CAM_JPEG_CMD_MINI_DUMP:
rc = cam_jpeg_dma_mini_dump(jpeg_dma_dev, cmd_args);
break;
default:
rc = -EINVAL;

Dosyayı Görüntüle

@@ -496,6 +496,32 @@ int cam_jpeg_enc_hw_dump(
return 0;
}
static int cam_jpeg_enc_mini_dump(struct cam_hw_info *dev, void *args) {
struct cam_jpeg_mini_dump_core_info *md;
struct cam_jpeg_enc_device_hw_info *hw_info;
struct cam_jpeg_enc_device_core_info *core_info;
if (!dev || !args) {
CAM_ERR(CAM_JPEG, "Invalid params priv %pK args %pK", dev, args);
return -EINVAL;
}
core_info = (struct cam_jpeg_enc_device_core_info *)dev->core_info;
hw_info = core_info->jpeg_enc_hw_info;
md = (struct cam_jpeg_mini_dump_core_info *)args;
md->framedone = hw_info->int_status.framedone;
md->resetdone = hw_info->int_status.resetdone;
md->iserror = hw_info->int_status.iserror;
md->stopdone = hw_info->int_status.stopdone;
md->open_count = dev->open_count;
md->hw_state = dev->hw_state;
md->ref_count = core_info->ref_count;
md->core_state = core_info->core_state;
return 0;
}
int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type,
void *cmd_args, uint32_t arg_size)
{
@@ -590,6 +616,11 @@ int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type,
}
break;
case CAM_JPEG_CMD_MINI_DUMP:
{
rc = cam_jpeg_enc_mini_dump(jpeg_enc_dev, cmd_args);
break;
}
default:
rc = -EINVAL;
break;