Merge e40030134a on remote branch

Change-Id: I61a691b1a48beb1b0c29c6e32201ff910bcec383
This commit is contained in:
Linux Build Service Account 2021-06-22 23:53:49 -07:00
commit f873ee2ea4
66 changed files with 1624 additions and 216 deletions

View file

@ -14,6 +14,10 @@ ifeq ($(CONFIG_ARCH_BENGAL), y)
include $(srctree)/techpack/camera/config/bengalcamera.conf
endif
ifeq ($(CONFIG_ARCH_MONACO), y)
include $(srctree)/techpack/camera/config/monacocamera.conf
endif
ifeq ($(CONFIG_ARCH_LAHAINA), y)
include $(srctree)/techpack/camera/config/lahainacamera.conf
endif
@ -22,6 +26,10 @@ ifeq ($(CONFIG_ARCH_HOLI), y)
include $(srctree)/techpack/camera/config/holicamera.conf
endif
ifeq ($(CONFIG_ARCH_BLAIR), y)
include $(srctree)/techpack/camera/config/blaircamera.conf
endif
ifeq ($(CONFIG_ARCH_SHIMA), y)
include $(srctree)/techpack/camera/config/shimacamera.conf
endif
@ -45,6 +53,11 @@ LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/bengalcameraconf.h
endif
ifeq ($(CONFIG_ARCH_MONACO), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/monacocameraconf.h
endif
ifeq ($(CONFIG_ARCH_LAHAINA), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/lahainacameraconf.h
@ -55,6 +68,11 @@ LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/holicameraconf.h
endif
ifeq ($(CONFIG_ARCH_BLAIR), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/blaircameraconf.h
endif
ifeq ($(CONFIG_ARCH_SHIMA), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/shimacameraconf.h

17
config/blaircamera.conf Normal file
View file

@ -0,0 +1,17 @@
# 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 "SPECTRA_CAMERA IS STATIC")
else
$(info "SPECTRA_CAMERA IS MODULAR")
export CONFIG_SPECTRA_CAMERA=m
endif
ifneq (,$(filter $(CONFIG_SPECTRA_CAMERA), y m))
export CONFIG_SPECTRA_ISP=y
export CONFIG_SPECTRA_OPE=y
export CONFIG_SPECTRA_TFE=y
export CONFIG_SPECTRA_SENSOR=y
endif

10
config/blaircameraconf.h Normal file
View file

@ -0,0 +1,10 @@
/* 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_OPE 1
#define CONFIG_SPECTRA_TFE 1
#define CONFIG_SPECTRA_SENSOR 1

8
config/monacocamera.conf Normal file
View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2019,2021 The Linux Foundation. All rights reserved.
export CONFIG_SPECTRA_CAMERA=y
export CONFIG_SPECTRA_TFE=y
export CONFIG_SPECTRA_ISP=y
export CONFIG_SPECTRA_SENSOR=y
export CONFIG_SPECTRA_OPE=y

11
config/monacocameraconf.h Normal file
View file

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

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 <linux/slab.h>
@ -583,6 +583,31 @@ int cam_context_handle_stop_dev(struct cam_context *ctx,
return rc;
}
int cam_context_handle_shutdown_dev(struct cam_context *ctx,
struct cam_control *cmd, struct v4l2_subdev_fh *fh)
{
int rc = 0;
if (!ctx || !ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!cmd) {
CAM_ERR(CAM_CORE, "Invalid stop device command payload");
return -EINVAL;
}
if (ctx->state_machine[ctx->state].ioctl_ops.shutdown_dev)
rc = ctx->state_machine[ctx->state].ioctl_ops.shutdown_dev(
(struct v4l2_subdev *)cmd->handle, fh);
else
CAM_WARN(CAM_CORE, "No shutdown device in dev %d, state %d",
ctx->dev_hdl, ctx->state);
return rc;
}
int cam_context_handle_info_dump(void *context,
enum cam_context_dump_id id)
{

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.
*/
#ifndef _CAM_CONTEXT_H_
@ -9,6 +9,7 @@
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/kref.h>
#include <media/v4l2-subdev.h>
#include "cam_req_mgr_interface.h"
#include "cam_hw_mgr_intf.h"
#include "cam_smmu_api.h"
@ -95,6 +96,7 @@ struct cam_ctx_request {
* @acquire_hw: Function pointer for acquire hw
* @release_hw: Function pointer for release hw
* @dump_dev: Function pointer for dump dev
* @shutdown_dev: Function pointer for shutdown dev
*
*/
struct cam_ctx_ioctl_ops {
@ -114,6 +116,8 @@ struct cam_ctx_ioctl_ops {
int (*release_hw)(struct cam_context *ctx, void *args);
int (*dump_dev)(struct cam_context *ctx,
struct cam_dump_req_cmd *cmd);
int (*shutdown_dev)(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh);
};
/**
@ -479,6 +483,19 @@ int cam_context_handle_start_dev(struct cam_context *ctx,
int cam_context_handle_stop_dev(struct cam_context *ctx,
struct cam_start_stop_dev_cmd *cmd);
/**
* cam_context_handle_shutdown_dev()
*
* @brief: Handle shutdown device command
*
* @ctx: Object pointer for cam_context
* @cmd: Shutdown device command payload
* @fh: Pointer to struct v4l2_subdev_fh
*
*/
int cam_context_handle_shutdown_dev(struct cam_context *ctx,
struct cam_control *cmd, struct v4l2_subdev_fh *fh);
/**
* cam_context_handle_dump_dev()
*

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 <linux/debugfs.h>
@ -297,6 +297,27 @@ static int __cam_node_handle_stop_dev(struct cam_node *node,
return rc;
}
int cam_node_handle_shutdown_dev(struct cam_node *node,
struct cam_control *cmd, struct v4l2_subdev_fh *fh)
{
struct cam_context *ctx = NULL;
int32_t dev_index = -1;
int rc = 0, ret = 0;
while ((dev_index = cam_get_dev_handle_info(cmd->handle,
&ctx, dev_index)) < CAM_REQ_MGR_MAX_HANDLES_V2) {
ret = cam_context_handle_shutdown_dev(ctx, cmd, fh);
if (ret) {
rc = ret;
CAM_ERR(CAM_CORE, "Shutdown failure for node %s",
node->name);
continue;
}
}
return rc;
}
static int __cam_node_handle_config_dev(struct cam_node *node,
struct cam_config_dev_cmd *config)
{

View file

@ -100,4 +100,30 @@ int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf,
*/
void cam_node_put_ctxt_to_free_list(struct kref *ref);
/**
* cam_get_dev_handle_info()
*
* @brief: provides the active dev index.
*
* @handle: pointer to struct v4l2_dev
* @ctx: pointer to struct cam_context
* @dev_index: dev index
*
*/
int32_t cam_get_dev_handle_info(uint64_t handle,
struct cam_context **ctx, int32_t dev_index);
/**
* cam_node_handle_shutdown_dev()
*
* @brief: Shutdowns all the active devices.
*
* @node: pointer to struct node
* @cmd: pointer to struct cmd
* @fh: pointer to struct v4l2_subdev_fh
*
*/
int cam_node_handle_shutdown_dev(struct cam_node *node,
struct cam_control *cmd, struct v4l2_subdev_fh *fh);
#endif /* _CAM_NODE_H_ */

View file

@ -45,6 +45,8 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
long rc;
struct cam_node *node =
(struct cam_node *) v4l2_get_subdevdata(sd);
struct v4l2_subdev_fh *fh = (struct v4l2_subdev_fh *)arg;
struct cam_control cntrl_cmd;
if (!node || node->state == CAM_NODE_STATE_UNINIT) {
rc = -EINVAL;
@ -56,6 +58,19 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
rc = cam_node_handle_ioctl(node,
(struct cam_control *) arg);
break;
case CAM_SD_SHUTDOWN:
if (!cam_req_mgr_is_shutdown()) {
CAM_WARN(CAM_CORE, "SD shouldn't come from user space");
return 0;
}
cntrl_cmd.op_code = CAM_SD_SHUTDOWN;
cntrl_cmd.handle = (uint64_t)sd;
rc = cam_node_handle_shutdown_dev(node, &cntrl_cmd, fh);
if (rc)
CAM_ERR(CAM_CORE, "shutdown device failed(rc = %d)",
rc);
break;
default:
CAM_ERR(CAM_CORE, "Invalid command %d for %s", cmd,
node->name);

View file

@ -691,7 +691,7 @@ static int cam_cpas_subdev_open(struct v4l2_subdev *sd,
return 0;
}
static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
static int __cam_cpas_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_cpas_intf *cpas_intf = v4l2_get_subdevdata(sd);
@ -702,6 +702,11 @@ static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
}
mutex_lock(&cpas_intf->intf_lock);
if (cpas_intf->open_cnt <= 0) {
CAM_WARN(CAM_CPAS, "device already closed, open_cnt: %d", cpas_intf->open_cnt);
mutex_unlock(&cpas_intf->intf_lock);
return 0;
}
cpas_intf->open_cnt--;
CAM_DBG(CAM_CPAS, "CPAS Subdev close count %d", cpas_intf->open_cnt);
mutex_unlock(&cpas_intf->intf_lock);
@ -709,6 +714,19 @@ static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
return 0;
}
static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_CPAS);
if (crm_active) {
CAM_DBG(CAM_CPAS, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return __cam_cpas_subdev_close(sd, fh);
}
static long cam_cpas_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
@ -724,6 +742,9 @@ static long cam_cpas_subdev_ioctl(struct v4l2_subdev *sd,
case VIDIOC_CAM_CONTROL:
rc = cam_cpas_subdev_cmd(cpas_intf, (struct cam_control *) arg);
break;
case CAM_SD_SHUTDOWN:
rc = __cam_cpas_subdev_close(sd, NULL);
break;
default:
CAM_ERR(CAM_CPAS, "Invalid command %d for CPAS!", cmd);
rc = -EINVAL;
@ -811,6 +832,7 @@ static int cam_cpas_subdev_register(struct platform_device *pdev)
subdev->sd_flags =
V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
subdev->ent_function = CAM_CPAS_DEVICE_TYPE;
subdev->close_seq_prior = CAM_SD_CLOSE_LOW_PRIORITY;
rc = cam_register_subdev(subdev);
if (rc) {

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 <linux/delay.h>
@ -28,6 +28,7 @@
#include "cpastop_v540_100.h"
#include "cpastop_v520_100.h"
#include "cpastop_v545_100.h"
#include "cpastop_v545_110.h"
#include "cpastop_v570_200.h"
#include "cpastop_v680_100.h"
#include "cpastop_v165_100.h"
@ -119,7 +120,7 @@ static const uint32_t cam_cpas_hw_version_map
{
CAM_CPAS_TITAN_545_V100,
0,
0,
CAM_CPAS_TITAN_545_V110,
0,
0,
0,
@ -934,6 +935,10 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
camnoc_info = &cam545_cpas100_camnoc_info;
qchannel_info = &cam545_cpas100_qchannel_info;
break;
case CAM_CPAS_TITAN_545_V110:
camnoc_info = &cam545_cpas110_camnoc_info;
qchannel_info = &cam545_cpas110_qchannel_info;
break;
case CAM_CPAS_TITAN_570_V200:
camnoc_info = &cam570_cpas200_camnoc_info;
qchannel_info = &cam570_cpas200_qchannel_info;

View file

@ -289,6 +289,27 @@ static struct cam_camnoc_specific
*/
.enable = false,
},
.qosgen_mainctl = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4808, /* IFE01234_RDI_QOSGEN_MAINCTL */
.value = 0x2,
},
.qosgen_shaping_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4820, /* IFE01234_RDI_QOSGEN_SHAPING_LOW */
.value = 0x07070707,
},
.qosgen_shaping_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4824, /* IFE01234_RDI_QOSGEN_SHAPING_HIGH */
.value = 0x07070707,
},
},
{
.port_type = CAM_CAMNOC_IFE01_NRDI_WRITE,
@ -343,6 +364,27 @@ static struct cam_camnoc_specific
.offset = 0x3B88, /* IFE01_NRDI_ENCCTL_LOW */
.value = 1,
},
.qosgen_mainctl = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4708, /* IFE01_NRDI_QOSGEN_MAINCTL */
.value = 0x2,
},
.qosgen_shaping_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4720, /* IFE01_NRDI_QOSGEN_SHAPING_LOW */
.value = 0x07070707,
},
.qosgen_shaping_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4724, /* IFE01_NRDI_QOSGEN_SHAPING_HIGH */
.value = 0x07070707,
},
},
{
.port_type = CAM_CAMNOC_IFE2_NRDI_WRITE,
@ -397,6 +439,27 @@ static struct cam_camnoc_specific
.offset = 0x5588, /* IFE2_NRDI_ENCCTL_LOW */
.value = 0,
},
.qosgen_mainctl = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5188, /* IFE2_NRDI_QOSGEN_MAINCTL */
.value = 0x2,
},
.qosgen_shaping_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x51A0, /* IFE2_NRDI_QOSGEN_SHAPING_LOW */
.value = 0x07070707,
},
.qosgen_shaping_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x51A4, /* IFE2_NRDI_QOSGEN_SHAPING_HIGH */
.value = 0x07070707,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,

View file

@ -0,0 +1,322 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP_V545_110_H_
#define _CPASTOP_V545_110_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v545_110_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0xA40, /* SBM_FAULTINEN0_LOW */
.value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
(TEST_IRQ_ENABLE ?
0x2 : /* SBM_FAULTINEN0_LOW_PORT6_MASK */
0x0) /* SBM_FAULTINEN0_LOW_PORT1_MASK */,
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0xA48, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0xA80, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x3 : 0x1,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v545_110_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = true,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0xD08, /* ERRORLOGGER_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0xD10, /* ERRORLOGGER_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0xD18, /* ERRORLOGGER_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT6_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0xA88, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0xA90, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas_v545_110_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xE30, /* CDM_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xE34, /* CDM_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xE38, /* CDM_URGENCY_LOW */
.value = 0x00000003,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xE40, /* CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xE48, /* CDM_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
},
{
.port_type = CAM_CAMNOC_TFE,
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* TFE_PRIORITYLUT_LOW */
.offset = 0x30,
.value = 0x55554433,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* TFE_PRIORITYLUT_HIGH */
.offset = 0x34,
.value = 0x66666655,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x38, /* TFE_URGENCY_LOW */
.value = 0x00001030,
},
.danger_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x40, /* TFE_DANGERLUT_LOW */
.value = 0xffff0000,
},
.safe_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x48, /* TFE_SAFELUT_LOW */
.value = 0x00000003,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
},
},
{
.port_type = CAM_CAMNOC_TFE_1,
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* TFE_PRIORITYLUT_LOW */
.offset = 0x4030,
.value = 0x55554433,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* TFE_PRIORITYLUT_HIGH */
.offset = 0x4034,
.value = 0x66666655,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4038, /* TFE_URGENCY_LOW */
.value = 0x00001030,
},
.danger_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x4040, /* TFE_DANGERLUT_LOW */
.value = 0xffff0000,
},
.safe_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x4048, /* TFE_SAFELUT_LOW */
.value = 0x00000003,
},
},
{
.port_type = CAM_CAMNOC_TFE_2,
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* TFE_PRIORITYLUT_LOW */
.offset = 0x5030,
.value = 0x55554433,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* TFE_PRIORITYLUT_HIGH */
.offset = 0x5034,
.value = 0x66666655,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5038, /* TFE_URGENCY_LOW */
.value = 0x00001030,
},
.danger_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x5040, /* TFE_DANGERLUT_LOW */
.value = 0xffff0000,
},
.safe_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x5048, /* TFE_SAFELUT_LOW */
.value = 0x00000003,
},
},
{
.port_type = CAM_CAMNOC_OPE,
.enable = true,
.priority_lut_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x430, /* OPE_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x434, /* OPE_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x438, /* OPE_URGENCY_LOW */
.value = 0x00000033,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x440, /* OPE_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x448, /* OPE_SAFELUT_LOW */
.value = 0xF,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
},
},
};
static struct cam_camnoc_err_logger_info cam545_cpas110_err_logger_offsets = {
.mainctrl = 0xD08, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0xD10, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0xD20, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0xD24, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0xD28, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0xD2C, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0xD30, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0xD34, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0xD38, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0xD3C, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_camnoc_info cam545_cpas110_camnoc_info = {
.specific = &cam_cpas_v545_110_camnoc_specific[0],
.specific_size = ARRAY_SIZE(cam_cpas_v545_110_camnoc_specific),
.irq_sbm = &cam_cpas_v545_110_irq_sbm,
.irq_err = &cam_cpas_v545_110_irq_err[0],
.irq_err_size = ARRAY_SIZE(cam_cpas_v545_110_irq_err),
.err_logger = &cam545_cpas110_err_logger_offsets,
.errata_wa_list = NULL,
};
static struct cam_cpas_camnoc_qchannel cam545_cpas110_qchannel_info = {
.qchannel_ctrl = 0x14,
.qchannel_status = 0x18,
};
#endif /* _CPASTOP_V545_110_H_ */

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.
*/
#ifndef _CAM_CPAS_API_H_
@ -139,6 +139,7 @@ enum cam_cpas_hw_version {
CAM_CPAS_TITAN_540_V100 = 0x540100,
CAM_CPAS_TITAN_520_V100 = 0x520100,
CAM_CPAS_TITAN_545_V100 = 0x545100,
CAM_CPAS_TITAN_545_V110 = 0x545110,
CAM_CPAS_TITAN_570_V200 = 0x570200,
CAM_CPAS_TITAN_680_V100 = 0x680100,
CAM_CPAS_TITAN_MAX

View file

@ -1604,6 +1604,19 @@ static int __cam_custom_ctx_apply_default_req(
return rc;
}
static int __cam_custom_ctx_shutdown_dev(
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
int rc = -EINVAL;
if (!sd || !fh) {
CAM_ERR(CAM_CUSTOM, "Invalid input pointer");
return rc;
}
return cam_custom_subdev_close_internal(sd, fh);
}
/* top state machine */
static struct cam_ctx_ops
cam_custom_dev_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
@ -1618,6 +1631,7 @@ static struct cam_ctx_ops
.ioctl_ops = {
.acquire_dev =
__cam_custom_ctx_acquire_dev_in_available,
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
@ -1629,6 +1643,7 @@ static struct cam_ctx_ops
.release_dev = __cam_custom_release_dev_in_acquired,
.config_dev = __cam_custom_ctx_config_dev_in_acquired,
.release_hw = __cam_custom_ctx_release_hw_in_top_state,
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
},
.crm_ops = {
.link = __cam_custom_ctx_link_in_acquired,
@ -1647,6 +1662,7 @@ static struct cam_ctx_ops
.release_dev = __cam_custom_release_dev_in_acquired,
.config_dev = __cam_custom_ctx_config_dev,
.release_hw = __cam_custom_ctx_release_hw_in_top_state,
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
},
.crm_ops = {
.unlink = __cam_custom_ctx_unlink_in_ready,
@ -1664,6 +1680,7 @@ static struct cam_ctx_ops
.config_dev = __cam_custom_ctx_config_dev_in_flushed,
.release_hw =
__cam_custom_ctx_release_hw_in_activated_state,
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
},
.crm_ops = {
.unlink = __cam_custom_ctx_unlink_in_ready,
@ -1680,6 +1697,7 @@ static struct cam_ctx_ops
.config_dev = __cam_custom_ctx_config_dev,
.release_hw =
__cam_custom_ctx_release_hw_in_activated_state,
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
},
.crm_ops = {
.unlink = __cam_custom_ctx_unlink_in_activated,

View file

@ -150,4 +150,16 @@ int cam_custom_dev_context_init(struct cam_custom_context *ctx,
*/
int cam_custom_dev_context_deinit(struct cam_custom_context *ctx);
/**
* cam_custom_subdev_close_internal()
*
* @brief: Close function for the Custom context
*
* @sd: Pointer to struct v4l2_subdev
* @fh: Pointer to struct v4l2_subdev_fh
*
*/
int cam_custom_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh);
#endif /* _CAM_CUSTOM_CONTEXT_H_ */

View file

@ -58,7 +58,7 @@ static int cam_custom_subdev_open(struct v4l2_subdev *sd,
return 0;
}
static int cam_custom_subdev_close(struct v4l2_subdev *sd,
int cam_custom_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
int rc = 0;
@ -86,6 +86,19 @@ end:
return rc;
}
static int cam_custom_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_CUSTOM);
if (crm_active) {
CAM_DBG(CAM_CUSTOM, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_custom_subdev_close_internal(sd, fh);
}
static const struct v4l2_subdev_internal_ops cam_custom_subdev_internal_ops = {
.close = cam_custom_subdev_close,
.open = cam_custom_subdev_open,
@ -102,6 +115,7 @@ static int cam_custom_component_bind(struct device *dev,
struct platform_device *pdev = to_platform_device(dev);
g_custom_dev.sd.internal_ops = &cam_custom_subdev_internal_ops;
g_custom_dev.sd.close_seq_prior = CAM_SD_CLOSE_HIGH_PRIORITY;
rc = cam_subdev_probe(&g_custom_dev.sd, pdev, CAM_CUSTOM_DEV_NAME,
CAM_CUSTOM_DEVICE_TYPE);

View file

@ -169,6 +169,19 @@ static int __cam_fd_ctx_handle_irq_in_activated(void *context,
return rc;
}
static int __cam_fd_shutdown_dev(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
int rc = -EINVAL;
if (!sd || !fh) {
CAM_ERR(CAM_FD, "Invalid input pointer");
return rc;
}
return cam_fd_dev_close_internal(sd, fh);
}
/* top state machine */
static struct cam_ctx_ops
cam_fd_ctx_state_machine[CAM_CTX_STATE_MAX] = {
@ -182,6 +195,7 @@ static struct cam_ctx_ops
{
.ioctl_ops = {
.acquire_dev = __cam_fd_ctx_acquire_dev_in_available,
.shutdown_dev = __cam_fd_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
@ -192,18 +206,25 @@ static struct cam_ctx_ops
.release_dev = __cam_fd_ctx_release_dev_in_acquired,
.config_dev = __cam_fd_ctx_config_dev_in_acquired,
.start_dev = __cam_fd_ctx_start_dev_in_acquired,
.shutdown_dev = __cam_fd_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
},
/* Ready */
{
.ioctl_ops = { },
.ioctl_ops = {
.shutdown_dev = __cam_fd_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
},
/* Flushed */
{},
{
.ioctl_ops = {
.shutdown_dev = __cam_fd_shutdown_dev,
},
},
/* Activated */
{
.ioctl_ops = {
@ -212,6 +233,7 @@ static struct cam_ctx_ops
.config_dev = __cam_fd_ctx_config_dev_in_activated,
.flush_dev = __cam_fd_ctx_flush_dev_in_activated,
.dump_dev = __cam_fd_ctx_dump_dev_in_activated,
.shutdown_dev = __cam_fd_shutdown_dev,
},
.crm_ops = {},
.irq_ops = __cam_fd_ctx_handle_irq_in_activated,

View file

@ -27,4 +27,15 @@ int cam_fd_context_init(struct cam_fd_context *fd_ctx,
uint32_t ctx_id);
int cam_fd_context_deinit(struct cam_fd_context *ctx);
/**
* cam_fd_dev_close_internal()
*
* @brief: Close function for the fd dev
*
* @sd: Pointer to struct v4l2_subdev
* @fh: Pointer to struct v4l2_subdev_fh
*/
int cam_fd_dev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh);
#endif /* _CAM_FD_CONTEXT_H_ */

View file

@ -57,7 +57,7 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd,
return 0;
}
static int cam_fd_dev_close(struct v4l2_subdev *sd,
static int cam_fd_dev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_fd_dev *fd_dev = &g_fd_dev;
@ -69,6 +69,11 @@ static int cam_fd_dev_close(struct v4l2_subdev *sd,
}
mutex_lock(&fd_dev->lock);
if (fd_dev->open_cnt == 0) {
CAM_WARN(CAM_FD, "device already closed");
mutex_unlock(&fd_dev->lock);
return 0;
}
fd_dev->open_cnt--;
CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt);
mutex_unlock(&fd_dev->lock);
@ -83,6 +88,19 @@ static int cam_fd_dev_close(struct v4l2_subdev *sd,
return 0;
}
static int cam_fd_dev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_FD);
if (crm_active) {
CAM_DBG(CAM_FD, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_fd_dev_close_internal(sd, fh);
}
static const struct v4l2_subdev_internal_ops cam_fd_subdev_internal_ops = {
.open = cam_fd_dev_open,
.close = cam_fd_dev_close,
@ -98,6 +116,7 @@ static int cam_fd_dev_component_bind(struct device *dev,
struct platform_device *pdev = to_platform_device(dev);
g_fd_dev.sd.internal_ops = &cam_fd_subdev_internal_ops;
g_fd_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
/* Initialize the v4l2 subdevice first. (create cam_node) */
rc = cam_subdev_probe(&g_fd_dev.sd, pdev, CAM_FD_DEV_NAME,

View file

@ -221,6 +221,12 @@ static int __cam_icp_handle_buf_done_in_ready(void *ctx,
return cam_context_buf_done_from_hw(ctx, done, evt_id);
}
static int __cam_icp_shutdown_dev(
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
return cam_icp_subdev_close_internal(sd, fh);
}
static struct cam_ctx_ops
cam_icp_ctx_state_machine[CAM_CTX_STATE_MAX] = {
/* Uninit */
@ -233,6 +239,7 @@ static struct cam_ctx_ops
{
.ioctl_ops = {
.acquire_dev = __cam_icp_acquire_dev_in_available,
.shutdown_dev = __cam_icp_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
@ -245,6 +252,7 @@ static struct cam_ctx_ops
.config_dev = __cam_icp_config_dev_in_ready,
.flush_dev = __cam_icp_flush_dev_in_ready,
.dump_dev = __cam_icp_dump_dev_in_ready,
.shutdown_dev = __cam_icp_shutdown_dev,
},
.crm_ops = {},
.irq_ops = __cam_icp_handle_buf_done_in_ready,
@ -258,16 +266,23 @@ static struct cam_ctx_ops
.config_dev = __cam_icp_config_dev_in_ready,
.flush_dev = __cam_icp_flush_dev_in_ready,
.dump_dev = __cam_icp_dump_dev_in_ready,
.shutdown_dev = __cam_icp_shutdown_dev,
},
.crm_ops = {},
.irq_ops = __cam_icp_handle_buf_done_in_ready,
.pagefault_ops = cam_icp_context_dump_active_request,
},
/* Flushed */
{},
{
.ioctl_ops = {
.shutdown_dev = __cam_icp_shutdown_dev,
},
},
/* Activated */
{
.ioctl_ops = {},
.ioctl_ops = {
.shutdown_dev = __cam_icp_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
.pagefault_ops = cam_icp_context_dump_active_request,

View file

@ -39,4 +39,12 @@ int cam_icp_context_init(struct cam_icp_context *ctx,
*/
int cam_icp_context_deinit(struct cam_icp_context *ctx);
/**
* cam_icp_subdev_close_internal() - Close function for the icp dev
* @sd: Pointer to struct v4l2_subdev
* @fh: Pointer to struct v4l2_subdev_fh
*/
int cam_icp_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh);
#endif /* _CAM_ICP_CONTEXT_H_ */

View file

@ -98,7 +98,7 @@ end:
return rc;
}
static int cam_icp_subdev_close(struct v4l2_subdev *sd,
int cam_icp_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
int rc = 0;
@ -108,7 +108,6 @@ static int cam_icp_subdev_close(struct v4l2_subdev *sd,
mutex_lock(&g_icp_dev.icp_lock);
if (g_icp_dev.open_cnt <= 0) {
CAM_DBG(CAM_ICP, "ICP subdev is already closed");
rc = -EINVAL;
goto end;
}
g_icp_dev.open_cnt--;
@ -133,7 +132,20 @@ static int cam_icp_subdev_close(struct v4l2_subdev *sd,
end:
mutex_unlock(&g_icp_dev.icp_lock);
return 0;
return rc;
}
static int cam_icp_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_ICP);
if (crm_active) {
CAM_DBG(CAM_ICP, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_icp_subdev_close_internal(sd, fh);
}
const struct v4l2_subdev_internal_ops cam_icp_subdev_internal_ops = {
@ -157,6 +169,7 @@ static int cam_icp_component_bind(struct device *dev,
g_icp_dev.sd.pdev = pdev;
g_icp_dev.sd.internal_ops = &cam_icp_subdev_internal_ops;
g_icp_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
rc = cam_subdev_probe(&g_icp_dev.sd, pdev, CAM_ICP_DEV_NAME,
CAM_ICP_DEVICE_TYPE);
if (rc) {

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 <linux/uaccess.h>
@ -1062,8 +1062,7 @@ static bool cam_icp_update_clk_free(struct cam_icp_hw_mgr *hw_mgr,
static bool cam_icp_debug_clk_update(struct cam_icp_clk_info *hw_mgr_clk_info)
{
if (icp_hw_mgr.icp_debug_clk < ICP_CLK_TURBO_HZ &&
icp_hw_mgr.icp_debug_clk &&
if (icp_hw_mgr.icp_debug_clk &&
icp_hw_mgr.icp_debug_clk != hw_mgr_clk_info->curr_clk) {
hw_mgr_clk_info->base_clk = icp_hw_mgr.icp_debug_clk;
hw_mgr_clk_info->curr_clk = icp_hw_mgr.icp_debug_clk;

View file

@ -864,6 +864,18 @@ static int __cam_isp_ctx_handle_buf_done_for_req_list(
list_add_tail(&req->list, &ctx->free_req_list);
req_isp->reapply = false;
req_isp->cdm_reset_before_apply = false;
req_isp->num_acked = 0;
req_isp->num_deferred_acks = 0;
req_isp->bubble_detected = false;
/*
* Only update the process_bubble and bubble_frame_cnt
* when bubble is detected on this req, in case the other
* request is processing bubble.
*/
if (req_isp->bubble_detected) {
atomic_set(&ctx_isp->process_bubble, 0);
ctx_isp->bubble_frame_cnt = 0;
}
CAM_DBG(CAM_REQ,
"Move active request %lld to free list(cnt = %d) [all fences done], ctx %u",
@ -1863,7 +1875,6 @@ notify_only:
if ((!req_isp->bubble_detected) &&
(req->request_id > ctx_isp->reported_req_id)) {
request_id = req->request_id;
ctx_isp->reported_req_id = request_id;
__cam_isp_ctx_update_event_record(ctx_isp,
CAM_ISP_CTX_EVENT_EPOCH, req);
break;
@ -1873,6 +1884,9 @@ notify_only:
if (ctx_isp->substate_activated == CAM_ISP_CTX_ACTIVATED_BUBBLE)
request_id = 0;
if (request_id != 0)
ctx_isp->reported_req_id = request_id;
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
@ -2099,6 +2113,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
ctx_isp->frame_id, ctx->ctx_id);
}
}
atomic_set(&ctx_isp->process_bubble, 1);
}
/*
@ -2334,6 +2349,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
ctx_isp->frame_id, ctx->ctx_id);
}
}
atomic_set(&ctx_isp->process_bubble, 1);
}
/*
@ -5837,6 +5853,12 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context,
return rc;
}
static int __cam_isp_shutdown_dev(
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
return cam_isp_subdev_close_internal(sd, fh);
}
/* top state machine */
static struct cam_ctx_ops
cam_isp_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
@ -5850,6 +5872,7 @@ static struct cam_ctx_ops
{
.ioctl_ops = {
.acquire_dev = __cam_isp_ctx_acquire_dev_in_available,
.shutdown_dev = __cam_isp_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
@ -5861,6 +5884,7 @@ static struct cam_ctx_ops
.release_dev = __cam_isp_ctx_release_dev_in_top_state,
.config_dev = __cam_isp_ctx_config_dev_in_acquired,
.release_hw = __cam_isp_ctx_release_hw_in_top_state,
.shutdown_dev = __cam_isp_shutdown_dev,
},
.crm_ops = {
.link = __cam_isp_ctx_link_in_acquired,
@ -5880,6 +5904,7 @@ static struct cam_ctx_ops
.release_dev = __cam_isp_ctx_release_dev_in_top_state,
.config_dev = __cam_isp_ctx_config_dev_in_top_state,
.release_hw = __cam_isp_ctx_release_hw_in_top_state,
.shutdown_dev = __cam_isp_shutdown_dev,
},
.crm_ops = {
.unlink = __cam_isp_ctx_unlink_in_ready,
@ -5897,6 +5922,7 @@ static struct cam_ctx_ops
.release_dev = __cam_isp_ctx_release_dev_in_activated,
.config_dev = __cam_isp_ctx_config_dev_in_flushed,
.release_hw = __cam_isp_ctx_release_hw_in_activated,
.shutdown_dev = __cam_isp_shutdown_dev,
},
.crm_ops = {
.unlink = __cam_isp_ctx_unlink_in_ready,
@ -5914,6 +5940,7 @@ static struct cam_ctx_ops
.release_dev = __cam_isp_ctx_release_dev_in_activated,
.config_dev = __cam_isp_ctx_config_dev_in_top_state,
.release_hw = __cam_isp_ctx_release_hw_in_activated,
.shutdown_dev = __cam_isp_shutdown_dev,
},
.crm_ops = {
.unlink = __cam_isp_ctx_unlink_in_activated,

View file

@ -364,5 +364,16 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
*/
int cam_isp_context_deinit(struct cam_isp_context *ctx);
/**
* cam_isp_subdev_close_internal()
*
* @brief: Close function for the isp dev
*
* @sd: Pointer to struct v4l2_subdev
* @fh: Pointer to struct v4l2_subdev_fh
*
*/
int cam_isp_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh);
#endif /* __CAM_ISP_CONTEXT_H__ */

View file

@ -71,7 +71,7 @@ static int cam_isp_subdev_open(struct v4l2_subdev *sd,
return 0;
}
static int cam_isp_subdev_close(struct v4l2_subdev *sd,
int cam_isp_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
int rc = 0;
@ -99,6 +99,18 @@ end:
return rc;
}
static int cam_isp_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_ISP);
if (crm_active) {
CAM_DBG(CAM_ISP, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_isp_subdev_close_internal(sd, fh);
}
static const struct v4l2_subdev_internal_ops cam_isp_subdev_internal_ops = {
.close = cam_isp_subdev_close,
.open = cam_isp_subdev_open,
@ -120,6 +132,7 @@ static int cam_isp_dev_component_bind(struct device *dev,
(const char **)&compat_str);
g_isp_dev.sd.internal_ops = &cam_isp_subdev_internal_ops;
g_isp_dev.sd.close_seq_prior = CAM_SD_CLOSE_HIGH_PRIORITY;
/* Initialize the v4l2 subdevice first. (create cam_node) */
if (strnstr(compat_str, "ife", strlen(compat_str))) {
rc = cam_subdev_probe(&g_isp_dev.sd, pdev, CAM_ISP_DEV_NAME,

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 <media/cam_defs.h>
@ -141,6 +141,14 @@ static int cam_isp_update_dual_config(
}
hw_mgr_res = &res_list_isp_out[i];
if (!hw_mgr_res) {
CAM_ERR(CAM_ISP,
"Invalid isp out resource i %d num_out_res %d",
i, dual_config->num_ports);
rc = -EINVAL;
goto end;
}
for (j = 0; j < CAM_ISP_HW_SPLIT_MAX; j++) {
if (!hw_mgr_res->hw_res[j])
continue;

View file

@ -1684,6 +1684,8 @@ static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw *csid_hw,
CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", 0x600, val);
}
res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
return 0;
}
@ -4241,6 +4243,8 @@ int cam_ife_csid_stop(void *hw_priv,
res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
}
csid_hw->error_irq_count = 0;
CAM_DBG(CAM_ISP, "%s: Exit\n", __func__);
return rc;

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.
*/
#include <linux/iopoll.h>
@ -203,6 +203,152 @@ static int cam_tfe_csid_get_format_ipp(
return rc;
}
static void cam_tfe_csid_enable_path_for_init_frame_drop(
struct cam_tfe_csid_hw *csid_hw,
int res_id)
{
struct cam_tfe_csid_path_cfg *path_data;
const struct cam_tfe_csid_pxl_reg_offset *pxl_reg = NULL;
const struct cam_tfe_csid_rdi_reg_offset *rdi_reg = NULL;
const struct cam_tfe_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
struct cam_isp_resource_node *res;
uint32_t val;
if (!csid_hw) {
CAM_WARN(CAM_ISP, "csid_hw cannot be NULL");
return;
}
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
if (res_id == CAM_TFE_CSID_PATH_RES_IPP) {
res = &csid_hw->ipp_res;
pxl_reg = csid_reg->ipp_reg;
} else if (res_id >= CAM_TFE_CSID_PATH_RES_RDI_0 &&
res_id <= CAM_TFE_CSID_PATH_RES_RDI_2) {
res = &csid_hw->rdi_res[res_id];
rdi_reg = csid_reg->rdi_reg[res_id];
} else {
CAM_ERR(CAM_ISP, "Invalid res_id");
return;
}
path_data = (struct cam_tfe_csid_path_cfg *)res->res_priv;
if (!path_data || !path_data->init_frame_drop)
return;
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING)
return;
path_data->res_sof_cnt++;
if ((path_data->res_sof_cnt + 1) <
path_data->res_sof_cnt) {
CAM_WARN(CAM_ISP, "Res %d sof count overflow %d",
res_id, path_data->res_sof_cnt);
return;
}
CAM_DBG(CAM_ISP, "CSID:%d res_id %d SOF cnt:%d init_frame_drop:%d",
csid_hw->hw_intf->hw_idx, res_id, path_data->res_sof_cnt,
path_data->init_frame_drop);
if ((path_data->res_sof_cnt ==
path_data->init_frame_drop) &&
pxl_reg) {
CAM_DBG(CAM_ISP, "Enabling pixel IPP Path");
if (path_data->sync_mode !=
CAM_ISP_HW_SYNC_SLAVE) {
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
pxl_reg->csid_pxl_ctrl_addr);
val |= CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY;
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base +
pxl_reg->csid_pxl_ctrl_addr);
}
if (!(csid_hw->csid_debug &
TFE_CSID_DEBUG_ENABLE_SOF_IRQ)) {
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
pxl_reg->csid_pxl_irq_mask_addr);
val &= ~(TFE_CSID_PATH_INFO_INPUT_SOF);
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base +
pxl_reg->csid_pxl_irq_mask_addr);
}
} else if ((path_data->res_sof_cnt ==
path_data->init_frame_drop) && rdi_reg) {
CAM_DBG(CAM_ISP, "Enabling RDI %d Path", res_id);
cam_io_w_mb(CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY,
soc_info->reg_map[0].mem_base +
rdi_reg->csid_rdi_ctrl_addr);
if (!(csid_hw->csid_debug &
TFE_CSID_DEBUG_ENABLE_SOF_IRQ)) {
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
rdi_reg->csid_rdi_irq_mask_addr);
val &= ~(TFE_CSID_PATH_INFO_INPUT_SOF);
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
rdi_reg->csid_rdi_irq_mask_addr);
}
}
}
static bool cam_tfe_csid_check_path_active(struct cam_tfe_csid_hw *csid_hw)
{
const struct cam_tfe_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
uint32_t i;
uint32_t path_status = 1;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
/* check the IPP path status */
if (csid_reg->cmn_reg->num_pix) {
path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_pxl_status_addr);
CAM_DBG(CAM_ISP, "CSID:%d IPP path status:%d",
csid_hw->hw_intf->hw_idx, path_status);
/* if status is 0 then it is active */
if (!path_status)
goto end;
}
/* Check the RDI path status */
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[i]->csid_rdi_status_addr);
CAM_DBG(CAM_ISP, "CSID:%d RDI:%d path status:%d",
csid_hw->hw_intf->hw_idx, i, path_status);
/* if status is 0 then it is active */
if (!path_status)
goto end;
}
end:
/* if status is 0 then path is active */
return path_status ? false : true;
}
static void cam_tfe_csid_reset_path_data(
struct cam_tfe_csid_hw *csid_hw,
struct cam_isp_resource_node *res)
{
struct cam_tfe_csid_path_cfg *path_data = NULL;
if (!csid_hw || !res) {
CAM_WARN(CAM_ISP, "csid_hw or res cannot be NULL");
return;
}
path_data = res->res_priv;
if (path_data) {
path_data->init_frame_drop = 0;
path_data->res_sof_cnt = 0;
}
}
static int cam_tfe_csid_cid_get(struct cam_tfe_csid_hw *csid_hw,
int32_t vc, uint32_t dt, uint32_t *cid)
{
@ -249,6 +395,7 @@ static int cam_tfe_csid_global_reset(struct cam_tfe_csid_hw *csid_hw)
{
struct cam_hw_soc_info *soc_info;
const struct cam_tfe_csid_reg_offset *csid_reg;
struct cam_tfe_csid_path_cfg *path_data = NULL;
int rc = 0;
uint32_t val = 0, i;
uint32_t status;
@ -348,6 +495,15 @@ static int cam_tfe_csid_global_reset(struct cam_tfe_csid_hw *csid_hw)
csid_hw->error_irq_count = 0;
csid_hw->prev_boot_timestamp = 0;
path_data = (struct cam_tfe_csid_path_cfg *)csid_hw->ipp_res.res_priv;
path_data->res_sof_cnt = 0;
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
path_data = (struct cam_tfe_csid_path_cfg *)
csid_hw->rdi_res[i].res_priv;
path_data->res_sof_cnt = 0;
}
return rc;
}
@ -675,6 +831,7 @@ static int cam_tfe_csid_path_reserve(struct cam_tfe_csid_hw *csid_hw,
path_data->height = reserve->in_port->height;
path_data->start_line = reserve->in_port->line_start;
path_data->end_line = reserve->in_port->line_end;
path_data->usage_type = reserve->in_port->usage_type;
csid_hw->event_cb = reserve->event_cb;
csid_hw->event_cb_priv = reserve->event_cb_prv;
@ -868,7 +1025,8 @@ static int cam_tfe_csid_enable_hw(struct cam_tfe_csid_hw *csid_hw)
{
int rc = 0;
const struct cam_tfe_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
struct cam_hw_soc_info *soc_info;
struct cam_tfe_csid_path_cfg *path_data = NULL;
uint32_t i, val, clk_lvl;
unsigned long flags;
@ -949,6 +1107,16 @@ static int cam_tfe_csid_enable_hw(struct cam_tfe_csid_hw *csid_hw)
spin_unlock_irqrestore(&csid_hw->spin_lock, flags);
cam_tasklet_start(csid_hw->tasklet);
path_data = (struct cam_tfe_csid_path_cfg *)csid_hw->ipp_res.res_priv;
path_data->res_sof_cnt = 0;
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
path_data = (struct cam_tfe_csid_path_cfg *)
csid_hw->rdi_res[i].res_priv;
path_data->res_sof_cnt = 0;
}
return rc;
disable_soc:
@ -1512,11 +1680,14 @@ static int cam_tfe_csid_enable_rdi_path(
{
const struct cam_tfe_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
struct cam_tfe_csid_path_cfg *path_data;
uint32_t id, val;
bool path_active = false;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
id = res->res_id;
path_data = (struct cam_tfe_csid_path_cfg *) res->res_priv;
if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
res->res_id > CAM_TFE_CSID_PATH_RES_RDI_2 ||
@ -1528,17 +1699,38 @@ static int cam_tfe_csid_enable_rdi_path(
return -EINVAL;
}
/* resume at frame boundary */
cam_io_w_mb(CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY,
soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
/*Drop one frame extra on RDI for dual TFE use case */
if (path_data->usage_type == CAM_ISP_TFE_IN_RES_USAGE_DUAL)
path_data->init_frame_drop = 1;
/*resume at frame boundary */
if (!path_data->init_frame_drop) {
CAM_DBG(CAM_ISP, "Start RDI:%d path", id);
/* resume at frame boundary */
cam_io_w_mb(CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY,
soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
} else {
path_active = cam_tfe_csid_check_path_active(csid_hw);
if (path_active)
cam_io_w_mb(CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY,
soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
CAM_DBG(CAM_ISP,
"CSID:%d %s RDI:%d path frame drop %d",
csid_hw->hw_intf->hw_idx,
path_active ? "Starting" : "Not Starting", id,
path_data->init_frame_drop);
}
/* Enable the required RDI interrupts */
val = TFE_CSID_PATH_INFO_RST_DONE | TFE_CSID_PATH_ERROR_FIFO_OVERFLOW |
TFE_CSID_PATH_RDI_ERROR_CCIF_VIOLATION |
TFE_CSID_PATH_RDI_OVERFLOW_IRQ;
if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)
if ((csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ) ||
(path_data->init_frame_drop && !path_active))
val |= TFE_CSID_PATH_INFO_INPUT_SOF;
if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_EOF_IRQ)
val |= TFE_CSID_PATH_INFO_INPUT_EOF;
@ -1560,10 +1752,12 @@ static int cam_tfe_csid_disable_rdi_path(
uint32_t id, val = 0;
const struct cam_tfe_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
struct cam_tfe_csid_path_cfg *path_data;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
id = res->res_id;
path_data = (struct cam_tfe_csid_path_cfg *) res->res_priv;
if ((res->res_id > CAM_TFE_CSID_PATH_RES_RDI_2) ||
(!csid_reg->rdi_reg[res->res_id])) {
@ -1599,6 +1793,9 @@ static int cam_tfe_csid_disable_rdi_path(
CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
csid_hw->hw_intf->hw_idx, res->res_id);
path_data->init_frame_drop = 0;
path_data->res_sof_cnt = 0;
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
@ -1964,6 +2161,8 @@ static int cam_tfe_csid_release(void *hw_priv,
res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
cam_tfe_csid_reset_path_data(csid_hw, res);
end:
mutex_unlock(&csid_hw->hw_info->hw_mutex);
return rc;
@ -3276,6 +3475,9 @@ handle_fatal_error:
complete(&csid_hw->csid_rdin_complete[i]);
}
if (irq_status[i] & TFE_CSID_PATH_INFO_INPUT_SOF)
cam_tfe_csid_enable_path_for_init_frame_drop(csid_hw, i);
if ((irq_status[i] & TFE_CSID_PATH_INFO_INPUT_SOF) &&
(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)) {
if (!csid_hw->sof_irq_triggered)

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_HW_H_
@ -332,7 +332,12 @@ struct cam_tfe_csid_cid_data {
* @sensor_fps Sensor fps
* @sensor_hbi Sensor horizontal blanking interval
* @sensor_vbi Sensor vertical blanking interval
*
* @usage_type: dual or single tfe information
* @init_frame_drop init frame drop value. In dual ife case rdi need to drop one
* more frame than pix.
* @res_sof_cnt path resource sof count value. it used for initial
* frame drop
*/
struct cam_tfe_csid_path_cfg {
uint32_t vc;
@ -355,6 +360,9 @@ struct cam_tfe_csid_path_cfg {
uint32_t sensor_fps;
uint32_t sensor_hbi;
uint32_t sensor_vbi;
uint32_t usage_type;
uint32_t init_frame_drop;
uint32_t res_sof_cnt;
};
/**

View file

@ -2954,9 +2954,8 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
struct cam_vfe_bus_ver3_wm_resource_data *wm_data = NULL;
struct cam_vfe_bus_ver3_reg_offset_ubwc_client *ubwc_client = NULL;
uint32_t *reg_val_pair;
uint32_t i, j, k, size = 0;
uint32_t i, j, size = 0;
uint32_t frame_inc = 0, val;
uint32_t loop_size = 0;
bus_priv = (struct cam_vfe_bus_ver3_priv *) priv;
update_buf = (struct cam_isp_hw_get_cmd_update *) cmd_args;
@ -3086,41 +3085,31 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
wm_data->index, reg_val_pair[j-1]);
}
if ((!bus_priv->common_data.is_lite && wm_data->index > 22) ||
bus_priv->common_data.is_lite)
loop_size = wm_data->irq_subsample_period + 1;
else
loop_size = 1;
/* WM Image address */
for (k = 0; k < loop_size; k++) {
if (wm_data->en_ubwc) {
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->image_addr,
update_buf->wm_update->image_buf[i] +
io_cfg->planes[i].meta_size +
k * frame_inc);
update_buf->wm_update->image_buf_offset[i] =
io_cfg->planes[i].meta_size;
} else if (wm_data->en_cfg & (0x3 << 16)) {
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->image_addr,
(update_buf->wm_update->image_buf[i] +
wm_data->offset + k * frame_inc));
update_buf->wm_update->image_buf_offset[i] =
wm_data->offset;
} else {
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->image_addr,
(update_buf->wm_update->image_buf[i] +
k * frame_inc));
update_buf->wm_update->image_buf_offset[i] = 0;
}
CAM_DBG(CAM_ISP, "WM:%d image address 0x%X",
wm_data->index, reg_val_pair[j-1]);
if (wm_data->en_ubwc) {
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->image_addr,
update_buf->wm_update->image_buf[i] +
io_cfg->planes[i].meta_size);
update_buf->wm_update->image_buf_offset[i] =
io_cfg->planes[i].meta_size;
} else if (wm_data->en_cfg & (0x3 << 16)) {
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->image_addr,
(update_buf->wm_update->image_buf[i] +
wm_data->offset));
update_buf->wm_update->image_buf_offset[i] =
wm_data->offset;
} else {
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->image_addr,
update_buf->wm_update->image_buf[i]);
update_buf->wm_update->image_buf_offset[i] = 0;
}
CAM_DBG(CAM_ISP, "WM:%d image address 0x%X",
wm_data->index, reg_val_pair[j-1]);
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->frame_incr, frame_inc);
CAM_DBG(CAM_ISP, "WM:%d frame_inc %d",

View file

@ -135,6 +135,12 @@ static int __cam_jpeg_ctx_stop_dev_in_acquired(struct cam_context *ctx,
return rc;
}
static int __cam_jpeg_shutdown_dev(
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
return cam_jpeg_subdev_close_internal(sd, fh);
}
/* top state machine */
static struct cam_ctx_ops
cam_jpeg_ctx_state_machine[CAM_CTX_STATE_MAX] = {
@ -148,6 +154,7 @@ static struct cam_ctx_ops
{
.ioctl_ops = {
.acquire_dev = __cam_jpeg_ctx_acquire_dev_in_available,
.shutdown_dev = __cam_jpeg_shutdown_dev,
},
.crm_ops = { },
.irq_ops = NULL,
@ -160,11 +167,30 @@ static struct cam_ctx_ops
.stop_dev = __cam_jpeg_ctx_stop_dev_in_acquired,
.flush_dev = __cam_jpeg_ctx_flush_dev_in_acquired,
.dump_dev = __cam_jpeg_ctx_dump_dev_in_acquired,
.shutdown_dev = __cam_jpeg_shutdown_dev,
},
.crm_ops = { },
.irq_ops = __cam_jpeg_ctx_handle_buf_done_in_acquired,
.pagefault_ops = cam_jpeg_context_dump_active_request,
},
/* Ready */
{
.ioctl_ops = {
.shutdown_dev = __cam_jpeg_shutdown_dev,
},
},
/* Flushed */
{
.ioctl_ops = {
.shutdown_dev = __cam_jpeg_shutdown_dev,
},
},
/* Activated */
{
.ioctl_ops = {
.shutdown_dev = __cam_jpeg_shutdown_dev,
},
},
};
int cam_jpeg_context_init(struct cam_jpeg_context *ctx,

View file

@ -64,4 +64,16 @@ int cam_jpeg_context_init(struct cam_jpeg_context *ctx,
*/
int cam_jpeg_context_deinit(struct cam_jpeg_context *ctx);
/**
* cam_jpeg_subdev_close_internal()
*
* @brief: Close function for the jpeg dev
*
* @sd: Pointer to struct v4l2_subdev
* @fh: Pointer to struct v4l2_subdev_fh
*
*/
int cam_jpeg_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh);
#endif /* __CAM_JPEG_CONTEXT_H__ */

View file

@ -56,13 +56,12 @@ static int cam_jpeg_subdev_open(struct v4l2_subdev *sd,
return 0;
}
static int cam_jpeg_subdev_close(struct v4l2_subdev *sd,
int cam_jpeg_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
int rc = 0;
struct cam_node *node = v4l2_get_subdevdata(sd);
mutex_lock(&g_jpeg_dev.jpeg_mutex);
if (g_jpeg_dev.open_cnt <= 0) {
CAM_DBG(CAM_JPEG, "JPEG subdev is already closed");
@ -86,6 +85,18 @@ end:
return rc;
}
static int cam_jpeg_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_JPEG);
if (crm_active) {
CAM_DBG(CAM_JPEG, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_jpeg_subdev_close_internal(sd, fh);
}
static const struct v4l2_subdev_internal_ops cam_jpeg_subdev_internal_ops = {
.close = cam_jpeg_subdev_close,
.open = cam_jpeg_subdev_open,
@ -102,6 +113,7 @@ static int cam_jpeg_dev_component_bind(struct device *dev,
struct platform_device *pdev = to_platform_device(dev);
g_jpeg_dev.sd.internal_ops = &cam_jpeg_subdev_internal_ops;
g_jpeg_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
rc = cam_subdev_probe(&g_jpeg_dev.sd, pdev, CAM_JPEG_DEV_NAME,
CAM_JPEG_DEVICE_TYPE);
if (rc) {

View file

@ -172,6 +172,12 @@ static int __cam_lrme_ctx_handle_irq_in_activated(void *context,
return rc;
}
static int __cam_lrme_shutdown_dev(
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
return cam_lrme_dev_close_internal(sd, fh);
}
/* top state machine */
static struct cam_ctx_ops
cam_lrme_ctx_state_machine[CAM_CTX_STATE_MAX] = {
@ -185,6 +191,7 @@ static struct cam_ctx_ops
{
.ioctl_ops = {
.acquire_dev = __cam_lrme_ctx_acquire_dev_in_available,
.shutdown_dev = __cam_lrme_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
@ -195,18 +202,25 @@ static struct cam_ctx_ops
.config_dev = __cam_lrme_ctx_config_dev_in_activated,
.release_dev = __cam_lrme_ctx_release_dev_in_acquired,
.start_dev = __cam_lrme_ctx_start_dev_in_acquired,
.shutdown_dev = __cam_lrme_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
},
/* Ready */
{
.ioctl_ops = {},
.ioctl_ops = {
.shutdown_dev = __cam_lrme_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
},
/* Flushed */
{},
{
.ioctl_ops = {
.shutdown_dev = __cam_lrme_shutdown_dev,
},
},
/* Activate */
{
.ioctl_ops = {
@ -215,6 +229,7 @@ static struct cam_ctx_ops
.stop_dev = __cam_lrme_ctx_stop_dev_in_activated,
.flush_dev = __cam_lrme_ctx_flush_dev_in_activated,
.dump_dev = __cam_lrme_ctx_dump_dev_in_activated,
.shutdown_dev = __cam_lrme_shutdown_dev,
},
.crm_ops = {},
.irq_ops = __cam_lrme_ctx_handle_irq_in_activated,

View file

@ -30,4 +30,16 @@ int cam_lrme_context_init(struct cam_lrme_context *lrme_ctx,
uint32_t index);
int cam_lrme_context_deinit(struct cam_lrme_context *lrme_ctx);
/**
* cam_lrme_dev_close_internal()
*
* @brief: Close function for the jpeg dev
*
* @sd: Pointer to struct v4l2_subdev
* @fh: Pointer to struct v4l2_subdev_fh
*
*/
int cam_lrme_dev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh);
#endif /* _CAM_LRME_CONTEXT_H_ */

View file

@ -72,7 +72,7 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd,
return 0;
}
static int cam_lrme_dev_close(struct v4l2_subdev *sd,
int cam_lrme_dev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
int rc = 0;
@ -106,6 +106,18 @@ end:
return rc;
}
static int cam_lrme_dev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_LRME);
if (crm_active) {
CAM_DBG(CAM_LRME, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_lrme_dev_close_internal(sd, fh);
}
static const struct v4l2_subdev_internal_ops cam_lrme_subdev_internal_ops = {
.open = cam_lrme_dev_open,
.close = cam_lrme_dev_close,
@ -126,6 +138,7 @@ static int cam_lrme_component_bind(struct device *dev,
return -ENOMEM;
}
g_lrme_dev->sd.internal_ops = &cam_lrme_subdev_internal_ops;
g_lrme_dev->sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
mutex_init(&g_lrme_dev->lock);

View file

@ -195,6 +195,12 @@ static int __cam_ope_handle_buf_done_in_ready(void *ctx,
return cam_context_buf_done_from_hw(ctx, done, evt_id);
}
static int __cam_ope_shutdown_dev(
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
return cam_ope_subdev_close_internal(sd, fh);
}
static struct cam_ctx_ops
cam_ope_ctx_state_machine[CAM_CTX_STATE_MAX] = {
/* Uninit */
@ -207,6 +213,7 @@ static struct cam_ctx_ops
{
.ioctl_ops = {
.acquire_dev = __cam_ope_acquire_dev_in_available,
.shutdown_dev = __cam_ope_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
@ -219,6 +226,7 @@ static struct cam_ctx_ops
.config_dev = __cam_ope_config_dev_in_ready,
.flush_dev = __cam_ope_flush_dev_in_ready,
.dump_dev = __cam_ope_dump_dev_in_ready,
.shutdown_dev = __cam_ope_shutdown_dev,
},
.crm_ops = {},
.irq_ops = __cam_ope_handle_buf_done_in_ready,
@ -232,14 +240,23 @@ static struct cam_ctx_ops
.config_dev = __cam_ope_config_dev_in_ready,
.flush_dev = __cam_ope_flush_dev_in_ready,
.dump_dev = __cam_ope_dump_dev_in_ready,
.shutdown_dev = __cam_ope_shutdown_dev,
},
.crm_ops = {},
.irq_ops = __cam_ope_handle_buf_done_in_ready,
.pagefault_ops = cam_ope_context_dump_active_request,
},
/* Flushed */
{
.ioctl_ops = {
.shutdown_dev = __cam_ope_shutdown_dev,
},
},
/* Activated */
{
.ioctl_ops = {},
.ioctl_ops = {
.shutdown_dev = __cam_ope_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
.pagefault_ops = cam_ope_context_dump_active_request,

View file

@ -41,4 +41,12 @@ int cam_ope_context_init(struct cam_ope_context *ctx,
*/
int cam_ope_context_deinit(struct cam_ope_context *ctx);
/**
* cam_ope_subdev_close_internal() - Close function for the icp dev
* @sd: Pointer to struct v4l2_subdev
* @fh: Pointer to struct v4l2_subdev_fh
*/
int cam_ope_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh);
#endif /* _CAM_OPE_CONTEXT_H_ */

View file

@ -95,7 +95,7 @@ end:
return rc;
}
static int cam_ope_subdev_close(struct v4l2_subdev *sd,
int cam_ope_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
int rc = 0;
@ -134,6 +134,19 @@ end:
return rc;
}
static int cam_ope_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_OPE);
if (crm_active) {
CAM_DBG(CAM_OPE, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_ope_subdev_close_internal(sd, fh);
}
const struct v4l2_subdev_internal_ops cam_ope_subdev_internal_ops = {
.open = cam_ope_subdev_open,
.close = cam_ope_subdev_close,
@ -156,6 +169,7 @@ static int cam_ope_subdev_component_bind(struct device *dev,
g_ope_dev.sd.pdev = pdev;
g_ope_dev.sd.internal_ops = &cam_ope_subdev_internal_ops;
g_ope_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
rc = cam_subdev_probe(&g_ope_dev.sd, pdev, OPE_DEV_NAME,
CAM_OPE_DEVICE_TYPE);
if (rc) {

View file

@ -1339,7 +1339,8 @@ static int __cam_req_mgr_check_sync_for_mslave(
static int __cam_req_mgr_check_sync_req_is_ready(
struct cam_req_mgr_core_link *link,
struct cam_req_mgr_core_link *sync_link,
struct cam_req_mgr_slot *slot)
struct cam_req_mgr_slot *slot,
uint32_t trigger)
{
struct cam_req_mgr_slot *sync_rd_slot = NULL;
int64_t req_id = 0, sync_req_id = 0;
@ -1513,7 +1514,8 @@ static int __cam_req_mgr_check_sync_req_is_ready(
*/
master_slave_diff = sync_frame_duration;
do_div(master_slave_diff, 5);
if ((sync_link->sof_timestamp > 0) &&
if ((trigger == CAM_TRIGGER_POINT_SOF) &&
(sync_link->sof_timestamp > 0) &&
(sof_timestamp_delta < master_slave_diff) &&
(sync_rd_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)) {
@ -1574,7 +1576,8 @@ static int __cam_req_mgr_check_multi_sync_link_ready(
}
if (link->max_delay == link->sync_link[i]->max_delay) {
rc = __cam_req_mgr_check_sync_req_is_ready(
link, link->sync_link[i], slot);
link, link->sync_link[i],
slot, trigger);
if (rc < 0) {
CAM_DBG(CAM_CRM, "link %x not ready",
link->link_hdl);

View file

@ -17,6 +17,7 @@
#include <media/v4l2-ioctl.h>
#include <media/cam_req_mgr.h>
#include <media/cam_defs.h>
#include <linux/list_sort.h>
#include "cam_req_mgr_dev.h"
#include "cam_req_mgr_util.h"
@ -32,6 +33,7 @@
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;
static struct device_attribute camera_debug_sysfs_attr =
__ATTR(debug_node, 0600, NULL, cam_debug_sysfs_node_store);
@ -122,6 +124,7 @@ static int cam_req_mgr_open(struct file *filep)
spin_unlock_bh(&g_dev.cam_eventq_lock);
g_dev.open_cnt++;
g_dev.read_active_dev_id_hdls = 0;
rc = cam_mem_mgr_init();
if (rc) {
g_dev.open_cnt--;
@ -158,6 +161,7 @@ static unsigned int cam_req_mgr_poll(struct file *f,
static int cam_req_mgr_close(struct file *filep)
{
struct v4l2_subdev *sd;
struct cam_subdev *csd;
struct v4l2_fh *vfh = filep->private_data;
struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
@ -172,18 +176,23 @@ static int cam_req_mgr_close(struct file *filep)
}
cam_req_mgr_handle_core_shutdown();
g_dev.shutdown_state = true;
list_for_each_entry(sd, &g_dev.v4l2_dev->subdevs, list) {
list_for_each_entry(csd, &cam_req_mgr_ordered_sd_list, list) {
sd = &csd->sd;
if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
continue;
if (sd->internal_ops && sd->internal_ops->close) {
if (sd->internal_ops) {
CAM_DBG(CAM_CRM, "Invoke subdev close for device %s",
sd->name);
sd->internal_ops->close(sd, subdev_fh);
v4l2_subdev_call(sd, core, ioctl,
CAM_SD_SHUTDOWN, subdev_fh);
}
}
g_dev.open_cnt--;
g_dev.shutdown_state = false;
g_dev.read_active_dev_id_hdls = 0;
v4l2_fh_release(filep);
spin_lock_bh(&g_dev.cam_eventq_lock);
@ -659,6 +668,51 @@ void cam_subdev_notify_message(u32 subdev_type,
}
EXPORT_SYMBOL(cam_subdev_notify_message);
static int cam_req_mgr_ordered_list_cmp(void *priv,
struct list_head *head_1, struct list_head *head_2)
{
struct cam_subdev *entry_1 =
list_entry(head_1, struct cam_subdev, list);
struct cam_subdev *entry_2 =
list_entry(head_2, struct cam_subdev, list);
int ret = -1;
if (entry_1->close_seq_prior > entry_2->close_seq_prior)
return 1;
else if (entry_1->close_seq_prior < entry_2->close_seq_prior)
return ret;
else
return 0;
}
bool cam_req_mgr_is_open(uint64_t dev_id)
{
bool crm_status;
bool dev_id_status;
mutex_lock(&g_dev.cam_lock);
crm_status = g_dev.open_cnt ? true : false;
if (!g_dev.read_active_dev_id_hdls) {
g_dev.active_dev_id_hdls = cam_get_dev_handle_status();
g_dev.read_active_dev_id_hdls++;
}
dev_id_status = (g_dev.active_dev_id_hdls & dev_id) ? true : false;
crm_status &= dev_id_status;
mutex_unlock(&g_dev.cam_lock);
return crm_status;
}
EXPORT_SYMBOL(cam_req_mgr_is_open);
bool cam_req_mgr_is_shutdown(void)
{
return g_dev.shutdown_state;
}
EXPORT_SYMBOL(cam_req_mgr_is_shutdown);
int cam_register_subdev(struct cam_subdev *csd)
{
struct v4l2_subdev *sd;
@ -687,6 +741,10 @@ int cam_register_subdev(struct cam_subdev *csd)
sd->entity.pads = NULL;
sd->entity.function = csd->ent_function;
list_add(&csd->list, &cam_req_mgr_ordered_sd_list);
list_sort(NULL, &cam_req_mgr_ordered_sd_list,
cam_req_mgr_ordered_list_cmp);
rc = v4l2_device_register_subdev(g_dev.v4l2_dev, sd);
if (rc) {
CAM_ERR(CAM_CRM, "register subdev failed");
@ -747,6 +805,7 @@ static int cam_req_mgr_component_master_bind(struct device *dev)
goto video_setup_fail;
g_dev.open_cnt = 0;
g_dev.shutdown_state = false;
mutex_init(&g_dev.cam_lock);
spin_lock_init(&g_dev.cam_eventq_lock);
mutex_init(&g_dev.dev_lock);
@ -764,6 +823,7 @@ static int cam_req_mgr_component_master_bind(struct device *dev)
}
g_dev.state = true;
INIT_LIST_HEAD(&cam_req_mgr_ordered_sd_list);
if (g_cam_req_mgr_timer_cachep == NULL) {
g_cam_req_mgr_timer_cachep = kmem_cache_create("crm_timer",

View file

@ -19,6 +19,9 @@
* @cam_lock: per file handle lock
* @cam_eventq: event queue
* @cam_eventq_lock: lock for event queue
* @shutdown_state: shutdown state
* @active_dev_id_hdls: active dev id handles
* @read_active_dev_id_hdls: read active_dev_id_hdls status
*/
struct cam_req_mgr_device {
struct video_device *video;
@ -30,6 +33,9 @@ struct cam_req_mgr_device {
struct mutex cam_lock;
struct v4l2_fh *cam_eventq;
spinlock_t cam_eventq_lock;
bool shutdown_state;
uint64_t active_dev_id_hdls;
int read_active_dev_id_hdls;
};
#define CAM_REQ_MGR_GET_PAYLOAD_PTR(ev, type) \

View file

@ -14,6 +14,7 @@
#include <media/cam_req_mgr.h>
#include "cam_req_mgr_util.h"
#include "cam_debug_util.h"
#include "cam_context.h"
static struct cam_req_mgr_util_hdl_tbl *hdl_tbl;
static DEFINE_SPINLOCK(hdl_tbl_lock);
@ -209,6 +210,36 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
return handle;
}
int32_t cam_get_dev_handle_info(uint64_t handle,
struct cam_context **ctx, int32_t dev_index)
{
int32_t idx;
struct v4l2_subdev *sd = (struct v4l2_subdev *)handle;
for (idx = dev_index + 1; idx < CAM_REQ_MGR_MAX_HANDLES_V2; idx++) {
if (hdl_tbl->hdl[idx].state == HDL_ACTIVE) {
*ctx = (struct cam_context *)cam_get_device_priv(
hdl_tbl->hdl[idx].hdl_value);
if ((*ctx) && !strcmp(sd->name, (*ctx)->dev_name))
return idx;
}
}
*ctx = NULL;
return CAM_REQ_MGR_MAX_HANDLES_V2;
}
uint64_t cam_get_dev_handle_status(void)
{
int32_t idx;
uint64_t active_dev_hdls = 0;
for (idx = 0; idx < CAM_REQ_MGR_MAX_HANDLES_V2; idx++)
if (hdl_tbl->hdl[idx].state == HDL_ACTIVE)
active_dev_hdls |= hdl_tbl->hdl[idx].dev_id;
return active_dev_hdls;
}
void *cam_get_device_priv(int32_t dev_hdl)
{
int idx;

View file

@ -166,4 +166,11 @@ int32_t cam_req_mgr_util_deinit(void);
*/
int32_t cam_req_mgr_util_free_hdls(void);
/**
* cam_get_dev_handle_status() - get dev handles status
*
* Returns dev handle status
*/
uint64_t cam_get_dev_handle_status(void);
#endif /* _CAM_REQ_MGR_UTIL_API_H_ */

View file

@ -21,6 +21,13 @@ enum cam_subdev_message_type_t {
CAM_SUBDEV_MESSAGE_CLOCK_UPDATE
};
/* Enum for close sequence priority */
enum cam_subdev_close_seq_priority {
CAM_SD_CLOSE_HIGH_PRIORITY,
CAM_SD_CLOSE_MEDIUM_PRIORITY,
CAM_SD_CLOSE_LOW_PRIORITY
};
/**
* struct cam_subdev - describes a camera sub-device
*
@ -39,6 +46,8 @@ enum cam_subdev_message_type_t {
* @ent_function: Media entity function type. Can be:
* %CAM_IFE_DEVICE_TYPE - identifies as IFE device.
* %CAM_ICP_DEVICE_TYPE - identifies as ICP device.
* @list: list pointer
* @close_seq_prior: cam_subdev_close_seq_priority type
*
* Each instance of a subdev driver should create this struct, either
* stand-alone or embedded in a larger struct. This structure should be
@ -58,6 +67,8 @@ struct cam_subdev {
struct v4l2_subdev *sd,
enum cam_subdev_message_type_t msg_type,
uint32_t data);
struct list_head list;
enum cam_subdev_close_seq_priority close_seq_prior;
};
/**
@ -119,4 +130,20 @@ int cam_register_subdev(struct cam_subdev *sd);
*/
int cam_unregister_subdev(struct cam_subdev *sd);
/**
* cam_req_mgr_is_open()
*
* @brief: This common utility function returns the crm active status
*
* @dev_id: device id type
*/
bool cam_req_mgr_is_open(uint64_t dev_id);
/**
* cam_req_mgr_is_shutdown()
*
* @brief: This common utility function returns the shutdown state
*/
bool cam_req_mgr_is_shutdown(void);
#endif /* _CAM_SUBDEV_H_ */

View file

@ -10,6 +10,38 @@
#include "cam_trace.h"
#include "camera_main.h"
static int cam_actuator_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_actuator_ctrl_t *a_ctrl =
v4l2_get_subdevdata(sd);
if (!a_ctrl) {
CAM_ERR(CAM_ACTUATOR, "a_ctrl ptr is NULL");
return -EINVAL;
}
mutex_lock(&(a_ctrl->actuator_mutex));
cam_actuator_shutdown(a_ctrl);
mutex_unlock(&(a_ctrl->actuator_mutex));
return 0;
}
static int cam_actuator_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_ACTUATOR);
if (crm_active) {
CAM_DBG(CAM_ACTUATOR,
"CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_actuator_subdev_close_internal(sd, fh);
}
static long cam_actuator_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
@ -24,6 +56,14 @@ static long cam_actuator_subdev_ioctl(struct v4l2_subdev *sd,
CAM_ERR(CAM_ACTUATOR,
"Failed for driver_cmd: %d", rc);
break;
case CAM_SD_SHUTDOWN:
if (!cam_req_mgr_is_shutdown()) {
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
return 0;
}
rc = cam_actuator_subdev_close_internal(sd, NULL);
break;
default:
CAM_ERR(CAM_ACTUATOR, "Invalid ioctl cmd: %u", cmd);
rc = -ENOIOCTLCMD;
@ -77,24 +117,6 @@ static long cam_actuator_init_subdev_do_ioctl(struct v4l2_subdev *sd,
}
#endif
static int cam_actuator_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_actuator_ctrl_t *a_ctrl =
v4l2_get_subdevdata(sd);
if (!a_ctrl) {
CAM_ERR(CAM_ACTUATOR, "a_ctrl ptr is NULL");
return -EINVAL;
}
mutex_lock(&(a_ctrl->actuator_mutex));
cam_actuator_shutdown(a_ctrl);
mutex_unlock(&(a_ctrl->actuator_mutex));
return 0;
}
static struct v4l2_subdev_core_ops cam_actuator_subdev_core_ops = {
.ioctl = cam_actuator_subdev_ioctl,
#ifdef CONFIG_COMPAT
@ -127,10 +149,13 @@ static int cam_actuator_init_subdev(struct cam_actuator_ctrl_t *a_ctrl)
a_ctrl->v4l2_dev_str.ent_function =
CAM_ACTUATOR_DEVICE_TYPE;
a_ctrl->v4l2_dev_str.token = a_ctrl;
a_ctrl->v4l2_dev_str.close_seq_prior =
CAM_SD_CLOSE_MEDIUM_PRIORITY;
rc = cam_register_subdev(&(a_ctrl->v4l2_dev_str));
if (rc)
CAM_ERR(CAM_SENSOR, "Fail with cam_register_subdev rc: %d", rc);
CAM_ERR(CAM_ACTUATOR,
"Fail with cam_register_subdev rc: %d", rc);
return rc;
}

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 <linux/module.h>
@ -985,6 +985,7 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd,
}
mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]);
cci_dev->is_burst_read[master] = true;
reinit_completion(&cci_dev->cci_master_info[master].report_q[queue]);
soc_info = &cci_dev->soc_info;
@ -1256,6 +1257,7 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd,
}
mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]);
cci_dev->is_burst_read[master] = false;
reinit_completion(&cci_dev->cci_master_info[master].report_q[queue]);
soc_info = &cci_dev->soc_info;
@ -1622,7 +1624,7 @@ static int32_t cam_cci_read_bytes_v_1_2(struct v4l2_subdev *sd,
else
read_cfg->num_byte = read_bytes;
cci_dev->is_burst_read = false;
cci_dev->is_burst_read[master] = false;
rc = cam_cci_read(sd, c_ctrl);
if (rc) {
CAM_ERR(CAM_CCI, "failed to read rc:%d", rc);
@ -1639,7 +1641,6 @@ static int32_t cam_cci_read_bytes_v_1_2(struct v4l2_subdev *sd,
} while (read_bytes);
ERROR:
cci_dev->is_burst_read = false;
return rc;
}
@ -1704,10 +1705,8 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd,
read_cfg->num_byte = read_bytes;
if (read_cfg->num_byte >= CCI_READ_MAX) {
cci_dev->is_burst_read = true;
rc = cam_cci_burst_read(sd, c_ctrl);
} else {
cci_dev->is_burst_read = false;
rc = cam_cci_read(sd, c_ctrl);
}
if (rc) {
@ -1726,7 +1725,6 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd,
} while (read_bytes);
ERROR:
cci_dev->is_burst_read = false;
return rc;
}

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_cci_dev.h"
@ -112,7 +112,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
(!rd_done_th_assert)) {
cci_dev->cci_master_info[MASTER_0].status = 0;
rd_done_th_assert = true;
if (cci_dev->is_burst_read)
if (cci_dev->is_burst_read[MASTER_0])
complete(
&cci_dev->cci_master_info[MASTER_0].th_complete);
complete(&cci_dev->cci_master_info[MASTER_0].rd_done);
@ -168,7 +168,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
(!rd_done_th_assert)) {
cci_dev->cci_master_info[MASTER_1].status = 0;
rd_done_th_assert = true;
if (cci_dev->is_burst_read)
if (cci_dev->is_burst_read[MASTER_1])
complete(
&cci_dev->cci_master_info[MASTER_1].th_complete);
complete(&cci_dev->cci_master_info[MASTER_1].rd_done);

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.
*/
#ifndef _CAM_CCI_DEV_H_
@ -50,8 +50,8 @@
#define CCI_READ_MAX 256
#define CCI_READ_MAX_V_1_2 0xE
#define CCI_I2C_READ_MAX_RETRIES 3
#define CCI_I2C_MAX_READ 10240
#define CCI_I2C_MAX_WRITE 10240
#define CCI_I2C_MAX_READ 20480
#define CCI_I2C_MAX_WRITE 20480
#define CCI_I2C_MAX_BYTE_COUNT 65535
#define CAMX_CCI_DEV_NAME "cam-cci-driver"
@ -224,7 +224,7 @@ struct cci_device {
uint32_t cpas_handle;
uint32_t irq_status1;
spinlock_t lock_status;
bool is_burst_read;
bool is_burst_read[MASTER_MAX];
uint32_t irqs_disabled;
struct mutex init_mutex;
uint64_t dump_en;

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_cci_dev.h"
@ -76,6 +76,7 @@ static int cam_cci_init_master(struct cci_device *cci_dev,
cci_dev->cci_master_info[master].status = 0;
cci_dev->cci_master_info[master].is_initilized = true;
cci_dev->is_burst_read[master] = false;
}
return 0;

View file

@ -77,29 +77,7 @@ static void cam_csiphy_debug_unregister(void)
root_dentry = NULL;
}
static long cam_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
struct csiphy_device *csiphy_dev = v4l2_get_subdevdata(sd);
int rc = 0;
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = cam_csiphy_core_cfg(csiphy_dev, arg);
if (rc)
CAM_ERR(CAM_CSIPHY,
"Failed in configuring the device: %d", rc);
break;
default:
CAM_ERR(CAM_CSIPHY, "Wrong ioctl : %d", cmd);
rc = -ENOIOCTLCMD;
break;
}
return rc;
}
static int cam_csiphy_subdev_close(struct v4l2_subdev *sd,
static int cam_csiphy_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct csiphy_device *csiphy_dev =
@ -117,6 +95,49 @@ static int cam_csiphy_subdev_close(struct v4l2_subdev *sd,
return 0;
}
static int cam_csiphy_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_CSIPHY);
if (crm_active) {
CAM_DBG(CAM_CSIPHY, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_csiphy_subdev_close_internal(sd, fh);
}
static long cam_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
struct csiphy_device *csiphy_dev = v4l2_get_subdevdata(sd);
int rc = 0;
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = cam_csiphy_core_cfg(csiphy_dev, arg);
if (rc)
CAM_ERR(CAM_CSIPHY,
"Failed in configuring the device: %d", rc);
break;
case CAM_SD_SHUTDOWN:
if (!cam_req_mgr_is_shutdown()) {
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
return 0;
}
rc = cam_csiphy_subdev_close_internal(sd, NULL);
break;
default:
CAM_ERR(CAM_CSIPHY, "Wrong ioctl : %d", cmd);
rc = -ENOIOCTLCMD;
break;
}
return rc;
}
#ifdef CONFIG_COMPAT
static long cam_csiphy_subdev_compat_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, unsigned long arg)
@ -236,6 +257,8 @@ static int cam_csiphy_component_bind(struct device *dev,
cam_csiphy_subdev_handle_message;
new_csiphy_dev->v4l2_dev_str.token =
new_csiphy_dev;
new_csiphy_dev->v4l2_dev_str.close_seq_prior =
CAM_SD_CLOSE_MEDIUM_PRIORITY;
rc = cam_register_subdev(&(new_csiphy_dev->v4l2_dev_str));
if (rc < 0) {

View file

@ -10,28 +10,7 @@
#include "cam_debug_util.h"
#include "camera_main.h"
static long cam_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
int rc = 0;
struct cam_eeprom_ctrl_t *e_ctrl = v4l2_get_subdevdata(sd);
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = cam_eeprom_driver_cmd(e_ctrl, arg);
if (rc)
CAM_ERR(CAM_EEPROM,
"Failed in Driver cmd: %d", rc);
break;
default:
rc = -ENOIOCTLCMD;
break;
}
return rc;
}
static int cam_eeprom_subdev_close(struct v4l2_subdev *sd,
static int cam_eeprom_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_eeprom_ctrl_t *e_ctrl =
@ -49,6 +28,48 @@ static int cam_eeprom_subdev_close(struct v4l2_subdev *sd,
return 0;
}
static int cam_eeprom_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_EEPROM);
if (crm_active) {
CAM_DBG(CAM_EEPROM, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_eeprom_subdev_close_internal(sd, fh);
}
static long cam_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
int rc = 0;
struct cam_eeprom_ctrl_t *e_ctrl = v4l2_get_subdevdata(sd);
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = cam_eeprom_driver_cmd(e_ctrl, arg);
if (rc)
CAM_ERR(CAM_EEPROM,
"Failed in Driver cmd: %d", rc);
break;
case CAM_SD_SHUTDOWN:
if (!cam_req_mgr_is_shutdown()) {
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
return 0;
}
rc = cam_eeprom_subdev_close_internal(sd, NULL);
break;
default:
rc = -ENOIOCTLCMD;
break;
}
return rc;
}
int32_t cam_eeprom_update_i2c_info(struct cam_eeprom_ctrl_t *e_ctrl,
struct cam_eeprom_i2c_info_t *i2c_info)
{
@ -147,6 +168,7 @@ static int cam_eeprom_init_subdev(struct cam_eeprom_ctrl_t *e_ctrl)
(V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS);
e_ctrl->v4l2_dev_str.ent_function = CAM_EEPROM_DEVICE_TYPE;
e_ctrl->v4l2_dev_str.token = e_ctrl;
e_ctrl->v4l2_dev_str.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
rc = cam_register_subdev(&(e_ctrl->v4l2_dev_str));
if (rc)

View file

@ -10,6 +10,7 @@
#include "cam_res_mgr_api.h"
#include "cam_common_util.h"
#include "cam_packet_util.h"
#include <asm/div64.h>
static uint default_on_timer = 2;
module_param(default_on_timer, uint, 0644);
@ -1558,8 +1559,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
add_req.trigger_eof = true;
/* Active time for the preflash */
flash_data->flash_active_time_ms =
(flash_operation_info->time_on_duration_ns)
/ 1000000;
do_div(flash_operation_info->time_on_duration_ns, 1000000);
CAM_DBG(CAM_FLASH,
"PRECISE FLASH: active_time: %llu",
flash_data->flash_active_time_ms);

View file

@ -133,7 +133,8 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
struct cam_flash_query_cap_info flash_cap = {0};
CAM_DBG(CAM_FLASH, "CAM_QUERY_CAP");
flash_cap.slot_info = fctrl->soc_info.index;
flash_cap.slot_info = fctrl->soc_info.index;
flash_cap.flash_type = soc_private->flash_type;
for (i = 0; i < fctrl->flash_num_sources; i++) {
flash_cap.max_current_flash[i] =
soc_private->flash_max_current[i];
@ -236,6 +237,37 @@ static const struct of_device_id cam_flash_dt_match[] = {
{}
};
static int cam_flash_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_flash_ctrl *fctrl =
v4l2_get_subdevdata(sd);
if (!fctrl) {
CAM_ERR(CAM_FLASH, "Flash ctrl ptr is NULL");
return -EINVAL;
}
mutex_lock(&fctrl->flash_mutex);
cam_flash_shutdown(fctrl);
mutex_unlock(&fctrl->flash_mutex);
return 0;
}
static int cam_flash_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_FLASH);
if (crm_active) {
CAM_DBG(CAM_FLASH, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_flash_subdev_close_internal(sd, fh);
}
static long cam_flash_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
@ -257,6 +289,14 @@ static long cam_flash_subdev_ioctl(struct v4l2_subdev *sd,
"Failed in driver cmd: %d", rc);
break;
}
case CAM_SD_SHUTDOWN:
if (!cam_req_mgr_is_shutdown()) {
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
return 0;
}
rc = cam_flash_subdev_close_internal(sd, NULL);
break;
default:
CAM_ERR(CAM_FLASH, "Invalid ioctl cmd type");
rc = -ENOIOCTLCMD;
@ -328,24 +368,6 @@ static int32_t cam_flash_i2c_driver_remove(struct i2c_client *client)
return rc;
}
static int cam_flash_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_flash_ctrl *fctrl =
v4l2_get_subdevdata(sd);
if (!fctrl) {
CAM_ERR(CAM_FLASH, "Flash ctrl ptr is NULL");
return -EINVAL;
}
mutex_lock(&fctrl->flash_mutex);
cam_flash_shutdown(fctrl);
mutex_unlock(&fctrl->flash_mutex);
return 0;
}
static struct v4l2_subdev_core_ops cam_flash_subdev_core_ops = {
.ioctl = cam_flash_subdev_ioctl,
#ifdef CONFIG_COMPAT
@ -375,6 +397,7 @@ static int cam_flash_init_subdev(struct cam_flash_ctrl *fctrl)
V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
fctrl->v4l2_dev_str.ent_function = CAM_FLASH_DEVICE_TYPE;
fctrl->v4l2_dev_str.token = fctrl;
fctrl->v4l2_dev_str.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
rc = cam_register_subdev(&(fctrl->v4l2_dev_str));
if (rc)
@ -390,6 +413,7 @@ static int cam_flash_component_bind(struct device *dev,
struct cam_flash_ctrl *fctrl = NULL;
struct device_node *of_parent = NULL;
struct platform_device *pdev = to_platform_device(dev);
struct cam_hw_soc_info *soc_info = NULL;
CAM_DBG(CAM_FLASH, "Binding flash component");
if (!pdev->dev.of_node) {
@ -445,6 +469,19 @@ static int cam_flash_component_bind(struct device *dev,
fctrl->io_master_info.cci_client->cci_device = fctrl->cci_num;
CAM_DBG(CAM_FLASH, "cci-index %d", fctrl->cci_num, rc);
soc_info = &fctrl->soc_info;
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");
return -EINVAL;
}
rc = cam_sensor_util_regulator_powerup(soc_info);
if (rc < 0) {
CAM_ERR(CAM_FLASH, "regulator power up for flash failed %d", rc);
return rc;
}
fctrl->i2c_data.per_frame =
kzalloc(sizeof(struct i2c_settings_array) *
MAX_PER_FRAME_ARRAY, GFP_KERNEL);

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.
*/
#ifndef _CAM_FLASH_DEV_H_
@ -30,6 +30,7 @@
#include "cam_subdev.h"
#include "cam_mem_mgr.h"
#include "cam_sensor_cmn_header.h"
#include "cam_sensor_util.h"
#include "cam_soc_util.h"
#include "cam_debug_util.h"
#include "cam_sensor_io.h"
@ -137,6 +138,7 @@ struct cam_flash_frame_setting {
* @torch_op_current : Torch operational current
* @torch_max_current : Max supported current for LED in torch mode
* @is_wled_flash : Detection between WLED/LED flash
* @flash_type : Flash type
*/
struct cam_flash_private_soc {
@ -149,6 +151,7 @@ struct cam_flash_private_soc {
uint32_t torch_op_current[CAM_FLASH_MAX_LED_TRIGGERS];
uint32_t torch_max_current[CAM_FLASH_MAX_LED_TRIGGERS];
bool is_wled_flash;
uint32_t flash_type;
};
struct cam_flash_func_tbl {

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 <linux/of.h>
@ -73,6 +73,12 @@ static int32_t cam_get_source_node_info(
soc_private->is_wled_flash =
of_property_read_bool(of_node, "wled-flash-support");
rc = of_property_read_u32(of_node, "flash-type", &soc_private->flash_type);
if (rc) {
CAM_ERR(CAM_FLASH,
"flash-type read failed rc=%d", rc);
}
switch_src_node = of_parse_phandle(of_node, "switch-source", 0);
if (!switch_src_node) {
CAM_WARN(CAM_FLASH, "switch_src_node NULL");

View file

@ -10,29 +10,7 @@
#include "cam_debug_util.h"
#include "camera_main.h"
static long cam_ois_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
int rc = 0;
struct cam_ois_ctrl_t *o_ctrl = v4l2_get_subdevdata(sd);
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = cam_ois_driver_cmd(o_ctrl, arg);
if (rc)
CAM_ERR(CAM_OIS,
"Failed with driver cmd: %d", rc);
break;
default:
CAM_ERR(CAM_OIS, "Wrong IOCTL cmd: %u", cmd);
rc = -ENOIOCTLCMD;
break;
}
return rc;
}
static int cam_ois_subdev_close(struct v4l2_subdev *sd,
static int cam_ois_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_ois_ctrl_t *o_ctrl =
@ -50,6 +28,48 @@ static int cam_ois_subdev_close(struct v4l2_subdev *sd,
return 0;
}
static int cam_ois_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_OIS);
if (crm_active) {
CAM_DBG(CAM_OIS, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_ois_subdev_close_internal(sd, fh);
}
static long cam_ois_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
int rc = 0;
struct cam_ois_ctrl_t *o_ctrl = v4l2_get_subdevdata(sd);
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = cam_ois_driver_cmd(o_ctrl, arg);
if (rc)
CAM_ERR(CAM_OIS,
"Failed with driver cmd: %d", rc);
break;
case CAM_SD_SHUTDOWN:
if (!cam_req_mgr_is_shutdown()) {
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
return 0;
}
rc = cam_ois_subdev_close_internal(sd, NULL);
break;
default:
CAM_ERR(CAM_OIS, "Wrong IOCTL cmd: %u", cmd);
rc = -ENOIOCTLCMD;
break;
}
return rc;
}
static int32_t cam_ois_update_i2c_info(struct cam_ois_ctrl_t *o_ctrl,
struct cam_ois_i2c_info_t *i2c_info)
{
@ -144,6 +164,7 @@ static int cam_ois_init_subdev_param(struct cam_ois_ctrl_t *o_ctrl)
(V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS);
o_ctrl->v4l2_dev_str.ent_function = CAM_OIS_DEVICE_TYPE;
o_ctrl->v4l2_dev_str.token = o_ctrl;
o_ctrl->v4l2_dev_str.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
rc = cam_register_subdev(&(o_ctrl->v4l2_dev_str));
if (rc)

View file

@ -9,29 +9,7 @@
#include "cam_sensor_core.h"
#include "camera_main.h"
static long cam_sensor_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
int rc = 0;
struct cam_sensor_ctrl_t *s_ctrl =
v4l2_get_subdevdata(sd);
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = cam_sensor_driver_cmd(s_ctrl, arg);
if (rc)
CAM_ERR(CAM_SENSOR,
"Failed in Driver cmd: %d", rc);
break;
default:
CAM_ERR(CAM_SENSOR, "Invalid ioctl cmd: %d", cmd);
rc = -ENOIOCTLCMD;
break;
}
return rc;
}
static int cam_sensor_subdev_close(struct v4l2_subdev *sd,
static int cam_sensor_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_sensor_ctrl_t *s_ctrl =
@ -49,6 +27,49 @@ static int cam_sensor_subdev_close(struct v4l2_subdev *sd,
return 0;
}
static int cam_sensor_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_SENSOR);
if (crm_active) {
CAM_DBG(CAM_SENSOR, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_sensor_subdev_close_internal(sd, fh);
}
static long cam_sensor_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
int rc = 0;
struct cam_sensor_ctrl_t *s_ctrl =
v4l2_get_subdevdata(sd);
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = cam_sensor_driver_cmd(s_ctrl, arg);
if (rc)
CAM_ERR(CAM_SENSOR,
"Failed in Driver cmd: %d", rc);
break;
case CAM_SD_SHUTDOWN:
if (!cam_req_mgr_is_shutdown()) {
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
return 0;
}
rc = cam_sensor_subdev_close_internal(sd, NULL);
break;
default:
CAM_ERR(CAM_SENSOR, "Invalid ioctl cmd: %d", cmd);
rc = -ENOIOCTLCMD;
break;
}
return rc;
}
#ifdef CONFIG_COMPAT
static long cam_sensor_init_subdev_do_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, unsigned long arg)
@ -122,6 +143,8 @@ static int cam_sensor_init_subdev_params(struct cam_sensor_ctrl_t *s_ctrl)
s_ctrl->v4l2_dev_str.ent_function =
CAM_SENSOR_DEVICE_TYPE;
s_ctrl->v4l2_dev_str.token = s_ctrl;
s_ctrl->v4l2_dev_str.close_seq_prior =
CAM_SD_CLOSE_MEDIUM_PRIORITY;
rc = cam_register_subdev(&(s_ctrl->v4l2_dev_str));
if (rc)

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.
*/
#ifndef _CAM_SENSOR_I2C_H_
@ -18,7 +18,7 @@
#define I2C_COMPARE_MATCH 0
#define I2C_COMPARE_MISMATCH 1
#define I2C_REG_DATA_MAX (10*1024)
#define I2C_REG_DATA_MAX (20*1024)
/**
* @client: CCI client structure

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.
*/
#ifndef _CAM_SENSOR_CMN_HEADER_
@ -345,6 +345,12 @@ enum msm_sensor_camera_id_t {
CAMERA_7,
CAMERA_8,
CAMERA_9,
CAMERA_10,
CAMERA_11,
CAMERA_12,
CAMERA_13,
CAMERA_14,
CAMERA_15,
MAX_CAMERAS,
};

View file

@ -2407,6 +2407,10 @@ int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
case SENSOR_CUSTOM_GPIO1:
case SENSOR_CUSTOM_GPIO2:
if (!gpio_num_info) {
CAM_ERR(CAM_SENSOR, "failed: No gpio");
continue;
}
if (!gpio_num_info->valid[pd->seq_type])
continue;

View file

@ -1,11 +1,11 @@
// 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.
*/
#include <linux/interconnect.h>
#include "cam_soc_bus.h"
#include <asm/div64.h>
/**
* struct cam_soc_bus_client_data : Bus client data
*
@ -37,8 +37,8 @@ int cam_soc_bus_client_update_request(void *client, unsigned int idx)
CAM_DBG(CAM_PERF, "Bus client=[%s] index[%d] ab[%llu] ib[%llu]",
bus_client->common_data->name, idx, ab, ib);
rc = icc_set_bw(bus_client_data->icc_data, Bps_to_icc(ab),
Bps_to_icc(ib));
rc = icc_set_bw(bus_client_data->icc_data, do_div(ab, 1000),
do_div(ib, 1000));
if (rc) {
CAM_ERR(CAM_UTIL,
"Update request failed, client[%s], idx: %d",
@ -60,8 +60,8 @@ int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib)
CAM_DBG(CAM_PERF, "Bus client=[%s] :ab[%llu] ib[%llu]",
bus_client->common_data->name, ab, ib);
rc = icc_set_bw(bus_client_data->icc_data, Bps_to_icc(ab),
Bps_to_icc(ib));
rc = icc_set_bw(bus_client_data->icc_data, do_div(ab, 1000),
do_div(ib, 1000));
if (rc) {
CAM_ERR(CAM_UTIL, "Update request failed, client[%s]",
bus_client->common_data->name);

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*/
#ifndef __UAPI_CAM_SENSOR_H__
@ -476,6 +476,7 @@ struct cam_flash_query_curr {
* @max_current_flash : max supported current for flash
* @max_duration_flash : max flash turn on duration
* @max_current_torch : max supported current for torch
* @flash_type : Indicates about the flash type -I2C,GPIO,PMIC
*
*/
struct cam_flash_query_cap_info {
@ -483,6 +484,7 @@ struct cam_flash_query_cap_info {
__u32 max_current_flash[CAM_FLASH_MAX_LED_TRIGGERS];
__u32 max_duration_flash[CAM_FLASH_MAX_LED_TRIGGERS];
__u32 max_current_torch[CAM_FLASH_MAX_LED_TRIGGERS];
__u32 flash_type;
} __attribute__ ((packed));
#endif