mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 15:49:17 -04:00
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:
commit
82f295420d
46 changed files with 853 additions and 203 deletions
|
|
@ -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))
|
||||
|
|
|
|||
18
techpack/camera/config/sm6150camera.conf
Normal file
18
techpack/camera/config/sm6150camera.conf
Normal 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
|
||||
12
techpack/camera/config/sm6150cameraconf.h
Normal file
12
techpack/camera/config/sm6150cameraconf.h
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue