Merge "msm: camera: ope: Handle OPE smmu fault with pid info" into camera-kernel.lnx.5.0
This commit is contained in:

کامیت شده توسط
Gerrit - the friendly Code Review server

کامیت
1ee4bca76c
@@ -54,7 +54,7 @@ static int cam_ope_context_dump_active_request(void *data,
|
||||
pf_dbg_entry = &(req->pf_data);
|
||||
CAM_INFO(CAM_OPE, "req_id : %lld", req->request_id);
|
||||
|
||||
rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
|
||||
rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry,
|
||||
&b_mem_found, &b_ctx_found, &resource_type, pf_info);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_OPE, "Failed to dump pf info");
|
||||
|
@@ -46,6 +46,9 @@ static struct cam_ope_hw_mgr *ope_hw_mgr;
|
||||
|
||||
static int cam_ope_req_timer_reset(struct cam_ope_ctx *ctx_data);
|
||||
|
||||
static void cam_ope_mgr_dump_pf_data(struct cam_ope_hw_mgr *hw_mgr,
|
||||
struct cam_hw_cmd_args *hw_cmd_args);
|
||||
|
||||
static int cam_ope_mgr_get_rsc_idx(struct cam_ope_ctx *ctx_data,
|
||||
struct ope_io_buf_info *in_io_buf)
|
||||
{
|
||||
@@ -1768,7 +1771,6 @@ static int cam_ope_mgr_process_io_cfg(struct cam_ope_hw_mgr *hw_mgr,
|
||||
struct cam_hw_prepare_update_args *prep_arg,
|
||||
struct cam_ope_ctx *ctx_data, uint32_t req_idx)
|
||||
{
|
||||
|
||||
int i, j = 0, k = 0, l, rc = 0;
|
||||
struct ope_io_buf *io_buf;
|
||||
int32_t sync_in_obj[CAM_MAX_IN_RES];
|
||||
@@ -2725,7 +2727,7 @@ static int cam_ope_mgr_acquire_hw(void *hw_priv, void *hw_acquire_args)
|
||||
|
||||
bw_update = kzalloc(sizeof(struct cam_ope_dev_bw_update), GFP_KERNEL);
|
||||
if (!bw_update) {
|
||||
CAM_ERR(CAM_ISP, "Out of memory");
|
||||
CAM_ERR(CAM_OPE, "Out of memory");
|
||||
goto ope_clk_update_failed;
|
||||
}
|
||||
bw_update->ahb_vote_valid = false;
|
||||
@@ -3282,6 +3284,8 @@ static int cam_ope_mgr_prepare_hw_update(void *hw_priv,
|
||||
(uintptr_t)ctx_data->req_list[request_idx]->cdm_cmd;
|
||||
prepare_args->priv = ctx_data->req_list[request_idx];
|
||||
prepare_args->pf_data->packet = packet;
|
||||
prepare_args->pf_data->req = ope_req;
|
||||
CAM_INFO(CAM_REQ, "OPE req %x num_batch %d", ope_req, ope_req->num_batch);
|
||||
ope_req->hang_data.packet = packet;
|
||||
ktime_get_boottime_ts64(&ts);
|
||||
ctx_data->last_req_time = (uint64_t)((ts.tv_sec * 1000000000) +
|
||||
@@ -3434,84 +3438,6 @@ config_err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void cam_ope_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)
|
||||
{
|
||||
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;
|
||||
|
||||
if (mem_found)
|
||||
*mem_found = false;
|
||||
|
||||
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++) {
|
||||
for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
|
||||
if (!io_cfg[i].mem_handle[j])
|
||||
break;
|
||||
|
||||
if (GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) ==
|
||||
GET_FD_FROM_HANDLE(pf_buf_info)) {
|
||||
CAM_INFO(CAM_OPE,
|
||||
"Found PF at port: %d mem %x fd: %x",
|
||||
io_cfg[i].resource_type,
|
||||
io_cfg[i].mem_handle[j],
|
||||
pf_buf_info);
|
||||
if (mem_found)
|
||||
*mem_found = true;
|
||||
}
|
||||
|
||||
CAM_INFO(CAM_OPE, "port: %d f: %u format: %d dir %d",
|
||||
io_cfg[i].resource_type,
|
||||
io_cfg[i].fence,
|
||||
io_cfg[i].format,
|
||||
io_cfg[i].direction);
|
||||
|
||||
mmu_hdl = cam_mem_is_secure_buf(
|
||||
io_cfg[i].mem_handle[j]) ? sec_mmu_hdl :
|
||||
iommu_hdl;
|
||||
rc = cam_mem_get_io_buf(io_cfg[i].mem_handle[j],
|
||||
mmu_hdl, &iova_addr, &src_buf_size);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_UTIL,
|
||||
"get src buf address fail rc %d mem %x",
|
||||
rc, io_cfg[i].mem_handle[j]);
|
||||
continue;
|
||||
}
|
||||
if ((iova_addr & 0xFFFFFFFF) != iova_addr) {
|
||||
CAM_ERR(CAM_OPE, "Invalid mapped address");
|
||||
rc = -EINVAL;
|
||||
continue;
|
||||
}
|
||||
|
||||
CAM_INFO(CAM_OPE,
|
||||
"pln %d dir %d w %d h %d s %u sh %u sz %d addr 0x%x off 0x%x memh %x",
|
||||
j, io_cfg[i].direction,
|
||||
io_cfg[i].planes[j].width,
|
||||
io_cfg[i].planes[j].height,
|
||||
io_cfg[i].planes[j].plane_stride,
|
||||
io_cfg[i].planes[j].slice_height,
|
||||
(int32_t)src_buf_size,
|
||||
(unsigned int)iova_addr,
|
||||
io_cfg[i].offsets[j],
|
||||
io_cfg[i].mem_handle[j]);
|
||||
|
||||
iova_addr += io_cfg[i].offsets[j];
|
||||
|
||||
}
|
||||
}
|
||||
cam_packet_dump_patch_info(packet, ope_hw_mgr->iommu_hdl,
|
||||
ope_hw_mgr->iommu_sec_hdl);
|
||||
}
|
||||
|
||||
static int cam_ope_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
|
||||
{
|
||||
int rc = 0;
|
||||
@@ -3525,16 +3451,11 @@ static int cam_ope_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
|
||||
|
||||
switch (hw_cmd_args->cmd_type) {
|
||||
case CAM_HW_MGR_CMD_DUMP_PF_INFO:
|
||||
cam_ope_mgr_print_io_bufs(
|
||||
hw_cmd_args->u.pf_args.pf_data.packet,
|
||||
hw_mgr->iommu_hdl,
|
||||
hw_mgr->iommu_sec_hdl,
|
||||
hw_cmd_args->u.pf_args.buf_info,
|
||||
hw_cmd_args->u.pf_args.mem_found);
|
||||
|
||||
cam_ope_mgr_dump_pf_data(hw_mgr, hw_cmd_args);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_OPE, "Invalid cmd");
|
||||
CAM_ERR(CAM_OPE, "Invalid cmd: %d",
|
||||
hw_cmd_args->cmd_type);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -3855,13 +3776,14 @@ static int cam_ope_mgr_init_devs(struct device_node *of_node)
|
||||
}
|
||||
|
||||
ope_hw_mgr->num_ope = count;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
ope_hw_mgr->ope_dev_intf[i] =
|
||||
ope_hw_mgr->devices[OPE_DEV_OPE][i];
|
||||
ope_dev = ope_hw_mgr->ope_dev_intf[i]->hw_priv;
|
||||
soc_info = &ope_dev->soc_info;
|
||||
ope_hw_mgr->cdm_reg_map[i][0] =
|
||||
soc_info->reg_map[0].mem_base;
|
||||
ope_dev = ope_hw_mgr->ope_dev_intf[i]->hw_priv;
|
||||
soc_info = &ope_dev->soc_info;
|
||||
ope_hw_mgr->cdm_reg_map[i][0] =
|
||||
soc_info->reg_map[0].mem_base;
|
||||
}
|
||||
|
||||
ope_hw_mgr->hfi_en = of_property_read_bool(of_node, "hfi_en");
|
||||
@@ -4028,20 +3950,20 @@ int cam_ope_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
|
||||
|
||||
hw_mgr_intf->hw_mgr_priv = ope_hw_mgr;
|
||||
hw_mgr_intf->hw_get_caps = cam_ope_mgr_get_hw_caps;
|
||||
hw_mgr_intf->hw_acquire = cam_ope_mgr_acquire_hw;
|
||||
hw_mgr_intf->hw_release = cam_ope_mgr_release_hw;
|
||||
hw_mgr_intf->hw_start = NULL;
|
||||
hw_mgr_intf->hw_stop = NULL;
|
||||
hw_mgr_intf->hw_acquire = cam_ope_mgr_acquire_hw;
|
||||
hw_mgr_intf->hw_release = cam_ope_mgr_release_hw;
|
||||
hw_mgr_intf->hw_start = NULL;
|
||||
hw_mgr_intf->hw_stop = NULL;
|
||||
hw_mgr_intf->hw_prepare_update = cam_ope_mgr_prepare_hw_update;
|
||||
hw_mgr_intf->hw_config_stream_settings = NULL;
|
||||
hw_mgr_intf->hw_config = cam_ope_mgr_config_hw;
|
||||
hw_mgr_intf->hw_read = NULL;
|
||||
hw_mgr_intf->hw_write = NULL;
|
||||
hw_mgr_intf->hw_cmd = cam_ope_mgr_cmd;
|
||||
hw_mgr_intf->hw_open = cam_ope_mgr_hw_open_u;
|
||||
hw_mgr_intf->hw_close = cam_ope_mgr_hw_close_u;
|
||||
hw_mgr_intf->hw_flush = cam_ope_mgr_hw_flush;
|
||||
hw_mgr_intf->hw_dump = cam_ope_mgr_hw_dump;
|
||||
hw_mgr_intf->hw_cmd = cam_ope_mgr_cmd;
|
||||
hw_mgr_intf->hw_open = cam_ope_mgr_hw_open_u;
|
||||
hw_mgr_intf->hw_close = cam_ope_mgr_hw_close_u;
|
||||
hw_mgr_intf->hw_flush = cam_ope_mgr_hw_flush;
|
||||
hw_mgr_intf->hw_dump = cam_ope_mgr_hw_dump;
|
||||
|
||||
ope_hw_mgr->secure_mode = false;
|
||||
mutex_init(&ope_hw_mgr->hw_mgr_mutex);
|
||||
@@ -4080,6 +4002,12 @@ int cam_ope_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
|
||||
ope_hw_mgr->ctx_bits = ope_hw_mgr->ctx_bitmap_size *
|
||||
BITS_PER_BYTE;
|
||||
|
||||
for (i = 0; i < OPE_DEV_MAX; i++) {
|
||||
rc = cam_ope_hw_init(&ope_hw_mgr->ope_dev_data[i], i);
|
||||
if (rc)
|
||||
goto ctx_bitmap_alloc_failed;
|
||||
}
|
||||
|
||||
rc = cam_smmu_get_handle("ope", &ope_hw_mgr->iommu_hdl);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_OPE, "get mmu handle failed: %d", rc);
|
||||
@@ -4149,3 +4077,167 @@ ope_ctx_bitmap_failed:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void cam_ope_mgr_dump_pf_data(
|
||||
struct cam_ope_hw_mgr *hw_mgr,
|
||||
struct cam_hw_cmd_args *hw_cmd_args)
|
||||
{
|
||||
struct cam_ope_ctx *ctx_data;
|
||||
struct cam_packet *packet;
|
||||
struct cam_buf_io_cfg *io_cfg = NULL;
|
||||
struct cam_ope_request *ope_request;
|
||||
struct ope_io_buf *io_buf = NULL;
|
||||
struct cam_ope_match_pid_args ope_pid_mid_args;
|
||||
|
||||
dma_addr_t iova_addr;
|
||||
int device_idx;
|
||||
bool *ctx_found;
|
||||
bool io_buf_found = false;
|
||||
size_t src_buf_size;
|
||||
int i, j;
|
||||
int32_t mmu_hdl;
|
||||
bool hw_pid_support = true;
|
||||
bool hw_id_found = false;
|
||||
uint32_t *resource_type;
|
||||
int stripe_num;
|
||||
int rc = 0;
|
||||
|
||||
ctx_data = (struct cam_ope_ctx *)hw_cmd_args->ctxt_to_hw_map;
|
||||
packet = hw_cmd_args->u.pf_args.pf_data.packet;
|
||||
ope_request = hw_cmd_args->u.pf_args.pf_data.req;
|
||||
|
||||
if (ctx_data->pf_mid_found)
|
||||
goto stripedump;
|
||||
|
||||
ope_pid_mid_args.fault_mid = hw_cmd_args->u.pf_args.mid;
|
||||
ope_pid_mid_args.fault_pid = hw_cmd_args->u.pf_args.pid;
|
||||
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) {
|
||||
hw_pid_support = false;
|
||||
goto stripedump;
|
||||
} else {
|
||||
*ctx_found = false;
|
||||
}
|
||||
|
||||
for (i = 0; i < ope_hw_mgr->num_ope; i++) {
|
||||
if (!ope_hw_mgr->ope_dev_data[i]->hw_intf)
|
||||
continue;
|
||||
for (j = 0; j < ope_hw_mgr->ope_dev_data[i]->num_hw_pid; j++) {
|
||||
if (ope_hw_mgr->ope_dev_data[i]->hw_pid[j] ==
|
||||
hw_cmd_args->u.pf_args.pid) {
|
||||
hw_id_found = true;
|
||||
device_idx = i;
|
||||
*ctx_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hw_id_found)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ope_hw_mgr->num_ope) {
|
||||
CAM_INFO(CAM_OPE,
|
||||
"PID:%d is not matching with any OPE HW PIDs ctx id:%d",
|
||||
hw_cmd_args->u.pf_args.pid, ctx_data->ctx_id);
|
||||
return;
|
||||
}
|
||||
|
||||
ope_pid_mid_args.device_idx = device_idx;
|
||||
|
||||
rc = hw_mgr->devices[OPE_DEV_OPE][device_idx]->hw_ops.process_cmd(
|
||||
hw_mgr->devices[OPE_DEV_OPE][device_idx]->hw_priv,
|
||||
OPE_HW_MATCH_PID_MID,
|
||||
&ope_pid_mid_args, sizeof(ope_pid_mid_args));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_OPE,
|
||||
"CAM_OPE_CMD_MATCH_PID_MID failed %d", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload +
|
||||
packet->io_configs_offset / 4);
|
||||
|
||||
*resource_type = ope_pid_mid_args.match_res;
|
||||
CAM_INFO(CAM_OPE, "Fault port %d", *resource_type);
|
||||
|
||||
stripedump:
|
||||
if (!ope_request)
|
||||
goto iodump;
|
||||
|
||||
CAM_INFO(CAM_OPE, "req_id %d Num of batches %d",
|
||||
ope_request->request_id, ope_request->num_batch);
|
||||
|
||||
for (i = 0; i < ope_request->num_batch; i++) {
|
||||
for (j = 0; j < ope_request->num_io_bufs[i]; j++) {
|
||||
io_buf = ope_request->io_buf[i][j];
|
||||
if (io_buf) {
|
||||
if (io_buf->resource_type == *resource_type) {
|
||||
io_buf_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (io_buf_found)
|
||||
break;
|
||||
}
|
||||
iodump:
|
||||
for (i = 0; i < packet->num_io_configs; i++) {
|
||||
if (hw_pid_support) {
|
||||
if (io_cfg[i].resource_type !=
|
||||
*resource_type)
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
|
||||
if (!io_cfg[i].mem_handle[j])
|
||||
break;
|
||||
CAM_INFO(CAM_OPE, "port: %d f: %u format: %d dir %d",
|
||||
io_cfg[i].resource_type,
|
||||
io_cfg[i].fence,
|
||||
io_cfg[i].format,
|
||||
io_cfg[i].direction);
|
||||
|
||||
mmu_hdl = cam_mem_is_secure_buf(
|
||||
io_cfg[i].mem_handle[j]) ?
|
||||
hw_mgr->iommu_sec_hdl :
|
||||
hw_mgr->iommu_hdl;
|
||||
rc = cam_mem_get_io_buf(io_cfg[i].mem_handle[j],
|
||||
mmu_hdl, &iova_addr, &src_buf_size);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_UTIL, "get src buf address fail");
|
||||
continue;
|
||||
}
|
||||
if ((iova_addr & 0xFFFFFFFF) != iova_addr) {
|
||||
CAM_ERR(CAM_OPE, "Invalid mapped address");
|
||||
rc = -EINVAL;
|
||||
continue;
|
||||
}
|
||||
CAM_INFO(CAM_OPE,
|
||||
"pln %u w %u h %u stride %u slice %u size %d addr 0x%x offset 0x%x memh %x",
|
||||
j, io_cfg[i].planes[j].width,
|
||||
io_cfg[i].planes[j].height,
|
||||
io_cfg[i].planes[j].plane_stride,
|
||||
io_cfg[i].planes[j].slice_height,
|
||||
(int32_t)src_buf_size,
|
||||
(unsigned int)iova_addr,
|
||||
io_cfg[i].offsets[j],
|
||||
io_cfg[i].mem_handle[j]);
|
||||
|
||||
if (io_buf_found) {
|
||||
for (stripe_num = 0; stripe_num < io_buf->num_stripes[j];
|
||||
stripe_num++) {
|
||||
CAM_INFO(CAM_OPE,
|
||||
"pln_num %d stripe_num %d width %d height %d stride %d io vaddr 0x%x",
|
||||
j, stripe_num, io_buf->s_io[j][stripe_num].width,
|
||||
io_buf->s_io[j][stripe_num].height,
|
||||
io_buf->s_io[j][stripe_num].stride,
|
||||
io_buf->s_io[j][stripe_num].iova_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hw_pid_support)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -469,39 +469,58 @@ struct cam_ope_ctx {
|
||||
struct cam_req_mgr_timer *clk_watch_dog;
|
||||
uint32_t clk_watch_dog_reset_counter;
|
||||
uint64_t last_flush_req;
|
||||
bool pf_mid_found;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_ope_hw_intf_data - OPE hw intf data
|
||||
*
|
||||
* @Brief: ope hw intf pointer and pid list data
|
||||
*
|
||||
* @devices: ope hw intf pointer
|
||||
* @num_devices: Number of OPE devices
|
||||
* @num_hw_pid: Number of pids for this hw
|
||||
* @hw_pid: ope hw pid values
|
||||
*
|
||||
*/
|
||||
struct cam_ope_hw_intf_data {
|
||||
struct cam_hw_intf *hw_intf;
|
||||
uint32_t num_hw_pid;
|
||||
uint32_t hw_pid[OPE_DEV_MAX];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_ope_hw_mgr
|
||||
*
|
||||
* @open_cnt: OPE device open count
|
||||
* @ope_ctx_cnt: Open context count
|
||||
* @hw_mgr_mutex: Mutex for HW manager
|
||||
* @hw_mgr_lock: Spinlock for HW manager
|
||||
* @hfi_en: Flag for HFI
|
||||
* @iommu_hdl: OPE Handle
|
||||
* @iommu_sec_hdl: OPE Handle for secure
|
||||
* @iommu_cdm_hdl: CDM Handle
|
||||
* @iommu_sec_cdm_hdl: CDM Handle for secure
|
||||
* @num_ope: Number of OPE
|
||||
* @secure_mode: Mode of OPE operation
|
||||
* @ctx_bitmap: Context bit map
|
||||
* @ctx_bitmap_size: Context bit map size
|
||||
* @ctx_bits: Context bit map bits
|
||||
* @ctx: OPE context
|
||||
* @devices: OPE devices
|
||||
* @ope_caps: OPE capabilities
|
||||
* @cmd_work: Command work
|
||||
* @msg_work: Message work
|
||||
* @timer_work: Timer work
|
||||
* @cmd_work_data: Command work data
|
||||
* @msg_work_data: Message work data
|
||||
* @timer_work_data: Timer work data
|
||||
* @ope_dev_intf: OPE device interface
|
||||
* @cdm_reg_map: OPE CDM register map
|
||||
* @clk_info: OPE clock Info for HW manager
|
||||
* @dentry: Pointer to OPE debugfs directory
|
||||
* @frame_dump_enable: OPE frame setting dump enablement
|
||||
* @open_cnt: OPE device open count
|
||||
* @ope_ctx_cnt: Open context count
|
||||
* @hw_mgr_mutex: Mutex for HW manager
|
||||
* @hw_mgr_lock: Spinlock for HW manager
|
||||
* @hfi_en: Flag for HFI
|
||||
* @iommu_hdl: OPE Handle
|
||||
* @iommu_sec_hdl: OPE Handle for secure
|
||||
* @iommu_cdm_hdl: CDM Handle
|
||||
* @iommu_sec_cdm_hdl: CDM Handle for secure
|
||||
* @num_ope: Number of OPE
|
||||
* @secure_mode: Mode of OPE operation
|
||||
* @ctx_bitmap: Context bit map
|
||||
* @ctx_bitmap_size: Context bit map size
|
||||
* @ctx_bits: Context bit map bits
|
||||
* @ctx: OPE context
|
||||
* @devices: OPE devices
|
||||
* @ope_dev_data: OPE device specific data
|
||||
* @ope_caps: OPE capabilities
|
||||
* @cmd_work: Command work
|
||||
* @msg_work: Message work
|
||||
* @timer_work: Timer work
|
||||
* @cmd_work_data: Command work data
|
||||
* @msg_work_data: Message work data
|
||||
* @timer_work_data: Timer work data
|
||||
* @ope_dev_intf: OPE device interface
|
||||
* @cdm_reg_map: OPE CDM register map
|
||||
* @clk_info: OPE clock Info for HW manager
|
||||
* @dentry: Pointer to OPE debugfs directory
|
||||
* @frame_dump_enable: OPE frame setting dump enablement
|
||||
* @dump_req_data_enable: OPE hang dump enablement
|
||||
*/
|
||||
struct cam_ope_hw_mgr {
|
||||
@@ -520,7 +539,8 @@ struct cam_ope_hw_mgr {
|
||||
size_t ctx_bitmap_size;
|
||||
size_t ctx_bits;
|
||||
struct cam_ope_ctx ctx[OPE_CTX_MAX];
|
||||
struct cam_hw_intf **devices[OPE_DEV_MAX];
|
||||
struct cam_hw_intf **devices[OPE_DEV_MAX];
|
||||
struct cam_ope_hw_intf_data *ope_dev_data[OPE_DEV_MAX];
|
||||
struct ope_query_cap_cmd ope_caps;
|
||||
uint64_t last_callback_time;
|
||||
|
||||
|
@@ -9,8 +9,12 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/completion.h>
|
||||
#include <media/cam_ope.h>
|
||||
#include "cam_ope_hw_mgr.h"
|
||||
|
||||
int cam_ope_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
|
||||
int *iommu_hdl);
|
||||
|
||||
int cam_ope_hw_init(struct cam_ope_hw_intf_data **ope_hw_intf_data,
|
||||
uint32_t hw_idx);
|
||||
|
||||
#endif /* CAM_OPE_HW_MGR_INTF_H */
|
||||
|
@@ -872,4 +872,3 @@ int cam_ope_bus_rd_process(struct ope_hw *ope_hw_info,
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@@ -17,7 +17,6 @@
|
||||
#include "cam_ope_context.h"
|
||||
#include "cam_ope_hw_mgr.h"
|
||||
|
||||
|
||||
/**
|
||||
* struct ope_bus_rd_cdm_info
|
||||
*
|
||||
|
@@ -1616,12 +1616,15 @@ int cam_ope_process_cmd(void *device_priv, uint32_t cmd_type,
|
||||
void *cmd_args, uint32_t arg_size)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_hw_info *ope_dev = device_priv;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
struct cam_ope_device_core_info *core_info = NULL;
|
||||
struct ope_hw *ope_hw;
|
||||
bool hfi_en;
|
||||
struct cam_hw_info *ope_dev = device_priv;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
struct cam_ope_device_core_info *core_info = NULL;
|
||||
struct cam_ope_match_pid_args *match_pid_mid = NULL;
|
||||
struct ope_hw *ope_hw;
|
||||
bool hfi_en;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
uint32_t device_idx;
|
||||
|
||||
if (!device_priv) {
|
||||
CAM_ERR(CAM_OPE, "Invalid args %x for cmd %u",
|
||||
@@ -1720,6 +1723,33 @@ int cam_ope_process_cmd(void *device_priv, uint32_t cmd_type,
|
||||
case OPE_HW_DUMP_DEBUG:
|
||||
rc = cam_ope_process_dump_debug_reg(ope_hw, hfi_en);
|
||||
break;
|
||||
case OPE_HW_MATCH_PID_MID:
|
||||
if (!cmd_args) {
|
||||
CAM_ERR(CAM_OPE, "cmd args NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
match_pid_mid = (struct cam_ope_match_pid_args *)cmd_args;
|
||||
match_pid_mid->mid_match_found = false;
|
||||
|
||||
device_idx = match_pid_mid->device_idx;
|
||||
|
||||
for (i = 0; i < MAX_RW_CLIENTS; i++) {
|
||||
if ((match_pid_mid->fault_mid ==
|
||||
ope_hw->common->ope_mid_info[device_idx][i].mid) &&
|
||||
(match_pid_mid->fault_pid ==
|
||||
ope_hw->common->ope_mid_info[device_idx][i].pid)) {
|
||||
match_pid_mid->match_res =
|
||||
ope_hw->common->ope_mid_info[device_idx][i].cam_ope_res_type;
|
||||
match_pid_mid->mid_match_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match_pid_mid->mid_match_found) {
|
||||
rc = -1;
|
||||
CAM_INFO(CAM_OPE, "mid match not found");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1758,3 +1788,4 @@ irqreturn_t cam_ope_irq(int irq_num, void *data)
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#ifndef CAM_OPE_CORE_H
|
||||
#define CAM_OPE_CORE_H
|
||||
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
@@ -15,6 +16,9 @@
|
||||
#include "cam_cpas_api.h"
|
||||
#include "ope_hw.h"
|
||||
#include "ope_dev_intf.h"
|
||||
|
||||
#define CAM_OPE_HW_MAX_NUM_PID 2
|
||||
|
||||
/**
|
||||
* struct cam_ope_cpas_vote
|
||||
* @ahb_vote: AHB vote info
|
||||
@@ -79,7 +83,6 @@ struct cam_ope_device_core_info {
|
||||
struct cam_ope_set_irq_cb irq_cb;
|
||||
};
|
||||
|
||||
|
||||
int cam_ope_init_hw(void *device_priv,
|
||||
void *init_hw_args, uint32_t arg_size);
|
||||
int cam_ope_deinit_hw(void *device_priv,
|
||||
|
@@ -21,8 +21,9 @@
|
||||
#include "ope_dev_intf.h"
|
||||
#include "camera_main.h"
|
||||
|
||||
static struct cam_ope_hw_intf_data cam_ope_dev_list[OPE_DEV_MAX];
|
||||
static struct cam_ope_device_hw_info ope_hw_info;
|
||||
static struct ope_dev_soc ope_soc_info;
|
||||
static struct cam_ope_soc_private ope_soc_info;
|
||||
EXPORT_SYMBOL(ope_soc_info);
|
||||
|
||||
static struct hw_version_reg ope_hw_version_reg = {
|
||||
@@ -115,10 +116,13 @@ static int cam_ope_component_bind(struct device *dev,
|
||||
struct cam_hw_info *ope_dev = NULL;
|
||||
const struct of_device_id *match_dev = NULL;
|
||||
struct cam_ope_device_core_info *core_info = NULL;
|
||||
int rc = 0;
|
||||
struct cam_ope_dev_probe ope_probe;
|
||||
struct cam_ope_cpas_vote cpas_vote;
|
||||
struct cam_ope_soc_private *soc_private;
|
||||
int i;
|
||||
uint32_t hw_idx;
|
||||
struct cam_ope_dev_probe ope_probe;
|
||||
struct cam_ope_cpas_vote cpas_vote;
|
||||
int rc = 0;
|
||||
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
of_property_read_u32(pdev->dev.of_node,
|
||||
@@ -156,8 +160,13 @@ static int cam_ope_component_bind(struct device *dev,
|
||||
ope_dev_intf->hw_type,
|
||||
ope_dev_intf->hw_idx);
|
||||
|
||||
if (ope_dev_intf->hw_idx < OPE_DEV_MAX)
|
||||
cam_ope_dev_list[ope_dev_intf->hw_idx].hw_intf =
|
||||
ope_dev_intf;
|
||||
|
||||
platform_set_drvdata(pdev, ope_dev_intf);
|
||||
|
||||
|
||||
ope_dev->core_info = kzalloc(sizeof(struct cam_ope_device_core_info),
|
||||
GFP_KERNEL);
|
||||
if (!ope_dev->core_info) {
|
||||
@@ -232,6 +241,14 @@ static int cam_ope_component_bind(struct device *dev,
|
||||
|
||||
CAM_DBG(CAM_OPE, "OPE:%d component bound successfully",
|
||||
ope_dev_intf->hw_idx);
|
||||
soc_private = ope_dev->soc_info.soc_private;
|
||||
cam_ope_dev_list[ope_dev_intf->hw_idx].num_hw_pid =
|
||||
soc_private->num_pid;
|
||||
|
||||
for (i = 0; i < soc_private->num_pid; i++)
|
||||
cam_ope_dev_list[ope_dev_intf->hw_idx].hw_pid[i] =
|
||||
soc_private->pid[i];
|
||||
|
||||
return rc;
|
||||
|
||||
init_hw_failure:
|
||||
@@ -255,6 +272,21 @@ static void cam_ope_component_unbind(struct device *dev,
|
||||
CAM_DBG(CAM_OPE, "Unbinding component: %s", pdev->name);
|
||||
}
|
||||
|
||||
int cam_ope_hw_init(struct cam_ope_hw_intf_data **ope_hw_intf_data,
|
||||
uint32_t hw_idx)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (cam_ope_dev_list[hw_idx].hw_intf) {
|
||||
*ope_hw_intf_data = &cam_ope_dev_list[hw_idx];
|
||||
rc = 0;
|
||||
} else {
|
||||
CAM_ERR(CAM_OPE, "inval param");
|
||||
*ope_hw_intf_data = NULL;
|
||||
rc = -ENODEV;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
const static struct component_ops cam_ope_component_ops = {
|
||||
.bind = cam_ope_component_bind,
|
||||
|
@@ -12,23 +12,32 @@
|
||||
#include "cam_cpas_api.h"
|
||||
|
||||
|
||||
#define OPE_HW_INIT 0x1
|
||||
#define OPE_HW_DEINIT 0x2
|
||||
#define OPE_HW_ACQUIRE 0x3
|
||||
#define OPE_HW_RELEASE 0x4
|
||||
#define OPE_HW_START 0x5
|
||||
#define OPE_HW_STOP 0x6
|
||||
#define OPE_HW_FLUSH 0x7
|
||||
#define OPE_HW_PREPARE 0x8
|
||||
#define OPE_HW_ISR 0x9
|
||||
#define OPE_HW_PROBE 0xA
|
||||
#define OPE_HW_CLK_UPDATE 0xB
|
||||
#define OPE_HW_BW_UPDATE 0xC
|
||||
#define OPE_HW_RESET 0xD
|
||||
#define OPE_HW_SET_IRQ_CB 0xE
|
||||
#define OPE_HW_CLK_DISABLE 0xF
|
||||
#define OPE_HW_CLK_ENABLE 0x10
|
||||
#define OPE_HW_DUMP_DEBUG 0x11
|
||||
#define OPE_HW_INIT 0x1
|
||||
#define OPE_HW_DEINIT 0x2
|
||||
#define OPE_HW_ACQUIRE 0x3
|
||||
#define OPE_HW_RELEASE 0x4
|
||||
#define OPE_HW_START 0x5
|
||||
#define OPE_HW_STOP 0x6
|
||||
#define OPE_HW_FLUSH 0x7
|
||||
#define OPE_HW_PREPARE 0x8
|
||||
#define OPE_HW_ISR 0x9
|
||||
#define OPE_HW_PROBE 0xA
|
||||
#define OPE_HW_CLK_UPDATE 0xB
|
||||
#define OPE_HW_BW_UPDATE 0xC
|
||||
#define OPE_HW_RESET 0xD
|
||||
#define OPE_HW_SET_IRQ_CB 0xE
|
||||
#define OPE_HW_CLK_DISABLE 0xF
|
||||
#define OPE_HW_CLK_ENABLE 0x10
|
||||
#define OPE_HW_DUMP_DEBUG 0x11
|
||||
#define OPE_HW_MATCH_PID_MID 0x12
|
||||
|
||||
struct cam_ope_match_pid_args {
|
||||
uint32_t fault_pid;
|
||||
uint32_t fault_mid;
|
||||
uint32_t match_res;
|
||||
uint32_t device_idx;
|
||||
bool mid_match_found;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_ope_dev_probe
|
||||
|
@@ -12,10 +12,12 @@
|
||||
#define OPE_DEV_OPE 0
|
||||
#define OPE_DEV_MAX 1
|
||||
|
||||
#define MAX_RD_CLIENTS 2
|
||||
#define MAX_RD_CLIENTS 3
|
||||
#define MAX_WR_CLIENTS 8
|
||||
#define MAX_PP_CLIENTS 29
|
||||
|
||||
#define MAX_RW_CLIENTS (MAX_RD_CLIENTS + MAX_WR_CLIENTS)
|
||||
|
||||
#define OPE_CDM_BASE 0x0
|
||||
#define OPE_TOP_BASE 0x1
|
||||
#define OPE_QOS_BASE 0x2
|
||||
@@ -24,7 +26,6 @@
|
||||
#define OPE_BUS_WR 0x5
|
||||
#define OPE_BASE_MAX 0x6
|
||||
|
||||
|
||||
#define BUS_RD_COMBO_BAYER_MASK 0x1
|
||||
#define BUS_RD_COMBO_YUV_MASK 0x2
|
||||
#define BUS_RD_COMBO_MAX 0x2
|
||||
@@ -53,8 +54,16 @@
|
||||
|
||||
#define OPE_MAX_DEBUG_REGISTER 30
|
||||
|
||||
struct cam_ope_pid_mid_info {
|
||||
int cam_ope_res_type;
|
||||
uint32_t pid;
|
||||
uint32_t mid;
|
||||
bool read;
|
||||
};
|
||||
|
||||
struct cam_ope_common {
|
||||
uint32_t mode[CAM_FORMAT_MAX];
|
||||
struct cam_ope_pid_mid_info (*ope_mid_info)[MAX_RW_CLIENTS];
|
||||
};
|
||||
|
||||
struct cam_ope_top_reg {
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#define OPE_BUS_RD_TYPE_BAYER 0x0
|
||||
#define OPE_BUS_RD_TYPE_YUV_Y 0x0
|
||||
#define OPE_BUS_RD_TYPE_YUC_C 0x1
|
||||
#define OPE_BUS_RD_TYPE_CDM 0x2
|
||||
|
||||
#define OPE_BUS_WR_TYPE_VID_Y 0x0
|
||||
#define OPE_BUS_WR_TYPE_VID_C 0x1
|
||||
@@ -19,6 +20,81 @@
|
||||
#define OPE_BUS_WR_TYPE_IHIST 0x6
|
||||
#define OPE_BUS_WR_TYPE_LTM 0x7
|
||||
|
||||
static struct cam_ope_pid_mid_info g_ope_mid_info[OPE_DEV_MAX][MAX_RW_CLIENTS] = {
|
||||
{
|
||||
{
|
||||
.cam_ope_res_type = OPE_IN_RES_FULL,
|
||||
.pid = 0,
|
||||
.mid = 0,
|
||||
.read = true,
|
||||
},
|
||||
{
|
||||
.cam_ope_res_type = OPE_IN_RES_FULL,
|
||||
.pid = 0,
|
||||
.mid = 1,
|
||||
.read = true,
|
||||
},
|
||||
{
|
||||
.cam_ope_res_type = OPE_IN_RES_FULL,
|
||||
.pid = 0,
|
||||
.mid = 2,
|
||||
.read = true,
|
||||
},
|
||||
{
|
||||
.cam_ope_res_type = OPE_OUT_RES_VIDEO,
|
||||
.pid = 1,
|
||||
.mid = 16,
|
||||
.read = false,
|
||||
},
|
||||
{
|
||||
.cam_ope_res_type = OPE_OUT_RES_VIDEO,
|
||||
.pid = 1,
|
||||
.mid = 17,
|
||||
.read = false,
|
||||
},
|
||||
{
|
||||
.cam_ope_res_type = OPE_OUT_RES_DISP,
|
||||
.pid = 1,
|
||||
.mid = 18,
|
||||
.read = false,
|
||||
},
|
||||
{
|
||||
.cam_ope_res_type = OPE_OUT_RES_DISP,
|
||||
.pid = 1,
|
||||
.mid = 19,
|
||||
.read = false,
|
||||
},
|
||||
{
|
||||
.cam_ope_res_type = OPE_OUT_RES_ARGB,
|
||||
.pid = 1,
|
||||
.mid = 20,
|
||||
.read = false,
|
||||
},
|
||||
{
|
||||
.cam_ope_res_type = OPE_OUT_RES_STATS_RS,
|
||||
.pid = 1,
|
||||
.mid = 21,
|
||||
.read = false,
|
||||
},
|
||||
{
|
||||
.cam_ope_res_type = OPE_OUT_RES_STATS_IHIST,
|
||||
.pid = 1,
|
||||
.mid = 22,
|
||||
.read = false,
|
||||
},
|
||||
{
|
||||
.cam_ope_res_type = OPE_OUT_RES_STATS_LTM,
|
||||
.pid = 1,
|
||||
.mid = 23,
|
||||
.read = false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct cam_ope_common common_data = {
|
||||
.ope_mid_info = g_ope_mid_info,
|
||||
};
|
||||
|
||||
enum cam_ope_bus_rd_unpacker_format {
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_128_BYPASS = 0x0,
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_8 = 0x1,
|
||||
@@ -100,8 +176,8 @@ static struct cam_ope_top_reg_val ope_top_reg_val = {
|
||||
.incr_mask = 0xF0000000,
|
||||
.incr_shift = 0x1B,
|
||||
.irq_mask = 0x0000000F,
|
||||
.sw_reset_cmd = 0x2,
|
||||
.hw_reset_cmd = 0x1,
|
||||
.sw_reset_cmd = 0x2,
|
||||
.hw_reset_cmd = 0x1,
|
||||
.irq_set_clear = 0x1,
|
||||
.rst_done = 0x1,
|
||||
.we_done = 0x2,
|
||||
@@ -657,6 +733,7 @@ static struct ope_hw ope_hw_100 = {
|
||||
.bus_wr_reg = &ope_bus_wr_reg,
|
||||
.bus_wr_reg_val = &ope_bus_wr_reg_val,
|
||||
.pp_reg = &ope_pp_reg,
|
||||
.common = &common_data,
|
||||
};
|
||||
|
||||
#endif /* CAM_OPE_HW_100_H */
|
||||
|
@@ -19,7 +19,7 @@ static int cam_ope_get_dt_properties(struct cam_hw_soc_info *soc_info)
|
||||
int rc = 0;
|
||||
struct platform_device *pdev = NULL;
|
||||
struct device_node *of_node = NULL;
|
||||
struct ope_dev_soc *ope_soc_info;
|
||||
struct cam_ope_soc_private *ope_soc_info;
|
||||
|
||||
if (!soc_info) {
|
||||
CAM_ERR(CAM_OPE, "soc_info is NULL");
|
||||
@@ -54,8 +54,18 @@ static int cam_ope_request_platform_resource(
|
||||
int cam_ope_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
||||
irq_handler_t ope_irq_handler, void *irq_data)
|
||||
{
|
||||
struct cam_ope_soc_private *soc_private;
|
||||
struct platform_device *pdev = NULL;
|
||||
int num_pid = 0, i = 0;
|
||||
int rc = 0;
|
||||
|
||||
soc_private = kzalloc(sizeof(struct cam_ope_soc_private), GFP_KERNEL);
|
||||
if (!soc_private) {
|
||||
CAM_DBG(CAM_ISP, "Error! soc_private Alloc Failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
soc_info->soc_private = soc_private;
|
||||
|
||||
rc = cam_ope_get_dt_properties(soc_info);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
@@ -65,6 +75,20 @@ int cam_ope_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
soc_private->num_pid = 0;
|
||||
pdev = soc_info->pdev;
|
||||
num_pid = of_property_count_u32_elems(pdev->dev.of_node, "cam_hw_pid");
|
||||
CAM_DBG(CAM_OPE, "ope: %d pid count %d", soc_info->index, num_pid);
|
||||
|
||||
if (num_pid <= 0 || num_pid > CAM_OPE_HW_MAX_NUM_PID)
|
||||
goto end;
|
||||
|
||||
soc_private->num_pid = num_pid;
|
||||
|
||||
for (i = 0; i < num_pid; i++)
|
||||
of_property_read_u32_index(pdev->dev.of_node, "cam_hw_pid", i,
|
||||
&soc_private->pid[i]);
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@@ -8,15 +8,23 @@
|
||||
|
||||
#include "cam_soc_util.h"
|
||||
|
||||
#define CAM_OPE_HW_MAX_NUM_PID 2
|
||||
|
||||
/**
|
||||
* struct ope_dev_soc
|
||||
* struct cam_ope_soc_private
|
||||
*
|
||||
* @hfi_en: HFI enable flag
|
||||
* @hfi_en: HFI enable flag
|
||||
* @num_pid: OPE number of pids
|
||||
* @pid: OPE pid value list
|
||||
*/
|
||||
struct ope_dev_soc {
|
||||
struct cam_ope_soc_private {
|
||||
uint32_t hfi_en;
|
||||
uint32_t num_pid;
|
||||
uint32_t pid[CAM_OPE_HW_MAX_NUM_PID];
|
||||
};
|
||||
|
||||
|
||||
|
||||
int cam_ope_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
||||
irq_handler_t ope_irq_handler, void *irq_data);
|
||||
|
||||
|
مرجع در شماره جدید
Block a user