Revert "DIRTY: camera-kernel: Import everything from Samsung"

This reverts commit 4e6b7ad60a.
This commit is contained in:
David Wronek 2025-01-06 17:10:44 +01:00
parent 1c37d8a8c1
commit 9eeb4d671b
213 changed files with 21648 additions and 5492 deletions

View File

@ -6,12 +6,8 @@ $(info "KERNEL_ROOT is: $(KERNEL_ROOT)")
endif
# Include Architecture configurations
ifeq ($(CONFIG_ARCH_PINEAPPLE), y)
include $(CAMERA_KERNEL_ROOT)/config/pineapple.mk
endif
ifeq ($(CONFIG_ARCH_KALAMA), y)
include $(CAMERA_KERNEL_ROOT)/config/kalama.mk
ifeq ($(CONFIG_ARCH_CLIFFS), y)
include $(CAMERA_KERNEL_ROOT)/config/cliffs.mk
endif
ifeq ($(CONFIG_ARCH_WAIPIO), y)
@ -54,6 +50,24 @@ ifeq ($(CONFIG_ARCH_PARROT), y)
include $(CAMERA_KERNEL_ROOT)/config/parrot.mk
endif
# For some targets which have binary compatible gki kernel with another one,
# we cannot rely on CONFIG_ARCH_* symbol which is defined in Kernel defconfig
ifeq ($(BOARD_PLATFORM), kalama)
include $(CAMERA_KERNEL_ROOT)/config/kalama.mk
endif
ifeq ($(BOARD_PLATFORM), crow)
include $(CAMERA_KERNEL_ROOT)/config/crow.mk
endif
ifeq ($(BOARD_PLATFORM), pineapple)
include $(CAMERA_KERNEL_ROOT)/config/pineapple.mk
endif
ifeq ($(BOARD_PLATFORM), volcano)
include $(CAMERA_KERNEL_ROOT)/config/volcano.mk
endif
ifneq ($(KBUILD_EXTRA_CONFIGS),)
include $(KBUILD_EXTRA_CONFIGS)
endif

View File

@ -6,6 +6,13 @@ config SPECTRA_ISP
This will enable camera ISP driver to handle IFE driver.
Core camera driver to handle VFE HW.
config SPECTRA_TFE
bool "enable camera tfe modele"
help
This is enabling camera tfe module.
tfe module files will be included to enable tfe based driver,
files.
config SPECTRA_ICP
bool "enable camera ICP module"
help
@ -21,7 +28,13 @@ config SPECTRA_JPEG
camera jpeg module will be functional.
This module interact with jpeg HW for
snapshot processing.
config SPECTRA_CRE
bool "enable camera jpeg module"
help
This is enabling camera CRE module.
camera cre module will be functional.
This module interact with cre HW for
format conversion.
config SPECTRA_SENSOR
bool "enable camera sensor module"
help
@ -86,6 +99,22 @@ config DOMAIN_ID_SECURE_CAMERA
domain ID based security architecture.
VC based security can be achieved with this.
config CSF_2_5_SECURE_CAMERA
bool "enable CSF2.5 feature flow"
help
This is to enable Call flow for CSF2.5
enabled platforms. this config differentiates
between csf2.0 and csf 2.5 compliant
scm calls.
config DYNAMIC_FD_PORT_CONFIG
bool "enable dynamic FD port config feature"
help
This config enables dynamic FD port config
feature that allows the userspace to configure
the FD port to secure or non-secure based on
the FD solution in use in secure camera use cases.
config SAMSUNG_OIS_MCU_STM32
bool "enable camera mcu stm32 module"
help

View File

@ -4,21 +4,27 @@
CONFIG_SPECTRA_ISP := y
CONFIG_SPECTRA_ICP := y
CONFIG_SPECTRA_JPEG := y
CONFIG_SPECTRA_CRE := y
CONFIG_SPECTRA_SENSOR := y
CONFIG_SPECTRA_LLCC_STALING := y
CONFIG_SPECTRA_USE_RPMH_DRV_API := y
CONFIG_SPECTRA_USE_CLK_CRM_API := y
CONFIG_DOMAIN_ID_SECURE_CAMERA := y
CONFIG_DYNAMIC_FD_PORT_CONFIG := y
CONFIG_CSF_2_5_SECURE_CAMERA := y
# Flags to pass into C preprocessor
ccflags-y += -DCONFIG_SPECTRA_ISP=1
ccflags-y += -DCONFIG_SPECTRA_ICP=1
ccflags-y += -DCONFIG_SPECTRA_JPEG=1
ccflags-y += -DCONFIG_SPECTRA_CRE=1
ccflags-y += -DCONFIG_SPECTRA_SENSOR=1
ccflags-y += -DCONFIG_SPECTRA_LLCC_STALING=1
ccflags-y += -DCONFIG_SPECTRA_USE_RPMH_DRV_API=1
ccflags-y += -DCONFIG_SPECTRA_USE_CLK_CRM_API=1
ccflags-y += -DCONFIG_DOMAIN_ID_SECURE_CAMERA=1
ccflags-y += -DCONFIG_DYNAMIC_FD_PORT_CONFIG=1
ccflags-y += -DCONFIG_CSF_2_5_SECURE_CAMERA=1
ifeq (y, $(filter y, \
$(CONFIG_SEC_PLATFORM_MU1Q) \

View File

@ -2349,7 +2349,7 @@ static int cam_hw_cdm_component_bind(struct device *dev,
sizeof(work_q_name));
snprintf(work_q_name + len, sizeof(work_q_name) - len, "%d_%d", cdm_hw->soc_info.index, i);
cdm_core->bl_fifo[i].work_queue = alloc_workqueue(work_q_name,
WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS | WQ_HIGHPRI,
WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS,
CAM_CDM_INFLIGHT_WORKS);
if (!cdm_core->bl_fifo[i].work_queue) {
CAM_ERR(CAM_CDM,

View File

@ -18,7 +18,6 @@
#define CAM_CDM_SW_CMD_COUNT 2
#define CAM_CMD_LENGTH_MASK 0xFFFF
#define CAM_CDM_COMMAND_OFFSET 24
#define CAM_CDM_REG_OFFSET_MASK 0x00FFFFFF
#define CAM_CDM_DMI_DATA_HI_OFFSET 8
@ -493,7 +492,7 @@ int cam_cdm_get_ioremap_from_base(uint32_t hw_base,
static int cam_cdm_util_cmd_buf_validation(void __iomem *base_addr,
uint32_t base_array_size,
struct cam_soc_reg_map *base_table[CAM_SOC_MAX_BLOCK],
uint32_t cmd_buf_size, uint32_t *buf,
uint32_t cmd_buf_size, uint32_t *cmd_buf, void *buf,
resource_size_t *size,
enum cam_cdm_command cmd_type)
{
@ -521,6 +520,8 @@ static int cam_cdm_util_cmd_buf_validation(void __iomem *base_addr,
switch (cmd_type) {
case CAM_CDM_CMD_REG_RANDOM: {
struct cdm_regrandom_cmd *reg_random = (struct cdm_regrandom_cmd *)buf;
uint32_t *data, offset;
if ((!reg_random->count) || (((reg_random->count * (sizeof(uint32_t) * 2)) +
cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM)) >
cmd_buf_size)) {
@ -528,10 +529,23 @@ static int cam_cdm_util_cmd_buf_validation(void __iomem *base_addr,
reg_random->count, cmd_buf_size);
ret = -EINVAL;
}
data = cmd_buf + cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);
for (i = 0; i < reg_random->count; i++) {
offset = data[0];
if (offset > *size) {
CAM_ERR(CAM_CDM, "Offset out of mapped range! size:%llu offset:%u",
*size, offset);
return -EINVAL;
}
data += 2;
}
}
break;
case CAM_CDM_CMD_REG_CONT: {
struct cdm_regcontinuous_cmd *reg_cont = (struct cdm_regcontinuous_cmd *) buf;
if ((!reg_cont->count) || (((reg_cont->count * sizeof(uint32_t)) +
cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT)) >
cmd_buf_size)) {
@ -539,17 +553,66 @@ static int cam_cdm_util_cmd_buf_validation(void __iomem *base_addr,
cmd_buf_size, reg_cont->count);
ret = -EINVAL;
}
if ((reg_cont->offset > *size) && ((reg_cont->offset +
(reg_cont->count * sizeof(uint32_t))) > *size)) {
CAM_ERR(CAM_CDM, "Offset out of mapped range! size: %lu, offset: %u",
*size, reg_cont->offset);
return -EINVAL;
}
}
break;
case CAM_CDM_CMD_DMI:
case CAM_CDM_CMD_SWD_DMI_32:
case CAM_CDM_CMD_SWD_DMI_64: {
struct cdm_dmi_cmd *swd_dmi = (struct cdm_dmi_cmd *) buf;
if (cmd_buf_size < (cam_cdm_required_size_dmi() + swd_dmi->length + 1)) {
CAM_ERR(CAM_CDM, "invalid CDM_SWD_DMI length %d",
swd_dmi->length + 1);
ret = -EINVAL;
}
if ((swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET > *size) ||
(swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_HI_OFFSET > *size)) {
CAM_ERR(CAM_CDM,
"Offset out of mapped range! size:%llu lo_offset:%u hi_offset:%u",
*size, swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET,
swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET);
return -EINVAL;
}
}
break;
case CAM_CDM_CMD_SWD_DMI_32: {
struct cdm_dmi_cmd *swd_dmi = (struct cdm_dmi_cmd *) buf;
if (cmd_buf_size < (cam_cdm_required_size_dmi() + swd_dmi->length + 1)) {
CAM_ERR(CAM_CDM, "invalid CDM_SWD_DMI length %d",
swd_dmi->length + 1);
ret = -EINVAL;
}
if (swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET > *size) {
CAM_ERR(CAM_CDM,
"Offset out of mapped range! size:%llu lo_offset:%u",
*size, swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET);
return -EINVAL;
}
}
break;
case CAM_CDM_CMD_DMI: {
struct cdm_dmi_cmd *swd_dmi = (struct cdm_dmi_cmd *) buf;
if (cmd_buf_size < (cam_cdm_required_size_dmi() + swd_dmi->length + 1)) {
CAM_ERR(CAM_CDM, "invalid CDM_SWD_DMI length %d",
swd_dmi->length + 1);
ret = -EINVAL;
}
if (swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_OFFSET > *size) {
CAM_ERR(CAM_CDM,
"Offset out of mapped range! size:%llu offset:%u",
*size, swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_OFFSET);
return -EINVAL;
}
}
break;
default:
@ -572,27 +635,19 @@ static int cam_cdm_util_reg_cont_write(void __iomem *base_addr,
struct cdm_regcontinuous_cmd reg_cont;
resource_size_t size = 0;
memcpy(&reg_cont, cmd_buf, sizeof(struct cdm_regcontinuous_cmd));
rc = cam_cdm_util_cmd_buf_validation(base_addr, base_array_size, base_table,
cmd_buf_size, cmd_buf, &size, CAM_CDM_CMD_REG_CONT);
cmd_buf_size, cmd_buf, (void *)&reg_cont,
&size, CAM_CDM_CMD_REG_CONT);
if (rc) {
CAM_ERR(CAM_CDM, "Validation failed! rc=%d", rc);
return rc;
}
memcpy(&reg_cont, cmd_buf, sizeof(struct cdm_regcontinuous_cmd));
data = cmd_buf + cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT);
if ((reg_cont.offset <= size) && ((reg_cont.offset +
(reg_cont.count * sizeof(uint32_t))) <= size)) {
cam_io_memcpy(base_addr + reg_cont.offset, data,
reg_cont.count * sizeof(uint32_t));
} else {
CAM_ERR(CAM_CDM, "Offset out of mapped range! size: %lu, offset: %u",
size, reg_cont.offset);
return -EINVAL;
}
cam_io_memcpy(base_addr + reg_cont.offset, data,
reg_cont.count * sizeof(uint32_t));
*used_bytes = (reg_cont.count * sizeof(uint32_t)) +
(4 * cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT));
@ -609,30 +664,25 @@ static int cam_cdm_util_reg_random_write(void __iomem *base_addr,
uint32_t *data, offset;
resource_size_t size = 0;
memcpy(&reg_random, cmd_buf, sizeof(struct cdm_regrandom_cmd));
rc = cam_cdm_util_cmd_buf_validation(base_addr, base_array_size, base_table,
cmd_buf_size, cmd_buf,
cmd_buf_size, cmd_buf, (void *)&reg_random,
&size, CAM_CDM_CMD_REG_RANDOM);
if (rc) {
CAM_ERR(CAM_CDM, "Validation failed! rc=%d", rc);
return rc;
}
memcpy(&reg_random, cmd_buf, sizeof(struct cdm_regrandom_cmd));
data = cmd_buf + cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);
for (i = 0; i < reg_random.count; i++) {
offset = data[0];
if (offset <= size) {
CAM_DBG(CAM_CDM, "reg random: offset %pK, value 0x%x",
((void __iomem *)(base_addr + offset)),
data[1]);
cam_io_w(data[1], base_addr + offset);
data += 2;
} else {
CAM_ERR(CAM_CDM, "Offset out of mapped range! size: %llu, offset: %u",
size, offset);
return -EINVAL;
}
CAM_DBG(CAM_CDM, "reg random: offset %pK, value 0x%x",
((void __iomem *)(base_addr + offset)),
data[1]);
cam_io_w(data[1], base_addr + offset);
data += 2;
}
*used_bytes = ((reg_random.count * (sizeof(uint32_t) * 2)) +
@ -651,52 +701,32 @@ static int cam_cdm_util_swd_dmi_write(uint32_t cdm_cmd_type,
uint32_t *data;
resource_size_t size = 0;
memcpy(&swd_dmi, cmd_buf, sizeof(struct cdm_dmi_cmd));
rc = cam_cdm_util_cmd_buf_validation(base_addr, base_array_size, base_table,
cmd_buf_size, cmd_buf,
cmd_buf_size, cmd_buf, (void *)&swd_dmi,
&size, cdm_cmd_type);
if (rc) {
CAM_ERR(CAM_CDM, "Validation failed! rc=%d", rc);
return rc;
}
memcpy(&swd_dmi, cmd_buf, sizeof(struct cdm_dmi_cmd));
data = cmd_buf + cam_cdm_required_size_dmi();
if (cdm_cmd_type == CAM_CDM_CMD_SWD_DMI_64) {
if ((swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET > size) ||
(swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_HI_OFFSET > size)) {
CAM_ERR(CAM_CDM,
"Offset out of mapped range! size:%llu lo_offset:%u hi_offset:%u",
size, swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET,
swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET);
return -EINVAL;
}
for (i = 0; i < (swd_dmi.length + 1)/8; i++) {
cam_io_w_mb(data[0], base_addr +
swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET);
cam_io_w_mb(data[1], base_addr +
swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_HI_OFFSET);
swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_HI_OFFSET);
data += 2;
}
} else if (cdm_cmd_type == CAM_CDM_CMD_DMI) {
if (swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_OFFSET > size) {
CAM_ERR(CAM_CDM,
"Offset out of mapped range! size:%llu offset:%u",
size, swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_OFFSET);
return -EINVAL;
}
for (i = 0; i < (swd_dmi.length + 1)/4; i++) {
cam_io_w_mb(data[0], base_addr +
swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_OFFSET);
data += 1;
}
} else {
if (swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET > size) {
CAM_ERR(CAM_CDM,
"Offset out of mapped range! size:%llu lo_offset:%u",
size, swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET);
return -EINVAL;
}
for (i = 0; i < (swd_dmi.length + 1)/4; i++) {
cam_io_w_mb(data[0], base_addr +
swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET);
@ -981,6 +1011,88 @@ static long cam_cdm_util_dump_perf_ctrl_cmd(uint32_t *cmd_buf_addr)
return ret;
}
bool cam_cdm_util_validate_cmd_buf(
uint32_t *cmd_buf_start, uint32_t *cmd_buf_end)
{
uint32_t *buf_now = cmd_buf_start;
uint32_t *buf_end = cmd_buf_end;
uint32_t cmd = 0;
int i = 0;
struct cdm_regcontinuous_cmd *p_regcont_cmd = NULL;
struct cdm_regrandom_cmd *p_regrand_cmd = NULL;
if (!cmd_buf_start || !cmd_buf_end) {
CAM_ERR(CAM_CDM, "Invalid args");
return true;
}
do {
cmd = *buf_now;
cmd = cmd >> CAM_CDM_COMMAND_OFFSET;
switch (cmd) {
case CAM_CDM_CMD_DMI:
case CAM_CDM_CMD_DMI_32:
case CAM_CDM_CMD_DMI_64:
if (buf_now > buf_end)
return true;
buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI];
break;
case CAM_CDM_CMD_REG_CONT:
p_regcont_cmd = (struct cdm_regcontinuous_cmd *)buf_now;
buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_CONT];
for (i = 0; i < p_regcont_cmd->count; i++) {
if (buf_now > buf_end)
return true;
buf_now++;
}
break;
case CAM_CDM_CMD_REG_RANDOM:
p_regrand_cmd = (struct cdm_regrandom_cmd *)buf_now;
buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_RANDOM];
for (i = 0; i < p_regrand_cmd->count; i++) {
if (buf_now > buf_end)
return true;
buf_now += 2;
}
break;
case CAM_CDM_CMD_BUFF_INDIRECT:
buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT];
if (buf_now > buf_end)
return true;
break;
case CAM_CDM_CMD_GEN_IRQ:
buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_GEN_IRQ];
break;
case CAM_CDM_CMD_WAIT_EVENT:
buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_WAIT_EVENT];
break;
case CAM_CDM_CMD_CHANGE_BASE:
if (buf_now > buf_end)
return true;
buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE];
break;
case CAM_CDM_CMD_PERF_CTRL:
buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_PERF_CTRL];
break;
case CAM_CDM_CMD_COMP_WAIT:
buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_COMP_WAIT];
break;
default:
CAM_ERR(CAM_CDM, "Invalid CMD: 0x%x buf 0x%x",
cmd, *buf_now);
return true;
}
} while (buf_now < cmd_buf_end);
return false;
}
void cam_cdm_util_dump_cmd_buf(
uint32_t *cmd_buf_start, uint32_t *cmd_buf_end)
{
@ -1039,7 +1151,7 @@ void cam_cdm_util_dump_cmd_buf(
buf_now++;
break;
}
} while (buf_now <= cmd_buf_end);
} while (buf_now < cmd_buf_end);
}
static uint32_t cam_cdm_util_dump_reg_cont_cmd_v2(
@ -1210,6 +1322,6 @@ int cam_cdm_util_dump_cmd_bufs_v2(
buf_now++;
break;
}
} while (buf_now <= dump_info->src_end);
} while (buf_now < dump_info->src_end);
return rc;
}

View File

@ -9,6 +9,7 @@
/* Max len for tag name for header while dumping cmd buffer*/
#define CAM_CDM_CMD_TAG_MAX_LEN 128
#define CAM_CDM_COMMAND_OFFSET 24
#include <linux/types.h>
@ -227,6 +228,20 @@ struct cam_cdm_cmd_dump_header {
uint32_t word_size;
};
/**
* cam_cdm_util_validate_cmd_buf()
*
* @brief: Util function to validate cdm command buffers
*
* @cmd_buffer_start: Pointer to start of cmd buffer
* @cmd_buffer_end: Pointer to end of cmd buffer
*
* return true if invalid cmd found, otherwise false
*
*/
bool cam_cdm_util_validate_cmd_buf(
uint32_t *cmd_buffer_start, uint32_t *cmd_buffer_end);
/**
* cam_cdm_util_log_cmd_bufs()
*

View File

@ -1,7 +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.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
@ -355,6 +355,31 @@ int cam_context_dump_pf_info(void *data, void *args)
return rc;
}
int cam_context_handle_message(struct cam_context *ctx,
uint32_t msg_type, void *data)
{
int rc = 0;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if ((ctx->state > CAM_CTX_AVAILABLE) &&
(ctx->state < CAM_CTX_STATE_MAX)) {
if (ctx->state_machine[ctx->state].msg_cb_ops) {
rc = ctx->state_machine[ctx->state].msg_cb_ops(
ctx, msg_type, data);
} else {
CAM_WARN(CAM_CORE,
"No message handler for ctx %d, state %d msg_type :%d",
ctx->dev_hdl, ctx->state, msg_type);
}
}
return rc;
}
int cam_context_handle_acquire_dev(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd)
{

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_CONTEXT_H_
@ -168,7 +168,9 @@ struct cam_ctx_crm_ops {
* context info
* @recovery_ops: Function to be invoked to try hardware recovery
* @mini_dump_ops: Function for mini dump
* @evt_inject_ops: Function for event injection
* @err_inject_ops: Function for error injection
* @msg_cb_ops: Function to be called on any message from
* other subdev notifications
*
*/
struct cam_ctx_ops {
@ -180,6 +182,7 @@ struct cam_ctx_ops {
cam_ctx_recovery_cb_func recovery_ops;
cam_ctx_mini_dump_cb_func mini_dump_ops;
cam_ctx_err_inject_cb_func evt_inject_ops;
cam_ctx_message_cb_func msg_cb_ops;
};
@ -273,6 +276,38 @@ struct cam_context {
struct timespec64 cdm_done_ts;
};
/**
* struct cam_context_stream_dump - camera context stream information
*
* @hw_mgr_ctx_id: Hw Mgr context id returned from hw mgr
* @dev_id: ID of device associated
* @dev_hdl: Device handle
* @link_hdl: Link handle
* @sessoin_hdl: Session handle
* @refcount: Context object refcount
* @last_flush_req: Last request to flush
* @state: Current state for top level state machine
*/
struct cam_context_stream_dump {
uint32_t hw_mgr_ctx_id;
uint32_t dev_id;
uint32_t dev_hdl;
uint32_t link_hdl;
uint32_t session_hdl;
uint32_t refcount;
uint32_t last_flush_req;
enum cam_context_state state;
};
/**
* struct cam_context_each_req_info - camera each request information
*
* @request_id: request id
*/
struct cam_context_each_req_info {
uint64_t request_id;
};
/**
* struct cam_context_dump_header - Function for context dump header
*
@ -416,6 +451,19 @@ int cam_context_mini_dump_from_hw(struct cam_context *ctx,
int cam_context_dump_pf_info(void *ctx,
void *pf_args);
/**
* cam_context_handle_message()
*
* @brief: Handle message callback command
*
* @ctx: Object pointer for cam_context
* @msg_type: message type sent from other subdev
* @data: data from other subdev
*
*/
int cam_context_handle_message(struct cam_context *ctx,
uint32_t msg_type, void *data);
/**
* cam_context_handle_acquire_dev()
*

View File

@ -1487,6 +1487,40 @@ end:
return rc;
}
static int cam_context_dump_data_validaion(void *src, void *dest,
uint32_t base_len, uint32_t actual_len, uint32_t bytes_required)
{
if (base_len + bytes_required >= actual_len) {
CAM_ERR(CAM_CTXT, "actual len %pK base len %pK",
actual_len, base_len);
return -ENOSPC;
}
memcpy(dest, src, bytes_required);
return 0;
}
static int cam_context_stream_dump_validation(struct cam_context *ctx,
uint64_t *addr, uint32_t local_len, uint32_t buf_len)
{
struct cam_context_stream_dump stream_dump;
stream_dump.hw_mgr_ctx_id = ctx->hw_mgr_ctx_id;
stream_dump.dev_id = ctx->dev_id;
stream_dump.dev_hdl = ctx->dev_hdl;
stream_dump.link_hdl = ctx->link_hdl;
stream_dump.session_hdl = ctx->session_hdl;
stream_dump.refcount = refcount_read(&(ctx->refcount.refcount));
stream_dump.last_flush_req = ctx->last_flush_req;
stream_dump.state = ctx->state;
if (cam_context_dump_data_validaion(&stream_dump, addr,
local_len, buf_len,
sizeof(struct cam_context_stream_dump))) {
CAM_WARN(CAM_CTXT, "failed to copy the stream info");
return -ENOSPC;
}
return 0;
}
static int cam_context_user_dump(struct cam_context *ctx,
struct cam_hw_dump_args *dump_args)
{
@ -1495,9 +1529,9 @@ static int cam_context_user_dump(struct cam_context *ctx,
struct cam_context_dump_header *hdr;
uint8_t *dst;
uint64_t *addr, *start;
uint32_t min_len;
size_t buf_len, remain_len;
uintptr_t cpu_addr;
uint32_t local_len;
if (!ctx || !dump_args) {
CAM_ERR(CAM_CORE, "Invalid parameters %pK %pK",
@ -1521,107 +1555,31 @@ static int cam_context_user_dump(struct cam_context *ctx,
return -ENOSPC;
}
spin_lock_bh(&ctx->lock);
if (!list_empty(&ctx->active_req_list)) {
req = list_first_entry(&ctx->active_req_list,
struct cam_ctx_request, list);
} else if (!list_empty(&ctx->wait_req_list)) {
req = list_first_entry(&ctx->wait_req_list,
struct cam_ctx_request, list);
} else if (!list_empty(&ctx->pending_req_list)) {
req = list_first_entry(&ctx->pending_req_list,
struct cam_ctx_request, list);
} else {
CAM_ERR(CAM_CTXT, "[%s][%d] no request to dump",
ctx->dev_name, ctx->ctx_id);
}
spin_unlock_bh(&ctx->lock);
/* Check for min len in case of available request to dump */
if (req != NULL) {
remain_len = buf_len - dump_args->offset;
min_len = sizeof(struct cam_context_dump_header) +
(CAM_CTXT_DUMP_NUM_WORDS + req->num_in_map_entries +
(req->num_out_map_entries * 2)) * sizeof(uint64_t);
if (remain_len < min_len) {
CAM_WARN(CAM_CTXT, "dump buffer exhaust remain %zu min %u",
remain_len, min_len);
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC;
}
}
/* Dump context info */
remain_len = buf_len - dump_args->offset;
if (remain_len < sizeof(struct cam_context_dump_header)) {
CAM_WARN(CAM_CTXT,
"No sufficient space in dump buffer for headers, remain buf size: %d, header size: %d",
remain_len, sizeof(struct cam_context_dump_header));
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC;
}
dst = (uint8_t *)cpu_addr + dump_args->offset;
hdr = (struct cam_context_dump_header *)dst;
local_len =
(dump_args->offset + sizeof(struct cam_context_dump_header));
scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
"%s_CTX_INFO:", ctx->dev_name);
hdr->word_size = sizeof(uint64_t);
addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
start = addr;
*addr++ = ctx->hw_mgr_ctx_id;
*addr++ = ctx->dev_id;
*addr++ = ctx->dev_hdl;
*addr++ = ctx->link_hdl;
*addr++ = ctx->session_hdl;
*addr++ = refcount_read(&(ctx->refcount.refcount));
*addr++ = ctx->last_flush_req;
*addr++ = ctx->state;
hdr->size = hdr->word_size * (addr - start);
dump_args->offset += hdr->size +
sizeof(struct cam_context_dump_header);
/* Dump pending request IDs */
dst = (uint8_t *)cpu_addr + dump_args->offset;
hdr = (struct cam_context_dump_header *)dst;
scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
"%s_OUT_FENCE_PENDING_REQUESTS:", ctx->dev_name);
hdr->word_size = sizeof(uint64_t);
addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
start = addr;
if (!list_empty(&ctx->pending_req_list)) {
list_for_each_entry_safe(req, req_temp, &ctx->pending_req_list, list) {
*addr++ = req->request_id;
}
if (cam_context_stream_dump_validation(ctx, addr, local_len, buf_len)) {
CAM_WARN(CAM_CTXT, "%s_CTX_INFO failed to copy the stream info ", ctx->dev_name);
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC;
}
hdr->size = hdr->word_size * (addr - start);
dump_args->offset += hdr->size +
sizeof(struct cam_context_dump_header);
/* Dump wait request IDs */
dst = (uint8_t *)cpu_addr + dump_args->offset;
hdr = (struct cam_context_dump_header *)dst;
scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
"%s_OUT_FENCE_APPLIED_REQUESTS:", ctx->dev_name);
hdr->word_size = sizeof(uint64_t);
addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
start = addr;
if (!list_empty(&ctx->wait_req_list)) {
list_for_each_entry_safe(req, req_temp, &ctx->wait_req_list, list) {
*addr++ = req->request_id;
}
}
hdr->size = hdr->word_size * (addr - start);
dump_args->offset += hdr->size +
sizeof(struct cam_context_dump_header);
/* Dump active request IDs */
dst = (uint8_t *)cpu_addr + dump_args->offset;
hdr = (struct cam_context_dump_header *)dst;
scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
"%s_OUT_FENCE_ACTIVE_REQUESTS:", ctx->dev_name);
hdr->word_size = sizeof(uint64_t);
addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
start = addr;
if (!list_empty(&ctx->active_req_list)) {
list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) {
*addr++ = req->request_id;
}
}
addr = addr + sizeof(struct cam_context_stream_dump);
hdr->size = hdr->word_size * (addr - start);
dump_args->offset += hdr->size +
sizeof(struct cam_context_dump_header);
@ -1630,8 +1588,19 @@ static int cam_context_user_dump(struct cam_context *ctx,
if (!list_empty(&ctx->wait_req_list)) {
list_for_each_entry_safe(req, req_temp, &ctx->wait_req_list, list) {
for (i = 0; i < req->num_out_map_entries; i++) {
remain_len = buf_len - dump_args->offset;
if (remain_len < sizeof(struct cam_context_dump_header)) {
CAM_WARN(CAM_CTXT,
"No sufficient space in dump buffer for headers, remain buf size: %d, header size: %d",
remain_len, sizeof(struct cam_context_dump_header));
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC;
}
dst = (uint8_t *)cpu_addr + dump_args->offset;
hdr = (struct cam_context_dump_header *)dst;
local_len = dump_args->offset +
sizeof(struct cam_context_dump_header);
scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
"%s_OUT_FENCE_REQUEST_APPLIED.%d.%d.%d:",
ctx->dev_name,
@ -1641,7 +1610,14 @@ static int cam_context_user_dump(struct cam_context *ctx,
hdr->word_size = sizeof(uint64_t);
addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
start = addr;
*addr++ = req->request_id;
if (cam_context_dump_data_validaion(&req->request_id, addr,
local_len, buf_len,
sizeof(struct cam_context_each_req_info))) {
CAM_WARN(CAM_CTXT, "%s_CTX_INFO waiting_req: failed to copy the request info",
ctx->dev_name);
goto cleanup;
}
addr = addr + sizeof(struct cam_context_each_req_info);
hdr->size = hdr->word_size * (addr - start);
dump_args->offset += hdr->size +
sizeof(struct cam_context_dump_header);
@ -1653,8 +1629,19 @@ static int cam_context_user_dump(struct cam_context *ctx,
if (!list_empty(&ctx->pending_req_list)) {
list_for_each_entry_safe(req, req_temp, &ctx->pending_req_list, list) {
for (i = 0; i < req->num_out_map_entries; i++) {
remain_len = buf_len - dump_args->offset;
if (remain_len < sizeof(struct cam_context_dump_header)) {
CAM_WARN(CAM_CTXT,
"No sufficient space in dump buffer for headers, remain buf size: %d, header size: %d",
remain_len, sizeof(struct cam_context_dump_header));
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC;
}
dst = (uint8_t *)cpu_addr + dump_args->offset;
hdr = (struct cam_context_dump_header *)dst;
local_len = dump_args->offset +
sizeof(struct cam_context_dump_header);
scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
"%s_OUT_FENCE_REQUEST_PENDING.%d.%d.%d:",
ctx->dev_name,
@ -1664,7 +1651,14 @@ static int cam_context_user_dump(struct cam_context *ctx,
hdr->word_size = sizeof(uint64_t);
addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
start = addr;
*addr++ = req->request_id;
if (cam_context_dump_data_validaion(&req->request_id, addr,
local_len, buf_len,
sizeof(struct cam_context_each_req_info))) {
CAM_WARN(CAM_CTXT, "%s_CTX_INFO pending_req: failed to copy the request info",
ctx->dev_name);
goto cleanup;
}
addr = addr + sizeof(struct cam_context_each_req_info);
hdr->size = hdr->word_size * (addr - start);
dump_args->offset += hdr->size +
sizeof(struct cam_context_dump_header);
@ -1676,8 +1670,19 @@ static int cam_context_user_dump(struct cam_context *ctx,
if (!list_empty(&ctx->active_req_list)) {
list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) {
for (i = 0; i < req->num_out_map_entries; i++) {
remain_len = buf_len - dump_args->offset;
if (remain_len < sizeof(struct cam_context_dump_header)) {
CAM_WARN(CAM_CTXT,
"No sufficient space in dump buffer for headers, remain buf size: %d, header size: %d",
remain_len, sizeof(struct cam_context_dump_header));
cam_mem_put_cpu_buf(dump_args->buf_handle);
return -ENOSPC;
}
dst = (uint8_t *)cpu_addr + dump_args->offset;
hdr = (struct cam_context_dump_header *)dst;
local_len = dump_args->offset +
sizeof(struct cam_context_dump_header);
scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
"%s_OUT_FENCE_REQUEST_ACTIVE.%d.%d.%d:",
ctx->dev_name,
@ -1687,14 +1692,21 @@ static int cam_context_user_dump(struct cam_context *ctx,
hdr->word_size = sizeof(uint64_t);
addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
start = addr;
*addr++ = req->request_id;
if (cam_context_dump_data_validaion(&req->request_id, addr,
local_len, buf_len,
sizeof(struct cam_context_each_req_info))) {
CAM_WARN(CAM_CTXT, "%s_CTX_INFO active_req: failed to copy the request info",
ctx->dev_name);
goto cleanup;
}
addr = addr + sizeof(struct cam_context_each_req_info);
hdr->size = hdr->word_size * (addr - start);
dump_args->offset += hdr->size +
sizeof(struct cam_context_dump_header);
}
}
}
cleanup:
cam_mem_put_cpu_buf(dump_args->buf_handle);
return 0;
}

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_HW_MGR_INTF_H_
@ -80,6 +80,10 @@ typedef int (*cam_ctx_mini_dump_cb_func)(void *context,
typedef int (*cam_ctx_err_inject_cb_func)(void *context,
void *args);
/* message callback function type */
typedef int (*cam_ctx_message_cb_func)(void *context,
uint32_t message_type, void *data);
/**
* struct cam_hw_update_entry - Entry for hardware config
*
@ -165,11 +169,13 @@ struct cam_hw_acquire_stream_caps {
* @hw_mgr_ctx_id HWMgr context id(returned)
* @op_flags: Used as bitwise params from hw_mgr to ctx
* See xxx_hw_mgr_intf.h for definitions
* @link_hdl: Link handle
* @acquired_hw_id: Acquired hardware mask
* @acquired_hw_path: Acquired path mask for an input
* if input splits into multiple paths,
* its updated per hardware
* @valid_acquired_hw: Valid num of acquired hardware
* @total_ports_acq Total ports acquired ipp+ppp+rdi
* @op_params: OP Params from hw_mgr to ctx
* @mini_dump_cb: Mini dump callback function
*
@ -185,11 +191,11 @@ struct cam_hw_acquire_args {
void *ctxt_to_hw_map;
uint32_t hw_mgr_ctx_id;
uint32_t op_flags;
uint32_t acquired_hw_id[CAM_MAX_ACQ_RES];
uint32_t acquired_hw_path[CAM_MAX_ACQ_RES][CAM_MAX_HW_SPLIT];
uint32_t valid_acquired_hw;
int32_t link_hdl;
uint32_t acquired_hw_id[CAM_MAX_ACQ_RES];
uint32_t acquired_hw_path[CAM_MAX_ACQ_RES][CAM_MAX_HW_SPLIT];
uint32_t valid_acquired_hw;
uint32_t total_ports_acq;
struct cam_hw_acquire_stream_caps op_params;
cam_ctx_mini_dump_cb_func mini_dump_cb;
};

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/device.h>
@ -514,7 +514,7 @@ bus_register_fail:
return rc;
}
static int cam_cpas_util_vote_default_ahb_axi(struct cam_hw_info *cpas_hw,
int cam_cpas_util_vote_default_ahb_axi(struct cam_hw_info *cpas_hw,
int enable)
{
int rc, i = 0;
@ -983,7 +983,8 @@ static int cam_cpas_apply_smart_qos(
struct cam_cpas_tree_node *niu_node;
struct cam_camnoc_info *camnoc_info;
uint8_t i;
int32_t reg_indx;
int32_t reg_indx, cam_qos_cnt = 0, ret = 0;
struct qcom_scm_camera_qos scm_buf[QCOM_SCM_CAMERA_MAX_QOS_CNT] = {0};
if (cpas_core->smart_qos_dump) {
CAM_INFO(CAM_PERF, "Printing SmartQos values before update");
@ -998,20 +999,44 @@ static int cam_cpas_apply_smart_qos(
niu_node = soc_private->smart_qos_info->rt_wr_niu_node[i];
if (niu_node->curr_priority_high != niu_node->applied_priority_high) {
cam_io_w_mb(niu_node->curr_priority_high,
soc_info->reg_map[reg_indx].mem_base +
niu_node->pri_lut_high_offset);
if (!soc_private->enable_secure_qos_update) {
cam_io_w_mb(niu_node->curr_priority_high,
soc_info->reg_map[reg_indx].mem_base +
niu_node->pri_lut_high_offset);
} else {
scm_buf[cam_qos_cnt].offset = niu_node->pri_lut_high_offset;
scm_buf[cam_qos_cnt].val = niu_node->curr_priority_high;
cam_qos_cnt++;
}
niu_node->applied_priority_high = niu_node->curr_priority_high;
}
if (niu_node->curr_priority_low != niu_node->applied_priority_low) {
cam_io_w_mb(niu_node->curr_priority_low,
soc_info->reg_map[reg_indx].mem_base +
niu_node->pri_lut_low_offset);
if (!soc_private->enable_secure_qos_update) {
cam_io_w_mb(niu_node->curr_priority_low,
soc_info->reg_map[reg_indx].mem_base +
niu_node->pri_lut_low_offset);
} else {
scm_buf[cam_qos_cnt].offset = niu_node->pri_lut_low_offset;
scm_buf[cam_qos_cnt].val = niu_node->curr_priority_low;
cam_qos_cnt++;
}
niu_node->applied_priority_low = niu_node->curr_priority_low;
}
if (soc_private->enable_secure_qos_update && cam_qos_cnt) {
CAM_DBG(CAM_PERF, "Updating secure camera smartOos count: %d", cam_qos_cnt);
ret = cam_update_camnoc_qos_settings(CAM_QOS_UPDATE_TYPE_SMART,
cam_qos_cnt, scm_buf);
if (ret) {
CAM_ERR(CAM_PERF, "Secure camera smartOos update failed:%d", ret);
return ret;
}
CAM_DBG(CAM_PERF, "Updated secure camera smartOos");
cam_qos_cnt = 0;
}
}
if (cpas_core->smart_qos_dump) {
@ -1055,9 +1080,6 @@ static int cam_cpas_util_set_camnoc_axi_drv_clk_rate(struct cam_hw_soc_info *soc
req_drv_low_camnoc_bw = 0, intermediate_drv_low_result = 0;
int64_t drv_high_clk_rate = 0, drv_low_clk_rate = 0;
int i, rc = 0;
void __iomem *cesta_base =
soc_info->reg_map[cpas_core->regbase_index[CAM_CPAS_REG_CESTA]].mem_base;
uint32_t cesta_vcd_curr_perfol_val;
if (!soc_private->enable_cam_clk_drv) {
CAM_ERR(CAM_CPAS, "Clk DRV not enabled, can't set clk rates through cesta APIs");
@ -1160,16 +1182,6 @@ static int cam_cpas_util_set_camnoc_axi_drv_clk_rate(struct cam_hw_soc_info *soc
hw_client_idx, rc);
return rc;
}
cesta_vcd_curr_perfol_val = cam_io_r_mb(cesta_base + 0x400c);
CAM_DBG(CAM_ISP, "Check camnoc VCD val after set I: 0x%x",
cesta_vcd_curr_perfol_val);
cesta_vcd_curr_perfol_val = cam_io_r_mb(cesta_base + 0x400c);
CAM_DBG(CAM_ISP, "Check camnoc VCD val after set II: 0x%x",
cesta_vcd_curr_perfol_val);
cesta_vcd_curr_perfol_val = cam_io_r_mb(cesta_base + 0x400c);
CAM_DBG(CAM_ISP, "Check camnoc VCD val after set III: 0x%x",
cesta_vcd_curr_perfol_val);
}
return rc;
@ -1183,9 +1195,6 @@ static int cam_cpas_util_set_camnoc_axi_hlos_clk_rate(struct cam_hw_soc_info *so
int64_t hlos_clk_rate = 0;
int i, rc = 0;
const struct camera_debug_settings *cam_debug = NULL;
void __iomem *cesta_base =
soc_info->reg_map[cpas_core->regbase_index[CAM_CPAS_REG_CESTA]].mem_base;
uint32_t cesta_vcd_curr_perfol_val;
for (i = 0; i < CAM_CPAS_MAX_TREE_NODES; i++) {
tree_node = soc_private->tree_node[i];
@ -1229,7 +1238,7 @@ static int cam_cpas_util_set_camnoc_axi_hlos_clk_rate(struct cam_hw_soc_info *so
do_div(intermediate_hlos_result, soc_private->camnoc_bus_width);
hlos_clk_rate = intermediate_hlos_result;
CAM_INFO(CAM_PERF, "Setting camnoc axi HLOS clk rate[BW Clk] : [%llu %lld]",
CAM_DBG(CAM_PERF, "Setting camnoc axi HLOS clk rate[BW Clk] : [%llu %lld]",
req_hlos_camnoc_bw, hlos_clk_rate);
/*
@ -1247,19 +1256,8 @@ static int cam_cpas_util_set_camnoc_axi_hlos_clk_rate(struct cam_hw_soc_info *so
req_hlos_camnoc_bw, hlos_clk_rate, rc);
cpas_core->applied_camnoc_axi_rate.sw_client = hlos_clk_rate;
cesta_vcd_curr_perfol_val = cam_io_r_mb(cesta_base + 0x400c);
CAM_DBG(CAM_ISP, "Check camnoc VCD val after set I: 0x%x",
cesta_vcd_curr_perfol_val);
cesta_vcd_curr_perfol_val = cam_io_r_mb(cesta_base + 0x400c);
CAM_DBG(CAM_ISP, "Check camnoc VCD val after set II: 0x%x",
cesta_vcd_curr_perfol_val);
cesta_vcd_curr_perfol_val = cam_io_r_mb(cesta_base + 0x400c);
CAM_DBG(CAM_ISP, "Check camnoc VCD val after set III: 0x%x",
cesta_vcd_curr_perfol_val);
}
return rc;
}
@ -3468,7 +3466,10 @@ static void *cam_cpas_user_dump_state_monitor_array_info(
*addr++ = monitor->applied_camnoc_clk.hw_client[2].low,
*addr++ = monitor->applied_ahb_level;
*addr++ = cpas_core->num_valid_camnoc;
*addr++ = soc_private->smart_qos_info->num_rt_wr_nius;
if (soc_private->enable_smart_qos)
*addr++ = soc_private->smart_qos_info->num_rt_wr_nius;
*addr++ = num_vcds;
*addr++ = cpas_core->num_axi_ports;
@ -3515,14 +3516,16 @@ static void *cam_cpas_user_dump_state_monitor_array_info(
}
}
for (i = 0; i < soc_private->smart_qos_info->num_rt_wr_nius; i++) {
niu_node = soc_private->smart_qos_info->rt_wr_niu_node[i];
dst = (uint8_t *)addr;
hdr = (struct cam_common_hw_dump_header *)dst;
scnprintf(hdr->tag, CAM_COMMON_HW_DUMP_TAG_MAX_LEN, "%s:", niu_node->node_name);
addr = (uint64_t *)(dst + sizeof(struct cam_common_hw_dump_header));
*addr++ = monitor->rt_wr_niu_pri_lut_high[i];
*addr++ = monitor->rt_wr_niu_pri_lut_low[i];
if (soc_private->enable_smart_qos) {
for (i = 0; i < soc_private->smart_qos_info->num_rt_wr_nius; i++) {
niu_node = soc_private->smart_qos_info->rt_wr_niu_node[i];
dst = (uint8_t *)addr;
hdr = (struct cam_common_hw_dump_header *)dst;
scnprintf(hdr->tag, CAM_COMMON_HW_DUMP_TAG_MAX_LEN, "%s:", niu_node->node_name);
addr = (uint64_t *)(dst + sizeof(struct cam_common_hw_dump_header));
*addr++ = monitor->rt_wr_niu_pri_lut_high[i];
*addr++ = monitor->rt_wr_niu_pri_lut_low[i];
}
}
vcd_reg_debug_info = &monitor->vcd_reg_debug_info;
@ -3613,9 +3616,11 @@ static int cam_cpas_dump_state_monitor_array_info(
min_len += sizeof(struct cam_common_hw_dump_header);
}
for (j = 0; j < soc_private->smart_qos_info->num_rt_wr_nius; j++)
min_len += sizeof(struct cam_common_hw_dump_header) +
CAM_CPAS_DUMP_NUM_WORDS_RT_WR_NIUS * sizeof(uint64_t);
if (soc_private->enable_smart_qos) {
for (j = 0; j < soc_private->smart_qos_info->num_rt_wr_nius; j++)
min_len += sizeof(struct cam_common_hw_dump_header) +
CAM_CPAS_DUMP_NUM_WORDS_RT_WR_NIUS * sizeof(uint64_t);
}
for (j = 0; j < CAM_CPAS_MAX_CESTA_VCD_NUM; j++)
min_len += CAM_CPAS_DUMP_NUM_WORDS_VCD_CURR_LVL * sizeof(uint64_t);
@ -3694,6 +3699,32 @@ done:
return rc;
}
static int cam_cpas_hw_enable_tpg_mux_sel(struct cam_hw_info *cpas_hw,
uint32_t tpg_mux)
{
struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
int rc = 0;
mutex_lock(&cpas_hw->hw_mutex);
if (cpas_core->internal_ops.set_tpg_mux_sel) {
rc = cpas_core->internal_ops.set_tpg_mux_sel(
cpas_hw, tpg_mux);
if (rc) {
CAM_ERR(CAM_CPAS,
"failed in tpg mux selection rc=%d",
rc);
}
} else {
CAM_ERR(CAM_CPAS,
"CPAS tpg mux sel not enabled");
rc = -EINVAL;
}
mutex_unlock(&cpas_hw->hw_mutex);
return rc;
}
static int cam_cpas_activate_cache(
struct cam_hw_info *cpas_hw,
struct cam_sys_cache_info *cache_info)
@ -4011,10 +4042,6 @@ static int cam_cpas_hw_csid_input_core_info_update(struct cam_hw_info *cpas_hw,
rc = cam_common_util_get_string_index(soc_private->client_name,
soc_private->num_clients, client_name, &client_indx);
if (rc || (client_indx < 0)) {
CAM_ERR(CAM_CPAS, "Failed in getting correct client index");
return -EINVAL;
}
if (!cpas_core->cpas_client[client_indx]->is_drv_dyn)
return 0;
@ -4367,6 +4394,20 @@ static int cam_cpas_hw_process_cmd(void *hw_priv,
rc = cam_cpas_hw_csid_process_resume(hw_priv, *csid_idx);
break;
}
case CAM_CPAS_HW_CMD_TPG_MUX_SEL: {
uint32_t *tpg_mux_sel;
if (sizeof(uint32_t) != arg_size) {
CAM_ERR(CAM_CPAS, "cmd_type %d, size mismatch %d",
cmd_type, arg_size);
break;
}
tpg_mux_sel = (uint32_t *)cmd_args;
rc = cam_cpas_hw_enable_tpg_mux_sel(hw_priv, *tpg_mux_sel);
break;
}
case CAM_CPAS_HW_CMD_ENABLE_DISABLE_DOMAIN_ID_CLK: {
bool *enable;
@ -4670,7 +4711,7 @@ int cam_cpas_hw_probe(struct platform_device *pdev,
cpas_hw_intf->hw_ops.process_cmd = cam_cpas_hw_process_cmd;
cpas_core->work_queue = alloc_workqueue(CAM_CPAS_WORKQUEUE_NAME,
WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_HIGHPRI, CAM_CPAS_INFLIGHT_WORKS);
WQ_UNBOUND | WQ_MEM_RECLAIM, CAM_CPAS_INFLIGHT_WORKS);
if (!cpas_core->work_queue) {
rc = -ENOMEM;
goto release_mem;

View File

@ -170,6 +170,7 @@ struct cam_cpas_kobj_map {
* @print_poweron_settings: Function pointer for hw to print poweron settings
* @qchannel_handshake: Function pointer for hw core specific qchannel
* handshake settings
* @set_tpg_mux_sel: Set tpg mux select on CPAS TOP register
*
*/
struct cam_cpas_internal_ops {
@ -186,6 +187,7 @@ struct cam_cpas_internal_ops {
uint32_t selection_mask);
int (*print_poweron_settings)(struct cam_hw_info *cpas_hw);
int (*qchannel_handshake)(struct cam_hw_info *cpas_hw, bool power_on, bool force_on);
int (*set_tpg_mux_sel)(struct cam_hw_info *cpas_hw, uint32_t tpg_num);
};
/**
@ -458,4 +460,7 @@ int cam_cpas_util_reg_read(struct cam_hw_info *cpas_hw,
int cam_cpas_util_client_cleanup(struct cam_hw_info *cpas_hw);
int cam_cpas_util_vote_default_ahb_axi(struct cam_hw_info *cpas_hw,
int enable);
#endif /* _CAM_CPAS_HW_H_ */

View File

@ -72,6 +72,7 @@ enum cam_cpas_hw_cmd_process {
CAM_CPAS_HW_CMD_CSID_INPUT_CORE_INFO_UPDATE,
CAM_CPAS_HW_CMD_CSID_PROCESS_RESUME,
CAM_CPAS_HW_CMD_ENABLE_DISABLE_DOMAIN_ID_CLK,
CAM_CPAS_HW_CMD_TPG_MUX_SEL,
CAM_CPAS_HW_CMD_DUMP_STATE_MONITOR_INFO,
CAM_CPAS_HW_CMD_INVALID,
};
@ -201,4 +202,10 @@ int cam_cpas_dev_init_module(void);
* @brief : API to remove CPAS interface from platform framework.
*/
void cam_cpas_dev_exit_module(void);
/**
* @brief : API to select TPG mux select.
*/
int cam_cpas_enable_tpg_mux_sel(uint32_t tpg_mux_sel);
#endif /* _CAM_CPAS_HW_INTF_H_ */

View File

@ -22,10 +22,18 @@
#include "cam_cpas_soc.h"
#include "cam_cpastop_hw.h"
#include "camera_main.h"
#include "cam_cpas_hw.h"
#include <linux/soc/qcom/llcc-qcom.h>
#include "cam_req_mgr_interface.h"
#ifdef CONFIG_DYNAMIC_FD_PORT_CONFIG
#include <linux/IClientEnv.h>
#include <linux/ITrustedCameraDriver.h>
#include <linux/CTrustedCameraDriver.h>
#define CAM_CPAS_ERROR_NOT_ALLOWED 10
#endif
#define CAM_CPAS_DEV_NAME "cam-cpas"
#define CAM_CPAS_INTF_INITIALIZED() (g_cpas_intf && g_cpas_intf->probe_done)
@ -767,6 +775,31 @@ int cam_cpas_select_qos_settings(uint32_t selection_mask)
}
EXPORT_SYMBOL(cam_cpas_select_qos_settings);
int cam_cpas_enable_tpg_mux_sel(uint32_t tpg_mux_sel)
{
int rc = 0;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -EBADR;
}
if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
g_cpas_intf->hw_intf->hw_priv,
CAM_CPAS_HW_CMD_TPG_MUX_SEL, &tpg_mux_sel,
sizeof(tpg_mux_sel));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
} else {
CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
rc = -EBADR;
}
return rc;
}
EXPORT_SYMBOL(cam_cpas_enable_tpg_mux_sel);
int cam_cpas_notify_event(const char *identifier_string,
int32_t identifier_value)
{
@ -1116,6 +1149,154 @@ int cam_cpas_dump_state_monitor_info(struct cam_req_mgr_dump_info *info)
}
EXPORT_SYMBOL(cam_cpas_dump_state_monitor_info);
#ifdef CONFIG_DYNAMIC_FD_PORT_CONFIG
static int cam_cpas_handle_fd_port_config(uint32_t is_secure)
{
int rc = 0;
struct Object client_env, sc_object;
struct cam_hw_info *cpas_hw = NULL;
struct cam_cpas *cpas_core;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -EINVAL;
}
cpas_hw = (struct cam_hw_info *) g_cpas_intf->hw_intf->hw_priv;
if (cpas_hw) {
cpas_core = (struct cam_cpas *) cpas_hw->core_info;
mutex_lock(&cpas_hw->hw_mutex);
if (cpas_core->streamon_clients > 0) {
CAM_ERR(CAM_CPAS,
"FD port config can not be updated during the session");
mutex_unlock(&cpas_hw->hw_mutex);
return -EINVAL;
}
} else {
CAM_ERR(CAM_CPAS, "cpas_hw handle not initialized");
return -EINVAL;
}
/* Need to vote first before enabling clocks */
rc = cam_cpas_util_vote_default_ahb_axi(cpas_hw, true);
if (rc) {
CAM_ERR(CAM_CPAS,
"failed to vote for the default ahb/axi clock, rc=%d", rc);
goto release_mutex;
}
rc = cam_cpas_soc_enable_resources(&cpas_hw->soc_info,
cpas_hw->soc_info.lowest_clk_level);
if (rc) {
CAM_ERR(CAM_CPAS, "failed in soc_enable_resources, rc=%d", rc);
goto remove_default_vote;
}
rc = get_client_env_object(&client_env);
if (rc) {
CAM_ERR(CAM_CPAS, "Failed getting mink env object, rc: %d", rc);
goto disable_resources;
}
rc = IClientEnv_open(client_env, CTrustedCameraDriver_UID, &sc_object);
if (rc) {
CAM_ERR(CAM_CPAS, "Failed getting mink sc_object, rc: %d", rc);
goto client_release;
}
rc = ITrustedCameraDriver_dynamicConfigureFDPort(sc_object, is_secure);
if (rc) {
if (rc == CAM_CPAS_ERROR_NOT_ALLOWED) {
CAM_ERR(CAM_CPAS, "Dynamic FD port config not allowed");
rc = -EPERM;
} else {
CAM_ERR(CAM_CPAS, "Mink secure call failed, rc: %d", rc);
rc = -EINVAL;
}
goto obj_release;
}
rc = Object_release(sc_object);
if (rc) {
CAM_ERR(CAM_CSIPHY, "Failed releasing secure camera object, rc: %d", rc);
goto client_release;
}
rc = Object_release(client_env);
if (rc) {
CAM_ERR(CAM_CSIPHY, "Failed releasing mink env object, rc: %d", rc);
goto disable_resources;
}
rc = cam_cpas_soc_disable_resources(&cpas_hw->soc_info, true, true);
if (rc) {
CAM_ERR(CAM_CPAS, "failed in soc_disable_resources, rc=%d", rc);
goto remove_default_vote;
}
rc = cam_cpas_util_vote_default_ahb_axi(cpas_hw, false);
if (rc)
CAM_ERR(CAM_CPAS,
"failed remove the vote on ahb/axi clock, rc=%d", rc);
mutex_unlock(&cpas_hw->hw_mutex);
return rc;
obj_release:
Object_release(sc_object);
client_release:
Object_release(client_env);
disable_resources:
cam_cpas_soc_disable_resources(&cpas_hw->soc_info, true, true);
remove_default_vote:
cam_cpas_util_vote_default_ahb_axi(cpas_hw, false);
release_mutex:
mutex_unlock(&cpas_hw->hw_mutex);
return rc;
}
#endif
static int cam_cpas_handle_custom_config_cmd(struct cam_cpas_intf *cpas_intf,
struct cam_custom_cmd *cmd)
{
int32_t rc = 0;
if (!cmd) {
CAM_ERR(CAM_CPAS, "Invalid input cmd");
return -EINVAL;
}
switch (cmd->cmd_type) {
#ifdef CONFIG_DYNAMIC_FD_PORT_CONFIG
case CAM_CPAS_CUSTOM_CMD_FD_PORT_CFG: {
struct cam_cpas_fd_port_config cfg;
if (cmd->size < sizeof(cfg))
return -EINVAL;
rc = copy_from_user(&cfg, u64_to_user_ptr(cmd->handle),
sizeof(cfg));
if (rc) {
CAM_ERR(CAM_CPAS, "Failed in copy from user, rc=%d",
rc);
rc = -EINVAL;
break;
}
rc = cam_cpas_handle_fd_port_config(cfg.is_secure);
break;
}
#endif
default:
CAM_ERR(CAM_CPAS, "Invalid custom command %d for CPAS", cmd->cmd_type);
rc = -EINVAL;
break;
}
return rc;
}
int cam_cpas_subdev_cmd(struct cam_cpas_intf *cpas_intf,
struct cam_control *cmd)
{
@ -1208,6 +1389,19 @@ int cam_cpas_subdev_cmd(struct cam_cpas_intf *cpas_intf,
break;
}
case CAM_CUSTOM_DEV_CONFIG: {
struct cam_custom_cmd custom_cmd;
rc = copy_from_user(&custom_cmd, u64_to_user_ptr(cmd->handle),
sizeof(custom_cmd));
if (rc) {
CAM_ERR(CAM_CPAS, "Failed in copy from user, rc=%d",
rc);
break;
}
rc = cam_cpas_handle_custom_config_cmd(cpas_intf, &custom_cmd);
break;
}
case CAM_SD_SHUTDOWN:
break;
default:

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/device.h>
@ -1455,6 +1455,9 @@ int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
soc_private->num_vdd_ahb_mapping = count;
}
soc_private->enable_secure_qos_update = of_property_read_bool(of_node,
"enable-secure-qos-update");
soc_private->enable_smart_qos = of_property_read_bool(of_node,
"enable-smart-qos");

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_CPAS_SOC_H_
@ -268,6 +268,7 @@ struct cam_cpas_sysfs_info {
* @num_caches: Number of last level caches
* @part_info: Camera Hw subpart info
* @llcc_info: Cache info
* @enable_secure_qos_update: whether to program QoS securely on current chipset
* @enable_smart_qos: Whether to enable Smart QoS mechanism on current chipset
* @enable_cam_ddr_drv: Whether to enable Camera DDR DRV on current chipset
* @enable_cam_clk_drv: Whether to enable Camera Clk DRV on current chipset
@ -303,6 +304,7 @@ struct cam_cpas_private_soc {
bool enable_smart_qos;
bool enable_cam_ddr_drv;
bool enable_cam_clk_drv;
bool enable_secure_qos_update;
struct cam_cpas_smart_qos_info *smart_qos_info;
int32_t icp_clk_index;
struct cam_cpas_domain_id_info domain_id_info;

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "cam_cpas_hw_intf.h"
@ -80,6 +81,7 @@ int cam_camsstop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops)
internal_ops->setup_qos_settings = NULL;
internal_ops->print_poweron_settings = NULL;
internal_ops->qchannel_handshake = NULL;
internal_ops->set_tpg_mux_sel = NULL;
return 0;
}

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/delay.h>
@ -36,13 +36,19 @@
#include "cpastop_v165_100.h"
#include "cpastop_v780_100.h"
#include "cpastop_v640_200.h"
#include "cpastop_v640_210.h"
#include "cpastop_v880_100.h"
#include "cpastop_v980_100.h"
#include "cpastop_v860_100.h"
#include "cpastop_v770_100.h"
#include "cpastop_v665_100.h"
#include "cam_req_mgr_workq.h"
#include "cam_common_util.h"
struct cam_camnoc_info *camnoc_info[CAM_CAMNOC_HW_TYPE_MAX];
struct cam_cpas_info *cpas_info;
struct cam_cpas_camnoc_qchannel *qchannel_info;
struct cam_cpas_top_regs *cpas_top_info;
#if (defined(CONFIG_CAM_TEST_IRQ_LINE) && defined(CONFIG_CAM_TEST_IRQ_LINE_AT_PROBE))
struct completion test_irq_hw_complete[CAM_CAMNOC_HW_TYPE_MAX];
@ -70,6 +76,7 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
0,
0,
},
/* for camera_170 */
{
@ -79,6 +86,7 @@ static const uint32_t cam_cpas_hw_version_map
CAM_CPAS_TITAN_170_V120,
0,
CAM_CPAS_TITAN_170_V200,
0,
},
/* for camera_175 */
{
@ -88,6 +96,7 @@ static const uint32_t cam_cpas_hw_version_map
CAM_CPAS_TITAN_175_V120,
CAM_CPAS_TITAN_175_V130,
0,
0,
},
/* for camera_480 */
{
@ -97,6 +106,7 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
0,
0,
},
/* for camera_580 */
{
@ -106,6 +116,7 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
0,
0,
},
/* for camera_520 */
{
@ -115,6 +126,7 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
0,
0,
},
/* for camera_540 */
@ -125,6 +137,7 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
0,
0,
},
/* for camera_545 */
{
@ -134,6 +147,7 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
0,
0,
},
/* for camera_570 */
{
@ -143,6 +157,7 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
CAM_CPAS_TITAN_570_V200,
0,
},
/* for camera_680 */
{
@ -152,6 +167,7 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
0,
0,
},
/* for camera_165 */
{
@ -161,6 +177,7 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
0,
0,
},
/* for camera_780 */
{
@ -170,6 +187,7 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
0,
0,
},
/* for camera_640 */
{
@ -179,6 +197,7 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
CAM_CPAS_TITAN_640_V200,
CAM_CPAS_TITAN_640_V210,
},
/* for camera_880 */
{
@ -188,6 +207,7 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
0,
0,
},
/* for camera_980 */
{
@ -197,6 +217,37 @@ static const uint32_t cam_cpas_hw_version_map
0,
0,
0,
0,
},
/* for camera_860 */
{
CAM_CPAS_TITAN_860_V100,
0,
0,
0,
0,
0,
0,
},
/* for camera_770 */
{
CAM_CPAS_TITAN_770_V100,
0,
0,
0,
0,
0,
0,
},
/* for camera_665 */
{
CAM_CPAS_TITAN_665_V100,
0,
0,
0,
0,
0,
0,
},
};
@ -279,6 +330,15 @@ static int cam_cpas_translate_camera_cpas_version_id(
case CAM_CPAS_CAMERA_VERSION_980:
*cam_version_id = CAM_CPAS_CAMERA_VERSION_ID_980;
break;
case CAM_CPAS_CAMERA_VERSION_860:
*cam_version_id = CAM_CPAS_CAMERA_VERSION_ID_860;
break;
case CAM_CPAS_CAMERA_VERSION_770:
*cam_version_id = CAM_CPAS_CAMERA_VERSION_ID_770;
break;
case CAM_CPAS_CAMERA_VERSION_665:
*cam_version_id = CAM_CPAS_CAMERA_VERSION_ID_665;
break;
default:
CAM_ERR(CAM_CPAS, "Invalid cam version %u",
cam_version);
@ -310,6 +370,10 @@ static int cam_cpas_translate_camera_cpas_version_id(
*cpas_version_id = CAM_CPAS_VERSION_ID_200;
break;
case CAM_CPAS_VERSION_210:
*cpas_version_id = CAM_CPAS_VERSION_ID_210;
break;
default:
CAM_ERR(CAM_CPAS, "Invalid cpas version %u",
cpas_version);
@ -976,59 +1040,72 @@ static int cam_cpastop_print_poweron_settings(struct cam_hw_info *cpas_hw)
static int cam_cpastop_poweron(struct cam_hw_info *cpas_hw)
{
int i, j;
int i, j, rc = 0;
struct cam_cpas_hw_errata_wa_list *errata_wa_list;
struct cam_cpas_hw_errata_wa *errata_wa;
struct cam_cpas *cpas_core = cpas_hw->core_info;
struct cam_cpas_private_soc *soc_private =
(struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;
bool errata_enabled = false;
for (i = 0; i < cpas_core->num_valid_camnoc; i++)
cam_cpastop_reset_irq(0x0, cpas_hw, i);
for (i = 0; i < cpas_core->num_valid_camnoc; i++) {
CAM_DBG(CAM_CPAS, "QOS settings for %s :",
camnoc_info[i]->camnoc_name);
for (j = 0; j < camnoc_info[i]->specific_size; j++) {
if (camnoc_info[i]->specific[j].enable) {
CAM_DBG(CAM_CPAS,
"Updating QoS settings port: %d prot name: %s",
camnoc_info[i]->specific[j].port_type,
camnoc_info[i]->specific[j].port_name);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].priority_lut_low);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].priority_lut_high);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].urgency);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].danger_lut);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].safe_lut);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].ubwc_ctl);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].flag_out_set0_low);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].dynattr_mainctl);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].qosgen_mainctl);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].qosgen_shaping_low);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].qosgen_shaping_high);
}
}
if (!soc_private->enable_secure_qos_update) {
for (i = 0; i < cpas_core->num_valid_camnoc; i++) {
CAM_DBG(CAM_CPAS, "QOS settings for %s :",
camnoc_info[i]->camnoc_name);
for (j = 0; j < camnoc_info[i]->specific_size; j++) {
if (camnoc_info[i]->specific[j].enable) {
CAM_DBG(CAM_CPAS,
"Updating QoS settings port: %d prot name: %s",
camnoc_info[i]->specific[j].port_type,
camnoc_info[i]->specific[j].port_name);
if (!errata_enabled) {
errata_wa_list = camnoc_info[i]->errata_wa_list;
if (errata_wa_list) {
errata_wa = &errata_wa_list->tcsr_camera_hf_sf_ares_glitch;
if (errata_wa->enable) {
cam_cpastop_scm_write(errata_wa);
errata_enabled = true;
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].priority_lut_low);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].priority_lut_high);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].urgency);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].danger_lut);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].safe_lut);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].ubwc_ctl);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].flag_out_set0_low);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].dynattr_mainctl);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].qosgen_mainctl);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].qosgen_shaping_low);
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
&camnoc_info[i]->specific[j].qosgen_shaping_high);
}
}
if (!errata_enabled) {
errata_wa_list = camnoc_info[i]->errata_wa_list;
if (errata_wa_list) {
errata_wa = &errata_wa_list->tcsr_camera_hf_sf_ares_glitch;
if (errata_wa->enable) {
cam_cpastop_scm_write(errata_wa);
errata_enabled = true;
}
}
}
}
} else {
CAM_DBG(CAM_CPAS, "Updating secure camera static QoS settings");
rc = cam_update_camnoc_qos_settings(CAM_QOS_UPDATE_TYPE_STATIC, 0, NULL);
if (rc) {
CAM_ERR(CAM_CPAS, "Secure camera static OoS update failed: %d", rc);
return rc;
}
CAM_DBG(CAM_CPAS, "Updated secure camera static QoS settings");
}
return 0;
@ -1277,6 +1354,33 @@ static int cam_cpastop_get_hw_capability(struct cam_hw_info *cpas_hw)
return 0;
}
static int cam_cpastop_set_tpg_mux_sel(struct cam_hw_info *cpas_hw,
uint32_t tpg_mux)
{
struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info;
int reg_cpas_top;
uint32_t curr_tpg_mux = 0;
reg_cpas_top = cpas_core->regbase_index[CAM_CPAS_REG_CPASTOP];
if (cpas_top_info == NULL)
return 0;
if (!cpas_top_info->tpg_mux_sel_enabled)
return 0;
curr_tpg_mux = cam_io_r_mb(soc_info->reg_map[reg_cpas_top].mem_base +
cpas_top_info->tpg_mux_sel);
curr_tpg_mux = curr_tpg_mux | ((1 << tpg_mux) << cpas_top_info->tpg_mux_sel_shift);
cam_io_w_mb(curr_tpg_mux, soc_info->reg_map[reg_cpas_top].mem_base +
cpas_top_info->tpg_mux_sel);
CAM_DBG(CAM_CPAS, "SET TPG MUX to 0x%x", curr_tpg_mux);
return 0;
}
static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
struct cam_cpas_hw_caps *hw_caps)
{
@ -1286,6 +1390,9 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
struct cam_cpas_cesta_info *cesta_info = NULL;
struct cam_camnoc_info *alloc_camnoc_info[CAM_CAMNOC_HW_TYPE_MAX] = {0};
qchannel_info = NULL;
cpas_top_info = NULL;
CAM_DBG(CAM_CPAS,
"hw_version=0x%x Camera Version %d.%d.%d, cpas version %d.%d.%d",
soc_info->hw_version,
@ -1376,6 +1483,12 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
case CAM_CPAS_TITAN_640_V200:
alloc_camnoc_info[CAM_CAMNOC_HW_COMBINED] = &cam640_cpas200_camnoc_info;
cpas_info = &cam640_cpas200_cpas_info;
cpas_top_info = &cam640_cpas200_cpas_top_info;
break;
case CAM_CPAS_TITAN_640_V210:
alloc_camnoc_info[CAM_CAMNOC_HW_COMBINED] = &cam640_cpas210_camnoc_info;
cpas_info = &cam640_cpas210_cpas_info;
cpas_top_info = &cam640_cpas210_cpas_top_info;
break;
case CAM_CPAS_TITAN_880_V100:
alloc_camnoc_info[CAM_CAMNOC_HW_COMBINED] = &cam880_cpas100_camnoc_info;
@ -1388,6 +1501,21 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
cpas_info = &cam980_cpas100_cpas_info;
cesta_info = &cam_v980_cesta_info;
break;
case CAM_CPAS_TITAN_860_V100:
alloc_camnoc_info[CAM_CAMNOC_HW_COMBINED] = &cam860_cpas100_camnoc_info;
cpas_info = &cam860_cpas100_cpas_info;
cesta_info = &cam_v860_cesta_info;
break;
case CAM_CPAS_TITAN_770_V100:
alloc_camnoc_info[CAM_CAMNOC_HW_COMBINED] = &cam770_cpas100_camnoc_info;
cpas_info = &cam770_cpas100_cpas_info;
cpas_top_info = &cam770_cpas100_cpas_top_info;
break;
case CAM_CPAS_TITAN_665_V100:
alloc_camnoc_info[CAM_CAMNOC_HW_COMBINED] = &cam665_cpas100_camnoc_info;
cpas_info = &cam665_cpas100_cpas_info;
cpas_top_info = &cam665_cpas100_cpas_top_info;
break;
default:
CAM_ERR(CAM_CPAS, "Camera Version not supported %d.%d.%d",
hw_caps->camera_version.major,
@ -1471,6 +1599,7 @@ int cam_cpastop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops)
internal_ops->print_poweron_settings =
cam_cpastop_print_poweron_settings;
internal_ops->qchannel_handshake = cam_cpastop_qchannel_handshake;
internal_ops->set_tpg_mux_sel = cam_cpastop_set_tpg_mux_sel;
return 0;
}

View File

@ -534,4 +534,17 @@ struct cam_cpas_info {
uint8_t num_qchannel;
};
/**
* struct cam_cpas_top_regs : CPAS Top registers
* @tpg_mux_sel_shift: TPG mux select shift value
* @tpg_mux_sel: For selecting TPG
* @tpg_mux_sel_enabled: TPG mux select enabled or not
*
*/
struct cam_cpas_top_regs {
uint32_t tpg_mux_sel_shift;
uint32_t tpg_mux_sel;
bool tpg_mux_sel_enabled;
};
#endif /* _CAM_CPASTOP_HW_H_ */

View File

@ -547,6 +547,9 @@ static struct cam_camnoc_err_logger_info cam640_cpas200_err_logger_offsets = {
};
static struct cam_cpas_hw_errata_wa_list cam640_cpas200_errata_wa_list = {
.enable_icp_clk_for_qchannel = {
.enable = true,
},
};
static struct cam_camnoc_info cam640_cpas200_camnoc_info = {
@ -573,5 +576,11 @@ static struct cam_cpas_info cam640_cpas200_cpas_info = {
.num_qchannel = 1,
};
static struct cam_cpas_top_regs cam640_cpas200_cpas_top_info = {
.tpg_mux_sel_enabled = true,
.tpg_mux_sel_shift = 0x0,
.tpg_mux_sel = 0x1C,
};
#endif /* _CPASTOP_V640_200_H_ */

View File

@ -0,0 +1,583 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CPASTOP_V640_210_H_
#define _CPASTOP_V640_210_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v640_210_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x6840, /* CAM_NOC_SBM_FAULTINEN0_LOW */
.value = 0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x04 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x08 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
(TEST_IRQ_ENABLE ?
0x80 : /* SBM_FAULTINEN0_LOW_PORT7_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x6848, /* CAM_NOC_SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x6880, /* CAM_NOC_SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x5 : 0x1,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v640_210_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = false,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x6608, /* CAM_NOC_ERL_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x6610, /* CAM_NOC_ERL_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x6618, /* CAM_NOC_ERL_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT1_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x5DA0, /* WR_NIU_ENCERREN_LOW */
.value = 0XF,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x5D90, /* WR_NIU_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x5D98, /* WR_NIU_ENCERRCLR_LOW */
.value = 0X1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE0_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x5F20, /* CAM_NOC_IPE_0_RD_NIU_DECERREN_LOW */
.value = 0xFF,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x5F10, /* CAM_NOC_IPE_0_RD_NIU_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x5F18, /* CAM_NOC_IPE_0_RD_NIU_DECERRCLR_LOW */
.value = 0X1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = false,
.sbm_port = 0x40, /* SBM_FAULTINSTATUS0_LOW_PORT6_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x6888, /* CAM_NOC_SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x6890, /* CAM_NOC_SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false, /* CAM_NOC_SBM_FLAGOUTCLR0_LOW */
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
};
static struct cam_camnoc_specific
cam_cpas_v640_210_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_TFE_BAYER_STATS,
.port_name = "TFE_BAYER",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5830, /*PRIORITYLUT_LOW */
.value = 0x55554433,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5834, /* PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5838, /* URGENCY_LOW */
.value = 0x00001030,
},
.danger_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5840, /* DANGERLUT_LOW */
.value = 0xffffff00,
},
.safe_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5848, /* SAFELUT_LOW */
.value = 0x0000000f,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4208, /* QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4220, /* QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4224, /* QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
.maxwr_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ,
.masked_value = 0,
.offset = 0x5820, /* UBWC_MAXWR_LOW */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_TFE_RAW,
.port_name = "TFE_RDI_RAW",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5A30, /* PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5A34, /* PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5A38, /* URGENCY_LOW */
.value = 0x00001030,
},
.danger_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5A40, /* DANGERLUT_LOW */
.value = 0xffffff00,
},
.safe_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5A48, /* SAFELUT_LOW */
.value = 0x000f,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4408, /* QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4420, /* QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4424, /* QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
.maxwr_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ,
.masked_value = 0,
.offset = 0x5A20, /* STATS_MAXWR_LOW */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_OPE_BPS_WR,
.port_name = "OPE_BPS_WR",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5C30, /* PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5C34, /* PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5C38, /* URGENCY_LOW */
.value = 0x00000030,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5C40, /* DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5C48, /* SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4608, /* QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4620, /* QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4624, /* QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
.maxwr_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ,
.masked_value = 0,
.offset = 0x5C20, /* MAXWR_LOW */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_OPE_BPS_CDM_RD,
.port_name = "OPE_BPS_CDM_RD",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5E30, /* IPE_WR_PRIORITYLUT_LOW */
.value = 0x55554433,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5E34, /* IPE_WR_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5E38, /* IPE_WR_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5E40, /* IPE_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5E48, /* IPE_WR_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4808, /* IPE_WR_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4820, /* IPE_WR_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4824, /* IPE_WR_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_CRE,
.port_name = "CRE_RD_WR",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x6030, /* BPS_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x6034, /* BPS_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x6038, /* BPS_WR_URGENCY_LOW */
.value = 0x03,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x6040, /* BPS_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x6048, /* BPS_WR_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4A08, /* BPS_WR_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4A20, /* BPS_WR_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4A24, /* BPS_WR_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
.maxwr_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ,
.masked_value = 0,
.offset = 0x6020, /* BPS_WR_MAXWR_LOW */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_ICP,
.port_name = "ICP",
.enable = false,
.flag_out_set0_low = {
.enable = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x6888,
.value = 0x100000,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4008, /* ICP_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4020, /* ICP_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4024, /* ICP_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
};
static struct cam_camnoc_err_logger_info cam640_cpas210_err_logger_offsets = {
.mainctrl = 0x6608, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x6610, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x6620, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x6624, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x6628, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x662c, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x6630, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x6634, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x6638, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x663c, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam640_cpas210_errata_wa_list = {
};
static struct cam_camnoc_info cam640_cpas210_camnoc_info = {
.specific = &cam_cpas_v640_210_camnoc_specific[0],
.specific_size = ARRAY_SIZE(cam_cpas_v640_210_camnoc_specific),
.irq_sbm = &cam_cpas_v640_210_irq_sbm,
.irq_err = &cam_cpas_v640_210_irq_err[0],
.irq_err_size = ARRAY_SIZE(cam_cpas_v640_210_irq_err),
.err_logger = &cam640_cpas210_err_logger_offsets,
.errata_wa_list = &cam640_cpas210_errata_wa_list,
};
static struct cam_cpas_camnoc_qchannel cam640_cpas210_qchannel_info = {
.qchannel_ctrl = 0x14,
.qchannel_status = 0x18,
};
static struct cam_cpas_info cam640_cpas210_cpas_info = {
.hw_caps_info = {
.num_caps_registers = 1,
.hw_caps_offsets = {0x8},
},
.qchannel_info = {&cam640_cpas210_qchannel_info},
.num_qchannel = 1,
};
static struct cam_cpas_top_regs cam640_cpas210_cpas_top_info = {
.tpg_mux_sel_enabled = true,
.tpg_mux_sel_shift = 0x0,
.tpg_mux_sel = 0x1C,
};
#endif /* _CPASTOP_V640_210_H_ */

View File

@ -0,0 +1,649 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CPASTOP_V665_100_H_
#define _CPASTOP_V665_100_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v665_100_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x240, /* CAM_NOC_SBM_FAULTINEN0_LOW */
.value = 0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x04 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x08 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
(TEST_IRQ_ENABLE ?
0x80 : /* SBM_FAULTINEN0_LOW_PORT7_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x248, /* CAM_NOC_SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x280, /* CAM_NOC_SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x5 : 0x1,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v665_100_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = false,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x8, /* CAM_NOC_ERL_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x10, /* CAM_NOC_ERL_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x18, /* CAM_NOC_ERL_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT1_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x89A0, /* WR_NIU_ENCERREN_LOW */
.value = 0XF,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x8990, /* WR_NIU_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x8998, /* WR_NIU_ENCERRCLR_LOW */
.value = 0X1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE0_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x8720, /* CAM_NOC_IPE_0_RD_NIU_DECERREN_LOW */
.value = 0xFF,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x8710, /* CAM_NOC_IPE_0_RD_NIU_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x8718, /* CAM_NOC_IPE_0_RD_NIU_DECERRCLR_LOW */
.value = 0X1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = false,
.sbm_port = 0x40, /* SBM_FAULTINSTATUS0_LOW_PORT6_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x288, /* CAM_NOC_SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x290, /* CAM_NOC_SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false, /* CAM_NOC_SBM_FLAGOUTCLR0_LOW */
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
};
static struct cam_camnoc_specific
cam_cpas_v665_100_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_TFE_BAYER_STATS,
.port_name = "TFE_BAYER",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8A30, /* TFE_BAYER_NIU_PRIORITYLUT_LOW */
.value = 0x55554433,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8A34, /* TFE_BAYER_NIU_PRIORITYLUT_HIGH */
.value = 0x66555555,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8A38, /* TFE_BAYER_NIU_URGENCY_LOW */
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8A40, /* TFE_BAYER_NIU_DANGERLUT_LOW */
.value = 0xffffff00,
},
.safe_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8A48, /* TFE_BAYER_NIU_SAFELUT_LOW */
.value = 0x0000000f,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9008, /* TFE_BAYER_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9020, /* TFE_BAYER_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9024, /* TFE_BAYER_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
.maxwr_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ,
.masked_value = 0,
.offset = 0x8A20, /* TFE_BAYER_NIU_MAXWR_LOW */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_TFE_RAW,
.port_name = "TFE_RDI_RAW",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8C30, /* TFE_RDI_NIU_PRIORITYLUT_LOW */
.value = 0x55554433,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8C34, /* TFE_RDI_NIU_PRIORITYLUT_HIGH */
.value = 0x66555555,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8C38, /* TFE_RDI_RAW_URGENCY_LOW */
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8C40, /* TFE_RDI_NIU_DANGERLUT_LOW */
.value = 0xffffff00,
},
.safe_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8C48, /* TFE_RDI_NIU_SAFELUT_LOW */
.value = 0x0000000f,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9088, /* TFE_RDI_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x90A0, /* TFE_RDI_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x90A4, /* TFE_RDI_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
.maxwr_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ,
.masked_value = 0,
.offset = 0x8C20, /* TFE_RDI_NIU_MAXWR_LOW */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_OPE_BPS_WR,
.port_name = "OPE_BPS_WR",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8830, /* OFFLINE_WR_NIU_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8834, /* OFFLINE_WR_NIU_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8838, /* OFFLINE_WR_NIU_URGENCY_LOW */
.value = 0x030,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8840, /* OFFLINE_WR_NIU_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8848, /* OFFLINE_WR_NIU_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8F88, /* OFFLINE_WR_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8FA0, /* OFFLINE_WR_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8FA4, /* OFFLINE_WR_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
.maxwr_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ,
.masked_value = 0,
.offset = 0x8820, /* OFFLINE_WR_NIU_MAXWR_LOW */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_OPE_BPS_CDM_RD,
.port_name = "OPE_BPS_CDM_RD",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8630, /* OFFLINE_RD_NIU_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8634, /* OFFLINE_RD_NIU_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8638, /* OFFLINE_RD_NIU_URGENCY_LOW */
.value = 0x003,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8640, /* OFFLINE_RD_NIU_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8648, /* OFFLINE_RD_NIU_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8F08, /* OFFLINE_RD_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8F20, /* OFFLINE_RD_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8F24, /* OFFLINE_RD_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_CRE,
.port_name = "CRE_RD_WR",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8230, /* CRE_NIU_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8234, /* CRE_NIU_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8238, /* CRE_NIU_URGENCY_LOW */
.value = 0x033,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8240, /* CRE_NIU_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8248, /* CRE_NIU_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8E88, /* CRE_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8EA0, /* CRE_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8EA4, /* CRE_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
.maxwr_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ,
.masked_value = 0,
.offset = 0x8220, /* CRE_NIU_MAXWR_LOW */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_CDM,
.port_name = "CDM",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8030, /* CDM_NIU_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8034, /* CDM_NIU_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8038, /* CDM_NIU_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8040, /* CDM_NIU_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8048, /* CDM_NIU_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8E08, /* CDM_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8E20, /* CDM_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8E24, /* CDM_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_ICP,
.port_name = "ICP",
.enable = false,
.flag_out_set0_low = {
.enable = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x288,
.value = 0x100000,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9108, /* ICP_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9120, /* ICP_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9124, /* ICP_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
};
static struct cam_camnoc_err_logger_info cam665_cpas100_err_logger_offsets = {
.mainctrl = 0x8, /* ERL_MAINCTL_LOW */
.errvld = 0x10, /* ERl_ERRVLD_LOW */
.errlog0_low = 0x20, /* ERL_ERRLOG0_LOW */
.errlog0_high = 0x24, /* ERL_ERRLOG0_HIGH */
.errlog1_low = 0x28, /* ERL_ERRLOG1_LOW */
.errlog1_high = 0x2C, /* ERL_ERRLOG1_HIGH */
.errlog2_low = 0x30, /* ERL_ERRLOG2_LOW */
.errlog2_high = 0x34, /* ERL_ERRLOG2_HIGH */
.errlog3_low = 0x38, /* ERL_ERRLOG3_LOW */
.errlog3_high = 0x3C, /* ERL_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam665_cpas100_errata_wa_list = {
.enable_icp_clk_for_qchannel = {
.enable = true,
},
};
static struct cam_camnoc_info cam665_cpas100_camnoc_info = {
.specific = &cam_cpas_v665_100_camnoc_specific[0],
.specific_size = ARRAY_SIZE(cam_cpas_v665_100_camnoc_specific),
.irq_sbm = &cam_cpas_v665_100_irq_sbm,
.irq_err = &cam_cpas_v665_100_irq_err[0],
.irq_err_size = ARRAY_SIZE(cam_cpas_v665_100_irq_err),
.err_logger = &cam665_cpas100_err_logger_offsets,
.errata_wa_list = &cam665_cpas100_errata_wa_list,
};
static struct cam_cpas_camnoc_qchannel cam665_cpas100_qchannel_info = {
.qchannel_ctrl = 0x14,
.qchannel_status = 0x18,
};
static struct cam_cpas_info cam665_cpas100_cpas_info = {
.hw_caps_info = {
.num_caps_registers = 1,
.hw_caps_offsets = {0x8},
},
.qchannel_info = {&cam665_cpas100_qchannel_info},
.num_qchannel = 1,
};
static struct cam_cpas_top_regs cam665_cpas100_cpas_top_info = {
.tpg_mux_sel_enabled = true,
.tpg_mux_sel_shift = 0x0,
.tpg_mux_sel = 0x1C,
};
#endif /* _CPASTOP_V665_100_H_ */

View File

@ -0,0 +1,692 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CPASTOP_V770_100_H_
#define _CPASTOP_V770_100_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v770_100_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x240, /* CAM_NOC_SBM_FAULTINEN0_LOW */
.value = 0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x04 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x08 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
(TEST_IRQ_ENABLE ?
0x80 : /* SBM_FAULTINEN0_LOW_PORT7_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x248, /* CAM_NOC_SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x280, /* CAM_NOC_SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x5 : 0x1,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v770_100_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = false,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x8, /* CAM_NOC_ERL_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x10, /* CAM_NOC_ERL_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x18, /* CAM_NOC_ERL_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT1_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x89A0, /* WR_NIU_ENCERREN_LOW */
.value = 0XF,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x8990, /* WR_NIU_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x8998, /* WR_NIU_ENCERRCLR_LOW */
.value = 0X1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE0_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x8720, /* CAM_NOC_IPE_0_RD_NIU_DECERREN_LOW */
.value = 0xFF,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x8710, /* CAM_NOC_IPE_0_RD_NIU_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x8718, /* CAM_NOC_IPE_0_RD_NIU_DECERRCLR_LOW */
.value = 0X1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = false,
.sbm_port = 0x40, /* SBM_FAULTINSTATUS0_LOW_PORT6_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x288, /* CAM_NOC_SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x290, /* CAM_NOC_SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false, /* CAM_NOC_SBM_FLAGOUTCLR0_LOW */
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
};
static struct cam_camnoc_specific
cam_cpas_v770_100_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_TFE_BAYER_STATS,
.port_name = "TFE_BAYER",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8A30, /* TFE_BAYER_NIU_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8A34, /* TFE_BAYER_NIU_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8A38, /* TFE_BAYER_NIU_URGENCY_LOW */
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8A40, /* TFE_BAYER_NIU_DANGERLUT_LOW */
.value = 0xffffff00,
},
.safe_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8A48, /* TFE_BAYER_NIU_SAFELUT_LOW */
.value = 0x0000000f,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9008, /* TFE_BAYER_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9020, /* TFE_BAYER_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9024, /* TFE_BAYER_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
.maxwr_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ,
.masked_value = 0,
.offset = 0x8A20, /* TFE_BAYER_NIU_MAXWR_LOW */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_TFE_RAW,
.port_name = "TFE_RDI_RAW",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8C30, /* TFE_RDI_NIU_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8C34, /* TFE_RDI_NIU_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8C38, /* TFE_RDI_RAW_URGENCY_LOW */
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8C40, /* TFE_RDI_NIU_DANGERLUT_LOW */
.value = 0xffffff00,
},
.safe_lut = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8C48, /* TFE_RDI_NIU_SAFELUT_LOW */
.value = 0x0000000f,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9088, /* TFE_RDI_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x90A0, /* TFE_RDI_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x90A4, /* TFE_RDI_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
.maxwr_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ,
.masked_value = 0,
.offset = 0x8C20, /* TFE_RDI_NIU_MAXWR_LOW */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_OPE_BPS_WR,
.port_name = "OPE_BPS_WR",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8830, /* OFFLINE_WR_NIU_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8834, /* OFFLINE_WR_NIU_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8838, /* OFFLINE_WR_NIU_URGENCY_LOW */
.value = 0x030,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8840, /* OFFLINE_WR_NIU_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8848, /* OFFLINE_WR_NIU_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8F88, /* OFFLINE_WR_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8FA0, /* OFFLINE_WR_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8FA4, /* OFFLINE_WR_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
.maxwr_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ,
.masked_value = 0,
.offset = 0x8820, /* OFFLINE_WR_NIU_MAXWR_LOW */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_OPE_BPS_CDM_RD,
.port_name = "OPE_BPS_CDM_RD",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8630, /* OFFLINE_RD_NIU_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8634, /* OFFLINE_RD_NIU_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8638, /* OFFLINE_RD_NIU_URGENCY_LOW */
.value = 0x003,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8640, /* OFFLINE_RD_NIU_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8648, /* OFFLINE_RD_NIU_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8F08, /* OFFLINE_RD_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8F20, /* OFFLINE_RD_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8F24, /* OFFLINE_RD_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_CRE,
.port_name = "CRE_RD_WR",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8230, /* CRE_NIU_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8234, /* CRE_NIU_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8238, /* CRE_NIU_URGENCY_LOW */
.value = 0x033,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8240, /* CRE_NIU_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8248, /* CRE_NIU_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8E88, /* CRE_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8EA0, /* CRE_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8EA4, /* CRE_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
.maxwr_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ,
.masked_value = 0,
.offset = 0x8220, /* CRE_NIU_MAXWR_LOW */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.port_name = "JPEG",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8430, /* JPEG_NIU_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8434, /* JPEG_NIU_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8438, /* JPEG_NIU_URGENCY_LOW */
.value = 0x33,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8440, /* JPEG_NIU_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8448, /* JPEG_NIU_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
},
{
.port_type = CAM_CAMNOC_CDM,
.port_name = "CDM",
.enable = true,
.priority_lut_low = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8030, /* CDM_NIU_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8034, /* CDM_NIU_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8038, /* CDM_NIU_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8040, /* CDM_NIU_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8048, /* CDM_NIU_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8E08, /* CDM_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8E20, /* CDM_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x8E24, /* CDM_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_ICP,
.port_name = "ICP",
.enable = false,
.flag_out_set0_low = {
.enable = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x288,
.value = 0x100000,
},
.qosgen_mainctl = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9108, /* ICP_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9120, /* ICP_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x9124, /* ICP_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
};
static struct cam_camnoc_err_logger_info cam770_cpas100_err_logger_offsets = {
.mainctrl = 0x8, /* ERL_MAINCTL_LOW */
.errvld = 0x10, /* ERl_ERRVLD_LOW */
.errlog0_low = 0x20, /* ERL_ERRLOG0_LOW */
.errlog0_high = 0x24, /* ERL_ERRLOG0_HIGH */
.errlog1_low = 0x28, /* ERL_ERRLOG1_LOW */
.errlog1_high = 0x2C, /* ERL_ERRLOG1_HIGH */
.errlog2_low = 0x30, /* ERL_ERRLOG2_LOW */
.errlog2_high = 0x34, /* ERL_ERRLOG2_HIGH */
.errlog3_low = 0x38, /* ERL_ERRLOG3_LOW */
.errlog3_high = 0x3C, /* ERL_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam770_cpas100_errata_wa_list = {
.enable_icp_clk_for_qchannel = {
.enable = true,
},
};
static struct cam_camnoc_info cam770_cpas100_camnoc_info = {
.specific = &cam_cpas_v770_100_camnoc_specific[0],
.specific_size = ARRAY_SIZE(cam_cpas_v770_100_camnoc_specific),
.irq_sbm = &cam_cpas_v770_100_irq_sbm,
.irq_err = &cam_cpas_v770_100_irq_err[0],
.irq_err_size = ARRAY_SIZE(cam_cpas_v770_100_irq_err),
.err_logger = &cam770_cpas100_err_logger_offsets,
.errata_wa_list = &cam770_cpas100_errata_wa_list,
};
static struct cam_cpas_camnoc_qchannel cam770_cpas100_qchannel_info = {
.qchannel_ctrl = 0x14,
.qchannel_status = 0x18,
};
static struct cam_cpas_info cam770_cpas100_cpas_info = {
.hw_caps_info = {
.num_caps_registers = 1,
.hw_caps_offsets = {0x8},
},
.qchannel_info = {&cam770_cpas100_qchannel_info},
.num_qchannel = 1,
};
static struct cam_cpas_top_regs cam770_cpas100_cpas_top_info = {
.tpg_mux_sel_enabled = true,
.tpg_mux_sel_shift = 0x0,
.tpg_mux_sel = 0x1C,
};
#endif /* _CPASTOP_V770_100_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_CPAS_API_H_
@ -32,6 +32,15 @@
#define CAM_CPAS_QOS_DEFAULT_SETTINGS_MASK 0x1
#define CAM_CPAS_QOS_CUSTOM_SETTINGS_MASK 0x2
/**
* Secure camera QoS update id - Enum for identify QOS settings update type
*/
enum secure_camera_qos_update_type {
CAM_QOS_UPDATE_TYPE_STATIC = 0x0,
CAM_QOS_UPDATE_TYPE_SMART = 0x1,
CAM_QOS_UPDATE_TYPE_MAX,
};
/**
* enum cam_cpas_regbase_types - Enum for cpas regbase available for clients
* to read/write
@ -86,6 +95,9 @@ enum cam_cpas_camera_version {
CAM_CPAS_CAMERA_VERSION_640 = 0x00060400,
CAM_CPAS_CAMERA_VERSION_880 = 0x00080800,
CAM_CPAS_CAMERA_VERSION_980 = 0x00090800,
CAM_CPAS_CAMERA_VERSION_860 = 0x00080600,
CAM_CPAS_CAMERA_VERSION_770 = 0x00070700,
CAM_CPAS_CAMERA_VERSION_665 = 0x00060605,
CAM_CPAS_CAMERA_VERSION_MAX
};
@ -100,6 +112,7 @@ enum cam_cpas_version {
CAM_CPAS_VERSION_120 = 0x10020000,
CAM_CPAS_VERSION_130 = 0x10030000,
CAM_CPAS_VERSION_200 = 0x20000000,
CAM_CPAS_VERSION_210 = 0x20010000,
CAM_CPAS_VERSION_MAX
};
@ -123,6 +136,9 @@ enum cam_cpas_camera_version_map_id {
CAM_CPAS_CAMERA_VERSION_ID_640 = 0xC,
CAM_CPAS_CAMERA_VERSION_ID_880 = 0xD,
CAM_CPAS_CAMERA_VERSION_ID_980 = 0xE,
CAM_CPAS_CAMERA_VERSION_ID_860 = 0xF,
CAM_CPAS_CAMERA_VERSION_ID_770 = 0x10,
CAM_CPAS_CAMERA_VERSION_ID_665 = 0x11,
CAM_CPAS_CAMERA_VERSION_ID_MAX
};
@ -137,6 +153,7 @@ enum cam_cpas_version_map_id {
CAM_CPAS_VERSION_ID_120 = 0x3,
CAM_CPAS_VERSION_ID_130 = 0x4,
CAM_CPAS_VERSION_ID_200 = 0x5,
CAM_CPAS_VERSION_ID_210 = 0x6,
CAM_CPAS_VERSION_ID_MAX
};
@ -166,8 +183,12 @@ enum cam_cpas_hw_version {
CAM_CPAS_TITAN_680_V110 = 0x680110,
CAM_CPAS_TITAN_780_V100 = 0x780100,
CAM_CPAS_TITAN_640_V200 = 0x640200,
CAM_CPAS_TITAN_640_V210 = 0x640210,
CAM_CPAS_TITAN_880_V100 = 0x880100,
CAM_CPAS_TITAN_980_V100 = 0x980100,
CAM_CPAS_TITAN_860_V100 = 0x860100,
CAM_CPAS_TITAN_770_V100 = 0x770100,
CAM_CPAS_TITAN_665_V100 = 0x665100,
CAM_CPAS_TITAN_MAX
};

View File

@ -43,7 +43,7 @@ static int __cam_cre_ctx_flush_dev_in_ready(struct cam_context *ctx,
flush_args.cmd = cmd;
flush_args.flush_active_req = false;
rc = cam_context_flush_dev_to_hw(ctx, cmd, &flush_args);
rc = cam_context_flush_dev_to_hw(ctx, &flush_args);
if (rc)
CAM_ERR(CAM_CRE, "Failed to flush device");

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/mutex.h>
@ -210,9 +210,17 @@ static int cam_cre_mgr_process_cmd_io_buf_req(struct cam_cre_hw_mgr *hw_mgr,
/* Width for WE has to be updated in number of pixels */
if (acq_io_buf->direction == CAM_BUF_OUTPUT) {
/* PLAIN 128/8 = 16 Bytes per pixel */
plane_info->width =
io_cfg_ptr[j].planes[k].plane_stride/16;
if (plane_info->format == CAM_FORMAT_PLAIN16_10) {
plane_info->width =
io_cfg_ptr[j].planes[k].plane_stride/2;
} else if (plane_info->format == CAM_FORMAT_PLAIN128) {
/* PLAIN 128/8 = 16 Bytes per pixel */
plane_info->width =
io_cfg_ptr[j].planes[k].plane_stride/16;
} else {
plane_info->width =
io_cfg_ptr[j].planes[k].width;
}
} else {
/* FE width should be in bytes */
plane_info->width =
@ -402,10 +410,6 @@ static int cam_cre_mgr_remove_bw(struct cam_cre_hw_mgr *hw_mgr, int ctx_id)
ctx_data->clk_info.axi_path[i].mnoc_ab_bw;
hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw -=
ctx_data->clk_info.axi_path[i].mnoc_ib_bw;
hw_mgr_clk_info->axi_path[path_index].ddr_ab_bw -=
ctx_data->clk_info.axi_path[i].ddr_ab_bw;
hw_mgr_clk_info->axi_path[path_index].ddr_ib_bw -=
ctx_data->clk_info.axi_path[i].ddr_ib_bw;
}
rc = cam_cre_update_cpas_vote(hw_mgr, ctx_data);
@ -474,10 +478,6 @@ static bool cam_cre_update_bw_v2(struct cam_cre_hw_mgr *hw_mgr,
ctx_data->clk_info.axi_path[i].mnoc_ab_bw;
hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw -=
ctx_data->clk_info.axi_path[i].mnoc_ib_bw;
hw_mgr_clk_info->axi_path[path_index].ddr_ab_bw -=
ctx_data->clk_info.axi_path[i].ddr_ab_bw;
hw_mgr_clk_info->axi_path[path_index].ddr_ib_bw -=
ctx_data->clk_info.axi_path[i].ddr_ib_bw;
}
ctx_data->clk_info.num_paths =
@ -515,10 +515,6 @@ static bool cam_cre_update_bw_v2(struct cam_cre_hw_mgr *hw_mgr,
ctx_data->clk_info.axi_path[i].mnoc_ab_bw;
hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw +=
ctx_data->clk_info.axi_path[i].mnoc_ib_bw;
hw_mgr_clk_info->axi_path[path_index].ddr_ab_bw +=
ctx_data->clk_info.axi_path[i].ddr_ab_bw;
hw_mgr_clk_info->axi_path[path_index].ddr_ib_bw +=
ctx_data->clk_info.axi_path[i].ddr_ib_bw;
CAM_DBG(CAM_CRE,
"Consolidate Path Vote : Dev[%s] i[%d] path_idx[%d] : [%s %s] [%lld %lld]",
ctx_data->cre_acquire.dev_name,
@ -764,45 +760,51 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
task_data = (struct cre_cmd_work_data *)data;
mutex_lock(&hw_mgr->hw_mgr_mutex);
mutex_lock(&ctx_data->ctx_mutex);
if (ctx_data->ctx_state != CRE_CTX_STATE_ACQUIRED) {
mutex_unlock(&hw_mgr->hw_mgr_mutex);
CAM_ERR(CAM_CRE, "ctx id :%u is not in use",
ctx_data->ctx_id);
return -EINVAL;
rc = -EINVAL;
goto err;
}
if (task_data->req_idx >= CAM_CTX_REQ_MAX) {
mutex_unlock(&hw_mgr->hw_mgr_mutex);
CAM_ERR(CAM_CRE, "Invalid reqIdx = %llu",
task_data->req_idx);
return -EINVAL;
task_data->req_idx);
rc = -EINVAL;
goto err;
}
if (task_data->request_id <= ctx_data->last_flush_req) {
CAM_WARN(CAM_CRE,
"request %lld has been flushed, reject packet", task_data->request_id);
rc = -EINVAL;
goto err;
}
cre_req = ctx_data->req_list[task_data->req_idx];
if (cre_req->request_id > ctx_data->last_flush_req)
ctx_data->last_flush_req = 0;
if (cre_req->request_id <= ctx_data->last_flush_req) {
CAM_WARN(CAM_CRE,
"request %lld has been flushed, reject packet",
cre_req->request_id, ctx_data->last_flush_req);
mutex_unlock(&hw_mgr->hw_mgr_mutex);
return -EINVAL;
}
if (!cam_cre_is_pending_request(ctx_data)) {
CAM_WARN(CAM_CRE, "no pending req, req %lld last flush %lld",
cre_req->request_id, ctx_data->last_flush_req);
mutex_unlock(&hw_mgr->hw_mgr_mutex);
return -EINVAL;
rc = -EINVAL;
goto err;
}
hw_mgr = task_data->data;
num_batch = cre_req->num_batch;
if (num_batch > CRE_MAX_BATCH_SIZE) {
CAM_WARN(CAM_CRE, "num_batch = %u is greater than max",
num_batch);
num_batch = CRE_MAX_BATCH_SIZE;
}
CAM_DBG(CAM_CRE,
"Going to configure cre for req %d, req_idx %d num_batch %d",
cre_req->request_id, cre_req->req_idx, num_batch);
"Ctx %d Going to configure cre for req %d, req_idx %d num_batch %d",
ctx_data->ctx_id, cre_req->request_id, cre_req->req_idx, num_batch);
for (i = 0; i < num_batch; i++) {
if (i != 0) {
@ -813,7 +815,8 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
cam_cre_device_timer_reset(cre_hw_mgr);
CAM_ERR(CAM_CRE,
"Timedout waiting for bufdone on last frame");
return -ETIMEDOUT;
rc = -EINVAL;
goto err;
} else {
reinit_completion(&ctx_data->cre_top->bufdone);
CAM_INFO(CAM_CRE,
@ -825,27 +828,13 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
cam_cre_mgr_update_reg_set(hw_mgr, cre_req, i);
cam_cre_ctx_wait_for_idle_irq(ctx_data);
}
err:
mutex_unlock(&ctx_data->ctx_mutex);
mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc;
}
static int cam_get_valid_ctx_id(void)
{
struct cam_cre_hw_mgr *hw_mgr = cre_hw_mgr;
int i;
for (i = 0; i < CRE_CTX_MAX; i++) {
if (hw_mgr->ctx[i].ctx_state == CRE_CTX_STATE_ACQUIRED)
break;
}
if (i == CRE_CTX_MAX)
return -EINVAL;
return i;
}
static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
{
struct cre_msg_work_data *task_data;
@ -854,7 +843,7 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
struct cam_cre_ctx *ctx;
struct cam_cre_request *active_req;
struct cam_cre_irq_data irq_data;
int32_t ctx_id;
struct cam_cre_hw_cfg_req *cfg_req = NULL;
uint32_t evt_id;
uint32_t active_req_idx;
int rc = 0;
@ -866,30 +855,51 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
task_data = data;
hw_mgr = priv;
ctx_id = cam_get_valid_ctx_id();
if (ctx_id < 0) {
CAM_ERR(CAM_CRE, "No valid context to handle error");
return ctx_id;
mutex_lock(&hw_mgr->hw_mgr_mutex);
cfg_req = list_first_entry(&hw_mgr->hw_config_req_list,
struct cam_cre_hw_cfg_req, list);
if (!cfg_req) {
CAM_ERR(CAM_CRE, "Hw config req list empty");
rc = -EFAULT;
mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc;
}
list_del_init(&cfg_req->list);
ctx = &hw_mgr->ctx[ctx_id];
mutex_lock(&ctx->ctx_mutex);
irq_data = task_data->irq_data;
if (ctx->ctx_state != CRE_CTX_STATE_ACQUIRED) {
CAM_DBG(CAM_CRE, "ctx id: %d not in right state: %d",
ctx_id, ctx->ctx_state);
mutex_unlock(&ctx->ctx_mutex);
if (cfg_req->ctx_id < 0) {
CAM_ERR(CAM_CRE, "No valid context to handle error");
mutex_unlock(&hw_mgr->hw_mgr_mutex);
return -EINVAL;
}
ctx = &hw_mgr->ctx[cfg_req->ctx_id];
mutex_lock(&ctx->ctx_mutex);
irq_data = task_data->irq_data;
if (ctx->ctx_state != CRE_CTX_STATE_ACQUIRED) {
CAM_DBG(CAM_CRE, "ctx id: %d not in right state: %d",
cfg_req->ctx_id, ctx->ctx_state);
rc = -EINVAL;
goto end;
}
active_req_idx = find_next_bit(ctx->bitmap, ctx->bits, ctx->last_done_req_idx);
CAM_DBG(CAM_CRE, "active_req_idx %d last_done_req_idx %d",
CAM_DBG(CAM_CRE, "Ctx %d active_req_idx %d last_done_req_idx %d", ctx->ctx_id,
active_req_idx, ctx->last_done_req_idx);
if (active_req_idx >= CAM_CTX_REQ_MAX) {
CAM_WARN(CAM_CRE, "ctx %d not valid req idx active_req_idx %d", active_req_idx);
rc = -EINVAL;
goto end;
}
active_req = ctx->req_list[active_req_idx];
if (!active_req)
if (!active_req) {
CAM_ERR(CAM_CRE, "Active req cannot be null");
rc = -EINVAL;
goto end;
}
if (irq_data.error) {
evt_id = CAM_CTX_EVT_ID_ERROR;
@ -905,14 +915,14 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
} else if (irq_data.wr_buf_done) {
/* Signal Buf done */
active_req->frames_done++;
CAM_DBG(CAM_CRE, "Received frames_done %d num_batch %d req id %d",
active_req->frames_done, active_req->num_batch,
CAM_DBG(CAM_CRE, "Ctx %d Received frames_done %d num_batch %d req id %d",
ctx->ctx_id, active_req->frames_done, active_req->num_batch,
active_req->request_id);
complete(&ctx->cre_top->bufdone);
if (active_req->frames_done == active_req->num_batch) {
ctx->last_done_req_idx = active_req_idx;
CAM_DBG(CAM_CRE, "signaling buff done for req %d",
active_req->request_id);
CAM_DBG(CAM_CRE, "Ctx %d signaling buff done for req %d",
ctx->ctx_id, active_req->request_id);
evt_id = CAM_CTX_EVT_ID_SUCCESS;
buf_data.evt_param = CAM_SYNC_COMMON_EVENT_SUCCESS;
buf_data.request_id = active_req->request_id;
@ -924,7 +934,10 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
ctx->req_list[active_req_idx] = NULL;
}
}
end:
list_add_tail(&cfg_req->list, &hw_mgr->free_req_list);
mutex_unlock(&ctx->ctx_mutex);
mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc;
}
@ -1550,6 +1563,12 @@ static int cam_cre_validate_acquire_res_info(
cre_acquire->in_res[i].format);
return -EINVAL;
}
if (!cre_acquire->in_res[i].width || !cre_acquire->in_res[i].height) {
CAM_ERR(CAM_CRE, "Invalid width %d height %d for in res %d",
cre_acquire->in_res[i].width, cre_acquire->in_res[i].height, i);
return -EINVAL;
}
}
for (i = 0; i < cre_acquire->num_out_res; i++) {
@ -1794,8 +1813,6 @@ static int cam_cre_mgr_acquire_hw(void *hw_priv, void *hw_acquire_args)
hw_mgr->clk_info.axi_path[i].camnoc_bw = 0;
hw_mgr->clk_info.axi_path[i].mnoc_ab_bw = 0;
hw_mgr->clk_info.axi_path[i].mnoc_ib_bw = 0;
hw_mgr->clk_info.axi_path[i].ddr_ab_bw = 0;
hw_mgr->clk_info.axi_path[i].ddr_ib_bw = 0;
}
}
@ -1843,8 +1860,6 @@ static int cam_cre_mgr_acquire_hw(void *hw_priv, void *hw_acquire_args)
bw_update->axi_vote.axi_path[0].camnoc_bw = 600000000;
bw_update->axi_vote.axi_path[0].mnoc_ab_bw = 600000000;
bw_update->axi_vote.axi_path[0].mnoc_ib_bw = 600000000;
bw_update->axi_vote.axi_path[0].ddr_ab_bw = 600000000;
bw_update->axi_vote.axi_path[0].ddr_ib_bw = 600000000;
bw_update->axi_vote.axi_path[0].transac_type =
CAM_AXI_TRANSACTION_WRITE;
bw_update->axi_vote.axi_path[0].path_data_type =
@ -2008,7 +2023,7 @@ static int cam_cre_mgr_release_hw(void *hw_priv, void *hw_release_args)
mutex_lock(&hw_mgr->hw_mgr_mutex);
rc = cam_cre_mgr_release_ctx(hw_mgr, ctx_id);
if (!hw_mgr->cre_ctx_cnt) {
CAM_DBG(CAM_CRE, "Last Release");
CAM_DBG(CAM_CRE, "Last Release #of CRE %d", cre_hw_mgr->num_cre);
for (i = 0; i < cre_hw_mgr->num_cre; i++) {
dev_intf = hw_mgr->cre_dev_intf[i];
irq_cb.cre_hw_mgr_cb = NULL;
@ -2106,20 +2121,20 @@ static int cam_cre_packet_generic_blob_handler(void *user_data,
clk_info = &ctx_data->req_list[index]->clk_info;
clk_info_v2 = &ctx_data->req_list[index]->clk_info_v2;
clk_info_v2.budget_ns = soc_req->budget_ns;
clk_info_v2.frame_cycles = soc_req->frame_cycles;
clk_info_v2.rt_flag = soc_req->rt_flag;
clk_info_v2.num_paths = soc_req->num_paths;
clk_info_v2->budget_ns = soc_req->budget_ns;
clk_info_v2->frame_cycles = soc_req->frame_cycles;
clk_info_v2->rt_flag = soc_req->rt_flag;
clk_info_v2->num_paths = soc_req->num_paths;
for (i = 0; i < soc_req->num_paths; i++) {
clk_info_v2.axi_path[i].usage_data = soc_req->axi_path[i].usage_data;
clk_info_v2.axi_path[i].transac_type = soc_req->axi_path[i].transac_type;
clk_info_v2.axi_path[i].path_data_type =
clk_info_v2->axi_path[i].usage_data = soc_req->axi_path[i].usage_data;
clk_info_v2->axi_path[i].transac_type = soc_req->axi_path[i].transac_type;
clk_info_v2->axi_path[i].path_data_type =
soc_req->axi_path[i].path_data_type;
clk_info_v2.axi_path[i].vote_level = 0;
clk_info_v2.axi_path[i].camnoc_bw = soc_req->axi_path[i].camnoc_bw;
clk_info_v2.axi_path[i].mnoc_ab_bw = soc_req->axi_path[i].mnoc_ab_bw;
clk_info_v2.axi_path[i].mnoc_ib_bw = soc_req->axi_path[i].mnoc_ib_bw;
clk_info_v2->axi_path[i].vote_level = 0;
clk_info_v2->axi_path[i].camnoc_bw = soc_req->axi_path[i].camnoc_bw;
clk_info_v2->axi_path[i].mnoc_ab_bw = soc_req->axi_path[i].mnoc_ab_bw;
clk_info_v2->axi_path[i].mnoc_ib_bw = soc_req->axi_path[i].mnoc_ib_bw;
}
/* Use v1 structure for clk fields */
@ -2292,7 +2307,6 @@ static int cam_cre_mgr_prepare_hw_update(void *hw_priv,
prepare_args->num_hw_update_entries = 1;
prepare_args->priv = ctx_data->req_list[request_idx];
cre_req->hang_data.packet = packet;
ktime_get_boottime_ts64(&ts);
ctx_data->last_req_time = (uint64_t)((ts.tv_sec * 1000000000) +
ts.tv_nsec);
@ -2330,7 +2344,8 @@ static int cam_cre_mgr_enqueue_config(struct cam_cre_hw_mgr *hw_mgr,
request_id = config_args->request_id;
hw_update_entries = config_args->hw_update_entries;
CAM_DBG(CAM_CRE, "req_id = %lld %pK", request_id, config_args->priv);
CAM_DBG(CAM_CRE, "Ctx %d req_id = %lld %pK", ctx_data->ctx_id,
request_id, config_args->priv);
task = cam_req_mgr_workq_get_task(cre_hw_mgr->cmd_work);
if (!task) {
@ -2341,6 +2356,7 @@ static int cam_cre_mgr_enqueue_config(struct cam_cre_hw_mgr *hw_mgr,
task_data = (struct cre_cmd_work_data *)task->payload;
task_data->data = (void *)hw_mgr;
task_data->req_idx = cre_req->req_idx;
task_data->request_id = cre_req->request_id;
task_data->type = CRE_WORKQ_TASK_CMD_TYPE;
task->process_cb = cam_cre_mgr_process_cmd;
@ -2361,8 +2377,8 @@ static int cam_cre_mgr_config_hw(void *hw_priv, void *hw_config_args)
struct cam_hw_config_args *config_args = hw_config_args;
struct cam_cre_ctx *ctx_data = NULL;
struct cam_cre_request *cre_req = NULL;
struct cam_cre_hw_cfg_req *cfg_req = NULL;
CAM_DBG(CAM_CRE, "E");
if (!hw_mgr || !config_args) {
CAM_ERR(CAM_CRE, "Invalid arguments %pK %pK",
hw_mgr, config_args);
@ -2378,23 +2394,42 @@ static int cam_cre_mgr_config_hw(void *hw_priv, void *hw_config_args)
mutex_lock(&hw_mgr->hw_mgr_mutex);
mutex_lock(&ctx_data->ctx_mutex);
if (ctx_data->ctx_state != CRE_CTX_STATE_ACQUIRED) {
mutex_unlock(&ctx_data->ctx_mutex);
mutex_unlock(&hw_mgr->hw_mgr_mutex);
CAM_ERR(CAM_CRE, "ctx id :%u is not in use",
ctx_data->ctx_id);
return -EINVAL;
rc= -EINVAL;
goto end;
}
if (list_empty(&hw_mgr->free_req_list)) {
CAM_ERR(CAM_CRE, "No request in free list");
rc = -ENOMEM;
goto end;
}
cfg_req = list_first_entry(&hw_mgr->free_req_list,
struct cam_cre_hw_cfg_req, list);
list_del_init(&cfg_req->list);
cre_req = config_args->priv;
cam_cre_mgr_cre_clk_update(hw_mgr, ctx_data, cre_req->req_idx);
ctx_data->req_list[cre_req->req_idx]->submit_timestamp = ktime_get();
if (cre_req->request_id <= ctx_data->last_flush_req)
CAM_DBG(CAM_CRE, "ctx id :%u req id %lld", ctx_data->ctx_id, cre_req->request_id);
cfg_req->req_id = cre_req->request_id;
cfg_req->ctx_id = ctx_data->ctx_id;
if (cre_req->request_id <= ctx_data->last_flush_req) {
CAM_WARN(CAM_CRE,
"Anomaly submitting flushed req %llu [last_flush %llu] in ctx %u",
cre_req->request_id, ctx_data->last_flush_req,
ctx_data->ctx_id);
rc = -EINVAL;
goto end;
}
list_add_tail(&cfg_req->list, &hw_mgr->hw_config_req_list);
rc = cam_cre_mgr_enqueue_config(hw_mgr, ctx_data, config_args);
if (rc)
@ -2409,6 +2444,7 @@ static int cam_cre_mgr_config_hw(void *hw_priv, void *hw_config_args)
return rc;
config_err:
cam_cre_mgr_handle_config_err(config_args, ctx_data);
end:
mutex_unlock(&ctx_data->ctx_mutex);
mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc;
@ -2417,6 +2453,7 @@ config_err:
static void cam_cre_mgr_dump_pf_data(struct cam_cre_hw_mgr *hw_mgr,
struct cam_hw_cmd_pf_args *pf_cmd_args)
{
int rc = 0;
struct cam_packet *packet;
struct cam_hw_dump_pf_args *pf_args;
size_t len;
@ -2970,6 +3007,14 @@ int cam_cre_hw_mgr_init(struct device_node *of_node, void *hw_mgr,
if (rc)
goto cre_wq_create_failed;
INIT_LIST_HEAD(&cre_hw_mgr->hw_config_req_list);
INIT_LIST_HEAD(&cre_hw_mgr->free_req_list);
for (i = 0; i < CAM_CRE_HW_CFG_Q_MAX; i++) {
INIT_LIST_HEAD(&cre_hw_mgr->req_list[i].list);
list_add_tail(&cre_hw_mgr->req_list[i].list,
&cre_hw_mgr->free_req_list);
}
cam_cre_create_debug_fs();
if (iommu_hdl)

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef CAM_CRE_HW_MGR_H
@ -146,14 +146,16 @@ struct cam_cre_clk_info {
/**
* struct cre_cmd_work_data
*
* @type: Type of work data
* @data: Private data
* @req_id: Request Idx
* @type: Type of work data
* @data: Private data
* @req_idx: Request Idx
* @request_id: Request id
*/
struct cre_cmd_work_data {
uint32_t type;
void *data;
int64_t req_idx;
uint64_t request_id;
};
/**
@ -341,6 +343,20 @@ struct cam_cre_ctx {
cam_hw_event_cb_func ctxt_event_cb;
};
/**
* struct cam_cre_hw_cfg_req
*
* @list: Requests submiited to HW
* @req_id: Request id
* ctx_id: Ctx id
*
*/
struct cam_cre_hw_cfg_req {
struct list_head list;
uint64_t req_id;
uint32_t ctx_id;
};
/**
* struct cam_cre_hw_mgr
*
@ -367,6 +383,9 @@ struct cam_cre_ctx {
* @clk_info: CRE clock Info for HW manager
* @dentry: Pointer to CRE debugfs directory
* @dump_req_data_enable: CRE hang dump enablement
* @hw_config_req_list: Requests submitted to HW
* @free_req_list: Requests that are free
* @req_list: Request list which is applied
*/
struct cam_cre_hw_mgr {
uint32_t cre_ctx_cnt;
@ -395,6 +414,10 @@ struct cam_cre_hw_mgr {
struct cam_cre_clk_info clk_info;
struct dentry *dentry;
bool dump_req_data_enable;
struct list_head hw_config_req_list;
struct list_head free_req_list;
struct cam_cre_hw_cfg_req req_list[CAM_CRE_HW_CFG_Q_MAX];
};
/**

View File

@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/delay.h>
#include "cam_hw.h"
#include "cam_hw_intf.h"
@ -66,7 +68,7 @@ static void cam_cre_update_read_reg_val(struct plane_info p_info,
p_info.alignment);
/* Fetch engine width has to be updated in number of bytes */
rd_client_reg_val->img_width = p_info.stride;
rd_client_reg_val->img_width = p_info.width;
rd_client_reg_val->stride = p_info.stride;
rd_client_reg_val->img_height = p_info.height;
rd_client_reg_val->alignment = p_info.alignment;
@ -137,6 +139,10 @@ static int cam_cre_bus_rd_update(struct cam_cre_hw *cam_cre_hw_info,
in_port_idx =
cam_cre_bus_rd_in_port_idx(io_buf->resource_type);
if (in_port_idx < 0) {
CAM_ERR(CAM_CRE, "Invalid in_port_idx for resource %d", io_buf->resource_type);
return -EINVAL;
}
CAM_DBG(CAM_CRE, "in_port_idx %d", in_port_idx);
for (k = 0; k < io_buf->num_planes; k++) {
@ -179,7 +185,7 @@ static int cam_cre_bus_rd_update(struct cam_cre_hw *cam_cre_hw_info,
/* Buffer size */
update_cre_reg_set(cre_reg_buf,
rd_reg->offset + rd_reg_client->rd_width,
rd_client_reg_val->img_width);
ctx_data->cre_acquire.in_res[in_port_idx].width);
update_cre_reg_set(cre_reg_buf,
rd_reg->offset + rd_reg_client->rd_height,
rd_client_reg_val->img_height);
@ -223,7 +229,7 @@ static int cam_cre_bus_rd_prepare(struct cam_cre_hw *cam_cre_hw_info,
struct cre_io_buf *io_buf;
struct cam_cre_bus_rd_reg *rd_reg;
struct cam_cre_bus_rd_reg_val *rd_reg_val;
struct cre_reg_buffer *cre_reg_buf;
struct cre_reg_buffer *cre_reg_buf = NULL;
int val;
@ -267,11 +273,12 @@ static int cam_cre_bus_rd_prepare(struct cam_cre_hw *cam_cre_hw_info,
rd_reg->offset + rd_reg->input_if_cmd,
val);
}
for (i = 0; i < cre_reg_buf->num_rd_reg_set; i++) {
CAM_DBG(CAM_CRE, "CRE value 0x%x offset 0x%x",
cre_reg_buf->rd_reg_set[i].value,
cre_reg_buf->rd_reg_set[i].offset);
if (cre_reg_buf) {
for (i = 0; i < cre_reg_buf->num_rd_reg_set; i++) {
CAM_DBG(CAM_CRE, "CRE value 0x%x offset 0x%x",
cre_reg_buf->rd_reg_set[i].value,
cre_reg_buf->rd_reg_set[i].offset);
}
}
end:
return 0;
@ -441,7 +448,8 @@ static int cam_cre_bus_rd_isr(struct cam_cre_hw *cam_cre_hw_info,
int32_t ctx_id, void *data)
{
uint32_t irq_status;
uint32_t violation_status;
uint32_t const_violation_status;
uint32_t ccif_violation_status;
uint32_t debug_status_0;
uint32_t debug_status_1;
struct cam_cre_bus_rd_reg *bus_rd_reg;
@ -464,24 +472,30 @@ static int cam_cre_bus_rd_isr(struct cam_cre_hw *cam_cre_hw_info,
cam_io_w_mb(bus_rd_reg_val->irq_cmd_clear,
bus_rd_reg->base + bus_rd_reg->irq_cmd);
CAM_DBG(CAM_CRE, "BUS irq_status 0x%x", irq_status);
if (irq_status & bus_rd_reg_val->rup_done)
CAM_DBG(CAM_CRE, "CRE Read Bus RUP done");
if (irq_status & bus_rd_reg_val->rd_buf_done)
CAM_DBG(CAM_CRE, "CRE Read Bus Buff done");
if (irq_status & bus_rd_reg_val->cons_violation) {
if ((irq_status & bus_rd_reg_val->cons_violation) ||
(irq_status & bus_rd_reg_val->ccif_violation)) {
irq_data->error = 1;
violation_status = cam_io_r_mb(bus_rd_reg->base +
bus_rd_reg->rd_clients[0].cons_violation_status);
const_violation_status = cam_io_r_mb(bus_rd_reg->base +
bus_rd_reg->cons_violation);
ccif_violation_status = cam_io_r_mb(bus_rd_reg->base +
bus_rd_reg->ccif_violation);
debug_status_0 = cam_io_r_mb(bus_rd_reg->base +
bus_rd_reg->rd_clients[0].debug_status_0);
debug_status_1 = cam_io_r_mb(bus_rd_reg->base +
bus_rd_reg->rd_clients[0].debug_status_1);
CAM_DBG(CAM_CRE, "CRE Read Bus Violation");
CAM_DBG(CAM_CRE,
"violation status 0x%x debug status 0/1 0x%x/0x%x",
violation_status, debug_status_0, debug_status_1);
"violation status 0x%x 0x%x debug status 0/1 0x%x/0x%x",
const_violation_status, ccif_violation_status,
debug_status_0, debug_status_1);
}
return 0;

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/delay.h>
#include "cam_io_util.h"
@ -22,6 +23,70 @@ static struct cre_bus_wr *wr_info;
cre_reg_buf->num_wr_reg_set++; \
} while (0)
static uint32_t cam_cre_bus_wr_format_idx(uint32_t format)
{
uint32_t format_idx = 0;
switch(format) {
case CAM_FORMAT_PLAIN128:
format_idx = 0x0;
break;
case CAM_FORMAT_PLAIN8:
format_idx = 0x1;
break;
case CAM_FORMAT_PLAIN8_SWAP:
format_idx = 0x2;
break;
case CAM_FORMAT_PLAIN8_10:
format_idx = 0x3;
break;
case CAM_FORMAT_PLAIN8_10_SWAP:
format_idx = 0x4;
break;
case CAM_FORMAT_PLAIN16_10:
format_idx = 0x5;
break;
case CAM_FORMAT_PLAIN16_12:
format_idx = 0x6;
break;
case CAM_FORMAT_PLAIN16_14:
format_idx = 0x7;
break;
case CAM_FORMAT_PLAIN16_16:
format_idx = 0x8;
break;
case CAM_FORMAT_PLAIN32:
format_idx = 0x9;
break;
case CAM_FORMAT_PLAIN64:
format_idx = 0xA;
break;
case CAM_FORMAT_PD10:
format_idx = 0xB;
break;
case CAM_FORMAT_MIPI_RAW_10:
format_idx = 0xC;
break;
case CAM_FORMAT_MIPI_RAW_12:
format_idx = 0xD;
break;
case CAM_FORMAT_MIPI_RAW_14:
format_idx = 0xE;
break;
case CAM_FORMAT_MIPI_RAW_20:
format_idx = 0xF;
break;
case CAM_FORMAT_PLAIN32_20:
format_idx = 0x10;
break;
default:
CAM_WARN(CAM_CRE, "Invalid format %d", format);
break;
}
return format_idx;
}
static int cam_cre_translate_write_format(struct plane_info p_info,
struct cam_cre_bus_wr_client_reg_val *wr_client_reg_val)
{
@ -36,12 +101,7 @@ static int cam_cre_translate_write_format(struct plane_info p_info,
wr_client_reg_val->height = p_info.height;
wr_client_reg_val->alignment = p_info.alignment;
/*
* Update packer format to zero irrespective of output format
* This is as per the recomendation from CRE HW team for CRE 1.0
* This logic has to be updated for CRE 1.1
*/
wr_client_reg_val->format = 0;
wr_client_reg_val->format = p_info.format;
return 0;
}
@ -101,6 +161,7 @@ static int cam_cre_bus_wr_update(struct cam_cre_hw *cam_cre_hw_info,
int rc, k, out_port_idx;
uint32_t req_idx;
uint32_t val = 0;
uint32_t format_idx = 0;
uint32_t iova_base, iova_offset;
struct cam_hw_prepare_update_args *prepare_args;
struct cam_cre_ctx *ctx_data;
@ -204,12 +265,13 @@ static int cam_cre_bus_wr_update(struct cam_cre_hw *cam_cre_hw_info,
wr_client_reg_val->stride);
val = 0;
val |= ((wr_client_reg_val->format &
wr_client_reg_val->format_mask) <<
format_idx = cam_cre_bus_wr_format_idx(wr_client_reg_val->format);
val |= ((format_idx & wr_client_reg_val->format_mask) <<
wr_client_reg_val->format_shift);
val |= ((wr_client_reg_val->alignment &
wr_client_reg_val->alignment_mask) <<
wr_client_reg_val->alignment_shift);
/* Update alignment as LSB by default*/
val |= (0x1 << wr_client_reg_val->alignment_shift);
/* pack cfg : Format and alignment */
update_cre_reg_set(cre_reg_buf,
wr_reg->offset + wr_reg_client->packer_cfg,

View File

@ -168,10 +168,6 @@ int cam_cre_init_hw(void *device_priv,
CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote->axi_vote.axi_path[0].mnoc_ib_bw =
CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote->axi_vote.axi_path[0].ddr_ab_bw =
CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote->axi_vote.axi_path[0].ddr_ib_bw =
CAM_CPAS_DEFAULT_AXI_BW;
rc = cam_cpas_start(core_info->cpas_handle,
&cpas_vote->ahb_vote, &cpas_vote->axi_vote);
@ -237,6 +233,11 @@ int cam_cre_deinit_hw(void *device_priv,
CAM_ERR(CAM_CRE, "soc disable is failed : %d", rc);
core_info->clk_enable = false;
if (cam_cpas_stop(core_info->cpas_handle))
CAM_ERR(CAM_CRE, "cpas stop is failed");
else
core_info->cpas_start = false;
return rc;
}

View File

@ -18,6 +18,7 @@
#include "cam_cpas_api.h"
#include "cam_debug_util.h"
#include "cre_hw_100.h"
#include "cre_hw_110.h"
#include "cre_dev_intf.h"
#include "cam_smmu_api.h"
#include "camera_main.h"
@ -58,6 +59,17 @@ static int cam_cre_init_hw_version(struct cam_hw_soc_info *soc_info,
switch (core_info->hw_version) {
case CRE_HW_VER_1_0_0:
core_info->cre_hw_info->cre_hw = &cre_hw_100;
cre_hw_100.top_reg_offset->base = core_info->cre_hw_info->cre_top_base;
cre_hw_100.bus_rd_reg_offset->base = core_info->cre_hw_info->cre_bus_rd_base;
cre_hw_100.bus_wr_reg_offset->base = core_info->cre_hw_info->cre_bus_wr_base;
break;
case CRE_HW_VER_1_1_0:
core_info->cre_hw_info->cre_hw = &cre_hw_110;
cre_hw_110.top_reg_offset->base = core_info->cre_hw_info->cre_top_base;
cre_hw_110.bus_rd_reg_offset->base = core_info->cre_hw_info->cre_bus_rd_base;
cre_hw_110.bus_wr_reg_offset->base = core_info->cre_hw_info->cre_bus_wr_base;
break;
default:
CAM_ERR(CAM_CRE, "Unsupported version : %u",
@ -66,9 +78,6 @@ static int cam_cre_init_hw_version(struct cam_hw_soc_info *soc_info,
break;
}
cre_hw_100.top_reg_offset->base = core_info->cre_hw_info->cre_top_base;
cre_hw_100.bus_rd_reg_offset->base = core_info->cre_hw_info->cre_bus_rd_base;
cre_hw_100.bus_wr_reg_offset->base = core_info->cre_hw_info->cre_bus_wr_base;
return rc;
}
@ -200,10 +209,6 @@ static int cam_cre_component_bind(struct device *dev,
CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote.axi_vote.axi_path[0].mnoc_ib_bw =
CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote.axi_vote.axi_path[0].ddr_ab_bw =
CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote.axi_vote.axi_path[0].ddr_ib_bw =
CAM_CPAS_DEFAULT_AXI_BW;
rc = cam_cpas_start(core_info->cpas_handle,
&cpas_vote.ahb_vote, &cpas_vote.axi_vote);

View File

@ -1,12 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef CAM_CRE_HW_H
#define CAM_CRE_HW_H
#define CRE_HW_VER_1_0_0 0x10000000
#define CRE_HW_VER_1_1_0 0x10010000
#define CRE_DEV_CRE 0
#define CRE_DEV_MAX 1
@ -24,6 +26,8 @@
#define CRE_WAIT_BUS_RD_DONE 0x3
#define CRE_WAIT_IDLE_IRQ 0x4
#define CAM_CRE_HW_CFG_Q_MAX 30
struct cam_cre_top_reg {
void *base;
uint32_t offset;
@ -87,6 +91,7 @@ struct cam_cre_bus_rd_client_reg {
uint32_t misr_cfg_0;
uint32_t misr_cfg_1;
uint32_t misr_rd_val;
uint32_t system_cache_cfg;
uint32_t debug_status_cfg;
uint32_t debug_status_0;
uint32_t debug_status_1;
@ -109,6 +114,8 @@ struct cam_cre_bus_rd_reg {
uint32_t iso_cfg;
uint32_t iso_seed;
uint32_t test_bus_ctrl;
uint32_t cons_violation;
uint32_t ccif_violation;
uint32_t num_clients;
struct cam_cre_bus_rd_client_reg rd_clients[MAX_CRE_RD_CLIENTS];
@ -161,6 +168,7 @@ struct cam_cre_bus_rd_reg_val {
uint32_t rup_done;
uint32_t rd_buf_done;
uint32_t cons_violation;
uint32_t ccif_violation;
uint32_t static_prg;
uint32_t static_prg_mask;
uint32_t ica_en;
@ -190,8 +198,9 @@ struct cam_cre_bus_wr_client_reg {
uint32_t img_cfg_0;
uint32_t img_cfg_1;
uint32_t img_cfg_2;
uint32_t bw_limit;
uint32_t packer_cfg;
uint32_t bw_limit;
uint32_t system_cache_cfg;
uint32_t addr_cfg;
uint32_t debug_status_cfg;
uint32_t debug_status_0;

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef CAM_CRE_HW_100_H
@ -11,7 +12,7 @@
#define CRE_BUS_RD_TYPE 0x1
#define CRE_BUS_WR_TYPE 0x2
static struct cam_cre_top_reg top_reg = {
static struct cam_cre_top_reg cre100_top_reg = {
.hw_version = 0x000,
.hw_cap = 0x004,
.debug_0 = 0x080,
@ -30,7 +31,7 @@ static struct cam_cre_top_reg top_reg = {
.top_spare = 0x1FC,
};
struct cam_cre_top_reg_val top_reg_value = {
struct cam_cre_top_reg_val cre100_top_reg_value = {
.hw_version = 0x10000000,
.hw_cap = 0x4000,
.irq_mask = 0xf,
@ -46,7 +47,7 @@ struct cam_cre_top_reg_val top_reg_value = {
.hw_reset_cmd = 0x1,
};
struct cam_cre_bus_rd_reg bus_rd_reg = {
struct cam_cre_bus_rd_reg cre100_bus_rd_reg = {
.hw_version = 0x00,
.irq_mask = 0x04,
.irq_clear = 0x08,
@ -82,7 +83,7 @@ struct cam_cre_bus_rd_reg bus_rd_reg = {
},
};
struct cam_cre_bus_wr_reg_val bus_wr_reg_value = {
struct cam_cre_bus_wr_reg_val cre100_bus_wr_reg_value = {
.hw_version = 0x30000000,
.cgc_override = 0x1,
.irq_mask_0 = 0xd0000101,
@ -137,7 +138,7 @@ struct cam_cre_bus_wr_reg_val bus_wr_reg_value = {
},
};
struct cam_cre_bus_rd_reg_val bus_rd_reg_value = {
struct cam_cre_bus_rd_reg_val cre100_bus_rd_reg_value = {
.hw_version = 0x30000000,
.irq_mask = 0x1, /* INFO_CONS_VIOLATION */
.rd_buf_done = 0x4,
@ -183,7 +184,7 @@ struct cam_cre_bus_rd_reg_val bus_rd_reg_value = {
},
};
struct cam_cre_bus_wr_reg bus_wr_reg = {
struct cam_cre_bus_wr_reg cre100_bus_wr_reg = {
.hw_version = 0x00,
.cgc_override = 0x08,
.irq_mask_0 = 0x18,
@ -230,11 +231,11 @@ struct cam_cre_bus_wr_reg bus_wr_reg = {
};
static struct cam_cre_hw cre_hw_100 = {
.top_reg_offset = &top_reg,
.top_reg_val = &top_reg_value,
.bus_wr_reg_offset = &bus_wr_reg,
.bus_wr_reg_val = &bus_wr_reg_value,
.bus_rd_reg_offset = &bus_rd_reg,
.bus_rd_reg_val = &bus_rd_reg_value,
.top_reg_offset = &cre100_top_reg,
.top_reg_val = &cre100_top_reg_value,
.bus_wr_reg_offset = &cre100_bus_wr_reg,
.bus_wr_reg_val = &cre100_bus_wr_reg_value,
.bus_rd_reg_offset = &cre100_bus_rd_reg,
.bus_rd_reg_val = &cre100_bus_rd_reg_value,
};
#endif // CAM_CRE_HW_100_H

View File

@ -0,0 +1,243 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef CAM_CRE_HW_110_H
#define CAM_CRE_HW_110_H
#include "cre_hw.h"
#define CRE_BUS_RD_TYPE 0x1
#define CRE_BUS_WR_TYPE 0x2
static struct cam_cre_top_reg cre110_top_reg = {
.hw_version = 0x000,
.hw_cap = 0x004,
.debug_0 = 0x080,
.debug_1 = 0x084,
.debug_cfg = 0x0DC,
.testbus_ctrl = 0x1F4,
.scratch_0 = 0x1F8,
.irq_status = 0x00C,
.irq_mask = 0x010,
.irq_clear = 0x014,
.irq_set = 0x018,
.irq_cmd = 0x01C,
.reset_cmd = 0x008,
.core_clk_cfg_ctrl_0 = 0x020,
.core_clk_cfg_ctrl_1 = 0x024,
.top_spare = 0x1FC,
};
struct cam_cre_top_reg_val cre110_top_reg_value = {
.hw_version = 0x10010000,
.hw_cap = 0x4000,
.irq_mask = 0xf,
.irq_clear = 0xf,
.irq_set = 0xf,
.irq_cmd_set = 0xf,
.irq_cmd_clear = 0xf,
.idle = 0x8,
.fe_done = 0x4,
.we_done = 0x2,
.rst_done = 0x1,
.sw_reset_cmd = 0x2,
.hw_reset_cmd = 0x1,
};
struct cam_cre_bus_rd_reg cre110_bus_rd_reg = {
.hw_version = 0x00,
.irq_mask = 0x04,
.irq_clear = 0x08,
.irq_cmd = 0x0C,
.irq_status = 0x10,
.input_if_cmd = 0x14,
.irq_set = 0x18,
.misr_reset = 0x1C,
.security_cfg = 0x20,
.iso_cfg = 0x24,
.iso_seed = 0x28,
.test_bus_ctrl = 0x2C,
.cons_violation = 0x30,
.ccif_violation = 0x34,
.num_clients = 1,
.rd_clients[0] = {
.core_cfg = 0x50,
.ccif_meta_data = 0x54,
.img_addr = 0x58,
.rd_width = 0x5C,
.rd_height = 0x60,
.rd_stride = 0x64,
.unpacker_cfg = 0x68,
.latency_buf_allocation = 0x7C,
.misr_cfg_0 = 0x84,
.misr_cfg_1 = 0x88,
.misr_rd_val = 0x8C,
.system_cache_cfg = 0x90,
.read_buff_cfg = 0x94,
.addr_cfg = 0x98,
.debug_status_cfg = 0xA4,
.debug_status_0 = 0xA8,
.debug_status_1 = 0xAC,
.spare = 0x38,
},
};
struct cam_cre_bus_wr_reg_val cre110_bus_wr_reg_value = {
.hw_version = 0x40000000,
.cgc_override = 0x1,
.irq_mask_0 = 0xd0000101,
.irq_set_0 = 0xd0000101,
.irq_clear_0 = 0xd0000101,
.img_size_violation = 0x80000000,
.violation = 0x40000000,
.cons_violation = 0x10000000,
.comp_buf_done = 0x100,
.comp_rup_done = 0x1,
.irq_mask_1 = 0x1,
.irq_set_1 = 0x1,
.irq_clear_1 = 0x1,
.irq_status_1 = 0x1,
.irq_cmd_set = 0x10,
.irq_cmd_clear = 0x1,
.iso_en = 0x1,
.iso_en_mask = 0x1,
.misr_0_en = 0x1,
.misr_0_en_mask = 0x1,
.misr_0_samp_mode = 0x1,
.misr_0_samp_mode_mask = 0x10000,
.misr_0_id_mask = 0xff,
.misr_rd_misr_sel_mask = 0xf,
.misr_rd_word_sel_mask = 0x70,
.num_clients = 1,
.wr_clients[0] = {
.client_en = 0x1,
.client_en_mask = 0x1,
.client_en_shift = 0x0,
.auto_recovery_en = 0x1,
.auto_recovery_en_mask = 0x1,
.auto_recovery_en_shift = 0x4,
.mode_mask = 0x3,
.mode_shift = 0x10,
.width_mask = 0xffff,
.width_shift = 0x0,
.height_mask = 0xffff,
.height_shift = 0x10,
.x_init_mask = 0xff,
.stride_mask = 0xffffff,
.format_mask = 0xf,
.format_shift = 0x0,
.alignment_mask = 0x1,
.alignment_shift = 0x5,
.bw_limit_en = 0x1,
.bw_limit_en_mask = 0x1,
.bw_limit_counter_mask = 0x1fe,
.client_buf_done = 0x1,
.output_port_id = CAM_CRE_OUTPUT_IMAGE,
.wm_port_id = 0,
},
};
struct cam_cre_bus_rd_reg_val cre110_bus_rd_reg_value = {
.hw_version = 0x40000000,
.irq_mask = 0x80000001,
.rd_buf_done = 0x4,
.rup_done = 0x2,
.cons_violation = 0x1,
.ccif_violation = 0x80000000,
.irq_cmd_set = 0x10,
.irq_cmd_clear = 0x1,
.static_prg = 0x8,
.static_prg_mask = 0x8,
.ica_en = 0x1,
.ica_en_mask = 0x2,
.go_cmd = 0x1,
.go_cmd_mask = 0x1,
.irq_set = 0x7,
.irq_clear = 0x7,
.misr_reset = 0x1,
.security_cfg = 0x1,
.iso_bpp_select_mask = 0x60,
.iso_pattern_select_mask = 0x6,
.iso_en = 0x1,
.iso_en_mask = 0x1,
.num_clients = 1,
.rd_clients[0] = {
.client_en = 0x1,
.ai_en = 0x1,
.ai_en_mask = 0x1000,
.ai_en_shift = 0xc,
.pix_pattern_mask = 0xfc,
.pix_pattern_shift = 0x2,
.stripe_location_mask = 0x3,
.stripe_location_shift = 0x0,
.alignment_mask = 0x1,
.alignment_shift = 0x5,
.format_mask = 0x1f,
.format_shift = 0x0,
.latency_buf_size_mask = 0xffff,
.misr_cfg_en_mask = 0x4,
.misr_cfg_samp_mode_mask = 0x3,
.x_int_mask = 0xffff,
.byte_offset_mask = 0xff,
.input_port_id = CAM_CRE_INPUT_IMAGE,
.rm_port_id = 0x0,
},
};
struct cam_cre_bus_wr_reg cre110_bus_wr_reg = {
.hw_version = 0x00,
.cgc_override = 0x08,
.irq_mask_0 = 0x18,
.irq_mask_1 = 0x1C,
.irq_clear_0 = 0x20,
.irq_clear_1 = 0x24,
.irq_status_0 = 0x28,
.irq_status_1 = 0x2C,
.irq_cmd = 0x30,
.local_frame_header_cfg_0 = 0x4C,
.irq_set_0 = 0x50,
.irq_set_1 = 0x54,
.iso_cfg = 0x5C,
.violation_status = 0x64,
.image_size_violation_status = 0x70,
.perf_count_cfg_0 = 0x74,
.perf_count_cfg_1 = 0x78,
.perf_count_cfg_2 = 0x7C,
.perf_count_cfg_3 = 0x80,
.perf_count_val_0 = 0x94,
.perf_count_val_1 = 0x98,
.perf_count_val_2 = 0x9C,
.perf_count_val_3 = 0xA0,
.perf_count_status = 0xB4,
.misr_cfg_0 = 0xB8,
.misr_cfg_1 = 0xBC,
.misr_rd_sel = 0xC8,
.misr_reset = 0xCC,
.misr_val = 0xD0,
.wr_clients[0] = {
.client_cfg = 0x200,
.img_addr = 0x204,
.img_cfg_0 = 0x20C,
.img_cfg_1 = 0x210,
.img_cfg_2 = 0x214,
.packer_cfg = 0x218,
.bw_limit = 0x21C,
.system_cache_cfg = 0x268,
.addr_cfg = 0x270,
.debug_status_cfg = 0x288,
.debug_status_0 = 0x28c,
.debug_status_1 = 0x290,
},
};
static struct cam_cre_hw cre_hw_110 = {
.top_reg_offset = &cre110_top_reg,
.top_reg_val = &cre110_top_reg_value,
.bus_wr_reg_offset = &cre110_bus_wr_reg,
.bus_wr_reg_val = &cre110_bus_wr_reg_value,
.bus_rd_reg_offset = &cre110_bus_rd_reg,
.bus_rd_reg_val = &cre110_bus_rd_reg_value,
};
#endif // CAM_CRE_HW_110_H

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/platform_device.h>
#include <linux/delay.h>
@ -46,8 +47,8 @@ static int cam_cre_top_reset(struct cam_cre_hw *cre_hw_info,
cam_io_w_mb(top_reg_val->irq_mask,
cre_hw_info->top_reg_offset->base + top_reg->irq_mask);
/* CRE SW RESET */
cam_io_w_mb(top_reg_val->sw_reset_cmd,
/* CRE HW RESET */
cam_io_w_mb(top_reg_val->hw_reset_cmd,
cre_hw_info->top_reg_offset->base + top_reg->reset_cmd);
rc = wait_for_completion_timeout(

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
@ -107,13 +108,19 @@ err:
static void cam_custom_csid_component_unbind(struct device *dev,
struct device *master_dev, void *data)
{
struct cam_hw_intf *csid_hw_intf;
struct cam_hw_intf *csid_hw_intf = NULL;
struct cam_hw_info *csid_hw_info;
struct cam_ife_csid_core_info *core_info = NULL;
struct platform_device *pdev = to_platform_device(dev);
const struct of_device_id *match_dev = NULL;
csid_hw_intf = (struct cam_hw_intf *)platform_get_drvdata(pdev);
if (!csid_hw_intf) {
CAM_ERR(CAM_CUSTOM, "ERROR No data in csid_hw_intf");
return;
}
csid_hw_info = csid_hw_intf->hw_priv;
core_info = csid_hw_info->core_info;

View File

@ -1,7 +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.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "cam_fd_hw_core.h"
@ -368,6 +368,13 @@ static int cam_fd_hw_util_processcmd_prestart(struct cam_hw_info *fd_hw,
((struct cam_fd_soc_private *)soc_info->soc_private)->
regbase_index[CAM_FD_REG_CORE]);
if (mem_base == -1) {
CAM_ERR(CAM_FD, "failed to get mem_base, index: %d num_reg_map: %u",
((struct cam_fd_soc_private *)soc_info->soc_private)->
regbase_index[CAM_FD_REG_CORE], soc_info->num_reg_map);
return -EINVAL;
}
ctx_hw_private->cdm_ops->cdm_write_changebase(cmd_buf_addr, mem_base);
cmd_buf_addr += size;
available_size -= (size * 4);

View File

@ -1,7 +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.
* Copyright (c) 2022,2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/delay.h>
@ -249,10 +249,12 @@ const struct v4l2_subdev_internal_ops cam_icp_subdev_internal_ops = {
.close = cam_icp_subdev_close,
};
static inline void cam_icp_subdev_clean_up(uint32_t device_idx)
static inline int cam_icp_subdev_clean_up(uint32_t device_idx)
{
kfree(g_icp_dev[device_idx]);
g_icp_dev[device_idx] = NULL;
return 0;
}
static int cam_icp_component_bind(struct device *dev,
@ -292,6 +294,7 @@ static int cam_icp_component_bind(struct device *dev,
else
subdev_name = cam_icp_subdev_name_arr[device_idx];
mutex_lock(&g_dev_lock);
if (g_icp_dev[device_idx]) {
CAM_ERR(CAM_ICP,
@ -303,15 +306,15 @@ static int cam_icp_component_bind(struct device *dev,
}
mutex_unlock(&g_dev_lock);
icp_dev = kzalloc(sizeof(struct cam_icp_subdev), GFP_KERNEL);
if (!icp_dev) {
CAM_ERR(CAM_ICP,
"Unable to allocate memory for icp device:%s size:%llu",
pdev->name, sizeof(struct cam_icp_subdev));
return -ENOMEM;
}
icp_dev = kzalloc(sizeof(struct cam_icp_subdev), GFP_KERNEL);
if (!icp_dev) {
CAM_ERR(CAM_ICP,
"Unable to allocate memory for icp device:%s size:%llu",
pdev->name, sizeof(struct cam_icp_subdev));
return -ENOMEM;
}
mutex_lock(&g_dev_lock);
mutex_lock(&g_dev_lock);
g_icp_dev[device_idx] = icp_dev;
mutex_unlock(&g_dev_lock);
@ -371,6 +374,7 @@ ctx_fail:
cam_icp_context_deinit(&icp_dev->ctx_icp[i]);
cam_icp_hw_mgr_deinit(device_idx);
hw_init_fail:
cam_node_deinit(icp_dev->node);
cam_subdev_remove(&icp_dev->sd);
probe_fail:
cam_icp_subdev_clean_up(device_idx);

View File

@ -76,7 +76,7 @@ static void __iomem *hfi_iface_addr(struct hfi_info *hfi)
static inline int hfi_get_client_info(int client_handle, struct hfi_info **hfi)
{
int idx;
uint32_t idx;
idx = HFI_GET_INDEX(client_handle);
if (!IS_VALID_HFI_INDEX(idx)) {
@ -310,6 +310,7 @@ int hfi_read_message(int client_handle, uint32_t *pmsg, uint8_t q_id,
struct hfi_q_hdr *q;
uint32_t new_read_idx, size_in_words, word_diff, temp;
uint32_t *read_q, *read_ptr, *write_ptr;
uint32_t size_upper_bound = 0;
struct mutex *q_lock;
int rc = 0;
@ -351,6 +352,15 @@ int hfi_read_message(int client_handle, uint32_t *pmsg, uint8_t q_id,
q_tbl_ptr = (struct hfi_qtbl *)hfi->map.qtbl.kva;
q = &q_tbl_ptr->q_hdr[q_id];
if (q->qhdr_read_idx == q->qhdr_write_idx) {
CAM_DBG(CAM_HFI, "[%s] hfi hdl: %d Q not ready, state:%u, r idx:%u, w idx:%u",
hfi->client_name, client_handle, hfi->hfi_state,
q->qhdr_read_idx, q->qhdr_write_idx);
rc = -EIO;
goto err;
}
size_upper_bound = q->qhdr_q_size;
if (q_id == Q_MSG)
read_q = (uint32_t *)hfi->map.msg_q.kva;
else
@ -359,20 +369,15 @@ int hfi_read_message(int client_handle, uint32_t *pmsg, uint8_t q_id,
read_ptr = (uint32_t *)(read_q + q->qhdr_read_idx);
write_ptr = (uint32_t *)(read_q + q->qhdr_write_idx);
if (write_ptr >= read_ptr)
if (write_ptr > read_ptr)
size_in_words = write_ptr - read_ptr;
else {
word_diff = read_ptr - write_ptr;
size_in_words = q->qhdr_q_size - word_diff;
}
if (size_in_words == 0) {
CAM_DBG(CAM_HFI, "[%s] hfi hdl: %d Q is empty, state:%u, r idx:%u, w idx:%u",
hfi->client_name, client_handle, hfi->hfi_state,
q->qhdr_read_idx, q->qhdr_write_idx);
rc = -ENOMSG;
goto err;
} else if (size_in_words > q->qhdr_q_size) {
if ((size_in_words == 0) ||
(size_in_words > size_upper_bound)) {
CAM_ERR(CAM_HFI, "[%s] Invalid HFI message packet size - 0x%08x hfi hdl:%d",
hfi->client_name, size_in_words << BYTE_WORD_SHIFT,
client_handle);
@ -381,9 +386,13 @@ int hfi_read_message(int client_handle, uint32_t *pmsg, uint8_t q_id,
goto err;
}
/* size to read from q is bounded by size of buffer */
if (size_in_words > buf_words_size)
size_in_words = buf_words_size;
if (size_in_words > buf_words_size) {
CAM_ERR(CAM_HFI,
"[%s] hdl: %d Size of buffer: %u is smaller than size to read from queue: %u",
hfi->client_name, client_handle, buf_words_size, size_in_words);
rc = -EIO;
goto err;
}
new_read_idx = q->qhdr_read_idx + size_in_words;

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/of.h>
@ -473,6 +473,10 @@ int cam_bps_process_cmd(void *device_priv, uint32_t cmd_type,
case CAM_ICP_DEV_CMD_RESET:
rc = cam_bps_cmd_reset(soc_info, core_info);
break;
case CAM_ICP_DEV_CMD_DUMP_CLK: {
rc = cam_soc_util_dump_clk(soc_info);
break;
}
default:
CAM_ERR(CAM_ICP, "Invalid Cmd Type:%u", cmd_type);
rc = -EINVAL;

View File

@ -1,7 +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.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@ -205,6 +205,12 @@ static void cam_bps_component_unbind(struct device *dev,
CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name);
bps_dev_intf = platform_get_drvdata(pdev);
if (!bps_dev_intf) {
CAM_ERR(CAM_ICP, "Error No data in pdev");
return;
}
bps_dev = bps_dev_intf->hw_priv;
core_info = (struct cam_bps_device_core_info *)bps_dev->core_info;
cam_cpas_unregister_client(core_info->cpas_handle);

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/uaccess.h>
@ -2329,9 +2329,28 @@ static void cam_icp_mgr_compute_fw_avg_response_time(struct cam_icp_hw_ctx_data
(perf_stats->total_resp_time / perf_stats->total_requests));
}
static int cam_icp_mgr_dump_clk(struct cam_icp_hw_ctx_data *ctx_data)
{
uint32_t i;
struct cam_hw_intf *dev_intf = NULL;
for (i = 0; i < ctx_data->device_info->hw_dev_cnt; i++) {
dev_intf = ctx_data->device_info->dev_intf[i];
if (!dev_intf) {
CAM_ERR(CAM_ICP, "Device intf for %s[%u] is NULL",
ctx_data->device_info->dev_name, i);
return -EINVAL;
}
dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, CAM_ICP_DEV_CMD_DUMP_CLK,
NULL, 0);
}
return 0;
}
static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
{
int i;
int i, rc;
uint32_t idx, event_id;
uint64_t request_id;
struct cam_icp_hw_mgr *hw_mgr = NULL;
@ -2394,6 +2413,7 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
cam_icp_error_handle_id_to_type(ioconfig_ack->err_type),
request_id);
event_id = CAM_CTX_EVT_ID_ERROR;
rc = cam_icp_mgr_dump_clk(ctx_data);
}
buf_data.evt_param = cam_icp_handle_err_type_to_evt_param(ioconfig_ack->err_type);
} else {
@ -2491,8 +2511,6 @@ static int cam_icp_mgr_process_msg_frame_process(uint32_t *msg_ptr)
if (ioconfig_ack->err_type != CAMERAICP_SUCCESS) {
cam_icp_mgr_handle_frame_process(msg_ptr,
ICP_FRAME_PROCESS_FAILURE);
if (ioconfig_ack->err_type == CAMERAICP_EABORTED)
return 0;
return -EIO;
}
@ -2951,90 +2969,68 @@ static int cam_icp_mgr_process_fatal_error(
static void cam_icp_mgr_process_dbg_buf(struct cam_icp_hw_mgr *hw_mgr)
{
uint32_t *msg_ptr = NULL, *pkt_ptr = NULL;
struct hfi_msg_debug *dbg_msg = NULL;
uint32_t read_in_words, remain_len, pre_remain_len = 0;
uint32_t buf_word_size = ICP_DBG_BUF_SIZE_IN_WORDS;
struct hfi_msg_debug *dbg_msg;
uint32_t read_len, size_processed = 0, debug_lvl;
uint64_t timestamp = 0;
char *msg_data;
char *dbg_buf;
int rc = 0;
if (!hw_mgr) {
CAM_ERR(CAM_ICP, "Invalid data");
rc = hfi_read_message(hw_mgr->hfi_handle, hw_mgr->dbg_buf, Q_DBG,
ICP_DBG_BUF_SIZE_IN_WORDS, &read_len);
if (rc)
return;
}
do {
rc = hfi_read_message(hw_mgr->hfi_handle,
hw_mgr->dbg_buf + (pre_remain_len >> BYTE_WORD_SHIFT),
Q_DBG, buf_word_size, &read_in_words);
if (rc)
break;
remain_len = pre_remain_len + (read_in_words << BYTE_WORD_SHIFT);
pre_remain_len = 0;
msg_ptr = (uint32_t *)hw_mgr->dbg_buf;
buf_word_size = ICP_DBG_BUF_SIZE_IN_WORDS;
while (remain_len) {
pkt_ptr = msg_ptr;
if ((remain_len < sizeof(struct hfi_msg_debug)) ||
(remain_len < pkt_ptr[ICP_PACKET_SIZE])) {
/*
* MSG is broken into two parts, need to read from dbg q again
* to complete the msg and get the remaining packets. Copy
* the remain data to start of buffer and shift buffer ptr to
* after the remaining data ends to read from queue.
*/
memcpy(hw_mgr->dbg_buf, msg_ptr, remain_len);
pre_remain_len = remain_len;
buf_word_size -= (pre_remain_len >> BYTE_WORD_SHIFT);
break;
}
if (pkt_ptr[ICP_PACKET_TYPE] == HFI_MSG_SYS_DEBUG) {
dbg_msg = (struct hfi_msg_debug *)pkt_ptr;
msg_data = (char *)&dbg_msg->msg_data;
timestamp = ((((uint64_t)(dbg_msg->timestamp_hi) << 32)
| dbg_msg->timestamp_lo) >> 16);
trace_cam_icp_fw_dbg(msg_data, timestamp/2,
hw_mgr->hw_mgr_name);
if (!hw_mgr->icp_dbg_lvl)
CAM_INFO(CAM_ICP, "[%s]: FW_DBG:%s",
hw_mgr->hw_mgr_name, msg_data);
}
remain_len -= pkt_ptr[ICP_PACKET_SIZE];
if (remain_len > 0)
msg_ptr += (pkt_ptr[ICP_PACKET_SIZE] >> BYTE_WORD_SHIFT);
else
break;
msg_ptr = (uint32_t *)hw_mgr->dbg_buf;
debug_lvl = hw_mgr->icp_dbg_lvl;
while (true) {
pkt_ptr = msg_ptr;
if (pkt_ptr[ICP_PACKET_TYPE] == HFI_MSG_SYS_DEBUG) {
dbg_msg = (struct hfi_msg_debug *)pkt_ptr;
dbg_buf = (char *)&dbg_msg->msg_data;
timestamp = ((((uint64_t)(dbg_msg->timestamp_hi) << 32)
| dbg_msg->timestamp_lo) >> 16);
trace_cam_icp_fw_dbg(dbg_buf, timestamp/2,
hw_mgr->hw_mgr_name);
if (!debug_lvl)
CAM_INFO(CAM_ICP, "[%s]: FW_DBG:%s",
hw_mgr->hw_mgr_name, dbg_buf);
}
/* Repeat reading if drain buffer is insufficient to read all MSGs at once */
} while (read_in_words >= buf_word_size);
size_processed += (pkt_ptr[ICP_PACKET_SIZE] >>
BYTE_WORD_SHIFT);
if (size_processed >= read_len)
return;
msg_ptr += (pkt_ptr[ICP_PACKET_SIZE] >>
BYTE_WORD_SHIFT);
}
}
static int cam_icp_process_msg_pkt_type(
struct cam_icp_hw_mgr *hw_mgr,
uint32_t *msg_ptr)
uint32_t *msg_ptr,
uint32_t *msg_processed_len)
{
int rc = 0;
int size_processed = 0;
switch (msg_ptr[ICP_PACKET_TYPE]) {
case HFI_MSG_SYS_INIT_DONE:
CAM_DBG(CAM_ICP, "[%s] received SYS_INIT_DONE", hw_mgr->hw_mgr_name);
complete(&hw_mgr->icp_complete);
size_processed = (
(struct hfi_msg_init_done *)msg_ptr)->size;
break;
case HFI_MSG_SYS_PC_PREP_DONE:
CAM_DBG(CAM_ICP, "[%s] HFI_MSG_SYS_PC_PREP_DONE is received\n",
hw_mgr->hw_mgr_name);
complete(&hw_mgr->icp_complete);
size_processed = sizeof(struct hfi_msg_pc_prep_done);
break;
case HFI_MSG_SYS_PING_ACK:
CAM_DBG(CAM_ICP, "[%s] received SYS_PING_ACK", hw_mgr->hw_mgr_name);
rc = cam_icp_mgr_process_msg_ping_ack(msg_ptr);
size_processed = sizeof(struct hfi_msg_ping_ack);
break;
case HFI_MSG_IPEBPS_CREATE_HANDLE_ACK:
@ -3042,27 +3038,36 @@ static int cam_icp_process_msg_pkt_type(
CAM_DBG(CAM_ICP, "[%s] received IPE/BPS/OFE CREATE_HANDLE_ACK",
hw_mgr->hw_mgr_name);
rc = cam_icp_mgr_process_msg_create_handle(msg_ptr);
size_processed = sizeof(struct hfi_msg_create_handle_ack);
break;
case HFI_MSG_IPEBPS_ASYNC_COMMAND_INDIRECT_ACK:
CAM_DBG(CAM_ICP, "[%s] received IPE/BPS ASYNC_INDIRECT_ACK",
hw_mgr->hw_mgr_name);
rc = cam_icp_mgr_process_ipebps_indirect_ack_msg(msg_ptr);
size_processed = (
(struct hfi_msg_dev_async_ack *)msg_ptr)->size;
break;
case HFI_MSG_OFE_ASYNC_COMMAND_ACK:
CAM_DBG(CAM_ICP, "[%s] received OFE ASYNC COMMAND ACK",
hw_mgr->hw_mgr_name);
rc = cam_icp_mgr_process_ofe_indirect_ack_msg(msg_ptr);
size_processed = (
(struct hfi_msg_dev_async_ack *)msg_ptr)->size;
break;
case HFI_MSG_IPEBPS_ASYNC_COMMAND_DIRECT_ACK:
CAM_DBG(CAM_ICP, "[%s] received ASYNC_DIRECT_ACK", hw_mgr->hw_mgr_name);
rc = cam_icp_mgr_process_direct_ack_msg(msg_ptr);
size_processed = (
(struct hfi_msg_dev_async_ack *)msg_ptr)->size;
break;
case HFI_MSG_EVENT_NOTIFY:
CAM_DBG(CAM_ICP, "[%s] received EVENT_NOTIFY", hw_mgr->hw_mgr_name);
size_processed = (
(struct hfi_msg_event_notify *)msg_ptr)->size;
rc = cam_icp_mgr_process_fatal_error(hw_mgr, msg_ptr);
if (rc)
CAM_ERR(CAM_ICP, "[%s] failed in processing evt notify",
@ -3072,133 +3077,24 @@ static int cam_icp_process_msg_pkt_type(
case HFI_MSG_DBG_SYNX_TEST:
CAM_DBG(CAM_ICP, "received DBG_SYNX_TEST");
size_processed = sizeof(struct hfi_cmd_synx_test_payload);
complete(&hw_mgr->icp_complete);
break;
default:
CAM_ERR(CAM_ICP, "[%s] invalid msg : %u",
hw_mgr->hw_mgr_name, msg_ptr[ICP_PACKET_TYPE]);
rc = -EINVAL;
}
*msg_processed_len = size_processed;
return rc;
}
static int cam_icp_get_msg_pkt_size(
struct cam_icp_hw_mgr *hw_mgr,
uint32_t *msg_ptr,
uint32_t *pkt_size)
static int32_t cam_icp_mgr_process_msg(void *priv, void *data)
{
switch (msg_ptr[ICP_PACKET_TYPE]) {
case HFI_MSG_SYS_INIT_DONE:
*pkt_size = (
(struct hfi_msg_init_done *)msg_ptr)->size;
break;
case HFI_MSG_SYS_PC_PREP_DONE:
*pkt_size = sizeof(struct hfi_msg_pc_prep_done);
break;
case HFI_MSG_SYS_PING_ACK:
*pkt_size = sizeof(struct hfi_msg_ping_ack);
break;
case HFI_MSG_IPEBPS_CREATE_HANDLE_ACK:
case HFI_MSG_OFE_CREATE_HANDLE_ACK:
*pkt_size = sizeof(struct hfi_msg_create_handle_ack);
break;
case HFI_MSG_IPEBPS_ASYNC_COMMAND_INDIRECT_ACK:
*pkt_size = (
(struct hfi_msg_dev_async_ack *)msg_ptr)->size;
break;
case HFI_MSG_OFE_ASYNC_COMMAND_ACK:
*pkt_size = (
(struct hfi_msg_dev_async_ack *)msg_ptr)->size;
break;
case HFI_MSG_IPEBPS_ASYNC_COMMAND_DIRECT_ACK:
*pkt_size = (
(struct hfi_msg_dev_async_ack *)msg_ptr)->size;
break;
case HFI_MSG_EVENT_NOTIFY:
*pkt_size = (
(struct hfi_msg_event_notify *)msg_ptr)->size;
break;
case HFI_MSG_DBG_SYNX_TEST:
*pkt_size = sizeof(struct hfi_cmd_synx_test_payload);
break;
default:
CAM_ERR(CAM_ICP, "[%s] invalid msg : %u",
hw_mgr->hw_mgr_name, msg_ptr[ICP_PACKET_TYPE]);
return -EINVAL;
}
return 0;
}
static int cam_icp_mgr_process_msg(struct cam_icp_hw_mgr *hw_mgr)
{
uint32_t msg_pkt_size, read_in_words;
uint32_t remain_len, pre_remain_len = 0;
uint32_t read_len, msg_processed_len;
uint32_t *msg_ptr = NULL;
uint32_t buf_word_size = ICP_MSG_BUF_SIZE_IN_WORDS;
int rc = 0;
if (!hw_mgr) {
CAM_ERR(CAM_ICP, "Invalid data");
return -EINVAL;
}
do {
rc = hfi_read_message(hw_mgr->hfi_handle,
hw_mgr->msg_buf + (pre_remain_len >> BYTE_WORD_SHIFT),
Q_MSG, buf_word_size, &read_in_words);
if (rc) {
if (rc != -ENOMSG)
CAM_DBG(CAM_ICP, "Unable to read msg q rc %d", rc);
break;
}
remain_len = pre_remain_len + (read_in_words << BYTE_WORD_SHIFT);
pre_remain_len = 0;
msg_ptr = (uint32_t *)hw_mgr->msg_buf;
buf_word_size = ICP_MSG_BUF_SIZE_IN_WORDS;
while (remain_len) {
rc = cam_icp_get_msg_pkt_size(hw_mgr, msg_ptr, &msg_pkt_size);
if (rc) {
CAM_ERR(CAM_ICP, "Failed to get pkt size");
break;
}
if (remain_len < msg_pkt_size) {
/*
* MSG is broken into two parts, need to read from msg q again
* to complete the msg and get the remaining packets. Copy
* the remain data to start of buffer and shift buffer ptr to
* after the remaining data ends to read from queue.
*/
memcpy(hw_mgr->msg_buf, msg_ptr, remain_len);
pre_remain_len = remain_len;
buf_word_size -= (pre_remain_len >> BYTE_WORD_SHIFT);
break;
}
rc = cam_icp_process_msg_pkt_type(hw_mgr, msg_ptr);
if (rc)
CAM_ERR(CAM_ICP, "Failed to process MSG");
remain_len -= msg_pkt_size;
if (remain_len > 0) {
msg_ptr += (msg_pkt_size >> BYTE_WORD_SHIFT);
msg_pkt_size = 0;
} else
break;
}
/* Repeat reading if drain buffer is insufficient to read all MSGs at once */
} while (read_in_words >= buf_word_size);
return rc;
}
static int32_t cam_icp_mgr_process_cb(void *priv, void *data)
{ struct hfi_msg_work_data *task_data;
struct hfi_msg_work_data *task_data;
struct cam_icp_hw_mgr *hw_mgr;
int rc = 0;
@ -3210,9 +3106,33 @@ static int32_t cam_icp_mgr_process_cb(void *priv, void *data)
task_data = data;
hw_mgr = priv;
rc = cam_icp_mgr_process_msg(hw_mgr);
if (rc && (rc != -ENOMSG))
CAM_ERR(CAM_ICP, "Failed to process MSG");
rc = hfi_read_message(hw_mgr->hfi_handle, hw_mgr->msg_buf, Q_MSG,
ICP_MSG_BUF_SIZE_IN_WORDS, &read_len);
if (rc) {
CAM_DBG(CAM_ICP, "Unable to read msg q rc %d", rc);
} else {
read_len = read_len << BYTE_WORD_SHIFT;
msg_ptr = (uint32_t *)hw_mgr->msg_buf;
while (true) {
cam_icp_process_msg_pkt_type(hw_mgr, msg_ptr,
&msg_processed_len);
if (!msg_processed_len) {
CAM_ERR(CAM_ICP, "Failed to read");
rc = -EINVAL;
break;
}
read_len -= msg_processed_len;
if (read_len > 0) {
msg_ptr += (msg_processed_len >>
BYTE_WORD_SHIFT);
msg_processed_len = 0;
} else {
break;
}
}
}
cam_icp_mgr_process_dbg_buf(hw_mgr);
@ -3250,7 +3170,7 @@ static int32_t cam_icp_hw_mgr_cb(void *data, bool recover)
task_data->data = hw_mgr;
task_data->recover = recover;
task_data->type = ICP_WORKQ_TASK_MSG_TYPE;
task->process_cb = cam_icp_mgr_process_cb;
task->process_cb = cam_icp_mgr_process_msg;
rc = cam_req_mgr_workq_enqueue_task(task, hw_mgr,
CRM_TASK_PRIORITY_0);
spin_unlock_irqrestore(&hw_mgr->hw_mgr_lock, flags);
@ -4728,7 +4648,7 @@ static int cam_icp_mgr_device_init(struct cam_icp_hw_mgr *hw_mgr)
hw_dev_deinit:
for (; i >= 0; i--) {
dev_info = &hw_mgr->dev_info[i];
j = (j == -1) ? dev_info->hw_dev_cnt : (j - 1);
j = (j == -1) ? (dev_info->hw_dev_cnt - 1) : (j - 1);
for (; j >= 0; j--) {
dev_intf = dev_info->dev_intf[j];
dev_intf->hw_ops.deinit(dev_intf->hw_priv, NULL, 0);
@ -5473,7 +5393,8 @@ static bool cam_icp_mgr_is_valid_outconfig(struct cam_packet *packet)
packet->io_configs_offset/4);
for (i = 0 ; i < packet->num_io_configs; i++)
if (io_cfg_ptr[i].direction == CAM_BUF_OUTPUT)
if ((io_cfg_ptr[i].direction == CAM_BUF_OUTPUT) ||
(io_cfg_ptr[i].direction == CAM_BUF_IN_OUT))
num_out_map_entries++;
if (num_out_map_entries <= CAM_MAX_OUT_RES) {
@ -5630,13 +5551,20 @@ static int cam_icp_mgr_process_io_cfg(struct cam_icp_hw_mgr *hw_mgr,
if (io_cfg_ptr[i].direction == CAM_BUF_INPUT) {
sync_in_obj[j++] = io_cfg_ptr[i].fence;
prepare_args->num_in_map_entries++;
} else {
} else if ((io_cfg_ptr[i].direction == CAM_BUF_OUTPUT) ||
(io_cfg_ptr[i].direction == CAM_BUF_IN_OUT)) {
prepare_args->out_map_entries[k].sync_id =
io_cfg_ptr[i].fence;
prepare_args->out_map_entries[k].resource_handle =
io_cfg_ptr[i].resource_type;
k++;
prepare_args->num_out_map_entries++;
} else {
CAM_ERR(CAM_ICP, "dir: %d, max_out:%u, out %u",
io_cfg_ptr[i].direction,
prepare_args->max_out_map_entries,
prepare_args->num_out_map_entries);
return -EINVAL;
}
CAM_DBG(CAM_REQ,
@ -5864,6 +5792,11 @@ static int cam_icp_packet_generic_blob_handler(void *user_data,
switch (blob_type) {
case CAM_ICP_CMD_GENERIC_BLOB_CLK:
if (index < 0) {
CAM_ERR(CAM_ICP, "Invalid index %d", index);
return -EINVAL;
}
CAM_WARN_RATE_LIMIT_CUSTOM(CAM_PERF, 300, 1,
"Using deprecated blob type GENERIC_BLOB_CLK");
if (blob_size != sizeof(struct cam_icp_clk_bw_request)) {
@ -5895,6 +5828,11 @@ static int cam_icp_packet_generic_blob_handler(void *user_data,
break;
case CAM_ICP_CMD_GENERIC_BLOB_CLK_V2:
if (index < 0) {
CAM_ERR(CAM_ICP, "Invalid index %d", index);
return -EINVAL;
}
if (blob_size < sizeof(struct cam_icp_clk_bw_request_v2)) {
CAM_ERR(CAM_ICP, "%s: Mismatch blob size %d expected %lu",
ctx_data->ctx_id_string,
@ -6042,6 +5980,11 @@ static int cam_icp_packet_generic_blob_handler(void *user_data,
break;
case CAM_ICP_CMD_GENERIC_BLOB_PRESIL_HANGDUMP:
if (index < 0) {
CAM_ERR(CAM_ICP, "Invalid index %d", index);
return -EINVAL;
}
if (cam_presil_mode_enabled()) {
cmd_mem_regions = (struct cam_cmd_mem_regions *)blob_data;
if (cmd_mem_regions->num_regions <= 0) {
@ -6261,10 +6204,10 @@ static int cam_icp_mgr_prepare_hw_update(void *hw_mgr_priv,
packet = prepare_args->packet;
if (cam_packet_util_validate_packet(packet, prepare_args->remain_len)) {
mutex_unlock(&ctx_data->ctx_mutex);
return -EINVAL;
}
if (cam_packet_util_validate_packet(packet, prepare_args->remain_len)) {
mutex_unlock(&ctx_data->ctx_mutex);
return -EINVAL;
}
rc = cam_icp_mgr_pkt_validation(ctx_data, packet);
if (rc) {
@ -6653,7 +6596,7 @@ static int cam_icp_mgr_hw_dump(void *hw_priv, void *hw_dump_args)
*mgr_addr++ = hw_mgr->icp_booted;
*mgr_addr++ = hw_mgr->icp_resumed;
*mgr_addr++ = hw_mgr->disable_ubwc_comp;
memcpy(mgr_addr, &hw_mgr->dev_info, sizeof(hw_mgr->dev_info));
memcpy(mgr_addr, &hw_mgr->dev_info, sizeof(struct cam_icp_hw_device_info));
mgr_addr += sizeof(hw_mgr->dev_info);
*mgr_addr++ = hw_mgr->icp_pc_flag;
*mgr_addr++ = hw_mgr->dev_pc_flag;
@ -7686,7 +7629,7 @@ static int cam_icp_mgr_alloc_devs(struct device_node *np, struct cam_icp_hw_mgr
struct cam_hw_intf **alloc_devices = NULL;
int rc, i;
enum cam_icp_hw_type icp_hw_type;
uint32_t num = 0, num_cpas_mask = 0, cpas_hw_mask[MAX_HW_CAPS_MASK] = {0};
uint32_t num = 0, mask = 0, num_cpas_mask = 0, cpas_hw_mask[MAX_HW_CAPS_MASK] = {0};
rc = cam_icp_alloc_processor_devs(np, &icp_hw_type, &alloc_devices, hw_dev_cnt);
if (rc) {
@ -7715,6 +7658,11 @@ static int cam_icp_mgr_alloc_devs(struct device_node *np, struct cam_icp_hw_mgr
devices[icp_hw_type] = alloc_devices;
hw_mgr->hw_cap_mask |= BIT(icp_hw_type);
num_cpas_mask = max(num_cpas_mask, (uint32_t)(ICP_CAPS_MASK_IDX + 1));
rc = of_property_read_u32(np, "icp-mask", &mask);
if (!rc)
icp_cpas_mask[hw_mgr->hw_mgr_id] = mask;
cpas_hw_mask[ICP_CAPS_MASK_IDX] |= icp_cpas_mask[hw_mgr->hw_mgr_id];
rc = of_property_read_u32(np, "num-ipe", &num);
@ -7730,7 +7678,12 @@ static int cam_icp_mgr_alloc_devs(struct device_node *np, struct cam_icp_hw_mgr
devices[CAM_ICP_DEV_IPE] = alloc_devices;
hw_mgr->hw_cap_mask |= BIT(CAM_ICP_DEV_IPE);
num_cpas_mask = max(num_cpas_mask, (uint32_t)(IPE_CAPS_MASK_IDX + 1));
cpas_hw_mask[IPE_CAPS_MASK_IDX] |= CPAS_TITAN_IPE0_CAP_BIT;
rc = of_property_read_u32(np, "ipe0-mask", &mask);
if (!rc)
cpas_hw_mask[IPE_CAPS_MASK_IDX] |= mask;
else
cpas_hw_mask[IPE_CAPS_MASK_IDX] |= CPAS_TITAN_IPE0_CAP_BIT;
}
rc = of_property_read_u32(np, "num-bps", &num);
@ -7746,7 +7699,12 @@ static int cam_icp_mgr_alloc_devs(struct device_node *np, struct cam_icp_hw_mgr
devices[CAM_ICP_DEV_BPS] = alloc_devices;
hw_mgr->hw_cap_mask |= BIT(CAM_ICP_DEV_BPS);
num_cpas_mask = max(num_cpas_mask, (uint32_t)(BPS_CAPS_MASK_IDX + 1));
cpas_hw_mask[BPS_CAPS_MASK_IDX] |= CPAS_BPS_BIT;
rc = of_property_read_u32(np, "bps-mask", &mask);
if (!rc)
cpas_hw_mask[BPS_CAPS_MASK_IDX] |= mask;
else
cpas_hw_mask[BPS_CAPS_MASK_IDX] |= CPAS_BPS_BIT;
}
rc = of_property_read_u32(np, "num-ofe", &num);
@ -8205,7 +8163,7 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
memset(hw_mgr_intf, 0, sizeof(struct cam_hw_mgr_intf));
hw_mgr = vzalloc(sizeof(struct cam_icp_hw_mgr));
hw_mgr = kzalloc(sizeof(struct cam_icp_hw_mgr), GFP_KERNEL);
if (!hw_mgr)
return -ENOMEM;
@ -8354,7 +8312,7 @@ destroy_mutex:
kfree(hw_mgr->ctx_data[i].hfi_frame_process.hangdump_mem_regions);
}
free_hw_mgr:
vfree(hw_mgr);
kfree(hw_mgr);
return rc;
}
@ -8384,6 +8342,6 @@ void cam_icp_hw_mgr_deinit(int device_idx)
kfree(hw_mgr->ctx_data[i].hfi_frame_process.hangdump_mem_regions);
}
vfree(hw_mgr);
kfree(hw_mgr);
g_icp_hw_mgr[device_idx] = NULL;
}

View File

@ -44,7 +44,7 @@
/* size of buffer to drain from msg/dbq queue */
#define ICP_MSG_BUF_SIZE_IN_WORDS 512
#define ICP_DBG_BUF_SIZE_IN_WORDS 5120
#define ICP_DBG_BUF_SIZE_IN_WORDS 25600
#define ICP_OVER_CLK_THRESHOLD 5
#define ICP_TWO_DEV_BW_SHARE_RATIO 2

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef CAM_ICP_HW_INTF_H
@ -55,6 +55,7 @@ enum cam_icp_dev_cmd_type {
CAM_ICP_DEV_CMD_UPDATE_CLK,
CAM_ICP_DEV_CMD_DISABLE_CLK,
CAM_ICP_DEV_CMD_RESET,
CAM_ICP_DEV_CMD_DUMP_CLK,
CAM_ICP_DEV_CMD_MAX
};

View File

@ -195,14 +195,8 @@ int cam_icp_proc_mini_dump(struct cam_icp_hw_dump_args *args,
static int cam_icp_proc_validate_ubwc_cfg(struct cam_icp_ubwc_cfg *ubwc_cfg,
uint32_t ubwc_cfg_dev_mask)
{
uint32_t found_ubwc_cfg_mask;
uint32_t found_ubwc_cfg_mask = ubwc_cfg->found_ubwc_cfg_mask;
if (!ubwc_cfg) {
CAM_ERR(CAM_ICP, "ubwc_cfg is NULL");
return -ENODATA;
}
found_ubwc_cfg_mask = ubwc_cfg->found_ubwc_cfg_mask;
if ((ubwc_cfg_dev_mask & BIT(CAM_ICP_DEV_IPE)) &&
!(found_ubwc_cfg_mask & BIT(CAM_ICP_DEV_IPE))) {
CAM_ERR(CAM_ICP, "IPE does not have UBWC cfg value");

View File

@ -1,7 +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.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@ -212,6 +212,12 @@ static void cam_icp_v1_component_unbind(struct device *dev,
struct platform_device *pdev = to_platform_device(dev);
icp_v1_dev_intf = platform_get_drvdata(pdev);
if (!icp_v1_dev_intf) {
CAM_ERR(CAM_ICP, "Error No data in pdev");
return;
}
icp_v1_dev = icp_v1_dev_intf->hw_priv;
core_info = (struct cam_icp_v1_device_core_info *)icp_v1_dev->core_info;

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@ -165,8 +165,17 @@ static void cam_icp_v2_component_unbind(struct device *dev,
struct device *mdev, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
struct cam_hw_intf *icp_v2_intf = platform_get_drvdata(pdev);
struct cam_hw_info *icp_v2_info = icp_v2_intf->hw_priv;
struct cam_hw_intf *icp_v2_intf = NULL;
struct cam_hw_info *icp_v2_info = NULL;
icp_v2_intf = platform_get_drvdata(pdev);
if (!icp_v2_intf) {
CAM_ERR(CAM_ICP, "Error No data in pdev");
return;
}
icp_v2_info = icp_v2_intf->hw_priv;
cam_icp_v2_cpas_unregister(icp_v2_intf);
cam_icp_soc_resources_deinit(&icp_v2_info->soc_info);

View File

@ -21,7 +21,7 @@
#define CAM_ICP_BW_BYTES_VOTE 40000000
#define CAM_ICP_CTX_MAX 64
#define CAM_ICP_CTX_MAX 54
#define CPAS_IPE1_BIT 0x2000

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/of.h>
@ -465,6 +465,10 @@ int cam_ipe_process_cmd(void *device_priv, uint32_t cmd_type,
case CAM_ICP_DEV_CMD_RESET:
rc = cam_ipe_cmd_reset(soc_info, core_info);
break;
case CAM_ICP_DEV_CMD_DUMP_CLK: {
rc = cam_soc_util_dump_clk(soc_info);
break;
}
default:
CAM_ERR(CAM_ICP, "Invalid Cmd Type:%u", cmd_type);
rc = -EINVAL;

View File

@ -188,6 +188,12 @@ static void cam_ipe_component_unbind(struct device *dev,
CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name);
ipe_dev_intf = platform_get_drvdata(pdev);
if (!ipe_dev_intf) {
CAM_ERR(CAM_ICP, "Error No data in pdev");
return;
}
ipe_dev = ipe_dev_intf->hw_priv;
core_info = (struct cam_ipe_device_core_info *)ipe_dev->core_info;
cam_cpas_unregister_client(core_info->cpas_handle);

View File

@ -184,6 +184,12 @@ static void cam_ofe_component_unbind(struct device *dev,
CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name);
ofe_dev_intf = platform_get_drvdata(pdev);
if (!ofe_dev_intf) {
CAM_ERR(CAM_ICP, "Error No data in pdev");
return;
}
ofe_dev = ofe_dev_intf->hw_priv;
core_info = (struct cam_ofe_device_core_info *)ofe_dev->core_info;
cam_cpas_unregister_client(core_info->cpas_handle);

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_ISP_CONTEXT_H_
@ -105,6 +105,7 @@ enum cam_isp_ctx_event {
CAM_ISP_CTX_EVENT_EPOCH,
CAM_ISP_CTX_EVENT_RUP,
CAM_ISP_CTX_EVENT_BUFDONE,
CAM_ISP_CTX_EVENT_SHUTTER,
CAM_ISP_CTX_EVENT_MAX
};
@ -198,7 +199,7 @@ struct cam_isp_ctx_req {
uint32_t num_fence_map_in;
uint32_t num_acked;
uint32_t num_deferred_acks;
uint32_t deferred_fence_map_index[CAM_ISP_CTX_RES_MAX];
uint32_t *deferred_fence_map_index;
int32_t bubble_report;
struct cam_isp_prepare_hw_update_data hw_update_data;
enum cam_hw_config_reapply_type reapply_type;
@ -241,6 +242,14 @@ struct cam_isp_context_req_id_info {
int64_t last_bufdone_req_id;
};
struct shutter_event {
uint64_t frame_id;
uint64_t req_id;
uint32_t status;
ktime_t boot_ts;
ktime_t sof_ts;
};
/**
*
*
@ -252,8 +261,12 @@ struct cam_isp_context_req_id_info {
*
*/
struct cam_isp_context_event_record {
uint64_t req_id;
ktime_t timestamp;
uint64_t req_id;
ktime_t timestamp;
int event_type;
union event {
struct shutter_event shutter_event;
} event;
};
/**
@ -407,6 +420,9 @@ struct cam_isp_fcg_prediction_tracker {
* @hw_idx: Hardware ID
* @fcg_tracker: FCG prediction tracker containing number of previously skipped
* frames and indicates which prediction should be used
* @is_shdr: true, if usecase is sdhr
* @is_shdr_master: Flag to indicate master context in shdr usecase
* @last_num_exp: Last num of exposure
*
*/
struct cam_isp_context {
@ -471,6 +487,9 @@ struct cam_isp_context {
bool mode_switch_en;
uint32_t hw_idx;
struct cam_isp_fcg_prediction_tracker fcg_tracker;
bool is_tfe_shdr;
bool is_shdr_master;
uint32_t last_num_exp;
};
/**

View File

@ -73,6 +73,22 @@ static void cam_isp_dev_iommu_fault_handler(struct cam_smmu_pf_info *pf_smmu_inf
}
}
static void cam_isp_subdev_handle_message(
struct v4l2_subdev *sd,
enum cam_subdev_message_type_t message_type,
void *data)
{
int i, rc = 0;
struct cam_node *node = v4l2_get_subdevdata(sd);
CAM_DBG(CAM_ISP, "node name %s", node->name);
for (i = 0; i < node->ctx_size; i++) {
rc = cam_context_handle_message(&(node->ctx_list[i]), message_type, data);
if (rc)
CAM_ERR(CAM_ISP, "Failed to handle message for %s", node->name);
}
}
static const struct of_device_id cam_isp_dt_match[] = {
{
.compatible = "qcom,cam-isp"
@ -170,6 +186,7 @@ static int cam_isp_dev_component_bind(struct device *dev,
} else if (strnstr(compat_str, "tfe", strlen(compat_str))) {
rc = cam_subdev_probe(&g_isp_dev.sd, pdev, CAM_ISP_DEV_NAME,
CAM_TFE_DEVICE_TYPE);
g_isp_dev.sd.msg_cb = cam_isp_subdev_handle_message;
g_isp_dev.isp_device_type = CAM_TFE_DEVICE_TYPE;
g_isp_dev.max_context = CAM_TFE_CTX_MAX;
} else {
@ -185,19 +202,22 @@ static int cam_isp_dev_component_bind(struct device *dev,
node = (struct cam_node *) g_isp_dev.sd.token;
memset(&hw_mgr_intf, 0, sizeof(hw_mgr_intf));
g_isp_dev.ctx = vzalloc(g_isp_dev.max_context * sizeof(struct cam_context));
g_isp_dev.ctx = kcalloc(g_isp_dev.max_context,
sizeof(struct cam_context),
GFP_KERNEL);
if (!g_isp_dev.ctx) {
CAM_ERR(CAM_ISP,
"Mem Allocation failed for ISP base context");
goto unregister;
}
g_isp_dev.ctx_isp = vzalloc(
g_isp_dev.max_context * sizeof(struct cam_isp_context));
g_isp_dev.ctx_isp = kcalloc(g_isp_dev.max_context,
sizeof(struct cam_isp_context),
GFP_KERNEL);
if (!g_isp_dev.ctx_isp) {
CAM_ERR(CAM_ISP,
"Mem Allocation failed for Isp private context");
vfree(g_isp_dev.ctx);
kfree(g_isp_dev.ctx);
g_isp_dev.ctx = NULL;
goto unregister;
}
@ -222,8 +242,12 @@ static int cam_isp_dev_component_bind(struct device *dev,
}
}
cam_common_register_evt_inject_cb(cam_isp_dev_evt_inject_cb,
CAM_COMMON_EVT_INJECT_HW_ISP);
if (g_isp_dev.isp_device_type == CAM_IFE_DEVICE_TYPE)
cam_common_register_evt_inject_cb(cam_isp_dev_evt_inject_cb,
CAM_COMMON_EVT_INJECT_HW_IFE);
else
cam_common_register_evt_inject_cb(cam_isp_dev_evt_inject_cb,
CAM_COMMON_EVT_INJECT_HW_TFE);
rc = cam_node_init(node, &hw_mgr_intf, g_isp_dev.ctx,
g_isp_dev.max_context, CAM_ISP_DEV_NAME);
@ -244,9 +268,9 @@ static int cam_isp_dev_component_bind(struct device *dev,
return 0;
free_mem:
vfree(g_isp_dev.ctx);
kfree(g_isp_dev.ctx);
g_isp_dev.ctx = NULL;
vfree(g_isp_dev.ctx_isp);
kfree(g_isp_dev.ctx_isp);
g_isp_dev.ctx_isp = NULL;
unregister:
@ -275,9 +299,9 @@ static void cam_isp_dev_component_unbind(struct device *dev,
i);
}
vfree(g_isp_dev.ctx);
kfree(g_isp_dev.ctx);
g_isp_dev.ctx = NULL;
vfree(g_isp_dev.ctx_isp);
kfree(g_isp_dev.ctx_isp);
g_isp_dev.ctx_isp = NULL;
rc = cam_subdev_remove(&g_isp_dev.sd);

View File

@ -64,7 +64,7 @@ enum cam_ife_ctx_master_type {
* @rx_capture_debug_set: If rx capture debug is set by user
* @disable_isp_drv: Disable ISP DRV config
* @enable_presil_reg_dump: Enable per req regdump in presil
*
* @enable_cdm_cmd_check: Enable invalid command check in cmd_buf
*/
struct cam_ife_hw_mgr_debug {
struct dentry *dentry;
@ -87,6 +87,7 @@ struct cam_ife_hw_mgr_debug {
bool rx_capture_debug_set;
bool disable_isp_drv;
bool enable_presil_reg_dump;
bool enable_cdm_cmd_check;
#if defined(CONFIG_SAMSUNG_DEBUG_SENSOR_TIMING)
uint32_t csid_dbg_fps;
uint32_t vfe_dbg_fps;

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_TFE_HW_MGR_H_
@ -19,7 +19,6 @@
/* TFE resource constants */
#define CAM_TFE_HW_IN_RES_MAX (CAM_ISP_TFE_IN_RES_MAX & 0xFF)
#define CAM_TFE_HW_OUT_RES_MAX (CAM_ISP_TFE_OUT_RES_MAX & 0xFF)
#define CAM_TFE_HW_RES_POOL_MAX 64
/**
@ -32,7 +31,7 @@
* @camif_debug: enable sensor diagnosis status
* @enable_reg_dump: enable reg dump on error;
* @per_req_reg_dump: Enable per request reg dump
*
* @enable_cdm_cmd_check: Enable invalid command check in cmd_buf
*/
struct cam_tfe_hw_mgr_debug {
struct dentry *dentry;
@ -42,6 +41,7 @@ struct cam_tfe_hw_mgr_debug {
uint32_t camif_debug;
uint32_t enable_reg_dump;
uint32_t per_req_reg_dump;
bool enable_cdm_cmd_check;
};
/**
@ -71,6 +71,28 @@ struct cam_tfe_comp_record_query {
void *reserved;
};
/**
* struct cam_tfe_cdm_user_data - TFE HW user data with CDM
*
* @prepare: hw_update_data
* @request_id: Request id
*/
struct cam_tfe_cdm_user_data {
struct cam_isp_prepare_hw_update_data *hw_update_data;
uint64_t request_id;
};
/**
* struct cam_isp_tfe_hw_caps - BUS capabilities
*
* @max_tfe_out_res_type : max tfe out res type value from hw
* @support_consumed_addr : indicate whether hw supports last consumed address
*/
struct cam_isp_tfe_hw_caps {
uint32_t max_tfe_out_res_type;
bool support_consumed_addr;
};
/**
* struct cam_tfe_hw_mgr_ctx - TFE HW manager Context object
*
@ -82,7 +104,9 @@ struct cam_tfe_comp_record_query {
* @res_list_csid: csid resource list
* @res_list_tfe_in: tfe input resource list
* @res_list_tfe_out: tfe output resoruces array
* @num_acq_tfe_out: Number of acquired TFE out resources
* @free_res_list: free resources list for the branch node
* @tfe_out_map: Map for TFE out ports
* @res_pool: memory storage for the free resource list
* @base device base index array contain the all TFE HW
* instance associated with this context.
@ -113,6 +137,14 @@ struct cam_tfe_comp_record_query {
* @packet CSL packet from user mode driver
* @bw_config_version BW Config version
* @tfe_bus_comp_grp pointer to tfe comp group info
* @cdm_userdata CDM user data
* @try_recovery_cnt Retry count for overflow recovery
* @current_mup Current MUP val
* @recovery_req_id The request id on which overflow recovery happens
* @acquired_wm_mask Bitmask of acquired out resource
* @is_shdr Indicate if the usecase is SHDR
* @is_shdr_slave Indicate whether context is slave in shdr usecase
* @ctx_state Indicate if ctx is active or paused
*/
struct cam_tfe_hw_mgr_ctx {
struct list_head list;
@ -124,10 +156,11 @@ struct cam_tfe_hw_mgr_ctx {
struct list_head res_list_tfe_csid;
struct list_head res_list_tfe_in;
struct cam_isp_hw_mgr_res
res_list_tfe_out[CAM_TFE_HW_OUT_RES_MAX];
struct cam_isp_hw_mgr_res *res_list_tfe_out;
uint32_t num_acq_tfe_out;
struct list_head free_res_list;
uint8_t *tfe_out_map;
struct cam_isp_hw_mgr_res res_pool[CAM_TFE_HW_RES_POOL_MAX];
struct cam_isp_ctx_base_info base[CAM_TFE_HW_NUM_MAX];
@ -156,6 +189,15 @@ struct cam_tfe_hw_mgr_ctx {
struct cam_packet *packet;
uint32_t bw_config_version;
struct cam_tfe_hw_comp_record *tfe_bus_comp_grp;
struct cam_tfe_cdm_user_data cdm_userdata;
uint32_t current_mup;
uint32_t try_recovery_cnt;
uint64_t recovery_req_id;
uint64_t acquired_wm_mask;
enum cam_cdm_id cdm_id;
bool is_shdr;
bool is_shdr_slave;
uint32_t ctx_state;
};
/**
@ -172,31 +214,35 @@ struct cam_tfe_hw_mgr_ctx {
* @free_ctx_list: free hw context list
* @used_ctx_list: used hw context list
* @ctx_pool: context storage
* @session_data: Data related to current session
* @tfe_csid_dev_caps csid device capability stored per core
* @tfe_dev_caps tfe device capability per core
* @work q work queue for TFE hw manager
* @debug_cfg debug configuration
* @support_consumed_addr indicate whether hw supports last consumed address
* @path_port_map Mapping of outport to TFE mux
* @ctx_lock Spinlock for HW manager
* @isp_caps Capability of underlying TFE HW
*/
struct cam_tfe_hw_mgr {
struct cam_isp_hw_mgr mgr_common;
struct cam_hw_intf *csid_devices[CAM_TFE_CSID_HW_NUM_MAX];
struct cam_isp_hw_intf_data *tfe_devices[CAM_TFE_HW_NUM_MAX];
struct cam_soc_reg_map *cdm_reg_map[CAM_TFE_HW_NUM_MAX];
struct mutex ctx_mutex;
atomic_t active_ctx_cnt;
struct list_head free_ctx_list;
struct list_head used_ctx_list;
struct cam_tfe_hw_mgr_ctx ctx_pool[CAM_TFE_CTX_MAX];
struct cam_isp_hw_mgr mgr_common;
struct cam_hw_intf *csid_devices[CAM_TFE_CSID_HW_NUM_MAX];
struct cam_isp_hw_intf_data *tfe_devices[CAM_TFE_HW_NUM_MAX];
struct cam_soc_reg_map *cdm_reg_map[CAM_TFE_HW_NUM_MAX];
struct mutex ctx_mutex;
atomic_t active_ctx_cnt;
struct list_head free_ctx_list;
struct list_head used_ctx_list;
struct cam_tfe_hw_mgr_ctx ctx_pool[CAM_TFE_CTX_MAX];
struct cam_isp_session_data session_data[CAM_TFE_HW_NUM_MAX];
struct cam_tfe_csid_hw_caps tfe_csid_dev_caps[
struct cam_tfe_csid_hw_caps tfe_csid_dev_caps[
CAM_TFE_CSID_HW_NUM_MAX];
struct cam_tfe_hw_get_hw_cap tfe_dev_caps[CAM_TFE_HW_NUM_MAX];
struct cam_req_mgr_core_workq *workq;
struct cam_tfe_hw_mgr_debug debug_cfg;
bool support_consumed_addr;
spinlock_t ctx_lock;
struct cam_tfe_hw_get_hw_cap tfe_dev_caps[CAM_TFE_HW_NUM_MAX];
struct cam_req_mgr_core_workq *workq;
struct cam_tfe_hw_mgr_debug debug_cfg;
struct cam_isp_hw_path_port_map path_port_map;
spinlock_t ctx_lock;
struct cam_isp_tfe_hw_caps isp_caps;
};
/**

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <media/cam_defs.h>
@ -767,8 +767,8 @@ static int cam_isp_io_buf_get_entries_util(
&buf_info->scratch_check_cfg->ife_scratch_res_info,
io_cfg->resource_type);
}
*hw_mgr_res = &buf_info->res_list_isp_out[buf_info->out_map[res_id]];
if ((*hw_mgr_res)->res_type == CAM_ISP_RESOURCE_UNINT) {
CAM_ERR(CAM_ISP, "io res id:%d not valid",
io_cfg->resource_type);
@ -852,9 +852,8 @@ static int cam_isp_add_io_buffers_util(
struct cam_hw_fence_map_entry *out_map_entry = NULL;
struct cam_smmu_buffer_tracker *old_head_entry, *new_head_entry;
uint32_t kmd_buf_remain_size;
uint32_t plane_id;
uint32_t num_entries;
uint32_t plane_id;
int num_entries;
dma_addr_t *image_buf_addr;
uint32_t *image_buf_offset;
size_t size;
@ -1014,7 +1013,6 @@ static int cam_isp_add_io_buffers_util(
num_entries = buf_info->prepare->num_out_map_entries - 1;
out_map_entry =
&buf_info->prepare->out_map_entries[num_entries];
if (!out_map_entry) {
CAM_ERR(CAM_ISP, "out_map_entry is NULL");
rc = -EINVAL;
@ -1126,7 +1124,7 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
int rc = 0;
struct cam_buf_io_cfg *io_cfg = NULL;
struct cam_isp_hw_mgr_res *hw_mgr_res = NULL;
uint32_t i;
uint32_t i, j;
uint32_t curr_used_bytes = 0;
uint32_t bytes_updated = 0;
struct cam_isp_resource_node *res = NULL;
@ -1135,6 +1133,8 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
uint8_t max_out_res = 0;
uint64_t *mc_cfg = NULL;
uint32_t major_version = 0;
struct cam_isp_prepare_hw_update_data *prepare_hw_data;
uint64_t cfg_io_mask = 0, disabled_wm_mask = 0;
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
&io_info->prepare->packet->payload +
@ -1161,6 +1161,7 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
}
}
prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) io_info->prepare->priv;
for (i = 0; i < io_info->prepare->packet->num_io_configs; i++) {
if (major_version == 3) {
@ -1195,6 +1196,8 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
if (!res)
continue;
cfg_io_mask |= (1 << (res->res_id & 0xFF));
rc = cam_isp_add_io_buffers_util(io_info, &io_cfg[i], res);
if (rc) {
CAM_ERR(CAM_ISP, "io_cfg[%d] add buf failed rc %d", i, rc);
@ -1217,9 +1220,26 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
vfree(mc_cfg);
}
disabled_wm_mask = (prepare_hw_data->wm_bitmask ^ cfg_io_mask);
if ((io_info->base->hw_type == CAM_ISP_HW_TYPE_TFE) && disabled_wm_mask) {
for (j = 0; j < io_info->out_max; j++) {
rc = cam_isp_add_disable_wm_update(io_info->prepare,
&io_info->res_list_isp_out[io_info->out_map[j]],
io_info->base->idx, io_info->kmd_buf_info,
&disabled_wm_mask,
io_info);
if (rc) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "Disable out res %d failed",
j, rc);
return rc;
}
}
}
bytes_updated = io_info->kmd_buf_info->used_bytes - curr_used_bytes;
CAM_DBG(CAM_ISP, "io_cfg_used_bytes %d, fill_fence %d",
bytes_updated, io_info->fill_fence);
CAM_DBG(CAM_ISP, "io_cfg_used_bytes %d, fill_fence %d acuired mask %x cfg mask %x",
bytes_updated, io_info->fill_fence, prepare_hw_data->wm_bitmask, cfg_io_mask);
if (bytes_updated) {
/**
@ -1240,17 +1260,82 @@ err:
return rc;
}
int cam_isp_add_disable_wm_update(
struct cam_hw_prepare_update_args *prepare,
struct cam_isp_hw_mgr_res *isp_hw_res,
uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info,
uint64_t *wm_mask,
struct cam_isp_io_buf_info *io_info)
{
int rc = 0;
struct cam_hw_intf *hw_intf;
struct cam_isp_resource_node *res;
struct cam_isp_hw_get_cmd_update wm_update;
uint32_t kmd_buf_remain_size, i;
if (prepare->packet->header.request_id == 0)
return 0;
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
if (!isp_hw_res->hw_res[i])
continue;
hw_intf = isp_hw_res->hw_res[i]->hw_intf;
res = isp_hw_res->hw_res[i];
if (res->hw_intf->hw_idx != base_idx)
continue;
if (!(*wm_mask & (1 << res->res_id))) {
CAM_DBG(CAM_ISP, "No need to disable out res %d", res->res_id);
continue;
}
*wm_mask &= ~BIT(res->res_id);
if (kmd_buf_info->used_bytes < kmd_buf_info->size) {
kmd_buf_remain_size = kmd_buf_info->size - kmd_buf_info->used_bytes;
} else {
CAM_ERR(CAM_ISP,
"no free kmd memory for base=%d bytes_used=%u buf_size=%u",
base_idx, kmd_buf_info->used_bytes, kmd_buf_info->size);
rc = -EINVAL;
return rc;
}
wm_update.cmd.cmd_buf_addr = kmd_buf_info->cpu_addr +
kmd_buf_info->used_bytes/4;
wm_update.cmd.size = kmd_buf_remain_size;
wm_update.cmd_type = CAM_ISP_HW_CMD_BUS_WM_DISABLE;
wm_update.res = res;
rc = res->hw_intf->hw_ops.process_cmd(
res->hw_intf->hw_priv,
CAM_ISP_HW_CMD_BUS_WM_DISABLE, &wm_update,
sizeof(struct cam_isp_hw_get_cmd_update));
if (rc) {
CAM_ERR(CAM_ISP, "Diaable res %d failed split %d",
res->res_id, i);
return rc;
}
CAM_DBG(CAM_ISP,
"Out res %d disable update added hw_id %d cdm_idx %d split id: %d",
res->res_id, res->hw_intf->hw_idx, base_idx, i);
io_info->kmd_buf_info->used_bytes += wm_update.cmd.used_bytes;
io_info->kmd_buf_info->offset += wm_update.cmd.used_bytes;
}
return rc;
}
int cam_isp_add_reg_update(
struct cam_hw_prepare_update_args *prepare,
struct list_head *res_list_isp_src,
uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info,
bool combine)
bool combine,
void *priv_data)
{
int rc = -EINVAL;
struct cam_isp_resource_node *res;
struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_isp_hw_get_cmd_update get_regup;
struct cam_isp_resource_node *res;
struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_isp_hw_get_cmd_update get_regup;
uint32_t kmd_buf_remain_size, i, reg_update_size;
/* Max one hw entries required for each base */
@ -1296,6 +1381,8 @@ int cam_isp_add_reg_update(
get_regup.cmd_type = CAM_ISP_HW_CMD_GET_REG_UPDATE;
get_regup.res = res;
get_regup.data = priv_data;
rc = res->hw_intf->hw_ops.process_cmd(
res->hw_intf->hw_priv,
CAM_ISP_HW_CMD_GET_REG_UPDATE, &get_regup,

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_ISP_HW_PARSER_H_
@ -278,6 +278,27 @@ int cam_isp_add_command_buffers(
*/
int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info);
/*
* cam_isp_add_disable_wm_update()
*
* @brief Add disable wm command
*
* @prepare: Contain the packet and HW update variables
* @isp_hw_res: Resource list for IFE/VFE out resource
* @base_idx: Base or dev index of the IFE/VFE HW instance
* @kmd_buf_info: Kmd buffer to store the change base command
* @wm_mask Bit mask of unconfigured resource
* @io_info IO buf info
*
*/
int cam_isp_add_disable_wm_update(
struct cam_hw_prepare_update_args *prepare,
struct cam_isp_hw_mgr_res *isp_hw_res,
uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info,
uint64_t *wm_mask,
struct cam_isp_io_buf_info *io_info);
/*
* cam_isp_add_reg_update()
*
@ -290,6 +311,7 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info);
* @base_idx: Base or dev index of the IFE/VFE HW instance
* @kmd_buf_info: Kmd buffer to store the change base command
* @combine: Indicate whether combine with prev update entry
* @priv_data: private data for HW driver
* @return: 0 for success
* -EINVAL for Fail
*/
@ -298,7 +320,8 @@ int cam_isp_add_reg_update(
struct list_head *res_list_isp_src,
uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info,
bool combine);
bool combine,
void *priv_data);
/*
* cam_isp_add_comp_wait()

View File

@ -24,7 +24,7 @@
#define CAM_ISP_BW_CONFIG_V1 1
#define CAM_ISP_BW_CONFIG_V2 2
#define CAM_ISP_BW_CONFIG_V3 3
#define CAM_TFE_HW_NUM_MAX 3
#define CAM_TFE_HW_NUM_MAX 4
#define CAM_TFE_RDI_NUM_MAX 3
#define CAM_IFE_SCRATCH_NUM_MAX 2
#define CAM_IFE_BUS_COMP_NUM_MAX 18
@ -33,7 +33,7 @@
#define CAM_TFE_BUS_COMP_NUM_MAX 18
/* maximum context numbers for TFE */
#define CAM_TFE_CTX_MAX 4
#define CAM_TFE_CTX_MAX 6
/* maximum context numbers for IFE */
#define CAM_IFE_CTX_MAX 8
@ -49,6 +49,8 @@
#define CAM_IFE_CTX_SFE_EN BIT(4)
#define CAM_IFE_CTX_AEB_EN BIT(5)
#define CAM_IFE_CTX_DYNAMIC_SWITCH_EN BIT(6)
#define CAM_IFE_CTX_SHDR_EN BIT(7)
#define CAM_IFE_CTX_SHDR_IS_MASTER BIT(8)
/*
* Maximum configuration entry size - This is based on the
@ -346,6 +348,7 @@ struct cam_isp_fcg_config_info {
* @packet: CSL packet from user mode driver
* @mup_val: MUP value if configured
* @num_exp: Num of exposures
* @wm_bitmask: Bitmask of acquired out resource
* @mup_en: Flag if dynamic sensor switch is enabled
* @fcg_info: Track FCG config for further usage in config stage
*
@ -368,7 +371,7 @@ struct cam_isp_prepare_hw_update_data {
struct cam_kmd_buf_info kmd_cmd_buff_info;
uint32_t mup_val;
uint32_t num_exp;
uint32_t configured_rup_aup;
uint64_t wm_bitmask;
bool mup_en;
struct cam_isp_fcg_config_info fcg_info;
};
@ -477,8 +480,8 @@ enum cam_isp_hw_mgr_command {
CAM_ISP_HW_MGR_GET_SOF_TS,
CAM_ISP_HW_MGR_DUMP_STREAM_INFO,
CAM_ISP_HW_MGR_GET_BUS_COMP_GROUP,
CAM_ISP_HW_MGR_CMD_UPDATE_CLOCK,
CAM_ISP_HW_MGR_GET_LAST_CONSUMED_ADDR,
CAM_ISP_HW_MGR_GET_PATH_SOF_TS,
CAM_ISP_HW_MGR_CMD_MAX,
};
@ -547,6 +550,21 @@ struct cam_isp_lcr_rdi_cfg_args {
bool is_init;
};
/**
* struct cam_isp_mode_switch_data - isp hardware mode update arguments
*
* @mup Mup value
* @num_expoures Number of exposures
* @mup_en Flag to indicate if mup is enable
*
*/
struct cam_isp_mode_switch_data {
uint32_t mup;
uint32_t num_expoures;
bool mup_en;
};
/**
* cam_isp_hw_mgr_init()
*

View File

@ -0,0 +1,90 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_IFE_CSID_860_H_
#define _CAM_IFE_CSID_860_H_
#include <linux/module.h>
#include "cam_ife_csid_dev.h"
#include "camera_main.h"
#include "cam_ife_csid_common.h"
#include "cam_ife_csid_hw_ver2.h"
#include "cam_irq_controller.h"
#include "cam_isp_hw_mgr_intf.h"
#include "cam_ife_csid880.h"
#define CAM_CSID_VERSION_V860 0x80060000
static struct cam_ife_csid_ver2_reg_info cam_ife_csid_860_reg_info = {
.top_irq_reg_info = cam_ife_csid_880_top_irq_reg_info,
.rx_irq_reg_info = cam_ife_csid_880_rx_irq_reg_info,
.path_irq_reg_info = {
&cam_ife_csid_880_path_irq_reg_info[CAM_IFE_PIX_PATH_RES_RDI_0],
&cam_ife_csid_880_path_irq_reg_info[CAM_IFE_PIX_PATH_RES_RDI_1],
&cam_ife_csid_880_path_irq_reg_info[CAM_IFE_PIX_PATH_RES_RDI_2],
&cam_ife_csid_880_path_irq_reg_info[CAM_IFE_PIX_PATH_RES_RDI_3],
&cam_ife_csid_880_path_irq_reg_info[CAM_IFE_PIX_PATH_RES_RDI_4],
&cam_ife_csid_880_path_irq_reg_info[CAM_IFE_PIX_PATH_RES_IPP],
&cam_ife_csid_880_path_irq_reg_info[CAM_IFE_PIX_PATH_RES_PPP],
},
.buf_done_irq_reg_info = &cam_ife_csid_880_buf_done_irq_reg_info,
.cmn_reg = &cam_ife_csid_880_cmn_reg_info,
.csi2_reg = &cam_ife_csid_880_csi2_reg_info,
.path_reg[CAM_IFE_PIX_PATH_RES_IPP] = &cam_ife_csid_880_ipp_reg_info,
.path_reg[CAM_IFE_PIX_PATH_RES_PPP] = &cam_ife_csid_880_ppp_reg_info,
.path_reg[CAM_IFE_PIX_PATH_RES_RDI_0] = &cam_ife_csid_880_rdi_0_reg_info,
.path_reg[CAM_IFE_PIX_PATH_RES_RDI_1] = &cam_ife_csid_880_rdi_1_reg_info,
.path_reg[CAM_IFE_PIX_PATH_RES_RDI_2] = &cam_ife_csid_880_rdi_2_reg_info,
.path_reg[CAM_IFE_PIX_PATH_RES_RDI_3] = &cam_ife_csid_880_rdi_3_reg_info,
.path_reg[CAM_IFE_PIX_PATH_RES_RDI_4] = &cam_ife_csid_880_rdi_4_reg_info,
.top_reg = &cam_ife_csid_880_top_reg_info,
.input_core_sel = {
{
0x0,
0x1,
0x2,
0x3,
-1,
-1,
-1,
-1,
},
{
0x0,
0x1,
0x2,
0x3,
-1,
-1,
-1,
-1,
},
{
0x0,
0x1,
0x2,
0x3,
-1,
-1,
-1,
-1,
},
},
.need_top_cfg = 0x1,
.top_irq_desc = &cam_ife_csid_880_top_irq_desc,
.rx_irq_desc = &cam_ife_csid_880_rx_irq_desc,
.path_irq_desc = cam_ife_csid_880_path_irq_desc,
.num_top_err_irqs = cam_ife_csid_880_num_top_irq_desc,
.num_rx_err_irqs = cam_ife_csid_880_num_rx_irq_desc,
.num_path_err_irqs = ARRAY_SIZE(cam_ife_csid_880_path_irq_desc),
.num_top_regs = 1,
.num_rx_regs = 1,
.width_fuse_max_val = 1,
.fused_max_dualife_width = {7296, 5344, UINT_MAX},
.fused_max_width = {7296, 7296, UINT_MAX},
.is_ife_sfe_mapped = true,
};
#endif /*_CAM_IFE_CSID_860_H_ */

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_IFE_CSID_880_H_
@ -1508,5 +1508,6 @@ static struct cam_ife_csid_ver2_reg_info cam_ife_csid_880_reg_info = {
.num_path_err_irqs = ARRAY_SIZE(cam_ife_csid_880_path_irq_desc),
.num_top_regs = 1,
.num_rx_regs = 1,
.is_ife_sfe_mapped = true,
};
#endif /*_CAM_IFE_CSID_880_H_ */

View File

@ -684,6 +684,12 @@ int cam_ife_csid_get_base(struct cam_hw_soc_info *soc_info,
}
mem_base = CAM_SOC_GET_REG_MAP_CAM_BASE(soc_info, base_id);
if (mem_base == -1) {
CAM_ERR(CAM_ISP, "failed to get mem_base, index: %d num_reg_map: %u",
base_id, soc_info->num_reg_map);
return -EINVAL;
}
if (cdm_args->cdm_id == CAM_CDM_RT) {
if (!soc_private->rt_wrapper_base) {
CAM_ERR(CAM_ISP, "rt_wrapper_base_addr is null");

View File

@ -116,6 +116,12 @@ static void cam_ife_csid_component_unbind(struct device *dev,
const struct of_device_id *match_dev = NULL;
hw_intf = (struct cam_hw_intf *)platform_get_drvdata(pdev);
if (!hw_intf) {
CAM_ERR(CAM_ISP, "Error No data in hw_intf");
return;
}
hw_info = hw_intf->hw_priv;
CAM_DBG(CAM_ISP, "CSID:%d component unbind",

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/iopoll.h>
@ -721,9 +721,8 @@ static int cam_ife_csid_ver1_deinit_rdi_path(
if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
res->res_id > CAM_IFE_PIX_PATH_RES_RDI_4) {
CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d",
csid_hw->hw_intf->hw_idx,
res->res_name,
"CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, res->res_name,
res->res_type, res->res_id, res->res_state);
return -EINVAL;
}
@ -782,9 +781,8 @@ static int cam_ife_csid_ver1_deinit_udi_path(
(res->res_id < CAM_IFE_PIX_PATH_RES_UDI_0 ||
res->res_id > CAM_IFE_PIX_PATH_RES_UDI_2)) {
CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d",
csid_hw->hw_intf->hw_idx,
res->res_name,
"CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, res->res_name,
res->res_type, res->res_id, res->res_state);
return -EINVAL;
}
@ -841,9 +839,8 @@ static int cam_ife_csid_ver1_deinit_pxl_path(
if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d",
csid_hw->hw_intf->hw_idx,
res->res_name,
"CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, res->res_name,
res->res_type, res->res_id, res->res_state);
return -EINVAL;
}
@ -903,9 +900,8 @@ static int cam_ife_csid_ver1_stop_pxl_path(
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d",
csid_hw->hw_intf->hw_idx,
res->res_name,
"CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, res->res_name,
res->res_type, res->res_id, res->res_state);
return -EINVAL;
}
@ -987,9 +983,8 @@ static int cam_ife_csid_ver1_stop_rdi_path(
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d",
csid_hw->hw_intf->hw_idx,
res->res_name,
"CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, res->res_name,
res->res_type, res->res_id, res->res_state);
return -EINVAL;
}
@ -1045,9 +1040,8 @@ static int cam_ife_csid_ver1_stop_udi_path(
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d",
csid_hw->hw_intf->hw_idx,
res->res_name,
"CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, res->res_name,
res->res_type, res->res_id, res->res_state);
return -EINVAL;
}
@ -1827,6 +1821,14 @@ int cam_ife_csid_ver1_release(void *hw_priv,
csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
path_cfg = (struct cam_ife_csid_ver1_path_cfg *)res->res_priv;
if (path_cfg->cid >= CAM_IFE_CSID_CID_MAX) {
CAM_ERR(CAM_ISP, "CSID:%d Invalid cid:%d",
csid_hw->hw_intf->hw_idx, path_cfg->cid);
rc = -EINVAL;
goto end;
}
cam_ife_csid_cid_release(&csid_hw->cid_data[path_cfg->cid],
csid_hw->hw_intf->hw_idx,
path_cfg->cid);
@ -1869,9 +1871,8 @@ static int cam_ife_csid_ver1_start_rdi_path(
if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
res->res_id > CAM_IFE_PIX_PATH_RES_RDI_4) {
CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d",
csid_hw->hw_intf->hw_idx,
res->res_name,
"CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, res->res_name,
res->res_type, res->res_id, res->res_state);
return -EINVAL;
}
@ -1921,9 +1922,8 @@ static int cam_ife_csid_ver1_start_udi_path(
(res->res_id < CAM_IFE_PIX_PATH_RES_UDI_0 ||
res->res_id > CAM_IFE_PIX_PATH_RES_UDI_2)) {
CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d",
csid_hw->hw_intf->hw_idx,
res->res_name,
"CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, res->res_name,
res->res_type, res->res_id, res->res_state);
return -EINVAL;
}
@ -1974,9 +1974,8 @@ static int cam_ife_csid_ver1_start_pix_path(
if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d",
csid_hw->hw_intf->hw_idx,
res->res_name,
"CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, res->res_name,
res->res_type, res->res_id, res->res_state);
return -EINVAL;
}
@ -2720,7 +2719,6 @@ static int cam_ife_csid_ver1_enable_hw(struct cam_ife_csid_ver1_hw *csid_hw)
csid_hw->flags.fatal_err_detected = false;
csid_hw->flags.device_enabled = true;
spin_unlock_irqrestore(&csid_hw->lock_state, flags);
cam_tasklet_start(csid_hw->tasklet);
return rc;
@ -2742,8 +2740,6 @@ int cam_ife_csid_ver1_init_hw(void *hw_priv,
struct cam_hw_info *hw_info;
int rc = 0;
if (!hw_priv || !init_args ||
(arg_size != sizeof(struct cam_isp_resource_node))) {
CAM_ERR(CAM_ISP, "CSID: Invalid args");
@ -2752,7 +2748,7 @@ int cam_ife_csid_ver1_init_hw(void *hw_priv,
hw_info = (struct cam_hw_info *)hw_priv;
csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info;
rc = cam_ife_csid_ver1_enable_hw(csid_hw);
if (rc) {
@ -2901,7 +2897,6 @@ static int cam_ife_csid_ver1_disable_hw(
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->top_irq_mask_addr);
cam_tasklet_stop(csid_hw->tasklet);
rc = cam_ife_csid_disable_soc_resources(soc_info);
if (rc)
CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed",
@ -3802,9 +3797,6 @@ static int cam_ife_csid_ver1_process_cmd(void *hw_priv,
case CAM_ISP_HW_CMD_CSID_DUMP_CROP_REG:
/* Not supported in V1*/
break;
case CAM_IFE_CSID_CMD_GET_PATH_TIME_STAMP:
/* Not supported in V1*/
break;
default:
CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
csid_hw->hw_intf->hw_idx, cmd_type);

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/iopoll.h>
@ -1327,9 +1327,6 @@ static inline uint32_t cam_ife_csid_ver2_input_core_to_hw_idx(int core_sel)
}
}
static int cam_ife_csid_ver2_dump_frame_stats(
struct cam_ife_csid_ver2_hw *csid_hw);
static int cam_ife_csid_ver2_handle_event_err(
struct cam_ife_csid_ver2_hw *csid_hw,
uint32_t irq_status,
@ -1382,7 +1379,6 @@ static int cam_ife_csid_ver2_handle_event_err(
cam_ife_csid_ver2_input_core_to_hw_idx(csid_hw->top_cfg.input_core_type);
cam_ife_csid_ver2_print_camif_timestamps(csid_hw);
cam_ife_csid_ver2_dump_frame_stats(csid_hw);
csid_hw->event_cb(csid_hw->token, CAM_ISP_HW_EVENT_ERROR, (void *)&evt);
@ -1667,7 +1663,7 @@ void cam_ife_csid_hw_ver2_drv_err_handler(void *csid)
void cam_ife_csid_hw_ver2_mup_mismatch_handler(
void *csid, void *resource)
{
uint32_t idx = 0, val;
uint32_t idx = 0;
struct timespec64 current_ts;
struct cam_ife_csid_ver2_hw *csid_hw = csid;
struct cam_isp_resource_node *res = resource;
@ -1694,16 +1690,16 @@ void cam_ife_csid_hw_ver2_mup_mismatch_handler(
if (path_cfg->ts_comb_vcdt_en) {
ktime_get_boottime_ts64(&current_ts);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
path_reg->timestamp_curr0_sof_addr);
idx = val & csid_reg->cmn_reg->ts_comb_vcdt_mask;
idx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
path_reg->timestamp_curr0_sof_addr) &
csid_reg->cmn_reg->ts_comb_vcdt_mask;
if (idx < CAM_IFE_CSID_MULTI_VC_DT_GRP_MAX)
CAM_INFO(CAM_ISP,
"CSID:%d Received frame with vc:%d on [id: %d name: %s] timestamp: %lld.%09lld register value: 0x%x",
"CSID:%d Received frame with vc:%d on [id: %d name: %s] timestamp: %lld.%09lld",
csid_hw->hw_intf->hw_idx, cid_data->vc_dt[idx].vc,
res->res_id, res->res_name, current_ts.tv_sec,
current_ts.tv_nsec, val);
current_ts.tv_nsec);
else
CAM_ERR(CAM_ISP,
"CSID:%d Get invalid vc index: %d on [id: %d name: %s] timestamp: %lld.%09lld",
@ -1749,7 +1745,8 @@ void cam_ife_csid_ver2_print_illegal_programming_irq_status(
cfg1 = cam_io_r_mb(base + path_reg->cfg1_addr);
vcdt_cfg0 = cam_io_r_mb(base + path_reg->multi_vcdt_cfg0_addr);
CAM_INFO(CAM_ISP, "cfg0 = %x cfg1 = %x vcdt_cfg0 = %x ", cfg0, cfg1, vcdt_cfg0);
CAM_INFO(CAM_ISP, "cfg0 = %x cfg1 = %x vcdt_cfg0 = %x vcrop %x", cfg0, cfg1, vcdt_cfg0,
cam_io_r_mb(base + path_reg->vcrop_addr));
if (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].valid) {
decode_fmt = ((cfg0 >>
@ -1962,7 +1959,6 @@ static int cam_ife_csid_ver2_parse_path_irq_status(
if ((irq_status & IFE_CSID_VER2_PATH_INFO_INPUT_SOF))
csid_hw->counters.irq_debug_cnt++;
if (csid_hw->counters.irq_debug_cnt >=
CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX) {
cam_ife_csid_ver2_sof_irq_debug(csid_hw,
@ -2474,9 +2470,8 @@ static int cam_ife_csid_ver2_rdi_bottom_half(
/* Only notify if secondary event is subscribed for */
if ((path_cfg->sec_evt_config.en_secondary_evt) &&
(path_cfg->sec_evt_config.evt_type &
CAM_IFE_CSID_EVT_SENSOR_SYNC_FRAME_DROP)) {
do_notify = true;
}
CAM_IFE_CSID_EVT_SENSOR_SYNC_FRAME_DROP))
do_notify = true;
/* Validate error threshold for primary RDI (master) */
if (res->is_rdi_primary_res) {
@ -2561,6 +2556,7 @@ int cam_ife_csid_ver2_get_hw_caps(void *hw_priv,
hw_caps->is_lite = soc_private->is_ife_csid_lite;
hw_caps->sfe_ipp_input_rdi_res = csid_reg->cmn_reg->sfe_ipp_input_rdi_res;
hw_caps->camif_irq_support = csid_reg->cmn_reg->camif_irq_support;
hw_caps->is_ife_sfe_mapped = csid_reg->is_ife_sfe_mapped;
CAM_DBG(CAM_ISP,
"CSID:%u num-rdis:%d, num-pix:%d, major:%d minor:%d ver:%d",
@ -2678,7 +2674,7 @@ static int cam_ife_csid_ver2_reset_irq_top_half(uint32_t evt_id,
}
static int cam_ife_csid_ver2_internal_reset(
struct cam_ife_csid_ver2_hw *csid_hw, bool power_on_rst,
struct cam_ife_csid_ver2_hw *csid_hw,
uint32_t rst_cmd, uint32_t rst_location, uint32_t rst_mode)
{
uint32_t val = 0;
@ -2707,18 +2703,9 @@ static int cam_ife_csid_ver2_internal_reset(
cam_io_w_mb(0x0, mem_base + csi2_reg->cfg1_addr);
}
/*
* After power on once the connection has been established
* between master and slave CSIDs, issuing a reset to master
* will also reset the slave. Reset to the slave is only needed
* when powering on the cores since at this point the master-slave
* connection is not established yet
*/
if ((csid_hw->sync_mode == CAM_ISP_HW_SYNC_SLAVE) && (!power_on_rst))
if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_SLAVE)
goto wait_only;
CAM_DBG(CAM_ISP, "CSID[%u] issuing reset", csid_hw->hw_intf->hw_idx);
reinit_completion(&csid_hw->hw_info->hw_complete);
/* Program the reset location */
@ -2779,16 +2766,14 @@ int cam_ife_csid_ver2_reset(void *hw_priv,
switch (reset->reset_type) {
case CAM_IFE_CSID_RESET_GLOBAL:
rc = cam_ife_csid_ver2_internal_reset(
csid_hw, reset->power_on_reset,
rc = cam_ife_csid_ver2_internal_reset(csid_hw,
CAM_IFE_CSID_RESET_CMD_SW_RST,
CAM_IFE_CSID_RESET_LOC_COMPLETE,
CAM_CSID_HALT_IMMEDIATELY);
break;
case CAM_IFE_CSID_RESET_PATH:
rc = cam_ife_csid_ver2_internal_reset(
csid_hw, reset->power_on_reset,
rc = cam_ife_csid_ver2_internal_reset(csid_hw,
CAM_IFE_CSID_RESET_CMD_HW_RST,
CAM_IFE_CSID_RESET_LOC_PATH_ONLY,
CAM_CSID_HALT_IMMEDIATELY);
@ -3362,6 +3347,82 @@ end:
return rc;
}
static bool cam_ife_csid_ver2_is_width_valid_by_fuse(
struct cam_csid_hw_reserve_resource_args *reserve,
struct cam_ife_csid_ver2_hw *csid_hw,
uint32_t width)
{
struct cam_ife_csid_ver2_reg_info *csid_reg;
uint32_t fuse_val = UINT_MAX;
csid_reg = (struct cam_ife_csid_ver2_reg_info *)
csid_hw->core_info->csid_reg;
cam_cpas_is_feature_supported(CAM_CPAS_MP_LIMIT_FUSE, CAM_CPAS_HW_IDX_ANY, &fuse_val);
if (fuse_val == UINT_MAX) {
CAM_DBG(CAM_ISP, "CSID[%u] MP limit fuse not present",
csid_hw->hw_intf->hw_idx);
return true;
}
if ((fuse_val > csid_reg->width_fuse_max_val) ||
(fuse_val >= CAM_IFE_CSID_WIDTH_FUSE_VAL_MAX)) {
CAM_ERR(CAM_ISP, "Invalid fuse value %u", fuse_val);
return false;
}
if (((reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) ||
(reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER)) &&
(width > csid_reg->fused_max_dualife_width[fuse_val])) {
CAM_ERR(CAM_ISP,
"CSID[%u] Resolution not supported required_width dualife: %d max_supported_width: %d",
csid_hw->hw_intf->hw_idx,
width, csid_reg->fused_max_dualife_width[fuse_val]);
return false;
} else if (width > csid_reg->fused_max_width[fuse_val]) {
CAM_ERR(CAM_ISP,
"CSID[%u] Resolution not supported required_width: %d max_supported_width: %d",
csid_hw->hw_intf->hw_idx,
width, csid_reg->fused_max_width[fuse_val]);
return false;
}
return true;
}
bool cam_ife_csid_ver2_is_width_valid(
struct cam_csid_hw_reserve_resource_args *reserve,
struct cam_ife_csid_ver2_hw *csid_hw)
{
uint32_t width = 0;
struct cam_csid_soc_private *soc_private;
soc_private = (struct cam_csid_soc_private *)csid_hw->hw_info->soc_info.soc_private;
if ((reserve->res_id != CAM_IFE_PIX_PATH_RES_IPP) || soc_private->is_ife_csid_lite)
return true;
if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER ||
reserve->sync_mode == CAM_ISP_HW_SYNC_NONE)
width = reserve->in_port->left_stop -
reserve->in_port->left_start + 1;
else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE)
width = reserve->in_port->right_stop -
reserve->in_port->right_start + 1;
if (reserve->in_port->horizontal_bin || reserve->in_port->qcfa_bin)
width /= 2;
if (!cam_ife_csid_ver2_is_width_valid_by_fuse(reserve, csid_hw, width)) {
CAM_ERR(CAM_ISP, "CSID[%u] width limited by fuse",
csid_hw->hw_intf->hw_idx);
return false;
}
return true;
}
static int cam_ife_csid_ver2_in_port_validate(
struct cam_csid_hw_reserve_resource_args *reserve,
struct cam_ife_csid_ver2_hw *csid_hw)
@ -3376,6 +3437,9 @@ static int cam_ife_csid_ver2_in_port_validate(
goto err;
}
if (!cam_ife_csid_ver2_is_width_valid(reserve, csid_hw))
goto err;
if (csid_hw->counters.csi2_reserve_cnt) {
if (csid_hw->token != reserve->cb_priv) {
@ -3573,6 +3637,13 @@ int cam_ife_csid_ver2_release(void *hw_priv,
path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv;
if (path_cfg->cid >= CAM_IFE_CSID_CID_MAX) {
CAM_ERR(CAM_ISP, "CSID:%d Invalid cid:%d",
csid_hw->hw_intf->hw_idx, path_cfg->cid);
rc = -EINVAL;
goto end;
}
cam_ife_csid_cid_release(&csid_hw->cid_data[path_cfg->cid],
csid_hw->hw_intf->hw_idx,
path_cfg->cid);
@ -3813,7 +3884,8 @@ static int cam_ife_csid_ver2_init_config_rdi_path(
res->res_id == CAM_IFE_PIX_PATH_RES_RDI_0))
cam_ife_csid_ver2_res_master_slave_cfg(csid_hw, res->res_id);
if (1) {
if (csid_hw->debug_info.debug_val &
CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) {
val = cam_io_r_mb(mem_base +
path_reg->format_measure_cfg0_addr);
val |= cmn_reg->measure_en_hbi_vbi_cnt_mask;
@ -3986,7 +4058,8 @@ static int cam_ife_csid_ver2_init_config_pxl_path(
cam_io_w_mb(val, mem_base + path_reg->err_recovery_cfg0_addr);
}
if (1) {
if (csid_hw->debug_info.debug_val &
CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) {
val = cam_io_r_mb(mem_base +
path_reg->format_measure_cfg0_addr);
val |= csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask;
@ -4095,7 +4168,8 @@ static int cam_ife_csid_ver2_path_irq_subscribe(
struct cam_isp_resource_node *res,
uint32_t irq_mask, uint32_t err_irq_mask)
{
uint32_t top_irq_mask[CAM_IFE_CSID_IRQ_REGISTERS_MAX] = {0};
uint32_t num_register = 0;
uint32_t *top_irq_mask = NULL;
struct cam_ife_csid_ver2_path_cfg *path_cfg = res->res_priv;
struct cam_ife_csid_ver2_reg_info *csid_reg = csid_hw->core_info->csid_reg;
int i, rc;
@ -4114,8 +4188,14 @@ static int cam_ife_csid_ver2_path_irq_subscribe(
return -EINVAL;
}
top_irq_mask[CAM_IFE_CSID_IRQ_TOP_REG_STATUS0] =
csid_reg->path_reg[res->res_id]->top_irq_mask[top_index];
num_register = csid_reg->top_irq_reg_info[top_index].num_registers;
top_irq_mask = vmalloc(sizeof(uint32_t) * num_register);
if (!top_irq_mask) {
CAM_ERR(CAM_ISP, "csid top_irq_mask allocation failed");
return -ENOMEM;
}
top_irq_mask[0] = csid_reg->path_reg[res->res_id]->top_irq_mask[top_index];
if (csid_reg->path_reg[res->res_id]->capabilities & CAM_IFE_CSID_CAP_MULTI_CTXT) {
rc = cam_ife_csid_ver2_mc_irq_subscribe(csid_hw, res, top_index);
@ -4182,7 +4262,7 @@ static int cam_ife_csid_ver2_path_irq_subscribe(
rc = -EINVAL;
goto unsub_path;
}
vfree(top_irq_mask);
return 0;
unsub_path:
@ -4201,6 +4281,7 @@ unsub_mc:
csid_hw->top_mc_irq_handle);
csid_hw->top_mc_irq_handle = 0;
end:
vfree(top_irq_mask);
return rc;
}
@ -4643,7 +4724,8 @@ static int cam_ife_csid_ver2_csi2_irq_subscribe(struct cam_ife_csid_ver2_hw *csi
uint32_t irq_mask, uint32_t err_irq_mask)
{
struct cam_ife_csid_ver2_reg_info *csid_reg = csid_hw->core_info->csid_reg;
uint32_t top_irq_mask[CAM_IFE_CSID_IRQ_REGISTERS_MAX] = {0};
uint32_t num_register = 0;
uint32_t *top_irq_mask = NULL;
int top_index = -1;
int i, rc;
@ -4661,8 +4743,14 @@ static int cam_ife_csid_ver2_csi2_irq_subscribe(struct cam_ife_csid_ver2_hw *csi
return rc;
}
top_irq_mask[CAM_IFE_CSID_IRQ_TOP_REG_STATUS0] =
csid_reg->csi2_reg->top_irq_mask[top_index];
num_register = csid_reg->top_irq_reg_info[top_index].num_registers;
top_irq_mask = vmalloc(sizeof(uint32_t) * num_register);
if (!top_irq_mask) {
CAM_ERR(CAM_ISP, "csid top_irq_mask allocation failed");
return -ENOMEM;
}
top_irq_mask[0] = csid_reg->csi2_reg->top_irq_mask[top_index];
csid_hw->rx_cfg.top_irq_handle = cam_irq_controller_subscribe_irq(
csid_hw->top_irq_controller[top_index],
@ -4726,7 +4814,7 @@ static int cam_ife_csid_ver2_csi2_irq_subscribe(struct cam_ife_csid_ver2_hw *csi
rc = -EINVAL;
goto unsub_rx;
}
vfree(top_irq_mask);
return 0;
unsub_rx:
@ -4743,6 +4831,7 @@ unsub_top:
csid_hw->rx_cfg.top_irq_handle);
csid_hw->rx_cfg.top_irq_handle = 0;
err:
vfree(top_irq_mask);
return rc;
}
@ -5055,8 +5144,9 @@ static int cam_ife_csid_ver2_enable_hw(
int i, rc;
void __iomem *mem_base;
const struct cam_ife_csid_ver2_path_reg_info *path_reg = NULL;
uint32_t num_register = 0;
uint32_t top_err_irq_mask = 0;
uint32_t buf_done_irq_mask[CAM_IFE_CSID_IRQ_REGISTERS_MAX] = {0};
uint32_t *buf_done_irq_mask = NULL;
uint32_t top_info_irq_mask = 0;
if (csid_hw->flags.device_enabled) {
@ -5097,12 +5187,16 @@ static int cam_ife_csid_ver2_enable_hw(
/* Read hw version */
val = cam_io_r_mb(mem_base + csid_reg->cmn_reg->hw_version_addr);
buf_done_irq_mask[CAM_IFE_CSID_IRQ_TOP_REG_STATUS0] =
csid_reg->cmn_reg->top_buf_done_irq_mask;
num_register = csid_reg->top_irq_reg_info[CAM_IFE_CSID_TOP_IRQ_STATUS_REG0].num_registers;
buf_done_irq_mask = vmalloc(sizeof(uint32_t) * num_register);
if (!buf_done_irq_mask) {
CAM_ERR(CAM_ISP, "csid buf_done_irq_mask allocation failed");
return -ENOMEM;
}
buf_done_irq_mask[0] = csid_reg->cmn_reg->top_buf_done_irq_mask;
if (csid_reg->ipp_mc_reg)
buf_done_irq_mask[CAM_IFE_CSID_IRQ_TOP_REG_STATUS0] |=
csid_reg->ipp_mc_reg->comp_subgrp0_mask |
buf_done_irq_mask[0] |= csid_reg->ipp_mc_reg->comp_subgrp0_mask |
csid_reg->ipp_mc_reg->comp_subgrp2_mask;
csid_hw->buf_done_irq_handle = cam_irq_controller_subscribe_irq(
@ -5120,7 +5214,8 @@ static int cam_ife_csid_ver2_enable_hw(
if (csid_hw->buf_done_irq_handle < 1) {
CAM_ERR(CAM_ISP, "CSID[%u] buf done irq subscribe fail",
csid_hw->hw_intf->hw_idx);
return -EINVAL;
rc = -EINVAL;
goto free_buf_done_mask;
}
top_err_irq_mask = csid_reg->cmn_reg->top_err_irq_mask[CAM_IFE_CSID_TOP_IRQ_STATUS_REG0];
@ -5182,6 +5277,7 @@ static int cam_ife_csid_ver2_enable_hw(
csid_hw->flags.fatal_err_detected = false;
CAM_DBG(CAM_ISP, "CSID:%u CSID HW version: 0x%x",
csid_hw->hw_intf->hw_idx, val);
vfree(buf_done_irq_mask);
return 0;
@ -5196,6 +5292,8 @@ unsubscribe_buf_done:
csid_hw->top_irq_controller[CAM_IFE_CSID_TOP_IRQ_STATUS_REG0],
csid_hw->buf_done_irq_handle);
csid_hw->buf_done_irq_handle = 0;
free_buf_done_mask:
vfree(buf_done_irq_mask);
return rc;
}
@ -5649,7 +5747,7 @@ int cam_ife_csid_ver2_start(void *hw_priv, void *args,
}
}
CAM_INFO(CAM_ISP, "CSID:%u RUP:0x%x AUP: 0x%x MUP:0x%x at start updated: %s",
CAM_DBG(CAM_ISP, "CSID:%u RUP:0x%x AUP: 0x%x MUP:0x%x at start updated: %s",
csid_hw->hw_intf->hw_idx, rup_aup_mask.rup_mask, rup_aup_mask.aup_mask,
rup_aup_mask.rup_aup_set_mask, CAM_BOOL_TO_YESNO(!start_args->is_internal_start));
@ -5831,7 +5929,6 @@ int cam_ife_csid_ver2_stop(void *hw_priv,
/* Issue a halt & reset to ensure there is no HW activity post the halt block */
reset.reset_type = CAM_IFE_CSID_RESET_PATH;
reset.power_on_reset = false;
cam_ife_csid_ver2_reset(hw_priv, &reset,
sizeof(struct cam_csid_reset_cfg_args));
@ -6182,7 +6279,7 @@ static int cam_ife_csid_ver2_reg_update(
if (rup_args->mup_en) {
csid_hw->rx_cfg.mup = rup_args->mup_val;
CAM_INFO(CAM_ISP, "CSID[%u] MUP %u",
CAM_DBG(CAM_ISP, "CSID[%u] MUP %u",
csid_hw->hw_intf->hw_idx, csid_hw->rx_cfg.mup);
}
@ -6191,7 +6288,6 @@ static int cam_ife_csid_ver2_reg_update(
else
cam_ife_csid_ver2_get_sc_reg_val_pair(csid_hw, reg_val_pair, rup_args);
rup_args->value = reg_val_pair[1];
if (rup_args->reg_write) {
for (i = 0; i < (2 * num_reg_val_pairs); i = i + 2)
cam_io_w_mb(reg_val_pair[i + 1], csid_clc_membase + reg_val_pair[i]);
@ -6547,72 +6643,6 @@ static int cam_ife_csid_ver2_update_frame_stats(
return 0;
}
static int cam_ife_csid_ver2_dump_frame_stats(
struct cam_ife_csid_ver2_hw *csid_hw)
{
int i, j;
uint32_t index, num_entries, oldest_entry, val0, val1;
struct cam_isp_resource_node *res;
const struct cam_ife_csid_ver2_reg_info *csid_reg;
const struct cam_ife_csid_ver2_path_reg_info *path_reg;
struct cam_ife_csid_ver2_path_cfg *path_cfg;
struct cam_hw_soc_info *soc_info;
struct cam_ife_csid_cid_data *cid_data;
int64_t state_head = 0;
csid_reg = (struct cam_ife_csid_ver2_reg_info *)
csid_hw->core_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
for (i = 0; i < CAM_IFE_PIX_PATH_RES_MAX; i++) {
res = &csid_hw->path_res[i];
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING)
continue;
path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv;
cid_data = &csid_hw->cid_data[path_cfg->cid];
path_reg = csid_reg->path_reg[res->res_id];
state_head = atomic64_read(&path_cfg->frame_stats_cntr);
val0 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
path_reg->format_measure1_addr);
val1 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
path_reg->format_measure2_addr);
CAM_INFO(CAM_ISP,
"PATH: %s current hbi_min: %u hbi_max: %u vblank: %u",
res->res_name, (val0 & 0xFFF), ((val0 >> 0x10) & 0xFFF), val1);
CAM_INFO(CAM_ISP, "vc0: %u dt0: %u vc1: %u dt1: %u vc1_valid: %u",
cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].vc,
cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].dt,
cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].vc,
cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].dt,
cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].valid);
if (state_head == -1)
continue;
if (state_head < CAM_CSID_MAX_FRAME_STATS_CNTR) {
num_entries = state_head + 1;
oldest_entry = 0;
} else {
num_entries = CAM_CSID_MAX_FRAME_STATS_CNTR;
div_u64_rem(state_head + 1, CAM_CSID_MAX_FRAME_STATS_CNTR,
&oldest_entry);
}
index = oldest_entry;
for (j = 0; j < num_entries; j++) {
CAM_INFO(CAM_ISP,
"PATH: %s Index: %u hbi_min: %u hbi_max: %u vblank: %u",
res->res_name, index, (path_cfg->frame_stats[index].hbi & 0xFFF),
((path_cfg->frame_stats[index].hbi >> 0x10) & 0xFFF),
path_cfg->frame_stats[index].vbi);
index = (index + 1) % CAM_CSID_MAX_FRAME_STATS_CNTR;
}
}
return 0;
}
static int cam_ife_csid_ver2_set_dynamic_switch_config(
struct cam_ife_csid_ver2_hw *csid_hw,
void *cmd_args)
@ -6631,7 +6661,7 @@ static int cam_ife_csid_ver2_set_dynamic_switch_config(
if (switch_update->mup_args.use_mup) {
csid_hw->rx_cfg.mup = switch_update->mup_args.mup_val;
CAM_INFO(CAM_ISP, "CSID[%u] MUP %u",
CAM_DBG(CAM_ISP, "CSID[%u] MUP %u",
csid_hw->hw_intf->hw_idx, csid_hw->rx_cfg.mup);
}

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_IFE_CSID_HW_VER2_H_
@ -752,6 +752,12 @@ struct cam_ife_csid_ver2_reg_info {
const uint32_t num_path_err_irqs;
const uint32_t num_top_regs;
const uint32_t num_rx_regs;
const uint32_t fused_max_dualife_width[
CAM_IFE_CSID_WIDTH_FUSE_VAL_MAX];
const uint32_t fused_max_width[
CAM_IFE_CSID_WIDTH_FUSE_VAL_MAX];
const uint32_t width_fuse_max_val;
bool is_ife_sfe_mapped;
};
/*

View File

@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_IFE_CSID_LITE_860_H_
#define _CAM_IFE_CSID_LITE_860_H_
#include "cam_ife_csid_common.h"
#include "cam_ife_csid_dev.h"
#include "cam_ife_csid_hw_ver2.h"
#include "cam_irq_controller.h"
#include "cam_isp_hw_mgr_intf.h"
#include "cam_ife_csid_lite880.h"
static struct cam_ife_csid_ver2_reg_info cam_ife_csid_lite_860_reg_info = {
.top_irq_reg_info = &cam_ife_csid_lite_880_top_irq_reg_info,
.rx_irq_reg_info = &cam_ife_csid_lite_880_rx_irq_reg_info,
.path_irq_reg_info = {
&cam_ife_csid_lite_880_path_irq_reg_info[CAM_IFE_PIX_PATH_RES_RDI_0],
&cam_ife_csid_lite_880_path_irq_reg_info[CAM_IFE_PIX_PATH_RES_RDI_1],
&cam_ife_csid_lite_880_path_irq_reg_info[CAM_IFE_PIX_PATH_RES_RDI_2],
&cam_ife_csid_lite_880_path_irq_reg_info[CAM_IFE_PIX_PATH_RES_RDI_3],
NULL,
&cam_ife_csid_lite_880_path_irq_reg_info[CAM_IFE_PIX_PATH_RES_IPP],
},
.buf_done_irq_reg_info = &cam_ife_csid_lite_880_buf_done_irq_reg_info,
.cmn_reg = &cam_ife_csid_lite_880_cmn_reg_info,
.csi2_reg = &cam_ife_csid_lite_880_csi2_reg_info,
.path_reg[CAM_IFE_PIX_PATH_RES_IPP] = &cam_ife_csid_lite_880_ipp_reg_info,
.path_reg[CAM_IFE_PIX_PATH_RES_PPP] = NULL,
.path_reg[CAM_IFE_PIX_PATH_RES_RDI_0] = &cam_ife_csid_lite_880_rdi_0_reg_info,
.path_reg[CAM_IFE_PIX_PATH_RES_RDI_1] = &cam_ife_csid_lite_880_rdi_1_reg_info,
.path_reg[CAM_IFE_PIX_PATH_RES_RDI_2] = &cam_ife_csid_lite_880_rdi_2_reg_info,
.path_reg[CAM_IFE_PIX_PATH_RES_RDI_3] = &cam_ife_csid_lite_880_rdi_3_reg_info,
.need_top_cfg = 0,
.top_irq_desc = &cam_ife_csid_lite_880_top_irq_desc,
.rx_irq_desc = &cam_ife_csid_lite_880_rx_irq_desc,
.path_irq_desc = cam_ife_csid_lite_880_path_irq_desc,
.num_top_err_irqs = cam_ife_csid_lite_880_num_top_irq_desc,
.num_rx_err_irqs = cam_ife_csid_lite_880_num_rx_irq_desc,
.num_path_err_irqs = ARRAY_SIZE(cam_ife_csid_lite_880_path_irq_desc),
.num_top_regs = 1,
.num_rx_regs = 1,
.is_ife_sfe_mapped = true,
};
#endif /* _CAM_IFE_CSID_LITE_860_H_ */

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_IFE_CSID_LITE_880_H_
@ -1067,5 +1067,6 @@ static struct cam_ife_csid_ver2_reg_info cam_ife_csid_lite_880_reg_info = {
.num_path_err_irqs = ARRAY_SIZE(cam_ife_csid_lite_880_path_irq_desc),
.num_top_regs = 1,
.num_rx_regs = 1,
.is_ife_sfe_mapped = true,
};
#endif /* _CAM_IFE_CSID_LITE_780_H_ */

View File

@ -13,6 +13,7 @@
#include "cam_ife_csid_lite480.h"
#include "cam_ife_csid_lite680.h"
#include "cam_ife_csid_lite780.h"
#include "cam_ife_csid_lite860.h"
#include "cam_ife_csid_lite880.h"
#define CAM_CSID_LITE_DRV_NAME "csid_lite"
@ -37,6 +38,11 @@ static struct cam_ife_csid_core_info cam_ife_csid_lite_780_hw_info = {
.sw_version = CAM_IFE_CSID_VER_2_0,
};
static struct cam_ife_csid_core_info cam_ife_csid_lite_860_hw_info = {
.csid_reg = &cam_ife_csid_lite_860_reg_info,
.sw_version = CAM_IFE_CSID_VER_2_0,
};
static struct cam_ife_csid_core_info cam_ife_csid_lite_880_hw_info = {
.csid_reg = &cam_ife_csid_lite_880_reg_info,
.sw_version = CAM_IFE_CSID_VER_2_0,
@ -79,6 +85,10 @@ static const struct of_device_id cam_ife_csid_lite_dt_match[] = {
.compatible = "qcom,csid-lite780",
.data = &cam_ife_csid_lite_780_hw_info,
},
{
.compatible = "qcom,csid-lite860",
.data = &cam_ife_csid_lite_860_hw_info,
},
{
.compatible = "qcom,csid-lite880",
.data = &cam_ife_csid_lite_880_hw_info,

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@ -20,6 +20,7 @@
#include "cam_ife_csid680.h"
#include "cam_ife_csid680_110.h"
#include "cam_ife_csid780.h"
#include "cam_ife_csid860.h"
#include "cam_ife_csid880.h"
#include "cam_ife_csid980.h"
@ -80,6 +81,11 @@ static struct cam_ife_csid_core_info cam_ife_csid780_hw_info = {
.sw_version = CAM_IFE_CSID_VER_2_0,
};
static struct cam_ife_csid_core_info cam_ife_csid860_hw_info = {
.csid_reg = &cam_ife_csid_860_reg_info,
.sw_version = CAM_IFE_CSID_VER_2_0,
};
static struct cam_ife_csid_core_info cam_ife_csid880_hw_info = {
.csid_reg = &cam_ife_csid_880_reg_info,
.sw_version = CAM_IFE_CSID_VER_2_0,
@ -136,6 +142,10 @@ static const struct of_device_id cam_ife_csid_dt_match[] = {
.compatible = "qcom,csid780",
.data = &cam_ife_csid780_hw_info,
},
{
.compatible = "qcom,csid860",
.data = &cam_ife_csid860_hw_info,
},
{
.compatible = "qcom,csid880",
.data = &cam_ife_csid880_hw_info,

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_CSID_HW_INTF_H_
@ -16,7 +16,6 @@
#define RT_BASE_IDX 2
#define CAM_ISP_MAX_PATHS 8
/**
* enum cam_ife_csid_hw_irq_regs - Specify the top irq reg
*/
@ -109,6 +108,7 @@ enum cam_ife_csid_secondary_evt_type {
* @rup_en: flag to indicate if rup is on csid side
* @only_master_rup: flag to indicate if only master RUP
* @camif_irq_support: flag to indicate if CSID supports CAMIF irq
* @is_ife_sfe_mapped: flag to indicate if IFE & SFE are one-one mapped
*/
struct cam_ife_csid_hw_caps {
uint32_t num_rdis;
@ -123,6 +123,7 @@ struct cam_ife_csid_hw_caps {
bool rup_en;
bool only_master_rup;
bool camif_irq_support;
bool is_ife_sfe_mapped;
};
struct cam_isp_out_port_generic_info {
@ -482,7 +483,6 @@ struct cam_isp_csid_reg_update_args {
bool reg_write;
uint32_t mup_val;
uint32_t mup_en;
uint32_t value;
};
/*

View File

@ -214,6 +214,7 @@ enum cam_isp_hw_cmd_type {
CAM_ISP_HW_CMD_FE_TRIGGER_CMD,
CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ,
CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT,
CAM_ISP_HW_CMD_GET_LAST_CONSUMED_ADDR,
CAM_ISP_HW_CMD_GET_RES_FOR_MID,
CAM_ISP_HW_CMD_BLANKING_UPDATE,
CAM_ISP_HW_CMD_CSID_CLOCK_DUMP,
@ -258,7 +259,10 @@ enum cam_isp_hw_cmd_type {
#if defined(CONFIG_SAMSUNG_DEBUG_SENSOR_TIMING)
CAM_IFE_CSID_SOF_IRQ_DEBUG_FOR_MODESWITCH,
#endif
CAM_ISP_HW_CMD_GET_LAST_CONSUMED_ADDR,
CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE,
CAM_ISP_HW_CMD_SET_SYNC_HW_IDX,
CAM_ISP_HW_CMD_BUS_WM_DISABLE,
CAM_ISP_HW_CMD_BUFFER_ALIGNMENT_UPDATE,
CAM_IFE_CSID_CMD_GET_PATH_TIME_STAMP,
CAM_ISP_HW_CMD_MAX,
};
@ -441,11 +445,13 @@ struct cam_isp_hw_get_wm_update {
* @Brief: Get the out resource id for given mid
*
* @mid: Mid number of hw outport numb
* @pid: Pid number associated with mid
* @out_res_id: Out resource id
*
*/
struct cam_isp_hw_get_res_for_mid {
uint32_t mid;
uint32_t pid;
uint32_t out_res_id;
};
@ -518,6 +524,7 @@ struct cam_isp_hw_fcg_cmd {
* @cmd: Command buffer information
* @use_scratch_cfg: To indicate if it's scratch buffer config
* @trigger_cdm_en: Flag to indicate if cdm is trigger
* @reg_write: if set use AHB to config rup/aup
*
*/
struct cam_isp_hw_get_cmd_update {
@ -532,6 +539,7 @@ struct cam_isp_hw_get_cmd_update {
struct cam_isp_hw_get_wm_update *rm_update;
};
bool trigger_cdm_en;
bool reg_write;
};
/*
@ -587,6 +595,20 @@ struct cam_isp_hw_dump_header {
uint32_t word_size;
};
/**
* struct cam_isp_session_data - Session data
*
* @Brief: ISP session or usecase data
*
* @link_hdl: Link handle
* @is_shdr: Indicate is usecase is shdr
*
*/
struct cam_isp_session_data {
int32_t link_hdl;
bool is_shdr;
};
/**
* struct cam_isp_hw_intf_data - ISP hw intf data
*

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_TFE_CSID_HW_INTF_H_
@ -12,7 +12,7 @@
#include "cam_tfe.h"
/* MAX TFE CSID instance */
#define CAM_TFE_CSID_HW_NUM_MAX 3
#define CAM_TFE_CSID_HW_NUM_MAX 4
#define CAM_TFE_CSID_RDI_MAX 3
/**
@ -23,6 +23,7 @@ enum cam_tfe_csid_path_res_id {
CAM_TFE_CSID_PATH_RES_RDI_1,
CAM_TFE_CSID_PATH_RES_RDI_2,
CAM_TFE_CSID_PATH_RES_IPP,
CAM_TFE_CSID_PATH_RES_PPP,
CAM_TFE_CSID_PATH_RES_MAX,
};
@ -36,6 +37,7 @@ enum cam_tfe_csid_irq_reg {
TFE_CSID_IRQ_REG_TOP,
TFE_CSID_IRQ_REG_RX,
TFE_CSID_IRQ_REG_IPP,
TFE_CSID_IRQ_REG_PPP,
TFE_CSID_IRQ_REG_MAX,
};
@ -89,6 +91,9 @@ struct cam_isp_tfe_in_port_generic_info {
uint32_t ipp_count;
uint32_t rdi_count;
uint32_t secure_mode;
bool shdr_en;
bool is_shdr_master;
bool epd_supported;
struct cam_isp_tfe_out_port_generic_info *data;
};
@ -96,17 +101,23 @@ struct cam_isp_tfe_in_port_generic_info {
* struct cam_tfe_csid_hw_caps- get the CSID hw capability
* @num_rdis: number of rdis supported by CSID HW device
* @num_pix: number of pxl paths supported by CSID HW device
* @num_ppp: number of ppp paths supported by CSID HW device
* @major_version : major version
* @minor_version: minor version
* @version_incr: version increment
* @sync_clk: sync clocks such that freq(TFE)>freq(CSID)>freq(CSIPHY)
* @is_lite: Indicate if it is CSID Lite
*
*/
struct cam_tfe_csid_hw_caps {
uint32_t num_rdis;
uint32_t num_pix;
uint32_t num_ppp;
uint32_t major_version;
uint32_t minor_version;
uint32_t version_incr;
bool sync_clk;
bool is_lite;
};
/**
@ -124,6 +135,7 @@ struct cam_tfe_csid_hw_caps {
* @event_cb_prv: Context data
* @event_cb: Callback function to hw mgr in case of hw events
* @node_res : Reserved resource structure pointer
* @crop_enable : Flag to indicate CSID crop enable
*
*/
struct cam_tfe_csid_hw_reserve_resource_args {
@ -137,6 +149,7 @@ struct cam_tfe_csid_hw_reserve_resource_args {
void *event_cb_prv;
cam_hw_mgr_event_cb_func event_cb;
struct cam_isp_resource_node *node_res;
bool crop_enable;
};
/**
@ -261,5 +274,15 @@ struct cam_tfe_csid_clock_update_args {
uint64_t clk_rate;
};
/*
* struct cam_tfe_csid_discard_init_frame_args:
*
* @num_frames: Num frames to discard
* @res: Node res for this path
*/
struct cam_tfe_csid_discard_init_frame_args {
uint32_t num_frames;
struct cam_isp_resource_node *res;
};
#endif /* _CAM_TFE_CSID_HW_INTF_H_ */

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_TFE_HW_INTF_H_
@ -10,7 +10,7 @@
#include "cam_isp_hw.h"
#include "cam_cpas_api.h"
#define CAM_TFE_HW_NUM_MAX 3
#define CAM_TFE_HW_NUM_MAX 4
#define TFE_CORE_BASE_IDX 0
@ -19,6 +19,7 @@ enum cam_isp_hw_tfe_in {
CAM_ISP_HW_TFE_IN_RDI0 = 1,
CAM_ISP_HW_TFE_IN_RDI1 = 2,
CAM_ISP_HW_TFE_IN_RDI2 = 3,
CAM_ISP_HW_TFE_IN_PDLIB = 4,
CAM_ISP_HW_TFE_IN_MAX,
};
@ -35,6 +36,7 @@ enum cam_tfe_hw_irq_status {
CAM_TFE_IRQ_STATUS_OVERFLOW,
CAM_TFE_IRQ_STATUS_P2I_ERROR,
CAM_TFE_IRQ_STATUS_VIOLATION,
CAM_TFE_IRQ_STATUS_OUT_OF_SYNC,
CAM_TFE_IRQ_STATUS_MAX,
};
@ -120,6 +122,7 @@ struct cam_tfe_hw_tfe_out_acquire_args {
* @in_port: Input port details to acquire
* @camif_pd_enable Camif pd enable or disable
* @dual_tfe_sync_sel_idx Dual tfe master hardware index
* @lcr_enable LCR enable field
*/
struct cam_tfe_hw_tfe_in_acquire_args {
struct cam_isp_resource_node *rsrc_node;
@ -129,6 +132,7 @@ struct cam_tfe_hw_tfe_in_acquire_args {
enum cam_isp_hw_sync_mode sync_mode;
bool camif_pd_enable;
uint32_t dual_tfe_sync_sel_idx;
bool lcr_enable;
};
/*
@ -244,6 +248,24 @@ struct cam_tfe_irq_evt_payload {
uint32_t last_consumed_addr;
};
/*
* cam_tfe_get_num_tfe_hws()
*
* @brief: Gets number of TFEs
*
* @num_tfes: Fills number of TFES in the address passed
*/
void cam_tfe_get_num_tfe_hws(uint32_t *num_tfes);
/*
* cam_tfe_get_num_tfe_lite_hws()
*
* @brief: Gets number of TFE-LITEs
*
* @num_tfe_lites: Fills number of TFE-LITEs in the address passed
*/
void cam_tfe_get_num_tfe_lite_hws(uint32_t *num_tfe_lites);
/*
* cam_tfe_hw_init()
*

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
@ -108,6 +109,12 @@ static void cam_ppi_component_unbind(struct device *dev,
struct platform_device *pdev = to_platform_device(dev);
ppi_dev = (struct cam_csid_ppi_hw *)platform_get_drvdata(pdev);
if (!ppi_dev) {
CAM_ERR(CAM_ISP, "Error No data in ppi_dev");
return;
}
ppi_hw_intf = ppi_dev->hw_intf;
ppi_hw_info = ppi_dev->hw_info;

View File

@ -0,0 +1,149 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_SFE860_H_
#define _CAM_SFE860_H_
#include "cam_sfe_core.h"
#include "cam_sfe_bus.h"
#include "cam_sfe_bus_rd.h"
#include "cam_sfe_bus_wr.h"
#include "cam_sfe880.h"
static struct cam_sfe_top_common_reg_offset sfe860_top_commong_reg = {
.hw_version = 0x00000000,
.hw_capability = 0x00000004,
.stats_feature = 0x00000008,
.core_cgc_ctrl = 0x00000010,
.ahb_clk_ovd = 0x00000014,
.core_cfg = 0x000000CC,
.ipp_violation_status = 0x00000030,
.diag_config = 0x00000034,
.diag_sensor_status_0 = 0x00000038,
.diag_sensor_status_1 = 0x0000003C,
.diag_sensor_frame_cnt_status0 = 0x00000040,
.diag_sensor_frame_cnt_status1 = 0x00000044,
.stats_ch2_throttle_cfg = 0x000000B0,
.stats_ch1_throttle_cfg = 0x000000B4,
.stats_ch0_throttle_cfg = 0x000000B8,
.hdr_throttle_cfg = 0x000000C0,
.sfe_op_throttle_cfg = 0x000000C4,
.irc_throttle_cfg = 0x000000C8,
.sfe_single_dual_cfg = 0x000000D0,
.bus_overflow_status = 0x00000868,
.num_perf_counters = 2,
.perf_count_reg = {
{
.perf_count_cfg = 0x00000080,
.perf_pix_count = 0x00000084,
.perf_line_count = 0x00000088,
.perf_stall_count = 0x0000008C,
.perf_always_count = 0x00000090,
.perf_count_status = 0x00000094,
},
{
.perf_count_cfg = 0x00000098,
.perf_pix_count = 0x0000009C,
.perf_line_count = 0x000000A0,
.perf_stall_count = 0x000000A4,
.perf_always_count = 0x000000A8,
.perf_count_status = 0x000000AC,
},
},
.top_debug_cfg = 0x0000007C,
.top_cc_test_bus_ctrl = 0x000001F0,
.lcr_supported = false,
.ir_supported = true,
.qcfa_only = false,
.num_sfe_mode = ARRAY_SIZE(sfe_880_mode),
.sfe_mode = sfe_880_mode,
.ipp_violation_mask = 0x4000,
.top_debug_testbus_reg = 13,
.top_debug_nonccif_regstart_idx = 12,
.top_cc_test_bus_supported = true,
.num_debug_registers = 20,
.top_debug = {
0x0000004C,
0x00000050,
0x00000054,
0x00000058,
0x0000005C,
0x00000060,
0x00000064,
0x00000068,
0x0000006C,
0x00000070,
0x00000074,
0x00000078,
0x000000EC,
0x000000F0,
0x000000F4,
0x000000F8,
0x000000FC,
0x00000100,
0x00000104,
0x00000108,
},
};
static struct cam_sfe_top_hw_info sfe860_top_hw_info = {
.common_reg = &sfe860_top_commong_reg,
.modules_hw_info = &sfe880_modules_common_reg,
.common_reg_data = &sfe_880_top_common_reg_data,
.ipp_module_desc = sfe_880_mod_desc,
.wr_client_desc = sfe_880_wr_client_desc,
.pix_reg_data = &sfe_880_pix_reg_data,
.rdi_reg_data[0] = &sfe_880_rdi0_reg_data,
.rdi_reg_data[1] = &sfe_880_rdi1_reg_data,
.rdi_reg_data[2] = &sfe_880_rdi2_reg_data,
.rdi_reg_data[3] = &sfe_880_rdi3_reg_data,
.rdi_reg_data[4] = &sfe_880_rdi4_reg_data,
.num_inputs = 6,
.input_type = {
CAM_SFE_PIX_VER_1_0,
CAM_SFE_RDI_VER_1_0,
CAM_SFE_RDI_VER_1_0,
CAM_SFE_RDI_VER_1_0,
CAM_SFE_RDI_VER_1_0,
CAM_SFE_RDI_VER_1_0,
},
.num_top_errors = ARRAY_SIZE(sfe_880_top_irq_err_desc),
.top_err_desc = sfe_880_top_irq_err_desc,
.num_clc_module = 12,
.clc_dbg_mod_info = &sfe880_clc_dbg_module_info,
.num_of_testbus = 2,
.test_bus_info = {
/* TEST BUS 1 INFO */
{
.debugfs_val = SFE_DEBUG_ENABLE_TESTBUS1,
.enable = false,
.value = 0x1,
.size = ARRAY_SIZE(sfe880_testbus1_info),
.testbus = sfe880_testbus1_info,
},
/* TEST BUS 2 INFO */
{
.debugfs_val = SFE_DEBUG_ENABLE_TESTBUS2,
.enable = false,
.value = 0x3,
.size = ARRAY_SIZE(sfe880_testbus2_info),
.testbus = sfe880_testbus2_info,
},
},
};
struct cam_sfe_hw_info cam_sfe860_hw_info = {
.irq_reg_info = &sfe880_top_irq_reg_info,
.bus_wr_version = CAM_SFE_BUS_WR_VER_1_0,
.bus_wr_hw_info = &sfe880_bus_wr_hw_info,
.bus_rd_version = CAM_SFE_BUS_RD_VER_1_0,
.bus_rd_hw_info = &sfe880_bus_rd_hw_info,
.top_version = CAM_SFE_TOP_VER_1_0,
.top_hw_info = &sfe860_top_hw_info,
};
#endif /* _CAM_SFE860_H_ */

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
@ -14,6 +14,7 @@
#include "cam_sfe_soc.h"
#include "cam_sfe680.h"
#include "cam_sfe780.h"
#include "cam_sfe860.h"
#include "cam_sfe880.h"
#include "cam_debug_util.h"
#include "camera_main.h"
@ -261,6 +262,10 @@ static const struct of_device_id cam_sfe_dt_match[] = {
.compatible = "qcom,sfe780",
.data = &cam_sfe780_hw_info,
},
{
.compatible = "qcom,sfe860",
.data = &cam_sfe860_hw_info,
},
{
.compatible = "qcom,sfe880",
.data = &cam_sfe880_hw_info,

View File

@ -780,6 +780,11 @@ static int cam_sfe_top_get_base(
mem_base = CAM_SOC_GET_REG_MAP_CAM_BASE(
top_priv->common_data.soc_info,
SFE_CORE_BASE_IDX);
if (mem_base == -1) {
CAM_ERR(CAM_SFE, "failed to get mem_base, index: %d num_reg_map: %u",
SFE_CORE_BASE_IDX, top_priv->common_data.soc_info->num_reg_map);
return -EINVAL;
}
if (cdm_args->cdm_id == CAM_CDM_RT) {
if (!soc_private->rt_wrapper_base) {
@ -1190,6 +1195,7 @@ static int cam_sfe_top_apply_fcg_update(
}
fcg_index_shift = fcg_module_info->fcg_index_shift;
for (i = 0, j = 0; i < fcg_config->num_ch_ctx; i++) {
if (j >= fcg_module_info->max_reg_val_pair_size) {
CAM_ERR(CAM_SFE, "reg_val_pair %d exceeds the array limit %u",
@ -1836,7 +1842,7 @@ static int cam_sfe_top_handle_irq_bottom_half(
void *handler_priv, void *evt_payload_priv)
{
int i;
uint32_t val0, val1, frame_cnt = 0, offset0, offset1;
uint32_t val0, val1, frame_cnt, offset0, offset1;
uint32_t irq_status[CAM_SFE_IRQ_REGISTERS_MAX] = {0};
enum cam_sfe_hw_irq_status ret = CAM_SFE_IRQ_STATUS_MAX;
struct cam_isp_resource_node *res = handler_priv;

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
@ -8,6 +9,9 @@
#include "cam_tfe_csid_core.h"
#include "cam_tfe_csid530.h"
#include "cam_tfe_csid640.h"
#include "cam_tfe_csid640_210.h"
#include "cam_tfe_csid770.h"
#include "cam_tfe_csid665.h"
#include "cam_tfe_csid_dev.h"
#include "camera_main.h"
@ -22,6 +26,22 @@ static const struct of_device_id cam_tfe_csid_dt_match[] = {
.compatible = "qcom,csid640",
.data = &cam_tfe_csid640_hw_info,
},
{
.compatible = "qcom,csid640_210",
.data = &cam_tfe_csid640_210_hw_info,
},
{
.compatible = "qcom,csid770",
.data = &cam_tfe_csid770_hw_info,
},
{
.compatible = "qcom,csid-lite770",
.data = &cam_tfe_csid770_hw_info,
},
{
.compatible = "qcom,csid665",
.data = &cam_tfe_csid665_hw_info,
},
{}
};

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_TFE_CSID_530_H_
@ -178,6 +179,7 @@ static struct cam_tfe_csid_csi2_rx_reg_offset
.csi2_rx_long_pkt_hdr_rst_stb_shift = 0x1,
.csi2_rx_short_pkt_hdr_rst_stb_shift = 0x2,
.csi2_rx_cphy_pkt_hdr_rst_stb_shift = 0x3,
.need_to_sel_tpg_mux = false,
};
static struct cam_tfe_csid_common_reg_offset

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_TFE_CSID_640_H_
@ -199,7 +200,7 @@ static struct cam_tfe_csid_csi2_rx_reg_offset
.csid_csi2_rx_stats_ecc_addr = 0x164,
.csid_csi2_rx_total_crc_err_addr = 0x168,
.phy_tpg_base_id = 0,
.phy_tpg_base_id = 1,
.csi2_rst_srb_all = 0x3FFF,
.csi2_rst_done_shift_val = 27,
.csi2_irq_mask_all = 0xFFFFFFF,
@ -216,6 +217,7 @@ static struct cam_tfe_csid_csi2_rx_reg_offset
.csi2_rx_long_pkt_hdr_rst_stb_shift = 0x1,
.csi2_rx_short_pkt_hdr_rst_stb_shift = 0x2,
.csi2_rx_cphy_pkt_hdr_rst_stb_shift = 0x3,
.need_to_sel_tpg_mux = true,
};
static struct cam_tfe_csid_common_reg_offset
@ -264,6 +266,7 @@ static struct cam_tfe_csid_common_reg_offset
.format_measure_height_shift_val = 16,
.format_measure_height_mask_val = 0xe,
.format_measure_width_mask_val = 0x10,
.sync_clk = true,
};
static struct cam_tfe_csid_reg_offset cam_tfe_csid_640_reg_offset = {

View File

@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_TFE_CSID_640_210_H_
#define _CAM_TFE_CSID_640_210_H_
#include "cam_tfe_csid_core.h"
#include "cam_tfe_csid640.h"
#define CAM_TFE_CSID_VERSION_V640_210 0x60040000
static struct cam_tfe_csid_hw_info cam_tfe_csid640_210_hw_info = {
.csid_reg = &cam_tfe_csid_640_reg_offset,
.hw_dts_version = CAM_TFE_CSID_VERSION_V640_210,
};
#endif /*_CAM_TFE_CSID_640_210_H_ */

View File

@ -0,0 +1,373 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_TFE_CSID_665_H_
#define _CAM_TFE_CSID_665_H_
#include "cam_tfe_csid_core.h"
#define CAM_TFE_CSID_VERSION_V665 0x70065000
static struct cam_tfe_csid_pxl_reg_offset cam_tfe_csid_665_ipp_reg_offset = {
.csid_pxl_irq_status_addr = 0x30,
.csid_pxl_irq_mask_addr = 0x34,
.csid_pxl_irq_clear_addr = 0x38,
.csid_pxl_irq_set_addr = 0x3c,
.csid_pxl_cfg0_addr = 0x200,
.csid_pxl_cfg1_addr = 0x204,
.csid_pxl_ctrl_addr = 0x208,
.csid_pxl_frame_drop_pattern = 0x20c,
.csid_pxl_frame_drop_period = 0x210,
.csid_pxl_irq_subsample_pattern = 0x214,
.csid_pxl_irq_subsample_period = 0x218,
.csid_pxl_hcrop_addr = 0x21c,
.csid_pxl_vcrop_addr = 0x220,
.csid_pxl_rst_strobes_addr = 0x240,
.csid_pxl_status_addr = 0x254,
.csid_pxl_misr_val_addr = 0x258,
.csid_pxl_format_measure_cfg0_addr = 0x270,
.csid_pxl_format_measure_cfg1_addr = 0x274,
.csid_pxl_format_measure0_addr = 0x278,
.csid_pxl_format_measure1_addr = 0x27c,
.csid_pxl_format_measure2_addr = 0x280,
.csid_pxl_timestamp_curr0_sof_addr = 0x290,
.csid_pxl_timestamp_curr1_sof_addr = 0x294,
.csid_pxl_timestamp_perv0_sof_addr = 0x298,
.csid_pxl_timestamp_perv1_sof_addr = 0x29c,
.csid_pxl_timestamp_curr0_eof_addr = 0x2a0,
.csid_pxl_timestamp_curr1_eof_addr = 0x2a4,
.csid_pxl_timestamp_perv0_eof_addr = 0x2a8,
.csid_pxl_timestamp_perv1_eof_addr = 0x2ac,
.csid_pxl_err_recovery_cfg0_addr = 0x2d0,
.csid_pxl_err_recovery_cfg1_addr = 0x2d4,
.csid_pxl_err_recovery_cfg2_addr = 0x2d8,
.csid_pxl_multi_vcdt_cfg0_addr = 0x2dc,
/* configurations */
.pix_store_en_shift_val = 7,
.early_eof_en_shift_val = 29,
.halt_master_sel_shift = 4,
.halt_mode_shift = 2,
.halt_mode_mask = 3,
.halt_master_sel_master_val = 1,
.halt_master_sel_slave_val = 0,
.binning_supported = 3,
.bin_qcfa_en_shift_val = 30,
.bin_en_shift_val = 2,
.is_multi_vc_dt_supported = true,
.format_measure_en_shift_val = 0,
.measure_en_hbi_vbi_cnt_val = 0xc,
.cgc_mode_en_shift_val = 9,
};
static struct cam_tfe_csid_pxl_reg_offset cam_tfe_csid_665_ppp_reg_offset = {
.csid_pxl_irq_status_addr = 0xA0,
.csid_pxl_irq_mask_addr = 0xA4,
.csid_pxl_irq_clear_addr = 0xA8,
.csid_pxl_irq_set_addr = 0xAc,
.csid_pxl_cfg0_addr = 0x700,
.csid_pxl_cfg1_addr = 0x704,
.csid_pxl_ctrl_addr = 0x708,
.csid_pxl_frame_drop_pattern = 0x70c,
.csid_pxl_frame_drop_period = 0x710,
.csid_pxl_irq_subsample_pattern = 0x714,
.csid_pxl_irq_subsample_period = 0x718,
.csid_pxl_hcrop_addr = 0x71c,
.csid_pxl_vcrop_addr = 0x720,
.csid_pxl_rst_strobes_addr = 0x740,
.csid_pxl_status_addr = 0x754,
.csid_pxl_misr_val_addr = 0x758,
.csid_pxl_format_measure_cfg0_addr = 0x770,
.csid_pxl_format_measure_cfg1_addr = 0x774,
.csid_pxl_format_measure0_addr = 0x778,
.csid_pxl_format_measure1_addr = 0x77c,
.csid_pxl_format_measure2_addr = 0x780,
.csid_pxl_timestamp_curr0_sof_addr = 0x790,
.csid_pxl_timestamp_curr1_sof_addr = 0x794,
.csid_pxl_timestamp_perv0_sof_addr = 0x798,
.csid_pxl_timestamp_perv1_sof_addr = 0x79c,
.csid_pxl_timestamp_curr0_eof_addr = 0x7a0,
.csid_pxl_timestamp_curr1_eof_addr = 0x7a4,
.csid_pxl_timestamp_perv0_eof_addr = 0x7a8,
.csid_pxl_timestamp_perv1_eof_addr = 0x7ac,
.csid_pxl_ppp_sparse_pd_ext_cfg0 = 0x7c0,
.csid_pxl_err_recovery_cfg0_addr = 0x7d0,
.csid_pxl_err_recovery_cfg1_addr = 0x7d4,
.csid_pxl_err_recovery_cfg2_addr = 0x7d8,
.csid_pxl_multi_vcdt_cfg0_addr = 0x7dc,
/* configurations */
.pix_store_en_shift_val = 7,
.early_eof_en_shift_val = 29,
.halt_master_sel_shift = 4,
.halt_mode_shift = 2,
.halt_mode_mask = 3,
.halt_master_sel_master_val = 3,
.halt_master_sel_slave_val = 2,
.binning_supported = 0,
.bin_qcfa_en_shift_val = 30,
.bin_en_shift_val = 2,
.is_multi_vc_dt_supported = true,
.format_measure_en_shift_val = 0,
.measure_en_hbi_vbi_cnt_val = 0xc,
.cgc_mode_en_shift_val = 9,
};
static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_665_rdi_0_reg_offset = {
.csid_rdi_irq_status_addr = 0x40,
.csid_rdi_irq_mask_addr = 0x44,
.csid_rdi_irq_clear_addr = 0x48,
.csid_rdi_irq_set_addr = 0x4c,
.csid_rdi_cfg0_addr = 0x300,
.csid_rdi_cfg1_addr = 0x304,
.csid_rdi_ctrl_addr = 0x308,
.csid_rdi_frame_drop_pattern = 0x30c,
.csid_rdi_frame_drop_period = 0x310,
.csid_rdi_irq_subsample_pattern = 0x314,
.csid_rdi_irq_subsample_period = 0x318,
.csid_rdi_rst_strobes_addr = 0x340,
.csid_rdi_status_addr = 0x350,
.csid_rdi_misr_val0_addr = 0x354,
.csid_rdi_misr_val1_addr = 0x358,
.csid_rdi_misr_val2_addr = 0x35c,
.csid_rdi_misr_val3_addr = 0x360,
.csid_rdi_format_measure_cfg0_addr = 0x370,
.csid_rdi_format_measure_cfg1_addr = 0x374,
.csid_rdi_format_measure0_addr = 0x378,
.csid_rdi_format_measure1_addr = 0x37c,
.csid_rdi_format_measure2_addr = 0x380,
.csid_rdi_timestamp_curr0_sof_addr = 0x390,
.csid_rdi_timestamp_curr1_sof_addr = 0x394,
.csid_rdi_timestamp_prev0_sof_addr = 0x398,
.csid_rdi_timestamp_prev1_sof_addr = 0x39c,
.csid_rdi_timestamp_curr0_eof_addr = 0x3a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x3a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x3a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x3ac,
.csid_rdi_err_recovery_cfg0_addr = 0x3b0,
.csid_rdi_err_recovery_cfg1_addr = 0x3b4,
.csid_rdi_err_recovery_cfg2_addr = 0x3b8,
.csid_rdi_byte_cntr_ping_addr = 0x3e0,
.csid_rdi_byte_cntr_pong_addr = 0x3e4,
.csid_rdi_multi_vcdt_cfg0_addr = 0x3bc,
/* configurations */
.is_multi_vc_dt_supported = true,
.format_measure_en_shift_val = 0,
.measure_en_hbi_vbi_cnt_val = 0xc,
.cgc_mode_en_shift_val = 8,
};
static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_665_rdi_1_reg_offset = {
.csid_rdi_irq_status_addr = 0x50,
.csid_rdi_irq_mask_addr = 0x54,
.csid_rdi_irq_clear_addr = 0x58,
.csid_rdi_irq_set_addr = 0x5c,
.csid_rdi_cfg0_addr = 0x400,
.csid_rdi_cfg1_addr = 0x404,
.csid_rdi_ctrl_addr = 0x408,
.csid_rdi_frame_drop_pattern = 0x40c,
.csid_rdi_frame_drop_period = 0x410,
.csid_rdi_irq_subsample_pattern = 0x414,
.csid_rdi_irq_subsample_period = 0x418,
.csid_rdi_rst_strobes_addr = 0x440,
.csid_rdi_status_addr = 0x450,
.csid_rdi_misr_val0_addr = 0x454,
.csid_rdi_misr_val1_addr = 0x458,
.csid_rdi_misr_val2_addr = 0x45c,
.csid_rdi_misr_val3_addr = 0x460,
.csid_rdi_format_measure_cfg0_addr = 0x470,
.csid_rdi_format_measure_cfg1_addr = 0x474,
.csid_rdi_format_measure0_addr = 0x478,
.csid_rdi_format_measure1_addr = 0x47c,
.csid_rdi_format_measure2_addr = 0x480,
.csid_rdi_timestamp_curr0_sof_addr = 0x490,
.csid_rdi_timestamp_curr1_sof_addr = 0x494,
.csid_rdi_timestamp_prev0_sof_addr = 0x498,
.csid_rdi_timestamp_prev1_sof_addr = 0x49c,
.csid_rdi_timestamp_curr0_eof_addr = 0x4a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x4a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x4a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x4ac,
.csid_rdi_err_recovery_cfg0_addr = 0x4b0,
.csid_rdi_err_recovery_cfg1_addr = 0x4b4,
.csid_rdi_err_recovery_cfg2_addr = 0x4b8,
.csid_rdi_byte_cntr_ping_addr = 0x4e0,
.csid_rdi_byte_cntr_pong_addr = 0x4e4,
.csid_rdi_multi_vcdt_cfg0_addr = 0x4bc,
/* configurations */
.is_multi_vc_dt_supported = true,
.format_measure_en_shift_val = 0,
.measure_en_hbi_vbi_cnt_val = 0xc,
.cgc_mode_en_shift_val = 8,
};
static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_665_rdi_2_reg_offset = {
.csid_rdi_irq_status_addr = 0x60,
.csid_rdi_irq_mask_addr = 0x64,
.csid_rdi_irq_clear_addr = 0x68,
.csid_rdi_irq_set_addr = 0x6c,
.csid_rdi_cfg0_addr = 0x500,
.csid_rdi_cfg1_addr = 0x504,
.csid_rdi_ctrl_addr = 0x508,
.csid_rdi_frame_drop_pattern = 0x50c,
.csid_rdi_frame_drop_period = 0x510,
.csid_rdi_irq_subsample_pattern = 0x514,
.csid_rdi_irq_subsample_period = 0x518,
.csid_rdi_rst_strobes_addr = 0x540,
.csid_rdi_status_addr = 0x550,
.csid_rdi_misr_val0_addr = 0x554,
.csid_rdi_misr_val1_addr = 0x558,
.csid_rdi_misr_val2_addr = 0x55c,
.csid_rdi_misr_val3_addr = 0x560,
.csid_rdi_format_measure_cfg0_addr = 0x570,
.csid_rdi_format_measure_cfg1_addr = 0x574,
.csid_rdi_format_measure0_addr = 0x578,
.csid_rdi_format_measure1_addr = 0x57c,
.csid_rdi_format_measure2_addr = 0x580,
.csid_rdi_timestamp_curr0_sof_addr = 0x590,
.csid_rdi_timestamp_curr1_sof_addr = 0x594,
.csid_rdi_timestamp_prev0_sof_addr = 0x598,
.csid_rdi_timestamp_prev1_sof_addr = 0x59c,
.csid_rdi_timestamp_curr0_eof_addr = 0x5a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x5a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x5a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x5ac,
.csid_rdi_err_recovery_cfg0_addr = 0x5b0,
.csid_rdi_err_recovery_cfg1_addr = 0x5b4,
.csid_rdi_err_recovery_cfg2_addr = 0x5b8,
.csid_rdi_byte_cntr_ping_addr = 0x5e0,
.csid_rdi_byte_cntr_pong_addr = 0x5e4,
.csid_rdi_multi_vcdt_cfg0_addr = 0x5bc,
/* configurations */
.is_multi_vc_dt_supported = true,
.format_measure_en_shift_val = 0,
.measure_en_hbi_vbi_cnt_val = 0xc,
.cgc_mode_en_shift_val = 8,
};
static struct cam_tfe_csid_csi2_rx_reg_offset
cam_tfe_csid_665_csi2_reg_offset = {
.csid_csi2_rx_irq_status_addr = 0x20,
.csid_csi2_rx_irq_mask_addr = 0x24,
.csid_csi2_rx_irq_clear_addr = 0x28,
.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,
.csid_csi2_rx_rst_strobes_addr = 0x110,
.csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120,
.csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124,
.csid_csi2_rx_captured_short_pkt_0_addr = 0x128,
.csid_csi2_rx_captured_short_pkt_1_addr = 0x12c,
.csid_csi2_rx_captured_long_pkt_0_addr = 0x130,
.csid_csi2_rx_captured_long_pkt_1_addr = 0x134,
.csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138,
.csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c,
.csid_csi2_rx_total_pkts_rcvd_addr = 0x160,
.csid_csi2_rx_stats_ecc_addr = 0x164,
.csid_csi2_rx_total_crc_err_addr = 0x168,
.phy_tpg_base_id = 3,
.csi2_rst_srb_all = 0x3FFF,
.csi2_rst_done_shift_val = 27,
.csi2_irq_mask_all = 0xFFFFFFF,
.csi2_misr_enable_shift_val = 6,
.csi2_vc_mode_shift_val = 2,
.csi2_capture_long_pkt_en_shift = 0,
.csi2_capture_short_pkt_en_shift = 1,
.csi2_capture_cphy_pkt_en_shift = 2,
.csi2_capture_long_pkt_dt_shift = 4,
.csi2_capture_long_pkt_vc_shift = 10,
.csi2_capture_short_pkt_vc_shift = 12,
.csi2_capture_cphy_pkt_dt_shift = 14,
.csi2_capture_cphy_pkt_vc_shift = 20,
.csi2_rx_phy_num_mask = 0x7,
.csi2_rx_long_pkt_hdr_rst_stb_shift = 0x1,
.csi2_rx_short_pkt_hdr_rst_stb_shift = 0x2,
.csi2_rx_cphy_pkt_hdr_rst_stb_shift = 0x3,
.need_to_sel_tpg_mux = true,
};
static struct cam_tfe_csid_common_reg_offset
cam_tfe_csid_665_cmn_reg_offset = {
.csid_hw_version_addr = 0x0,
.csid_cfg0_addr = 0x4,
.csid_ctrl_addr = 0x8,
.csid_rst_strobes_addr = 0x10,
.csid_test_bus_ctrl_addr = 0x14,
.csid_top_irq_status_addr = 0x70,
.csid_top_irq_mask_addr = 0x74,
.csid_top_irq_clear_addr = 0x78,
.csid_top_irq_set_addr = 0x7c,
.csid_irq_cmd_addr = 0x80,
/*configurations */
.major_version = 5,
.minor_version = 3,
.version_incr = 0,
.num_rdis = 3,
.num_pix = 1,
.num_ppp = 1,
.csid_reg_rst_stb = 1,
.csid_rst_stb = 0x1e,
.csid_rst_stb_sw_all = 0x1f,
.ipp_path_rst_stb_all = 0x17,
.ppp_path_rst_stb_all = 0x17,
.rdi_path_rst_stb_all = 0x97,
.path_rst_done_shift_val = 1,
.path_en_shift_val = 31,
.dt_id_shift_val = 27,
.vc_shift_val = 22,
.dt_shift_val = 16,
.vc1_shift_val = 2,
.dt1_shift_val = 7,
.multi_vc_dt_en_shift_val = 0,
.fmt_shift_val = 12,
.plain_fmt_shit_val = 10,
.crop_v_en_shift_val = 6,
.crop_h_en_shift_val = 5,
.crop_shift = 16,
.ipp_irq_mask_all = 0x3FFFF,
.ppp_irq_mask_all = 0x3FFFF,
.rdi_irq_mask_all = 0x3FFFF,
.top_tfe2_pix_pipe_fuse_reg = 0xFE4,
.top_tfe2_fuse_reg = 0xFE8,
.format_measure_support = true,
.format_measure_height_shift_val = 16,
.format_measure_height_mask_val = 0xFFFF,
.format_measure_width_mask_val = 0xFFFF,
.sync_clk = true,
};
static struct cam_tfe_csid_reg_offset cam_tfe_csid_665_reg_offset = {
.cmn_reg = &cam_tfe_csid_665_cmn_reg_offset,
.csi2_reg = &cam_tfe_csid_665_csi2_reg_offset,
.ipp_reg = &cam_tfe_csid_665_ipp_reg_offset,
.ppp_reg = &cam_tfe_csid_665_ppp_reg_offset,
.rdi_reg = {
&cam_tfe_csid_665_rdi_0_reg_offset,
&cam_tfe_csid_665_rdi_1_reg_offset,
&cam_tfe_csid_665_rdi_2_reg_offset,
},
};
static struct cam_tfe_csid_hw_info cam_tfe_csid665_hw_info = {
.csid_reg = &cam_tfe_csid_665_reg_offset,
.hw_dts_version = CAM_TFE_CSID_VERSION_V665,
};
#endif /*_CAM_TFE_CSID_665_H_ */

View File

@ -0,0 +1,374 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_TFE_CSID_770_H_
#define _CAM_TFE_CSID_770_H_
#include "cam_tfe_csid_core.h"
#define CAM_TFE_CSID_VERSION_V770 0x70070000
static struct cam_tfe_csid_pxl_reg_offset cam_tfe_csid_770_ipp_reg_offset = {
.csid_pxl_irq_status_addr = 0x30,
.csid_pxl_irq_mask_addr = 0x34,
.csid_pxl_irq_clear_addr = 0x38,
.csid_pxl_irq_set_addr = 0x3c,
.csid_pxl_cfg0_addr = 0x200,
.csid_pxl_cfg1_addr = 0x204,
.csid_pxl_ctrl_addr = 0x208,
.csid_pxl_frame_drop_pattern = 0x20c,
.csid_pxl_frame_drop_period = 0x210,
.csid_pxl_irq_subsample_pattern = 0x214,
.csid_pxl_irq_subsample_period = 0x218,
.csid_pxl_hcrop_addr = 0x21c,
.csid_pxl_vcrop_addr = 0x220,
.csid_pxl_rst_strobes_addr = 0x240,
.csid_pxl_status_addr = 0x254,
.csid_pxl_misr_val_addr = 0x258,
.csid_pxl_format_measure_cfg0_addr = 0x270,
.csid_pxl_format_measure_cfg1_addr = 0x274,
.csid_pxl_format_measure0_addr = 0x278,
.csid_pxl_format_measure1_addr = 0x27c,
.csid_pxl_format_measure2_addr = 0x280,
.csid_pxl_timestamp_curr0_sof_addr = 0x290,
.csid_pxl_timestamp_curr1_sof_addr = 0x294,
.csid_pxl_timestamp_perv0_sof_addr = 0x298,
.csid_pxl_timestamp_perv1_sof_addr = 0x29c,
.csid_pxl_timestamp_curr0_eof_addr = 0x2a0,
.csid_pxl_timestamp_curr1_eof_addr = 0x2a4,
.csid_pxl_timestamp_perv0_eof_addr = 0x2a8,
.csid_pxl_timestamp_perv1_eof_addr = 0x2ac,
.csid_pxl_err_recovery_cfg0_addr = 0x2d0,
.csid_pxl_err_recovery_cfg1_addr = 0x2d4,
.csid_pxl_err_recovery_cfg2_addr = 0x2d8,
.csid_pxl_multi_vcdt_cfg0_addr = 0x2dc,
/* configurations */
.pix_store_en_shift_val = 7,
.early_eof_en_shift_val = 29,
.halt_master_sel_shift = 4,
.halt_mode_shift = 2,
.halt_mode_mask = 3,
.halt_master_sel_master_val = 1,
.halt_master_sel_slave_val = 0,
.binning_supported = 3,
.bin_qcfa_en_shift_val = 30,
.bin_en_shift_val = 2,
.is_multi_vc_dt_supported = true,
.format_measure_en_shift_val = 0,
.measure_en_hbi_vbi_cnt_val = 0xc,
.cgc_mode_en_shift_val = 9,
};
static struct cam_tfe_csid_pxl_reg_offset cam_tfe_csid_770_ppp_reg_offset = {
.csid_pxl_irq_status_addr = 0xA0,
.csid_pxl_irq_mask_addr = 0xA4,
.csid_pxl_irq_clear_addr = 0xA8,
.csid_pxl_irq_set_addr = 0xAc,
.csid_pxl_cfg0_addr = 0x700,
.csid_pxl_cfg1_addr = 0x704,
.csid_pxl_ctrl_addr = 0x708,
.csid_pxl_frame_drop_pattern = 0x70c,
.csid_pxl_frame_drop_period = 0x710,
.csid_pxl_irq_subsample_pattern = 0x714,
.csid_pxl_irq_subsample_period = 0x718,
.csid_pxl_hcrop_addr = 0x71c,
.csid_pxl_vcrop_addr = 0x720,
.csid_pxl_rst_strobes_addr = 0x740,
.csid_pxl_status_addr = 0x754,
.csid_pxl_misr_val_addr = 0x758,
.csid_pxl_format_measure_cfg0_addr = 0x770,
.csid_pxl_format_measure_cfg1_addr = 0x774,
.csid_pxl_format_measure0_addr = 0x778,
.csid_pxl_format_measure1_addr = 0x77c,
.csid_pxl_format_measure2_addr = 0x780,
.csid_pxl_timestamp_curr0_sof_addr = 0x790,
.csid_pxl_timestamp_curr1_sof_addr = 0x794,
.csid_pxl_timestamp_perv0_sof_addr = 0x798,
.csid_pxl_timestamp_perv1_sof_addr = 0x79c,
.csid_pxl_timestamp_curr0_eof_addr = 0x7a0,
.csid_pxl_timestamp_curr1_eof_addr = 0x7a4,
.csid_pxl_timestamp_perv0_eof_addr = 0x7a8,
.csid_pxl_timestamp_perv1_eof_addr = 0x7ac,
.csid_pxl_ppp_sparse_pd_ext_cfg0 = 0x7c0,
.csid_pxl_err_recovery_cfg0_addr = 0x7d0,
.csid_pxl_err_recovery_cfg1_addr = 0x7d4,
.csid_pxl_err_recovery_cfg2_addr = 0x7d8,
.csid_pxl_multi_vcdt_cfg0_addr = 0x7dc,
/* configurations */
.pix_store_en_shift_val = 7,
.early_eof_en_shift_val = 29,
.halt_master_sel_shift = 4,
.halt_mode_shift = 2,
.halt_mode_mask = 3,
.halt_master_sel_master_val = 3,
.halt_master_sel_slave_val = 2,
.binning_supported = 0,
.bin_qcfa_en_shift_val = 30,
.bin_en_shift_val = 2,
.is_multi_vc_dt_supported = true,
.format_measure_en_shift_val = 0,
.measure_en_hbi_vbi_cnt_val = 0xc,
.cgc_mode_en_shift_val = 9,
};
static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_770_rdi_0_reg_offset = {
.csid_rdi_irq_status_addr = 0x40,
.csid_rdi_irq_mask_addr = 0x44,
.csid_rdi_irq_clear_addr = 0x48,
.csid_rdi_irq_set_addr = 0x4c,
.csid_rdi_cfg0_addr = 0x300,
.csid_rdi_cfg1_addr = 0x304,
.csid_rdi_ctrl_addr = 0x308,
.csid_rdi_frame_drop_pattern = 0x30c,
.csid_rdi_frame_drop_period = 0x310,
.csid_rdi_irq_subsample_pattern = 0x314,
.csid_rdi_irq_subsample_period = 0x318,
.csid_rdi_rst_strobes_addr = 0x340,
.csid_rdi_status_addr = 0x350,
.csid_rdi_misr_val0_addr = 0x354,
.csid_rdi_misr_val1_addr = 0x358,
.csid_rdi_misr_val2_addr = 0x35c,
.csid_rdi_misr_val3_addr = 0x360,
.csid_rdi_format_measure_cfg0_addr = 0x370,
.csid_rdi_format_measure_cfg1_addr = 0x374,
.csid_rdi_format_measure0_addr = 0x378,
.csid_rdi_format_measure1_addr = 0x37c,
.csid_rdi_format_measure2_addr = 0x380,
.csid_rdi_timestamp_curr0_sof_addr = 0x390,
.csid_rdi_timestamp_curr1_sof_addr = 0x394,
.csid_rdi_timestamp_prev0_sof_addr = 0x398,
.csid_rdi_timestamp_prev1_sof_addr = 0x39c,
.csid_rdi_timestamp_curr0_eof_addr = 0x3a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x3a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x3a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x3ac,
.csid_rdi_err_recovery_cfg0_addr = 0x3b0,
.csid_rdi_err_recovery_cfg1_addr = 0x3b4,
.csid_rdi_err_recovery_cfg2_addr = 0x3b8,
.csid_rdi_byte_cntr_ping_addr = 0x3e0,
.csid_rdi_byte_cntr_pong_addr = 0x3e4,
.csid_rdi_multi_vcdt_cfg0_addr = 0x3bc,
/* configurations */
.is_multi_vc_dt_supported = true,
.format_measure_en_shift_val = 0,
.measure_en_hbi_vbi_cnt_val = 0xc,
.cgc_mode_en_shift_val = 8,
};
static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_770_rdi_1_reg_offset = {
.csid_rdi_irq_status_addr = 0x50,
.csid_rdi_irq_mask_addr = 0x54,
.csid_rdi_irq_clear_addr = 0x58,
.csid_rdi_irq_set_addr = 0x5c,
.csid_rdi_cfg0_addr = 0x400,
.csid_rdi_cfg1_addr = 0x404,
.csid_rdi_ctrl_addr = 0x408,
.csid_rdi_frame_drop_pattern = 0x40c,
.csid_rdi_frame_drop_period = 0x410,
.csid_rdi_irq_subsample_pattern = 0x414,
.csid_rdi_irq_subsample_period = 0x418,
.csid_rdi_rst_strobes_addr = 0x440,
.csid_rdi_status_addr = 0x450,
.csid_rdi_misr_val0_addr = 0x454,
.csid_rdi_misr_val1_addr = 0x458,
.csid_rdi_misr_val2_addr = 0x45c,
.csid_rdi_misr_val3_addr = 0x460,
.csid_rdi_format_measure_cfg0_addr = 0x470,
.csid_rdi_format_measure_cfg1_addr = 0x474,
.csid_rdi_format_measure0_addr = 0x478,
.csid_rdi_format_measure1_addr = 0x47c,
.csid_rdi_format_measure2_addr = 0x480,
.csid_rdi_timestamp_curr0_sof_addr = 0x490,
.csid_rdi_timestamp_curr1_sof_addr = 0x494,
.csid_rdi_timestamp_prev0_sof_addr = 0x498,
.csid_rdi_timestamp_prev1_sof_addr = 0x49c,
.csid_rdi_timestamp_curr0_eof_addr = 0x4a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x4a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x4a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x4ac,
.csid_rdi_err_recovery_cfg0_addr = 0x4b0,
.csid_rdi_err_recovery_cfg1_addr = 0x4b4,
.csid_rdi_err_recovery_cfg2_addr = 0x4b8,
.csid_rdi_byte_cntr_ping_addr = 0x4e0,
.csid_rdi_byte_cntr_pong_addr = 0x4e4,
.csid_rdi_multi_vcdt_cfg0_addr = 0x4bc,
/* configurations */
.is_multi_vc_dt_supported = true,
.format_measure_en_shift_val = 0,
.measure_en_hbi_vbi_cnt_val = 0xc,
.cgc_mode_en_shift_val = 8,
};
static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_770_rdi_2_reg_offset = {
.csid_rdi_irq_status_addr = 0x60,
.csid_rdi_irq_mask_addr = 0x64,
.csid_rdi_irq_clear_addr = 0x68,
.csid_rdi_irq_set_addr = 0x6c,
.csid_rdi_cfg0_addr = 0x500,
.csid_rdi_cfg1_addr = 0x504,
.csid_rdi_ctrl_addr = 0x508,
.csid_rdi_frame_drop_pattern = 0x50c,
.csid_rdi_frame_drop_period = 0x510,
.csid_rdi_irq_subsample_pattern = 0x514,
.csid_rdi_irq_subsample_period = 0x518,
.csid_rdi_rst_strobes_addr = 0x540,
.csid_rdi_status_addr = 0x550,
.csid_rdi_misr_val0_addr = 0x554,
.csid_rdi_misr_val1_addr = 0x558,
.csid_rdi_misr_val2_addr = 0x55c,
.csid_rdi_misr_val3_addr = 0x560,
.csid_rdi_format_measure_cfg0_addr = 0x570,
.csid_rdi_format_measure_cfg1_addr = 0x574,
.csid_rdi_format_measure0_addr = 0x578,
.csid_rdi_format_measure1_addr = 0x57c,
.csid_rdi_format_measure2_addr = 0x580,
.csid_rdi_timestamp_curr0_sof_addr = 0x590,
.csid_rdi_timestamp_curr1_sof_addr = 0x594,
.csid_rdi_timestamp_prev0_sof_addr = 0x598,
.csid_rdi_timestamp_prev1_sof_addr = 0x59c,
.csid_rdi_timestamp_curr0_eof_addr = 0x5a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x5a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x5a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x5ac,
.csid_rdi_err_recovery_cfg0_addr = 0x5b0,
.csid_rdi_err_recovery_cfg1_addr = 0x5b4,
.csid_rdi_err_recovery_cfg2_addr = 0x5b8,
.csid_rdi_byte_cntr_ping_addr = 0x5e0,
.csid_rdi_byte_cntr_pong_addr = 0x5e4,
.csid_rdi_multi_vcdt_cfg0_addr = 0x5bc,
/* configurations */
.is_multi_vc_dt_supported = true,
.format_measure_en_shift_val = 0,
.measure_en_hbi_vbi_cnt_val = 0xc,
.cgc_mode_en_shift_val = 8,
};
static struct cam_tfe_csid_csi2_rx_reg_offset
cam_tfe_csid_770_csi2_reg_offset = {
.csid_csi2_rx_irq_status_addr = 0x20,
.csid_csi2_rx_irq_mask_addr = 0x24,
.csid_csi2_rx_irq_clear_addr = 0x28,
.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,
.csid_csi2_rx_rst_strobes_addr = 0x110,
.csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120,
.csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124,
.csid_csi2_rx_captured_short_pkt_0_addr = 0x128,
.csid_csi2_rx_captured_short_pkt_1_addr = 0x12c,
.csid_csi2_rx_captured_long_pkt_0_addr = 0x130,
.csid_csi2_rx_captured_long_pkt_1_addr = 0x134,
.csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138,
.csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c,
.csid_csi2_rx_total_pkts_rcvd_addr = 0x160,
.csid_csi2_rx_stats_ecc_addr = 0x164,
.csid_csi2_rx_total_crc_err_addr = 0x168,
.phy_tpg_base_id = 3,
.csi2_rst_srb_all = 0x3FFF,
.csi2_rst_done_shift_val = 27,
.csi2_irq_mask_all = 0xFFFFFFF,
.csi2_misr_enable_shift_val = 6,
.csi2_vc_mode_shift_val = 2,
.csi2_rx_epd_mode_shift_en = 8,
.csi2_capture_long_pkt_en_shift = 0,
.csi2_capture_short_pkt_en_shift = 1,
.csi2_capture_cphy_pkt_en_shift = 2,
.csi2_capture_long_pkt_dt_shift = 4,
.csi2_capture_long_pkt_vc_shift = 10,
.csi2_capture_short_pkt_vc_shift = 12,
.csi2_capture_cphy_pkt_dt_shift = 14,
.csi2_capture_cphy_pkt_vc_shift = 20,
.csi2_rx_phy_num_mask = 0x7,
.csi2_rx_long_pkt_hdr_rst_stb_shift = 0x1,
.csi2_rx_short_pkt_hdr_rst_stb_shift = 0x2,
.csi2_rx_cphy_pkt_hdr_rst_stb_shift = 0x3,
.need_to_sel_tpg_mux = true,
};
static struct cam_tfe_csid_common_reg_offset
cam_tfe_csid_770_cmn_reg_offset = {
.csid_hw_version_addr = 0x0,
.csid_cfg0_addr = 0x4,
.csid_ctrl_addr = 0x8,
.csid_rst_strobes_addr = 0x10,
.csid_test_bus_ctrl_addr = 0x14,
.csid_top_irq_status_addr = 0x70,
.csid_top_irq_mask_addr = 0x74,
.csid_top_irq_clear_addr = 0x78,
.csid_top_irq_set_addr = 0x7c,
.csid_irq_cmd_addr = 0x80,
/*configurations */
.major_version = 5,
.minor_version = 3,
.version_incr = 0,
.num_rdis = 3,
.num_pix = 1,
.num_ppp = 1,
.csid_reg_rst_stb = 1,
.csid_rst_stb = 0x1e,
.csid_rst_stb_sw_all = 0x1f,
.ipp_path_rst_stb_all = 0x17,
.ppp_path_rst_stb_all = 0x17,
.rdi_path_rst_stb_all = 0x97,
.path_rst_done_shift_val = 1,
.path_en_shift_val = 31,
.dt_id_shift_val = 27,
.vc_shift_val = 22,
.dt_shift_val = 16,
.vc1_shift_val = 2,
.dt1_shift_val = 7,
.multi_vc_dt_en_shift_val = 0,
.fmt_shift_val = 12,
.plain_fmt_shit_val = 10,
.crop_v_en_shift_val = 6,
.crop_h_en_shift_val = 5,
.crop_shift = 16,
.ipp_irq_mask_all = 0x3FFFF,
.ppp_irq_mask_all = 0x3FFFF,
.rdi_irq_mask_all = 0x3FFFF,
.top_tfe2_pix_pipe_fuse_reg = 0xFE4,
.top_tfe2_fuse_reg = 0xFE8,
.format_measure_support = true,
.format_measure_height_shift_val = 16,
.format_measure_height_mask_val = 0xFFFF,
.format_measure_width_mask_val = 0xFFFF,
.sync_clk = true,
};
static struct cam_tfe_csid_reg_offset cam_tfe_csid_770_reg_offset = {
.cmn_reg = &cam_tfe_csid_770_cmn_reg_offset,
.csi2_reg = &cam_tfe_csid_770_csi2_reg_offset,
.ipp_reg = &cam_tfe_csid_770_ipp_reg_offset,
.ppp_reg = &cam_tfe_csid_770_ppp_reg_offset,
.rdi_reg = {
&cam_tfe_csid_770_rdi_0_reg_offset,
&cam_tfe_csid_770_rdi_1_reg_offset,
&cam_tfe_csid_770_rdi_2_reg_offset,
},
};
static struct cam_tfe_csid_hw_info cam_tfe_csid770_hw_info = {
.csid_reg = &cam_tfe_csid_770_reg_offset,
.hw_dts_version = CAM_TFE_CSID_VERSION_V770,
};
#endif /*_CAM_TFE_CSID_770_H_ */

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_TFE_CSID_HW_H_
@ -55,11 +56,14 @@
#define TFE_CSID_PATH_ERROR_PIX_COUNT BIT(13)
#define TFE_CSID_PATH_ERROR_LINE_COUNT BIT(14)
#define TFE_CSID_PATH_IPP_ERROR_CCIF_VIOLATION BIT(15)
#define TFE_CSID_PATH_IPP_OVERFLOW_IRQ BIT(16)
#define TFE_CSID_PATH_IPP_FRAME_DROP BIT(17)
#define TFE_CSID_PATH_IPP_FRAME_DROP BIT(16)
#define TFE_CSID_PATH_IPP_OVERFLOW_IRQ BIT(17)
#define TFE_CSID_PATH_PPP_ERROR_CCIF_VIOLATION BIT(15)
#define TFE_CSID_PATH_PPP_FRAME_DROP BIT(16)
#define TFE_CSID_PATH_PPP_OVERFLOW_IRQ BIT(17)
#define TFE_CSID_PATH_RDI_ERROR_CCIF_VIOLATION BIT(15)
#define TFE_CSID_PATH_RDI_FRAME_DROP BIT(16)
#define TFE_CSID_PATH_RDI_OVERFLOW_IRQ BIT(17)
#define TFE_CSID_PATH_RDI_ERROR_CCIF_VIOLATION BIT(18)
/*
* Debug values enable the corresponding interrupts and debug logs provide
@ -94,6 +98,14 @@ enum cam_tfe_csid_path_halt_mode {
TFE_CSID_HALT_MODE_SLAVE,
};
/* enum cam_csid_path_halt_master select the path halt master control */
enum cam_tfe_csid_path_halt_master_sel {
TFE_CSID_HALT_CMD_SOURCE_EXTERNAL,
TFE_CSID_HALT_CMD_SOURCE_NONE,
TFE_CSID_HALT_CMD_SOURCE_INTERNAL2,
TFE_CSID_HALT_CMD_SOURCE_INTERNAL1,
};
/**
*enum cam_csid_path_timestamp_stb_sel - select the sof/eof strobes used to
* capture the timestamp
@ -115,11 +127,20 @@ struct cam_tfe_csid_pxl_reg_offset {
uint32_t csid_pxl_cfg0_addr;
uint32_t csid_pxl_cfg1_addr;
uint32_t csid_pxl_ctrl_addr;
uint32_t csid_pxl_frame_drop_pattern;
uint32_t csid_pxl_frame_drop_period;
uint32_t csid_pxl_irq_subsample_pattern;
uint32_t csid_pxl_irq_subsample_period;
uint32_t csid_pxl_hcrop_addr;
uint32_t csid_pxl_vcrop_addr;
uint32_t csid_pxl_rst_strobes_addr;
uint32_t csid_pxl_status_addr;
uint32_t csid_pxl_misr_val_addr;
uint32_t csid_pxl_format_measure_cfg0_addr;
uint32_t csid_pxl_format_measure_cfg1_addr;
uint32_t csid_pxl_format_measure0_addr;
uint32_t csid_pxl_format_measure1_addr;
uint32_t csid_pxl_format_measure2_addr;
uint32_t csid_pxl_timestamp_curr0_sof_addr;
uint32_t csid_pxl_timestamp_curr1_sof_addr;
uint32_t csid_pxl_timestamp_perv0_sof_addr;
@ -128,21 +149,19 @@ struct cam_tfe_csid_pxl_reg_offset {
uint32_t csid_pxl_timestamp_curr1_eof_addr;
uint32_t csid_pxl_timestamp_perv0_eof_addr;
uint32_t csid_pxl_timestamp_perv1_eof_addr;
uint32_t csid_pxl_ppp_sparse_pd_ext_cfg0;
uint32_t csid_pxl_err_recovery_cfg0_addr;
uint32_t csid_pxl_err_recovery_cfg1_addr;
uint32_t csid_pxl_err_recovery_cfg2_addr;
uint32_t csid_pxl_multi_vcdt_cfg0_addr;
uint32_t csid_pxl_format_measure_cfg0_addr;
uint32_t csid_pxl_format_measure_cfg1_addr;
uint32_t csid_pxl_format_measure0_addr;
uint32_t csid_pxl_format_measure1_addr;
uint32_t csid_pxl_format_measure2_addr;
/* configuration */
uint32_t pix_store_en_shift_val;
uint32_t early_eof_en_shift_val;
uint32_t halt_master_sel_shift;
uint32_t halt_mode_shift;
uint32_t halt_mode_mask;
uint32_t halt_cmd_shift;
uint32_t halt_master_sel_master_val;
uint32_t halt_master_sel_slave_val;
uint32_t binning_supported;
@ -151,6 +170,7 @@ struct cam_tfe_csid_pxl_reg_offset {
uint32_t format_measure_en_shift_val;
uint32_t measure_en_hbi_vbi_cnt_val;
bool is_multi_vc_dt_supported;
uint32_t cgc_mode_en_shift_val;
};
struct cam_tfe_csid_rdi_reg_offset {
@ -163,10 +183,21 @@ struct cam_tfe_csid_rdi_reg_offset {
uint32_t csid_rdi_cfg0_addr;
uint32_t csid_rdi_cfg1_addr;
uint32_t csid_rdi_ctrl_addr;
uint32_t csid_rdi_frame_drop_pattern;
uint32_t csid_rdi_frame_drop_period;
uint32_t csid_rdi_irq_subsample_pattern;
uint32_t csid_rdi_irq_subsample_period;
uint32_t csid_rdi_rst_strobes_addr;
uint32_t csid_rdi_status_addr;
uint32_t csid_rdi_misr_val0_addr;
uint32_t csid_rdi_misr_val1_addr;
uint32_t csid_rdi_misr_val2_addr;
uint32_t csid_rdi_misr_val3_addr;
uint32_t csid_rdi_format_measure_cfg0_addr;
uint32_t csid_rdi_format_measure_cfg1_addr;
uint32_t csid_rdi_format_measure0_addr;
uint32_t csid_rdi_format_measure1_addr;
uint32_t csid_rdi_format_measure2_addr;
uint32_t csid_rdi_timestamp_curr0_sof_addr;
uint32_t csid_rdi_timestamp_curr1_sof_addr;
uint32_t csid_rdi_timestamp_prev0_sof_addr;
@ -181,17 +212,13 @@ struct cam_tfe_csid_rdi_reg_offset {
uint32_t csid_rdi_byte_cntr_ping_addr;
uint32_t csid_rdi_byte_cntr_pong_addr;
uint32_t csid_rdi_multi_vcdt_cfg0_addr;
uint32_t csid_rdi_format_measure_cfg0_addr;
uint32_t csid_rdi_format_measure_cfg1_addr;
uint32_t csid_rdi_format_measure0_addr;
uint32_t csid_rdi_format_measure1_addr;
uint32_t csid_rdi_format_measure2_addr;
/* configuration */
uint32_t packing_format;
uint32_t format_measure_en_shift_val;
uint32_t measure_en_hbi_vbi_cnt_val;
bool is_multi_vc_dt_supported;
uint32_t cgc_mode_en_shift_val;
};
struct cam_tfe_csid_csi2_rx_reg_offset {
@ -223,6 +250,7 @@ struct cam_tfe_csid_csi2_rx_reg_offset {
uint32_t csi2_irq_mask_all;
uint32_t csi2_misr_enable_shift_val;
uint32_t csi2_vc_mode_shift_val;
uint32_t csi2_rx_epd_mode_shift_en;
uint32_t csi2_capture_long_pkt_en_shift;
uint32_t csi2_capture_short_pkt_en_shift;
uint32_t csi2_capture_cphy_pkt_en_shift;
@ -235,6 +263,7 @@ struct cam_tfe_csid_csi2_rx_reg_offset {
uint32_t csi2_rx_long_pkt_hdr_rst_stb_shift;
uint32_t csi2_rx_short_pkt_hdr_rst_stb_shift;
uint32_t csi2_rx_cphy_pkt_hdr_rst_stb_shift;
bool need_to_sel_tpg_mux;
};
struct cam_tfe_csid_common_reg_offset {
@ -257,10 +286,12 @@ struct cam_tfe_csid_common_reg_offset {
uint32_t version_incr;
uint32_t num_rdis;
uint32_t num_pix;
uint32_t num_ppp;
uint32_t csid_reg_rst_stb;
uint32_t csid_rst_stb;
uint32_t csid_rst_stb_sw_all;
uint32_t ipp_path_rst_stb_all;
uint32_t ppp_path_rst_stb_all;
uint32_t rdi_path_rst_stb_all;
uint32_t path_rst_done_shift_val;
uint32_t path_en_shift_val;
@ -276,6 +307,7 @@ struct cam_tfe_csid_common_reg_offset {
uint32_t crop_h_en_shift_val;
uint32_t crop_shift;
uint32_t ipp_irq_mask_all;
uint32_t ppp_irq_mask_all;
uint32_t rdi_irq_mask_all;
uint32_t top_tfe2_pix_pipe_fuse_reg;
uint32_t top_tfe2_fuse_reg;
@ -283,6 +315,7 @@ struct cam_tfe_csid_common_reg_offset {
uint32_t format_measure_height_mask_val;
uint32_t format_measure_width_mask_val;
bool format_measure_support;
bool sync_clk;
};
/**
@ -298,9 +331,37 @@ struct cam_tfe_csid_reg_offset {
const struct cam_tfe_csid_common_reg_offset *cmn_reg;
const struct cam_tfe_csid_csi2_rx_reg_offset *csi2_reg;
const struct cam_tfe_csid_pxl_reg_offset *ipp_reg;
const struct cam_tfe_csid_pxl_reg_offset *ppp_reg;
const struct cam_tfe_csid_rdi_reg_offset *rdi_reg[CAM_TFE_CSID_RDI_MAX];
};
/**
* struct cam_tfe_csid_secure_info: Contains all relevant info to be
* programmed for targets supporting
* this feature
* @phy_sel: Intermediate value for this mask. CSID passes
* phy_sel.This variable's position at the top is to
* be left unchanged, to have it be used correctly
* in the cam_subdev_notify_message callback for
* csiphy
* @lane_cfg: This value is similar to lane_assign in the PHY
* driver, and is used to identify the particular
* PHY instance with which this IFE session is
* connected to.
* @vc_mask: Virtual channel masks (Unused for mobile usecase)
* @csid_hw_idx_mask: Bit position denoting CSID(s) in use for secure
* session
* @cdm_hw_idx_mask: Bit position denoting CDM in use for secure
* session
*/
struct cam_tfe_csid_secure_info {
uint32_t phy_sel;
uint32_t lane_cfg;
uint64_t vc_mask;
uint32_t csid_hw_idx_mask;
uint32_t cdm_hw_idx_mask;
};
/**
* struct cam_tfe_csid_hw_info- CSID HW info
*
@ -317,10 +378,11 @@ struct cam_tfe_csid_hw_info {
/**
* struct cam_tfe_csid_csi2_rx_cfg- csid csi2 rx configuration data
* @phy_sel: input resource type for sensor only
* @lane_type: lane type: c-phy or d-phy
* @lane_num : active lane number
* @lane_cfg: lane configurations: 4 bits per lane
* @phy_sel: input resource type for sensor only
* @lane_type: lane type: c-phy or d-phy
* @lane_num : active lane number
* @lane_cfg: lane configurations: 4 bits per lane
* @epd_supported: Flag to check if epd supported
*
*/
struct cam_tfe_csid_csi2_rx_cfg {
@ -328,6 +390,7 @@ struct cam_tfe_csid_csi2_rx_cfg {
uint32_t lane_type;
uint32_t lane_num;
uint32_t lane_cfg;
uint32_t epd_supported;
};
/**
@ -392,7 +455,8 @@ struct cam_tfe_csid_cid_data {
* one more frame than pix.
* @res_sof_cnt path resource sof count value. it used for initial
* frame drop
*
* @is_shdr_master flag to indicate path to be shdr master
* @is_shdr flag to indicate if shdr mode is enabled
*/
struct cam_tfe_csid_path_cfg {
struct vc_dt_data vc_dt[CAM_ISP_TFE_VC_DT_CFG];
@ -420,6 +484,8 @@ struct cam_tfe_csid_path_cfg {
uint32_t usage_type;
uint32_t init_frame_drop;
uint32_t res_sof_cnt;
bool is_shdr_master;
bool is_shdr;
};
/**
@ -450,13 +516,14 @@ struct cam_csid_evt_payload {
* @in_res_id: csid in resource type
* @csi2_rx_cfg: csi2 rx decoder configuration for csid
* @csi2_rx_reserve_cnt: csi2 reservations count value
* pxl_pipe_enable: flag to specify if the hardware has IPP
* @ipp_res: image pixel path resource
* @ppp_res: PD pixel path resource
* @rdi_res: raw dump image path resources
* @cid_res: cid resources values
* @csid_top_reset_complete: csid top reset completion
* @csid_csi2_reset_complete: csi2 reset completion
* @csid_ipp_reset_complete: ipp reset completion
* @csid_ppp_complete: ppp reset completion
* @csid_rdin_reset_complete: rdi n completion
* @csid_debug: csid debug information to enable the SOT, EOT,
* SOF, EOF, measure etc in the csid hw
@ -477,6 +544,8 @@ struct cam_csid_evt_payload {
* or not
* @prev_boot_timestamp previous frame bootime stamp
* @prev_qtimer_ts previous frame qtimer csid timestamp
* @sync_clk sync clocks such that freq(TFE)>freq(CSID)>freq(CSIPHY)
* @is_secure Flag to denote secure operation
*
*/
struct cam_tfe_csid_hw {
@ -491,11 +560,13 @@ struct cam_tfe_csid_hw {
uint32_t csi2_reserve_cnt;
uint32_t pxl_pipe_enable;
struct cam_isp_resource_node ipp_res;
struct cam_isp_resource_node ppp_res;
struct cam_isp_resource_node rdi_res[CAM_TFE_CSID_RDI_MAX];
struct cam_tfe_csid_cid_data cid_res[CAM_TFE_CSID_CID_MAX];
struct completion csid_top_complete;
struct completion csid_csi2_complete;
struct completion csid_ipp_complete;
struct completion csid_ppp_complete;
struct completion csid_rdin_complete[CAM_TFE_CSID_RDI_MAX];
uint64_t csid_debug;
uint64_t clk_rate;
@ -511,6 +582,8 @@ struct cam_tfe_csid_hw {
bool ppi_enable;
uint64_t prev_boot_timestamp;
uint64_t prev_qtimer_ts;
bool sync_clk;
bool is_secure;
};
int cam_tfe_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,

View File

@ -1,16 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
#include <linux/mod_devicetable.h>
#include <linux/of_device.h>
#include <dt-bindings/msm-camera.h>
#include "cam_tfe_csid_core.h"
#include "cam_tfe_csid_dev.h"
#include "cam_tfe_csid_hw_intf.h"
#include "cam_debug_util.h"
#include "camera_main.h"
#include "cam_cpas_api.h"
static struct cam_hw_intf *cam_tfe_csid_hw_list[CAM_TFE_CSID_HW_NUM_MAX] = {
0, 0, 0};
@ -24,12 +27,25 @@ static int cam_tfe_csid_component_bind(struct device *dev,
struct cam_tfe_csid_hw *csid_dev = NULL;
const struct of_device_id *match_dev = NULL;
struct cam_tfe_csid_hw_info *csid_hw_data = NULL;
uint32_t csid_dev_idx;
uint32_t csid_dev_idx = 0;
int rc = 0;
struct platform_device *pdev = to_platform_device(dev);
CAM_DBG(CAM_ISP, "probe called");
/* get tfe csid hw index */
rc = of_property_read_u32(pdev->dev.of_node, "cell-index", &csid_dev_idx);
if (rc) {
CAM_ERR(CAM_ISP, "Failed to read cell-index of TFE CSID HW, rc: %d", rc);
goto err;
}
if (!cam_cpas_is_feature_supported(CAM_CPAS_ISP_FUSE, BIT(csid_dev_idx), NULL) ||
!cam_cpas_is_feature_supported(CAM_CPAS_ISP_LITE_FUSE, BIT(csid_dev_idx), NULL)) {
CAM_DBG(CAM_ISP, "CSID[%d] not supported based on fuse", csid_dev_idx);
goto err;
}
csid_hw_intf = kzalloc(sizeof(*csid_hw_intf), GFP_KERNEL);
if (!csid_hw_intf) {
rc = -ENOMEM;
@ -48,8 +64,6 @@ static int cam_tfe_csid_component_bind(struct device *dev,
goto free_hw_info;
}
/* get tfe csid hw index */
of_property_read_u32(pdev->dev.of_node, "cell-index", &csid_dev_idx);
/* get tfe csid hw information */
match_dev = of_match_device(pdev->dev.driver->of_match_table,
&pdev->dev);
@ -107,6 +121,12 @@ void cam_tfe_csid_component_unbind(struct device *dev,
struct platform_device *pdev = to_platform_device(dev);
csid_dev = (struct cam_tfe_csid_hw *)platform_get_drvdata(pdev);
if (!csid_dev) {
CAM_ERR(CAM_ISP, "Error No data in csid_dev");
return;
}
csid_hw_intf = csid_dev->hw_intf;
csid_hw_info = csid_dev->hw_info;

View File

@ -24,7 +24,6 @@ int cam_tfe_csid_init_soc_resources(struct cam_hw_soc_info *soc_info,
soc_info->soc_private = soc_private;
rc = cam_soc_util_get_dt_properties(soc_info);
if (rc < 0)
return rc;
@ -32,6 +31,10 @@ int cam_tfe_csid_init_soc_resources(struct cam_hw_soc_info *soc_info,
for (i = 0; i < soc_info->irq_count; i++)
irq_data[i] = data;
soc_private->is_tfe_csid_lite = false;
if (strnstr(soc_info->compatible, "lite", strlen(soc_info->compatible)) != NULL)
soc_private->is_tfe_csid_lite = true;
/* Need to see if we want post process the clock list */
rc = cam_soc_util_request_platform_resource(soc_info, csid_irq_handler, &(irq_data[0]));
if (rc < 0) {

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_TFE_CSID_SOC_H_
@ -16,9 +17,11 @@
* @cpas_handle: Handle returned on registering with CPAS driver.
* This handle is used for all further interface
* with CPAS.
* @is_tfe_csid_lite: Flag to indicate if it is CSID lite HW
*/
struct cam_tfe_csid_soc_private {
uint32_t cpas_handle;
bool is_tfe_csid_lite;
};
/**

View File

@ -1,11 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
#include "cam_tfe530.h"
#include "cam_tfe640.h"
#include "cam_tfe640_210.h"
#include "cam_tfe770.h"
#include "cam_tfe_lite770.h"
#include "cam_tfe665.h"
#include "cam_tfe_hw_intf.h"
#include "cam_tfe_core.h"
#include "cam_tfe_dev.h"
@ -20,6 +25,22 @@ static const struct of_device_id cam_tfe_dt_match[] = {
.compatible = "qcom,tfe640",
.data = &cam_tfe640,
},
{
.compatible = "qcom,tfe640_210",
.data = &cam_tfe640_210,
},
{
.compatible = "qcom,tfe770",
.data = &cam_tfe770,
},
{
.compatible = "qcom,tfe-lite770",
.data = &cam_tfe_lite770,
},
{
.compatible = "qcom,tfe665",
.data = &cam_tfe665,
},
{}
};
MODULE_DEVICE_TABLE(of, cam_tfe_dt_match);

View File

@ -18,7 +18,7 @@ static struct cam_tfe_top_reg_offset_common tfe530_top_commong_reg = {
.stats_feature = 0x0000100C,
.zoom_feature = 0x00001010,
.global_reset_cmd = 0x00001014,
.core_cgc_ctrl = 0x00001018,
.core_cgc_ctrl_0 = 0x00001018,
.ahb_cgc_ctrl = 0x0000101C,
.core_cfg_0 = 0x00001024,
.core_cfg_1 = 0x00001028,
@ -53,6 +53,24 @@ static struct cam_tfe_top_reg_offset_common tfe530_top_commong_reg = {
.diag_neq_hbi_shift = 14,
.diag_sensor_hbi_mask = 0x3FFF,
.serializer_supported = false,
.pp_camif_violation_bit = BIT(0),
.pp_violation_bit = BIT(1),
.rdi0_camif_violation_bit = BIT(2),
.rdi1_camif_violation_bit = BIT(3),
.rdi2_camif_violation_bit = BIT(4),
.diag_violation_bit = BIT(5),
.pp_frame_drop_bit = BIT(8),
.rdi0_frame_drop_bit = BIT(9),
.rdi1_frame_drop_bit = BIT(10),
.rdi2_frame_drop_bit = BIT(11),
.pp_overflow_bit = BIT(16),
.rdi0_overflow_bit = BIT(17),
.rdi1_overflow_bit = BIT(18),
.rdi2_overflow_bit = BIT(19),
.mup_shift_val = 0,
.mup_supported = false,
.height_shift = 16,
.epoch_shift_val = 16,
};
static struct cam_tfe_camif_reg tfe530_camif_reg = {
@ -220,7 +238,6 @@ static struct cam_tfe_rdi_reg_data tfe530_rdi2_reg_data = {
.enable_diagnostic_hw = 0x1,
.diag_sensor_sel = 0x3,
.diag_sensor_shift = 0x1,
};
static struct cam_tfe_clc_hw_status tfe530_clc_hw_info[CAM_TFE_MAX_CLC] = {
@ -859,6 +876,8 @@ static struct cam_tfe_bus_hw_info tfe530_bus_hw_info = {
.max_bw_counter_limit = 0xFF,
.counter_limit_shift = 1,
.counter_limit_mask = 0xF,
.mode_cfg_shift = 16,
.height_shift = 16,
};
struct cam_tfe_hw_info cam_tfe530 = {

View File

@ -18,7 +18,7 @@ static struct cam_tfe_top_reg_offset_common tfe640_top_commong_reg = {
.stats_feature = 0x0000180C,
.zoom_feature = 0x00001810,
.global_reset_cmd = 0x00001814,
.core_cgc_ctrl = 0x00001818,
.core_cgc_ctrl_0 = 0x00001818,
.ahb_cgc_ctrl = 0x0000181C,
.core_cfg_0 = 0x00001824,
.reg_update_cmd = 0x0000182C,
@ -66,6 +66,24 @@ static struct cam_tfe_top_reg_offset_common tfe640_top_commong_reg = {
.diag_neq_hbi_shift = 14,
.diag_sensor_hbi_mask = 0x3FFF,
.serializer_supported = true,
.pp_camif_violation_bit = BIT(0),
.pp_violation_bit = BIT(1),
.rdi0_camif_violation_bit = BIT(2),
.rdi1_camif_violation_bit = BIT(3),
.rdi2_camif_violation_bit = BIT(4),
.diag_violation_bit = BIT(5),
.pp_frame_drop_bit = BIT(8),
.rdi0_frame_drop_bit = BIT(9),
.rdi1_frame_drop_bit = BIT(10),
.rdi2_frame_drop_bit = BIT(11),
.pp_overflow_bit = BIT(16),
.rdi0_overflow_bit = BIT(17),
.rdi1_overflow_bit = BIT(18),
.rdi2_overflow_bit = BIT(19),
.mup_shift_val = 0,
.mup_supported = false,
.height_shift = 16,
.epoch_shift_val = 16,
};
static struct cam_tfe_camif_reg tfe640_camif_reg = {
@ -235,7 +253,6 @@ static struct cam_tfe_rdi_reg_data tfe640_rdi2_reg_data = {
.enable_diagnostic_hw = 0x1,
.diag_sensor_sel = 0x3,
.diag_sensor_shift = 0x1,
};
static struct cam_tfe_clc_hw_status tfe640_clc_hw_info[CAM_TFE_MAX_CLC] = {
@ -1175,6 +1192,8 @@ static struct cam_tfe_bus_hw_info tfe640_bus_hw_info = {
.max_bw_counter_limit = 0xFF,
.counter_limit_shift = 1,
.counter_limit_mask = 0xF,
.mode_cfg_shift = 16,
.height_shift = 16,
};
struct cam_tfe_hw_info cam_tfe640 = {

View File

@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_TFE640_210_H_
#define _CAM_TFE640_210_H_
#include "cam_tfe_core.h"
#include "cam_tfe_bus.h"
#include "cam_tfe640.h"
struct cam_tfe_hw_info cam_tfe640_210 = {
.top_irq_mask = {
0x00001834,
0x00001838,
0x0000183C,
},
.top_irq_clear = {
0x00001840,
0x00001844,
0x00001848,
},
.top_irq_status = {
0x0000184C,
0x00001850,
0x00001854,
},
.top_irq_cmd = 0x00001830,
.global_clear_bitmask = 0x00000001,
.bus_irq_mask = {
0x00003018,
0x0000301C,
},
.bus_irq_clear = {
0x00003020,
0x00003024,
},
.bus_irq_status = {
0x00003028,
0x0000302C,
},
.bus_irq_cmd = 0x00003030,
.bus_violation_reg = 0x00003064,
.bus_overflow_reg = 0x00003068,
.bus_image_size_vilation_reg = 0x3070,
.bus_overflow_clear_cmd = 0x3060,
.debug_status_top = 0x30D8,
.reset_irq_mask = {
0x00000001,
0x00000000,
0x00000000,
},
.error_irq_mask = {
0x000F0F00,
0x00000000,
0x0000003F,
},
.bus_reg_irq_mask = {
0x00000002,
0x00000000,
},
.bus_error_irq_mask = {
0xC0000000,
0x00000000,
},
.num_clc = 39,
.clc_hw_status_info = tfe640_clc_hw_info,
.bus_version = CAM_TFE_BUS_1_0,
.bus_hw_info = &tfe640_bus_hw_info,
.top_version = CAM_TFE_TOP_1_0,
.top_hw_info = &tfe640_top_hw_info,
};
#endif /* _CAM_TFE640_210_H_ */

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/ratelimit.h>
@ -71,6 +71,8 @@ struct cam_tfe_bus_common_data {
uint32_t num_sec_out;
uint32_t comp_done_shift;
uint32_t rdi_width;
uint32_t mode_cfg_shift;
uint32_t height_shift;
bool is_lite;
bool support_consumed_addr;
cam_hw_mgr_event_cb_func event_cb;
@ -79,6 +81,7 @@ struct cam_tfe_bus_common_data {
uint32_t max_bw_counter_limit;
uint32_t counter_limit_shift;
uint32_t counter_limit_mask;
uint32_t pack_align_shift;
};
struct cam_tfe_bus_wm_resource_data {
@ -108,7 +111,12 @@ struct cam_tfe_bus_wm_resource_data {
uint32_t acquired_width;
uint32_t acquired_height;
uint32_t acquired_stride;
uint32_t buffer_offset;
bool is_buffer_aligned;
bool limiter_blob_status;
bool is_dim_update;
};
struct cam_tfe_bus_comp_grp_data {
@ -152,6 +160,7 @@ struct cam_tfe_bus_tfe_out_data {
void *priv;
cam_hw_mgr_event_cb_func event_cb;
uint32_t mid[CAM_TFE_BUS_MAX_MID_PER_PORT];
uint64_t pid_mask;
};
struct cam_tfe_bus_priv {
@ -173,6 +182,7 @@ struct cam_tfe_bus_priv {
uint32_t comp_buf_done_mask;
uint32_t comp_rup_done_mask;
uint32_t bus_irq_error_mask[CAM_TFE_BUS_IRQ_REGISTERS_MAX];
uint32_t max_out_res;
};
static bool cam_tfe_bus_can_be_secure(uint32_t out_id)
@ -186,6 +196,9 @@ static bool cam_tfe_bus_can_be_secure(uint32_t out_id)
case CAM_TFE_BUS_TFE_OUT_DS4:
case CAM_TFE_BUS_TFE_OUT_DS16:
case CAM_TFE_BUS_TFE_OUT_AI:
case CAM_TFE_BUS_TFE_OUT_PD_LCR_STATS:
case CAM_TFE_BUS_TFE_OUT_PD_PREPROCESSED:
case CAM_TFE_BUS_TFE_OUT_PD_PARSED:
return true;
case CAM_TFE_BUS_TFE_OUT_STATS_HDR_BE:
@ -233,6 +246,12 @@ static enum cam_tfe_bus_tfe_out_id
return CAM_TFE_BUS_TFE_OUT_DS16;
case CAM_ISP_TFE_OUT_RES_AI:
return CAM_TFE_BUS_TFE_OUT_AI;
case CAM_ISP_TFE_OUT_RES_PD_LCR_STATS:
return CAM_TFE_BUS_TFE_OUT_PD_LCR_STATS;
case CAM_ISP_TFE_OUT_RES_PD_PREPROCESSED:
return CAM_TFE_BUS_TFE_OUT_PD_PREPROCESSED;
case CAM_ISP_TFE_OUT_RES_PD_PARSED:
return CAM_TFE_BUS_TFE_OUT_PD_PARSED;
default:
return CAM_TFE_BUS_TFE_OUT_MAX;
}
@ -323,7 +342,7 @@ static int cam_tfe_bus_get_num_wm(
switch (format) {
case CAM_FORMAT_NV12:
case CAM_FORMAT_TP10:
case CAM_FORMAT_PD10:
case CAM_FORMAT_PLAIN16_10:
return 2;
default:
break;
@ -350,6 +369,17 @@ static int cam_tfe_bus_get_num_wm(
break;
}
break;
case CAM_TFE_BUS_TFE_OUT_PD_LCR_STATS:
case CAM_TFE_BUS_TFE_OUT_PD_PREPROCESSED:
case CAM_TFE_BUS_TFE_OUT_PD_PARSED:
switch (format) {
case CAM_FORMAT_PLAIN16_10:
case CAM_FORMAT_PLAIN64:
return 1;
default:
break;
}
break;
default:
break;
}
@ -360,6 +390,47 @@ static int cam_tfe_bus_get_num_wm(
return -EINVAL;
}
static int cam_tfe_lite_bus_get_wm_idx(
enum cam_tfe_bus_tfe_out_id tfe_out_res_id,
enum cam_tfe_bus_plane_type plane)
{
int wm_idx = -1;
switch (tfe_out_res_id) {
case CAM_TFE_BUS_TFE_OUT_RDI0:
switch (plane) {
case PLANE_Y:
wm_idx = 0;
break;
default:
break;
}
break;
case CAM_TFE_BUS_TFE_OUT_RDI1:
switch (plane) {
case PLANE_Y:
wm_idx = 1;
break;
default:
break;
}
break;
case CAM_TFE_BUS_TFE_OUT_RDI2:
switch (plane) {
case PLANE_Y:
wm_idx = 2;
break;
default:
break;
}
break;
default:
break;
}
return wm_idx;
}
static int cam_tfe_bus_get_wm_idx(
enum cam_tfe_bus_tfe_out_id tfe_out_res_id,
enum cam_tfe_bus_plane_type plane,
@ -510,6 +581,33 @@ static int cam_tfe_bus_get_wm_idx(
break;
}
break;
case CAM_TFE_BUS_TFE_OUT_PD_LCR_STATS:
switch (plane) {
case PLANE_Y:
wm_idx = 16;
break;
default:
break;
}
break;
case CAM_TFE_BUS_TFE_OUT_PD_PREPROCESSED:
switch (plane) {
case PLANE_Y:
wm_idx = 17;
break;
default:
break;
}
break;
case CAM_TFE_BUS_TFE_OUT_PD_PARSED:
switch (plane) {
case PLANE_Y:
wm_idx = 18;
break;
default:
break;
}
break;
default:
break;
}
@ -561,6 +659,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
{
int pack_fmt = 0;
int rdi_width = rsrc_data->common_data->rdi_width;
int mode_cfg_shift = rsrc_data->common_data->mode_cfg_shift;
if (rdi_width == 64)
pack_fmt = 0xa;
@ -581,7 +680,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0;
rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1;
rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
}
break;
case CAM_FORMAT_MIPI_RAW_8:
@ -598,7 +697,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0;
rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1;
rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
}
break;
case CAM_FORMAT_MIPI_RAW_10:
@ -614,7 +713,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0;
rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1;
rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
}
break;
case CAM_FORMAT_MIPI_RAW_12:
@ -630,7 +729,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0;
rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1;
rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
}
break;
case CAM_FORMAT_MIPI_RAW_14:
@ -646,7 +745,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0;
rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1;
rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
}
break;
case CAM_FORMAT_PLAIN16_10:
@ -666,7 +765,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0;
rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1;
rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
}
break;
@ -684,7 +783,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0;
rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1;
rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
}
break;
default:
@ -711,14 +810,16 @@ static int cam_tfe_bus_acquire_wm(
struct cam_tfe_bus_wm_resource_data *rsrc_data = NULL;
uint32_t wm_idx = 0;
int rc = 0;
*wm_res = NULL;
/* No need to allocate for BUS TFE OUT to WM is fixed. */
wm_idx = cam_tfe_bus_get_wm_idx(tfe_out_res_id, plane,
bus_priv->common_data.pdaf_rdi2_mux_en);
if (bus_priv->common_data.is_lite)
wm_idx = cam_tfe_lite_bus_get_wm_idx(tfe_out_res_id, plane);
else
wm_idx = cam_tfe_bus_get_wm_idx(tfe_out_res_id, plane,
bus_priv->common_data.pdaf_rdi2_mux_en);
if (wm_idx < 0 || wm_idx >= bus_priv->num_client) {
CAM_ERR(CAM_ISP, "Unsupported TFE out %d plane %d",
tfe_out_res_id, plane);
CAM_ERR(CAM_ISP, "Unsupported TFE out %d plane %d wm id %d num client %d",
tfe_out_res_id, plane, wm_idx, bus_priv->num_client);
return -EINVAL;
}
@ -754,8 +855,8 @@ static int cam_tfe_bus_acquire_wm(
/* Set WM offset value to default */
rsrc_data->offset = 0;
if (((rsrc_data->index >= 7) && (rsrc_data->index <= 9)) &&
(tfe_out_res_id != CAM_TFE_BUS_TFE_OUT_PDAF)) {
if (bus_priv->common_data.is_lite || (((rsrc_data->index >= 7) &&
(rsrc_data->index <= 9)) && (tfe_out_res_id != CAM_TFE_BUS_TFE_OUT_PDAF))) {
/* WM 7-9 refers to RDI 0/ RDI 1/RDI 2 */
rc = cam_tfe_bus_acquire_rdi_wm(rsrc_data);
if (rc)
@ -781,6 +882,21 @@ static int cam_tfe_bus_acquire_wm(
case CAM_FORMAT_PLAIN16_10:
rsrc_data->pack_fmt = 0x5;
rsrc_data->pack_fmt |= 0x10;
/* AI port */
if (rsrc_data->index == 13 || rsrc_data->index == 14) {
rsrc_data->pack_fmt = 0x5;
switch (plane) {
case PLANE_C:
rsrc_data->height /= 2;
break;
case PLANE_Y:
break;
default:
CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
return -EINVAL;
}
}
break;
case CAM_FORMAT_PLAIN16_12:
rsrc_data->pack_fmt = 0x6;
@ -818,11 +934,52 @@ static int cam_tfe_bus_acquire_wm(
rsrc_data->width = 0;
rsrc_data->height = 0;
rsrc_data->stride = 1;
rsrc_data->en_cfg = (0x1 << 16) | 0x1;
rsrc_data->en_cfg = (0x1 << rsrc_data->common_data->mode_cfg_shift) | 0x1;
/*RS state packet format*/
if (rsrc_data->index == 15)
rsrc_data->pack_fmt = 0x9;
} else if (rsrc_data->index == 16) {
/* LCR */
switch (rsrc_data->format) {
case CAM_FORMAT_PLAIN64:
rsrc_data->width = 0;
rsrc_data->height = 0;
rsrc_data->stride = 1;
rsrc_data->en_cfg = (0x1 << rsrc_data->common_data->mode_cfg_shift) | 0x1;
break;
default:
CAM_ERR(CAM_ISP, "Invalid format %d out_type:%d index: %d",
rsrc_data->format, tfe_out_res_id, rsrc_data->index);
return -EINVAL;
}
} else if (rsrc_data->index == 17) {
/* PD_PREPROCESSED */
switch (rsrc_data->format) {
case CAM_FORMAT_PLAIN16_10:
rsrc_data->stride = ALIGNUP(rsrc_data->width * 2, 8);
rsrc_data->en_cfg = 0x1;
break;
default:
CAM_ERR(CAM_ISP, "Invalid format %d out_type:%d index: %d",
rsrc_data->format, tfe_out_res_id, rsrc_data->index);
return -EINVAL;
}
} else if (rsrc_data->index == 18) {
/* PD PARSED */
switch (rsrc_data->format) {
case CAM_FORMAT_PLAIN16_10:
rsrc_data->stride = ALIGNUP(rsrc_data->width * 2, 8);
rsrc_data->en_cfg = 0x1;
/* LSB aligned */
rsrc_data->pack_fmt |= (1 <<
bus_priv->common_data.pack_align_shift);
break;
default:
CAM_ERR(CAM_ISP, "Invalid format %d out_type:%d index: %d",
rsrc_data->format, tfe_out_res_id, rsrc_data->index);
return -EINVAL;
}
} else {
CAM_ERR(CAM_ISP, "Invalid WM:%d requested", rsrc_data->index);
return -EINVAL;
@ -859,6 +1016,8 @@ static int cam_tfe_bus_release_wm(void *bus_priv,
rsrc_data->en_cfg = 0;
rsrc_data->is_dual = 0;
rsrc_data->limiter_blob_status = false;
rsrc_data->is_buffer_aligned = false;
rsrc_data->buffer_offset = 0;
wm_res->tasklet_info = NULL;
wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
@ -875,13 +1034,14 @@ static int cam_tfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
wm_res->res_priv;
struct cam_tfe_bus_common_data *common_data =
rsrc_data->common_data;
int height_shift = rsrc_data->common_data->height_shift;
/* Skip to overwrite if wm bandwidth limiter blob already sent */
if (!rsrc_data->limiter_blob_status)
cam_io_w(rsrc_data->common_data->counter_limit_mask,
common_data->mem_base + rsrc_data->hw_regs->bw_limit);
cam_io_w((rsrc_data->height << 16) | rsrc_data->width,
cam_io_w((rsrc_data->height << height_shift) | rsrc_data->width,
common_data->mem_base + rsrc_data->hw_regs->image_cfg_0);
cam_io_w(rsrc_data->pack_fmt,
common_data->mem_base + rsrc_data->hw_regs->packer_cfg);
@ -897,10 +1057,6 @@ static int cam_tfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
rsrc_data->stride);
}
/* Enable WM */
cam_io_w_mb(rsrc_data->en_cfg, common_data->mem_base +
rsrc_data->hw_regs->cfg);
CAM_DBG(CAM_ISP, "TFE:%d WM:%d width = %d, height = %d",
common_data->core_index, rsrc_data->index,
rsrc_data->width, rsrc_data->height);
@ -1271,7 +1427,10 @@ static int cam_tfe_bus_init_comp_grp(uint32_t index,
INIT_LIST_HEAD(&comp_grp->list);
comp_grp->res_id = index;
rsrc_data->comp_grp_id = index;
if (bus_priv->common_data.is_lite)
rsrc_data->comp_grp_id = hw_info->bus_client_reg[index].comp_group;
else
rsrc_data->comp_grp_id = index;
rsrc_data->common_data = &bus_priv->common_data;
rsrc_data->max_wm_per_comp_grp =
bus_priv->max_wm_per_comp_grp;
@ -1697,6 +1856,8 @@ static int cam_tfe_bus_init_tfe_out_resource(uint32_t index,
for (i = 0; i < CAM_TFE_BUS_MAX_MID_PER_PORT; i++)
rsrc_data->mid[i] = hw_info->tfe_out_hw_info[index].mid[i];
rsrc_data->pid_mask = hw_info->tfe_out_hw_info[index].pid_mask;
tfe_out->hw_intf = bus_priv->common_data.hw_intf;
return 0;
@ -1745,6 +1906,8 @@ static const char *cam_tfe_bus_rup_type(
return "RDI1 RUP";
case CAM_ISP_HW_TFE_IN_RDI2:
return "RDI2 RUP";
case CAM_ISP_HW_TFE_IN_PDLIB:
return "PDLIB RUP";
default:
return "invalid rup group";
}
@ -1753,12 +1916,10 @@ static int cam_tfe_bus_rup_bottom_half(
struct cam_tfe_bus_priv *bus_priv,
struct cam_tfe_irq_evt_payload *evt_payload)
{
struct cam_tfe_bus_common_data *common_data;
struct cam_tfe_bus_tfe_out_data *out_rsrc_data;
struct cam_tfe_bus_tfe_out_data *out_rsrc_data = NULL;
struct cam_isp_hw_event_info evt_info;
uint32_t i, j;
common_data = &bus_priv->common_data;
evt_info.hw_idx = bus_priv->common_data.core_index;
evt_info.res_type = CAM_ISP_RESOURCE_TFE_OUT;
@ -1768,17 +1929,20 @@ static int cam_tfe_bus_rup_bottom_half(
break;
if (evt_payload->bus_irq_val[0] & BIT(i)) {
for (j = 0; j < CAM_TFE_BUS_TFE_OUT_MAX; j++) {
for (j = 0; j < bus_priv->num_out; j++) {
out_rsrc_data =
(struct cam_tfe_bus_tfe_out_data *)
bus_priv->tfe_out[j].res_priv;
if (!out_rsrc_data)
break;
if ((out_rsrc_data->rup_group_id == i) &&
(bus_priv->tfe_out[j].res_state ==
CAM_ISP_RESOURCE_STATE_STREAMING))
break;
}
if (j == CAM_TFE_BUS_TFE_OUT_MAX) {
if (j == bus_priv->num_out) {
CAM_ERR(CAM_ISP,
"TFE:%d out rsc active status[0]:0x%x",
bus_priv->common_data.core_index,
@ -1790,6 +1954,13 @@ static int cam_tfe_bus_rup_bottom_half(
bus_priv->common_data.core_index,
cam_tfe_bus_rup_type(i));
evt_info.res_id = i;
if (!out_rsrc_data) {
CAM_ERR(CAM_ISP,
"out_rsrc_data null for out_res: %d, RUP_group: %d",
j, i);
break;
}
if (out_rsrc_data->event_cb) {
out_rsrc_data->event_cb(
out_rsrc_data->priv,
@ -1816,13 +1987,15 @@ static uint32_t cam_tfe_bus_get_last_consumed_addr(
struct cam_isp_resource_node *rsrc_node = NULL;
struct cam_tfe_bus_tfe_out_data *rsrc_data = NULL;
struct cam_tfe_bus_wm_resource_data *wm_rsrc_data = NULL;
enum cam_tfe_bus_tfe_out_id tfe_out_res_id;
if (out_id >= CAM_TFE_BUS_TFE_OUT_MAX) {
tfe_out_res_id = cam_tfe_bus_get_out_res_id(out_id);
if (tfe_out_res_id >= CAM_TFE_BUS_TFE_OUT_MAX) {
CAM_ERR(CAM_ISP, "invalid out_id:%u", out_id);
return 0;
}
rsrc_node = &bus_priv->tfe_out[out_id];
rsrc_node = &bus_priv->tfe_out[tfe_out_res_id];
rsrc_data = rsrc_node->res_priv;
wm_rsrc_data = rsrc_data->wm_res[PLANE_Y]->res_priv;
@ -1830,6 +2003,9 @@ static uint32_t cam_tfe_bus_get_last_consumed_addr(
wm_rsrc_data->common_data->mem_base +
wm_rsrc_data->hw_regs->addr_status_0);
CAM_DBG(CAM_ISP, "TFE:%u res_type:0x%x res_id:0x%x last_consumed_addr:0x%x",
bus_priv->common_data.core_index, out_id, tfe_out_res_id, val);
return val;
}
@ -1844,6 +2020,7 @@ static int cam_tfe_bus_bufdone_bottom_half(
struct cam_tfe_bus_comp_grp_data *comp_rsrc_data;
struct cam_isp_hw_bufdone_event_info bufdone_evt_info = {0};
uint32_t i;
struct cam_tfe_bus_wm_resource_data *wm_rsrc_data = NULL;
common_data = &bus_priv->common_data;
@ -1855,31 +2032,31 @@ static int cam_tfe_bus_bufdone_bottom_half(
comp_rsrc_data = (struct cam_tfe_bus_comp_grp_data *)
bus_priv->comp_grp[i].res_priv;
CAM_DBG(CAM_ISP, "i: %d irq: 0x%x comm_done: 0x%x com_grp: %d",
i, evt_payload->bus_irq_val[0], bus_priv->common_data.comp_done_shift,
comp_rsrc_data->comp_grp_id);
if (evt_payload->bus_irq_val[0] &
BIT(comp_rsrc_data->comp_grp_id +
bus_priv->common_data.comp_done_shift)) {
out_rsrc = comp_rsrc_data->out_rsrc[0];
out_rsrc_data = out_rsrc->res_priv;
evt_info.res_type = out_rsrc->res_type;
evt_info.hw_idx = out_rsrc->hw_intf->hw_idx;
evt_info.res_id = out_rsrc->res_id;
bufdone_evt_info.res_id = out_rsrc->res_id;
bufdone_evt_info.comp_grp_id = comp_rsrc_data->comp_grp_id;
bufdone_evt_info.last_consumed_addr =
cam_tfe_bus_get_last_consumed_addr(
out_rsrc_data->bus_priv,
out_rsrc_data->out_id);
evt_info.event_data = (void *)&bufdone_evt_info;
out_rsrc = comp_rsrc_data->out_rsrc[0];
out_rsrc_data = out_rsrc->res_priv;
evt_info.res_type = out_rsrc->res_type;
evt_info.hw_idx = out_rsrc->hw_intf->hw_idx;
evt_info.res_id = out_rsrc->res_id;
bufdone_evt_info.res_id = out_rsrc->res_id;
bufdone_evt_info.comp_grp_id = comp_rsrc_data->comp_grp_id;
wm_rsrc_data = out_rsrc_data->wm_res[PLANE_Y]->res_priv;
bufdone_evt_info.last_consumed_addr = cam_io_r_mb(
wm_rsrc_data->common_data->mem_base +
wm_rsrc_data->hw_regs->addr_status_0);
evt_info.event_data = (void *)&bufdone_evt_info;
if (out_rsrc_data->event_cb)
out_rsrc_data->event_cb(out_rsrc_data->priv,
CAM_ISP_HW_EVENT_DONE,
(void *)&evt_info);
if (out_rsrc_data->event_cb)
out_rsrc_data->event_cb(out_rsrc_data->priv,
CAM_ISP_HW_EVENT_DONE,
(void *)&evt_info);
}
evt_payload->bus_irq_val[0] &=
BIT(comp_rsrc_data->comp_grp_id +
bus_priv->common_data.comp_done_shift);
}
return 0;
@ -2027,6 +2204,103 @@ end:
}
static int cam_tfe_bus_update_wm_config(void *priv, void *cmd_args,
uint32_t arg_size)
{
struct cam_tfe_bus_priv *bus_priv;
struct cam_isp_hw_get_cmd_update *update_wm_cmd;
struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL;
struct cam_tfe_bus_wm_resource_data *wm_data = NULL;
struct cam_isp_tfe_wm_dimension_config *update_out_cfg;
uint32_t i, rc = 0;
bus_priv = (struct cam_tfe_bus_priv *) priv;
update_wm_cmd = (struct cam_isp_hw_get_cmd_update *) cmd_args;
update_out_cfg = (struct cam_isp_tfe_wm_dimension_config *) update_wm_cmd->data;
tfe_out_data = (struct cam_tfe_bus_tfe_out_data *) update_wm_cmd->res->res_priv;
if (!tfe_out_data) {
CAM_ERR(CAM_ISP, "Failed! invalid data");
return -EINVAL;
}
for (i = 0; i < tfe_out_data->num_wm; i++) {
wm_data = tfe_out_data->wm_res[i]->res_priv;
wm_data->is_dim_update = true;
wm_data->width = update_out_cfg->width;
wm_data->height = update_out_cfg->height;
CAM_DBG(CAM_ISP, "WM %d width %lld height %lld", wm_data->index,
wm_data->width, wm_data->height);
}
return rc;
}
static int cam_tfe_bus_diable_wm(void *priv, void *cmd_args,
uint32_t arg_size)
{
struct cam_tfe_bus_priv *bus_priv;
struct cam_isp_hw_get_cmd_update *update_buf;
struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL;
struct cam_tfe_bus_wm_resource_data *wm_data = NULL;
struct cam_cdm_utils_ops *cdm_util_ops = NULL;
uint32_t *reg_val_pair;
uint32_t num_regval_pairs = 0;
uint32_t i, j, size = 0;
bus_priv = (struct cam_tfe_bus_priv *) priv;
update_buf = (struct cam_isp_hw_get_cmd_update *) cmd_args;
tfe_out_data = (struct cam_tfe_bus_tfe_out_data *) update_buf->res->res_priv;
if (!tfe_out_data || !(tfe_out_data->cdm_util_ops)) {
CAM_ERR(CAM_ISP, "Failed! invalid data");
return -EINVAL;
}
cdm_util_ops = tfe_out_data->cdm_util_ops;
reg_val_pair = &tfe_out_data->common_data->io_buf_update[0];
for (i = 0, j = 0; i < tfe_out_data->num_wm; i++) {
if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
CAM_ERR(CAM_ISP,
"reg_val_pair %d exceeds the array limit %zu",
j, MAX_REG_VAL_PAIR_SIZE);
return -ENOMEM;
}
wm_data = tfe_out_data->wm_res[i]->res_priv;
CAM_TFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->cfg, 0);
CAM_DBG(CAM_ISP, "WM:%d disabled cfg %x", wm_data->index, wm_data->hw_regs->cfg);
}
num_regval_pairs = j / 2;
if (num_regval_pairs) {
size = cdm_util_ops->cdm_required_size_reg_random(num_regval_pairs);
/* cdm util returns dwords, need to convert to bytes */
if ((size * 4) > update_buf->cmd.size) {
CAM_ERR(CAM_ISP,
"Failed! Buf size:%d insufficient, expected size:%d",
update_buf->cmd.size, size);
return -ENOMEM;
}
cdm_util_ops->cdm_write_regrandom(
update_buf->cmd.cmd_buf_addr,
num_regval_pairs, reg_val_pair);
/* cdm util returns dwords, need to convert to bytes */
update_buf->cmd.used_bytes = size * 4;
} else {
update_buf->cmd.used_bytes = 0;
CAM_DBG(CAM_ISP, "No reg val pairs. num_wms: %u", tfe_out_data->num_wm);
}
return 0;
}
static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
uint32_t arg_size)
{
@ -2035,7 +2309,7 @@ static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
struct cam_buf_io_cfg *io_cfg;
struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL;
struct cam_tfe_bus_wm_resource_data *wm_data = NULL;
struct cam_cdm_utils_ops *cdm_util_ops;
struct cam_cdm_utils_ops *cdm_util_ops = NULL;
uint32_t *reg_val_pair;
uint32_t num_regval_pairs = 0;
uint32_t i, j, size = 0;
@ -2047,13 +2321,13 @@ static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
tfe_out_data = (struct cam_tfe_bus_tfe_out_data *)
update_buf->res->res_priv;
cdm_util_ops = tfe_out_data->cdm_util_ops;
if (!tfe_out_data || !cdm_util_ops) {
CAM_ERR(CAM_ISP, "Failed! Invalid data");
if (!tfe_out_data || !(tfe_out_data->cdm_util_ops)) {
CAM_ERR(CAM_ISP, "Failed! invalid data");
return -EINVAL;
}
cdm_util_ops = tfe_out_data->cdm_util_ops;
if (update_buf->wm_update->num_buf != tfe_out_data->num_wm) {
CAM_ERR(CAM_ISP,
"Failed! Invalid number buffers:%d required:%d",
@ -2074,7 +2348,8 @@ static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
wm_data = tfe_out_data->wm_res[i]->res_priv;
/* update width register */
val = ((wm_data->height << 16) | (wm_data->width & 0xFFFF));
val = ((wm_data->height << wm_data->common_data->height_shift) |
(wm_data->width & 0xFFFF));
CAM_TFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->image_cfg_0, val);
CAM_DBG(CAM_ISP, "WM:%d image height and width 0x%x",
@ -2089,7 +2364,9 @@ static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
if ((wm_data->index < 7) || ((wm_data->index >= 7) &&
(wm_data->mode == CAM_ISP_TFE_WM_LINE_BASED_MODE)) ||
(wm_data->out_id == CAM_TFE_BUS_TFE_OUT_PDAF) ||
(wm_data->index >= 11 && wm_data->index <= 15)) {
(wm_data->index >= 11 && wm_data->index <= 15) ||
(wm_data->index >= 17)) {
CAM_TFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->image_cfg_2,
io_cfg->planes[i].plane_stride);
@ -2101,6 +2378,9 @@ static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
frame_inc = io_cfg->planes[i].plane_stride *
io_cfg->planes[i].slice_height;
if (wm_data->is_buffer_aligned)
update_buf->wm_update->image_buf[i] += wm_data->buffer_offset;
CAM_TFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->image_addr,
update_buf->wm_update->image_buf[i]);
@ -2148,6 +2428,38 @@ static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
return 0;
}
static int cam_tfe_buffer_alignment_update(void *priv, void *cmd_args,
uint32_t arg_size)
{
struct cam_tfe_bus_priv *bus_priv;
struct cam_isp_hw_get_cmd_update *alignment_cmd;
struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL;
struct cam_tfe_bus_wm_resource_data *wm_data = NULL;
struct cam_isp_tfe_alignment_offset_config *alignment_port_cfg = NULL;
uint32_t i, rc = 0;
bus_priv = (struct cam_tfe_bus_priv *) priv;
alignment_cmd = (struct cam_isp_hw_get_cmd_update *) cmd_args;
alignment_port_cfg = (struct cam_isp_tfe_alignment_offset_config *) alignment_cmd->data;
tfe_out_data = (struct cam_tfe_bus_tfe_out_data *) alignment_cmd->res->res_priv;
if (!tfe_out_data) {
CAM_ERR(CAM_ISP, "Failed! invalid data");
return -EINVAL;
}
for (i = 0; i < tfe_out_data->num_wm; i++) {
wm_data = tfe_out_data->wm_res[i]->res_priv;
wm_data->is_buffer_aligned = true;
wm_data->offset = alignment_port_cfg->x_offset;
wm_data->buffer_offset = alignment_port_cfg->y_offset;
CAM_DBG(CAM_ISP, "wm %d X-Offset %x Y-Offset %x", wm_data->index,
wm_data->offset, wm_data->buffer_offset);
}
return rc;
}
static int cam_tfe_bus_update_hfr(void *priv, void *cmd_args,
uint32_t arg_size)
@ -2156,7 +2468,7 @@ static int cam_tfe_bus_update_hfr(void *priv, void *cmd_args,
struct cam_isp_hw_get_cmd_update *update_hfr;
struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL;
struct cam_tfe_bus_wm_resource_data *wm_data = NULL;
struct cam_cdm_utils_ops *cdm_util_ops;
struct cam_cdm_utils_ops *cdm_util_ops = NULL;
struct cam_isp_tfe_port_hfr_config *hfr_cfg = NULL;
uint32_t *reg_val_pair;
uint32_t num_regval_pairs = 0;
@ -2168,13 +2480,12 @@ static int cam_tfe_bus_update_hfr(void *priv, void *cmd_args,
tfe_out_data = (struct cam_tfe_bus_tfe_out_data *)
update_hfr->res->res_priv;
cdm_util_ops = tfe_out_data->cdm_util_ops;
if (!tfe_out_data || !cdm_util_ops) {
CAM_ERR(CAM_ISP, "Failed! Invalid data");
if (!tfe_out_data || !(tfe_out_data->cdm_util_ops)) {
CAM_ERR(CAM_ISP, "Failed! invalid data");
return -EINVAL;
}
cdm_util_ops = tfe_out_data->cdm_util_ops;
reg_val_pair = &tfe_out_data->common_data->io_buf_update[0];
hfr_cfg = (struct cam_isp_tfe_port_hfr_config *)update_hfr->data;
@ -2295,7 +2606,9 @@ static int cam_tfe_bus_get_res_id_for_mid(
struct cam_isp_hw_get_cmd_update *cmd_update =
(struct cam_isp_hw_get_cmd_update *)cmd_args;
struct cam_isp_hw_get_res_for_mid *get_res = NULL;
uint32_t num_mid = 0, port_mid[CAM_TFE_BUS_TFE_OUT_MAX] = {0};
int i, j;
bool pid_found = false;
get_res = (struct cam_isp_hw_get_res_for_mid *)cmd_update->data;
if (!get_res) {
@ -2313,11 +2626,23 @@ static int cam_tfe_bus_get_res_id_for_mid(
for (j = 0; j < CAM_TFE_BUS_MAX_MID_PER_PORT; j++) {
if (tfe_out_data->mid[j] == get_res->mid)
goto end;
port_mid[num_mid++] = i;
}
}
if (i == bus_priv->num_out) {
for (i = 0; i < num_mid; i++) {
tfe_out_data = (struct cam_tfe_bus_tfe_out_data *)
bus_priv->tfe_out[port_mid[i]].res_priv;
get_res->out_res_id = bus_priv->tfe_out[port_mid[i]].res_id;
if (tfe_out_data->pid_mask & (1 << get_res->pid)) {
get_res->out_res_id = bus_priv->tfe_out[port_mid[i]].res_id;
pid_found = true;
goto end;
}
}
if (!num_mid) {
CAM_ERR(CAM_ISP,
"mid:%d does not match with any out resource",
get_res->mid);
@ -2326,9 +2651,8 @@ static int cam_tfe_bus_get_res_id_for_mid(
}
end:
CAM_INFO(CAM_ISP, "match mid :%d out resource:%d found",
get_res->mid, bus_priv->tfe_out[i].res_id);
get_res->out_res_id = bus_priv->tfe_out[i].res_id;
CAM_INFO(CAM_ISP, "match mid :%d out resource:%d found, is pid found %d",
get_res->mid, get_res->out_res_id, pid_found);
return 0;
}
@ -2549,15 +2873,49 @@ static int cam_tfe_bus_deinit_hw(void *hw_priv,
return rc;
}
static int cam_tfe_bus_check_overflow(
struct cam_tfe_bus_priv *bus_priv,
void *cmd_args, uint32_t arg_size)
{
struct cam_tfe_bus_wm_resource_data *rsrc_data;
struct cam_isp_hw_overflow_info *overflow_info = NULL;
uint32_t bus_overflow_status = 0, i = 0, tmp = 0;
overflow_info = (struct cam_isp_hw_overflow_info *)cmd_args;
bus_overflow_status = cam_io_r(bus_priv->common_data.mem_base +
bus_priv->common_data.common_reg->overflow_status);
if (bus_overflow_status) {
overflow_info->is_bus_overflow = true;
CAM_INFO(CAM_ISP, "TFE[%d] Bus overflow status: 0x%x",
bus_priv->common_data.core_index, bus_overflow_status);
}
tmp = bus_overflow_status;
while (tmp) {
if (tmp & 0x1) {
rsrc_data = bus_priv->bus_client[i].res_priv;
CAM_ERR(CAM_ISP, "TFE[%d] WM : %d %s overflow",
bus_priv->common_data.core_index, i,
rsrc_data->hw_regs->client_name);
}
tmp = tmp >> 1;
i++;
}
return 0;
}
static int cam_tfe_bus_process_cmd(void *priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
struct cam_tfe_bus_priv *bus_priv;
int rc = -EINVAL;
int rc = 0;
uint32_t i, val;
bool *support_consumed_addr;
bool *pdaf_rdi2_mux_en;
struct cam_isp_hw_done_event_data *done;
struct cam_isp_hw_cap *tfe_bus_cap;
if (!priv || !cmd_args) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid input arguments");
@ -2589,10 +2947,11 @@ static int cam_tfe_bus_process_cmd(void *priv,
bus_priv->common_data.common_reg->irq_mask[i]);
}
break;
case CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT:
case CAM_ISP_HW_CMD_QUERY_CAP:
bus_priv = (struct cam_tfe_bus_priv *) priv;
support_consumed_addr = (bool *)cmd_args;
*support_consumed_addr =
tfe_bus_cap = (struct cam_isp_hw_cap *) cmd_args;
tfe_bus_cap->max_out_res_type = bus_priv->max_out_res;
tfe_bus_cap->support_consumed_addr =
bus_priv->common_data.support_consumed_addr;
break;
case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
@ -2615,9 +2974,22 @@ static int cam_tfe_bus_process_cmd(void *priv,
done->last_consumed_addr = cam_tfe_bus_get_last_consumed_addr(
bus_priv, done->resource_handle);
break;
case CAM_ISP_HW_CMD_BUS_WM_DISABLE:
rc = cam_tfe_bus_diable_wm(priv, cmd_args, arg_size);
break;
case CAM_ISP_HW_NOTIFY_OVERFLOW:
rc = cam_tfe_bus_check_overflow(priv, cmd_args, arg_size);
break;
case CAM_ISP_HW_CMD_BUFFER_ALIGNMENT_UPDATE:
rc = cam_tfe_buffer_alignment_update(priv, cmd_args, arg_size);
break;
case CAM_ISP_HW_CMD_WM_CONFIG_UPDATE:
rc = cam_tfe_bus_update_wm_config(priv, cmd_args, arg_size);
break;
default:
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
cmd_type);
rc = -EINVAL;
break;
}
@ -2635,6 +3007,7 @@ int cam_tfe_bus_init(
struct cam_tfe_bus_priv *bus_priv = NULL;
struct cam_tfe_bus *tfe_bus_local;
struct cam_tfe_bus_hw_info *hw_info = bus_hw_info;
struct cam_tfe_soc_private *soc_private = NULL;
if (!soc_info || !hw_intf || !bus_hw_info) {
CAM_ERR(CAM_ISP,
@ -2644,6 +3017,13 @@ int cam_tfe_bus_init(
goto end;
}
soc_private = soc_info->soc_private;
if (!soc_private) {
CAM_ERR(CAM_ISP, "Invalid soc_private");
rc = -ENODEV;
goto end;
}
tfe_bus_local = kzalloc(sizeof(struct cam_tfe_bus), GFP_KERNEL);
if (!tfe_bus_local) {
CAM_DBG(CAM_ISP, "Failed to alloc for tfe_bus");
@ -2665,6 +3045,7 @@ int cam_tfe_bus_init(
bus_priv->num_comp_grp = hw_info->num_comp_grp;
bus_priv->max_wm_per_comp_grp = hw_info->max_wm_per_comp_grp;
bus_priv->top_bus_wr_irq_shift = hw_info->top_bus_wr_irq_shift;
bus_priv->max_out_res = hw_info->max_out_res;
bus_priv->common_data.comp_done_shift = hw_info->comp_done_shift;
bus_priv->common_data.num_sec_out = 0;
@ -2684,16 +3065,15 @@ int cam_tfe_bus_init(
bus_priv->common_data.max_bw_counter_limit = hw_info->max_bw_counter_limit;
bus_priv->common_data.counter_limit_shift = hw_info->counter_limit_shift;
bus_priv->common_data.counter_limit_mask = hw_info->counter_limit_mask;
bus_priv->common_data.mode_cfg_shift = hw_info->mode_cfg_shift;
bus_priv->common_data.height_shift = hw_info->height_shift;
bus_priv->common_data.pack_align_shift = hw_info->pack_align_shift;
for (i = 0; i < CAM_TFE_BUS_IRQ_REGISTERS_MAX; i++)
bus_priv->bus_irq_error_mask[i] =
hw_info->bus_irq_error_mask[i];
if (strnstr(soc_info->compatible, "lite",
strlen(soc_info->compatible)) != NULL)
bus_priv->common_data.is_lite = true;
else
bus_priv->common_data.is_lite = false;
bus_priv->common_data.is_lite = soc_private->is_tfe_lite;
for (i = 0; i < CAM_TFE_BUS_RUP_GRP_MAX; i++)
bus_priv->common_data.rup_irq_enable[i] = false;
@ -2808,7 +3188,7 @@ int cam_tfe_bus_deinit(
"Deinit Comp Grp failed rc=%d", rc);
}
for (i = 0; i < CAM_TFE_BUS_TFE_OUT_MAX; i++) {
for (i = 0; i < bus_priv->num_out; i++) {
rc = cam_tfe_bus_deinit_tfe_out_resource(
&bus_priv->tfe_out[i]);
if (rc < 0)

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
@ -12,7 +12,7 @@
#include "cam_isp_hw.h"
#include "cam_tfe_hw_intf.h"
#define CAM_TFE_BUS_MAX_CLIENTS 16
#define CAM_TFE_BUS_MAX_CLIENTS 19
#define CAM_TFE_BUS_MAX_SUB_GRPS 4
#define CAM_TFE_BUS_MAX_PERF_CNT_REG 8
#define CAM_TFE_BUS_MAX_IRQ_REGISTERS 2
@ -61,6 +61,7 @@ enum cam_tfe_bus_comp_grp_id {
CAM_TFE_BUS_COMP_GRP_8,
CAM_TFE_BUS_COMP_GRP_9,
CAM_TFE_BUS_COMP_GRP_10,
CAM_TFE_BUS_COMP_GRP_11,
CAM_TFE_BUS_COMP_GRP_MAX,
};
@ -69,6 +70,7 @@ enum cam_tfe_bus_rup_grp_id {
CAM_TFE_BUS_RUP_GRP_1,
CAM_TFE_BUS_RUP_GRP_2,
CAM_TFE_BUS_RUP_GRP_3,
CAM_TFE_BUS_RUP_GRP_4,
CAM_TFE_BUS_RUP_GRP_MAX,
};
@ -88,6 +90,9 @@ enum cam_tfe_bus_tfe_out_id {
CAM_TFE_BUS_TFE_OUT_DS4,
CAM_TFE_BUS_TFE_OUT_DS16,
CAM_TFE_BUS_TFE_OUT_AI,
CAM_TFE_BUS_TFE_OUT_PD_LCR_STATS,
CAM_TFE_BUS_TFE_OUT_PD_PREPROCESSED,
CAM_TFE_BUS_TFE_OUT_PD_PARSED,
CAM_TFE_BUS_TFE_OUT_MAX,
};
@ -145,6 +150,7 @@ struct cam_tfe_bus_reg_offset_bus_client {
uint32_t irq_subsample_pattern;
uint32_t framedrop_period;
uint32_t framedrop_pattern;
uint32_t system_cache_cfg;
uint32_t addr_status_0;
uint32_t addr_status_1;
uint32_t addr_status_2;
@ -161,12 +167,13 @@ struct cam_tfe_bus_reg_offset_bus_client {
* struct cam_tfe_bus_tfe_out_hw_info:
*
* @Brief: HW capability of TFE Bus Client
* tfe_out_id Tfe out port id
* max_width Max width supported by the outport
* max_height Max height supported by outport
* composite_group Out port composite group id
* rup_group_id Reg update group of outport id
* tfe_out_id: Tfe out port id
* max_width: Max width supported by the outport
* max_height: Max height supported by outport
* composite_group: Out port composite group id
* rup_group_id: Reg update group of outport id
* mid: ouport mid value
* pid: pid associated with mid
*/
struct cam_tfe_bus_tfe_out_hw_info {
enum cam_tfe_bus_tfe_out_id tfe_out_id;
@ -175,6 +182,7 @@ struct cam_tfe_bus_tfe_out_hw_info {
uint32_t composite_group;
uint32_t rup_group_id;
uint32_t mid[CAM_TFE_BUS_MAX_MID_PER_PORT];
uint64_t pid_mask;
};
/*
@ -189,6 +197,8 @@ struct cam_tfe_bus_tfe_out_hw_info {
* @num_comp_grp: Number of composite group
* @max_wm_per_comp_grp: Max number of wm associated with one composite group
* @comp_done_shift: Mask shift for comp done mask
* @mode_cfg_shift: Mask shift for mode config
* @height_shift: Mask shift for height shift
* @top_bus_wr_irq_shift: Mask shift for top level BUS WR irq
* @comp_buf_done_mask: Composite buf done bits mask
* @comp_rup_done_mask: Reg update done mask
@ -199,6 +209,9 @@ struct cam_tfe_bus_tfe_out_hw_info {
* @max_bw_counter_limit: Max BW counter limit
* @counter_limit_shift: Mask shift for BW counter limit
* @counter_limit_mask: Default Mask of BW limit counter
* @en_cfg_shift: bus client frame based enable bit
* @pack_align_shift: pack alignment shift
* @max_out_res: Max tfe out resource value supported for hw
*/
struct cam_tfe_bus_hw_info {
struct cam_tfe_bus_reg_offset_common common_reg;
@ -211,6 +224,8 @@ struct cam_tfe_bus_hw_info {
uint32_t num_comp_grp;
uint32_t max_wm_per_comp_grp;
uint32_t comp_done_shift;
uint32_t mode_cfg_shift;
uint32_t height_shift;
uint32_t top_bus_wr_irq_shift;
uint32_t comp_buf_done_mask;
uint32_t comp_rup_done_mask;
@ -221,6 +236,8 @@ struct cam_tfe_bus_hw_info {
uint32_t max_bw_counter_limit;
uint32_t counter_limit_shift;
uint32_t counter_limit_mask;
uint32_t pack_align_shift;
uint32_t max_out_res;
};
/*

Some files were not shown because too many files have changed in this diff Show More