Merge "msm: camera: common: Add Minidump changes for NRT devices" into camera-kernel.lnx.5.0

Цей коміт міститься в:
Savita Patted
2021-08-24 20:02:04 -07:00
зафіксовано Gerrit - the friendly Code Review server
джерело 09f1d471b3 2f5933b075
коміт 946cfd80fe
23 змінених файлів з 889 додано та 7 видалено

Переглянути файл

@@ -341,6 +341,27 @@ int cam_context_handle_crm_dump_req(struct cam_context *ctx,
return rc;
}
int cam_context_mini_dump_from_hw(struct cam_context *ctx,
void *args)
{
int rc = 0;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context [id %d name:%s] is not ready", ctx->ctx_id,
ctx->dev_name);
return -EINVAL;
}
if ((ctx->state >= CAM_CTX_AVAILABLE) && (ctx->state < CAM_CTX_STATE_MAX)) {
if (ctx->state_machine[ctx->state].mini_dump_ops)
rc = ctx->state_machine[ctx->state].mini_dump_ops(ctx, args);
else
CAM_WARN(CAM_CORE, "No dump ctx in dev %d, state %d",
ctx->dev_hdl, ctx->state);
}
return rc;
}
int cam_context_dump_pf_info(struct cam_context *ctx,
struct cam_smmu_pf_info *pf_info)
{

Переглянути файл

@@ -168,6 +168,7 @@ struct cam_ctx_crm_ops {
* @dumpinfo_ops: Function to be invoked for dumping any
* context info
* @recovery_ops: Function to be invoked to try hardware recovery
* @mini_dump_ops: Function for mini dump
*
*/
struct cam_ctx_ops {
@@ -177,6 +178,7 @@ struct cam_ctx_ops {
cam_hw_pagefault_cb_func pagefault_ops;
cam_ctx_info_dump_cb_func dumpinfo_ops;
cam_ctx_recovery_cb_func recovery_ops;
cam_ctx_mini_dump_cb_func mini_dump_ops;
};
/**
@@ -218,6 +220,7 @@ struct cam_ctx_ops {
* @hw_updater_entry: Hw update entry
* @in_map_entries: In map update entry
* @out_map_entries: Out map entry
* @mini dump cb: Mini dump cb
*
*/
struct cam_context {
@@ -262,6 +265,7 @@ struct cam_context {
struct cam_hw_update_entry *hw_update_entry;
struct cam_hw_fence_map_entry *in_map_entries;
struct cam_hw_fence_map_entry *out_map_entries;
cam_ctx_mini_dump_cb_func mini_dump_cb;
};
@@ -408,6 +412,18 @@ int cam_context_handle_crm_process_evt(struct cam_context *ctx,
int cam_context_handle_crm_dump_req(struct cam_context *ctx,
struct cam_req_mgr_dump_info *dump);
/**
* cam_context_mini_dump_from_hw()
*
* @brief: Handle mini dump request command
*
* @ctx: Object pointer for cam_context
* @args: Args to be passed
*
*/
int cam_context_mini_dump_from_hw(struct cam_context *ctx,
void *args);
/**
* cam_context_dump_pf_info()
*

Переглянути файл

@@ -615,6 +615,7 @@ int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx,
param.context_data = ctx;
param.ctx_id = ctx->ctx_id;
param.event_cb = ctx->irq_cb_intf;
param.mini_dump_cb = ctx->mini_dump_cb;
param.num_acq = cmd->num_resources;
param.acquire_info = cmd->resource_hdl;
@@ -1318,3 +1319,154 @@ err:
return 0;
}
static void __cam_context_req_mini_dump(struct cam_ctx_request *req,
uint8_t *start_addr, uint8_t *end_addr,
unsigned long *bytes_updated)
{
struct cam_hw_req_mini_dump *req_md;
struct cam_buf_io_cfg *io_cfg;
struct cam_packet *packet = NULL;
unsigned long bytes_written = 0;
unsigned long bytes_required = 0;
bytes_required = sizeof(*req_md);
if (start_addr + bytes_written + bytes_required > end_addr)
goto end;
req_md = (struct cam_hw_req_mini_dump *)start_addr;
req_md->num_fence_map_in = req->num_in_map_entries;
req_md->num_fence_map_out = req->num_out_map_entries;
req_md->num_in_acked = atomic_read(&req->num_in_acked);
req_md->num_out_acked = req->num_out_acked;
req_md->request_id = req->request_id;
bytes_written += bytes_required;
if (req->num_out_map_entries) {
bytes_required = sizeof(struct cam_hw_fence_map_entry) *
req->num_out_map_entries;
if (start_addr + bytes_written + bytes_required > end_addr)
goto end;
req_md->fence_map_out = (struct cam_hw_fence_map_entry *)
(start_addr + bytes_written);
memcpy(req_md->fence_map_out, req->out_map_entries, bytes_required);
req_md->num_fence_map_out = req->num_out_map_entries;
bytes_written += bytes_required;
}
if (req->num_in_map_entries) {
bytes_required = sizeof(struct cam_hw_fence_map_entry) *
req->num_in_map_entries;
if (start_addr + bytes_written + bytes_required > end_addr)
goto end;
req_md->fence_map_in = (struct cam_hw_fence_map_entry *)
(start_addr + bytes_written);
memcpy(req_md->fence_map_in, req->in_map_entries, bytes_required);
req_md->num_fence_map_in = req->num_in_map_entries;
bytes_written += bytes_required;
}
packet = (struct cam_packet *)req->pf_data.packet;
if (packet && packet->num_io_configs) {
bytes_required = packet->num_io_configs * sizeof(struct cam_buf_io_cfg);
if (start_addr + bytes_written + bytes_required > end_addr)
goto end;
io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload +
packet->io_configs_offset / 4);
req_md->io_cfg = (struct cam_buf_io_cfg *)(start_addr + bytes_written);
memcpy(req_md->io_cfg, io_cfg, bytes_required);
bytes_written += bytes_required;
req_md->num_io_cfg = packet->num_io_configs;
}
end:
*bytes_updated = bytes_written;
}
int cam_context_mini_dump(struct cam_context *ctx, void *args)
{
struct cam_hw_mini_dump_info *md;
struct cam_ctx_request *req, *req_temp;
struct cam_hw_mini_dump_args *md_args;
uint8_t *start_addr;
uint8_t *end_addr;
unsigned long bytes_written = 0;
unsigned long bytes_updated = 0;
if (!ctx || !args) {
CAM_ERR(CAM_CTXT, "invalid params");
return -EINVAL;
}
md_args = (struct cam_hw_mini_dump_args *)args;
if (md_args->len < sizeof(*md)) {
md_args->bytes_written = 0;
CAM_ERR(CAM_CTXT, "Insufficient len %lu, bytes_written %lu", md_args->len,
md_args->bytes_written);
return 0;
}
start_addr = (uint8_t *)md_args->start_addr;
end_addr = start_addr + md_args->len;
md = (struct cam_hw_mini_dump_info *)md_args->start_addr;
md->ctx_id = ctx->ctx_id;
md->last_flush_req = ctx->last_flush_req;
md->hw_mgr_ctx_id = ctx->hw_mgr_ctx_id;
md->dev_id = ctx->dev_id;
md->link_hdl = ctx->link_hdl;
md->state = ctx->state;
md->session_hdl = ctx->session_hdl;
md->dev_hdl = ctx->dev_hdl;
scnprintf(md->name, CAM_HW_MINI_DUMP_DEV_NAME_LEN, ctx->dev_name);
bytes_written += sizeof(*md);
if (!list_empty(&ctx->active_req_list)) {
md->active_list = (struct cam_hw_req_mini_dump *)
(start_addr + bytes_written);
list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) {
bytes_updated = 0;
__cam_context_req_mini_dump(req,
(uint8_t *)&md->active_list[md->active_cnt++],
end_addr, &bytes_updated);
if ((start_addr + bytes_written + bytes_updated >= end_addr))
goto end;
bytes_written += bytes_updated;
}
}
if (!list_empty(&ctx->wait_req_list)) {
md->wait_list = (struct cam_hw_req_mini_dump *)
(start_addr + bytes_written);
list_for_each_entry_safe(req, req_temp, &ctx->wait_req_list, list) {
bytes_updated = 0;
__cam_context_req_mini_dump(req,
(uint8_t *)&md->wait_list[md->wait_cnt++],
end_addr, &bytes_updated);
if ((start_addr + bytes_written + bytes_updated >= end_addr))
goto end;
bytes_written += bytes_updated;
}
}
if (!list_empty(&ctx->pending_req_list)) {
md->pending_list = (struct cam_hw_req_mini_dump *)
(start_addr + bytes_written);
list_for_each_entry_safe(req, req_temp, &ctx->pending_req_list, list) {
bytes_updated = 0;
__cam_context_req_mini_dump(req,
(uint8_t *)&md->pending_list[md->pending_cnt++],
end_addr, &bytes_updated);
if ((start_addr + bytes_written + bytes_updated >= end_addr))
goto end;
bytes_written += bytes_updated;
}
}
end:
md_args->bytes_written = bytes_written;
CAM_INFO(CAM_CTXT, "Ctx %s bytes_written %lu", ctx->dev_name, md_args->bytes_written);
return 0;
}

Переглянути файл

@@ -36,4 +36,5 @@ int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx,
struct cam_dump_req_cmd *cmd);
size_t cam_context_parse_config_cmd(struct cam_context *ctx, struct cam_config_dev_cmd *cmd,
struct cam_packet **packet);
int cam_context_mini_dump(struct cam_context *ctx, void *args);
#endif /* _CAM_CONTEXT_UTILS_H_ */

Переглянути файл

@@ -26,6 +26,9 @@
/* Maximum reg dump cmd buffer entries in a context */
#define CAM_REG_DUMP_MAX_BUF_ENTRIES 10
/* max device name string length*/
#define CAM_HW_MINI_DUMP_DEV_NAME_LEN 20
/**
* enum cam_context_dump_id -
* context dump type
@@ -415,6 +418,73 @@ struct cam_hw_mini_dump_args {
unsigned long bytes_written;
};
/**
* struct cam_hw_req_mini_dump - Mini dump context req
*
* @fence_map_out: Fence map out array
* @fence_map_in: Fence map in array
* @io_cfg: IO cfg.
* @request_id: Request id
* @num_fence_map_in: num of fence map in
* @num_fence_map_in: num of fence map out
* @num_io_cfg: num of io cfg
* @num_in_acked: num in acked
* @num_out_acked: num out acked
* @status: Status
* @flushed: whether request is flushed
*
*/
struct cam_hw_req_mini_dump {
struct cam_hw_fence_map_entry *fence_map_out;
struct cam_hw_fence_map_entry *fence_map_in;
struct cam_buf_io_cfg *io_cfg;
uint64_t request_id;
uint16_t num_fence_map_in;
uint16_t num_fence_map_out;
uint16_t num_io_cfg;
uint16_t num_in_acked;
uint16_t num_out_acked;
uint8_t status;
uint8_t flushed;
};
/**
* struct cam_hw_mini_dump_info - Mini dump context info
*
* @active_list: array of active req in context
* @wait_list: array of wait req in context
* @pending_list: array of pending req in context
* @name: name of context
* @dev_id: dev id.
* @last_flush_req: last flushed request id
* @refcount: kernel ref count
* @ctx_id: Context id
* @session_hdl: Session handle
* @link_hdl: link handle
* @dev_hdl: Dev hdl
* @state: State of context
* @hw_mgr_ctx_id: ctx id with hw mgr
*
*/
struct cam_hw_mini_dump_info {
struct cam_hw_req_mini_dump *active_list;
struct cam_hw_req_mini_dump *wait_list;
struct cam_hw_req_mini_dump *pending_list;
char name[CAM_HW_MINI_DUMP_DEV_NAME_LEN];
uint64_t dev_id;
uint32_t last_flush_req;
uint32_t refcount;
uint32_t ctx_id;
uint32_t active_cnt;
uint32_t pending_cnt;
uint32_t wait_cnt;
int32_t session_hdl;
int32_t link_hdl;
int32_t dev_hdl;
uint8_t state;
uint8_t hw_mgr_ctx_id;
};
/**
* cam_hw_mgr_intf - HW manager interface
*

Переглянути файл

@@ -66,6 +66,25 @@ end:
return rc;
}
static int cam_icp_context_mini_dump(void *priv, void *args)
{
int rc;
struct cam_context *ctx;
if (!priv || !args) {
CAM_ERR(CAM_ICP, "Invalid 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_ICP, "ctx [id: %u name: %s] Mini Dump failed rc %d", ctx->dev_name,
ctx->ctx_id, rc);
return rc;
}
static int __cam_icp_acquire_dev_in_available(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd)
{
@@ -236,6 +255,7 @@ static struct cam_ctx_ops
},
.crm_ops = {},
.irq_ops = NULL,
.mini_dump_ops = cam_icp_context_mini_dump,
},
/* Acquired */
{
@@ -249,6 +269,7 @@ static struct cam_ctx_ops
.crm_ops = {},
.irq_ops = __cam_icp_handle_buf_done_in_ready,
.pagefault_ops = cam_icp_context_dump_active_request,
.mini_dump_ops = cam_icp_context_mini_dump,
},
/* Ready */
{
@@ -262,6 +283,7 @@ static struct cam_ctx_ops
.crm_ops = {},
.irq_ops = __cam_icp_handle_buf_done_in_ready,
.pagefault_ops = cam_icp_context_dump_active_request,
.mini_dump_ops = cam_icp_context_mini_dump,
},
/* Flushed */
{
@@ -273,6 +295,7 @@ static struct cam_ctx_ops
.crm_ops = {},
.irq_ops = NULL,
.pagefault_ops = cam_icp_context_dump_active_request,
.mini_dump_ops = cam_icp_context_mini_dump,
},
};

Переглянути файл

@@ -66,6 +66,19 @@ static void cam_icp_dev_iommu_fault_handler(struct cam_smmu_pf_info *pf_info)
cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
}
static void cam_icp_dev_mini_dump_cb(void *priv, void *args)
{
struct cam_context *ctx = NULL;
if (!priv || !args) {
CAM_ERR(CAM_ICP, "Invalid param priv: %pK args %pK", priv, args);
return;
}
ctx = (struct cam_context *)priv;
cam_context_mini_dump_from_hw(ctx, args);
}
static int cam_icp_subdev_open(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
@@ -187,7 +200,7 @@ static int cam_icp_component_bind(struct device *dev,
}
rc = cam_icp_hw_mgr_init(pdev->dev.of_node, (uint64_t *)hw_mgr_intf,
&iommu_hdl);
&iommu_hdl, cam_icp_dev_mini_dump_cb);
if (rc) {
CAM_ERR(CAM_ICP, "ICP HW manager init failed: %d", rc);
goto hw_init_fail;

Переглянути файл

@@ -8,6 +8,9 @@
#include <linux/types.h>
#define HFI_CMD_Q_MINI_DUMP_SIZE_IN_BYTES 4096
#define HFI_MSG_Q_MINI_DUMP_SIZE_IN_BYTES 4096
/**
* struct hfi_mem
* @len: length of memory
@@ -61,6 +64,19 @@ struct hfi_ops {
void __iomem *(*iface_addr)(void *data);
};
/**
* struct hfi_mini_dump_info
* @cmd_q: cmd queue
* @msg_q: msg queue
* @msg_q_state: msg queue state
* @cmd_q_state: cmd queue state
*/
struct hfi_mini_dump_info {
uint32_t cmd_q[HFI_CMD_Q_MINI_DUMP_SIZE_IN_BYTES];
uint32_t msg_q[HFI_MSG_Q_MINI_DUMP_SIZE_IN_BYTES];
bool msg_q_state;
bool cmd_q_state;
};
/**
* hfi_write_cmd() - function for hfi write
* @cmd_ptr: pointer to command data for hfi write
@@ -163,5 +179,9 @@ int cam_hfi_resume(struct hfi_mem_info *hfi_mem);
*/
void cam_hfi_queue_dump(void);
/**
* cam_hfi_mini_dump() - utility function for mini dump
*/
void cam_hfi_mini_dump(struct hfi_mini_dump_info *dst);
#endif /* _HFI_INTF_H_ */

Переглянути файл

@@ -87,6 +87,32 @@ static void hfi_queue_dump(uint32_t *dwords, int count)
rows * 4, dwords[0], dwords[1], dwords[2]);
}
void cam_hfi_mini_dump(struct hfi_mini_dump_info *dst)
{
struct hfi_mem_info *hfi_mem = &g_hfi->map;
struct hfi_qtbl *qtbl;
struct hfi_q_hdr *q_hdr;
uint32_t *dwords;
int num_dwords;
if (!hfi_mem) {
CAM_ERR(CAM_HFI, "hfi mem info NULL... unable to dump queues");
return;
}
qtbl = (struct hfi_qtbl *)hfi_mem->qtbl.kva;
q_hdr = &qtbl->q_hdr[Q_CMD];
dwords = (uint32_t *)hfi_mem->cmd_q.kva;
num_dwords = ICP_CMD_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT;
memcpy(dst->cmd_q, dwords, ICP_CMD_Q_SIZE_IN_BYTES);
q_hdr = &qtbl->q_hdr[Q_MSG];
dwords = (uint32_t *)hfi_mem->msg_q.kva;
memcpy(dst->msg_q, dwords, ICP_CMD_Q_SIZE_IN_BYTES);
dst->msg_q_state = g_hfi->msg_q_state;
dst->cmd_q_state = g_hfi->cmd_q_state;
}
void cam_hfi_queue_dump(void)
{
struct hfi_mem_info *hfi_mem = &g_hfi->map;

Переглянути файл

@@ -178,6 +178,37 @@ static int cam_a5_fw_dump(
return 0;
}
static int cam_a5_fw_mini_dump(
struct cam_icp_hw_dump_args *dump_args,
struct cam_a5_device_core_info *core_info)
{
u8 *dest;
u8 *src;
if (!core_info || !dump_args) {
CAM_ERR(CAM_ICP, "invalid params %pK %pK", core_info, dump_args);
return -EINVAL;
}
if (!core_info->fw_kva_addr || !dump_args->cpu_addr) {
CAM_ERR(CAM_ICP, "invalid params %pK, 0x%zx", core_info->fw_kva_addr,
dump_args->cpu_addr);
return -EINVAL;
}
if (dump_args->buf_len < core_info->fw_buf_len) {
CAM_WARN(CAM_ICP, "Insufficient Len %lu fw_len %llu",
dump_args->buf_len, core_info->fw_buf_len);
return -ENOSPC;
}
dest = (u8 *)dump_args->cpu_addr;
src = (u8 *)core_info->fw_kva_addr;
memcpy_fromio(dest, src, core_info->fw_buf_len);
dump_args->offset = core_info->fw_buf_len;
return 0;
}
int cam_a5_init_hw(void *device_priv,
void *init_hw_args, uint32_t arg_size)
{
@@ -706,6 +737,13 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,
rc = cam_a5_fw_dump(dump_args, core_info);
break;
}
case CAM_ICP_CMD_HW_MINI_DUMP: {
struct cam_icp_hw_dump_args *dump_args = cmd_args;
rc = cam_a5_fw_mini_dump(dump_args, core_info);
break;
}
default:
break;
}

Переглянути файл

@@ -3711,6 +3711,132 @@ static int cam_icp_mgr_release_ctx(struct cam_icp_hw_mgr *hw_mgr, int ctx_id)
return 0;
}
static unsigned long cam_icp_hw_mgr_mini_dump_cb(void *dst, unsigned long len)
{
struct cam_icp_hw_mini_dump_info *md;
struct cam_icp_hw_ctx_mini_dump *ctx_md;
struct cam_icp_hw_ctx_data *ctx;
struct cam_icp_hw_mgr *hw_mgr;
struct cam_hw_mini_dump_args hw_dump_args;
struct cam_icp_hw_dump_args icp_dump_args;
struct cam_hw_intf *icp_dev_intf = NULL;
uint32_t i = 0, j = 0;
unsigned long dumped_len = 0;
unsigned long remain_len = len;
int rc = 0;
if (!dst || len < sizeof(*md)) {
CAM_ERR(CAM_ICP, "Invalid params dst %pk len %lu", dst, len);
return 0;
}
md = (struct cam_icp_hw_mini_dump_info *)dst;
md->num_context = 0;
hw_mgr = &icp_hw_mgr;
cam_hfi_mini_dump(&md->hfi_info);
memcpy(&md->hfi_mem_info, &hw_mgr->hfi_mem,
sizeof(struct icp_hfi_mem_info));
md->recovery = atomic_read(&hw_mgr->recovery);
md->icp_booted = hw_mgr->icp_booted;
md->icp_resumed = hw_mgr->icp_resumed;
md->ipe_clk_state = hw_mgr->ipe_clk_state;
md->ipe_clk_state = hw_mgr->ipe_clk_state;
md->bps_clk_state = hw_mgr->bps_clk_state;
md->disable_ubwc_comp = hw_mgr->disable_ubwc_comp;
md->ipe0_enable = hw_mgr->ipe0_enable;
md->ipe1_enable = hw_mgr->ipe1_enable;
md->bps_enable = hw_mgr->bps_enable;
md->icp_pc_flag = hw_mgr->icp_pc_flag;
md->ipe_bps_pc_flag = hw_mgr->ipe_bps_pc_flag;
md->icp_use_pil = hw_mgr->icp_use_pil;
dumped_len += sizeof(*md);
remain_len = len - dumped_len;
for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
ctx = &hw_mgr->ctx_data[i];
if (ctx->state == CAM_ICP_CTX_STATE_FREE ||
ctx->state == CAM_ICP_CTX_STATE_RELEASE)
continue;
if (remain_len < sizeof(*ctx_md))
goto end;
md->num_context++;
ctx_md = (struct cam_icp_hw_ctx_mini_dump *)
((uint8_t *)dst + dumped_len);
md->ctx[i] = ctx_md;
ctx_md->state = ctx->state;
ctx_md->ctx_id = ctx->ctx_id;
memcpy(ctx_md->ctx_id_string, ctx->ctx_id_string,
strlen(ctx->ctx_id_string));
if (ctx->icp_dev_acquire_info) {
ctx_md->acquire.secure_mode =
ctx->icp_dev_acquire_info->secure_mode;
ctx_md->acquire.dev_type =
ctx->icp_dev_acquire_info->dev_type;
ctx_md->acquire.num_out_res =
ctx->icp_dev_acquire_info->num_out_res;
memcpy(&ctx_md->acquire.in_res,
&ctx->icp_dev_acquire_info->in_res,
sizeof(struct cam_icp_res_info));
memcpy(ctx_md->acquire.out_res,
ctx->icp_dev_acquire_info->out_res,
sizeof(ctx->icp_dev_acquire_info->out_res));
} else {
memset(&ctx_md->acquire, 0,
sizeof(struct cam_icp_mini_dump_acquire_info));
}
memcpy(ctx_md->hfi_frame.request_id, ctx->hfi_frame_process.request_id,
sizeof(ctx->hfi_frame_process.request_id));
memcpy(ctx_md->hfi_frame.in_resource, ctx->hfi_frame_process.in_resource,
sizeof(ctx->hfi_frame_process.in_resource));
memcpy(ctx_md->hfi_frame.submit_timestamp,
ctx->hfi_frame_process.submit_timestamp,
sizeof(ctx->hfi_frame_process.submit_timestamp));
memcpy(ctx_md->hfi_frame.num_out_res, ctx->hfi_frame_process.num_out_resources,
sizeof(ctx->hfi_frame_process.num_out_resources));
memcpy(ctx_md->hfi_frame.out_res, ctx->hfi_frame_process.out_resource,
sizeof(ctx->hfi_frame_process.out_resource));
for (j = 0; j < CAM_FRAME_CMD_MAX; j++) {
ctx_md->hfi_frame.fw_process_flag[j] =
ctx->hfi_frame_process.fw_process_flag[j];
}
dumped_len += sizeof(*ctx_md);
remain_len = len - dumped_len;
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;
ctx_md->hw_ctx = hw_dump_args.start_addr;
dumped_len += hw_dump_args.bytes_written;
remain_len = len - dumped_len;
}
/* Dump fw image */
if (!hw_mgr->icp_use_pil) {
icp_dump_args.cpu_addr = (uintptr_t)((uint8_t *)dst + dumped_len);
icp_dump_args.offset = 0;
icp_dump_args.buf_len = remain_len;
icp_dev_intf = hw_mgr->icp_dev_intf;
rc = icp_dev_intf->hw_ops.process_cmd(
icp_dev_intf->hw_priv,
CAM_ICP_CMD_HW_MINI_DUMP, &icp_dump_args,
sizeof(struct cam_icp_hw_dump_args));
if (rc)
goto end;
dumped_len += icp_dump_args.offset;
md->fw_img = (void *)icp_dump_args.cpu_addr;
remain_len = len - dumped_len;
}
end:
return dumped_len;
}
static void cam_icp_mgr_device_deinit(struct cam_icp_hw_mgr *hw_mgr)
{
struct cam_hw_intf *icp_dev_intf = NULL;
@@ -6351,7 +6477,7 @@ static int cam_icp_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
}
int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
int *iommu_hdl)
int *iommu_hdl, cam_icp_mini_dump_cb mini_dump_cb)
{
int i, rc = 0;
struct cam_hw_mgr_intf *hw_mgr_intf;
@@ -6380,6 +6506,7 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
hw_mgr_intf->hw_dump = cam_icp_mgr_hw_dump;
icp_hw_mgr.secure_mode = CAM_SECURE_MODE_NON_SECURE;
icp_hw_mgr.mini_dump_cb = mini_dump_cb;
mutex_init(&icp_hw_mgr.hw_mgr_mutex);
spin_lock_init(&icp_hw_mgr.hw_mgr_lock);
@@ -6445,6 +6572,8 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
*iommu_hdl = icp_hw_mgr.iommu_hdl;
init_completion(&icp_hw_mgr.icp_complete);
cam_common_register_mini_dump_cb(
cam_icp_hw_mgr_mini_dump_cb, "cam_icp");
return rc;
icp_wq_create_failed:

Переглянути файл

@@ -14,6 +14,7 @@
#include "cam_hw_intf.h"
#include "cam_a5_hw_intf.h"
#include "hfi_session_defs.h"
#include "hfi_intf.h"
#include "cam_req_mgr_workq.h"
#include "cam_mem_mgr.h"
#include "cam_smmu_api.h"
@@ -75,6 +76,8 @@
*/
#define CAM_ICP_CTX_RESPONSE_TIME_THRESHOLD 300000
struct hfi_mini_dump_info;
/**
* struct icp_hfi_mem_info
* @qtbl: Memory info of queue table
@@ -321,6 +324,7 @@ struct cam_icp_clk_info {
* @devices: Devices of ICP hardware manager
* @ctx_data: Context data
* @icp_caps: ICP capabilities
* @mini_dump_cb: Mini dump cb
* @icp_booted: Processor is booted i.e. firmware loaded
* @icp_resumed: Processor is powered on
* @iommu_hdl: Non secure IOMMU handle
@@ -372,6 +376,7 @@ struct cam_icp_hw_mgr {
struct cam_hw_intf **devices[CAM_ICP_DEV_MAX];
struct cam_icp_hw_ctx_data ctx_data[CAM_ICP_CTX_MAX];
struct cam_icp_query_cap_cmd icp_caps;
cam_icp_mini_dump_cb mini_dump_cb;
bool icp_booted;
bool icp_resumed;
@@ -415,6 +420,99 @@ struct cam_icp_hw_mgr {
atomic_t recovery;
};
/**
* struct cam_icp_mini_dump_acquire_info - ICP mini dump device info
*
* @in_res: resource info used for clock and bandwidth calculation
* @out_res: output resource
* @num_out_res: number of output resources
* @dev_type: device type (IPE_RT/IPE_NON_RT/BPS)
* @secure_mode: camera mode (secure/non secure)
*/
struct cam_icp_mini_dump_acquire_info {
struct cam_icp_res_info out_res[ICP_MAX_OUTPUT_SUPPORTED];
struct cam_icp_res_info in_res;
uint16_t num_out_res;
uint8_t dev_type;
uint8_t secure_mode;
};
/**
* struct hfi_frame_process_info
* @request_id: Request id list
* @num_out_res: Number of out syncs
* @out_res: Out sync info
* @in_resource: In sync info
* @submit_timestamp: Submit timestamp to hw
* @fw_process_flag: Frame process flag
*/
struct hfi_frame_mini_dump_info {
uint64_t request_id[CAM_FRAME_CMD_MAX];
uint32_t num_out_res[CAM_FRAME_CMD_MAX];
uint32_t out_res[CAM_FRAME_CMD_MAX][CAM_MAX_OUT_RES];
uint32_t in_resource[CAM_FRAME_CMD_MAX];
ktime_t submit_timestamp[CAM_FRAME_CMD_MAX];
uint8_t fw_process_flag[CAM_FRAME_CMD_MAX];
};
/**
* struct cam_icp_hw_ctx_mini_dump
* @acquire: Acquire device info
* @hfi_frame: Frame command
* @hw_ctx: Context private data
* @state: context state
* @ctx_id_string: Context id string
* @ctx_id: Context Id
*/
struct cam_icp_hw_ctx_mini_dump {
struct cam_icp_mini_dump_acquire_info acquire;
struct hfi_frame_mini_dump_info hfi_frame;
void *hw_ctx;
char ctx_id_string[128];
uint8_t state;
uint8_t ctx_id;
};
/**
* struct cam_icp_hw_mini_dump_info
*
* @ctx: Context for minidump
* @hfi_info: hfi info
* @hfi_mem_info: hfi mem info
* @fw_img: FW image
* @recovery: To indicate if recovery is on
* @icp_booted: Indicate if ICP is booted
* @icp_resumed: Indicate if ICP is resumed
* @ipe_clk_state: IPE Clk state
* @bps_clk_state: BPS clk state
* @disable_ubwc_comp: Indicate if ubws comp is disabled
* @ipe0_enable: Is IPE0 enabled
* @ipe1_enable: Is IPE1 enabled
* @bps_enable: Is BPS enabled
* @icp_pc_flag: Is ICP PC enabled
* @ipe_bps_pc_flag: Is IPE BPS PC enabled
* @icp_use_pil: Is PIL used
*/
struct cam_icp_hw_mini_dump_info {
struct cam_icp_hw_ctx_mini_dump *ctx[CAM_ICP_CTX_MAX];
struct hfi_mini_dump_info hfi_info;
struct icp_hfi_mem_info hfi_mem_info;
void *fw_img;
uint32_t recovery;
uint32_t num_context;
bool icp_booted;
bool icp_resumed;
bool ipe_clk_state;
bool bps_clk_state;
bool disable_ubwc_comp;
bool ipe0_enable;
bool ipe1_enable;
bool bps_enable;
bool icp_pc_flag;
bool ipe_bps_pc_flag;
bool icp_use_pil;
};
static int cam_icp_mgr_hw_close(void *hw_priv, void *hw_close_args);
static int cam_icp_mgr_hw_open(void *hw_mgr_priv, void *download_fw_args);
static int cam_icp_mgr_icp_resume(struct cam_icp_hw_mgr *hw_mgr);

Переглянути файл

@@ -42,6 +42,7 @@ enum cam_icp_cmd_type {
CAM_ICP_CMD_PC_PREP,
CAM_ICP_CMD_CLK_UPDATE,
CAM_ICP_CMD_HW_DUMP,
CAM_ICP_CMD_HW_MINI_DUMP,
CAM_ICP_CMD_MAX,
};

Переглянути файл

@@ -30,8 +30,12 @@
#define CAM_ICP_DUMP_TAG_MAX_LEN 32
#define CAM_ICP_DUMP_NUM_WORDS 5
typedef void(*cam_icp_mini_dump_cb)(void *priv,
void *args);
int cam_icp_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_icp_mini_dump_cb mini_dump_cb);
void cam_icp_hw_mgr_deinit(void);

Переглянути файл

@@ -777,6 +777,38 @@ static int __cam_lx7_update_clk_rate(
return rc;
}
static int __cam_lx7_fw_mini_dump(
struct cam_lx7_core_info *core_info,
struct cam_icp_hw_dump_args *args)
{
u8 *dest;
u8 *src;
struct cam_icp_hw_dump_args *dump_args = args;
if (!core_info || !dump_args) {
CAM_ERR(CAM_ICP, "invalid params %pK %pK", core_info, dump_args);
return -EINVAL;
}
if (!core_info->fw_params.fw_kva_addr || !dump_args->cpu_addr) {
CAM_ERR(CAM_ICP, "invalid params %pK, 0x%zx",
core_info->fw_params.fw_kva_addr, dump_args->cpu_addr);
return -EINVAL;
}
if (dump_args->buf_len < core_info->fw_params.fw_buf_len) {
CAM_WARN(CAM_ICP, "Insufficient Len %lu fw_len %llu",
dump_args->buf_len, core_info->fw_params.fw_buf_len);
return -ENOSPC;
}
dest = (u8 *)dump_args->cpu_addr;
src = (u8 *)core_info->fw_params.fw_kva_addr;
memcpy_fromio(dest, src, core_info->fw_params.fw_buf_len);
dump_args->offset = core_info->fw_params.fw_buf_len;
return 0;
}
int cam_lx7_process_cmd(void *priv, uint32_t cmd_type,
void *args, uint32_t arg_size)
{
@@ -829,6 +861,10 @@ int cam_lx7_process_cmd(void *priv, uint32_t cmd_type,
/* Not supported for lx7 */
rc = 0;
break;
case CAM_ICP_CMD_HW_MINI_DUMP: {
rc = __cam_lx7_fw_mini_dump(lx7_info->core_info, args);
break;
}
default:
CAM_ERR(CAM_ICP, "invalid command type=%u", cmd_type);
break;

Переглянути файл

@@ -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 */
{

Переглянути файл

@@ -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;

Переглянути файл

@@ -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:

Переглянути файл

@@ -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 */

Переглянути файл

@@ -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,
};

Переглянути файл

@@ -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 */

Переглянути файл

@@ -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;

Переглянути файл

@@ -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;