Merge "msm: camera: core: Send event on smmu page fault" into camera-kernel.lnx.4.0

This commit is contained in:
Camera Software Integration
2020-08-21 14:07:01 -07:00
committed by Gerrit - the friendly Code Review server
35 changed files with 728 additions and 162 deletions

View File

@@ -1224,16 +1224,14 @@ static void cam_hw_cdm_work(struct work_struct *work)
}
static void cam_hw_cdm_iommu_fault_handler(struct iommu_domain *domain,
struct device *dev, unsigned long iova, int flags, void *token,
uint32_t buf_info)
static void cam_hw_cdm_iommu_fault_handler(struct cam_smmu_pf_info *pf_info)
{
struct cam_hw_info *cdm_hw = NULL;
struct cam_cdm *core = NULL;
int i;
if (token) {
cdm_hw = (struct cam_hw_info *)token;
if (pf_info->token) {
cdm_hw = (struct cam_hw_info *)pf_info->token;
core = (struct cam_cdm *)cdm_hw->core_info;
set_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
mutex_lock(&cdm_hw->hw_mutex);
@@ -1254,9 +1252,9 @@ static void cam_hw_cdm_iommu_fault_handler(struct iommu_domain *domain,
mutex_unlock(&core->bl_fifo[i].fifo_lock);
mutex_unlock(&cdm_hw->hw_mutex);
CAM_ERR_RATE_LIMIT(CAM_CDM, "Page fault iova addr %pK\n",
(void *)iova);
(void *)pf_info->iova);
cam_cdm_notify_clients(cdm_hw, CAM_CDM_CB_STATUS_PAGEFAULT,
(void *)iova);
(void *)pf_info->iova);
clear_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
} else {
CAM_ERR(CAM_CDM, "Invalid token");

View File

@@ -287,8 +287,8 @@ int cam_context_handle_crm_dump_req(struct cam_context *ctx,
return rc;
}
int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
uint32_t buf_info)
int cam_context_dump_pf_info(struct cam_context *ctx,
struct cam_smmu_pf_info *pf_info)
{
int rc = 0;
@@ -301,7 +301,7 @@ int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
(ctx->state < CAM_CTX_STATE_MAX)) {
if (ctx->state_machine[ctx->state].pagefault_ops) {
rc = ctx->state_machine[ctx->state].pagefault_ops(
ctx, iova, buf_info);
ctx, pf_info);
} else {
CAM_WARN(CAM_CORE, "No dump ctx in dev %d, state %d",
ctx->dev_hdl, ctx->state);

View File

@@ -11,6 +11,7 @@
#include <linux/kref.h>
#include "cam_req_mgr_interface.h"
#include "cam_hw_mgr_intf.h"
#include "cam_smmu_api.h"
/* Forward declarations */
struct cam_context;
@@ -360,12 +361,11 @@ int cam_context_handle_crm_dump_req(struct cam_context *ctx,
* @brief: Handle dump active request request command
*
* @ctx: Object pointer for cam_context
* @iova: Page fault address
* @buf_info: Information about closest memory handle
* @pf_info: Smmu page fault info
*
*/
int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
uint32_t buf_info);
int cam_context_dump_pf_info(struct cam_context *ctx,
struct cam_smmu_pf_info *pf_info);
/**
* cam_context_handle_acquire_dev()

View File

@@ -998,8 +998,8 @@ end:
}
int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
struct cam_packet *packet, unsigned long iova, uint32_t buf_info,
bool *mem_found)
struct cam_packet *packet, bool *mem_found, bool *ctx_found,
uint32_t *resource_type, struct cam_smmu_pf_info *pf_info)
{
int rc = 0;
struct cam_hw_cmd_args cmd_args;
@@ -1021,9 +1021,14 @@ int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
cmd_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
cmd_args.cmd_type = CAM_HW_MGR_CMD_DUMP_PF_INFO;
cmd_args.u.pf_args.pf_data.packet = packet;
cmd_args.u.pf_args.iova = iova;
cmd_args.u.pf_args.buf_info = buf_info;
cmd_args.u.pf_args.iova = pf_info->iova;
cmd_args.u.pf_args.buf_info = pf_info->buf_info;
cmd_args.u.pf_args.mem_found = mem_found;
cmd_args.u.pf_args.ctx_found = ctx_found;
cmd_args.u.pf_args.resource_type = resource_type;
cmd_args.u.pf_args.bid = pf_info->bid;
cmd_args.u.pf_args.pid = pf_info->pid;
cmd_args.u.pf_args.mid = pf_info->mid;
ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
&cmd_args);
}

View File

@@ -7,6 +7,7 @@
#define _CAM_CONTEXT_UTILS_H_
#include <linux/types.h>
#include "cam_smmu_api.h"
int cam_context_buf_done_from_hw(struct cam_context *ctx,
void *done_event_data, uint32_t evt_id);
@@ -27,8 +28,9 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx);
int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
struct cam_flush_dev_cmd *cmd);
int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
struct cam_packet *packet, unsigned long iova, uint32_t buf_info,
bool *mem_found);
struct cam_packet *packet, bool *mem_found, bool *ctx_found,
uint32_t *resource_type,
struct cam_smmu_pf_info *pf_info);
int32_t cam_context_dump_hw_acq_info(struct cam_context *ctx);
int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx,
struct cam_dump_req_cmd *cmd);

View File

@@ -9,6 +9,8 @@
#include <linux/time.h>
#include <linux/types.h>
#include <media/cam_defs.h>
#include "cam_smmu_api.h"
/*
* This file declares Constants, Enums, Structures and APIs to be used as
* Interface between HW Manager and Context.
@@ -44,8 +46,8 @@ typedef int (*cam_hw_event_cb_func)(void *context, uint32_t evt_id,
void *evt_data);
/* hardware page fault callback function type */
typedef int (*cam_hw_pagefault_cb_func)(void *context, unsigned long iova,
uint32_t buf_info);
typedef int (*cam_hw_pagefault_cb_func)(void *context,
struct cam_smmu_pf_info *pf_info);
/* ctx dump callback function type */
typedef int (*cam_ctx_info_dump_cb_func)(void *context,
@@ -295,6 +297,11 @@ struct cam_hw_flush_args {
* fault occurred
* @mem_found: If fault memory found in current
* request
* @ctx_found If fault pid found in context acquired hardware
* @resource_type Resource type of the port which caused pf
* @bid: Indicate the bus id
* @pid: Indicates unique hw group ports
* @mid: Indicates port id of the camera hw
*
*/
struct cam_hw_dump_pf_args {
@@ -302,6 +309,11 @@ struct cam_hw_dump_pf_args {
unsigned long iova;
uint32_t buf_info;
bool *mem_found;
bool *ctx_found;
uint32_t *resource_type;
uint32_t bid;
uint32_t pid;
uint32_t mid;
};
/**

View File

@@ -14,6 +14,7 @@
#include "cam_cpas_hw_intf.h"
#include "cam_cpas_soc.h"
#include "cam_req_mgr_dev.h"
#include "cam_smmu_api.h"
static uint cam_min_camnoc_ib_bw;
module_param(cam_min_camnoc_ib_bw, uint, 0644);
@@ -1431,6 +1432,8 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
}
CAM_DBG(CAM_CPAS, "irq_count=%d\n",
atomic_read(&cpas_core->irq_count));
cam_smmu_reset_cb_page_fault_cnt();
cpas_hw->hw_state = CAM_HW_STATE_POWER_UP;
}

View File

@@ -25,22 +25,20 @@
static struct cam_custom_dev g_custom_dev;
static void cam_custom_dev_iommu_fault_handler(
struct iommu_domain *domain, struct device *dev, unsigned long iova,
int flags, void *token, uint32_t buf_info)
struct cam_smmu_pf_info *pf_info)
{
int i = 0;
struct cam_node *node = NULL;
if (!token) {
if (!pf_info || !pf_info->token) {
CAM_ERR(CAM_CUSTOM, "invalid token in page handler cb");
return;
}
node = (struct cam_node *)token;
node = (struct cam_node *)pf_info->token;
for (i = 0; i < node->ctx_size; i++)
cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
buf_info);
cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
}
static const struct of_device_id cam_custom_dt_match[] = {

View File

@@ -22,15 +22,16 @@
static const char icp_dev_name[] = "cam-icp";
static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
uint32_t buf_info)
static int cam_icp_context_dump_active_request(void *data,
struct cam_smmu_pf_info *pf_info)
{
struct cam_context *ctx = (struct cam_context *)data;
struct cam_ctx_request *req = NULL;
struct cam_ctx_request *req_temp = NULL;
struct cam_hw_mgr_dump_pf_data *pf_dbg_entry = NULL;
uint32_t resource_type = 0;
int rc = 0;
bool b_mem_found = false;
bool b_mem_found = false, b_ctx_found = false;
if (!ctx) {
CAM_ERR(CAM_ICP, "Invalid ctx");
@@ -52,7 +53,7 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
CAM_INFO(CAM_ICP, "req_id : %lld", req->request_id);
rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
iova, buf_info, &b_mem_found);
&b_mem_found, &b_ctx_found, &resource_type, pf_info);
if (rc)
CAM_ERR(CAM_ICP, "Failed to dump pf info");

View File

@@ -50,23 +50,20 @@ static const struct of_device_id cam_icp_dt_match[] = {
{}
};
static void cam_icp_dev_iommu_fault_handler(
struct iommu_domain *domain, struct device *dev, unsigned long iova,
int flags, void *token, uint32_t buf_info)
static void cam_icp_dev_iommu_fault_handler(struct cam_smmu_pf_info *pf_info)
{
int i = 0;
struct cam_node *node = NULL;
if (!token) {
CAM_ERR(CAM_ICP, "invalid token in page handler cb");
if (!pf_info || !pf_info->token) {
CAM_ERR(CAM_ISP, "invalid token in page handler cb");
return;
}
node = (struct cam_node *)token;
node = (struct cam_node *)pf_info->token;
for (i = 0; i < node->ctx_size; i++)
cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
buf_info);
cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
}
static int cam_icp_subdev_open(struct v4l2_subdev *sd,

View File

@@ -28,8 +28,8 @@ static struct cam_isp_ctx_debug isp_ctx_debug;
div_u64_rem(atomic64_add_return(1, head),\
max_entries, (ret))
static int cam_isp_context_dump_requests(void *data, unsigned long iova,
uint32_t buf_info);
static int cam_isp_context_dump_requests(void *data,
struct cam_smmu_pf_info *pf_info);
static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
struct cam_start_stop_dev_cmd *cmd);
@@ -5423,9 +5423,8 @@ static struct cam_ctx_ops
},
};
static int cam_isp_context_dump_requests(void *data, unsigned long iova,
uint32_t buf_info)
static int cam_isp_context_dump_requests(void *data,
struct cam_smmu_pf_info *pf_info)
{
struct cam_context *ctx = (struct cam_context *)data;
@@ -5434,7 +5433,10 @@ static int cam_isp_context_dump_requests(void *data, unsigned long iova,
struct cam_isp_ctx_req *req_isp = NULL;
struct cam_isp_prepare_hw_update_data *hw_update_data = NULL;
struct cam_hw_mgr_dump_pf_data *pf_dbg_entry = NULL;
bool mem_found = false;
struct cam_req_mgr_message req_msg;
struct cam_isp_context *ctx_isp;
uint32_t resource_type = 0;
bool mem_found = false, ctx_found = false, send_error = false;
int rc = 0;
struct cam_isp_context *isp_ctx =
@@ -5457,13 +5459,12 @@ static int cam_isp_context_dump_requests(void *data, unsigned long iova,
req->request_id);
rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
iova, buf_info, &mem_found);
&mem_found, &ctx_found, &resource_type, pf_info);
if (rc)
CAM_ERR(CAM_ISP, "Failed to dump pf info");
if (mem_found)
CAM_ERR(CAM_ISP, "Found page fault in req %lld %d",
req->request_id, rc);
if (ctx_found)
send_error = true;
}
CAM_INFO(CAM_ISP, "Iterating over wait_list of isp ctx %d state %d",
@@ -5477,13 +5478,12 @@ static int cam_isp_context_dump_requests(void *data, unsigned long iova,
CAM_INFO(CAM_ISP, "Wait List: req_id : %lld ", req->request_id);
rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
iova, buf_info, &mem_found);
&mem_found, &ctx_found, &resource_type, pf_info);
if (rc)
CAM_ERR(CAM_ISP, "Failed to dump pf info");
if (mem_found)
CAM_ERR(CAM_ISP, "Found page fault in req %lld %d",
req->request_id, rc);
if (ctx_found)
send_error = true;
}
/*
@@ -5508,15 +5508,57 @@ static int cam_isp_context_dump_requests(void *data, unsigned long iova,
req->request_id);
rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
iova, buf_info, &mem_found);
&mem_found, &ctx_found, &resource_type, pf_info);
if (rc)
CAM_ERR(CAM_ISP, "Failed to dump pf info");
if (mem_found)
CAM_ERR(CAM_ISP, "Found page fault in req %lld %d",
req->request_id, rc);
if (ctx_found)
send_error = true;
}
if (resource_type) {
ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
if (ctx_isp->isp_device_type == CAM_IFE_DEVICE_TYPE)
CAM_ERR(CAM_ISP,
"Page fault on resource id:%s (0x%x) ctx id:%d frame id:%d reported id:%lld applied id:%lld",
__cam_isp_resource_handle_id_to_type(
resource_type),
resource_type, ctx->ctx_id, ctx_isp->frame_id,
ctx_isp->reported_req_id,
ctx_isp->last_applied_req_id);
else
CAM_ERR(CAM_ISP,
"Page fault on resource id:%s (0x%x) ctx id:%d frame id:%d reported id:%lld applied id:%lld",
__cam_isp_tfe_resource_handle_id_to_type(
resource_type),
resource_type, ctx->ctx_id, ctx_isp->frame_id,
ctx_isp->reported_req_id,
ctx_isp->last_applied_req_id);
}
if (send_error) {
CAM_INFO(CAM_ISP,
"page fault notifying to umd ctx %u session_hdl:%d device_hdl:%d link_hdl:%d",
ctx->ctx_id, ctx->session_hdl,
ctx->dev_hdl, ctx->link_hdl);
req_msg.session_hdl = ctx->session_hdl;
req_msg.u.err_msg.device_hdl = ctx->dev_hdl;
req_msg.u.err_msg.error_type =
CAM_REQ_MGR_ERROR_TYPE_PAGE_FAULT;
req_msg.u.err_msg.link_hdl = ctx->link_hdl;
req_msg.u.err_msg.request_id = 0;
req_msg.u.err_msg.resource_size = 0x0;
if (cam_req_mgr_notify_message(&req_msg,
V4L_EVENT_CAM_REQ_MGR_ERROR,
V4L_EVENT_CAM_REQ_MGR_EVENT))
CAM_ERR(CAM_ISP,
"could not send page fault notification ctx %u session_hdl:%d device_hdl:%d link_hdl:%d",
ctx->ctx_id, ctx->session_hdl,
ctx->dev_hdl, ctx->link_hdl);
}
return rc;
}

View File

@@ -22,23 +22,20 @@
static struct cam_isp_dev g_isp_dev;
static void cam_isp_dev_iommu_fault_handler(
struct iommu_domain *domain, struct device *dev, unsigned long iova,
int flags, void *token, uint32_t buf_info)
static void cam_isp_dev_iommu_fault_handler(struct cam_smmu_pf_info *pf_info)
{
int i = 0;
struct cam_node *node = NULL;
if (!token) {
if (!pf_info || !pf_info->token) {
CAM_ERR(CAM_ISP, "invalid token in page handler cb");
return;
}
node = (struct cam_node *)token;
node = (struct cam_node *)pf_info->token;
for (i = 0; i < node->ctx_size; i++)
cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
buf_info);
cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
}
static const struct of_device_id cam_isp_dt_match[] = {

View File

@@ -1527,7 +1527,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_src(
continue;
hw_intf = ife_hw_mgr->ife_devices[
csid_res->hw_res[i]->hw_intf->hw_idx];
csid_res->hw_res[i]->hw_intf->hw_idx]->hw_intf;
if (i == CAM_ISP_HW_SPLIT_LEFT &&
ife_src_res->is_dual_isp) {
@@ -2348,7 +2348,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_bus_rd(
if (!ife_hw_mgr->ife_devices[j])
continue;
hw_intf = ife_hw_mgr->ife_devices[j];
hw_intf = ife_hw_mgr->ife_devices[j]->hw_intf;
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
&vfe_acquire, sizeof(struct cam_vfe_acquire_args));
@@ -2379,7 +2379,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_bus_rd(
if (j == ife_bus_rd_res->hw_res[i]->hw_intf->hw_idx)
continue;
hw_intf = ife_hw_mgr->ife_devices[j];
hw_intf = ife_hw_mgr->ife_devices[j]->hw_intf;
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
&vfe_acquire,
sizeof(struct cam_vfe_acquire_args));
@@ -2463,7 +2463,7 @@ static int cam_ife_hw_mgr_acquire_offline_res_ife_camif(
vfe_acquire.vfe_in.sync_mode = CAM_ISP_HW_SYNC_NONE;
hw_intf = ife_hw_mgr->ife_devices[
ife_bus_rd_res->hw_res[i]->hw_intf->hw_idx];
ife_bus_rd_res->hw_res[i]->hw_intf->hw_idx]->hw_intf;
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &vfe_acquire,
sizeof(struct cam_vfe_acquire_args));
@@ -2493,7 +2493,7 @@ static int cam_ife_hw_mgr_acquire_offline_res_ife_camif(
vfe_acquire.vfe_in.sync_mode = CAM_ISP_HW_SYNC_SLAVE;
hw_intf = ife_hw_mgr->ife_devices[
ife_bus_rd_res->hw_res[++i]->hw_intf->hw_idx];
ife_bus_rd_res->hw_res[++i]->hw_intf->hw_idx]->hw_intf;
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &vfe_acquire,
sizeof(struct cam_vfe_acquire_args));
@@ -4163,10 +4163,10 @@ static int cam_ife_mgr_reset_vfe_hw(struct cam_ife_hw_mgr *hw_mgr,
if (!hw_mgr->ife_devices[i])
continue;
if (hw_idx != hw_mgr->ife_devices[i]->hw_idx)
if (hw_idx != hw_mgr->ife_devices[i]->hw_intf->hw_idx)
continue;
CAM_DBG(CAM_ISP, "VFE (id = %d) reset", hw_idx);
vfe_hw_intf = hw_mgr->ife_devices[i];
vfe_hw_intf = hw_mgr->ife_devices[i]->hw_intf;
vfe_hw_intf->hw_ops.reset(vfe_hw_intf->hw_priv,
&vfe_reset_type, sizeof(vfe_reset_type));
break;
@@ -4188,12 +4188,15 @@ static int cam_ife_mgr_unmask_bus_wr_irq(struct cam_ife_hw_mgr *hw_mgr,
}
for (i = 0; i < CAM_VFE_HW_NUM_MAX; i++) {
if (hw_idx != hw_mgr->ife_devices[i]->hw_idx)
if (!hw_mgr->ife_devices[i])
continue;
if (hw_idx != hw_mgr->ife_devices[i]->hw_intf->hw_idx)
continue;
CAM_DBG(CAM_ISP, "Unmask VFE:%d BUS_WR IRQ", hw_idx);
vfe_hw_intf = hw_mgr->ife_devices[i];
vfe_hw_intf = hw_mgr->ife_devices[i]->hw_intf;
vfe_hw_intf->hw_ops.process_cmd(vfe_hw_intf->hw_priv,
CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ,
@@ -4632,6 +4635,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
ctx->dsp_enabled = false;
ctx->is_fe_enabled = false;
ctx->is_offline = false;
ctx->pf_mid_found = false;
atomic_set(&ctx->overflow_pending, 0);
for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
ctx->sof_cnt[i] = 0;
@@ -6421,42 +6425,43 @@ static int cam_ife_mgr_sof_irq_debug(
return rc;
}
static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet,
int32_t iommu_hdl, int32_t sec_mmu_hdl, uint32_t pf_buf_info,
bool *mem_found)
static void cam_ife_mgr_print_io_bufs(struct cam_ife_hw_mgr *hw_mgr,
uint32_t res_id, struct cam_packet *packet,
bool *ctx_found, struct cam_ife_hw_mgr_ctx *ctx)
{
dma_addr_t iova_addr;
size_t src_buf_size;
int i;
int j;
int rc = 0;
int32_t mmu_hdl;
struct cam_buf_io_cfg *io_cfg = NULL;
int32_t mmu_hdl, iommu_hdl, sec_mmu_hdl;
dma_addr_t iova_addr;
size_t src_buf_size;
int i, j, rc = 0;
if (mem_found)
*mem_found = false;
iommu_hdl = hw_mgr->mgr_common.img_iommu_hdl;
sec_mmu_hdl = hw_mgr->mgr_common.img_iommu_hdl_secure;
io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload +
packet->io_configs_offset / 4);
for (i = 0; i < packet->num_io_configs; i++) {
if (io_cfg[i].resource_type != res_id)
continue;
else
break;
}
if (i == packet->num_io_configs) {
*ctx_found = false;
CAM_ERR(CAM_ISP,
"getting io port for mid resource id failed ctx id:%d req id:%lld res id:0x%x",
ctx->ctx_index, packet->header.request_id,
res_id);
return;
}
for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
if (!io_cfg[i].mem_handle[j])
break;
if (pf_buf_info &&
GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) ==
GET_FD_FROM_HANDLE(pf_buf_info)) {
CAM_INFO(CAM_ISP,
"Found PF at port: 0x%x mem 0x%x fd: 0x%x",
io_cfg[i].resource_type,
io_cfg[i].mem_handle[j],
pf_buf_info);
if (mem_found)
*mem_found = true;
}
CAM_INFO(CAM_ISP, "port: 0x%x f: %u format: %d dir %d",
io_cfg[i].resource_type,
io_cfg[i].fence,
@@ -6476,7 +6481,6 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet,
}
if ((iova_addr & 0xFFFFFFFF) != iova_addr) {
CAM_ERR(CAM_ISP, "Invalid mapped address");
rc = -EINVAL;
continue;
}
@@ -6492,7 +6496,185 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet,
io_cfg[i].offsets[j],
io_cfg[i].mem_handle[j]);
}
}
static void cam_ife_mgr_pf_dump(uint32_t res_id,
struct cam_ife_hw_mgr_ctx *ctx)
{
struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_hw_intf *hw_intf;
struct cam_isp_hw_event_info event_info;
uint32_t res_id_out;
int i, rc = 0;
/* dump the registers */
rc = cam_ife_mgr_handle_reg_dump(ctx, ctx->reg_dump_buf_desc,
ctx->num_reg_dump_buf,
CAM_ISP_PACKET_META_REG_DUMP_ON_ERROR, NULL, false);
if (rc)
CAM_ERR(CAM_ISP,
"Reg dump on pf failed req id: %llu rc: %d",
ctx->applied_req_id, rc);
/* dump the acquire data */
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
if (!hw_mgr_res->hw_res[i])
continue;
hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
if (hw_intf && hw_intf->hw_ops.process_cmd) {
rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv,
CAM_IFE_CSID_LOG_ACQUIRE_DATA,
hw_mgr_res->hw_res[i],
sizeof(void *));
if (rc)
CAM_ERR(CAM_ISP,
"csid acquire data dump failed");
} else
CAM_ERR(CAM_ISP, "NULL hw_intf!");
}
}
event_info.res_id = res_id;
res_id_out = res_id & 0xFF;
if (res_id_out >= CAM_IFE_HW_OUT_RES_MAX) {
CAM_ERR(CAM_ISP, "Invalid out resource id :%x",
res_id);
return;
}
hw_mgr_res = &ctx->res_list_ife_out[res_id_out];
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
if (!hw_mgr_res->hw_res[i])
continue;
hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
if (hw_intf->hw_ops.process_cmd) {
rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv,
CAM_ISP_HW_CMD_DUMP_BUS_INFO,
(void *)&event_info,
sizeof(struct cam_isp_hw_event_info));
}
}
}
static void cam_ife_mgr_dump_pf_data(
struct cam_ife_hw_mgr *hw_mgr,
struct cam_hw_cmd_args *hw_cmd_args)
{
struct cam_ife_hw_mgr_ctx *ctx;
struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_isp_hw_get_cmd_update cmd_update;
struct cam_isp_hw_get_res_for_mid get_res;
struct cam_packet *packet;
uint32_t hw_id;
uint32_t *resource_type;
bool *ctx_found, hw_id_found = false;
int i, j, rc = 0;
ctx = (struct cam_ife_hw_mgr_ctx *)hw_cmd_args->ctxt_to_hw_map;
packet = hw_cmd_args->u.pf_args.pf_data.packet;
ctx_found = hw_cmd_args->u.pf_args.ctx_found;
resource_type = hw_cmd_args->u.pf_args.resource_type;
if ((*ctx_found) && (*resource_type))
goto outportlog;
if (ctx->pf_mid_found)
goto outportlog;
if (!g_ife_hw_mgr.hw_pid_support)
goto mid_check;
for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
if (!hw_mgr->ife_devices[i])
continue;
for (j = 0; j < g_ife_hw_mgr.ife_devices[i]->num_hw_pid; j++) {
if (g_ife_hw_mgr.ife_devices[i]->hw_pid[j] ==
hw_cmd_args->u.pf_args.pid) {
hw_id_found = true;
hw_id = i;
break;
}
}
if (hw_id_found)
break;
}
if (i == CAM_IFE_HW_NUM_MAX) {
CAM_INFO(CAM_ISP,
"PID:%d is not matching with any IFE HW PIDs ctx id:%d",
hw_cmd_args->u.pf_args.pid, ctx->ctx_index);
return;
}
for (i = 0; i < ctx->num_base; i++) {
if (ctx->base[i].idx == hw_id) {
*ctx_found = true;
break;
}
}
if (!(*ctx_found)) {
CAM_INFO(CAM_ISP,
"This context does not cause pf:pid:%d hw id:%d ctx_id:%d",
hw_cmd_args->u.pf_args.pid, hw_id, ctx->ctx_index);
return;
}
mid_check:
for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) {
hw_mgr_res = &ctx->res_list_ife_out[i];
if (!hw_mgr_res->hw_res[0])
continue;
break;
}
if (i >= CAM_IFE_HW_OUT_RES_MAX) {
CAM_ERR(CAM_ISP,
"NO valid outport resources ctx id:%d req id:%lld",
ctx->ctx_index, packet->header.request_id);
return;
}
get_res.mid = hw_cmd_args->u.pf_args.mid;
cmd_update.res = hw_mgr_res->hw_res[0];
cmd_update.cmd_type = CAM_ISP_HW_CMD_GET_RES_FOR_MID;
cmd_update.data = (void *) &get_res;
/* get resource id for given mid */
rc = hw_mgr_res->hw_res[0]->hw_intf->hw_ops.process_cmd(
hw_mgr_res->hw_res[0]->hw_intf->hw_priv,
cmd_update.cmd_type, &cmd_update,
sizeof(struct cam_isp_hw_get_cmd_update));
if (rc) {
CAM_ERR(CAM_ISP,
"getting mid port resource id failed ctx id:%d req id:%lld",
ctx->ctx_index, packet->header.request_id);
return;
}
CAM_ERR(CAM_ISP,
"Page fault on resource id:(0x%x) ctx id:%d req id:%lld",
get_res.out_res_id, ctx->ctx_index, packet->header.request_id);
*resource_type = get_res.out_res_id;
ctx->pf_mid_found = true;
cam_ife_mgr_pf_dump(get_res.out_res_id, ctx);
outportlog:
cam_ife_mgr_print_io_bufs(hw_mgr, *resource_type, packet,
ctx_found, ctx);
}
static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
@@ -6567,12 +6749,8 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
}
break;
case CAM_HW_MGR_CMD_DUMP_PF_INFO:
cam_ife_mgr_print_io_bufs(
hw_cmd_args->u.pf_args.pf_data.packet,
hw_mgr->mgr_common.img_iommu_hdl,
hw_mgr->mgr_common.img_iommu_hdl_secure,
hw_cmd_args->u.pf_args.buf_info,
hw_cmd_args->u.pf_args.mem_found);
cam_ife_mgr_dump_pf_data(hw_mgr, hw_cmd_args);
break;
case CAM_HW_MGR_CMD_REG_DUMP_ON_FLUSH:
if (ctx->last_dump_flush_req_id == ctx->applied_req_id)
@@ -7548,9 +7726,9 @@ static int cam_ife_hw_mgr_sort_dev_with_caps(
for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
if (!ife_hw_mgr->ife_devices[i])
continue;
if (ife_hw_mgr->ife_devices[i]->hw_ops.get_hw_caps) {
ife_hw_mgr->ife_devices[i]->hw_ops.get_hw_caps(
ife_hw_mgr->ife_devices[i]->hw_priv,
if (ife_hw_mgr->ife_devices[i]->hw_intf->hw_ops.get_hw_caps) {
ife_hw_mgr->ife_devices[i]->hw_intf->hw_ops.get_hw_caps(
ife_hw_mgr->ife_devices[i]->hw_intf->hw_priv,
&ife_hw_mgr->ife_dev_caps[i],
sizeof(ife_hw_mgr->ife_dev_caps[i]));
}
@@ -7671,7 +7849,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
rc = cam_vfe_hw_init(&g_ife_hw_mgr.ife_devices[i], i);
if (!rc) {
struct cam_hw_intf *ife_device =
g_ife_hw_mgr.ife_devices[i];
g_ife_hw_mgr.ife_devices[i]->hw_intf;
struct cam_hw_info *vfe_hw =
(struct cam_hw_info *)
ife_device->hw_priv;
@@ -7690,6 +7868,10 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
"reg_map: mem base = %pK cam_base = 0x%llx",
(void __iomem *)soc_info->reg_map[0].mem_base,
(uint64_t) soc_info->reg_map[0].mem_cam_base);
if (g_ife_hw_mgr.ife_devices[i]->num_hw_pid)
g_ife_hw_mgr.hw_pid_support = true;
} else {
g_ife_hw_mgr.cdm_reg_map[i] = NULL;
}

View File

@@ -99,6 +99,7 @@ struct cam_ife_hw_mgr_debug {
* @dsp_enabled Indicate whether dsp is enabled in this context
* @hw_enabled Array to indicate active HW
* @internal_cdm Indicate whether context uses internal CDM
* @pf_mid_found in page fault, mid found for this ctx.
*/
struct cam_ife_hw_mgr_ctx {
struct list_head list;
@@ -154,6 +155,7 @@ struct cam_ife_hw_mgr_ctx {
bool is_offline;
bool dsp_enabled;
bool internal_cdm;
bool pf_mid_found;
};
/**
@@ -172,13 +174,15 @@ struct cam_ife_hw_mgr_ctx {
* @ife_dev_caps ife device capability per core
* @work q work queue for IFE hw manager
* @debug_cfg debug configuration
* @ctx_lock context lock
* @support_consumed_addr indicate whether hw supports last consumed address
* @hw_pid_support hw pid support for this target
*/
struct cam_ife_hw_mgr {
struct cam_isp_hw_mgr mgr_common;
struct cam_hw_intf *tpg_devices[CAM_TOP_TPG_HW_NUM_MAX];
struct cam_hw_intf *csid_devices[CAM_IFE_CSID_HW_NUM_MAX];
struct cam_hw_intf *ife_devices[CAM_IFE_HW_NUM_MAX];
struct cam_isp_hw_intf_data *ife_devices[CAM_IFE_HW_NUM_MAX];
struct cam_soc_reg_map *cdm_reg_map[CAM_IFE_HW_NUM_MAX];
struct mutex ctx_mutex;
@@ -194,6 +198,7 @@ struct cam_ife_hw_mgr {
struct cam_ife_hw_mgr_debug debug_cfg;
spinlock_t ctx_lock;
bool support_consumed_addr;
bool hw_pid_support;
};
/**

View File

@@ -4118,6 +4118,55 @@ static int cam_ife_csid_dump_hw(
return 0;
}
static int cam_ife_csid_log_acquire_data(
struct cam_ife_csid_hw *csid_hw, void *cmd_args)
{
struct cam_isp_resource_node *res =
(struct cam_isp_resource_node *)cmd_args;
struct cam_ife_csid_path_cfg *path_data;
struct cam_hw_soc_info *soc_info;
const struct cam_ife_csid_reg_offset *csid_reg;
const struct cam_ife_csid_rdi_reg_offset *rdi_reg;
uint32_t byte_cnt_ping, byte_cnt_pong;
path_data = (struct cam_ife_csid_path_cfg *)res->res_priv;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
if (res->res_state <= CAM_ISP_RESOURCE_STATE_AVAILABLE) {
CAM_ERR(CAM_ISP,
"CSID:%d invalid res id:%d res type: %d state:%d",
csid_hw->hw_intf->hw_idx, res->res_id, res->res_type,
res->res_state);
return -EINVAL;
}
/* Dump all the acquire data for this hardware */
CAM_INFO(CAM_ISP,
"CSID:%d res id:%d type:%d state:%d in f:%d out f:%d st pix:%d end pix:%d st line:%d end line:%d h bin:%d qcfa bin:%d",
csid_hw->hw_intf->hw_idx, res->res_id, res->res_type,
res->res_type, path_data->in_format, path_data->out_format,
path_data->start_pixel, path_data->end_pixel,
path_data->start_line, path_data->end_line,
path_data->horizontal_bin, path_data->qcfa_bin);
if (res->res_id >= CAM_IFE_PIX_PATH_RES_RDI_0 &&
res->res_id <= CAM_IFE_PIX_PATH_RES_RDI_3) {
rdi_reg = csid_reg->rdi_reg[res->res_id];
/* read total number of bytes transmitted through RDI */
byte_cnt_ping = cam_io_r_mb(soc_info->reg_map[0].mem_base +
rdi_reg->csid_rdi_byte_cntr_ping_addr);
byte_cnt_pong = cam_io_r_mb(soc_info->reg_map[0].mem_base +
rdi_reg->csid_rdi_byte_cntr_pong_addr);
CAM_INFO(CAM_ISP,
"CSID:%d res id:%d byte cnt val ping:%d pong:%d",
csid_hw->hw_intf->hw_idx, res->res_id,
byte_cnt_ping, byte_cnt_pong);
}
return 0;
}
static int cam_ife_csid_process_cmd(void *hw_priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
@@ -4164,6 +4213,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv,
case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG:
rc = cam_ife_csid_set_sensor_dimension(csid_hw, cmd_args);
break;
case CAM_IFE_CSID_LOG_ACQUIRE_DATA:
rc = cam_ife_csid_log_acquire_data(csid_hw, cmd_args);
break;
default:
CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
csid_hw->hw_intf->hw_idx, cmd_type);

View File

@@ -212,6 +212,7 @@ enum cam_ife_csid_cmd_type {
CAM_IFE_CSID_SOF_IRQ_DEBUG,
CAM_IFE_CSID_SET_CONFIG,
CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG,
CAM_IFE_CSID_LOG_ACQUIRE_DATA,
CAM_IFE_CSID_CMD_MAX,
};

View File

@@ -15,6 +15,8 @@
/* Maximum length of tag while dumping */
#define CAM_ISP_HW_DUMP_TAG_MAX_LEN 32
/* Max isp hw pid values number */
#define CAM_ISP_HW_MAX_PID_VAL 4
/*
* struct cam_isp_timestamp:
*
@@ -121,6 +123,7 @@ enum cam_isp_hw_cmd_type {
CAM_ISP_HW_CMD_FE_TRIGGER_CMD,
CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ,
CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT,
CAM_ISP_HW_CMD_GET_RES_FOR_MID,
CAM_ISP_HW_CMD_MAX,
};
@@ -233,6 +236,20 @@ struct cam_isp_hw_get_wm_update {
struct cam_buf_io_cfg *io_cfg;
};
/*
* struct cam_isp_hw_get_res_for_mid:
*
* @Brief: Get the out resource id for given mid
*
* @mid: Mid number of hw outport numb
* @out_res_id: Out resource id
*
*/
struct cam_isp_hw_get_res_for_mid {
uint32_t mid;
uint32_t out_res_id;
};
/*
* struct cam_isp_hw_get_cmd_update:
*
@@ -308,4 +325,19 @@ struct cam_isp_hw_dump_header {
uint32_t word_size;
};
/**
* struct cam_isp_hw_intf_data - ISP hw intf data
*
* @Brief: isp hw intf pointer and pid list data
*
* @isp_hw_intf: Isp hw intf pointer
* @num_hw_pid: Number of pids for this hw
* @isp_hw_pid: Isp hw pid values
*
*/
struct cam_isp_hw_intf_data {
struct cam_hw_intf *hw_intf;
uint32_t num_hw_pid;
uint32_t hw_pid[CAM_ISP_HW_MAX_PID_VAL];
};
#endif /* _CAM_ISP_HW_H_ */

View File

@@ -389,7 +389,8 @@ struct cam_vfe_generic_ubwc_config {
* successful initialization
* @hw_idx: Index of VFE HW
*/
int cam_vfe_hw_init(struct cam_hw_intf **vfe_hw, uint32_t hw_idx);
int cam_vfe_hw_init(struct cam_isp_hw_intf_data **vfe_hw,
uint32_t hw_idx);
/*
* cam_vfe_put_evt_payload()

View File

@@ -616,6 +616,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
case CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ:
case CAM_ISP_HW_CMD_DUMP_BUS_INFO:
case CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT:
case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
rc = core_info->vfe_bus->hw_ops.process_cmd(
core_info->vfe_bus->bus_priv, cmd_type, cmd_args,
arg_size);

View File

@@ -14,8 +14,7 @@
#include "cam_vfe_soc.h"
#include "cam_debug_util.h"
static struct cam_hw_intf *cam_vfe_hw_list[CAM_VFE_HW_NUM_MAX];
static struct cam_isp_hw_intf_data cam_vfe_hw_list[CAM_VFE_HW_NUM_MAX];
static char vfe_dev_name[8];
static int cam_vfe_component_bind(struct device *dev,
@@ -28,6 +27,8 @@ static int cam_vfe_component_bind(struct device *dev,
struct cam_vfe_hw_info *hw_info = NULL;
int rc = 0;
struct platform_device *pdev = to_platform_device(dev);
struct cam_vfe_soc_private *vfe_soc_priv;
uint32_t i;
vfe_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
if (!vfe_hw_intf) {
@@ -109,7 +110,13 @@ static int cam_vfe_component_bind(struct device *dev,
init_completion(&vfe_hw->hw_complete);
if (vfe_hw_intf->hw_idx < CAM_VFE_HW_NUM_MAX)
cam_vfe_hw_list[vfe_hw_intf->hw_idx] = vfe_hw_intf;
cam_vfe_hw_list[vfe_hw_intf->hw_idx].hw_intf = vfe_hw_intf;
vfe_soc_priv = vfe_hw->soc_info.soc_private;
cam_vfe_hw_list[vfe_hw_intf->hw_idx].num_hw_pid = vfe_soc_priv->num_pid;
for (i = 0; i < vfe_soc_priv->num_pid; i++)
cam_vfe_hw_list[vfe_hw_intf->hw_idx].hw_pid[i] =
vfe_soc_priv->pid[i];
cam_vfe_init_hw(vfe_hw, NULL, 0);
cam_vfe_deinit_hw(vfe_hw, NULL, 0);
@@ -150,7 +157,7 @@ static void cam_vfe_component_unbind(struct device *dev,
vfe_hw_intf->hw_type, vfe_hw_intf->hw_idx);
if (vfe_hw_intf->hw_idx < CAM_VFE_HW_NUM_MAX)
cam_vfe_hw_list[vfe_hw_intf->hw_idx] = NULL;
cam_vfe_hw_list[vfe_hw_intf->hw_idx].hw_intf = NULL;
vfe_hw = vfe_hw_intf->hw_priv;
if (!vfe_hw) {
@@ -207,15 +214,17 @@ int cam_vfe_remove(struct platform_device *pdev)
return 0;
}
int cam_vfe_hw_init(struct cam_hw_intf **vfe_hw, uint32_t hw_idx)
int cam_vfe_hw_init(struct cam_isp_hw_intf_data **vfe_hw_intf,
uint32_t hw_idx)
{
int rc = 0;
if (cam_vfe_hw_list[hw_idx]) {
*vfe_hw = cam_vfe_hw_list[hw_idx];
if (cam_vfe_hw_list[hw_idx].hw_intf) {
*vfe_hw_intf = &cam_vfe_hw_list[hw_idx];
rc = 0;
} else {
*vfe_hw = NULL;
CAM_ERR(CAM_ISP, "inval param");
*vfe_hw_intf = NULL;
rc = -ENODEV;
}
return rc;

View File

@@ -36,7 +36,7 @@ static bool cam_vfe_cpas_cb(uint32_t client_handle, void *userdata,
static int cam_vfe_get_dt_properties(struct cam_hw_soc_info *soc_info)
{
int rc = 0, num_ubwc_cfg = 0, i = 0;
int rc = 0, num_ubwc_cfg = 0, i = 0, num_pid = 0;
struct device_node *of_node = NULL;
struct platform_device *pdev = NULL;
struct cam_vfe_soc_private *vfe_soc_private;
@@ -55,7 +55,7 @@ static int cam_vfe_get_dt_properties(struct cam_hw_soc_info *soc_info)
if (strnstr(soc_info->compatible, "lite",
strlen(soc_info->compatible)) != NULL) {
vfe_soc_private->is_ife_lite = true;
goto end;
goto pid;
}
switch (soc_info->hw_version) {
@@ -69,7 +69,7 @@ static int cam_vfe_get_dt_properties(struct cam_hw_soc_info *soc_info)
CAM_ERR(CAM_ISP, "wrong num_ubwc_cfg: %d",
num_ubwc_cfg);
rc = num_ubwc_cfg;
goto end;
goto pid;
}
for (i = 0; i < num_ubwc_cfg; i++) {
@@ -86,8 +86,24 @@ static int cam_vfe_get_dt_properties(struct cam_hw_soc_info *soc_info)
default:
break;
}
pid:
/* set some default values */
vfe_soc_private->num_pid = 0;
num_pid = of_property_count_u32_elems(pdev->dev.of_node, "cam_hw_pid");
CAM_DBG(CAM_CPAS, "vfe:%d pid count %d", soc_info->index, num_pid);
if (num_pid <= 0 || num_pid > CAM_ISP_HW_MAX_PID_VAL)
goto end;
for (i = 0; i < num_pid; i++)
of_property_read_u32_index(pdev->dev.of_node, "cam_hw_pid", i,
&vfe_soc_private->pid[i]);
vfe_soc_private->num_pid = num_pid;
end:
return rc;
}

View File

@@ -25,6 +25,8 @@
* @ubwc_static_ctrl: UBWC static control configuration
* @is_ife_lite: Flag to indicate full vs lite IFE
* @ife_clk_src: IFE source clock
* @num_pid: Number of pids of ife
* @pid: IFE pid values list
*/
struct cam_vfe_soc_private {
uint32_t cpas_handle;
@@ -35,6 +37,8 @@ struct cam_vfe_soc_private {
uint32_t ubwc_static_ctrl[UBWC_STATIC_CONFIG_MAX];
bool is_ife_lite;
uint64_t ife_clk_src;
uint32_t num_pid;
uint32_t pid[CAM_ISP_HW_MAX_PID_VAL];
};
/*

View File

@@ -1176,60 +1176,77 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_3,
.mid[0] = 8,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI1,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_4,
.mid[0] = 9,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI2,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_5,
.mid[0] = 10,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_FULL,
.max_width = 4096,
.max_height = 4096,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 32,
.mid[1] = 33,
.mid[2] = 34,
.mid[3] = 35,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_DS4,
.max_width = 1920,
.max_height = 1080,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 16,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_DS16,
.max_width = 1920,
.max_height = 1080,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 17,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RAW_DUMP,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 11,
.mid[1] = 12,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_FD,
.max_width = 1920,
.max_height = 1080,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 20,
.mid[1] = 21,
.mid[2] = 22,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_PDAF,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 25,
.mid[1] = 26,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BE,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 40,
},
{
.vfe_out_type =
@@ -1237,6 +1254,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
.max_width = 1920,
.max_height = 1080,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 41,
},
{
.vfe_out_type =
@@ -1244,72 +1262,88 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 42,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_BF,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 43,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_AWB_BG,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 44,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_BHIST,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 45,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_RS,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 46,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_CS,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 47,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_IHIST,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 48,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_FULL_DISP,
.max_width = 4096,
.max_height = 4096,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 36,
.mid[1] = 37,
.mid[2] = 38,
.mid[3] = 39,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_DS4_DISP,
.max_width = 1920,
.max_height = 1080,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 18,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_DS16_DISP,
.max_width = 1920,
.max_height = 1080,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 19,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_2PD,
.max_width = 1920,
.max_height = 1080,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_1,
.mid[0] = 23,
.mid[1] = 24,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_LCR,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_2,
.mid[0] = 27,
},
},
.comp_done_shift = 6,

View File

@@ -373,24 +373,28 @@ static struct cam_vfe_bus_ver3_hw_info vfe48x_bus_hw_info = {
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_0,
.mid[0] = 16,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI1,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_1,
.mid[0] = 17,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI2,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_2,
.mid[0] = 18,
},
{
.vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI3,
.max_width = -1,
.max_height = -1,
.source_group = CAM_VFE_BUS_VER3_SRC_GRP_3,
.mid[0] = 19,
},
},
.comp_done_shift = 4,

View File

@@ -180,6 +180,7 @@ struct cam_vfe_bus_ver2_vfe_out_data {
struct cam_cdm_utils_ops *cdm_util_ops;
uint32_t secure_mode;
void *priv;
uint32_t mid[CAM_VFE_BUS_VER2_MAX_MID_PER_PORT];
};
struct cam_vfe_bus_ver2_priv {
@@ -2431,7 +2432,7 @@ static int cam_vfe_bus_init_vfe_out_resource(uint32_t index,
{
struct cam_isp_resource_node *vfe_out = NULL;
struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
int rc = 0;
int rc = 0, i;
int32_t vfe_out_type =
ver2_hw_info->vfe_out_hw_info[index].vfe_out_type;
@@ -2481,6 +2482,9 @@ static int cam_vfe_bus_init_vfe_out_resource(uint32_t index,
vfe_out->hw_intf = ver2_bus_priv->common_data.hw_intf;
vfe_out->irq_handle = 0;
for (i = 0; i < CAM_VFE_BUS_VER2_MAX_MID_PER_PORT; i++)
rsrc_data->mid[i] = ver2_hw_info->vfe_out_hw_info[index].mid[i];
return 0;
}
@@ -3576,6 +3580,50 @@ int cam_vfe_bus_dump_wm_data(void *priv, void *cmd_args, uint32_t arg_size)
return 0;
}
static int cam_vfe_bus_get_res_for_mid(
struct cam_vfe_bus_ver2_priv *bus_priv,
void *cmd_args, uint32_t arg_size)
{
struct cam_vfe_bus_ver2_vfe_out_data *out_data = NULL;
struct cam_isp_hw_get_cmd_update *cmd_update = cmd_args;
struct cam_isp_hw_get_res_for_mid *get_res = NULL;
int i, j;
get_res = (struct cam_isp_hw_get_res_for_mid *)cmd_update->data;
if (!get_res) {
CAM_ERR(CAM_ISP,
"invalid get resource for mid paramas");
return -EINVAL;
}
for (i = 0; i < bus_priv->num_out; i++) {
out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
bus_priv->vfe_out[i].res_priv;
if (!out_data)
continue;
for (j = 0; j < CAM_VFE_BUS_VER2_MAX_MID_PER_PORT; j++) {
if (out_data->mid[j] == get_res->mid)
goto end;
}
}
if (i == bus_priv->num_out) {
CAM_ERR(CAM_ISP,
"mid:%d does not match with any out resource",
get_res->mid);
get_res->out_res_id = 0;
return -EINVAL;
}
end:
CAM_INFO(CAM_ISP, "match mid :%d out resource:0x%x found",
get_res->mid, bus_priv->vfe_out[i].res_id);
get_res->out_res_id = bus_priv->vfe_out[i].res_id;
return 0;
}
static int cam_vfe_bus_process_cmd(
struct cam_isp_resource_node *priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
@@ -3636,6 +3684,10 @@ static int cam_vfe_bus_process_cmd(
*support_consumed_addr =
bus_priv->common_data.support_consumed_addr;
break;
case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
rc = cam_vfe_bus_get_res_for_mid(bus_priv, cmd_args, arg_size);
break;
default:
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
cmd_type);

View File

@@ -10,6 +10,7 @@
#include "cam_vfe_bus.h"
#define CAM_VFE_BUS_VER2_MAX_CLIENTS 24
#define CAM_VFE_BUS_VER2_MAX_MID_PER_PORT 4
enum cam_vfe_bus_ver2_vfe_core_id {
CAM_VFE_BUS_VER2_VFE_CORE_0,
@@ -167,6 +168,7 @@ struct cam_vfe_bus_ver2_vfe_out_hw_info {
enum cam_vfe_bus_ver2_vfe_out_type vfe_out_type;
uint32_t max_width;
uint32_t max_height;
uint32_t mid[CAM_VFE_BUS_VER2_MAX_MID_PER_PORT];
};
/*

View File

@@ -177,6 +177,7 @@ struct cam_vfe_bus_ver3_vfe_out_data {
struct cam_cdm_utils_ops *cdm_util_ops;
uint32_t secure_mode;
void *priv;
uint32_t mid[CAM_VFE_BUS_VER3_MAX_MID_PER_PORT];
};
struct cam_vfe_bus_ver3_priv {
@@ -2641,7 +2642,7 @@ static int cam_vfe_bus_ver3_init_vfe_out_resource(uint32_t index,
{
struct cam_isp_resource_node *vfe_out = NULL;
struct cam_vfe_bus_ver3_vfe_out_data *rsrc_data = NULL;
int rc = 0;
int rc = 0, i;
int32_t vfe_out_type =
ver3_hw_info->vfe_out_hw_info[index].vfe_out_type;
@@ -2694,6 +2695,10 @@ static int cam_vfe_bus_ver3_init_vfe_out_resource(uint32_t index,
vfe_out->hw_intf = ver3_bus_priv->common_data.hw_intf;
vfe_out->irq_handle = 0;
for (i = 0; i < CAM_VFE_BUS_VER3_MAX_MID_PER_PORT; i++)
rsrc_data->mid[i] = ver3_hw_info->vfe_out_hw_info[index].mid[i];
return 0;
}
@@ -2735,7 +2740,9 @@ static int cam_vfe_bus_ver3_print_dimensions(
struct cam_isp_resource_node *rsrc_node = NULL;
struct cam_vfe_bus_ver3_vfe_out_data *rsrc_data = NULL;
struct cam_vfe_bus_ver3_wm_resource_data *wm_data = NULL;
struct cam_vfe_bus_ver3_common_data *common_data = NULL;
int i, wm_idx;
uint32_t addr_status0, addr_status1, addr_status2, addr_status3;
rsrc_node = &bus_priv->vfe_out[vfe_out_res_id];
rsrc_data = rsrc_node->res_priv;
@@ -2748,6 +2755,16 @@ static int cam_vfe_bus_ver3_print_dimensions(
return -EINVAL;
}
wm_data = bus_priv->bus_client[wm_idx].res_priv;
common_data = rsrc_data->common_data;
addr_status0 = cam_io_r_mb(common_data->mem_base +
wm_data->hw_regs->addr_status_0);
addr_status1 = cam_io_r_mb(common_data->mem_base +
wm_data->hw_regs->addr_status_1);
addr_status2 = cam_io_r_mb(common_data->mem_base +
wm_data->hw_regs->addr_status_2);
addr_status3 = cam_io_r_mb(common_data->mem_base +
wm_data->hw_regs->addr_status_3);
CAM_INFO(CAM_ISP,
"VFE:%d WM:%d width:%u height:%u stride:%u x_init:%u en_cfg:%u acquired width:%u height:%u",
wm_data->common_data->core_index, wm_idx,
@@ -2757,6 +2774,14 @@ static int cam_vfe_bus_ver3_print_dimensions(
wm_data->en_cfg,
wm_data->acquired_width,
wm_data->acquired_height);
CAM_INFO(CAM_ISP,
"hw:%d WM:%d last consumed address:0x%x last frame addr:0x%x fifo cnt:0x%x current client address:0x%x",
common_data->hw_intf->hw_idx,
wm_data->index,
addr_status0,
addr_status1,
addr_status2,
addr_status3);
}
return 0;
}
@@ -3689,6 +3714,50 @@ static int cam_vfe_bus_ver3_deinit_hw(void *hw_priv,
return rc;
}
static int cam_vfe_bus_get_res_for_mid(
struct cam_vfe_bus_ver3_priv *bus_priv,
void *cmd_args, uint32_t arg_size)
{
struct cam_vfe_bus_ver3_vfe_out_data *out_data = NULL;
struct cam_isp_hw_get_cmd_update *cmd_update = cmd_args;
struct cam_isp_hw_get_res_for_mid *get_res = NULL;
int i, j;
get_res = (struct cam_isp_hw_get_res_for_mid *)cmd_update->data;
if (!get_res) {
CAM_ERR(CAM_ISP,
"invalid get resource for mid paramas");
return -EINVAL;
}
for (i = 0; i < bus_priv->num_out; i++) {
out_data = (struct cam_vfe_bus_ver3_vfe_out_data *)
bus_priv->vfe_out[i].res_priv;
if (!out_data)
continue;
for (j = 0; j < CAM_VFE_BUS_VER3_MAX_MID_PER_PORT; j++) {
if (out_data->mid[j] == get_res->mid)
goto end;
}
}
if (i == bus_priv->num_out) {
CAM_ERR(CAM_ISP,
"mid:%d does not match with any out resource",
get_res->mid);
get_res->out_res_id = 0;
return -EINVAL;
}
end:
CAM_INFO(CAM_ISP, "match mid :%d out resource:0x%x found",
get_res->mid, bus_priv->vfe_out[i].res_id);
get_res->out_res_id = bus_priv->vfe_out[i].res_id;
return 0;
}
static int __cam_vfe_bus_ver3_process_cmd(void *priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
@@ -3766,6 +3835,10 @@ static int cam_vfe_bus_ver3_process_cmd(
*support_consumed_addr =
bus_priv->common_data.support_consumed_addr;
break;
case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
bus_priv = (struct cam_vfe_bus_ver3_priv *) priv;
rc = cam_vfe_bus_get_res_for_mid(bus_priv, cmd_args, arg_size);
break;
default:
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
cmd_type);

View File

@@ -12,6 +12,7 @@
#define CAM_VFE_BUS_VER3_MAX_CLIENTS 26
#define CAM_VFE_BUS_VER3_MAX_SUB_GRPS 6
#define CAM_VFE_BUS_VER3_MAX_MID_PER_PORT 4
enum cam_vfe_bus_ver3_vfe_core_id {
CAM_VFE_BUS_VER3_VFE_CORE_0,
@@ -160,6 +161,7 @@ struct cam_vfe_bus_ver3_vfe_out_hw_info {
uint32_t max_width;
uint32_t max_height;
uint32_t source_group;
uint32_t mid[CAM_VFE_BUS_VER3_MAX_MID_PER_PORT];
};
/*

View File

@@ -16,17 +16,18 @@
static const char jpeg_dev_name[] = "cam-jpeg";
static int cam_jpeg_context_dump_active_request(void *data, unsigned long iova,
uint32_t buf_info)
static int cam_jpeg_context_dump_active_request(void *data,
struct cam_smmu_pf_info *pf_info)
{
struct cam_context *ctx = (struct cam_context *)data;
struct cam_ctx_request *req = NULL;
struct cam_ctx_request *req_temp = NULL;
struct cam_hw_mgr_dump_pf_data *pf_dbg_entry = NULL;
uint32_t resource_type = 0;
int rc = 0;
int closest_port;
bool b_mem_found = false;
bool b_mem_found = false, b_ctx_found = false;
if (!ctx) {
@@ -44,7 +45,7 @@ static int cam_jpeg_context_dump_active_request(void *data, unsigned long iova,
CAM_INFO(CAM_JPEG, "req_id : %lld ", req->request_id);
rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
iova, buf_info, &b_mem_found);
&b_mem_found, &b_ctx_found, &resource_type, pf_info);
if (rc)
CAM_ERR(CAM_JPEG, "Failed to dump pf info");

View File

@@ -22,22 +22,20 @@
static struct cam_jpeg_dev g_jpeg_dev;
static void cam_jpeg_dev_iommu_fault_handler(
struct iommu_domain *domain, struct device *dev, unsigned long iova,
int flags, void *token, uint32_t buf_info)
struct cam_smmu_pf_info *pf_info)
{
int i = 0;
struct cam_node *node = NULL;
if (!token) {
CAM_ERR(CAM_JPEG, "invalid token in page handler cb");
if (!pf_info || !pf_info->token) {
CAM_ERR(CAM_ISP, "invalid token in page handler cb");
return;
}
node = (struct cam_node *)token;
node = (struct cam_node *)pf_info->token;
for (i = 0; i < node->ctx_size; i++)
cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
buf_info);
cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
}
static const struct of_device_id cam_jpeg_dt_match[] = {

View File

@@ -23,15 +23,16 @@
static const char ope_dev_name[] = "cam-ope";
static int cam_ope_context_dump_active_request(void *data, unsigned long iova,
uint32_t buf_info)
static int cam_ope_context_dump_active_request(void *data,
struct cam_smmu_pf_info *pf_info)
{
struct cam_context *ctx = (struct cam_context *)data;
struct cam_ctx_request *req = NULL;
struct cam_ctx_request *req_temp = NULL;
struct cam_hw_mgr_dump_pf_data *pf_dbg_entry = NULL;
uint32_t resource_type = 0;
int rc = 0;
bool b_mem_found = false;
bool b_mem_found = false, b_ctx_found = false;
if (!ctx) {
CAM_ERR(CAM_OPE, "Invalid ctx");
@@ -54,7 +55,7 @@ static int cam_ope_context_dump_active_request(void *data, unsigned long iova,
CAM_INFO(CAM_OPE, "req_id : %lld", req->request_id);
rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
iova, buf_info, &b_mem_found);
&b_mem_found, &b_ctx_found, &resource_type, pf_info);
if (rc)
CAM_ERR(CAM_OPE, "Failed to dump pf info");

View File

@@ -46,22 +46,20 @@ struct cam_ope_subdev {
static struct cam_ope_subdev g_ope_dev;
static void cam_ope_dev_iommu_fault_handler(
struct iommu_domain *domain, struct device *dev, unsigned long iova,
int flags, void *token, uint32_t buf_info)
struct cam_smmu_pf_info *pf_info)
{
int i = 0;
struct cam_node *node = NULL;
if (!token) {
CAM_ERR(CAM_OPE, "invalid token in page handler cb");
if (!pf_info || !pf_info->token) {
CAM_ERR(CAM_ISP, "invalid token in page handler cb");
return;
}
node = (struct cam_node *)token;
node = (struct cam_node *)pf_info->token;
for (i = 0; i < node->ctx_size; i++)
cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
buf_info);
cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
}
static int cam_ope_subdev_open(struct v4l2_subdev *sd,

View File

@@ -47,7 +47,7 @@
div_u64_rem(atomic64_add_return(1, head),\
CAM_SMMU_MONITOR_MAX_ENTRIES, (ret))
static int g_num_pf_handled = 4;
static int g_num_pf_handled = 1;
module_param(g_num_pf_handled, int, 0644);
struct cam_fw_alloc_info icp_fw;
@@ -145,7 +145,7 @@ struct cam_context_bank_info {
int handle;
enum cam_smmu_ops_param state;
cam_smmu_client_page_fault_handler handler[CAM_SMMU_CB_MAX];
void (*handler[CAM_SMMU_CB_MAX]) (struct cam_smmu_pf_info *pf_info);
void *token[CAM_SMMU_CB_MAX];
int cb_count;
int secure_count;
@@ -363,6 +363,8 @@ static void cam_smmu_page_fault_work(struct work_struct *work)
int idx;
struct cam_smmu_work_payload *payload;
uint32_t buf_info;
struct iommu_fault_ids fault_ids = {0, 0, 0};
struct cam_smmu_pf_info pf_info;
mutex_lock(&iommu_cb_set.payload_list_lock);
if (list_empty(&iommu_cb_set.payload_list)) {
@@ -377,21 +379,33 @@ static void cam_smmu_page_fault_work(struct work_struct *work)
list_del(&payload->list);
mutex_unlock(&iommu_cb_set.payload_list_lock);
if ((iommu_get_fault_ids(payload->domain, &fault_ids)))
CAM_ERR(CAM_SMMU,
"Error: Can not get smmu fault ids");
CAM_ERR(CAM_SMMU, "smmu fault ids bid:%d pid:%d mid:%d",
fault_ids.bid, fault_ids.pid, fault_ids.mid);
/* Dereference the payload to call the handler */
idx = payload->idx;
buf_info = cam_smmu_find_closest_mapping(idx, (void *)payload->iova);
if (buf_info != 0)
CAM_INFO(CAM_SMMU, "closest buf 0x%x idx %d", buf_info, idx);
pf_info.domain = payload->domain;
pf_info.dev = payload->dev;
pf_info.iova = payload->iova;
pf_info.flags = payload->flags;
pf_info.buf_info = buf_info;
pf_info.bid = fault_ids.bid;
pf_info.pid = fault_ids.pid;
pf_info.mid = fault_ids.mid;
for (j = 0; j < CAM_SMMU_CB_MAX; j++) {
if ((iommu_cb_set.cb_info[idx].handler[j])) {
iommu_cb_set.cb_info[idx].handler[j](
payload->domain,
payload->dev,
payload->iova,
payload->flags,
iommu_cb_set.cb_info[idx].token[j],
buf_info);
pf_info.token = iommu_cb_set.cb_info[idx].token[j];
iommu_cb_set.cb_info[idx].handler[j](&pf_info);
}
}
cam_smmu_dump_cb_info(idx);
@@ -565,7 +579,7 @@ end:
}
void cam_smmu_set_client_page_fault_handler(int handle,
cam_smmu_client_page_fault_handler handler_cb, void *token)
void (*handler_cb)(struct cam_smmu_pf_info *pf_info), void *token)
{
int idx, i = 0;
@@ -726,6 +740,15 @@ static int cam_smmu_iommu_fault_handler(struct iommu_domain *domain,
return -EINVAL;
}
void cam_smmu_reset_cb_page_fault_cnt(void)
{
int idx;
for (idx = 0; idx < iommu_cb_set.cb_num; idx++)
iommu_cb_set.cb_info[idx].pf_count = 0;
}
static int cam_smmu_translate_dir_to_iommu_dir(
enum cam_smmu_map_dir dir)
{

View File

@@ -43,8 +43,7 @@ enum cam_smmu_region_id {
};
/**
* @brief : Callback function type that gets called back on cam
* smmu page fault.
* @brief : cam_smmu_pf_info
*
* @param domain : Iommu domain received in iommu page fault handler
* @param dev : Device received in iommu page fault handler
@@ -52,10 +51,22 @@ enum cam_smmu_region_id {
* @param flags : Flags received in iommu page fault handler
* @param token : Userdata given during callback registration
* @param buf_info : Closest mapped buffer info
* @bid : bus id
* @pid : unique id for hw group of ports
* @mid : port id of hw
*/
typedef void (*cam_smmu_client_page_fault_handler)(struct iommu_domain *domain,
struct device *dev, unsigned long iova, int flags, void *token,
uint32_t buf_info);
struct cam_smmu_pf_info {
struct iommu_domain *domain;
struct device *dev;
unsigned long iova;
int flags;
void *token;
uint32_t buf_info;
uint32_t bid;
uint32_t pid;
uint32_t mid;
};
/**
* @brief : Structure to store region information
@@ -234,7 +245,7 @@ int cam_smmu_find_index_by_handle(int hdl);
* @param token: It is input param when trigger page fault handler
*/
void cam_smmu_set_client_page_fault_handler(int handle,
cam_smmu_client_page_fault_handler handler_cb, void *token);
void (*handler_cb)(struct cam_smmu_pf_info *pf_info), void *token);
/**
* @brief : Unregisters smmu fault handler for client
@@ -403,6 +414,13 @@ int cam_smmu_get_io_region_info(int32_t smmu_hdl,
dma_addr_t *iova, size_t *len,
dma_addr_t *discard_iova_start, size_t *discard_iova_len);
/**
* @brief : API to reset the call context bank page fault count
* This should be done on the starting of new camera open
* @return void.
*/
void cam_smmu_reset_cb_page_fault_cnt(void);
/**
* @brief : API to register SMMU hw to platform framework.
* @return struct platform_device pointer on on success, or ERR_PTR() on error.
@@ -413,4 +431,5 @@ int cam_smmu_init_module(void);
* @brief : API to remove SMMU Hw from platform framework.
*/
void cam_smmu_exit_module(void);
#endif /* _CAM_SMMU_API_H_ */

View File

@@ -424,6 +424,7 @@ struct cam_mem_cache_ops_cmd {
* @CAM_REQ_MGR_ERROR_TYPE_BUFFER: Buffer was not filled, not fatal
* @CAM_REQ_MGR_ERROR_TYPE_RECOVERY: Fatal error, can be recovered
* @CAM_REQ_MGR_ERROR_TYPE_SOF_FREEZE: SOF freeze, can be recovered
* @CAM_REQ_MGR_ERROR_TYPE_PAGE_FAULT: page fault, can be recovered
*/
#define CAM_REQ_MGR_ERROR_TYPE_DEVICE 0
#define CAM_REQ_MGR_ERROR_TYPE_REQUEST 1
@@ -431,7 +432,7 @@ struct cam_mem_cache_ops_cmd {
#define CAM_REQ_MGR_ERROR_TYPE_RECOVERY 3
#define CAM_REQ_MGR_ERROR_TYPE_SOF_FREEZE 4
#define CAM_REQ_MGR_ERROR_TYPE_FULL_RECOVERY 5
#define CAM_REQ_MGR_ERROR_TYPE_PAGE_FAULT 6
/**
* struct cam_req_mgr_error_msg