Merge tag 'LA.UM.9.14.r1-19500-LAHAINA.QSSI12.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/camera-kernel into android12-5.4-lahaina

"LA.UM.9.14.r1-19500-LAHAINA.QSSI12.0"

* tag 'LA.UM.9.14.r1-19500-LAHAINA.QSSI12.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/camera-kernel:
  msm: camera: ife: dump data at overlflow for rdi only use case
  msm: camera: memmgr: update correct length in bufq
  msm: camera: reqmgr: Validate the link handle
  msm: camera: cdm: Fix workqueue timing issue
  msm: camera: reqmgr: Avoid freeing subdev twice
  msm: camera: tfe: dump csid clock and path data at overflow
  msm: camera: reqmgr: reader writer locks to avoid memory faults
  msm: camera: ope: Fix for 32-bit kernel
  msm: camera: reqmgr: check if link handle is correctly passed
  msm: camera: isp: Add eof notification for rdi only context
  msm: camera: config: Enable camera drivers for qcs610
  msm: camera: ope: Update request timeout for NRT/RT context
  msm: camera: ope: Increase max bl limit and max stripe to process
  msm: camera: reqmgr: Prevent session deadlock
  msm: camera: isp: handle buf_done at apply failure from deferred list
  msm: camera: cdm: Fix deadlock issue in CDM handle error
  msm: camera: isp: Fix PPI index based on the phy selection
  msm: camera: ife: Add ife num outport bound checks
  msm: camera: cdm: handle dead lock scenario
  msm: camera: isp: Add handling for flush in flushed state
  msm: camera: core: Delete request from pending list in case of error
  msm: camera: req_mgr: Table info dump removed
  msm: camera: flash: Add support for qup i2c flash
  msm: camera: jpeg: Ensure in/out map entries are within allowed range
  msm: camera: memmgr: ref count for init and deinit

Change-Id: I023497de5674200d39cabeeba781c277c4c4dfc9
This commit is contained in:
Michael Bestas 2022-05-19 00:36:59 +03:00
commit 82f295420d
No known key found for this signature in database
GPG key ID: CC95044519BE6669
46 changed files with 853 additions and 203 deletions

View file

@ -38,6 +38,10 @@ ifeq ($(CONFIG_ARCH_YUPIK), y)
include $(srctree)/techpack/camera/config/yupikcamera.conf
endif
ifeq ($(CONFIG_ARCH_SM6150), y)
include $(srctree)/techpack/camera/config/sm6150camera.conf
endif
ifeq ($(CONFIG_ARCH_KONA), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/konacameraconf.h
@ -83,6 +87,11 @@ LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/yupikcameraconf.h
endif
ifeq ($(CONFIG_ARCH_SM6150), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/sm6150cameraconf.h
endif
endif
ifneq (,$(filter $(CONFIG_SPECTRA_CAMERA), y m))

View file

@ -0,0 +1,18 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2021, The Linux Foundation. All rights reserved.
ifeq ($(CONFIG_QGKI),y)
export CONFIG_SPECTRA_CAMERA=m
$(info "QGKI Spectra Camera Building as DLKM")
else
export CONFIG_SPECTRA_CAMERA=m
$(info "GKI Spectra Camera Building as DLKM")
endif
ifneq (,$(filter $(CONFIG_SPECTRA_CAMERA), y m))
export CONFIG_SPECTRA_ISP=y
export CONFIG_SPECTRA_SENSOR=y
export CONFIG_SPECTRA_ICP=y
export CONFIG_SPECTRA_JPEG=y
export CONFIG_SPECTRA_CUSTOM=y
endif

View file

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#define CONFIG_SPECTRA_CAMERA 1
#define CONFIG_SPECTRA_ISP 1
#define CONFIG_SPECTRA_SENSOR 1
#define CONFIG_SPECTRA_ICP 1
#define CONFIG_SPECTRA_JPEG 1
#define CONFIG_SPECTRA_CUSTOM 1

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_CDM_H_
@ -68,6 +69,8 @@
#define CAM_CDM_BL_FIFO_LENGTH_MAX_DEFAULT 0x40
#define CAM_CDM_BL_FIFO_LENGTH_CFG_SHIFT 0x10
#define CAM_CDM_BL_FIFO_FLUSH_SHIFT 0x3
#define CAM_CDM_BL_FIFO_BOUNDARY_CHECK \
(CAM_CDM_BL_FIFO_LENGTH_MAX_DEFAULT / 2)
#define CAM_CDM_BL_FIFO_REQ_SIZE_MAX 0x00
#define CAM_CDM_BL_FIFO_REQ_SIZE_MAX_DIV2 0x01

View file

@ -180,12 +180,10 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
(struct cam_cdm_bl_cb_request_entry *)data;
client_idx = CAM_CDM_GET_CLIENT_IDX(node->client_hdl);
mutex_lock(&cdm_hw->hw_mutex);
client = core->clients[client_idx];
if ((!client) || (client->handle != node->client_hdl)) {
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client,
node->client_hdl);
mutex_unlock(&cdm_hw->hw_mutex);
return;
}
cam_cdm_get_client_refcount(client);
@ -204,7 +202,6 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
}
mutex_unlock(&client->lock);
cam_cdm_put_client_refcount(client);
mutex_unlock(&cdm_hw->hw_mutex);
return;
} else if (status == CAM_CDM_CB_STATUS_HW_RESET_DONE ||
status == CAM_CDM_CB_STATUS_HW_FLUSH ||
@ -242,7 +239,6 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
for (i = 0; i < CAM_PER_CDM_MAX_REGISTERED_CLIENTS; i++) {
if (core->clients[i] != NULL) {
mutex_lock(&cdm_hw->hw_mutex);
client = core->clients[i];
cam_cdm_get_client_refcount(client);
mutex_lock(&client->lock);
@ -265,7 +261,6 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
}
mutex_unlock(&client->lock);
cam_cdm_put_client_refcount(client);
mutex_unlock(&cdm_hw->hw_mutex);
}
}
}

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/delay.h>
@ -1238,6 +1239,7 @@ static void cam_hw_cdm_work(struct work_struct *work)
return;
}
mutex_lock(&cdm_hw->hw_mutex);
mutex_lock(&core->bl_fifo[fifo_idx].fifo_lock);
if (atomic_read(&core->bl_fifo[fifo_idx].work_record))
@ -1251,6 +1253,7 @@ static void cam_hw_cdm_work(struct work_struct *work)
core->arbitration);
mutex_unlock(&core->bl_fifo[fifo_idx]
.fifo_lock);
mutex_unlock(&cdm_hw->hw_mutex);
return;
}
@ -1261,26 +1264,30 @@ static void cam_hw_cdm_work(struct work_struct *work)
list_for_each_entry_safe(node, tnode,
&core->bl_fifo[fifo_idx].bl_request_list,
entry) {
if (node->request_type ==
CAM_HW_CDM_BL_CB_CLIENT) {
cam_cdm_notify_clients(cdm_hw,
CAM_CDM_CB_STATUS_BL_SUCCESS,
(void *)node);
} else if (node->request_type ==
CAM_HW_CDM_BL_CB_INTERNAL) {
CAM_ERR(CAM_CDM,
"Invalid node=%pK %d",
node,
node->request_type);
}
list_del_init(&node->entry);
if (node->bl_tag == payload->irq_data) {
if ((node->bl_tag <= payload->irq_data) ||
((node->bl_tag - payload->irq_data) >
CAM_CDM_BL_FIFO_BOUNDARY_CHECK)) {
if (node->request_type ==
CAM_HW_CDM_BL_CB_CLIENT) {
cam_cdm_notify_clients(cdm_hw,
CAM_CDM_CB_STATUS_BL_SUCCESS,
(void *)node);
} else if (node->request_type ==
CAM_HW_CDM_BL_CB_INTERNAL) {
CAM_ERR(CAM_CDM,
"Invalid node=%pK %d",
node,
node->request_type);
}
list_del_init(&node->entry);
if (node->bl_tag == payload->irq_data) {
kfree(node);
node = NULL;
break;
}
kfree(node);
node = NULL;
break;
}
kfree(node);
node = NULL;
}
} else {
CAM_INFO(CAM_CDM,
@ -1289,6 +1296,7 @@ static void cam_hw_cdm_work(struct work_struct *work)
}
mutex_unlock(&core->bl_fifo[payload->fifo_idx]
.fifo_lock);
mutex_unlock(&cdm_hw->hw_mutex);
}
if (payload->irq_status &
@ -1405,9 +1413,9 @@ handle_cdm_pf:
cdm_hw->soc_info.index);
for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++)
mutex_unlock(&core->bl_fifo[i].fifo_lock);
mutex_unlock(&cdm_hw->hw_mutex);
cam_cdm_notify_clients(cdm_hw, CAM_CDM_CB_STATUS_PAGEFAULT,
(void *)pf_info->iova);
mutex_unlock(&cdm_hw->hw_mutex);
clear_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
} else {
CAM_ERR(CAM_CDM, "Invalid token");

View file

@ -457,6 +457,9 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
rc = cam_sync_check_valid(
req->in_map_entries[j].sync_id);
if (rc) {
spin_lock(&ctx->lock);
list_del_init(&req->list);
spin_unlock(&ctx->lock);
CAM_ERR(CAM_CTXT,
"invalid in map sync object %d",
req->in_map_entries[j].sync_id);

View file

@ -55,8 +55,10 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
switch (cmd) {
case VIDIOC_CAM_CONTROL:
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);
rc = cam_node_handle_ioctl(node,
(struct cam_control *) arg);
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
break;
case CAM_SD_SHUTDOWN:
if (!cam_req_mgr_is_shutdown()) {

View file

@ -1030,6 +1030,7 @@ static int cam_cpas_util_apply_default_axi_vote(
struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
struct cam_cpas_axi_port *axi_port = NULL;
uint64_t mnoc_ab_bw = 0, mnoc_ib_bw = 0;
uint64_t applied_ab_bw = 0, applied_ib_bw = 0;
int rc = 0, i = 0;
mutex_lock(&cpas_core->tree_lock);
@ -1057,6 +1058,8 @@ static int cam_cpas_util_apply_default_axi_vote(
mnoc_ab_bw, mnoc_ib_bw, rc);
goto unlock_tree;
}
cpas_core->axi_port[i].applied_ab_bw = applied_ab_bw;
cpas_core->axi_port[i].applied_ib_bw = applied_ib_bw;
}
unlock_tree:

View file

@ -44,8 +44,11 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd,
{
struct cam_fd_dev *fd_dev = &g_fd_dev;
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);
if (!fd_dev->probe_done) {
CAM_ERR(CAM_FD, "FD Dev not initialized, fd_dev=%pK", fd_dev);
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
return -ENODEV;
}
@ -54,6 +57,8 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd,
CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt);
mutex_unlock(&fd_dev->lock);
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
return 0;
}

View file

@ -73,6 +73,8 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd,
struct cam_node *node = v4l2_get_subdevdata(sd);
int rc = 0;
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);
mutex_lock(&g_icp_dev.icp_lock);
if (g_icp_dev.open_cnt >= 1) {
CAM_ERR(CAM_ICP, "ICP subdev is already opened");
@ -95,6 +97,7 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd,
g_icp_dev.open_cnt++;
end:
mutex_unlock(&g_icp_dev.icp_lock);
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
return rc;
}

View file

@ -3541,6 +3541,19 @@ hw_dump:
return rc;
}
static int __cam_isp_ctx_flush_req_in_flushed_state(
struct cam_context *ctx,
struct cam_req_mgr_flush_request *flush_req)
{
if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
CAM_INFO(CAM_ISP, "Flush in flushed state req id %lld ctx_id:%d",
flush_req->req_id, ctx->ctx_id);
ctx->last_flush_req = flush_req->req_id;
}
return 0;
}
static int __cam_isp_ctx_flush_req(struct cam_context *ctx,
struct list_head *req_list, struct cam_req_mgr_flush_request *flush_req)
{
@ -4106,6 +4119,16 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state(
CAM_DBG(CAM_ISP,
"CDM callback detected for req: %lld, possible buf_done delay, waiting for buf_done",
req->request_id);
if (req_isp->num_fence_map_out ==
req_isp->num_deferred_acks) {
__cam_isp_handle_deferred_buf_done(ctx_isp, req,
true,
CAM_SYNC_STATE_SIGNALED_ERROR,
CAM_SYNC_ISP_EVENT_BUBBLE);
__cam_isp_ctx_handle_buf_done_for_req_list(
ctx_isp, req);
}
goto end;
} else {
CAM_WARN(CAM_ISP,
@ -4292,7 +4315,7 @@ static struct cam_isp_ctx_irq_ops
__cam_isp_ctx_rdi_only_sof_in_top_state,
__cam_isp_ctx_reg_upd_in_sof,
NULL,
NULL,
__cam_isp_ctx_notify_eof_in_activated_state,
NULL,
},
},
@ -4303,7 +4326,7 @@ static struct cam_isp_ctx_irq_ops
__cam_isp_ctx_rdi_only_sof_in_applied_state,
NULL,
NULL,
NULL,
__cam_isp_ctx_notify_eof_in_activated_state,
__cam_isp_ctx_buf_done_in_applied,
},
},
@ -4314,7 +4337,7 @@ static struct cam_isp_ctx_irq_ops
__cam_isp_ctx_rdi_only_sof_in_top_state,
NULL,
NULL,
NULL,
__cam_isp_ctx_notify_eof_in_activated_state,
__cam_isp_ctx_buf_done_in_epoch,
},
},
@ -4325,7 +4348,7 @@ static struct cam_isp_ctx_irq_ops
__cam_isp_ctx_rdi_only_sof_in_bubble_state,
__cam_isp_ctx_rdi_only_reg_upd_in_bubble_state,
NULL,
NULL,
__cam_isp_ctx_notify_eof_in_activated_state,
__cam_isp_ctx_buf_done_in_bubble,
},
},
@ -4336,7 +4359,7 @@ static struct cam_isp_ctx_irq_ops
__cam_isp_ctx_rdi_only_sof_in_bubble_applied,
__cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state,
NULL,
NULL,
__cam_isp_ctx_notify_eof_in_activated_state,
__cam_isp_ctx_buf_done_in_bubble_applied,
},
},
@ -4637,6 +4660,14 @@ static int __cam_isp_ctx_config_dev_in_top_state(
packet->header.request_id);
rc = -EBADR;
goto free_req;
} else if ((packet_opcode == CAM_ISP_PACKET_INIT_DEV)
&& (packet->header.request_id <= ctx->last_flush_req)
&& ctx->last_flush_req && packet->header.request_id) {
CAM_WARN(CAM_ISP,
"last flushed req is %lld, config dev(init) for req %lld",
ctx->last_flush_req, packet->header.request_id);
rc = -EBADR;
goto free_req;
}
cfg.packet = packet;
@ -5927,6 +5958,7 @@ static struct cam_ctx_ops
.crm_ops = {
.unlink = __cam_isp_ctx_unlink_in_ready,
.process_evt = __cam_isp_ctx_process_evt,
.flush_req = __cam_isp_ctx_flush_req_in_flushed_state,
},
.irq_ops = NULL,
.pagefault_ops = cam_isp_context_dump_requests,

View file

@ -64,10 +64,14 @@ static const struct of_device_id cam_isp_dt_match[] = {
static int cam_isp_subdev_open(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);
mutex_lock(&g_isp_dev.isp_mutex);
g_isp_dev.open_cnt++;
mutex_unlock(&g_isp_dev.isp_mutex);
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
return 0;
}

View file

@ -7990,6 +7990,14 @@ static int cam_ife_hw_mgr_handle_hw_eof(
case CAM_ISP_HW_VFE_IN_RDI1:
case CAM_ISP_HW_VFE_IN_RDI2:
case CAM_ISP_HW_VFE_IN_RDI3:
if (!ife_hw_mgr_ctx->is_rdi_only_context)
break;
if (atomic_read(&ife_hw_mgr_ctx->overflow_pending))
break;
ife_hw_irq_eof_cb(ife_hw_mgr_ctx->common.cb_priv,
CAM_ISP_HW_EVENT_EOF, (void *)&eof_done_event_data);
break;
case CAM_ISP_HW_VFE_IN_PDLIB:
case CAM_ISP_HW_VFE_IN_LCR:
break;

View file

@ -5405,6 +5405,65 @@ end:
return 0;
}
static int cam_tfe_hw_mgr_handle_hw_dump_info(
void *ctx,
void *evt_info)
{
struct cam_tfe_hw_mgr_ctx *tfe_hw_mgr_ctx =
(struct cam_tfe_hw_mgr_ctx *)ctx;
struct cam_isp_hw_event_info *event_info =
(struct cam_isp_hw_event_info *)evt_info;
struct cam_isp_hw_mgr_res *hw_mgr_res = NULL;
struct cam_hw_intf *hw_intf;
uint32_t i, out_port_id;
uint64_t dummy_args;
int rc = 0;
list_for_each_entry(hw_mgr_res,
&tfe_hw_mgr_ctx->res_list_tfe_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_ops.process_cmd) {
rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv,
CAM_ISP_HW_CMD_CSID_CLOCK_DUMP,
&dummy_args,
sizeof(uint64_t));
if (rc)
CAM_ERR(CAM_ISP,
"CSID Clock Dump failed");
}
}
}
if (event_info->res_type == CAM_ISP_RESOURCE_VFE_OUT) {
out_port_id = event_info->res_id & 0xFF;
if (out_port_id >= CAM_TFE_HW_OUT_RES_MAX) {
CAM_ERR(CAM_ISP,
"Resource out of range");
goto end;
}
hw_mgr_res =
&tfe_hw_mgr_ctx->res_list_tfe_out[out_port_id];
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));
}
}
}
end:
return rc;
}
static int cam_tfe_hw_mgr_handle_csid_event(
struct cam_isp_hw_event_info *event_info)
{
@ -5433,8 +5492,10 @@ static int cam_tfe_hw_mgr_handle_csid_event(
}
static int cam_tfe_hw_mgr_handle_hw_err(
void *ctx,
void *evt_info)
{
struct cam_tfe_hw_mgr_ctx *tfe_hw_mgr_ctx;
struct cam_isp_hw_event_info *event_info = evt_info;
struct cam_isp_hw_error_event_data error_event_data = {0};
struct cam_tfe_hw_event_recovery_data recovery_data = {0};
@ -5456,6 +5517,18 @@ static int cam_tfe_hw_mgr_handle_hw_err(
return rc;
}
if (ctx) {
tfe_hw_mgr_ctx =
(struct cam_tfe_hw_mgr_ctx *)ctx;
if (event_info->res_type ==
CAM_ISP_RESOURCE_TFE_IN &&
!tfe_hw_mgr_ctx->is_rdi_only_context &&
event_info->res_id !=
CAM_ISP_HW_TFE_IN_CAMIF)
cam_tfe_hw_mgr_handle_hw_dump_info(
tfe_hw_mgr_ctx, event_info);
}
core_idx = event_info->hw_idx;
if (g_tfe_hw_mgr.debug_cfg.enable_recovery)
@ -5649,6 +5722,12 @@ static int cam_tfe_hw_mgr_handle_hw_eof(
case CAM_ISP_HW_TFE_IN_RDI0:
case CAM_ISP_HW_TFE_IN_RDI1:
case CAM_ISP_HW_TFE_IN_RDI2:
if (!tfe_hw_mgr_ctx->is_rdi_only_context)
break;
if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending))
break;
tfe_hw_irq_eof_cb(tfe_hw_mgr_ctx->common.cb_priv,
CAM_ISP_HW_EVENT_EOF, (void *)&eof_done_event_data);
break;
default:
@ -5732,7 +5811,7 @@ static int cam_tfe_hw_mgr_event_handler(
break;
case CAM_ISP_HW_EVENT_ERROR:
rc = cam_tfe_hw_mgr_handle_hw_err(evt_info);
rc = cam_tfe_hw_mgr_handle_hw_err(priv, evt_info);
break;
default:

View file

@ -124,6 +124,12 @@ static int cam_isp_update_dual_config(
cpu_addr += (cmd_desc->offset / 4);
dual_config = (struct cam_isp_dual_config *)cpu_addr;
if (dual_config->num_ports > size_isp_out) {
CAM_ERR(CAM_ISP, "num_ports %d more than max_vfe_out_res %d",
dual_config->num_ports, size_isp_out);
return -EINVAL;
}
if ((dual_config->num_ports *
sizeof(struct cam_isp_dual_stripe_config)) >
(remain_len - offsetof(struct cam_isp_dual_config, stripes))) {
@ -132,14 +138,6 @@ static int cam_isp_update_dual_config(
}
for (i = 0; i < dual_config->num_ports; i++) {
if (i >= CAM_ISP_IFE_OUT_RES_BASE + size_isp_out) {
CAM_ERR(CAM_ISP,
"failed update for i:%d > size_isp_out:%d",
i, size_isp_out);
rc = -EINVAL;
goto end;
}
hw_mgr_res = &res_list_isp_out[i];
if (!hw_mgr_res) {
CAM_ERR(CAM_ISP,

View file

@ -163,9 +163,7 @@ static int cam_csid_ppi_init_hw(void *hw_priv, void *init_args,
{
int i, rc = 0;
uint32_t num_lanes;
uint32_t lanes[CAM_CSID_PPI_HW_MAX] = {0, 0, 0, 0};
uint32_t cphy;
bool dl0, dl1;
uint32_t ppi_cfg_val = 0;
struct cam_csid_ppi_hw *ppi_hw;
struct cam_hw_info *ppi_hw_info;
@ -180,7 +178,6 @@ static int cam_csid_ppi_init_hw(void *hw_priv, void *init_args,
goto end;
}
dl0 = dl1 = false;
ppi_hw_info = (struct cam_hw_info *)hw_priv;
ppi_hw = (struct cam_csid_ppi_hw *)ppi_hw_info->core_info;
ppi_reg = ppi_hw->ppi_info->ppi_reg;
@ -195,30 +192,15 @@ static int cam_csid_ppi_init_hw(void *hw_priv, void *init_args,
CAM_DBG(CAM_ISP, "lane_cfg 0x%x | num_lanes 0x%x | lane_type 0x%x",
ppi_cfg.lane_cfg, num_lanes, cphy);
for (i = 0; i < num_lanes; i++) {
lanes[i] = ppi_cfg.lane_cfg & (0x3 << (4 * i));
(lanes[i] < 2) ? (dl0 = true) : (dl1 = true);
CAM_DBG(CAM_ISP, "lanes[%d] %d", i, lanes[i]);
if (cphy) {
ppi_cfg_val |= PPI_CFG_CPHY_DLX_SEL(0);
ppi_cfg_val |= PPI_CFG_CPHY_DLX_SEL(1);
} else {
ppi_cfg_val = 0;
}
if (num_lanes) {
if (cphy) {
for (i = 0; i < num_lanes; i++) {
ppi_cfg_val |= PPI_CFG_CPHY_DLX_SEL(lanes[i]);
ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(lanes[i]);
}
} else {
if (dl0)
ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(0);
if (dl1)
ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(1);
}
} else {
CAM_ERR(CAM_ISP,
"Number of lanes to enable is cannot be zero");
rc = -1;
goto end;
}
for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++)
ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(i);
CAM_DBG(CAM_ISP, "ppi_cfg_val 0x%x", ppi_cfg_val);
soc_info = &ppi_hw->hw_info->soc_info;

View file

@ -25,7 +25,7 @@
/*
* Select the PHY (CPHY set '1' or DPHY set '0')
*/
#define PPI_CFG_CPHY_DLX_SEL(X) ((X < 2) ? BIT(X) : 0)
#define PPI_CFG_CPHY_DLX_SEL(X) BIT(X)
#define PPI_CFG_CPHY_DLX_EN(X) BIT(4+X)

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_TFE_CSID_530_H_
@ -134,6 +134,7 @@ static struct cam_tfe_csid_csi2_rx_reg_offset
.csid_csi2_rx_irq_set_addr = 0x2c,
/*CSI2 rx control */
.phy_sel_base = 1,
.csid_csi2_rx_cfg0_addr = 0x100,
.csid_csi2_rx_cfg1_addr = 0x104,
.csid_csi2_rx_capture_ctrl_addr = 0x108,

View file

@ -960,8 +960,14 @@ static int cam_tfe_csid_enable_csi2(
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
/*
* There is one to one mapping for ppi index with phy index
* we do not always update phy sel equal to phy number,for some
* targets "phy_sel = phy_num + 1", and for some targets it is
* "phy_sel = phy_num", ppi_index should be updated accordingly
*/
ppi_index = csid_hw->csi2_rx_cfg.phy_sel - csid_reg->csi2_reg->phy_sel_base;
ppi_index = csid_hw->csi2_rx_cfg.phy_sel;
if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) {
ppi_lane_cfg.lane_type = csid_hw->csi2_rx_cfg.lane_type;
ppi_lane_cfg.lane_num = csid_hw->csi2_rx_cfg.lane_num;
@ -1005,7 +1011,7 @@ static int cam_tfe_csid_disable_csi2(
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
ppi_index = csid_hw->csi2_rx_cfg.phy_sel;
ppi_index = csid_hw->csi2_rx_cfg.phy_sel - csid_reg->csi2_reg->phy_sel_base;
if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) {
/* De-Initialize the PPI bridge */
CAM_DBG(CAM_ISP, "ppi_index to de-init %d\n", ppi_index);
@ -2604,6 +2610,19 @@ static int cam_tfe_csid_set_csid_clock(
return 0;
}
static int cam_tfe_csid_dump_csid_clock(
struct cam_tfe_csid_hw *csid_hw, void *cmd_args)
{
if (!csid_hw)
return -EINVAL;
CAM_INFO(CAM_ISP, "CSID:%d clock rate %llu",
csid_hw->hw_intf->hw_idx,
csid_hw->clk_rate);
return 0;
}
static int cam_tfe_csid_get_csid_clock(
struct cam_tfe_csid_hw *csid_hw, void *cmd_args)
{
@ -2910,6 +2929,9 @@ static int cam_tfe_csid_process_cmd(void *hw_priv,
case CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE:
rc = cam_tfe_csid_set_csid_clock(csid_hw, cmd_args);
break;
case CAM_ISP_HW_CMD_CSID_CLOCK_DUMP:
rc = cam_tfe_csid_dump_csid_clock(csid_hw, cmd_args);
break;
case CAM_TFE_CSID_CMD_GET_REG_DUMP:
rc = cam_tfe_csid_get_regdump(csid_hw, cmd_args);
break;
@ -3513,9 +3535,23 @@ handle_fatal_error:
is_error_irq = true;
}
if (is_error_irq || log_en)
if (is_error_irq || log_en) {
CAM_ERR(CAM_ISP,
"CSID %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x",
csid_hw->hw_intf->hw_idx,
irq_status[TFE_CSID_IRQ_REG_TOP],
irq_status[TFE_CSID_IRQ_REG_RX],
irq_status[TFE_CSID_IRQ_REG_IPP]);
CAM_ERR(CAM_ISP,
"RDI0: 0x%x RDI1: 0x%x RDI2: 0x%x CSID clk:%d",
irq_status[TFE_CSID_IRQ_REG_RDI0],
irq_status[TFE_CSID_IRQ_REG_RDI1],
irq_status[TFE_CSID_IRQ_REG_RDI2],
csid_hw->clk_rate);
cam_tfe_csid_handle_hw_err_irq(csid_hw,
CAM_ISP_HW_ERROR_NONE, irq_status);
}
if (csid_hw->irq_debug_cnt >= CAM_TFE_CSID_IRQ_SOF_DEBUG_CNT_MAX) {
cam_tfe_csid_sof_irq_debug(csid_hw, &sof_irq_debug_en);

View file

@ -185,6 +185,7 @@ struct cam_tfe_csid_csi2_rx_reg_offset {
uint32_t csid_csi2_rx_total_crc_err_addr;
/*configurations */
uint32_t phy_sel_base;
uint32_t csi2_rst_srb_all;
uint32_t csi2_rst_done_shift_val;
uint32_t csi2_irq_mask_all;

View file

@ -444,7 +444,7 @@ static void cam_tfe_log_error_irq_status(
"TFE clock rate:%d TFE total bw applied:%lld",
top_priv->hw_clk_rate,
top_priv->total_bw_applied);
cam_cpas_log_votes();
}
static int cam_tfe_error_irq_bottom_half(

View file

@ -16,6 +16,7 @@
#include "cam_tasklet_util.h"
#include "cam_vfe_bus.h"
#include "cam_vfe_bus_ver2.h"
#include "cam_vfe_soc.h"
#include "cam_vfe_core.h"
#include "cam_debug_util.h"
#include "cam_cpas_api.h"
@ -80,6 +81,12 @@ enum cam_vfe_bus_comp_grp_id {
CAM_VFE_BUS_COMP_GROUP_ID_5 = 0x5,
};
struct cam_vfe_bus_error_info {
uint32_t bitmask;
uint32_t vfe_output;
char *error_description;
};
struct cam_vfe_bus_ver2_common_data {
uint32_t core_index;
void __iomem *mem_base;
@ -99,6 +106,7 @@ struct cam_vfe_bus_ver2_common_data {
uint32_t num_sec_out;
uint32_t addr_no_sync;
cam_hw_mgr_event_cb_func event_cb;
bool is_lite;
bool hw_init;
bool support_consumed_addr;
bool disable_ubwc_comp;
@ -193,6 +201,7 @@ struct cam_vfe_bus_ver2_priv {
struct cam_isp_resource_node bus_client[CAM_VFE_BUS_VER2_MAX_CLIENTS];
struct cam_isp_resource_node comp_grp[CAM_VFE_BUS_VER2_COMP_GRP_MAX];
struct cam_isp_resource_node vfe_out[CAM_VFE_BUS_VER2_VFE_OUT_MAX];
uint32_t vfe_out_map_outtype[CAM_VFE_BUS_VER2_VFE_OUT_MAX];
struct list_head free_comp_grp;
struct list_head free_dual_comp_grp;
@ -204,6 +213,138 @@ struct cam_vfe_bus_ver2_priv {
uint32_t max_out_res;
};
static const struct cam_vfe_bus_error_info vfe_error_list[] = {
{
.bitmask = 0x80000000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_FULL_DISP,
.error_description = "DISP C 1:1"
},
{
.bitmask = 0x40000000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_FULL_DISP,
.error_description = "DISP Y 1:1"
},
{
.bitmask = 0x01000000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG,
.error_description = "STATS TINTLESS BG"
},
{
.bitmask = 0x00800000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST,
.error_description = "STATS BHIST"
},
{
.bitmask = 0x00400000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST,
.error_description = "STATS IHIST"
},
{
.bitmask = 0x00200000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS,
.error_description = "STATS CS"
},
{
.bitmask = 0x00100000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS,
.error_description = "STATS RS"
},
{
.bitmask = 0x00080000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST,
.error_description = "STATS HDR BHIST"
},
{
.bitmask = 0x00040000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF,
.error_description = "STATS BAF"
},
{
.bitmask = 0x00020000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG,
.error_description = "STATS AWB BG"
},
{
.bitmask = 0x00010000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE,
.error_description = "STATS HDR BE"
},
{
.bitmask = 0x00004000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_2PD,
.error_description = "PD"
},
{
.bitmask = 0x00002000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP,
.error_description = "PIXEL RAW DUMP"
},
{
.bitmask = 0x00001000,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_FULL,
.error_description = "VID C 1:1"
},
{
.bitmask = 0x00000800,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_FULL,
.error_description = "VID Y 1:1"
},
{
.bitmask = 0x00000400,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_FD,
.error_description = "FD C"
},
{
.bitmask = 0x00000200,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_FD,
.error_description = "FD Y"
},
{
.bitmask = 0x00000020,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI3,
.error_description = "Full RDI 3"
},
{
.bitmask = 0x00000010,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI2,
.error_description = "Full RDI 2"
},
{
.bitmask = 0x00000008,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI1,
.error_description = "Full RDI 1"
},
{
.bitmask = 0x00000004,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI0,
.error_description = "Full RDI 0"
},
};
static const struct cam_vfe_bus_error_info vfe_lite_error_list[] = {
{
.bitmask = 0x04,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI0,
.error_description = "Lite RDI 0"
},
{
.bitmask = 0x08,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI1,
.error_description = "Lite RDI 1"
},
{
.bitmask = 0x10,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI2,
.error_description = "Lite RDI 2"
},
{
.bitmask = 0x20,
.vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI3,
.error_description = "Lite RDI 3"
}
};
static int cam_vfe_bus_process_cmd(
struct cam_isp_resource_node *priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size);
@ -481,6 +622,22 @@ static enum cam_vfe_bus_ver2_vfe_out_type
}
}
static enum cam_vfe_bus_ver2_vfe_out_type
cam_vfe_bus_ver2_get_out_res_id_and_index(
struct cam_vfe_bus_ver2_priv *bus_priv,
uint32_t res_type, uint32_t *index)
{
uint32_t vfe_out_type;
vfe_out_type = cam_vfe_bus_get_out_res_id(res_type);
if (vfe_out_type == CAM_VFE_BUS_VER2_VFE_OUT_MAX)
*index = CAM_VFE_BUS_VER2_VFE_OUT_MAX;
else
*index = bus_priv->vfe_out_map_outtype[vfe_out_type];
return vfe_out_type;
}
static int cam_vfe_bus_get_num_wm(
enum cam_vfe_bus_ver2_vfe_out_type res_type,
uint32_t format)
@ -1440,6 +1597,94 @@ static int cam_vfe_bus_handle_wm_done_bottom_half(void *handler_priv,
return rc;
}
static int cam_vfe_bus_ver2_print_dimensions(
uint32_t res_id,
struct cam_vfe_bus_ver2_priv *bus_priv)
{
struct cam_isp_resource_node *rsrc_node = NULL;
struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
struct cam_vfe_bus_ver2_common_data *common_data = NULL;
int i;
uint32_t addr_status0, addr_status1;
enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id =
CAM_VFE_BUS_VER2_VFE_OUT_MAX;
uint32_t outmap_index = CAM_VFE_BUS_VER2_VFE_OUT_MAX;
if (!bus_priv) {
CAM_ERR(CAM_ISP, "Invalid bus private data, res_id: %d",
res_id);
return -EINVAL;
}
vfe_out_res_id = cam_vfe_bus_ver2_get_out_res_id_and_index(bus_priv,
res_id, &outmap_index);
if ((vfe_out_res_id == CAM_VFE_BUS_VER2_VFE_OUT_MAX) ||
(outmap_index >= bus_priv->num_out)) {
CAM_WARN_RATE_LIMIT(CAM_ISP,
"target does not support req res id :0x%x outtype:%d index:%d",
res_id,
vfe_out_res_id, outmap_index);
return -EINVAL;
}
rsrc_node = &bus_priv->vfe_out[outmap_index];
rsrc_data = rsrc_node->res_priv;
if (!rsrc_data) {
CAM_ERR(CAM_ISP, "VFE out data is null, res_id: %d",
vfe_out_res_id);
return -EINVAL;
}
for (i = 0; i < rsrc_data->num_wm; i++) {
wm_data = rsrc_data->wm_res[i]->res_priv;
common_data = rsrc_data->common_data;
addr_status0 = cam_io_r_mb(common_data->mem_base +
wm_data->hw_regs->status0);
addr_status1 = cam_io_r_mb(common_data->mem_base +
wm_data->hw_regs->status1);
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_data->index,
wm_data->width,
wm_data->height,
wm_data->stride, wm_data->h_init,
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",
common_data->hw_intf->hw_idx,
wm_data->index,
addr_status0,
addr_status1);
}
return 0;
}
static void cam_vfe_print_violations(
char *error_type,
const struct cam_vfe_bus_error_info *error_list,
uint32_t num_errors,
uint32_t status,
struct cam_vfe_bus_ver2_priv *bus_priv)
{
int i;
for (i = 0; i < num_errors; i++) {
if (status & error_list[i].bitmask) {
CAM_INFO(CAM_ISP, "%s: %s violation",
error_list[i].error_description,
error_type);
if (bus_priv != NULL)
cam_vfe_bus_ver2_print_dimensions(
error_list[i].vfe_output,
bus_priv);
}
}
}
static int cam_vfe_bus_err_bottom_half(void *handler_priv,
void *evt_payload_priv)
@ -1448,7 +1693,10 @@ static int cam_vfe_bus_err_bottom_half(void *handler_priv,
struct cam_vfe_bus_ver2_priv *bus_priv = handler_priv;
struct cam_vfe_bus_ver2_common_data *common_data;
struct cam_isp_hw_event_info evt_info;
const struct cam_vfe_bus_error_info *error_list = NULL;
uint32_t val = 0;
uint32_t error_list_size = 0;
uint32_t status = 0;
if (!handler_priv || !evt_payload_priv)
return -EINVAL;
@ -1459,77 +1707,76 @@ static int cam_vfe_bus_err_bottom_half(void *handler_priv,
val = evt_payload->debug_status_0;
CAM_ERR(CAM_ISP, "Bus Violation: debug_status_0 = 0x%x", val);
if (val & 0x01)
error_list = common_data->is_lite ?
vfe_lite_error_list : vfe_error_list;
error_list_size = common_data->is_lite ?
ARRAY_SIZE(vfe_lite_error_list) : ARRAY_SIZE(vfe_error_list);
if (val & 0x00000004)
CAM_INFO(CAM_ISP, "RDI 0 violation");
if (val & 0x02)
if (val & 0x00000008)
CAM_INFO(CAM_ISP, "RDI 1 violation");
if (val & 0x04)
if (val & 0x00000010)
CAM_INFO(CAM_ISP, "RDI 2 violation");
if (val & 0x08)
CAM_INFO(CAM_ISP, "VID Y 1:1 UBWC violation");
if (val & 0x00000020)
CAM_INFO(CAM_ISP, "RDI 3 violation");
if (val & 0x010)
CAM_INFO(CAM_ISP, "VID C 1:1 UBWC violation");
if (val & 0x020)
CAM_INFO(CAM_ISP, "VID YC 4:1 violation");
if (val & 0x040)
CAM_INFO(CAM_ISP, "VID YC 16:1 violation");
if (val & 0x080)
if (val & 0x00000200)
CAM_INFO(CAM_ISP, "FD Y violation");
if (val & 0x0100)
if (val & 0x00000400)
CAM_INFO(CAM_ISP, "FD C violation");
if (val & 0x0200)
if (val & 0x00001000)
CAM_INFO(CAM_ISP, "VID C 1:1 UBWC violation");
if (val & 0x00000800)
CAM_INFO(CAM_ISP, "VID Y 1:1 UBWC violation");
if (val & 0x00002000)
CAM_INFO(CAM_ISP, "RAW DUMP violation");
if (val & 0x0400)
if (val & 0x00004000)
CAM_INFO(CAM_ISP, "PDAF violation");
if (val & 0x0800)
if (val & 0x00010000)
CAM_INFO(CAM_ISP, "STATs HDR BE violation");
if (val & 0x01000)
CAM_INFO(CAM_ISP, "STATs HDR BHIST violation");
if (val & 0x02000)
CAM_INFO(CAM_ISP, "STATs TINTLESS BG violation");
if (val & 0x04000)
CAM_INFO(CAM_ISP, "STATs BF violation");
if (val & 0x08000)
if (val & 0x00020000)
CAM_INFO(CAM_ISP, "STATs AWB BG UBWC violation");
if (val & 0x010000)
CAM_INFO(CAM_ISP, "STATs BHIST violation");
if (val & 0x00040000)
CAM_INFO(CAM_ISP, "STATs BF violation");
if (val & 0x020000)
if (val & 0x00080000)
CAM_INFO(CAM_ISP, "STATs HDR BHIST violation");
if (val & 0x00100000)
CAM_INFO(CAM_ISP, "STATs RS violation");
if (val & 0x040000)
if (val & 0x00200000)
CAM_INFO(CAM_ISP, "STATs CS violation");
if (val & 0x080000)
if (val & 0x00400000)
CAM_INFO(CAM_ISP, "STATs IHIST violation");
if (val & 0x0100000)
if (val & 0x00800000)
CAM_INFO(CAM_ISP, "STATs BHIST violation");
if (val & 0x01000000)
CAM_INFO(CAM_ISP, "STATs TINTLESS BG violation");
if (val & 0x40000000)
CAM_INFO(CAM_ISP, "DISP Y 1:1 UBWC violation");
if (val & 0x0200000)
if (val & 0x80000000)
CAM_INFO(CAM_ISP, "DISP C 1:1 UBWC violation");
if (val & 0x0400000)
CAM_INFO(CAM_ISP, "DISP YC 4:1 violation");
if (val & 0x0800000)
CAM_INFO(CAM_ISP, "DISP YC 16:1 violation");
cam_vfe_print_violations("Error", error_list,
error_list_size, status, bus_priv);
cam_vfe_bus_put_evt_payload(common_data, &evt_payload);
@ -2550,7 +2797,8 @@ static int cam_vfe_bus_init_vfe_out_resource(uint32_t index,
return -EINVAL;
}
vfe_out = &ver2_bus_priv->vfe_out[vfe_out_type];
ver2_bus_priv->vfe_out_map_outtype[vfe_out_type] = index;
vfe_out = &ver2_bus_priv->vfe_out[index];
if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_UNAVAILABLE ||
vfe_out->res_priv) {
CAM_ERR(CAM_ISP,
@ -3830,6 +4078,7 @@ int cam_vfe_bus_ver2_init(
struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
struct cam_vfe_bus *vfe_bus_local;
struct cam_vfe_bus_ver2_hw_info *ver2_hw_info = bus_hw_info;
struct cam_vfe_soc_private *soc_private = NULL;
CAM_DBG(CAM_ISP, "Enter");
@ -3842,6 +4091,13 @@ int cam_vfe_bus_ver2_init(
goto end;
}
soc_private = soc_info->soc_private;
if (!soc_private) {
CAM_ERR(CAM_ISP, "Invalid soc_private");
rc = -ENODEV;
goto end;
}
vfe_bus_local = kzalloc(sizeof(struct cam_vfe_bus), GFP_KERNEL);
if (!vfe_bus_local) {
CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus");
@ -3876,6 +4132,7 @@ int cam_vfe_bus_ver2_init(
bus_priv->common_data.support_consumed_addr =
ver2_hw_info->support_consumed_addr;
bus_priv->common_data.disable_ubwc_comp = false;
bus_priv->common_data.is_lite = soc_private->is_ife_lite;
mutex_init(&bus_priv->common_data.bus_mutex);
@ -3909,6 +4166,10 @@ int cam_vfe_bus_ver2_init(
}
}
for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++)
bus_priv->vfe_out_map_outtype[i] =
CAM_VFE_BUS_VER2_VFE_OUT_MAX;
for (i = 0; i < bus_priv->num_out; i++) {
rc = cam_vfe_bus_init_vfe_out_resource(i, bus_priv,
bus_hw_info);

View file

@ -48,11 +48,14 @@ static const struct of_device_id cam_jpeg_dt_match[] = {
static int cam_jpeg_subdev_open(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);
mutex_lock(&g_jpeg_dev.jpeg_mutex);
g_jpeg_dev.open_cnt++;
mutex_unlock(&g_jpeg_dev.jpeg_mutex);
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
return 0;
}

View file

@ -761,10 +761,11 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv,
}
if ((packet->num_cmd_buf > 5) || !packet->num_patches ||
!packet->num_io_configs) {
CAM_ERR(CAM_JPEG, "wrong number of cmd/patch info: %u %u",
packet->num_cmd_buf,
packet->num_patches);
!packet->num_io_configs ||
(packet->num_io_configs > CAM_JPEG_IMAGE_MAX)) {
CAM_ERR(CAM_JPEG,
"wrong number of cmd/patch/io_configs info: %u %u %u",
packet->num_cmd_buf, packet->num_patches, packet->num_io_configs);
return -EINVAL;
}

View file

@ -59,9 +59,12 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd,
{
struct cam_lrme_dev *lrme_dev = g_lrme_dev;
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);
if (!lrme_dev) {
CAM_ERR(CAM_LRME,
"LRME Dev not initialized, dev=%pK", lrme_dev);
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
return -ENODEV;
}
@ -69,6 +72,8 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd,
lrme_dev->open_cnt++;
mutex_unlock(&lrme_dev->lock);
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
return 0;
}

View file

@ -69,6 +69,8 @@ static int cam_ope_subdev_open(struct v4l2_subdev *sd,
struct cam_node *node = v4l2_get_subdevdata(sd);
int rc = 0;
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);
mutex_lock(&g_ope_dev.ope_lock);
if (g_ope_dev.open_cnt >= 1) {
CAM_ERR(CAM_OPE, "OPE subdev is already opened");
@ -92,6 +94,7 @@ static int cam_ope_subdev_open(struct v4l2_subdev *sd,
CAM_DBG(CAM_OPE, "OPE HW open success: %d", rc);
end:
mutex_unlock(&g_ope_dev.ope_lock);
cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
return rc;
}

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2022, The Linux Foundation. All rights reserved.
*/
#include <linux/uaccess.h>
@ -19,6 +19,7 @@
#include <media/cam_defs.h>
#include <media/cam_ope.h>
#include <media/cam_cpas.h>
#include <linux/math64.h>
#include "cam_sync_api.h"
#include "cam_packet_util.h"
@ -624,8 +625,8 @@ static bool cam_ope_check_req_delay(struct cam_ope_ctx *ctx_data,
ts.tv_nsec);
if (ts_ns - req_time <
((OPE_REQUEST_TIMEOUT -
OPE_REQUEST_TIMEOUT / 10) * 1000000)) {
((ctx_data->req_timer_timeout -
div_u64(ctx_data->req_timer_timeout, 10)) * 1000000)) {
CAM_INFO(CAM_OPE, "ctx: %d, ts_ns : %llu",
ctx_data->ctx_id, ts_ns);
cam_ope_req_timer_reset(ctx_data);
@ -848,7 +849,7 @@ static int cam_ope_start_req_timer(struct cam_ope_ctx *ctx_data)
int rc = 0;
rc = crm_timer_init(&ctx_data->req_watch_dog,
OPE_REQUEST_TIMEOUT, ctx_data, &cam_ope_req_timer_cb);
ctx_data->req_timer_timeout, ctx_data, &cam_ope_req_timer_cb);
if (rc)
CAM_ERR(CAM_OPE, "Failed to start timer");
@ -2626,11 +2627,15 @@ static int cam_ope_mgr_acquire_hw(void *hw_priv, void *hw_acquire_args)
goto end;
}
strlcpy(cdm_acquire->identifier, "ope", sizeof("ope"));
if (ctx->ope_acquire.dev_type == OPE_DEV_TYPE_OPE_RT)
if (ctx->ope_acquire.dev_type == OPE_DEV_TYPE_OPE_RT) {
cdm_acquire->priority = CAM_CDM_BL_FIFO_3;
ctx->req_timer_timeout = OPE_REQUEST_RT_TIMEOUT;
}
else if (ctx->ope_acquire.dev_type ==
OPE_DEV_TYPE_OPE_NRT)
OPE_DEV_TYPE_OPE_NRT) {
cdm_acquire->priority = CAM_CDM_BL_FIFO_0;
ctx->req_timer_timeout = OPE_REQUEST_NRT_TIMEOUT;
}
else
goto free_cdm_acquire;
@ -3300,7 +3305,7 @@ static int cam_ope_mgr_prepare_hw_update(void *hw_priv,
CAM_DBG(CAM_REQ, "req_id= %llu ctx_id= %d lrt=%llu",
packet->header.request_id, ctx_data->ctx_id,
ctx_data->last_req_time);
cam_ope_req_timer_modify(ctx_data, OPE_REQUEST_TIMEOUT);
cam_ope_req_timer_modify(ctx_data, ctx_data->req_timer_timeout);
set_bit(request_idx, ctx_data->bitmap);
mutex_unlock(&ctx_data->ctx_mutex);
@ -3620,7 +3625,7 @@ static int cam_ope_mgr_hw_dump(void *hw_priv, void *hw_dump_args)
cur_ts = ktime_to_timespec64(cur_time);
req_ts = ktime_to_timespec64(ctx_data->req_list[idx]->submit_timestamp);
if (diff < (OPE_REQUEST_TIMEOUT * 1000)) {
if (diff < (ctx_data->req_timer_timeout * 1000)) {
CAM_INFO(CAM_OPE, "No Error req %llu %ld:%06ld %ld:%06ld",
dump_args->request_id,
req_ts.tv_sec,

View file

@ -50,7 +50,7 @@
#define OPE_CMDS OPE_MAX_CMD_BUFS
#define CAM_MAX_IN_RES 8
#define OPE_MAX_CDM_BLS 24
#define OPE_MAX_CDM_BLS 32
#define CAM_OPE_MAX_PER_PATH_VOTES 6
#define CAM_OPE_BW_CONFIG_UNKNOWN 0
@ -60,7 +60,8 @@
#define CLK_HW_MAX 0x1
#define OPE_DEVICE_IDLE_TIMEOUT 400
#define OPE_REQUEST_TIMEOUT 200
#define OPE_REQUEST_RT_TIMEOUT 200
#define OPE_REQUEST_NRT_TIMEOUT 400
/**
* struct cam_ope_clk_bw_request_v2
@ -447,6 +448,7 @@ struct cam_ope_cdm {
* @clk_watch_dog: Clock watchdog
* @clk_watch_dog_reset_counter: Reset counter
* @last_flush_req: last flush req for this ctx
* @req_timer_timeout: req timer timeout value
*/
struct cam_ope_ctx {
void *context_priv;
@ -470,6 +472,7 @@ struct cam_ope_ctx {
uint32_t clk_watch_dog_reset_counter;
uint64_t last_flush_req;
bool pf_mid_found;
uint64_t req_timer_timeout;
};
/**

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@ -758,7 +759,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd)
tbl.bufq[idx].kmdvaddr = kvaddr;
tbl.bufq[idx].vaddr = hw_vaddr;
tbl.bufq[idx].dma_buf = dmabuf;
tbl.bufq[idx].len = cmd->len;
tbl.bufq[idx].len = len;
tbl.bufq[idx].num_hdl = cmd->num_hdl;
memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls,
sizeof(int32_t) * cmd->num_hdl);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@ -1714,20 +1715,20 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
return -EINVAL;
}
mutex_lock(&session->lock);
/*
* In case if the wq is scheduled while destroying session
* the session mutex is already taken and will cause a
* dead lock. To avoid further processing check link state
* and exit.
* During session destroy/unlink the link state is updated and session
* mutex is released when flushing the workq. In case the wq is scheduled
* thereafter this API will then check the updated link state and exit
*/
spin_lock_bh(&link->link_state_spin_lock);
if (link->state == CAM_CRM_LINK_STATE_IDLE) {
spin_unlock_bh(&link->link_state_spin_lock);
mutex_unlock(&session->lock);
return -EPERM;
}
spin_unlock_bh(&link->link_state_spin_lock);
mutex_lock(&session->lock);
in_q = link->req.in_q;
/*
* Check if new read index,
@ -2281,10 +2282,13 @@ static int __cam_req_mgr_create_subdevs(
*
*/
static void __cam_req_mgr_destroy_subdev(
struct cam_req_mgr_connected_device *l_device)
struct cam_req_mgr_connected_device **l_device)
{
kfree(l_device);
l_device = NULL;
CAM_DBG(CAM_CRM, "*l_device %pK", *l_device);
if (*(l_device) != NULL) {
kfree(*(l_device));
*l_device = NULL;
}
}
/**
@ -3786,13 +3790,17 @@ end:
/**
* __cam_req_mgr_unlink()
*
* @brief : Unlink devices on a link structure from the session
* @link : Pointer to the link structure
* @brief : Unlink devices on a link structure from the session
* This API is to be invoked with session mutex held
* @session: session of the link
* @link : Pointer to the link structure
*
* @return: 0 for success, negative for failure
*
*/
static int __cam_req_mgr_unlink(struct cam_req_mgr_core_link *link)
static int __cam_req_mgr_unlink(
struct cam_req_mgr_core_session *session,
struct cam_req_mgr_core_link *link)
{
int rc;
@ -3808,19 +3816,21 @@ static int __cam_req_mgr_unlink(struct cam_req_mgr_core_link *link)
}
mutex_lock(&link->lock);
spin_lock_bh(&link->link_state_spin_lock);
/* Destroy timer of link */
crm_timer_exit(&link->watchdog);
spin_unlock_bh(&link->link_state_spin_lock);
/* Release session mutex for workq processing */
mutex_unlock(&session->lock);
/* Destroy workq of link */
cam_req_mgr_workq_destroy(&link->workq);
/* Acquire session mutex after workq flush */
mutex_lock(&session->lock);
/* Cleanup request tables and unlink devices */
__cam_req_mgr_destroy_link_info(link);
/* Free memory holding data of linked devs */
__cam_req_mgr_destroy_subdev(link->l_dev);
__cam_req_mgr_destroy_subdev(&link->l_dev);
/* Destroy the link handle */
rc = cam_destroy_device_hdl(link->link_hdl);
@ -3851,12 +3861,15 @@ int cam_req_mgr_destroy_session(
mutex_lock(&g_crm_core_dev->crm_lock);
cam_session = (struct cam_req_mgr_core_session *)
cam_get_device_priv(ses_info->session_hdl);
if (!cam_session) {
CAM_ERR(CAM_CRM, "failed to get session priv");
if (!cam_session || (cam_session->session_hdl != ses_info->session_hdl)) {
CAM_ERR(CAM_CRM, "session: %s, ses_info->ses_hdl:%x, session->ses_hdl:%x",
CAM_IS_NULL_TO_STR(cam_session), ses_info->session_hdl,
(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
rc = -ENOENT;
goto end;
}
mutex_lock(&cam_session->lock);
if (cam_session->num_links) {
CAM_DBG(CAM_CRM, "destroy session %x num_active_links %d",
@ -3872,7 +3885,7 @@ int cam_req_mgr_destroy_session(
link->link_hdl);
/* Ignore return value since session is going away */
link->is_shutdown = is_shutdown;
__cam_req_mgr_unlink(link);
__cam_req_mgr_unlink(cam_session, link);
__cam_req_mgr_free_link(link);
}
}
@ -3921,8 +3934,10 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info)
/* session hdl's priv data is cam session struct */
cam_session = (struct cam_req_mgr_core_session *)
cam_get_device_priv(link_info->u.link_info_v1.session_hdl);
if (!cam_session) {
CAM_DBG(CAM_CRM, "NULL pointer");
if (!cam_session || (cam_session->session_hdl != link_info->u.link_info_v1.session_hdl)) {
CAM_ERR(CAM_CRM, "session: %s, link_info->ses_hdl:%x, session->ses_hdl:%x",
CAM_IS_NULL_TO_STR(cam_session), link_info->u.link_info_v1.session_hdl,
(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
mutex_unlock(&g_crm_core_dev->crm_lock);
return -EINVAL;
}
@ -3995,7 +4010,7 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info)
mutex_unlock(&g_crm_core_dev->crm_lock);
return rc;
setup_failed:
__cam_req_mgr_destroy_subdev(link->l_dev);
__cam_req_mgr_destroy_subdev(&link->l_dev);
create_subdev_failed:
cam_destroy_device_hdl(link->link_hdl);
link_info->u.link_info_v1.link_hdl = -1;
@ -4031,8 +4046,10 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
/* session hdl's priv data is cam session struct */
cam_session = (struct cam_req_mgr_core_session *)
cam_get_device_priv(link_info->u.link_info_v2.session_hdl);
if (!cam_session) {
CAM_DBG(CAM_CRM, "NULL pointer");
if (!cam_session || (cam_session->session_hdl != link_info->u.link_info_v2.session_hdl)) {
CAM_ERR(CAM_CRM, "session: %s, link_info->ses_hdl:%x, session->ses_hdl:%x",
CAM_IS_NULL_TO_STR(cam_session), link_info->u.link_info_v2.session_hdl,
(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
mutex_unlock(&g_crm_core_dev->crm_lock);
return -EINVAL;
}
@ -4111,7 +4128,7 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
mutex_unlock(&g_crm_core_dev->crm_lock);
return rc;
setup_failed:
__cam_req_mgr_destroy_subdev(link->l_dev);
__cam_req_mgr_destroy_subdev(&link->l_dev);
create_subdev_failed:
cam_destroy_device_hdl(link->link_hdl);
link_info->u.link_info_v2.link_hdl = -1;
@ -4140,21 +4157,26 @@ int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info)
/* session hdl's priv data is cam session struct */
cam_session = (struct cam_req_mgr_core_session *)
cam_get_device_priv(unlink_info->session_hdl);
if (!cam_session) {
CAM_ERR(CAM_CRM, "NULL pointer");
if (!cam_session || (cam_session->session_hdl != unlink_info->session_hdl)) {
CAM_ERR(CAM_CRM, "session: %s, unlink_info->ses_hdl:%x, cam_session->ses_hdl:%x",
CAM_IS_NULL_TO_STR(cam_session), unlink_info->session_hdl,
(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
mutex_unlock(&g_crm_core_dev->crm_lock);
return -EINVAL;
}
/* link hdl's priv data is core_link struct */
link = cam_get_device_priv(unlink_info->link_hdl);
if (!link) {
CAM_ERR(CAM_CRM, "NULL pointer");
if (!link || (link->link_hdl != unlink_info->link_hdl)) {
CAM_ERR(CAM_CRM, "link: %s, unlink_info->link_hdl:%x, link->link_hdl:%x",
CAM_IS_NULL_TO_STR(link), unlink_info->link_hdl,
(!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl);
rc = -EINVAL;
goto done;
}
rc = __cam_req_mgr_unlink(link);
mutex_lock(&cam_session->lock);
rc = __cam_req_mgr_unlink(cam_session, link);
mutex_unlock(&cam_session->lock);
/* Free curent link and put back into session's free pool of links */
__cam_req_mgr_unreserve_link(cam_session, link);
@ -4181,8 +4203,10 @@ int cam_req_mgr_schedule_request(
mutex_lock(&g_crm_core_dev->crm_lock);
link = (struct cam_req_mgr_core_link *)
cam_get_device_priv(sched_req->link_hdl);
if (!link) {
CAM_DBG(CAM_CRM, "link ptr NULL %x", sched_req->link_hdl);
if (!link || (link->link_hdl != sched_req->link_hdl)) {
CAM_ERR(CAM_CRM, "link: %s, sched_req->link_hdl:%x, link->link_hdl:%x",
CAM_IS_NULL_TO_STR(link), sched_req->link_hdl,
(!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl);
rc = -EINVAL;
goto end;
}
@ -4266,8 +4290,10 @@ int cam_req_mgr_sync_config(
/* session hdl's priv data is cam session struct */
cam_session = (struct cam_req_mgr_core_session *)
cam_get_device_priv(sync_info->session_hdl);
if (!cam_session) {
CAM_ERR(CAM_CRM, "NULL pointer");
if (!cam_session || (cam_session->session_hdl != sync_info->session_hdl)) {
CAM_ERR(CAM_CRM, "session: %s, sync_info->session_hdl:%x, session->ses_hdl:%x",
CAM_IS_NULL_TO_STR(cam_session), sync_info->session_hdl,
(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
mutex_unlock(&g_crm_core_dev->crm_lock);
return -EINVAL;
}
@ -4283,8 +4309,10 @@ int cam_req_mgr_sync_config(
}
link[i] = cam_get_device_priv(sync_info->link_hdls[i]);
if (!link[i]) {
CAM_ERR(CAM_CRM, "link%d NULL pointer", i);
if (!link[i] || (link[i]->link_hdl != sync_info->link_hdls[i])) {
CAM_ERR(CAM_CRM, "link: %s, sync_info->link_hdl:%x, link->link_hdl:%x",
CAM_IS_NULL_TO_STR(link), sync_info->link_hdls[i],
(!link[i]) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link[i]->link_hdl);
rc = -EINVAL;
goto done;
}
@ -4360,8 +4388,10 @@ int cam_req_mgr_flush_requests(
/* session hdl's priv data is cam session struct */
session = (struct cam_req_mgr_core_session *)
cam_get_device_priv(flush_info->session_hdl);
if (!session) {
CAM_ERR(CAM_CRM, "Invalid session %x", flush_info->session_hdl);
if (!session || (session->session_hdl != flush_info->session_hdl)) {
CAM_ERR(CAM_CRM, "session: %s, flush_info->ses_hdl:%x, session->ses_hdl:%x",
CAM_IS_NULL_TO_STR(session), flush_info->session_hdl,
(!session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : session->session_hdl);
rc = -EINVAL;
goto end;
}
@ -4373,8 +4403,10 @@ int cam_req_mgr_flush_requests(
link = (struct cam_req_mgr_core_link *)
cam_get_device_priv(flush_info->link_hdl);
if (!link) {
CAM_DBG(CAM_CRM, "link ptr NULL %x", flush_info->link_hdl);
if (!link || (link->link_hdl != flush_info->link_hdl)) {
CAM_ERR(CAM_CRM, "link: %s, flush_info->link_hdl:%x, link->link_hdl:%x",
CAM_IS_NULL_TO_STR(link), flush_info->link_hdl,
(!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl);
rc = -EINVAL;
goto end;
}
@ -4432,9 +4464,10 @@ int cam_req_mgr_link_control(struct cam_req_mgr_link_control *control)
for (i = 0; i < control->num_links; i++) {
link = (struct cam_req_mgr_core_link *)
cam_get_device_priv(control->link_hdls[i]);
if (!link) {
CAM_ERR(CAM_CRM, "Link(%d) is NULL on session 0x%x",
i, control->session_hdl);
if (!link || (link->link_hdl != control->link_hdls[i])) {
CAM_ERR(CAM_CRM, "link: %s, control->link_hdl:%x, link->link_hdl:%x",
CAM_IS_NULL_TO_STR(link), control->link_hdls[i],
(!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl);
rc = -EINVAL;
break;
}
@ -4520,9 +4553,10 @@ int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req)
/* session hdl's priv data is cam session struct */
session = (struct cam_req_mgr_core_session *)
cam_get_device_priv(dump_req->session_handle);
if (!session) {
CAM_ERR(CAM_CRM, "Invalid session %x",
dump_req->session_handle);
if (!session || (session->session_hdl != dump_req->session_handle)) {
CAM_ERR(CAM_CRM, "session: %s, dump_req->ses_hdl:%x, session->ses_hdl:%x",
CAM_IS_NULL_TO_STR(session), dump_req->session_handle,
(!session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : session->session_hdl);
rc = -EINVAL;
goto end;
}
@ -4534,8 +4568,10 @@ int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req)
link = (struct cam_req_mgr_core_link *)
cam_get_device_priv(dump_req->link_hdl);
if (!link) {
CAM_DBG(CAM_CRM, "link ptr NULL %x", dump_req->link_hdl);
if (!link || (link->link_hdl != dump_req->link_hdl)) {
CAM_ERR(CAM_CRM, "link: %s, dump_req->link_hdl:%x, link->link_hdl:%x",
CAM_IS_NULL_TO_STR(link), dump_req->link_hdl,
(!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl);
rc = -EINVAL;
goto end;
}

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_REQ_MGR_CORE_H_
#define _CAM_REQ_MGR_CORE_H_
@ -18,6 +19,7 @@
#define CAM_REQ_MGR_WATCHDOG_TIMEOUT_MAX 50000
#define CAM_REQ_MGR_SCHED_REQ_TIMEOUT 1000
#define CAM_REQ_MGR_SIMULATE_SCHED_REQ 30
#define CAM_REQ_MGR_DEFAULT_HDL_VAL 0
#define FORCE_DISABLE_RECOVERY 2
#define FORCE_ENABLE_RECOVERY 1

View file

@ -8,6 +8,7 @@
#include <linux/platform_device.h>
#include <linux/highmem.h>
#include <linux/types.h>
#include <linux/rwsem.h>
#include <mm/slab.h>
@ -35,6 +36,8 @@ static struct cam_req_mgr_device g_dev;
struct kmem_cache *g_cam_req_mgr_timer_cachep;
static struct list_head cam_req_mgr_ordered_sd_list;
DECLARE_RWSEM(rwsem_lock);
static struct device_attribute camera_debug_sysfs_attr =
__ATTR(debug_node, 0600, NULL, cam_debug_sysfs_node_store);
@ -103,10 +106,29 @@ static void cam_v4l2_device_cleanup(void)
g_dev.v4l2_dev = NULL;
}
void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock)
{
if (lock == CAM_SUBDEV_LOCK)
down_read(&rwsem_lock);
else if (lock == CAM_SUBDEV_UNLOCK)
up_read(&rwsem_lock);
}
static void cam_req_mgr_rwsem_write_op(enum cam_subdev_rwsem lock)
{
if (lock == CAM_SUBDEV_LOCK)
down_write(&rwsem_lock);
else if (lock == CAM_SUBDEV_UNLOCK)
up_write(&rwsem_lock);
}
static int cam_req_mgr_open(struct file *filep)
{
int rc;
cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK);
mutex_lock(&g_dev.cam_lock);
if (g_dev.open_cnt >= 1) {
rc = -EALREADY;
@ -133,12 +155,14 @@ static int cam_req_mgr_open(struct file *filep)
}
mutex_unlock(&g_dev.cam_lock);
cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK);
return rc;
mem_mgr_init_fail:
v4l2_fh_release(filep);
end:
mutex_unlock(&g_dev.cam_lock);
cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK);
return rc;
}
@ -168,10 +192,14 @@ static int cam_req_mgr_close(struct file *filep)
CAM_WARN(CAM_CRM,
"release invoked associated userspace process has died, open_cnt: %d",
g_dev.open_cnt);
cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK);
mutex_lock(&g_dev.cam_lock);
if (g_dev.open_cnt <= 0) {
mutex_unlock(&g_dev.cam_lock);
cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK);
return -EINVAL;
}
@ -203,6 +231,8 @@ static int cam_req_mgr_close(struct file *filep)
cam_mem_mgr_deinit();
mutex_unlock(&g_dev.cam_lock);
cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK);
return 0;
}

View file

@ -15,6 +15,7 @@
#include "cam_req_mgr_util.h"
#include "cam_debug_util.h"
#include "cam_context.h"
#include "cam_subdev.h"
static struct cam_req_mgr_util_hdl_tbl *hdl_tbl;
static DEFINE_SPINLOCK(hdl_tbl_lock);
@ -115,7 +116,7 @@ static int32_t cam_get_free_handle_index(void)
idx = find_first_zero_bit(hdl_tbl->bitmap, hdl_tbl->bits);
if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2 || idx < 0) {
CAM_DBG(CAM_CRM, "idx: %d", idx);
CAM_ERR(CAM_CRM, "No free index found idx: %d", idx);
return -ENOSR;
}
@ -124,20 +125,6 @@ static int32_t cam_get_free_handle_index(void)
return idx;
}
void cam_dump_tbl_info(void)
{
int i;
for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES_V2; i++)
CAM_INFO(CAM_CRM,
"i: %d session_hdl=0x%x hdl_value=0x%x type=%d state=%d dev_id=0x%llx",
i, hdl_tbl->hdl[i].session_hdl,
hdl_tbl->hdl[i].hdl_value,
hdl_tbl->hdl[i].type,
hdl_tbl->hdl[i].state,
hdl_tbl->hdl[i].dev_id);
}
int32_t cam_create_session_hdl(void *priv)
{
int idx;
@ -154,7 +141,6 @@ int32_t cam_create_session_hdl(void *priv)
idx = cam_get_free_handle_index();
if (idx < 0) {
CAM_ERR(CAM_CRM, "Unable to create session handle");
cam_dump_tbl_info();
spin_unlock_bh(&hdl_tbl_lock);
return idx;
}
@ -178,6 +164,14 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
int idx;
int rand = 0;
int32_t handle;
bool crm_active;
crm_active = cam_req_mgr_is_open(CAM_CRM);
if (!crm_active) {
CAM_ERR(CAM_CRM, "CRM is not ACTIVE");
spin_unlock_bh(&hdl_tbl_lock);
return -EINVAL;
}
spin_lock_bh(&hdl_tbl_lock);
if (!hdl_tbl) {
@ -190,7 +184,6 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
if (idx < 0) {
CAM_ERR(CAM_CRM,
"Unable to create device handle(idx= %d)", idx);
cam_dump_tbl_info();
spin_unlock_bh(&hdl_tbl_lock);
return idx;
}

View file

@ -28,6 +28,11 @@ enum cam_subdev_close_seq_priority {
CAM_SD_CLOSE_LOW_PRIORITY
};
enum cam_subdev_rwsem {
CAM_SUBDEV_LOCK = 1,
CAM_SUBDEV_UNLOCK,
};
/**
* struct cam_subdev - describes a camera sub-device
*
@ -130,6 +135,15 @@ int cam_register_subdev(struct cam_subdev *sd);
*/
int cam_unregister_subdev(struct cam_subdev *sd);
/**
* cam_req_mgr_rwsem_read_op()
*
* @brief : API to acquire read semaphore lock to platform framework.
*
* @lock : value indicates to lock or unlock the read lock
*/
void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock);
/**
* cam_req_mgr_is_open()
*

View file

@ -859,6 +859,11 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl,
actuator_acq_dev.device_handle =
cam_create_device_hdl(&bridge_params);
if (actuator_acq_dev.device_handle <= 0) {
rc = -EFAULT;
CAM_ERR(CAM_ACTUATOR, "Can not create device handle");
goto release_mutex;
}
a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle;
a_ctrl->bridge_intf.session_hdl =
actuator_acq_dev.session_handle;

View file

@ -1182,6 +1182,12 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
index = csiphy_dev->acquire_count;
csiphy_acq_dev.device_handle =
cam_create_device_hdl(&bridge_params);
if (csiphy_acq_dev.device_handle <= 0) {
rc = -EFAULT;
CAM_ERR(CAM_CSIPHY, "Can not create device handle");
goto release_mutex;
}
csiphy_dev->csiphy_info[index].hdl_data.device_hdl =
csiphy_acq_dev.device_handle;
csiphy_dev->csiphy_info[index].hdl_data.session_hdl =

View file

@ -360,6 +360,10 @@ static int32_t cam_eeprom_get_dev_handle(struct cam_eeprom_ctrl_t *e_ctrl,
eeprom_acq_dev.device_handle =
cam_create_device_hdl(&bridge_params);
if (eeprom_acq_dev.device_handle <= 0) {
CAM_ERR(CAM_EEPROM, "Can not create device handle");
return -EFAULT;
}
e_ctrl->bridge_intf.device_hdl = eeprom_acq_dev.device_handle;
e_ctrl->bridge_intf.session_hdl = eeprom_acq_dev.session_handle;

View file

@ -68,6 +68,11 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
flash_acq_dev.device_handle =
cam_create_device_hdl(&bridge_params);
if (flash_acq_dev.device_handle <= 0) {
rc = -EFAULT;
CAM_ERR(CAM_FLASH, "Can not create device handle");
goto release_mutex;
}
fctrl->bridge_intf.device_hdl =
flash_acq_dev.device_handle;
fctrl->bridge_intf.session_hdl =
@ -429,6 +434,7 @@ static int cam_flash_component_bind(struct device *dev,
return -ENOMEM;
fctrl->pdev = pdev;
fctrl->of_node = pdev->dev.of_node;
fctrl->soc_info.pdev = pdev;
fctrl->soc_info.dev = &pdev->dev;
fctrl->soc_info.dev_name = pdev->name;
@ -600,13 +606,18 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client,
{
int32_t rc = 0, i = 0;
struct cam_flash_ctrl *fctrl;
struct cam_hw_soc_info *soc_info = NULL;
if (client == NULL || id == NULL) {
CAM_ERR(CAM_FLASH, "Invalid Args client: %pK id: %pK",
client, id);
if (client == NULL) {
CAM_ERR(CAM_FLASH, "Invalid Args client: %pK",
client);
return -EINVAL;
}
if (id == NULL) {
CAM_DBG(CAM_FLASH, "device id is Null");
}
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
CAM_ERR(CAM_FLASH, "%s :: i2c_check_functionality failed",
client->name);
@ -618,9 +629,9 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client,
if (!fctrl)
return -ENOMEM;
i2c_set_clientdata(client, fctrl);
client->dev.driver_data = fctrl;
fctrl->io_master_info.client = client;
fctrl->of_node = client->dev.of_node;
fctrl->soc_info.dev = &client->dev;
fctrl->soc_info.dev_name = client->name;
fctrl->io_master_info.master_type = I2C_MASTER;
@ -631,6 +642,40 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client,
goto free_ctrl;
}
rc = cam_flash_init_default_params(fctrl);
if (rc) {
CAM_ERR(CAM_FLASH,
"failed: cam_flash_init_default_params rc %d",
rc);
goto free_ctrl;
}
soc_info = &fctrl->soc_info;
rc = cam_sensor_util_regulator_powerup(soc_info);
if (rc < 0) {
CAM_ERR(CAM_FLASH, "regulator power up for flash failed %d",
rc);
goto free_ctrl;
}
if (!soc_info->gpio_data) {
CAM_DBG(CAM_FLASH, "No GPIO found");
rc = 0;
return rc;
}
if (!soc_info->gpio_data->cam_gpio_common_tbl_size) {
CAM_DBG(CAM_FLASH, "No GPIO found");
return -EINVAL;
}
rc = cam_sensor_util_init_gpio_pin_tbl(soc_info,
&fctrl->power_info.gpio_num_info);
if ((rc < 0) || (!fctrl->power_info.gpio_num_info)) {
CAM_ERR(CAM_FLASH, "No/Error Flash GPIOs");
goto free_ctrl;
}
rc = cam_flash_init_subdev(fctrl);
if (rc)
goto free_ctrl;
@ -699,6 +744,7 @@ static struct i2c_driver cam_flash_i2c_driver = {
.remove = cam_flash_i2c_driver_remove,
.driver = {
.name = FLASH_DRIVER_I2C,
.of_match_table = cam_flash_dt_match,
},
};
@ -713,8 +759,9 @@ int32_t cam_flash_init_module(void)
}
rc = i2c_add_driver(&cam_flash_i2c_driver);
if (rc)
if (rc < 0)
CAM_ERR(CAM_FLASH, "i2c_add_driver failed rc: %d", rc);
return rc;
}

View file

@ -293,7 +293,14 @@ int cam_flash_get_dt_data(struct cam_flash_ctrl *fctrl,
rc = -ENOMEM;
goto release_soc_res;
}
of_node = fctrl->pdev->dev.of_node;
if (fctrl->of_node == NULL) {
CAM_ERR(CAM_FLASH, "device node is NULL");
rc = -EINVAL;
goto free_soc_private;
}
of_node = fctrl->of_node;
rc = cam_soc_util_get_dt_properties(soc_info);
if (rc) {

View file

@ -86,6 +86,10 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl,
ois_acq_dev.device_handle =
cam_create_device_hdl(&bridge_params);
if (ois_acq_dev.device_handle <= 0) {
CAM_ERR(CAM_OIS, "Can not create device handle");
return -EFAULT;
}
o_ctrl->bridge_intf.device_hdl = ois_acq_dev.device_handle;
o_ctrl->bridge_intf.session_hdl = ois_acq_dev.session_handle;

View file

@ -839,6 +839,11 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
sensor_acq_dev.device_handle =
cam_create_device_hdl(&bridge_params);
if (sensor_acq_dev.device_handle <= 0) {
rc = -EFAULT;
CAM_ERR(CAM_SENSOR, "Can not create device handle");
goto release_mutex;
}
s_ctrl->bridge_intf.device_hdl = sensor_acq_dev.device_handle;
s_ctrl->bridge_intf.session_hdl = sensor_acq_dev.session_handle;

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#include "cam_sensor_cmn_header.h"
@ -31,9 +31,14 @@ static int32_t cam_qup_i2c_rxdata(
},
};
rc = i2c_transfer(dev_client->adapter, msgs, 2);
if (rc < 0)
if (rc < 0) {
CAM_ERR(CAM_SENSOR, "failed 0x%x", saddr);
return rc;
return rc;
}
/* Returns negative errno */
/* else the number of messages executed. */
/* So positive values are not errors. */
return 0;
}
@ -52,9 +57,14 @@ static int32_t cam_qup_i2c_txdata(
},
};
rc = i2c_transfer(dev_client->client->adapter, msg, 1);
if (rc < 0)
if (rc < 0) {
CAM_ERR(CAM_SENSOR, "failed 0x%x", saddr);
return rc;
return rc;
}
/* Returns negative errno, */
/* else the number of messages executed. */
/* So positive values are not errors. */
return 0;
}
int32_t cam_qup_i2c_read(struct i2c_client *client,

View file

@ -74,11 +74,11 @@ int32_t cam_sensor_util_regulator_powerup(struct cam_hw_soc_info *soc_info)
if (IS_ERR_OR_NULL(soc_info->rgltr[i])) {
rc = PTR_ERR(soc_info->rgltr[i]);
rc = rc ? rc : -EINVAL;
CAM_ERR(CAM_ACTUATOR, "get failed for regulator %s %d",
CAM_ERR(CAM_SENSOR, "get failed for regulator %s %d",
soc_info->rgltr_name[i], rc);
return rc;
}
CAM_DBG(CAM_ACTUATOR, "get for regulator %s",
CAM_DBG(CAM_SENSOR, "get for regulator %s",
soc_info->rgltr_name[i]);
}

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_DEBUG_UTIL_H_
@ -8,6 +9,8 @@
#include <linux/platform_device.h>
#define CAM_IS_NULL_TO_STR(ptr) ((ptr) ? "Non-NULL" : "NULL")
/* Module IDs used for debug logging */
#define CAM_CDM (1 << 0)
#define CAM_CORE (1 << 1)

View file

@ -73,7 +73,7 @@
#define OPE_MAX_IO_BUFS (OPE_OUT_RES_MAX + OPE_IN_RES_MAX)
#define OPE_MAX_PASS 1
#define OPE_MAX_PLANES 2
#define OPE_MAX_STRIPES 48
#define OPE_MAX_STRIPES 64
#define OPE_MAX_BATCH_SIZE 16
/**