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 endif
# Include Architecture configurations # Include Architecture configurations
ifeq ($(CONFIG_ARCH_PINEAPPLE), y) ifeq ($(CONFIG_ARCH_CLIFFS), y)
include $(CAMERA_KERNEL_ROOT)/config/pineapple.mk include $(CAMERA_KERNEL_ROOT)/config/cliffs.mk
endif
ifeq ($(CONFIG_ARCH_KALAMA), y)
include $(CAMERA_KERNEL_ROOT)/config/kalama.mk
endif endif
ifeq ($(CONFIG_ARCH_WAIPIO), y) ifeq ($(CONFIG_ARCH_WAIPIO), y)
@ -54,6 +50,24 @@ ifeq ($(CONFIG_ARCH_PARROT), y)
include $(CAMERA_KERNEL_ROOT)/config/parrot.mk include $(CAMERA_KERNEL_ROOT)/config/parrot.mk
endif 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),) ifneq ($(KBUILD_EXTRA_CONFIGS),)
include $(KBUILD_EXTRA_CONFIGS) include $(KBUILD_EXTRA_CONFIGS)
endif endif

View File

@ -6,6 +6,13 @@ config SPECTRA_ISP
This will enable camera ISP driver to handle IFE driver. This will enable camera ISP driver to handle IFE driver.
Core camera driver to handle VFE HW. 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 config SPECTRA_ICP
bool "enable camera ICP module" bool "enable camera ICP module"
help help
@ -21,7 +28,13 @@ config SPECTRA_JPEG
camera jpeg module will be functional. camera jpeg module will be functional.
This module interact with jpeg HW for This module interact with jpeg HW for
snapshot processing. 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 config SPECTRA_SENSOR
bool "enable camera sensor module" bool "enable camera sensor module"
help help
@ -86,6 +99,22 @@ config DOMAIN_ID_SECURE_CAMERA
domain ID based security architecture. domain ID based security architecture.
VC based security can be achieved with this. 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 config SAMSUNG_OIS_MCU_STM32
bool "enable camera mcu stm32 module" bool "enable camera mcu stm32 module"
help help

View File

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

View File

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

View File

@ -18,7 +18,6 @@
#define CAM_CDM_SW_CMD_COUNT 2 #define CAM_CDM_SW_CMD_COUNT 2
#define CAM_CMD_LENGTH_MASK 0xFFFF #define CAM_CMD_LENGTH_MASK 0xFFFF
#define CAM_CDM_COMMAND_OFFSET 24
#define CAM_CDM_REG_OFFSET_MASK 0x00FFFFFF #define CAM_CDM_REG_OFFSET_MASK 0x00FFFFFF
#define CAM_CDM_DMI_DATA_HI_OFFSET 8 #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, static int cam_cdm_util_cmd_buf_validation(void __iomem *base_addr,
uint32_t base_array_size, uint32_t base_array_size,
struct cam_soc_reg_map *base_table[CAM_SOC_MAX_BLOCK], 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, resource_size_t *size,
enum cam_cdm_command cmd_type) 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) { switch (cmd_type) {
case CAM_CDM_CMD_REG_RANDOM: { case CAM_CDM_CMD_REG_RANDOM: {
struct cdm_regrandom_cmd *reg_random = (struct cdm_regrandom_cmd *)buf; 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)) + if ((!reg_random->count) || (((reg_random->count * (sizeof(uint32_t) * 2)) +
cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM)) > cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM)) >
cmd_buf_size)) { 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); reg_random->count, cmd_buf_size);
ret = -EINVAL; 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; break;
case CAM_CDM_CMD_REG_CONT: { case CAM_CDM_CMD_REG_CONT: {
struct cdm_regcontinuous_cmd *reg_cont = (struct cdm_regcontinuous_cmd *) buf; struct cdm_regcontinuous_cmd *reg_cont = (struct cdm_regcontinuous_cmd *) buf;
if ((!reg_cont->count) || (((reg_cont->count * sizeof(uint32_t)) + if ((!reg_cont->count) || (((reg_cont->count * sizeof(uint32_t)) +
cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT)) > cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT)) >
cmd_buf_size)) { 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); cmd_buf_size, reg_cont->count);
ret = -EINVAL; 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; break;
case CAM_CDM_CMD_DMI:
case CAM_CDM_CMD_SWD_DMI_32:
case CAM_CDM_CMD_SWD_DMI_64: { case CAM_CDM_CMD_SWD_DMI_64: {
struct cdm_dmi_cmd *swd_dmi = (struct cdm_dmi_cmd *) buf; struct cdm_dmi_cmd *swd_dmi = (struct cdm_dmi_cmd *) buf;
if (cmd_buf_size < (cam_cdm_required_size_dmi() + swd_dmi->length + 1)) { if (cmd_buf_size < (cam_cdm_required_size_dmi() + swd_dmi->length + 1)) {
CAM_ERR(CAM_CDM, "invalid CDM_SWD_DMI length %d", CAM_ERR(CAM_CDM, "invalid CDM_SWD_DMI length %d",
swd_dmi->length + 1); swd_dmi->length + 1);
ret = -EINVAL; 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; break;
default: default:
@ -572,27 +635,19 @@ static int cam_cdm_util_reg_cont_write(void __iomem *base_addr,
struct cdm_regcontinuous_cmd reg_cont; struct cdm_regcontinuous_cmd reg_cont;
resource_size_t size = 0; 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, 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) { if (rc) {
CAM_ERR(CAM_CDM, "Validation failed! rc=%d", rc); CAM_ERR(CAM_CDM, "Validation failed! rc=%d", rc);
return 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); data = cmd_buf + cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT);
if ((reg_cont.offset <= size) && ((reg_cont.offset + cam_io_memcpy(base_addr + reg_cont.offset, data,
(reg_cont.count * sizeof(uint32_t))) <= size)) { reg_cont.count * sizeof(uint32_t));
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;
}
*used_bytes = (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)); (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; uint32_t *data, offset;
resource_size_t size = 0; 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, 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); &size, CAM_CDM_CMD_REG_RANDOM);
if (rc) { if (rc) {
CAM_ERR(CAM_CDM, "Validation failed! rc=%d", rc); CAM_ERR(CAM_CDM, "Validation failed! rc=%d", rc);
return 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); data = cmd_buf + cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);
for (i = 0; i < reg_random.count; i++) { for (i = 0; i < reg_random.count; i++) {
offset = data[0]; offset = data[0];
if (offset <= size) { CAM_DBG(CAM_CDM, "reg random: offset %pK, value 0x%x",
CAM_DBG(CAM_CDM, "reg random: offset %pK, value 0x%x", ((void __iomem *)(base_addr + offset)),
((void __iomem *)(base_addr + offset)), data[1]);
data[1]); cam_io_w(data[1], base_addr + offset);
cam_io_w(data[1], base_addr + offset); data += 2;
data += 2;
} else {
CAM_ERR(CAM_CDM, "Offset out of mapped range! size: %llu, offset: %u",
size, offset);
return -EINVAL;
}
} }
*used_bytes = ((reg_random.count * (sizeof(uint32_t) * 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; uint32_t *data;
resource_size_t size = 0; 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, 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); &size, cdm_cmd_type);
if (rc) { if (rc) {
CAM_ERR(CAM_CDM, "Validation failed! rc=%d", rc); CAM_ERR(CAM_CDM, "Validation failed! rc=%d", rc);
return rc; return rc;
} }
memcpy(&swd_dmi, cmd_buf, sizeof(struct cdm_dmi_cmd));
data = cmd_buf + cam_cdm_required_size_dmi(); data = cmd_buf + cam_cdm_required_size_dmi();
if (cdm_cmd_type == CAM_CDM_CMD_SWD_DMI_64) { 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++) { for (i = 0; i < (swd_dmi.length + 1)/8; i++) {
cam_io_w_mb(data[0], base_addr + cam_io_w_mb(data[0], base_addr +
swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET); swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET);
cam_io_w_mb(data[1], base_addr + 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; data += 2;
} }
} else if (cdm_cmd_type == CAM_CDM_CMD_DMI) { } 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++) { for (i = 0; i < (swd_dmi.length + 1)/4; i++) {
cam_io_w_mb(data[0], base_addr + cam_io_w_mb(data[0], base_addr +
swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_OFFSET); swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_OFFSET);
data += 1; data += 1;
} }
} else { } 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++) { for (i = 0; i < (swd_dmi.length + 1)/4; i++) {
cam_io_w_mb(data[0], base_addr + cam_io_w_mb(data[0], base_addr +
swd_dmi.DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET); 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; 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( void cam_cdm_util_dump_cmd_buf(
uint32_t *cmd_buf_start, uint32_t *cmd_buf_end) uint32_t *cmd_buf_start, uint32_t *cmd_buf_end)
{ {
@ -1039,7 +1151,7 @@ void cam_cdm_util_dump_cmd_buf(
buf_now++; buf_now++;
break; break;
} }
} while (buf_now <= cmd_buf_end); } while (buf_now < cmd_buf_end);
} }
static uint32_t cam_cdm_util_dump_reg_cont_cmd_v2( 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++; buf_now++;
break; break;
} }
} while (buf_now <= dump_info->src_end); } while (buf_now < dump_info->src_end);
return rc; return rc;
} }

View File

@ -9,6 +9,7 @@
/* Max len for tag name for header while dumping cmd buffer*/ /* Max len for tag name for header while dumping cmd buffer*/
#define CAM_CDM_CMD_TAG_MAX_LEN 128 #define CAM_CDM_CMD_TAG_MAX_LEN 128
#define CAM_CDM_COMMAND_OFFSET 24
#include <linux/types.h> #include <linux/types.h>
@ -227,6 +228,20 @@ struct cam_cdm_cmd_dump_header {
uint32_t word_size; 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() * cam_cdm_util_log_cmd_bufs()
* *

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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> #include <linux/slab.h>
@ -355,6 +355,31 @@ int cam_context_dump_pf_info(void *data, void *args)
return rc; 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, int cam_context_handle_acquire_dev(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd) struct cam_acquire_dev_cmd *cmd)
{ {

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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_ #ifndef _CAM_CONTEXT_H_
@ -168,7 +168,9 @@ struct cam_ctx_crm_ops {
* context info * context info
* @recovery_ops: Function to be invoked to try hardware recovery * @recovery_ops: Function to be invoked to try hardware recovery
* @mini_dump_ops: Function for mini dump * @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 { struct cam_ctx_ops {
@ -180,6 +182,7 @@ struct cam_ctx_ops {
cam_ctx_recovery_cb_func recovery_ops; cam_ctx_recovery_cb_func recovery_ops;
cam_ctx_mini_dump_cb_func mini_dump_ops; cam_ctx_mini_dump_cb_func mini_dump_ops;
cam_ctx_err_inject_cb_func evt_inject_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 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 * 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, int cam_context_dump_pf_info(void *ctx,
void *pf_args); 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() * cam_context_handle_acquire_dev()
* *

View File

@ -1487,6 +1487,40 @@ end:
return rc; 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, static int cam_context_user_dump(struct cam_context *ctx,
struct cam_hw_dump_args *dump_args) 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; struct cam_context_dump_header *hdr;
uint8_t *dst; uint8_t *dst;
uint64_t *addr, *start; uint64_t *addr, *start;
uint32_t min_len;
size_t buf_len, remain_len; size_t buf_len, remain_len;
uintptr_t cpu_addr; uintptr_t cpu_addr;
uint32_t local_len;
if (!ctx || !dump_args) { if (!ctx || !dump_args) {
CAM_ERR(CAM_CORE, "Invalid parameters %pK %pK", CAM_ERR(CAM_CORE, "Invalid parameters %pK %pK",
@ -1521,107 +1555,31 @@ static int cam_context_user_dump(struct cam_context *ctx,
return -ENOSPC; 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 */ /* 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; dst = (uint8_t *)cpu_addr + dump_args->offset;
hdr = (struct cam_context_dump_header *)dst; 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, scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
"%s_CTX_INFO:", ctx->dev_name); "%s_CTX_INFO:", ctx->dev_name);
hdr->word_size = sizeof(uint64_t); hdr->word_size = sizeof(uint64_t);
addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header)); addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
start = addr; start = addr;
*addr++ = ctx->hw_mgr_ctx_id; if (cam_context_stream_dump_validation(ctx, addr, local_len, buf_len)) {
*addr++ = ctx->dev_id; CAM_WARN(CAM_CTXT, "%s_CTX_INFO failed to copy the stream info ", ctx->dev_name);
*addr++ = ctx->dev_hdl; cam_mem_put_cpu_buf(dump_args->buf_handle);
*addr++ = ctx->link_hdl; return -ENOSPC;
*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;
}
} }
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);
/* 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;
}
}
hdr->size = hdr->word_size * (addr - start); hdr->size = hdr->word_size * (addr - start);
dump_args->offset += hdr->size + dump_args->offset += hdr->size +
sizeof(struct cam_context_dump_header); 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)) { if (!list_empty(&ctx->wait_req_list)) {
list_for_each_entry_safe(req, req_temp, &ctx->wait_req_list, list) { list_for_each_entry_safe(req, req_temp, &ctx->wait_req_list, list) {
for (i = 0; i < req->num_out_map_entries; i++) { 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; dst = (uint8_t *)cpu_addr + dump_args->offset;
hdr = (struct cam_context_dump_header *)dst; 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, scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
"%s_OUT_FENCE_REQUEST_APPLIED.%d.%d.%d:", "%s_OUT_FENCE_REQUEST_APPLIED.%d.%d.%d:",
ctx->dev_name, ctx->dev_name,
@ -1641,7 +1610,14 @@ static int cam_context_user_dump(struct cam_context *ctx,
hdr->word_size = sizeof(uint64_t); hdr->word_size = sizeof(uint64_t);
addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header)); addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
start = addr; 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); hdr->size = hdr->word_size * (addr - start);
dump_args->offset += hdr->size + dump_args->offset += hdr->size +
sizeof(struct cam_context_dump_header); 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)) { if (!list_empty(&ctx->pending_req_list)) {
list_for_each_entry_safe(req, req_temp, &ctx->pending_req_list, list) { list_for_each_entry_safe(req, req_temp, &ctx->pending_req_list, list) {
for (i = 0; i < req->num_out_map_entries; i++) { 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; dst = (uint8_t *)cpu_addr + dump_args->offset;
hdr = (struct cam_context_dump_header *)dst; 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, scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
"%s_OUT_FENCE_REQUEST_PENDING.%d.%d.%d:", "%s_OUT_FENCE_REQUEST_PENDING.%d.%d.%d:",
ctx->dev_name, ctx->dev_name,
@ -1664,7 +1651,14 @@ static int cam_context_user_dump(struct cam_context *ctx,
hdr->word_size = sizeof(uint64_t); hdr->word_size = sizeof(uint64_t);
addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header)); addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
start = addr; 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); hdr->size = hdr->word_size * (addr - start);
dump_args->offset += hdr->size + dump_args->offset += hdr->size +
sizeof(struct cam_context_dump_header); 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)) { if (!list_empty(&ctx->active_req_list)) {
list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) { list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) {
for (i = 0; i < req->num_out_map_entries; i++) { 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; dst = (uint8_t *)cpu_addr + dump_args->offset;
hdr = (struct cam_context_dump_header *)dst; 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, scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
"%s_OUT_FENCE_REQUEST_ACTIVE.%d.%d.%d:", "%s_OUT_FENCE_REQUEST_ACTIVE.%d.%d.%d:",
ctx->dev_name, ctx->dev_name,
@ -1687,14 +1692,21 @@ static int cam_context_user_dump(struct cam_context *ctx,
hdr->word_size = sizeof(uint64_t); hdr->word_size = sizeof(uint64_t);
addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header)); addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
start = addr; 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); hdr->size = hdr->word_size * (addr - start);
dump_args->offset += hdr->size + dump_args->offset += hdr->size +
sizeof(struct cam_context_dump_header); sizeof(struct cam_context_dump_header);
} }
} }
} }
cleanup:
cam_mem_put_cpu_buf(dump_args->buf_handle); cam_mem_put_cpu_buf(dump_args->buf_handle);
return 0; return 0;
} }

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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_ #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, typedef int (*cam_ctx_err_inject_cb_func)(void *context,
void *args); 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 * 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) * @hw_mgr_ctx_id HWMgr context id(returned)
* @op_flags: Used as bitwise params from hw_mgr to ctx * @op_flags: Used as bitwise params from hw_mgr to ctx
* See xxx_hw_mgr_intf.h for definitions * See xxx_hw_mgr_intf.h for definitions
* @link_hdl: Link handle
* @acquired_hw_id: Acquired hardware mask * @acquired_hw_id: Acquired hardware mask
* @acquired_hw_path: Acquired path mask for an input * @acquired_hw_path: Acquired path mask for an input
* if input splits into multiple paths, * if input splits into multiple paths,
* its updated per hardware * its updated per hardware
* @valid_acquired_hw: Valid num of acquired 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 * @op_params: OP Params from hw_mgr to ctx
* @mini_dump_cb: Mini dump callback function * @mini_dump_cb: Mini dump callback function
* *
@ -185,11 +191,11 @@ struct cam_hw_acquire_args {
void *ctxt_to_hw_map; void *ctxt_to_hw_map;
uint32_t hw_mgr_ctx_id; uint32_t hw_mgr_ctx_id;
uint32_t op_flags; uint32_t op_flags;
int32_t link_hdl;
uint32_t acquired_hw_id[CAM_MAX_ACQ_RES]; uint32_t acquired_hw_id[CAM_MAX_ACQ_RES];
uint32_t acquired_hw_path[CAM_MAX_ACQ_RES][CAM_MAX_HW_SPLIT]; uint32_t acquired_hw_path[CAM_MAX_ACQ_RES][CAM_MAX_HW_SPLIT];
uint32_t valid_acquired_hw; uint32_t valid_acquired_hw;
uint32_t total_ports_acq;
struct cam_hw_acquire_stream_caps op_params; struct cam_hw_acquire_stream_caps op_params;
cam_ctx_mini_dump_cb_func mini_dump_cb; cam_ctx_mini_dump_cb_func mini_dump_cb;
}; };

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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> #include <linux/device.h>
@ -514,7 +514,7 @@ bus_register_fail:
return rc; 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 enable)
{ {
int rc, i = 0; int rc, i = 0;
@ -983,7 +983,8 @@ static int cam_cpas_apply_smart_qos(
struct cam_cpas_tree_node *niu_node; struct cam_cpas_tree_node *niu_node;
struct cam_camnoc_info *camnoc_info; struct cam_camnoc_info *camnoc_info;
uint8_t i; 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) { if (cpas_core->smart_qos_dump) {
CAM_INFO(CAM_PERF, "Printing SmartQos values before update"); 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]; niu_node = soc_private->smart_qos_info->rt_wr_niu_node[i];
if (niu_node->curr_priority_high != niu_node->applied_priority_high) { if (niu_node->curr_priority_high != niu_node->applied_priority_high) {
cam_io_w_mb(niu_node->curr_priority_high, if (!soc_private->enable_secure_qos_update) {
soc_info->reg_map[reg_indx].mem_base + cam_io_w_mb(niu_node->curr_priority_high,
niu_node->pri_lut_high_offset); 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; niu_node->applied_priority_high = niu_node->curr_priority_high;
} }
if (niu_node->curr_priority_low != niu_node->applied_priority_low) { if (niu_node->curr_priority_low != niu_node->applied_priority_low) {
cam_io_w_mb(niu_node->curr_priority_low, if (!soc_private->enable_secure_qos_update) {
soc_info->reg_map[reg_indx].mem_base + cam_io_w_mb(niu_node->curr_priority_low,
niu_node->pri_lut_low_offset); 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; 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) { 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; req_drv_low_camnoc_bw = 0, intermediate_drv_low_result = 0;
int64_t drv_high_clk_rate = 0, drv_low_clk_rate = 0; int64_t drv_high_clk_rate = 0, drv_low_clk_rate = 0;
int i, rc = 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) { if (!soc_private->enable_cam_clk_drv) {
CAM_ERR(CAM_CPAS, "Clk DRV not enabled, can't set clk rates through cesta APIs"); 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); hw_client_idx, rc);
return 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; 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; int64_t hlos_clk_rate = 0;
int i, rc = 0; int i, rc = 0;
const struct camera_debug_settings *cam_debug = NULL; 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++) { for (i = 0; i < CAM_CPAS_MAX_TREE_NODES; i++) {
tree_node = soc_private->tree_node[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); do_div(intermediate_hlos_result, soc_private->camnoc_bus_width);
hlos_clk_rate = intermediate_hlos_result; 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); 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); req_hlos_camnoc_bw, hlos_clk_rate, rc);
cpas_core->applied_camnoc_axi_rate.sw_client = hlos_clk_rate; 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; 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_camnoc_clk.hw_client[2].low,
*addr++ = monitor->applied_ahb_level; *addr++ = monitor->applied_ahb_level;
*addr++ = cpas_core->num_valid_camnoc; *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++ = num_vcds;
*addr++ = cpas_core->num_axi_ports; *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++) { if (soc_private->enable_smart_qos) {
niu_node = soc_private->smart_qos_info->rt_wr_niu_node[i]; for (i = 0; i < soc_private->smart_qos_info->num_rt_wr_nius; i++) {
dst = (uint8_t *)addr; niu_node = soc_private->smart_qos_info->rt_wr_niu_node[i];
hdr = (struct cam_common_hw_dump_header *)dst; dst = (uint8_t *)addr;
scnprintf(hdr->tag, CAM_COMMON_HW_DUMP_TAG_MAX_LEN, "%s:", niu_node->node_name); hdr = (struct cam_common_hw_dump_header *)dst;
addr = (uint64_t *)(dst + sizeof(struct cam_common_hw_dump_header)); scnprintf(hdr->tag, CAM_COMMON_HW_DUMP_TAG_MAX_LEN, "%s:", niu_node->node_name);
*addr++ = monitor->rt_wr_niu_pri_lut_high[i]; addr = (uint64_t *)(dst + sizeof(struct cam_common_hw_dump_header));
*addr++ = monitor->rt_wr_niu_pri_lut_low[i]; *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; 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); min_len += sizeof(struct cam_common_hw_dump_header);
} }
for (j = 0; j < soc_private->smart_qos_info->num_rt_wr_nius; j++) if (soc_private->enable_smart_qos) {
min_len += sizeof(struct cam_common_hw_dump_header) + for (j = 0; j < soc_private->smart_qos_info->num_rt_wr_nius; j++)
CAM_CPAS_DUMP_NUM_WORDS_RT_WR_NIUS * sizeof(uint64_t); 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++) for (j = 0; j < CAM_CPAS_MAX_CESTA_VCD_NUM; j++)
min_len += CAM_CPAS_DUMP_NUM_WORDS_VCD_CURR_LVL * sizeof(uint64_t); min_len += CAM_CPAS_DUMP_NUM_WORDS_VCD_CURR_LVL * sizeof(uint64_t);
@ -3694,6 +3699,32 @@ done:
return rc; 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( static int cam_cpas_activate_cache(
struct cam_hw_info *cpas_hw, struct cam_hw_info *cpas_hw,
struct cam_sys_cache_info *cache_info) 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, rc = cam_common_util_get_string_index(soc_private->client_name,
soc_private->num_clients, client_name, &client_indx); 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) if (!cpas_core->cpas_client[client_indx]->is_drv_dyn)
return 0; 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); rc = cam_cpas_hw_csid_process_resume(hw_priv, *csid_idx);
break; 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: { case CAM_CPAS_HW_CMD_ENABLE_DISABLE_DOMAIN_ID_CLK: {
bool *enable; 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_hw_intf->hw_ops.process_cmd = cam_cpas_hw_process_cmd;
cpas_core->work_queue = alloc_workqueue(CAM_CPAS_WORKQUEUE_NAME, 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) { if (!cpas_core->work_queue) {
rc = -ENOMEM; rc = -ENOMEM;
goto release_mem; 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 * @print_poweron_settings: Function pointer for hw to print poweron settings
* @qchannel_handshake: Function pointer for hw core specific qchannel * @qchannel_handshake: Function pointer for hw core specific qchannel
* handshake settings * handshake settings
* @set_tpg_mux_sel: Set tpg mux select on CPAS TOP register
* *
*/ */
struct cam_cpas_internal_ops { struct cam_cpas_internal_ops {
@ -186,6 +187,7 @@ struct cam_cpas_internal_ops {
uint32_t selection_mask); uint32_t selection_mask);
int (*print_poweron_settings)(struct cam_hw_info *cpas_hw); 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 (*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_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_ */ #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_INPUT_CORE_INFO_UPDATE,
CAM_CPAS_HW_CMD_CSID_PROCESS_RESUME, CAM_CPAS_HW_CMD_CSID_PROCESS_RESUME,
CAM_CPAS_HW_CMD_ENABLE_DISABLE_DOMAIN_ID_CLK, 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_DUMP_STATE_MONITOR_INFO,
CAM_CPAS_HW_CMD_INVALID, 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. * @brief : API to remove CPAS interface from platform framework.
*/ */
void cam_cpas_dev_exit_module(void); 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_ */ #endif /* _CAM_CPAS_HW_INTF_H_ */

View File

@ -22,10 +22,18 @@
#include "cam_cpas_soc.h" #include "cam_cpas_soc.h"
#include "cam_cpastop_hw.h" #include "cam_cpastop_hw.h"
#include "camera_main.h" #include "camera_main.h"
#include "cam_cpas_hw.h"
#include <linux/soc/qcom/llcc-qcom.h> #include <linux/soc/qcom/llcc-qcom.h>
#include "cam_req_mgr_interface.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_DEV_NAME "cam-cpas"
#define CAM_CPAS_INTF_INITIALIZED() (g_cpas_intf && g_cpas_intf->probe_done) #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); 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, int cam_cpas_notify_event(const char *identifier_string,
int32_t identifier_value) 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); 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, int cam_cpas_subdev_cmd(struct cam_cpas_intf *cpas_intf,
struct cam_control *cmd) struct cam_control *cmd)
{ {
@ -1208,6 +1389,19 @@ int cam_cpas_subdev_cmd(struct cam_cpas_intf *cpas_intf,
break; 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: case CAM_SD_SHUTDOWN:
break; break;
default: default:

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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> #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->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, soc_private->enable_smart_qos = of_property_read_bool(of_node,
"enable-smart-qos"); "enable-smart-qos");

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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_ #ifndef _CAM_CPAS_SOC_H_
@ -268,6 +268,7 @@ struct cam_cpas_sysfs_info {
* @num_caches: Number of last level caches * @num_caches: Number of last level caches
* @part_info: Camera Hw subpart info * @part_info: Camera Hw subpart info
* @llcc_info: Cache 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_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_ddr_drv: Whether to enable Camera DDR DRV on current chipset
* @enable_cam_clk_drv: Whether to enable Camera Clk 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_smart_qos;
bool enable_cam_ddr_drv; bool enable_cam_ddr_drv;
bool enable_cam_clk_drv; bool enable_cam_clk_drv;
bool enable_secure_qos_update;
struct cam_cpas_smart_qos_info *smart_qos_info; struct cam_cpas_smart_qos_info *smart_qos_info;
int32_t icp_clk_index; int32_t icp_clk_index;
struct cam_cpas_domain_id_info domain_id_info; struct cam_cpas_domain_id_info domain_id_info;

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved. * 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" #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->setup_qos_settings = NULL;
internal_ops->print_poweron_settings = NULL; internal_ops->print_poweron_settings = NULL;
internal_ops->qchannel_handshake = NULL; internal_ops->qchannel_handshake = NULL;
internal_ops->set_tpg_mux_sel = NULL;
return 0; return 0;
} }

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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> #include <linux/delay.h>
@ -36,13 +36,19 @@
#include "cpastop_v165_100.h" #include "cpastop_v165_100.h"
#include "cpastop_v780_100.h" #include "cpastop_v780_100.h"
#include "cpastop_v640_200.h" #include "cpastop_v640_200.h"
#include "cpastop_v640_210.h"
#include "cpastop_v880_100.h" #include "cpastop_v880_100.h"
#include "cpastop_v980_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_req_mgr_workq.h"
#include "cam_common_util.h" #include "cam_common_util.h"
struct cam_camnoc_info *camnoc_info[CAM_CAMNOC_HW_TYPE_MAX]; struct cam_camnoc_info *camnoc_info[CAM_CAMNOC_HW_TYPE_MAX];
struct cam_cpas_info *cpas_info; 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)) #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]; 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,
0, 0,
0,
}, },
/* for camera_170 */ /* for camera_170 */
{ {
@ -79,6 +86,7 @@ static const uint32_t cam_cpas_hw_version_map
CAM_CPAS_TITAN_170_V120, CAM_CPAS_TITAN_170_V120,
0, 0,
CAM_CPAS_TITAN_170_V200, CAM_CPAS_TITAN_170_V200,
0,
}, },
/* for camera_175 */ /* 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_V120,
CAM_CPAS_TITAN_175_V130, CAM_CPAS_TITAN_175_V130,
0, 0,
0,
}, },
/* for camera_480 */ /* for camera_480 */
{ {
@ -97,6 +106,7 @@ static const uint32_t cam_cpas_hw_version_map
0, 0,
0, 0,
0, 0,
0,
}, },
/* for camera_580 */ /* for camera_580 */
{ {
@ -106,6 +116,7 @@ static const uint32_t cam_cpas_hw_version_map
0, 0,
0, 0,
0, 0,
0,
}, },
/* for camera_520 */ /* for camera_520 */
{ {
@ -115,6 +126,7 @@ static const uint32_t cam_cpas_hw_version_map
0, 0,
0, 0,
0, 0,
0,
}, },
/* for camera_540 */ /* for camera_540 */
@ -125,6 +137,7 @@ static const uint32_t cam_cpas_hw_version_map
0, 0,
0, 0,
0, 0,
0,
}, },
/* for camera_545 */ /* for camera_545 */
{ {
@ -134,6 +147,7 @@ static const uint32_t cam_cpas_hw_version_map
0, 0,
0, 0,
0, 0,
0,
}, },
/* for camera_570 */ /* for camera_570 */
{ {
@ -143,6 +157,7 @@ static const uint32_t cam_cpas_hw_version_map
0, 0,
0, 0,
CAM_CPAS_TITAN_570_V200, CAM_CPAS_TITAN_570_V200,
0,
}, },
/* for camera_680 */ /* for camera_680 */
{ {
@ -152,6 +167,7 @@ static const uint32_t cam_cpas_hw_version_map
0, 0,
0, 0,
0, 0,
0,
}, },
/* for camera_165 */ /* for camera_165 */
{ {
@ -161,6 +177,7 @@ static const uint32_t cam_cpas_hw_version_map
0, 0,
0, 0,
0, 0,
0,
}, },
/* for camera_780 */ /* for camera_780 */
{ {
@ -170,6 +187,7 @@ static const uint32_t cam_cpas_hw_version_map
0, 0,
0, 0,
0, 0,
0,
}, },
/* for camera_640 */ /* for camera_640 */
{ {
@ -179,6 +197,7 @@ static const uint32_t cam_cpas_hw_version_map
0, 0,
0, 0,
CAM_CPAS_TITAN_640_V200, CAM_CPAS_TITAN_640_V200,
CAM_CPAS_TITAN_640_V210,
}, },
/* for camera_880 */ /* for camera_880 */
{ {
@ -188,6 +207,7 @@ static const uint32_t cam_cpas_hw_version_map
0, 0,
0, 0,
0, 0,
0,
}, },
/* for camera_980 */ /* for camera_980 */
{ {
@ -197,6 +217,37 @@ static const uint32_t cam_cpas_hw_version_map
0, 0,
0, 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: case CAM_CPAS_CAMERA_VERSION_980:
*cam_version_id = CAM_CPAS_CAMERA_VERSION_ID_980; *cam_version_id = CAM_CPAS_CAMERA_VERSION_ID_980;
break; 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: default:
CAM_ERR(CAM_CPAS, "Invalid cam version %u", CAM_ERR(CAM_CPAS, "Invalid cam version %u",
cam_version); cam_version);
@ -310,6 +370,10 @@ static int cam_cpas_translate_camera_cpas_version_id(
*cpas_version_id = CAM_CPAS_VERSION_ID_200; *cpas_version_id = CAM_CPAS_VERSION_ID_200;
break; break;
case CAM_CPAS_VERSION_210:
*cpas_version_id = CAM_CPAS_VERSION_ID_210;
break;
default: default:
CAM_ERR(CAM_CPAS, "Invalid cpas version %u", CAM_ERR(CAM_CPAS, "Invalid cpas version %u",
cpas_version); 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) 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_list *errata_wa_list;
struct cam_cpas_hw_errata_wa *errata_wa; struct cam_cpas_hw_errata_wa *errata_wa;
struct cam_cpas *cpas_core = cpas_hw->core_info; 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; bool errata_enabled = false;
for (i = 0; i < cpas_core->num_valid_camnoc; i++) for (i = 0; i < cpas_core->num_valid_camnoc; i++)
cam_cpastop_reset_irq(0x0, cpas_hw, i); cam_cpastop_reset_irq(0x0, cpas_hw, i);
for (i = 0; i < cpas_core->num_valid_camnoc; i++) { if (!soc_private->enable_secure_qos_update) {
CAM_DBG(CAM_CPAS, "QOS settings for %s :", for (i = 0; i < cpas_core->num_valid_camnoc; i++) {
camnoc_info[i]->camnoc_name); CAM_DBG(CAM_CPAS, "QOS settings for %s :",
for (j = 0; j < camnoc_info[i]->specific_size; j++) { camnoc_info[i]->camnoc_name);
if (camnoc_info[i]->specific[j].enable) { for (j = 0; j < camnoc_info[i]->specific_size; j++) {
CAM_DBG(CAM_CPAS, if (camnoc_info[i]->specific[j].enable) {
"Updating QoS settings port: %d prot name: %s", CAM_DBG(CAM_CPAS,
camnoc_info[i]->specific[j].port_type, "Updating QoS settings port: %d prot name: %s",
camnoc_info[i]->specific[j].port_name); camnoc_info[i]->specific[j].port_type,
cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base, camnoc_info[i]->specific[j].port_name);
&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) { cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
errata_wa_list = camnoc_info[i]->errata_wa_list; &camnoc_info[i]->specific[j].priority_lut_low);
if (errata_wa_list) { cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
errata_wa = &errata_wa_list->tcsr_camera_hf_sf_ares_glitch; &camnoc_info[i]->specific[j].priority_lut_high);
if (errata_wa->enable) { cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
cam_cpastop_scm_write(errata_wa); &camnoc_info[i]->specific[j].urgency);
errata_enabled = true; 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; return 0;
@ -1277,6 +1354,33 @@ static int cam_cpastop_get_hw_capability(struct cam_hw_info *cpas_hw)
return 0; 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, static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
struct cam_cpas_hw_caps *hw_caps) 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_cpas_cesta_info *cesta_info = NULL;
struct cam_camnoc_info *alloc_camnoc_info[CAM_CAMNOC_HW_TYPE_MAX] = {0}; struct cam_camnoc_info *alloc_camnoc_info[CAM_CAMNOC_HW_TYPE_MAX] = {0};
qchannel_info = NULL;
cpas_top_info = NULL;
CAM_DBG(CAM_CPAS, CAM_DBG(CAM_CPAS,
"hw_version=0x%x Camera Version %d.%d.%d, cpas version %d.%d.%d", "hw_version=0x%x Camera Version %d.%d.%d, cpas version %d.%d.%d",
soc_info->hw_version, 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: case CAM_CPAS_TITAN_640_V200:
alloc_camnoc_info[CAM_CAMNOC_HW_COMBINED] = &cam640_cpas200_camnoc_info; alloc_camnoc_info[CAM_CAMNOC_HW_COMBINED] = &cam640_cpas200_camnoc_info;
cpas_info = &cam640_cpas200_cpas_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; break;
case CAM_CPAS_TITAN_880_V100: case CAM_CPAS_TITAN_880_V100:
alloc_camnoc_info[CAM_CAMNOC_HW_COMBINED] = &cam880_cpas100_camnoc_info; 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; cpas_info = &cam980_cpas100_cpas_info;
cesta_info = &cam_v980_cesta_info; cesta_info = &cam_v980_cesta_info;
break; 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: default:
CAM_ERR(CAM_CPAS, "Camera Version not supported %d.%d.%d", CAM_ERR(CAM_CPAS, "Camera Version not supported %d.%d.%d",
hw_caps->camera_version.major, 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 = internal_ops->print_poweron_settings =
cam_cpastop_print_poweron_settings; cam_cpastop_print_poweron_settings;
internal_ops->qchannel_handshake = cam_cpastop_qchannel_handshake; internal_ops->qchannel_handshake = cam_cpastop_qchannel_handshake;
internal_ops->set_tpg_mux_sel = cam_cpastop_set_tpg_mux_sel;
return 0; return 0;
} }

View File

@ -534,4 +534,17 @@ struct cam_cpas_info {
uint8_t num_qchannel; 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_ */ #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 = { 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 = { 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, .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_ */ #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 */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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_ #ifndef _CAM_CPAS_API_H_
@ -32,6 +32,15 @@
#define CAM_CPAS_QOS_DEFAULT_SETTINGS_MASK 0x1 #define CAM_CPAS_QOS_DEFAULT_SETTINGS_MASK 0x1
#define CAM_CPAS_QOS_CUSTOM_SETTINGS_MASK 0x2 #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 * enum cam_cpas_regbase_types - Enum for cpas regbase available for clients
* to read/write * to read/write
@ -86,6 +95,9 @@ enum cam_cpas_camera_version {
CAM_CPAS_CAMERA_VERSION_640 = 0x00060400, CAM_CPAS_CAMERA_VERSION_640 = 0x00060400,
CAM_CPAS_CAMERA_VERSION_880 = 0x00080800, CAM_CPAS_CAMERA_VERSION_880 = 0x00080800,
CAM_CPAS_CAMERA_VERSION_980 = 0x00090800, 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 CAM_CPAS_CAMERA_VERSION_MAX
}; };
@ -100,6 +112,7 @@ enum cam_cpas_version {
CAM_CPAS_VERSION_120 = 0x10020000, CAM_CPAS_VERSION_120 = 0x10020000,
CAM_CPAS_VERSION_130 = 0x10030000, CAM_CPAS_VERSION_130 = 0x10030000,
CAM_CPAS_VERSION_200 = 0x20000000, CAM_CPAS_VERSION_200 = 0x20000000,
CAM_CPAS_VERSION_210 = 0x20010000,
CAM_CPAS_VERSION_MAX 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_640 = 0xC,
CAM_CPAS_CAMERA_VERSION_ID_880 = 0xD, CAM_CPAS_CAMERA_VERSION_ID_880 = 0xD,
CAM_CPAS_CAMERA_VERSION_ID_980 = 0xE, 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 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_120 = 0x3,
CAM_CPAS_VERSION_ID_130 = 0x4, CAM_CPAS_VERSION_ID_130 = 0x4,
CAM_CPAS_VERSION_ID_200 = 0x5, CAM_CPAS_VERSION_ID_200 = 0x5,
CAM_CPAS_VERSION_ID_210 = 0x6,
CAM_CPAS_VERSION_ID_MAX CAM_CPAS_VERSION_ID_MAX
}; };
@ -166,8 +183,12 @@ enum cam_cpas_hw_version {
CAM_CPAS_TITAN_680_V110 = 0x680110, CAM_CPAS_TITAN_680_V110 = 0x680110,
CAM_CPAS_TITAN_780_V100 = 0x780100, CAM_CPAS_TITAN_780_V100 = 0x780100,
CAM_CPAS_TITAN_640_V200 = 0x640200, CAM_CPAS_TITAN_640_V200 = 0x640200,
CAM_CPAS_TITAN_640_V210 = 0x640210,
CAM_CPAS_TITAN_880_V100 = 0x880100, CAM_CPAS_TITAN_880_V100 = 0x880100,
CAM_CPAS_TITAN_980_V100 = 0x980100, 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 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.cmd = cmd;
flush_args.flush_active_req = false; 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) if (rc)
CAM_ERR(CAM_CRE, "Failed to flush device"); CAM_ERR(CAM_CRE, "Failed to flush device");

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2021, The Linux Foundation. All rights reserved. * 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> #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 */ /* Width for WE has to be updated in number of pixels */
if (acq_io_buf->direction == CAM_BUF_OUTPUT) { if (acq_io_buf->direction == CAM_BUF_OUTPUT) {
/* PLAIN 128/8 = 16 Bytes per pixel */ if (plane_info->format == CAM_FORMAT_PLAIN16_10) {
plane_info->width = plane_info->width =
io_cfg_ptr[j].planes[k].plane_stride/16; 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 { } else {
/* FE width should be in bytes */ /* FE width should be in bytes */
plane_info->width = 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; ctx_data->clk_info.axi_path[i].mnoc_ab_bw;
hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw -= hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw -=
ctx_data->clk_info.axi_path[i].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); 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; ctx_data->clk_info.axi_path[i].mnoc_ab_bw;
hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw -= hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw -=
ctx_data->clk_info.axi_path[i].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 = 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; ctx_data->clk_info.axi_path[i].mnoc_ab_bw;
hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw += hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw +=
ctx_data->clk_info.axi_path[i].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, CAM_DBG(CAM_CRE,
"Consolidate Path Vote : Dev[%s] i[%d] path_idx[%d] : [%s %s] [%lld %lld]", "Consolidate Path Vote : Dev[%s] i[%d] path_idx[%d] : [%s %s] [%lld %lld]",
ctx_data->cre_acquire.dev_name, 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; task_data = (struct cre_cmd_work_data *)data;
mutex_lock(&hw_mgr->hw_mgr_mutex); mutex_lock(&hw_mgr->hw_mgr_mutex);
mutex_lock(&ctx_data->ctx_mutex);
if (ctx_data->ctx_state != CRE_CTX_STATE_ACQUIRED) { 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", CAM_ERR(CAM_CRE, "ctx id :%u is not in use",
ctx_data->ctx_id); ctx_data->ctx_id);
return -EINVAL; rc = -EINVAL;
goto err;
} }
if (task_data->req_idx >= CAM_CTX_REQ_MAX) { if (task_data->req_idx >= CAM_CTX_REQ_MAX) {
mutex_unlock(&hw_mgr->hw_mgr_mutex);
CAM_ERR(CAM_CRE, "Invalid reqIdx = %llu", CAM_ERR(CAM_CRE, "Invalid reqIdx = %llu",
task_data->req_idx); task_data->req_idx);
return -EINVAL; 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]; cre_req = ctx_data->req_list[task_data->req_idx];
if (cre_req->request_id > ctx_data->last_flush_req) if (cre_req->request_id > ctx_data->last_flush_req)
ctx_data->last_flush_req = 0; 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)) { if (!cam_cre_is_pending_request(ctx_data)) {
CAM_WARN(CAM_CRE, "no pending req, req %lld last flush %lld", CAM_WARN(CAM_CRE, "no pending req, req %lld last flush %lld",
cre_req->request_id, ctx_data->last_flush_req); cre_req->request_id, ctx_data->last_flush_req);
mutex_unlock(&hw_mgr->hw_mgr_mutex); rc = -EINVAL;
return -EINVAL; goto err;
} }
hw_mgr = task_data->data; hw_mgr = task_data->data;
num_batch = cre_req->num_batch; 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, CAM_DBG(CAM_CRE,
"Going to configure cre for req %d, req_idx %d num_batch %d", "Ctx %d Going to configure cre for req %d, req_idx %d num_batch %d",
cre_req->request_id, cre_req->req_idx, num_batch); ctx_data->ctx_id, cre_req->request_id, cre_req->req_idx, num_batch);
for (i = 0; i < num_batch; i++) { for (i = 0; i < num_batch; i++) {
if (i != 0) { 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_cre_device_timer_reset(cre_hw_mgr);
CAM_ERR(CAM_CRE, CAM_ERR(CAM_CRE,
"Timedout waiting for bufdone on last frame"); "Timedout waiting for bufdone on last frame");
return -ETIMEDOUT; rc = -EINVAL;
goto err;
} else { } else {
reinit_completion(&ctx_data->cre_top->bufdone); reinit_completion(&ctx_data->cre_top->bufdone);
CAM_INFO(CAM_CRE, 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_mgr_update_reg_set(hw_mgr, cre_req, i);
cam_cre_ctx_wait_for_idle_irq(ctx_data); cam_cre_ctx_wait_for_idle_irq(ctx_data);
} }
err:
mutex_unlock(&ctx_data->ctx_mutex);
mutex_unlock(&hw_mgr->hw_mgr_mutex); mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc; 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) static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
{ {
struct cre_msg_work_data *task_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_ctx *ctx;
struct cam_cre_request *active_req; struct cam_cre_request *active_req;
struct cam_cre_irq_data irq_data; 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 evt_id;
uint32_t active_req_idx; uint32_t active_req_idx;
int rc = 0; int rc = 0;
@ -866,30 +855,51 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
task_data = data; task_data = data;
hw_mgr = priv; hw_mgr = priv;
ctx_id = cam_get_valid_ctx_id();
if (ctx_id < 0) { mutex_lock(&hw_mgr->hw_mgr_mutex);
CAM_ERR(CAM_CRE, "No valid context to handle error"); cfg_req = list_first_entry(&hw_mgr->hw_config_req_list,
return ctx_id; 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]; if (cfg_req->ctx_id < 0) {
CAM_ERR(CAM_CRE, "No valid context to handle error");
mutex_lock(&ctx->ctx_mutex); mutex_unlock(&hw_mgr->hw_mgr_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);
return -EINVAL; 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); 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); 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]; active_req = ctx->req_list[active_req_idx];
if (!active_req) if (!active_req) {
CAM_ERR(CAM_CRE, "Active req cannot be null"); CAM_ERR(CAM_CRE, "Active req cannot be null");
rc = -EINVAL;
goto end;
}
if (irq_data.error) { if (irq_data.error) {
evt_id = CAM_CTX_EVT_ID_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) { } else if (irq_data.wr_buf_done) {
/* Signal Buf done */ /* Signal Buf done */
active_req->frames_done++; active_req->frames_done++;
CAM_DBG(CAM_CRE, "Received frames_done %d num_batch %d req id %d", CAM_DBG(CAM_CRE, "Ctx %d Received frames_done %d num_batch %d req id %d",
active_req->frames_done, active_req->num_batch, ctx->ctx_id, active_req->frames_done, active_req->num_batch,
active_req->request_id); active_req->request_id);
complete(&ctx->cre_top->bufdone); complete(&ctx->cre_top->bufdone);
if (active_req->frames_done == active_req->num_batch) { if (active_req->frames_done == active_req->num_batch) {
ctx->last_done_req_idx = active_req_idx; ctx->last_done_req_idx = active_req_idx;
CAM_DBG(CAM_CRE, "signaling buff done for req %d", CAM_DBG(CAM_CRE, "Ctx %d signaling buff done for req %d",
active_req->request_id); ctx->ctx_id, active_req->request_id);
evt_id = CAM_CTX_EVT_ID_SUCCESS; evt_id = CAM_CTX_EVT_ID_SUCCESS;
buf_data.evt_param = CAM_SYNC_COMMON_EVENT_SUCCESS; buf_data.evt_param = CAM_SYNC_COMMON_EVENT_SUCCESS;
buf_data.request_id = active_req->request_id; 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; 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(&ctx->ctx_mutex);
mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc; return rc;
} }
@ -1550,6 +1563,12 @@ static int cam_cre_validate_acquire_res_info(
cre_acquire->in_res[i].format); cre_acquire->in_res[i].format);
return -EINVAL; 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++) { 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].camnoc_bw = 0;
hw_mgr->clk_info.axi_path[i].mnoc_ab_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].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].camnoc_bw = 600000000;
bw_update->axi_vote.axi_path[0].mnoc_ab_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].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 = bw_update->axi_vote.axi_path[0].transac_type =
CAM_AXI_TRANSACTION_WRITE; CAM_AXI_TRANSACTION_WRITE;
bw_update->axi_vote.axi_path[0].path_data_type = 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); mutex_lock(&hw_mgr->hw_mgr_mutex);
rc = cam_cre_mgr_release_ctx(hw_mgr, ctx_id); rc = cam_cre_mgr_release_ctx(hw_mgr, ctx_id);
if (!hw_mgr->cre_ctx_cnt) { 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++) { for (i = 0; i < cre_hw_mgr->num_cre; i++) {
dev_intf = hw_mgr->cre_dev_intf[i]; dev_intf = hw_mgr->cre_dev_intf[i];
irq_cb.cre_hw_mgr_cb = NULL; 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 = &ctx_data->req_list[index]->clk_info;
clk_info_v2 = &ctx_data->req_list[index]->clk_info_v2; clk_info_v2 = &ctx_data->req_list[index]->clk_info_v2;
clk_info_v2.budget_ns = soc_req->budget_ns; clk_info_v2->budget_ns = soc_req->budget_ns;
clk_info_v2.frame_cycles = soc_req->frame_cycles; clk_info_v2->frame_cycles = soc_req->frame_cycles;
clk_info_v2.rt_flag = soc_req->rt_flag; clk_info_v2->rt_flag = soc_req->rt_flag;
clk_info_v2.num_paths = soc_req->num_paths; clk_info_v2->num_paths = soc_req->num_paths;
for (i = 0; i < soc_req->num_paths; i++) { 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].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].transac_type = soc_req->axi_path[i].transac_type;
clk_info_v2.axi_path[i].path_data_type = clk_info_v2->axi_path[i].path_data_type =
soc_req->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].vote_level = 0;
clk_info_v2.axi_path[i].camnoc_bw = soc_req->axi_path[i].camnoc_bw; 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_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].mnoc_ib_bw = soc_req->axi_path[i].mnoc_ib_bw;
} }
/* Use v1 structure for clk fields */ /* 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->num_hw_update_entries = 1;
prepare_args->priv = ctx_data->req_list[request_idx]; prepare_args->priv = ctx_data->req_list[request_idx];
cre_req->hang_data.packet = packet;
ktime_get_boottime_ts64(&ts); ktime_get_boottime_ts64(&ts);
ctx_data->last_req_time = (uint64_t)((ts.tv_sec * 1000000000) + ctx_data->last_req_time = (uint64_t)((ts.tv_sec * 1000000000) +
ts.tv_nsec); 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; request_id = config_args->request_id;
hw_update_entries = config_args->hw_update_entries; 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); task = cam_req_mgr_workq_get_task(cre_hw_mgr->cmd_work);
if (!task) { 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 = (struct cre_cmd_work_data *)task->payload;
task_data->data = (void *)hw_mgr; task_data->data = (void *)hw_mgr;
task_data->req_idx = cre_req->req_idx; 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_data->type = CRE_WORKQ_TASK_CMD_TYPE;
task->process_cb = cam_cre_mgr_process_cmd; 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_hw_config_args *config_args = hw_config_args;
struct cam_cre_ctx *ctx_data = NULL; struct cam_cre_ctx *ctx_data = NULL;
struct cam_cre_request *cre_req = 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) { if (!hw_mgr || !config_args) {
CAM_ERR(CAM_CRE, "Invalid arguments %pK %pK", CAM_ERR(CAM_CRE, "Invalid arguments %pK %pK",
hw_mgr, config_args); 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(&hw_mgr->hw_mgr_mutex);
mutex_lock(&ctx_data->ctx_mutex); mutex_lock(&ctx_data->ctx_mutex);
if (ctx_data->ctx_state != CRE_CTX_STATE_ACQUIRED) { 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", CAM_ERR(CAM_CRE, "ctx id :%u is not in use",
ctx_data->ctx_id); 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; cre_req = config_args->priv;
cam_cre_mgr_cre_clk_update(hw_mgr, ctx_data, cre_req->req_idx); 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(); 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, CAM_WARN(CAM_CRE,
"Anomaly submitting flushed req %llu [last_flush %llu] in ctx %u", "Anomaly submitting flushed req %llu [last_flush %llu] in ctx %u",
cre_req->request_id, ctx_data->last_flush_req, cre_req->request_id, ctx_data->last_flush_req,
ctx_data->ctx_id); 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); rc = cam_cre_mgr_enqueue_config(hw_mgr, ctx_data, config_args);
if (rc) if (rc)
@ -2409,6 +2444,7 @@ static int cam_cre_mgr_config_hw(void *hw_priv, void *hw_config_args)
return rc; return rc;
config_err: config_err:
cam_cre_mgr_handle_config_err(config_args, ctx_data); cam_cre_mgr_handle_config_err(config_args, ctx_data);
end:
mutex_unlock(&ctx_data->ctx_mutex); mutex_unlock(&ctx_data->ctx_mutex);
mutex_unlock(&hw_mgr->hw_mgr_mutex); mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc; return rc;
@ -2417,6 +2453,7 @@ config_err:
static void cam_cre_mgr_dump_pf_data(struct cam_cre_hw_mgr *hw_mgr, static void cam_cre_mgr_dump_pf_data(struct cam_cre_hw_mgr *hw_mgr,
struct cam_hw_cmd_pf_args *pf_cmd_args) struct cam_hw_cmd_pf_args *pf_cmd_args)
{ {
int rc = 0;
struct cam_packet *packet; struct cam_packet *packet;
struct cam_hw_dump_pf_args *pf_args; struct cam_hw_dump_pf_args *pf_args;
size_t len; size_t len;
@ -2970,6 +3007,14 @@ int cam_cre_hw_mgr_init(struct device_node *of_node, void *hw_mgr,
if (rc) if (rc)
goto cre_wq_create_failed; 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(); cam_cre_create_debug_fs();
if (iommu_hdl) if (iommu_hdl)

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2021, The Linux Foundation. All rights reserved. * 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 #ifndef CAM_CRE_HW_MGR_H
@ -146,14 +146,16 @@ struct cam_cre_clk_info {
/** /**
* struct cre_cmd_work_data * struct cre_cmd_work_data
* *
* @type: Type of work data * @type: Type of work data
* @data: Private data * @data: Private data
* @req_id: Request Idx * @req_idx: Request Idx
* @request_id: Request id
*/ */
struct cre_cmd_work_data { struct cre_cmd_work_data {
uint32_t type; uint32_t type;
void *data; void *data;
int64_t req_idx; int64_t req_idx;
uint64_t request_id;
}; };
/** /**
@ -341,6 +343,20 @@ struct cam_cre_ctx {
cam_hw_event_cb_func ctxt_event_cb; 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 * struct cam_cre_hw_mgr
* *
@ -367,6 +383,9 @@ struct cam_cre_ctx {
* @clk_info: CRE clock Info for HW manager * @clk_info: CRE clock Info for HW manager
* @dentry: Pointer to CRE debugfs directory * @dentry: Pointer to CRE debugfs directory
* @dump_req_data_enable: CRE hang dump enablement * @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 { struct cam_cre_hw_mgr {
uint32_t cre_ctx_cnt; uint32_t cre_ctx_cnt;
@ -395,6 +414,10 @@ struct cam_cre_hw_mgr {
struct cam_cre_clk_info clk_info; struct cam_cre_clk_info clk_info;
struct dentry *dentry; struct dentry *dentry;
bool dump_req_data_enable; 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 // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2021, The Linux Foundation. All rights reserved. * 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 <linux/delay.h>
#include "cam_hw.h" #include "cam_hw.h"
#include "cam_hw_intf.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); p_info.alignment);
/* Fetch engine width has to be updated in number of bytes */ /* 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->stride = p_info.stride;
rd_client_reg_val->img_height = p_info.height; rd_client_reg_val->img_height = p_info.height;
rd_client_reg_val->alignment = p_info.alignment; 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 = in_port_idx =
cam_cre_bus_rd_in_port_idx(io_buf->resource_type); 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); CAM_DBG(CAM_CRE, "in_port_idx %d", in_port_idx);
for (k = 0; k < io_buf->num_planes; k++) { 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 */ /* Buffer size */
update_cre_reg_set(cre_reg_buf, update_cre_reg_set(cre_reg_buf,
rd_reg->offset + rd_reg_client->rd_width, 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, update_cre_reg_set(cre_reg_buf,
rd_reg->offset + rd_reg_client->rd_height, rd_reg->offset + rd_reg_client->rd_height,
rd_client_reg_val->img_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 cre_io_buf *io_buf;
struct cam_cre_bus_rd_reg *rd_reg; struct cam_cre_bus_rd_reg *rd_reg;
struct cam_cre_bus_rd_reg_val *rd_reg_val; 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; 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, rd_reg->offset + rd_reg->input_if_cmd,
val); val);
} }
if (cre_reg_buf) {
for (i = 0; i < cre_reg_buf->num_rd_reg_set; i++) { for (i = 0; i < cre_reg_buf->num_rd_reg_set; i++) {
CAM_DBG(CAM_CRE, "CRE value 0x%x offset 0x%x", 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].value,
cre_reg_buf->rd_reg_set[i].offset); cre_reg_buf->rd_reg_set[i].offset);
}
} }
end: end:
return 0; 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) int32_t ctx_id, void *data)
{ {
uint32_t irq_status; 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_0;
uint32_t debug_status_1; uint32_t debug_status_1;
struct cam_cre_bus_rd_reg *bus_rd_reg; 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, cam_io_w_mb(bus_rd_reg_val->irq_cmd_clear,
bus_rd_reg->base + bus_rd_reg->irq_cmd); 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) if (irq_status & bus_rd_reg_val->rup_done)
CAM_DBG(CAM_CRE, "CRE Read Bus RUP done"); CAM_DBG(CAM_CRE, "CRE Read Bus RUP done");
if (irq_status & bus_rd_reg_val->rd_buf_done) if (irq_status & bus_rd_reg_val->rd_buf_done)
CAM_DBG(CAM_CRE, "CRE Read Bus Buff 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; irq_data->error = 1;
violation_status = cam_io_r_mb(bus_rd_reg->base + const_violation_status = cam_io_r_mb(bus_rd_reg->base +
bus_rd_reg->rd_clients[0].cons_violation_status); 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 + debug_status_0 = cam_io_r_mb(bus_rd_reg->base +
bus_rd_reg->rd_clients[0].debug_status_0); bus_rd_reg->rd_clients[0].debug_status_0);
debug_status_1 = cam_io_r_mb(bus_rd_reg->base + debug_status_1 = cam_io_r_mb(bus_rd_reg->base +
bus_rd_reg->rd_clients[0].debug_status_1); bus_rd_reg->rd_clients[0].debug_status_1);
CAM_DBG(CAM_CRE, "CRE Read Bus Violation"); CAM_DBG(CAM_CRE, "CRE Read Bus Violation");
CAM_DBG(CAM_CRE, CAM_DBG(CAM_CRE,
"violation status 0x%x debug status 0/1 0x%x/0x%x", "violation status 0x%x 0x%x debug status 0/1 0x%x/0x%x",
violation_status, debug_status_0, debug_status_1); const_violation_status, ccif_violation_status,
debug_status_0, debug_status_1);
} }
return 0; return 0;

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2021, The Linux Foundation. All rights reserved. * 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 <linux/delay.h>
#include "cam_io_util.h" #include "cam_io_util.h"
@ -22,6 +23,70 @@ static struct cre_bus_wr *wr_info;
cre_reg_buf->num_wr_reg_set++; \ cre_reg_buf->num_wr_reg_set++; \
} while (0) } 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, static int cam_cre_translate_write_format(struct plane_info p_info,
struct cam_cre_bus_wr_client_reg_val *wr_client_reg_val) 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->height = p_info.height;
wr_client_reg_val->alignment = p_info.alignment; wr_client_reg_val->alignment = p_info.alignment;
/* wr_client_reg_val->format = p_info.format;
* 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;
return 0; 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; int rc, k, out_port_idx;
uint32_t req_idx; uint32_t req_idx;
uint32_t val = 0; uint32_t val = 0;
uint32_t format_idx = 0;
uint32_t iova_base, iova_offset; uint32_t iova_base, iova_offset;
struct cam_hw_prepare_update_args *prepare_args; struct cam_hw_prepare_update_args *prepare_args;
struct cam_cre_ctx *ctx_data; 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); wr_client_reg_val->stride);
val = 0; val = 0;
val |= ((wr_client_reg_val->format & format_idx = cam_cre_bus_wr_format_idx(wr_client_reg_val->format);
wr_client_reg_val->format_mask) << val |= ((format_idx & wr_client_reg_val->format_mask) <<
wr_client_reg_val->format_shift); wr_client_reg_val->format_shift);
val |= ((wr_client_reg_val->alignment &
wr_client_reg_val->alignment_mask) << /* Update alignment as LSB by default*/
wr_client_reg_val->alignment_shift); val |= (0x1 << wr_client_reg_val->alignment_shift);
/* pack cfg : Format and alignment */ /* pack cfg : Format and alignment */
update_cre_reg_set(cre_reg_buf, update_cre_reg_set(cre_reg_buf,
wr_reg->offset + wr_reg_client->packer_cfg, 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; CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote->axi_vote.axi_path[0].mnoc_ib_bw = cpas_vote->axi_vote.axi_path[0].mnoc_ib_bw =
CAM_CPAS_DEFAULT_AXI_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, rc = cam_cpas_start(core_info->cpas_handle,
&cpas_vote->ahb_vote, &cpas_vote->axi_vote); &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); CAM_ERR(CAM_CRE, "soc disable is failed : %d", rc);
core_info->clk_enable = false; 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; return rc;
} }

View File

@ -18,6 +18,7 @@
#include "cam_cpas_api.h" #include "cam_cpas_api.h"
#include "cam_debug_util.h" #include "cam_debug_util.h"
#include "cre_hw_100.h" #include "cre_hw_100.h"
#include "cre_hw_110.h"
#include "cre_dev_intf.h" #include "cre_dev_intf.h"
#include "cam_smmu_api.h" #include "cam_smmu_api.h"
#include "camera_main.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) { switch (core_info->hw_version) {
case CRE_HW_VER_1_0_0: case CRE_HW_VER_1_0_0:
core_info->cre_hw_info->cre_hw = &cre_hw_100; 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; break;
default: default:
CAM_ERR(CAM_CRE, "Unsupported version : %u", 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; 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; return rc;
} }
@ -200,10 +209,6 @@ static int cam_cre_component_bind(struct device *dev,
CAM_CPAS_DEFAULT_AXI_BW; CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote.axi_vote.axi_path[0].mnoc_ib_bw = cpas_vote.axi_vote.axi_path[0].mnoc_ib_bw =
CAM_CPAS_DEFAULT_AXI_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, rc = cam_cpas_start(core_info->cpas_handle,
&cpas_vote.ahb_vote, &cpas_vote.axi_vote); &cpas_vote.ahb_vote, &cpas_vote.axi_vote);

View File

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

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2021, The Linux Foundation. All rights reserved. * 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 #ifndef CAM_CRE_HW_100_H
@ -11,7 +12,7 @@
#define CRE_BUS_RD_TYPE 0x1 #define CRE_BUS_RD_TYPE 0x1
#define CRE_BUS_WR_TYPE 0x2 #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_version = 0x000,
.hw_cap = 0x004, .hw_cap = 0x004,
.debug_0 = 0x080, .debug_0 = 0x080,
@ -30,7 +31,7 @@ static struct cam_cre_top_reg top_reg = {
.top_spare = 0x1FC, .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_version = 0x10000000,
.hw_cap = 0x4000, .hw_cap = 0x4000,
.irq_mask = 0xf, .irq_mask = 0xf,
@ -46,7 +47,7 @@ struct cam_cre_top_reg_val top_reg_value = {
.hw_reset_cmd = 0x1, .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, .hw_version = 0x00,
.irq_mask = 0x04, .irq_mask = 0x04,
.irq_clear = 0x08, .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, .hw_version = 0x30000000,
.cgc_override = 0x1, .cgc_override = 0x1,
.irq_mask_0 = 0xd0000101, .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, .hw_version = 0x30000000,
.irq_mask = 0x1, /* INFO_CONS_VIOLATION */ .irq_mask = 0x1, /* INFO_CONS_VIOLATION */
.rd_buf_done = 0x4, .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, .hw_version = 0x00,
.cgc_override = 0x08, .cgc_override = 0x08,
.irq_mask_0 = 0x18, .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 = { static struct cam_cre_hw cre_hw_100 = {
.top_reg_offset = &top_reg, .top_reg_offset = &cre100_top_reg,
.top_reg_val = &top_reg_value, .top_reg_val = &cre100_top_reg_value,
.bus_wr_reg_offset = &bus_wr_reg, .bus_wr_reg_offset = &cre100_bus_wr_reg,
.bus_wr_reg_val = &bus_wr_reg_value, .bus_wr_reg_val = &cre100_bus_wr_reg_value,
.bus_rd_reg_offset = &bus_rd_reg, .bus_rd_reg_offset = &cre100_bus_rd_reg,
.bus_rd_reg_val = &bus_rd_reg_value, .bus_rd_reg_val = &cre100_bus_rd_reg_value,
}; };
#endif // CAM_CRE_HW_100_H #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 // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2021, The Linux Foundation. All rights reserved. * 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/platform_device.h>
#include <linux/delay.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, cam_io_w_mb(top_reg_val->irq_mask,
cre_hw_info->top_reg_offset->base + top_reg->irq_mask); cre_hw_info->top_reg_offset->base + top_reg->irq_mask);
/* CRE SW RESET */ /* CRE HW RESET */
cam_io_w_mb(top_reg_val->sw_reset_cmd, cam_io_w_mb(top_reg_val->hw_reset_cmd,
cre_hw_info->top_reg_offset->base + top_reg->reset_cmd); cre_hw_info->top_reg_offset->base + top_reg->reset_cmd);
rc = wait_for_completion_timeout( rc = wait_for_completion_timeout(

View File

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

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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" #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)-> ((struct cam_fd_soc_private *)soc_info->soc_private)->
regbase_index[CAM_FD_REG_CORE]); 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); ctx_hw_private->cdm_ops->cdm_write_changebase(cmd_buf_addr, mem_base);
cmd_buf_addr += size; cmd_buf_addr += size;
available_size -= (size * 4); available_size -= (size * 4);

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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> #include <linux/delay.h>
@ -249,10 +249,12 @@ const struct v4l2_subdev_internal_ops cam_icp_subdev_internal_ops = {
.close = cam_icp_subdev_close, .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]); kfree(g_icp_dev[device_idx]);
g_icp_dev[device_idx] = NULL; g_icp_dev[device_idx] = NULL;
return 0;
} }
static int cam_icp_component_bind(struct device *dev, static int cam_icp_component_bind(struct device *dev,
@ -292,6 +294,7 @@ static int cam_icp_component_bind(struct device *dev,
else else
subdev_name = cam_icp_subdev_name_arr[device_idx]; subdev_name = cam_icp_subdev_name_arr[device_idx];
mutex_lock(&g_dev_lock); mutex_lock(&g_dev_lock);
if (g_icp_dev[device_idx]) { if (g_icp_dev[device_idx]) {
CAM_ERR(CAM_ICP, CAM_ERR(CAM_ICP,
@ -303,15 +306,15 @@ static int cam_icp_component_bind(struct device *dev,
} }
mutex_unlock(&g_dev_lock); mutex_unlock(&g_dev_lock);
icp_dev = kzalloc(sizeof(struct cam_icp_subdev), GFP_KERNEL); icp_dev = kzalloc(sizeof(struct cam_icp_subdev), GFP_KERNEL);
if (!icp_dev) { if (!icp_dev) {
CAM_ERR(CAM_ICP, CAM_ERR(CAM_ICP,
"Unable to allocate memory for icp device:%s size:%llu", "Unable to allocate memory for icp device:%s size:%llu",
pdev->name, sizeof(struct cam_icp_subdev)); pdev->name, sizeof(struct cam_icp_subdev));
return -ENOMEM; return -ENOMEM;
} }
mutex_lock(&g_dev_lock); mutex_lock(&g_dev_lock);
g_icp_dev[device_idx] = icp_dev; g_icp_dev[device_idx] = icp_dev;
mutex_unlock(&g_dev_lock); mutex_unlock(&g_dev_lock);
@ -371,6 +374,7 @@ ctx_fail:
cam_icp_context_deinit(&icp_dev->ctx_icp[i]); cam_icp_context_deinit(&icp_dev->ctx_icp[i]);
cam_icp_hw_mgr_deinit(device_idx); cam_icp_hw_mgr_deinit(device_idx);
hw_init_fail: hw_init_fail:
cam_node_deinit(icp_dev->node);
cam_subdev_remove(&icp_dev->sd); cam_subdev_remove(&icp_dev->sd);
probe_fail: probe_fail:
cam_icp_subdev_clean_up(device_idx); 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) 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); idx = HFI_GET_INDEX(client_handle);
if (!IS_VALID_HFI_INDEX(idx)) { 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; struct hfi_q_hdr *q;
uint32_t new_read_idx, size_in_words, word_diff, temp; uint32_t new_read_idx, size_in_words, word_diff, temp;
uint32_t *read_q, *read_ptr, *write_ptr; uint32_t *read_q, *read_ptr, *write_ptr;
uint32_t size_upper_bound = 0;
struct mutex *q_lock; struct mutex *q_lock;
int rc = 0; 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_tbl_ptr = (struct hfi_qtbl *)hfi->map.qtbl.kva;
q = &q_tbl_ptr->q_hdr[q_id]; 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) if (q_id == Q_MSG)
read_q = (uint32_t *)hfi->map.msg_q.kva; read_q = (uint32_t *)hfi->map.msg_q.kva;
else 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); read_ptr = (uint32_t *)(read_q + q->qhdr_read_idx);
write_ptr = (uint32_t *)(read_q + q->qhdr_write_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; size_in_words = write_ptr - read_ptr;
else { else {
word_diff = read_ptr - write_ptr; word_diff = read_ptr - write_ptr;
size_in_words = q->qhdr_q_size - word_diff; size_in_words = q->qhdr_q_size - word_diff;
} }
if (size_in_words == 0) { if ((size_in_words == 0) ||
CAM_DBG(CAM_HFI, "[%s] hfi hdl: %d Q is empty, state:%u, r idx:%u, w idx:%u", (size_in_words > size_upper_bound)) {
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) {
CAM_ERR(CAM_HFI, "[%s] Invalid HFI message packet size - 0x%08x hfi hdl:%d", CAM_ERR(CAM_HFI, "[%s] Invalid HFI message packet size - 0x%08x hfi hdl:%d",
hfi->client_name, size_in_words << BYTE_WORD_SHIFT, hfi->client_name, size_in_words << BYTE_WORD_SHIFT,
client_handle); client_handle);
@ -381,9 +386,13 @@ int hfi_read_message(int client_handle, uint32_t *pmsg, uint8_t q_id,
goto err; goto err;
} }
/* size to read from q is bounded by size of buffer */ if (size_in_words > buf_words_size) {
if (size_in_words > buf_words_size) CAM_ERR(CAM_HFI,
size_in_words = buf_words_size; "[%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; new_read_idx = q->qhdr_read_idx + size_in_words;

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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> #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: case CAM_ICP_DEV_CMD_RESET:
rc = cam_bps_cmd_reset(soc_info, core_info); rc = cam_bps_cmd_reset(soc_info, core_info);
break; break;
case CAM_ICP_DEV_CMD_DUMP_CLK: {
rc = cam_soc_util_dump_clk(soc_info);
break;
}
default: default:
CAM_ERR(CAM_ICP, "Invalid Cmd Type:%u", cmd_type); CAM_ERR(CAM_ICP, "Invalid Cmd Type:%u", cmd_type);
rc = -EINVAL; rc = -EINVAL;

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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> #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); CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name);
bps_dev_intf = platform_get_drvdata(pdev); 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; bps_dev = bps_dev_intf->hw_priv;
core_info = (struct cam_bps_device_core_info *)bps_dev->core_info; core_info = (struct cam_bps_device_core_info *)bps_dev->core_info;
cam_cpas_unregister_client(core_info->cpas_handle); cam_cpas_unregister_client(core_info->cpas_handle);

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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> #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)); (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) static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
{ {
int i; int i, rc;
uint32_t idx, event_id; uint32_t idx, event_id;
uint64_t request_id; uint64_t request_id;
struct cam_icp_hw_mgr *hw_mgr = NULL; 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), cam_icp_error_handle_id_to_type(ioconfig_ack->err_type),
request_id); request_id);
event_id = CAM_CTX_EVT_ID_ERROR; 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); buf_data.evt_param = cam_icp_handle_err_type_to_evt_param(ioconfig_ack->err_type);
} else { } 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) { if (ioconfig_ack->err_type != CAMERAICP_SUCCESS) {
cam_icp_mgr_handle_frame_process(msg_ptr, cam_icp_mgr_handle_frame_process(msg_ptr,
ICP_FRAME_PROCESS_FAILURE); ICP_FRAME_PROCESS_FAILURE);
if (ioconfig_ack->err_type == CAMERAICP_EABORTED)
return 0;
return -EIO; 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) static void cam_icp_mgr_process_dbg_buf(struct cam_icp_hw_mgr *hw_mgr)
{ {
uint32_t *msg_ptr = NULL, *pkt_ptr = NULL; uint32_t *msg_ptr = NULL, *pkt_ptr = NULL;
struct hfi_msg_debug *dbg_msg = NULL; struct hfi_msg_debug *dbg_msg;
uint32_t read_in_words, remain_len, pre_remain_len = 0; uint32_t read_len, size_processed = 0, debug_lvl;
uint32_t buf_word_size = ICP_DBG_BUF_SIZE_IN_WORDS;
uint64_t timestamp = 0; uint64_t timestamp = 0;
char *msg_data; char *dbg_buf;
int rc = 0; int rc = 0;
if (!hw_mgr) { rc = hfi_read_message(hw_mgr->hfi_handle, hw_mgr->dbg_buf, Q_DBG,
CAM_ERR(CAM_ICP, "Invalid data"); ICP_DBG_BUF_SIZE_IN_WORDS, &read_len);
if (rc)
return; return;
}
do { msg_ptr = (uint32_t *)hw_mgr->dbg_buf;
rc = hfi_read_message(hw_mgr->hfi_handle, debug_lvl = hw_mgr->icp_dbg_lvl;
hw_mgr->dbg_buf + (pre_remain_len >> BYTE_WORD_SHIFT), while (true) {
Q_DBG, buf_word_size, &read_in_words); pkt_ptr = msg_ptr;
if (rc) if (pkt_ptr[ICP_PACKET_TYPE] == HFI_MSG_SYS_DEBUG) {
break; dbg_msg = (struct hfi_msg_debug *)pkt_ptr;
dbg_buf = (char *)&dbg_msg->msg_data;
remain_len = pre_remain_len + (read_in_words << BYTE_WORD_SHIFT); timestamp = ((((uint64_t)(dbg_msg->timestamp_hi) << 32)
pre_remain_len = 0; | dbg_msg->timestamp_lo) >> 16);
msg_ptr = (uint32_t *)hw_mgr->dbg_buf; trace_cam_icp_fw_dbg(dbg_buf, timestamp/2,
buf_word_size = ICP_DBG_BUF_SIZE_IN_WORDS; hw_mgr->hw_mgr_name);
if (!debug_lvl)
while (remain_len) { CAM_INFO(CAM_ICP, "[%s]: FW_DBG:%s",
pkt_ptr = msg_ptr; hw_mgr->hw_mgr_name, dbg_buf);
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;
} }
size_processed += (pkt_ptr[ICP_PACKET_SIZE] >>
/* Repeat reading if drain buffer is insufficient to read all MSGs at once */ BYTE_WORD_SHIFT);
} while (read_in_words >= buf_word_size); if (size_processed >= read_len)
return;
msg_ptr += (pkt_ptr[ICP_PACKET_SIZE] >>
BYTE_WORD_SHIFT);
}
} }
static int cam_icp_process_msg_pkt_type( static int cam_icp_process_msg_pkt_type(
struct cam_icp_hw_mgr *hw_mgr, struct cam_icp_hw_mgr *hw_mgr,
uint32_t *msg_ptr) uint32_t *msg_ptr,
uint32_t *msg_processed_len)
{ {
int rc = 0; int rc = 0;
int size_processed = 0;
switch (msg_ptr[ICP_PACKET_TYPE]) { switch (msg_ptr[ICP_PACKET_TYPE]) {
case HFI_MSG_SYS_INIT_DONE: case HFI_MSG_SYS_INIT_DONE:
CAM_DBG(CAM_ICP, "[%s] received SYS_INIT_DONE", hw_mgr->hw_mgr_name); CAM_DBG(CAM_ICP, "[%s] received SYS_INIT_DONE", hw_mgr->hw_mgr_name);
complete(&hw_mgr->icp_complete); complete(&hw_mgr->icp_complete);
size_processed = (
(struct hfi_msg_init_done *)msg_ptr)->size;
break; break;
case HFI_MSG_SYS_PC_PREP_DONE: case HFI_MSG_SYS_PC_PREP_DONE:
CAM_DBG(CAM_ICP, "[%s] HFI_MSG_SYS_PC_PREP_DONE is received\n", CAM_DBG(CAM_ICP, "[%s] HFI_MSG_SYS_PC_PREP_DONE is received\n",
hw_mgr->hw_mgr_name); hw_mgr->hw_mgr_name);
complete(&hw_mgr->icp_complete); complete(&hw_mgr->icp_complete);
size_processed = sizeof(struct hfi_msg_pc_prep_done);
break; break;
case HFI_MSG_SYS_PING_ACK: case HFI_MSG_SYS_PING_ACK:
CAM_DBG(CAM_ICP, "[%s] received SYS_PING_ACK", hw_mgr->hw_mgr_name); CAM_DBG(CAM_ICP, "[%s] received SYS_PING_ACK", hw_mgr->hw_mgr_name);
rc = cam_icp_mgr_process_msg_ping_ack(msg_ptr); rc = cam_icp_mgr_process_msg_ping_ack(msg_ptr);
size_processed = sizeof(struct hfi_msg_ping_ack);
break; break;
case HFI_MSG_IPEBPS_CREATE_HANDLE_ACK: 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", CAM_DBG(CAM_ICP, "[%s] received IPE/BPS/OFE CREATE_HANDLE_ACK",
hw_mgr->hw_mgr_name); hw_mgr->hw_mgr_name);
rc = cam_icp_mgr_process_msg_create_handle(msg_ptr); rc = cam_icp_mgr_process_msg_create_handle(msg_ptr);
size_processed = sizeof(struct hfi_msg_create_handle_ack);
break; break;
case HFI_MSG_IPEBPS_ASYNC_COMMAND_INDIRECT_ACK: case HFI_MSG_IPEBPS_ASYNC_COMMAND_INDIRECT_ACK:
CAM_DBG(CAM_ICP, "[%s] received IPE/BPS ASYNC_INDIRECT_ACK", CAM_DBG(CAM_ICP, "[%s] received IPE/BPS ASYNC_INDIRECT_ACK",
hw_mgr->hw_mgr_name); hw_mgr->hw_mgr_name);
rc = cam_icp_mgr_process_ipebps_indirect_ack_msg(msg_ptr); rc = cam_icp_mgr_process_ipebps_indirect_ack_msg(msg_ptr);
size_processed = (
(struct hfi_msg_dev_async_ack *)msg_ptr)->size;
break; break;
case HFI_MSG_OFE_ASYNC_COMMAND_ACK: case HFI_MSG_OFE_ASYNC_COMMAND_ACK:
CAM_DBG(CAM_ICP, "[%s] received OFE ASYNC COMMAND ACK", CAM_DBG(CAM_ICP, "[%s] received OFE ASYNC COMMAND ACK",
hw_mgr->hw_mgr_name); hw_mgr->hw_mgr_name);
rc = cam_icp_mgr_process_ofe_indirect_ack_msg(msg_ptr); rc = cam_icp_mgr_process_ofe_indirect_ack_msg(msg_ptr);
size_processed = (
(struct hfi_msg_dev_async_ack *)msg_ptr)->size;
break; break;
case HFI_MSG_IPEBPS_ASYNC_COMMAND_DIRECT_ACK: case HFI_MSG_IPEBPS_ASYNC_COMMAND_DIRECT_ACK:
CAM_DBG(CAM_ICP, "[%s] received ASYNC_DIRECT_ACK", hw_mgr->hw_mgr_name); CAM_DBG(CAM_ICP, "[%s] received ASYNC_DIRECT_ACK", hw_mgr->hw_mgr_name);
rc = cam_icp_mgr_process_direct_ack_msg(msg_ptr); rc = cam_icp_mgr_process_direct_ack_msg(msg_ptr);
size_processed = (
(struct hfi_msg_dev_async_ack *)msg_ptr)->size;
break; break;
case HFI_MSG_EVENT_NOTIFY: case HFI_MSG_EVENT_NOTIFY:
CAM_DBG(CAM_ICP, "[%s] received EVENT_NOTIFY", hw_mgr->hw_mgr_name); 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); rc = cam_icp_mgr_process_fatal_error(hw_mgr, msg_ptr);
if (rc) if (rc)
CAM_ERR(CAM_ICP, "[%s] failed in processing evt notify", 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: case HFI_MSG_DBG_SYNX_TEST:
CAM_DBG(CAM_ICP, "received 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); complete(&hw_mgr->icp_complete);
break; break;
default: default:
CAM_ERR(CAM_ICP, "[%s] invalid msg : %u", CAM_ERR(CAM_ICP, "[%s] invalid msg : %u",
hw_mgr->hw_mgr_name, msg_ptr[ICP_PACKET_TYPE]); hw_mgr->hw_mgr_name, msg_ptr[ICP_PACKET_TYPE]);
rc = -EINVAL; rc = -EINVAL;
} }
*msg_processed_len = size_processed;
return rc; return rc;
} }
static int cam_icp_get_msg_pkt_size( static int32_t cam_icp_mgr_process_msg(void *priv, void *data)
struct cam_icp_hw_mgr *hw_mgr,
uint32_t *msg_ptr,
uint32_t *pkt_size)
{ {
switch (msg_ptr[ICP_PACKET_TYPE]) { uint32_t read_len, msg_processed_len;
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 *msg_ptr = NULL; uint32_t *msg_ptr = NULL;
uint32_t buf_word_size = ICP_MSG_BUF_SIZE_IN_WORDS; struct hfi_msg_work_data *task_data;
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 cam_icp_hw_mgr *hw_mgr; struct cam_icp_hw_mgr *hw_mgr;
int rc = 0; int rc = 0;
@ -3210,9 +3106,33 @@ static int32_t cam_icp_mgr_process_cb(void *priv, void *data)
task_data = data; task_data = data;
hw_mgr = priv; hw_mgr = priv;
rc = cam_icp_mgr_process_msg(hw_mgr); rc = hfi_read_message(hw_mgr->hfi_handle, hw_mgr->msg_buf, Q_MSG,
if (rc && (rc != -ENOMSG)) ICP_MSG_BUF_SIZE_IN_WORDS, &read_len);
CAM_ERR(CAM_ICP, "Failed to process MSG"); 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); 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->data = hw_mgr;
task_data->recover = recover; task_data->recover = recover;
task_data->type = ICP_WORKQ_TASK_MSG_TYPE; 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, rc = cam_req_mgr_workq_enqueue_task(task, hw_mgr,
CRM_TASK_PRIORITY_0); CRM_TASK_PRIORITY_0);
spin_unlock_irqrestore(&hw_mgr->hw_mgr_lock, flags); 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: hw_dev_deinit:
for (; i >= 0; i--) { for (; i >= 0; i--) {
dev_info = &hw_mgr->dev_info[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--) { for (; j >= 0; j--) {
dev_intf = dev_info->dev_intf[j]; dev_intf = dev_info->dev_intf[j];
dev_intf->hw_ops.deinit(dev_intf->hw_priv, NULL, 0); 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); packet->io_configs_offset/4);
for (i = 0 ; i < packet->num_io_configs; i++) 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++; num_out_map_entries++;
if (num_out_map_entries <= CAM_MAX_OUT_RES) { 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) { if (io_cfg_ptr[i].direction == CAM_BUF_INPUT) {
sync_in_obj[j++] = io_cfg_ptr[i].fence; sync_in_obj[j++] = io_cfg_ptr[i].fence;
prepare_args->num_in_map_entries++; 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 = prepare_args->out_map_entries[k].sync_id =
io_cfg_ptr[i].fence; io_cfg_ptr[i].fence;
prepare_args->out_map_entries[k].resource_handle = prepare_args->out_map_entries[k].resource_handle =
io_cfg_ptr[i].resource_type; io_cfg_ptr[i].resource_type;
k++; k++;
prepare_args->num_out_map_entries++; 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, CAM_DBG(CAM_REQ,
@ -5864,6 +5792,11 @@ static int cam_icp_packet_generic_blob_handler(void *user_data,
switch (blob_type) { switch (blob_type) {
case CAM_ICP_CMD_GENERIC_BLOB_CLK: 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, CAM_WARN_RATE_LIMIT_CUSTOM(CAM_PERF, 300, 1,
"Using deprecated blob type GENERIC_BLOB_CLK"); "Using deprecated blob type GENERIC_BLOB_CLK");
if (blob_size != sizeof(struct cam_icp_clk_bw_request)) { 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; break;
case CAM_ICP_CMD_GENERIC_BLOB_CLK_V2: 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)) { if (blob_size < sizeof(struct cam_icp_clk_bw_request_v2)) {
CAM_ERR(CAM_ICP, "%s: Mismatch blob size %d expected %lu", CAM_ERR(CAM_ICP, "%s: Mismatch blob size %d expected %lu",
ctx_data->ctx_id_string, ctx_data->ctx_id_string,
@ -6042,6 +5980,11 @@ static int cam_icp_packet_generic_blob_handler(void *user_data,
break; break;
case CAM_ICP_CMD_GENERIC_BLOB_PRESIL_HANGDUMP: 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()) { if (cam_presil_mode_enabled()) {
cmd_mem_regions = (struct cam_cmd_mem_regions *)blob_data; cmd_mem_regions = (struct cam_cmd_mem_regions *)blob_data;
if (cmd_mem_regions->num_regions <= 0) { 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; packet = prepare_args->packet;
if (cam_packet_util_validate_packet(packet, prepare_args->remain_len)) { if (cam_packet_util_validate_packet(packet, prepare_args->remain_len)) {
mutex_unlock(&ctx_data->ctx_mutex); mutex_unlock(&ctx_data->ctx_mutex);
return -EINVAL; return -EINVAL;
} }
rc = cam_icp_mgr_pkt_validation(ctx_data, packet); rc = cam_icp_mgr_pkt_validation(ctx_data, packet);
if (rc) { 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_booted;
*mgr_addr++ = hw_mgr->icp_resumed; *mgr_addr++ = hw_mgr->icp_resumed;
*mgr_addr++ = hw_mgr->disable_ubwc_comp; *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 += sizeof(hw_mgr->dev_info);
*mgr_addr++ = hw_mgr->icp_pc_flag; *mgr_addr++ = hw_mgr->icp_pc_flag;
*mgr_addr++ = hw_mgr->dev_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; struct cam_hw_intf **alloc_devices = NULL;
int rc, i; int rc, i;
enum cam_icp_hw_type icp_hw_type; 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); rc = cam_icp_alloc_processor_devs(np, &icp_hw_type, &alloc_devices, hw_dev_cnt);
if (rc) { 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; devices[icp_hw_type] = alloc_devices;
hw_mgr->hw_cap_mask |= BIT(icp_hw_type); hw_mgr->hw_cap_mask |= BIT(icp_hw_type);
num_cpas_mask = max(num_cpas_mask, (uint32_t)(ICP_CAPS_MASK_IDX + 1)); 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]; cpas_hw_mask[ICP_CAPS_MASK_IDX] |= icp_cpas_mask[hw_mgr->hw_mgr_id];
rc = of_property_read_u32(np, "num-ipe", &num); 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; devices[CAM_ICP_DEV_IPE] = alloc_devices;
hw_mgr->hw_cap_mask |= BIT(CAM_ICP_DEV_IPE); hw_mgr->hw_cap_mask |= BIT(CAM_ICP_DEV_IPE);
num_cpas_mask = max(num_cpas_mask, (uint32_t)(IPE_CAPS_MASK_IDX + 1)); 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); 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; devices[CAM_ICP_DEV_BPS] = alloc_devices;
hw_mgr->hw_cap_mask |= BIT(CAM_ICP_DEV_BPS); hw_mgr->hw_cap_mask |= BIT(CAM_ICP_DEV_BPS);
num_cpas_mask = max(num_cpas_mask, (uint32_t)(BPS_CAPS_MASK_IDX + 1)); 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); 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)); 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) if (!hw_mgr)
return -ENOMEM; return -ENOMEM;
@ -8354,7 +8312,7 @@ destroy_mutex:
kfree(hw_mgr->ctx_data[i].hfi_frame_process.hangdump_mem_regions); kfree(hw_mgr->ctx_data[i].hfi_frame_process.hangdump_mem_regions);
} }
free_hw_mgr: free_hw_mgr:
vfree(hw_mgr); kfree(hw_mgr);
return rc; 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); 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; g_icp_hw_mgr[device_idx] = NULL;
} }

View File

@ -44,7 +44,7 @@
/* size of buffer to drain from msg/dbq queue */ /* size of buffer to drain from msg/dbq queue */
#define ICP_MSG_BUF_SIZE_IN_WORDS 512 #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_OVER_CLK_THRESHOLD 5
#define ICP_TWO_DEV_BW_SHARE_RATIO 2 #define ICP_TWO_DEV_BW_SHARE_RATIO 2

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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 #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_UPDATE_CLK,
CAM_ICP_DEV_CMD_DISABLE_CLK, CAM_ICP_DEV_CMD_DISABLE_CLK,
CAM_ICP_DEV_CMD_RESET, CAM_ICP_DEV_CMD_RESET,
CAM_ICP_DEV_CMD_DUMP_CLK,
CAM_ICP_DEV_CMD_MAX 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, static int cam_icp_proc_validate_ubwc_cfg(struct cam_icp_ubwc_cfg *ubwc_cfg,
uint32_t ubwc_cfg_dev_mask) 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)) && if ((ubwc_cfg_dev_mask & BIT(CAM_ICP_DEV_IPE)) &&
!(found_ubwc_cfg_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"); CAM_ERR(CAM_ICP, "IPE does not have UBWC cfg value");

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * 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> #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); struct platform_device *pdev = to_platform_device(dev);
icp_v1_dev_intf = platform_get_drvdata(pdev); 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; icp_v1_dev = icp_v1_dev_intf->hw_priv;
core_info = (struct cam_icp_v1_device_core_info *)icp_v1_dev->core_info; 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 // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2021, The Linux Foundation. All rights reserved. * 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> #include <linux/module.h>
@ -165,8 +165,17 @@ static void cam_icp_v2_component_unbind(struct device *dev,
struct device *mdev, void *data) struct device *mdev, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct cam_hw_intf *icp_v2_intf = platform_get_drvdata(pdev); struct cam_hw_intf *icp_v2_intf = NULL;
struct cam_hw_info *icp_v2_info = icp_v2_intf->hw_priv; 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_v2_cpas_unregister(icp_v2_intf);
cam_icp_soc_resources_deinit(&icp_v2_info->soc_info); 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_BW_BYTES_VOTE 40000000
#define CAM_ICP_CTX_MAX 64 #define CAM_ICP_CTX_MAX 54
#define CPAS_IPE1_BIT 0x2000 #define CPAS_IPE1_BIT 0x2000

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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> #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: case CAM_ICP_DEV_CMD_RESET:
rc = cam_ipe_cmd_reset(soc_info, core_info); rc = cam_ipe_cmd_reset(soc_info, core_info);
break; break;
case CAM_ICP_DEV_CMD_DUMP_CLK: {
rc = cam_soc_util_dump_clk(soc_info);
break;
}
default: default:
CAM_ERR(CAM_ICP, "Invalid Cmd Type:%u", cmd_type); CAM_ERR(CAM_ICP, "Invalid Cmd Type:%u", cmd_type);
rc = -EINVAL; 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); CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name);
ipe_dev_intf = platform_get_drvdata(pdev); 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; ipe_dev = ipe_dev_intf->hw_priv;
core_info = (struct cam_ipe_device_core_info *)ipe_dev->core_info; core_info = (struct cam_ipe_device_core_info *)ipe_dev->core_info;
cam_cpas_unregister_client(core_info->cpas_handle); 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); CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name);
ofe_dev_intf = platform_get_drvdata(pdev); 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; ofe_dev = ofe_dev_intf->hw_priv;
core_info = (struct cam_ofe_device_core_info *)ofe_dev->core_info; core_info = (struct cam_ofe_device_core_info *)ofe_dev->core_info;
cam_cpas_unregister_client(core_info->cpas_handle); cam_cpas_unregister_client(core_info->cpas_handle);

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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_ #ifndef _CAM_ISP_CONTEXT_H_
@ -105,6 +105,7 @@ enum cam_isp_ctx_event {
CAM_ISP_CTX_EVENT_EPOCH, CAM_ISP_CTX_EVENT_EPOCH,
CAM_ISP_CTX_EVENT_RUP, CAM_ISP_CTX_EVENT_RUP,
CAM_ISP_CTX_EVENT_BUFDONE, CAM_ISP_CTX_EVENT_BUFDONE,
CAM_ISP_CTX_EVENT_SHUTTER,
CAM_ISP_CTX_EVENT_MAX CAM_ISP_CTX_EVENT_MAX
}; };
@ -198,7 +199,7 @@ struct cam_isp_ctx_req {
uint32_t num_fence_map_in; uint32_t num_fence_map_in;
uint32_t num_acked; uint32_t num_acked;
uint32_t num_deferred_acks; 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; int32_t bubble_report;
struct cam_isp_prepare_hw_update_data hw_update_data; struct cam_isp_prepare_hw_update_data hw_update_data;
enum cam_hw_config_reapply_type reapply_type; 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; 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 { struct cam_isp_context_event_record {
uint64_t req_id; uint64_t req_id;
ktime_t timestamp; 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 * @hw_idx: Hardware ID
* @fcg_tracker: FCG prediction tracker containing number of previously skipped * @fcg_tracker: FCG prediction tracker containing number of previously skipped
* frames and indicates which prediction should be used * 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 { struct cam_isp_context {
@ -471,6 +487,9 @@ struct cam_isp_context {
bool mode_switch_en; bool mode_switch_en;
uint32_t hw_idx; uint32_t hw_idx;
struct cam_isp_fcg_prediction_tracker fcg_tracker; 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[] = { static const struct of_device_id cam_isp_dt_match[] = {
{ {
.compatible = "qcom,cam-isp" .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))) { } else if (strnstr(compat_str, "tfe", strlen(compat_str))) {
rc = cam_subdev_probe(&g_isp_dev.sd, pdev, CAM_ISP_DEV_NAME, rc = cam_subdev_probe(&g_isp_dev.sd, pdev, CAM_ISP_DEV_NAME,
CAM_TFE_DEVICE_TYPE); 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.isp_device_type = CAM_TFE_DEVICE_TYPE;
g_isp_dev.max_context = CAM_TFE_CTX_MAX; g_isp_dev.max_context = CAM_TFE_CTX_MAX;
} else { } else {
@ -185,19 +202,22 @@ static int cam_isp_dev_component_bind(struct device *dev,
node = (struct cam_node *) g_isp_dev.sd.token; node = (struct cam_node *) g_isp_dev.sd.token;
memset(&hw_mgr_intf, 0, sizeof(hw_mgr_intf)); 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) { if (!g_isp_dev.ctx) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"Mem Allocation failed for ISP base context"); "Mem Allocation failed for ISP base context");
goto unregister; goto unregister;
} }
g_isp_dev.ctx_isp = vzalloc( g_isp_dev.ctx_isp = kcalloc(g_isp_dev.max_context,
g_isp_dev.max_context * sizeof(struct cam_isp_context)); sizeof(struct cam_isp_context),
GFP_KERNEL);
if (!g_isp_dev.ctx_isp) { if (!g_isp_dev.ctx_isp) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"Mem Allocation failed for Isp private context"); "Mem Allocation failed for Isp private context");
vfree(g_isp_dev.ctx); kfree(g_isp_dev.ctx);
g_isp_dev.ctx = NULL; g_isp_dev.ctx = NULL;
goto unregister; 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, if (g_isp_dev.isp_device_type == CAM_IFE_DEVICE_TYPE)
CAM_COMMON_EVT_INJECT_HW_ISP); 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, rc = cam_node_init(node, &hw_mgr_intf, g_isp_dev.ctx,
g_isp_dev.max_context, CAM_ISP_DEV_NAME); 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; return 0;
free_mem: free_mem:
vfree(g_isp_dev.ctx); kfree(g_isp_dev.ctx);
g_isp_dev.ctx = NULL; g_isp_dev.ctx = NULL;
vfree(g_isp_dev.ctx_isp); kfree(g_isp_dev.ctx_isp);
g_isp_dev.ctx_isp = NULL; g_isp_dev.ctx_isp = NULL;
unregister: unregister:
@ -275,9 +299,9 @@ static void cam_isp_dev_component_unbind(struct device *dev,
i); i);
} }
vfree(g_isp_dev.ctx); kfree(g_isp_dev.ctx);
g_isp_dev.ctx = NULL; g_isp_dev.ctx = NULL;
vfree(g_isp_dev.ctx_isp); kfree(g_isp_dev.ctx_isp);
g_isp_dev.ctx_isp = NULL; g_isp_dev.ctx_isp = NULL;
rc = cam_subdev_remove(&g_isp_dev.sd); 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 * @rx_capture_debug_set: If rx capture debug is set by user
* @disable_isp_drv: Disable ISP DRV config * @disable_isp_drv: Disable ISP DRV config
* @enable_presil_reg_dump: Enable per req regdump in presil * @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 cam_ife_hw_mgr_debug {
struct dentry *dentry; struct dentry *dentry;
@ -87,6 +87,7 @@ struct cam_ife_hw_mgr_debug {
bool rx_capture_debug_set; bool rx_capture_debug_set;
bool disable_isp_drv; bool disable_isp_drv;
bool enable_presil_reg_dump; bool enable_presil_reg_dump;
bool enable_cdm_cmd_check;
#if defined(CONFIG_SAMSUNG_DEBUG_SENSOR_TIMING) #if defined(CONFIG_SAMSUNG_DEBUG_SENSOR_TIMING)
uint32_t csid_dbg_fps; uint32_t csid_dbg_fps;
uint32_t vfe_dbg_fps; uint32_t vfe_dbg_fps;

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * 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_ #ifndef _CAM_TFE_HW_MGR_H_
@ -19,7 +19,6 @@
/* TFE resource constants */ /* TFE resource constants */
#define CAM_TFE_HW_IN_RES_MAX (CAM_ISP_TFE_IN_RES_MAX & 0xFF) #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 #define CAM_TFE_HW_RES_POOL_MAX 64
/** /**
@ -32,7 +31,7 @@
* @camif_debug: enable sensor diagnosis status * @camif_debug: enable sensor diagnosis status
* @enable_reg_dump: enable reg dump on error; * @enable_reg_dump: enable reg dump on error;
* @per_req_reg_dump: Enable per request reg dump * @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 cam_tfe_hw_mgr_debug {
struct dentry *dentry; struct dentry *dentry;
@ -42,6 +41,7 @@ struct cam_tfe_hw_mgr_debug {
uint32_t camif_debug; uint32_t camif_debug;
uint32_t enable_reg_dump; uint32_t enable_reg_dump;
uint32_t per_req_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; 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 * 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_csid: csid resource list
* @res_list_tfe_in: tfe input resource list * @res_list_tfe_in: tfe input resource list
* @res_list_tfe_out: tfe output resoruces array * @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 * @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 * @res_pool: memory storage for the free resource list
* @base device base index array contain the all TFE HW * @base device base index array contain the all TFE HW
* instance associated with this context. * instance associated with this context.
@ -113,6 +137,14 @@ struct cam_tfe_comp_record_query {
* @packet CSL packet from user mode driver * @packet CSL packet from user mode driver
* @bw_config_version BW Config version * @bw_config_version BW Config version
* @tfe_bus_comp_grp pointer to tfe comp group info * @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 cam_tfe_hw_mgr_ctx {
struct list_head list; 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_csid;
struct list_head res_list_tfe_in; struct list_head res_list_tfe_in;
struct cam_isp_hw_mgr_res struct cam_isp_hw_mgr_res *res_list_tfe_out;
res_list_tfe_out[CAM_TFE_HW_OUT_RES_MAX]; uint32_t num_acq_tfe_out;
struct list_head free_res_list; 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_hw_mgr_res res_pool[CAM_TFE_HW_RES_POOL_MAX];
struct cam_isp_ctx_base_info base[CAM_TFE_HW_NUM_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; struct cam_packet *packet;
uint32_t bw_config_version; uint32_t bw_config_version;
struct cam_tfe_hw_comp_record *tfe_bus_comp_grp; 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 * @free_ctx_list: free hw context list
* @used_ctx_list: used hw context list * @used_ctx_list: used hw context list
* @ctx_pool: context storage * @ctx_pool: context storage
* @session_data: Data related to current session
* @tfe_csid_dev_caps csid device capability stored per core * @tfe_csid_dev_caps csid device capability stored per core
* @tfe_dev_caps tfe device capability per core * @tfe_dev_caps tfe device capability per core
* @work q work queue for TFE hw manager * @work q work queue for TFE hw manager
* @debug_cfg debug configuration * @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 * @ctx_lock Spinlock for HW manager
* @isp_caps Capability of underlying TFE HW
*/ */
struct cam_tfe_hw_mgr { struct cam_tfe_hw_mgr {
struct cam_isp_hw_mgr mgr_common; struct cam_isp_hw_mgr mgr_common;
struct cam_hw_intf *csid_devices[CAM_TFE_CSID_HW_NUM_MAX]; 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_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 cam_soc_reg_map *cdm_reg_map[CAM_TFE_HW_NUM_MAX];
struct mutex ctx_mutex; struct mutex ctx_mutex;
atomic_t active_ctx_cnt; atomic_t active_ctx_cnt;
struct list_head free_ctx_list; struct list_head free_ctx_list;
struct list_head used_ctx_list; struct list_head used_ctx_list;
struct cam_tfe_hw_mgr_ctx ctx_pool[CAM_TFE_CTX_MAX]; 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]; CAM_TFE_CSID_HW_NUM_MAX];
struct cam_tfe_hw_get_hw_cap tfe_dev_caps[CAM_TFE_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_req_mgr_core_workq *workq;
struct cam_tfe_hw_mgr_debug debug_cfg; struct cam_tfe_hw_mgr_debug debug_cfg;
bool support_consumed_addr; struct cam_isp_hw_path_port_map path_port_map;
spinlock_t ctx_lock; 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 // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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> #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, &buf_info->scratch_check_cfg->ife_scratch_res_info,
io_cfg->resource_type); io_cfg->resource_type);
} }
*hw_mgr_res = &buf_info->res_list_isp_out[buf_info->out_map[res_id]]; *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) { if ((*hw_mgr_res)->res_type == CAM_ISP_RESOURCE_UNINT) {
CAM_ERR(CAM_ISP, "io res id:%d not valid", CAM_ERR(CAM_ISP, "io res id:%d not valid",
io_cfg->resource_type); 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_hw_fence_map_entry *out_map_entry = NULL;
struct cam_smmu_buffer_tracker *old_head_entry, *new_head_entry; struct cam_smmu_buffer_tracker *old_head_entry, *new_head_entry;
uint32_t kmd_buf_remain_size; uint32_t kmd_buf_remain_size;
uint32_t plane_id; uint32_t plane_id;
uint32_t num_entries; int num_entries;
dma_addr_t *image_buf_addr; dma_addr_t *image_buf_addr;
uint32_t *image_buf_offset; uint32_t *image_buf_offset;
size_t size; 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; num_entries = buf_info->prepare->num_out_map_entries - 1;
out_map_entry = out_map_entry =
&buf_info->prepare->out_map_entries[num_entries]; &buf_info->prepare->out_map_entries[num_entries];
if (!out_map_entry) { if (!out_map_entry) {
CAM_ERR(CAM_ISP, "out_map_entry is NULL"); CAM_ERR(CAM_ISP, "out_map_entry is NULL");
rc = -EINVAL; rc = -EINVAL;
@ -1126,7 +1124,7 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
int rc = 0; int rc = 0;
struct cam_buf_io_cfg *io_cfg = NULL; struct cam_buf_io_cfg *io_cfg = NULL;
struct cam_isp_hw_mgr_res *hw_mgr_res = 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 curr_used_bytes = 0;
uint32_t bytes_updated = 0; uint32_t bytes_updated = 0;
struct cam_isp_resource_node *res = NULL; 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; uint8_t max_out_res = 0;
uint64_t *mc_cfg = NULL; uint64_t *mc_cfg = NULL;
uint32_t major_version = 0; 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_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
&io_info->prepare->packet->payload + &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++) { for (i = 0; i < io_info->prepare->packet->num_io_configs; i++) {
if (major_version == 3) { if (major_version == 3) {
@ -1195,6 +1196,8 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
if (!res) if (!res)
continue; continue;
cfg_io_mask |= (1 << (res->res_id & 0xFF));
rc = cam_isp_add_io_buffers_util(io_info, &io_cfg[i], res); rc = cam_isp_add_io_buffers_util(io_info, &io_cfg[i], res);
if (rc) { if (rc) {
CAM_ERR(CAM_ISP, "io_cfg[%d] add buf failed rc %d", i, 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); 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; bytes_updated = io_info->kmd_buf_info->used_bytes - curr_used_bytes;
CAM_DBG(CAM_ISP, "io_cfg_used_bytes %d, fill_fence %d", CAM_DBG(CAM_ISP, "io_cfg_used_bytes %d, fill_fence %d acuired mask %x cfg mask %x",
bytes_updated, io_info->fill_fence); bytes_updated, io_info->fill_fence, prepare_hw_data->wm_bitmask, cfg_io_mask);
if (bytes_updated) { if (bytes_updated) {
/** /**
@ -1240,17 +1260,82 @@ err:
return rc; 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( int cam_isp_add_reg_update(
struct cam_hw_prepare_update_args *prepare, struct cam_hw_prepare_update_args *prepare,
struct list_head *res_list_isp_src, struct list_head *res_list_isp_src,
uint32_t base_idx, uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info, struct cam_kmd_buf_info *kmd_buf_info,
bool combine) bool combine,
void *priv_data)
{ {
int rc = -EINVAL; int rc = -EINVAL;
struct cam_isp_resource_node *res; struct cam_isp_resource_node *res;
struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_isp_hw_get_cmd_update get_regup; struct cam_isp_hw_get_cmd_update get_regup;
uint32_t kmd_buf_remain_size, i, reg_update_size; uint32_t kmd_buf_remain_size, i, reg_update_size;
/* Max one hw entries required for each base */ /* 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.cmd_type = CAM_ISP_HW_CMD_GET_REG_UPDATE;
get_regup.res = res; get_regup.res = res;
get_regup.data = priv_data;
rc = res->hw_intf->hw_ops.process_cmd( rc = res->hw_intf->hw_ops.process_cmd(
res->hw_intf->hw_priv, res->hw_intf->hw_priv,
CAM_ISP_HW_CMD_GET_REG_UPDATE, &get_regup, CAM_ISP_HW_CMD_GET_REG_UPDATE, &get_regup,

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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_ #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); 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() * 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 * @base_idx: Base or dev index of the IFE/VFE HW instance
* @kmd_buf_info: Kmd buffer to store the change base command * @kmd_buf_info: Kmd buffer to store the change base command
* @combine: Indicate whether combine with prev update entry * @combine: Indicate whether combine with prev update entry
* @priv_data: private data for HW driver
* @return: 0 for success * @return: 0 for success
* -EINVAL for Fail * -EINVAL for Fail
*/ */
@ -298,7 +320,8 @@ int cam_isp_add_reg_update(
struct list_head *res_list_isp_src, struct list_head *res_list_isp_src,
uint32_t base_idx, uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info, struct cam_kmd_buf_info *kmd_buf_info,
bool combine); bool combine,
void *priv_data);
/* /*
* cam_isp_add_comp_wait() * cam_isp_add_comp_wait()

View File

@ -24,7 +24,7 @@
#define CAM_ISP_BW_CONFIG_V1 1 #define CAM_ISP_BW_CONFIG_V1 1
#define CAM_ISP_BW_CONFIG_V2 2 #define CAM_ISP_BW_CONFIG_V2 2
#define CAM_ISP_BW_CONFIG_V3 3 #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_TFE_RDI_NUM_MAX 3
#define CAM_IFE_SCRATCH_NUM_MAX 2 #define CAM_IFE_SCRATCH_NUM_MAX 2
#define CAM_IFE_BUS_COMP_NUM_MAX 18 #define CAM_IFE_BUS_COMP_NUM_MAX 18
@ -33,7 +33,7 @@
#define CAM_TFE_BUS_COMP_NUM_MAX 18 #define CAM_TFE_BUS_COMP_NUM_MAX 18
/* maximum context numbers for TFE */ /* maximum context numbers for TFE */
#define CAM_TFE_CTX_MAX 4 #define CAM_TFE_CTX_MAX 6
/* maximum context numbers for IFE */ /* maximum context numbers for IFE */
#define CAM_IFE_CTX_MAX 8 #define CAM_IFE_CTX_MAX 8
@ -49,6 +49,8 @@
#define CAM_IFE_CTX_SFE_EN BIT(4) #define CAM_IFE_CTX_SFE_EN BIT(4)
#define CAM_IFE_CTX_AEB_EN BIT(5) #define CAM_IFE_CTX_AEB_EN BIT(5)
#define CAM_IFE_CTX_DYNAMIC_SWITCH_EN BIT(6) #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 * 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 * @packet: CSL packet from user mode driver
* @mup_val: MUP value if configured * @mup_val: MUP value if configured
* @num_exp: Num of exposures * @num_exp: Num of exposures
* @wm_bitmask: Bitmask of acquired out resource
* @mup_en: Flag if dynamic sensor switch is enabled * @mup_en: Flag if dynamic sensor switch is enabled
* @fcg_info: Track FCG config for further usage in config stage * @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; struct cam_kmd_buf_info kmd_cmd_buff_info;
uint32_t mup_val; uint32_t mup_val;
uint32_t num_exp; uint32_t num_exp;
uint32_t configured_rup_aup; uint64_t wm_bitmask;
bool mup_en; bool mup_en;
struct cam_isp_fcg_config_info fcg_info; 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_GET_SOF_TS,
CAM_ISP_HW_MGR_DUMP_STREAM_INFO, CAM_ISP_HW_MGR_DUMP_STREAM_INFO,
CAM_ISP_HW_MGR_GET_BUS_COMP_GROUP, 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_LAST_CONSUMED_ADDR,
CAM_ISP_HW_MGR_GET_PATH_SOF_TS,
CAM_ISP_HW_MGR_CMD_MAX, CAM_ISP_HW_MGR_CMD_MAX,
}; };
@ -547,6 +550,21 @@ struct cam_isp_lcr_rdi_cfg_args {
bool is_init; 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() * 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 */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. * 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_ #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_path_err_irqs = ARRAY_SIZE(cam_ife_csid_880_path_irq_desc),
.num_top_regs = 1, .num_top_regs = 1,
.num_rx_regs = 1, .num_rx_regs = 1,
.is_ife_sfe_mapped = true,
}; };
#endif /*_CAM_IFE_CSID_880_H_ */ #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); 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 (cdm_args->cdm_id == CAM_CDM_RT) {
if (!soc_private->rt_wrapper_base) { if (!soc_private->rt_wrapper_base) {
CAM_ERR(CAM_ISP, "rt_wrapper_base_addr is null"); 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; const struct of_device_id *match_dev = NULL;
hw_intf = (struct cam_hw_intf *)platform_get_drvdata(pdev); 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; hw_info = hw_intf->hw_priv;
CAM_DBG(CAM_ISP, "CSID:%d component unbind", CAM_DBG(CAM_ISP, "CSID:%d component unbind",

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. * 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> #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 || if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
res->res_id > CAM_IFE_PIX_PATH_RES_RDI_4) { res->res_id > CAM_IFE_PIX_PATH_RES_RDI_4) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d", "CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx, res->res_name,
res->res_name,
res->res_type, res->res_id, res->res_state); res->res_type, res->res_id, res->res_state);
return -EINVAL; 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_0 ||
res->res_id > CAM_IFE_PIX_PATH_RES_UDI_2)) { res->res_id > CAM_IFE_PIX_PATH_RES_UDI_2)) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d", "CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx, res->res_name,
res->res_name,
res->res_type, res->res_id, res->res_state); res->res_type, res->res_id, res->res_state);
return -EINVAL; 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) { if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d", "CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx, res->res_name,
res->res_name,
res->res_type, res->res_id, res->res_state); res->res_type, res->res_id, res->res_state);
return -EINVAL; return -EINVAL;
} }
@ -903,9 +900,8 @@ static int cam_ife_csid_ver1_stop_pxl_path(
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d", "CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx, res->res_name,
res->res_name,
res->res_type, res->res_id, res->res_state); res->res_type, res->res_id, res->res_state);
return -EINVAL; return -EINVAL;
} }
@ -987,9 +983,8 @@ static int cam_ife_csid_ver1_stop_rdi_path(
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d", "CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx, res->res_name,
res->res_name,
res->res_type, res->res_id, res->res_state); res->res_type, res->res_id, res->res_state);
return -EINVAL; return -EINVAL;
} }
@ -1045,9 +1040,8 @@ static int cam_ife_csid_ver1_stop_udi_path(
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d", "CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx, res->res_name,
res->res_name,
res->res_type, res->res_id, res->res_state); res->res_type, res->res_id, res->res_state);
return -EINVAL; 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); csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
path_cfg = (struct cam_ife_csid_ver1_path_cfg *)res->res_priv; 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], cam_ife_csid_cid_release(&csid_hw->cid_data[path_cfg->cid],
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx,
path_cfg->cid); 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 || if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
res->res_id > CAM_IFE_PIX_PATH_RES_RDI_4) { res->res_id > CAM_IFE_PIX_PATH_RES_RDI_4) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d", "CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx, res->res_name,
res->res_name,
res->res_type, res->res_id, res->res_state); res->res_type, res->res_id, res->res_state);
return -EINVAL; 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_0 ||
res->res_id > CAM_IFE_PIX_PATH_RES_UDI_2)) { res->res_id > CAM_IFE_PIX_PATH_RES_UDI_2)) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d", "CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx, res->res_name,
res->res_name,
res->res_type, res->res_id, res->res_state); res->res_type, res->res_id, res->res_state);
return -EINVAL; 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) { if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID:%d %s path res type:%d res_id:%d Invalid state%d", "CSID:%d %s path res_type:%d res_id:%d Invalid state:%d",
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx, res->res_name,
res->res_name,
res->res_type, res->res_id, res->res_state); res->res_type, res->res_id, res->res_state);
return -EINVAL; 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.fatal_err_detected = false;
csid_hw->flags.device_enabled = true; csid_hw->flags.device_enabled = true;
spin_unlock_irqrestore(&csid_hw->lock_state, flags); spin_unlock_irqrestore(&csid_hw->lock_state, flags);
cam_tasklet_start(csid_hw->tasklet);
return rc; return rc;
@ -2742,8 +2740,6 @@ int cam_ife_csid_ver1_init_hw(void *hw_priv,
struct cam_hw_info *hw_info; struct cam_hw_info *hw_info;
int rc = 0; int rc = 0;
if (!hw_priv || !init_args || if (!hw_priv || !init_args ||
(arg_size != sizeof(struct cam_isp_resource_node))) { (arg_size != sizeof(struct cam_isp_resource_node))) {
CAM_ERR(CAM_ISP, "CSID: Invalid args"); 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; hw_info = (struct cam_hw_info *)hw_priv;
csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info; csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info;
rc = cam_ife_csid_ver1_enable_hw(csid_hw); rc = cam_ife_csid_ver1_enable_hw(csid_hw);
if (rc) { 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 + cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->top_irq_mask_addr); csid_reg->cmn_reg->top_irq_mask_addr);
cam_tasklet_stop(csid_hw->tasklet);
rc = cam_ife_csid_disable_soc_resources(soc_info); rc = cam_ife_csid_disable_soc_resources(soc_info);
if (rc) if (rc)
CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed", 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: case CAM_ISP_HW_CMD_CSID_DUMP_CROP_REG:
/* Not supported in V1*/ /* Not supported in V1*/
break; break;
case CAM_IFE_CSID_CMD_GET_PATH_TIME_STAMP:
/* Not supported in V1*/
break;
default: default:
CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
csid_hw->hw_intf->hw_idx, cmd_type); csid_hw->hw_intf->hw_idx, cmd_type);

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. * 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> #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( static int cam_ife_csid_ver2_handle_event_err(
struct cam_ife_csid_ver2_hw *csid_hw, struct cam_ife_csid_ver2_hw *csid_hw,
uint32_t irq_status, 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_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_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); 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 cam_ife_csid_hw_ver2_mup_mismatch_handler(
void *csid, void *resource) void *csid, void *resource)
{ {
uint32_t idx = 0, val; uint32_t idx = 0;
struct timespec64 current_ts; struct timespec64 current_ts;
struct cam_ife_csid_ver2_hw *csid_hw = csid; struct cam_ife_csid_ver2_hw *csid_hw = csid;
struct cam_isp_resource_node *res = resource; 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) { if (path_cfg->ts_comb_vcdt_en) {
ktime_get_boottime_ts64(&current_ts); ktime_get_boottime_ts64(&current_ts);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base + idx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
path_reg->timestamp_curr0_sof_addr); path_reg->timestamp_curr0_sof_addr) &
idx = val & csid_reg->cmn_reg->ts_comb_vcdt_mask; csid_reg->cmn_reg->ts_comb_vcdt_mask;
if (idx < CAM_IFE_CSID_MULTI_VC_DT_GRP_MAX) if (idx < CAM_IFE_CSID_MULTI_VC_DT_GRP_MAX)
CAM_INFO(CAM_ISP, 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, csid_hw->hw_intf->hw_idx, cid_data->vc_dt[idx].vc,
res->res_id, res->res_name, current_ts.tv_sec, res->res_id, res->res_name, current_ts.tv_sec,
current_ts.tv_nsec, val); current_ts.tv_nsec);
else else
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID:%d Get invalid vc index: %d on [id: %d name: %s] timestamp: %lld.%09lld", "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); cfg1 = cam_io_r_mb(base + path_reg->cfg1_addr);
vcdt_cfg0 = cam_io_r_mb(base + path_reg->multi_vcdt_cfg0_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) { if (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].valid) {
decode_fmt = ((cfg0 >> 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)) if ((irq_status & IFE_CSID_VER2_PATH_INFO_INPUT_SOF))
csid_hw->counters.irq_debug_cnt++; csid_hw->counters.irq_debug_cnt++;
if (csid_hw->counters.irq_debug_cnt >= if (csid_hw->counters.irq_debug_cnt >=
CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX) { CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX) {
cam_ife_csid_ver2_sof_irq_debug(csid_hw, 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 */ /* Only notify if secondary event is subscribed for */
if ((path_cfg->sec_evt_config.en_secondary_evt) && if ((path_cfg->sec_evt_config.en_secondary_evt) &&
(path_cfg->sec_evt_config.evt_type & (path_cfg->sec_evt_config.evt_type &
CAM_IFE_CSID_EVT_SENSOR_SYNC_FRAME_DROP)) { CAM_IFE_CSID_EVT_SENSOR_SYNC_FRAME_DROP))
do_notify = true; do_notify = true;
}
/* Validate error threshold for primary RDI (master) */ /* Validate error threshold for primary RDI (master) */
if (res->is_rdi_primary_res) { 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->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->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->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, CAM_DBG(CAM_ISP,
"CSID:%u num-rdis:%d, num-pix:%d, major:%d minor:%d ver:%d", "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( 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 rst_cmd, uint32_t rst_location, uint32_t rst_mode)
{ {
uint32_t val = 0; 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); cam_io_w_mb(0x0, mem_base + csi2_reg->cfg1_addr);
} }
/* if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_SLAVE)
* 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))
goto wait_only; 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); reinit_completion(&csid_hw->hw_info->hw_complete);
/* Program the reset location */ /* Program the reset location */
@ -2779,16 +2766,14 @@ int cam_ife_csid_ver2_reset(void *hw_priv,
switch (reset->reset_type) { switch (reset->reset_type) {
case CAM_IFE_CSID_RESET_GLOBAL: case CAM_IFE_CSID_RESET_GLOBAL:
rc = cam_ife_csid_ver2_internal_reset( rc = cam_ife_csid_ver2_internal_reset(csid_hw,
csid_hw, reset->power_on_reset,
CAM_IFE_CSID_RESET_CMD_SW_RST, CAM_IFE_CSID_RESET_CMD_SW_RST,
CAM_IFE_CSID_RESET_LOC_COMPLETE, CAM_IFE_CSID_RESET_LOC_COMPLETE,
CAM_CSID_HALT_IMMEDIATELY); CAM_CSID_HALT_IMMEDIATELY);
break; break;
case CAM_IFE_CSID_RESET_PATH: case CAM_IFE_CSID_RESET_PATH:
rc = cam_ife_csid_ver2_internal_reset( rc = cam_ife_csid_ver2_internal_reset(csid_hw,
csid_hw, reset->power_on_reset,
CAM_IFE_CSID_RESET_CMD_HW_RST, CAM_IFE_CSID_RESET_CMD_HW_RST,
CAM_IFE_CSID_RESET_LOC_PATH_ONLY, CAM_IFE_CSID_RESET_LOC_PATH_ONLY,
CAM_CSID_HALT_IMMEDIATELY); CAM_CSID_HALT_IMMEDIATELY);
@ -3362,6 +3347,82 @@ end:
return rc; 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( static int cam_ife_csid_ver2_in_port_validate(
struct cam_csid_hw_reserve_resource_args *reserve, struct cam_csid_hw_reserve_resource_args *reserve,
struct cam_ife_csid_ver2_hw *csid_hw) struct cam_ife_csid_ver2_hw *csid_hw)
@ -3376,6 +3437,9 @@ static int cam_ife_csid_ver2_in_port_validate(
goto err; 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->counters.csi2_reserve_cnt) {
if (csid_hw->token != reserve->cb_priv) { 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; 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], cam_ife_csid_cid_release(&csid_hw->cid_data[path_cfg->cid],
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx,
path_cfg->cid); 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)) res->res_id == CAM_IFE_PIX_PATH_RES_RDI_0))
cam_ife_csid_ver2_res_master_slave_cfg(csid_hw, res->res_id); 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 + val = cam_io_r_mb(mem_base +
path_reg->format_measure_cfg0_addr); path_reg->format_measure_cfg0_addr);
val |= cmn_reg->measure_en_hbi_vbi_cnt_mask; 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); 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 + val = cam_io_r_mb(mem_base +
path_reg->format_measure_cfg0_addr); path_reg->format_measure_cfg0_addr);
val |= csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; 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, struct cam_isp_resource_node *res,
uint32_t irq_mask, uint32_t err_irq_mask) 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_path_cfg *path_cfg = res->res_priv;
struct cam_ife_csid_ver2_reg_info *csid_reg = csid_hw->core_info->csid_reg; struct cam_ife_csid_ver2_reg_info *csid_reg = csid_hw->core_info->csid_reg;
int i, rc; int i, rc;
@ -4114,8 +4188,14 @@ static int cam_ife_csid_ver2_path_irq_subscribe(
return -EINVAL; return -EINVAL;
} }
top_irq_mask[CAM_IFE_CSID_IRQ_TOP_REG_STATUS0] = num_register = csid_reg->top_irq_reg_info[top_index].num_registers;
csid_reg->path_reg[res->res_id]->top_irq_mask[top_index]; 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) { 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); 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; rc = -EINVAL;
goto unsub_path; goto unsub_path;
} }
vfree(top_irq_mask);
return 0; return 0;
unsub_path: unsub_path:
@ -4201,6 +4281,7 @@ unsub_mc:
csid_hw->top_mc_irq_handle); csid_hw->top_mc_irq_handle);
csid_hw->top_mc_irq_handle = 0; csid_hw->top_mc_irq_handle = 0;
end: end:
vfree(top_irq_mask);
return rc; 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) uint32_t irq_mask, uint32_t err_irq_mask)
{ {
struct cam_ife_csid_ver2_reg_info *csid_reg = csid_hw->core_info->csid_reg; 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 top_index = -1;
int i, rc; 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; return rc;
} }
top_irq_mask[CAM_IFE_CSID_IRQ_TOP_REG_STATUS0] = num_register = csid_reg->top_irq_reg_info[top_index].num_registers;
csid_reg->csi2_reg->top_irq_mask[top_index]; 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->rx_cfg.top_irq_handle = cam_irq_controller_subscribe_irq(
csid_hw->top_irq_controller[top_index], 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; rc = -EINVAL;
goto unsub_rx; goto unsub_rx;
} }
vfree(top_irq_mask);
return 0; return 0;
unsub_rx: unsub_rx:
@ -4743,6 +4831,7 @@ unsub_top:
csid_hw->rx_cfg.top_irq_handle); csid_hw->rx_cfg.top_irq_handle);
csid_hw->rx_cfg.top_irq_handle = 0; csid_hw->rx_cfg.top_irq_handle = 0;
err: err:
vfree(top_irq_mask);
return rc; return rc;
} }
@ -5055,8 +5144,9 @@ static int cam_ife_csid_ver2_enable_hw(
int i, rc; int i, rc;
void __iomem *mem_base; void __iomem *mem_base;
const struct cam_ife_csid_ver2_path_reg_info *path_reg = NULL; 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 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; uint32_t top_info_irq_mask = 0;
if (csid_hw->flags.device_enabled) { if (csid_hw->flags.device_enabled) {
@ -5097,12 +5187,16 @@ static int cam_ife_csid_ver2_enable_hw(
/* Read hw version */ /* Read hw version */
val = cam_io_r_mb(mem_base + csid_reg->cmn_reg->hw_version_addr); 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] = num_register = csid_reg->top_irq_reg_info[CAM_IFE_CSID_TOP_IRQ_STATUS_REG0].num_registers;
csid_reg->cmn_reg->top_buf_done_irq_mask; 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) if (csid_reg->ipp_mc_reg)
buf_done_irq_mask[CAM_IFE_CSID_IRQ_TOP_REG_STATUS0] |= buf_done_irq_mask[0] |= csid_reg->ipp_mc_reg->comp_subgrp0_mask |
csid_reg->ipp_mc_reg->comp_subgrp0_mask |
csid_reg->ipp_mc_reg->comp_subgrp2_mask; csid_reg->ipp_mc_reg->comp_subgrp2_mask;
csid_hw->buf_done_irq_handle = cam_irq_controller_subscribe_irq( 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) { if (csid_hw->buf_done_irq_handle < 1) {
CAM_ERR(CAM_ISP, "CSID[%u] buf done irq subscribe fail", CAM_ERR(CAM_ISP, "CSID[%u] buf done irq subscribe fail",
csid_hw->hw_intf->hw_idx); 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]; 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; csid_hw->flags.fatal_err_detected = false;
CAM_DBG(CAM_ISP, "CSID:%u CSID HW version: 0x%x", CAM_DBG(CAM_ISP, "CSID:%u CSID HW version: 0x%x",
csid_hw->hw_intf->hw_idx, val); csid_hw->hw_intf->hw_idx, val);
vfree(buf_done_irq_mask);
return 0; return 0;
@ -5196,6 +5292,8 @@ unsubscribe_buf_done:
csid_hw->top_irq_controller[CAM_IFE_CSID_TOP_IRQ_STATUS_REG0], csid_hw->top_irq_controller[CAM_IFE_CSID_TOP_IRQ_STATUS_REG0],
csid_hw->buf_done_irq_handle); csid_hw->buf_done_irq_handle);
csid_hw->buf_done_irq_handle = 0; csid_hw->buf_done_irq_handle = 0;
free_buf_done_mask:
vfree(buf_done_irq_mask);
return rc; 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, 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)); 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 */ /* Issue a halt & reset to ensure there is no HW activity post the halt block */
reset.reset_type = CAM_IFE_CSID_RESET_PATH; reset.reset_type = CAM_IFE_CSID_RESET_PATH;
reset.power_on_reset = false;
cam_ife_csid_ver2_reset(hw_priv, &reset, cam_ife_csid_ver2_reset(hw_priv, &reset,
sizeof(struct cam_csid_reset_cfg_args)); sizeof(struct cam_csid_reset_cfg_args));
@ -6182,7 +6279,7 @@ static int cam_ife_csid_ver2_reg_update(
if (rup_args->mup_en) { if (rup_args->mup_en) {
csid_hw->rx_cfg.mup = rup_args->mup_val; 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); csid_hw->hw_intf->hw_idx, csid_hw->rx_cfg.mup);
} }
@ -6191,7 +6288,6 @@ static int cam_ife_csid_ver2_reg_update(
else else
cam_ife_csid_ver2_get_sc_reg_val_pair(csid_hw, reg_val_pair, rup_args); 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) { if (rup_args->reg_write) {
for (i = 0; i < (2 * num_reg_val_pairs); i = i + 2) 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]); 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; 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( static int cam_ife_csid_ver2_set_dynamic_switch_config(
struct cam_ife_csid_ver2_hw *csid_hw, struct cam_ife_csid_ver2_hw *csid_hw,
void *cmd_args) void *cmd_args)
@ -6631,7 +6661,7 @@ static int cam_ife_csid_ver2_set_dynamic_switch_config(
if (switch_update->mup_args.use_mup) { if (switch_update->mup_args.use_mup) {
csid_hw->rx_cfg.mup = switch_update->mup_args.mup_val; 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); csid_hw->hw_intf->hw_idx, csid_hw->rx_cfg.mup);
} }

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. * 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_ #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_path_err_irqs;
const uint32_t num_top_regs; const uint32_t num_top_regs;
const uint32_t num_rx_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 */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. * 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_ #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_path_err_irqs = ARRAY_SIZE(cam_ife_csid_lite_880_path_irq_desc),
.num_top_regs = 1, .num_top_regs = 1,
.num_rx_regs = 1, .num_rx_regs = 1,
.is_ife_sfe_mapped = true,
}; };
#endif /* _CAM_IFE_CSID_LITE_780_H_ */ #endif /* _CAM_IFE_CSID_LITE_780_H_ */

View File

@ -13,6 +13,7 @@
#include "cam_ife_csid_lite480.h" #include "cam_ife_csid_lite480.h"
#include "cam_ife_csid_lite680.h" #include "cam_ife_csid_lite680.h"
#include "cam_ife_csid_lite780.h" #include "cam_ife_csid_lite780.h"
#include "cam_ife_csid_lite860.h"
#include "cam_ife_csid_lite880.h" #include "cam_ife_csid_lite880.h"
#define CAM_CSID_LITE_DRV_NAME "csid_lite" #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, .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 = { static struct cam_ife_csid_core_info cam_ife_csid_lite_880_hw_info = {
.csid_reg = &cam_ife_csid_lite_880_reg_info, .csid_reg = &cam_ife_csid_lite_880_reg_info,
.sw_version = CAM_IFE_CSID_VER_2_0, .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", .compatible = "qcom,csid-lite780",
.data = &cam_ife_csid_lite_780_hw_info, .data = &cam_ife_csid_lite_780_hw_info,
}, },
{
.compatible = "qcom,csid-lite860",
.data = &cam_ife_csid_lite_860_hw_info,
},
{ {
.compatible = "qcom,csid-lite880", .compatible = "qcom,csid-lite880",
.data = &cam_ife_csid_lite_880_hw_info, .data = &cam_ife_csid_lite_880_hw_info,

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. * 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> #include <linux/module.h>
@ -20,6 +20,7 @@
#include "cam_ife_csid680.h" #include "cam_ife_csid680.h"
#include "cam_ife_csid680_110.h" #include "cam_ife_csid680_110.h"
#include "cam_ife_csid780.h" #include "cam_ife_csid780.h"
#include "cam_ife_csid860.h"
#include "cam_ife_csid880.h" #include "cam_ife_csid880.h"
#include "cam_ife_csid980.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, .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 = { static struct cam_ife_csid_core_info cam_ife_csid880_hw_info = {
.csid_reg = &cam_ife_csid_880_reg_info, .csid_reg = &cam_ife_csid_880_reg_info,
.sw_version = CAM_IFE_CSID_VER_2_0, .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", .compatible = "qcom,csid780",
.data = &cam_ife_csid780_hw_info, .data = &cam_ife_csid780_hw_info,
}, },
{
.compatible = "qcom,csid860",
.data = &cam_ife_csid860_hw_info,
},
{ {
.compatible = "qcom,csid880", .compatible = "qcom,csid880",
.data = &cam_ife_csid880_hw_info, .data = &cam_ife_csid880_hw_info,

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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_ #ifndef _CAM_CSID_HW_INTF_H_
@ -16,7 +16,6 @@
#define RT_BASE_IDX 2 #define RT_BASE_IDX 2
#define CAM_ISP_MAX_PATHS 8 #define CAM_ISP_MAX_PATHS 8
/** /**
* enum cam_ife_csid_hw_irq_regs - Specify the top irq reg * 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 * @rup_en: flag to indicate if rup is on csid side
* @only_master_rup: flag to indicate if only master RUP * @only_master_rup: flag to indicate if only master RUP
* @camif_irq_support: flag to indicate if CSID supports CAMIF irq * @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 { struct cam_ife_csid_hw_caps {
uint32_t num_rdis; uint32_t num_rdis;
@ -123,6 +123,7 @@ struct cam_ife_csid_hw_caps {
bool rup_en; bool rup_en;
bool only_master_rup; bool only_master_rup;
bool camif_irq_support; bool camif_irq_support;
bool is_ife_sfe_mapped;
}; };
struct cam_isp_out_port_generic_info { struct cam_isp_out_port_generic_info {
@ -482,7 +483,6 @@ struct cam_isp_csid_reg_update_args {
bool reg_write; bool reg_write;
uint32_t mup_val; uint32_t mup_val;
uint32_t mup_en; 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_FE_TRIGGER_CMD,
CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ, CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ,
CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT, 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_GET_RES_FOR_MID,
CAM_ISP_HW_CMD_BLANKING_UPDATE, CAM_ISP_HW_CMD_BLANKING_UPDATE,
CAM_ISP_HW_CMD_CSID_CLOCK_DUMP, CAM_ISP_HW_CMD_CSID_CLOCK_DUMP,
@ -258,7 +259,10 @@ enum cam_isp_hw_cmd_type {
#if defined(CONFIG_SAMSUNG_DEBUG_SENSOR_TIMING) #if defined(CONFIG_SAMSUNG_DEBUG_SENSOR_TIMING)
CAM_IFE_CSID_SOF_IRQ_DEBUG_FOR_MODESWITCH, CAM_IFE_CSID_SOF_IRQ_DEBUG_FOR_MODESWITCH,
#endif #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_IFE_CSID_CMD_GET_PATH_TIME_STAMP,
CAM_ISP_HW_CMD_MAX, 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 * @Brief: Get the out resource id for given mid
* *
* @mid: Mid number of hw outport numb * @mid: Mid number of hw outport numb
* @pid: Pid number associated with mid
* @out_res_id: Out resource id * @out_res_id: Out resource id
* *
*/ */
struct cam_isp_hw_get_res_for_mid { struct cam_isp_hw_get_res_for_mid {
uint32_t mid; uint32_t mid;
uint32_t pid;
uint32_t out_res_id; uint32_t out_res_id;
}; };
@ -518,6 +524,7 @@ struct cam_isp_hw_fcg_cmd {
* @cmd: Command buffer information * @cmd: Command buffer information
* @use_scratch_cfg: To indicate if it's scratch buffer config * @use_scratch_cfg: To indicate if it's scratch buffer config
* @trigger_cdm_en: Flag to indicate if cdm is trigger * @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 { 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; struct cam_isp_hw_get_wm_update *rm_update;
}; };
bool trigger_cdm_en; bool trigger_cdm_en;
bool reg_write;
}; };
/* /*
@ -587,6 +595,20 @@ struct cam_isp_hw_dump_header {
uint32_t word_size; 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 * struct cam_isp_hw_intf_data - ISP hw intf data
* *

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * 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_ #ifndef _CAM_TFE_CSID_HW_INTF_H_
@ -12,7 +12,7 @@
#include "cam_tfe.h" #include "cam_tfe.h"
/* MAX TFE CSID instance */ /* 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 #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_1,
CAM_TFE_CSID_PATH_RES_RDI_2, CAM_TFE_CSID_PATH_RES_RDI_2,
CAM_TFE_CSID_PATH_RES_IPP, CAM_TFE_CSID_PATH_RES_IPP,
CAM_TFE_CSID_PATH_RES_PPP,
CAM_TFE_CSID_PATH_RES_MAX, 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_TOP,
TFE_CSID_IRQ_REG_RX, TFE_CSID_IRQ_REG_RX,
TFE_CSID_IRQ_REG_IPP, TFE_CSID_IRQ_REG_IPP,
TFE_CSID_IRQ_REG_PPP,
TFE_CSID_IRQ_REG_MAX, TFE_CSID_IRQ_REG_MAX,
}; };
@ -89,6 +91,9 @@ struct cam_isp_tfe_in_port_generic_info {
uint32_t ipp_count; uint32_t ipp_count;
uint32_t rdi_count; uint32_t rdi_count;
uint32_t secure_mode; uint32_t secure_mode;
bool shdr_en;
bool is_shdr_master;
bool epd_supported;
struct cam_isp_tfe_out_port_generic_info *data; 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 * struct cam_tfe_csid_hw_caps- get the CSID hw capability
* @num_rdis: number of rdis supported by CSID HW device * @num_rdis: number of rdis supported by CSID HW device
* @num_pix: number of pxl paths 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 * @major_version : major version
* @minor_version: minor version * @minor_version: minor version
* @version_incr: version increment * @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 { struct cam_tfe_csid_hw_caps {
uint32_t num_rdis; uint32_t num_rdis;
uint32_t num_pix; uint32_t num_pix;
uint32_t num_ppp;
uint32_t major_version; uint32_t major_version;
uint32_t minor_version; uint32_t minor_version;
uint32_t version_incr; 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_prv: Context data
* @event_cb: Callback function to hw mgr in case of hw events * @event_cb: Callback function to hw mgr in case of hw events
* @node_res : Reserved resource structure pointer * @node_res : Reserved resource structure pointer
* @crop_enable : Flag to indicate CSID crop enable
* *
*/ */
struct cam_tfe_csid_hw_reserve_resource_args { struct cam_tfe_csid_hw_reserve_resource_args {
@ -137,6 +149,7 @@ struct cam_tfe_csid_hw_reserve_resource_args {
void *event_cb_prv; void *event_cb_prv;
cam_hw_mgr_event_cb_func event_cb; cam_hw_mgr_event_cb_func event_cb;
struct cam_isp_resource_node *node_res; 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; 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_ */ #endif /* _CAM_TFE_CSID_HW_INTF_H_ */

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * 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_ #ifndef _CAM_TFE_HW_INTF_H_
@ -10,7 +10,7 @@
#include "cam_isp_hw.h" #include "cam_isp_hw.h"
#include "cam_cpas_api.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 #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_RDI0 = 1,
CAM_ISP_HW_TFE_IN_RDI1 = 2, CAM_ISP_HW_TFE_IN_RDI1 = 2,
CAM_ISP_HW_TFE_IN_RDI2 = 3, CAM_ISP_HW_TFE_IN_RDI2 = 3,
CAM_ISP_HW_TFE_IN_PDLIB = 4,
CAM_ISP_HW_TFE_IN_MAX, 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_OVERFLOW,
CAM_TFE_IRQ_STATUS_P2I_ERROR, CAM_TFE_IRQ_STATUS_P2I_ERROR,
CAM_TFE_IRQ_STATUS_VIOLATION, CAM_TFE_IRQ_STATUS_VIOLATION,
CAM_TFE_IRQ_STATUS_OUT_OF_SYNC,
CAM_TFE_IRQ_STATUS_MAX, CAM_TFE_IRQ_STATUS_MAX,
}; };
@ -120,6 +122,7 @@ struct cam_tfe_hw_tfe_out_acquire_args {
* @in_port: Input port details to acquire * @in_port: Input port details to acquire
* @camif_pd_enable Camif pd enable or disable * @camif_pd_enable Camif pd enable or disable
* @dual_tfe_sync_sel_idx Dual tfe master hardware index * @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_tfe_hw_tfe_in_acquire_args {
struct cam_isp_resource_node *rsrc_node; 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; enum cam_isp_hw_sync_mode sync_mode;
bool camif_pd_enable; bool camif_pd_enable;
uint32_t dual_tfe_sync_sel_idx; 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; 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() * cam_tfe_hw_init()
* *

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/slab.h> #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); struct platform_device *pdev = to_platform_device(dev);
ppi_dev = (struct cam_csid_ppi_hw *)platform_get_drvdata(pdev); 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_intf = ppi_dev->hw_intf;
ppi_hw_info = ppi_dev->hw_info; 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 // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. * 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> #include <linux/slab.h>
@ -14,6 +14,7 @@
#include "cam_sfe_soc.h" #include "cam_sfe_soc.h"
#include "cam_sfe680.h" #include "cam_sfe680.h"
#include "cam_sfe780.h" #include "cam_sfe780.h"
#include "cam_sfe860.h"
#include "cam_sfe880.h" #include "cam_sfe880.h"
#include "cam_debug_util.h" #include "cam_debug_util.h"
#include "camera_main.h" #include "camera_main.h"
@ -261,6 +262,10 @@ static const struct of_device_id cam_sfe_dt_match[] = {
.compatible = "qcom,sfe780", .compatible = "qcom,sfe780",
.data = &cam_sfe780_hw_info, .data = &cam_sfe780_hw_info,
}, },
{
.compatible = "qcom,sfe860",
.data = &cam_sfe860_hw_info,
},
{ {
.compatible = "qcom,sfe880", .compatible = "qcom,sfe880",
.data = &cam_sfe880_hw_info, .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( mem_base = CAM_SOC_GET_REG_MAP_CAM_BASE(
top_priv->common_data.soc_info, top_priv->common_data.soc_info,
SFE_CORE_BASE_IDX); 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 (cdm_args->cdm_id == CAM_CDM_RT) {
if (!soc_private->rt_wrapper_base) { 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; fcg_index_shift = fcg_module_info->fcg_index_shift;
for (i = 0, j = 0; i < fcg_config->num_ch_ctx; i++) { for (i = 0, j = 0; i < fcg_config->num_ch_ctx; i++) {
if (j >= fcg_module_info->max_reg_val_pair_size) { if (j >= fcg_module_info->max_reg_val_pair_size) {
CAM_ERR(CAM_SFE, "reg_val_pair %d exceeds the array limit %u", 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) void *handler_priv, void *evt_payload_priv)
{ {
int i; 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}; uint32_t irq_status[CAM_SFE_IRQ_REGISTERS_MAX] = {0};
enum cam_sfe_hw_irq_status ret = CAM_SFE_IRQ_STATUS_MAX; enum cam_sfe_hw_irq_status ret = CAM_SFE_IRQ_STATUS_MAX;
struct cam_isp_resource_node *res = handler_priv; struct cam_isp_resource_node *res = handler_priv;

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2021, The Linux Foundation. All rights reserved. * 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_csid_core.h"
#include "cam_tfe_csid530.h" #include "cam_tfe_csid530.h"
#include "cam_tfe_csid640.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 "cam_tfe_csid_dev.h"
#include "camera_main.h" #include "camera_main.h"
@ -22,6 +26,22 @@ static const struct of_device_id cam_tfe_csid_dt_match[] = {
.compatible = "qcom,csid640", .compatible = "qcom,csid640",
.data = &cam_tfe_csid640_hw_info, .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 */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * 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_ #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_long_pkt_hdr_rst_stb_shift = 0x1,
.csi2_rx_short_pkt_hdr_rst_stb_shift = 0x2, .csi2_rx_short_pkt_hdr_rst_stb_shift = 0x2,
.csi2_rx_cphy_pkt_hdr_rst_stb_shift = 0x3, .csi2_rx_cphy_pkt_hdr_rst_stb_shift = 0x3,
.need_to_sel_tpg_mux = false,
}; };
static struct cam_tfe_csid_common_reg_offset static struct cam_tfe_csid_common_reg_offset

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * 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_ #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_stats_ecc_addr = 0x164,
.csid_csi2_rx_total_crc_err_addr = 0x168, .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_srb_all = 0x3FFF,
.csi2_rst_done_shift_val = 27, .csi2_rst_done_shift_val = 27,
.csi2_irq_mask_all = 0xFFFFFFF, .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_long_pkt_hdr_rst_stb_shift = 0x1,
.csi2_rx_short_pkt_hdr_rst_stb_shift = 0x2, .csi2_rx_short_pkt_hdr_rst_stb_shift = 0x2,
.csi2_rx_cphy_pkt_hdr_rst_stb_shift = 0x3, .csi2_rx_cphy_pkt_hdr_rst_stb_shift = 0x3,
.need_to_sel_tpg_mux = true,
}; };
static struct cam_tfe_csid_common_reg_offset 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_shift_val = 16,
.format_measure_height_mask_val = 0xe, .format_measure_height_mask_val = 0xe,
.format_measure_width_mask_val = 0x10, .format_measure_width_mask_val = 0x10,
.sync_clk = true,
}; };
static struct cam_tfe_csid_reg_offset cam_tfe_csid_640_reg_offset = { 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 */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * 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_ #ifndef _CAM_TFE_CSID_HW_H_
@ -55,11 +56,14 @@
#define TFE_CSID_PATH_ERROR_PIX_COUNT BIT(13) #define TFE_CSID_PATH_ERROR_PIX_COUNT BIT(13)
#define TFE_CSID_PATH_ERROR_LINE_COUNT BIT(14) #define TFE_CSID_PATH_ERROR_LINE_COUNT BIT(14)
#define TFE_CSID_PATH_IPP_ERROR_CCIF_VIOLATION BIT(15) #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(16)
#define TFE_CSID_PATH_IPP_FRAME_DROP BIT(17) #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_FRAME_DROP BIT(16)
#define TFE_CSID_PATH_RDI_OVERFLOW_IRQ BIT(17) #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 * 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, 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 *enum cam_csid_path_timestamp_stb_sel - select the sof/eof strobes used to
* capture the timestamp * capture the timestamp
@ -115,11 +127,20 @@ struct cam_tfe_csid_pxl_reg_offset {
uint32_t csid_pxl_cfg0_addr; uint32_t csid_pxl_cfg0_addr;
uint32_t csid_pxl_cfg1_addr; uint32_t csid_pxl_cfg1_addr;
uint32_t csid_pxl_ctrl_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_hcrop_addr;
uint32_t csid_pxl_vcrop_addr; uint32_t csid_pxl_vcrop_addr;
uint32_t csid_pxl_rst_strobes_addr; uint32_t csid_pxl_rst_strobes_addr;
uint32_t csid_pxl_status_addr; uint32_t csid_pxl_status_addr;
uint32_t csid_pxl_misr_val_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_curr0_sof_addr;
uint32_t csid_pxl_timestamp_curr1_sof_addr; uint32_t csid_pxl_timestamp_curr1_sof_addr;
uint32_t csid_pxl_timestamp_perv0_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_curr1_eof_addr;
uint32_t csid_pxl_timestamp_perv0_eof_addr; uint32_t csid_pxl_timestamp_perv0_eof_addr;
uint32_t csid_pxl_timestamp_perv1_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_cfg0_addr;
uint32_t csid_pxl_err_recovery_cfg1_addr; uint32_t csid_pxl_err_recovery_cfg1_addr;
uint32_t csid_pxl_err_recovery_cfg2_addr; uint32_t csid_pxl_err_recovery_cfg2_addr;
uint32_t csid_pxl_multi_vcdt_cfg0_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 */ /* configuration */
uint32_t pix_store_en_shift_val; uint32_t pix_store_en_shift_val;
uint32_t early_eof_en_shift_val; uint32_t early_eof_en_shift_val;
uint32_t halt_master_sel_shift; uint32_t halt_master_sel_shift;
uint32_t halt_mode_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_master_val;
uint32_t halt_master_sel_slave_val; uint32_t halt_master_sel_slave_val;
uint32_t binning_supported; uint32_t binning_supported;
@ -151,6 +170,7 @@ struct cam_tfe_csid_pxl_reg_offset {
uint32_t format_measure_en_shift_val; uint32_t format_measure_en_shift_val;
uint32_t measure_en_hbi_vbi_cnt_val; uint32_t measure_en_hbi_vbi_cnt_val;
bool is_multi_vc_dt_supported; bool is_multi_vc_dt_supported;
uint32_t cgc_mode_en_shift_val;
}; };
struct cam_tfe_csid_rdi_reg_offset { 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_cfg0_addr;
uint32_t csid_rdi_cfg1_addr; uint32_t csid_rdi_cfg1_addr;
uint32_t csid_rdi_ctrl_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_rst_strobes_addr;
uint32_t csid_rdi_status_addr; uint32_t csid_rdi_status_addr;
uint32_t csid_rdi_misr_val0_addr; uint32_t csid_rdi_misr_val0_addr;
uint32_t csid_rdi_misr_val1_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_curr0_sof_addr;
uint32_t csid_rdi_timestamp_curr1_sof_addr; uint32_t csid_rdi_timestamp_curr1_sof_addr;
uint32_t csid_rdi_timestamp_prev0_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_ping_addr;
uint32_t csid_rdi_byte_cntr_pong_addr; uint32_t csid_rdi_byte_cntr_pong_addr;
uint32_t csid_rdi_multi_vcdt_cfg0_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 */ /* configuration */
uint32_t packing_format; uint32_t packing_format;
uint32_t format_measure_en_shift_val; uint32_t format_measure_en_shift_val;
uint32_t measure_en_hbi_vbi_cnt_val; uint32_t measure_en_hbi_vbi_cnt_val;
bool is_multi_vc_dt_supported; bool is_multi_vc_dt_supported;
uint32_t cgc_mode_en_shift_val;
}; };
struct cam_tfe_csid_csi2_rx_reg_offset { 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_irq_mask_all;
uint32_t csi2_misr_enable_shift_val; uint32_t csi2_misr_enable_shift_val;
uint32_t csi2_vc_mode_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_long_pkt_en_shift;
uint32_t csi2_capture_short_pkt_en_shift; uint32_t csi2_capture_short_pkt_en_shift;
uint32_t csi2_capture_cphy_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_long_pkt_hdr_rst_stb_shift;
uint32_t csi2_rx_short_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; uint32_t csi2_rx_cphy_pkt_hdr_rst_stb_shift;
bool need_to_sel_tpg_mux;
}; };
struct cam_tfe_csid_common_reg_offset { struct cam_tfe_csid_common_reg_offset {
@ -257,10 +286,12 @@ struct cam_tfe_csid_common_reg_offset {
uint32_t version_incr; uint32_t version_incr;
uint32_t num_rdis; uint32_t num_rdis;
uint32_t num_pix; uint32_t num_pix;
uint32_t num_ppp;
uint32_t csid_reg_rst_stb; uint32_t csid_reg_rst_stb;
uint32_t csid_rst_stb; uint32_t csid_rst_stb;
uint32_t csid_rst_stb_sw_all; uint32_t csid_rst_stb_sw_all;
uint32_t ipp_path_rst_stb_all; uint32_t ipp_path_rst_stb_all;
uint32_t ppp_path_rst_stb_all;
uint32_t rdi_path_rst_stb_all; uint32_t rdi_path_rst_stb_all;
uint32_t path_rst_done_shift_val; uint32_t path_rst_done_shift_val;
uint32_t path_en_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_h_en_shift_val;
uint32_t crop_shift; uint32_t crop_shift;
uint32_t ipp_irq_mask_all; uint32_t ipp_irq_mask_all;
uint32_t ppp_irq_mask_all;
uint32_t rdi_irq_mask_all; uint32_t rdi_irq_mask_all;
uint32_t top_tfe2_pix_pipe_fuse_reg; uint32_t top_tfe2_pix_pipe_fuse_reg;
uint32_t top_tfe2_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_height_mask_val;
uint32_t format_measure_width_mask_val; uint32_t format_measure_width_mask_val;
bool format_measure_support; 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_common_reg_offset *cmn_reg;
const struct cam_tfe_csid_csi2_rx_reg_offset *csi2_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 *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]; 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 * 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 * struct cam_tfe_csid_csi2_rx_cfg- csid csi2 rx configuration data
* @phy_sel: input resource type for sensor only * @phy_sel: input resource type for sensor only
* @lane_type: lane type: c-phy or d-phy * @lane_type: lane type: c-phy or d-phy
* @lane_num : active lane number * @lane_num : active lane number
* @lane_cfg: lane configurations: 4 bits per lane * @lane_cfg: lane configurations: 4 bits per lane
* @epd_supported: Flag to check if epd supported
* *
*/ */
struct cam_tfe_csid_csi2_rx_cfg { 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_type;
uint32_t lane_num; uint32_t lane_num;
uint32_t lane_cfg; uint32_t lane_cfg;
uint32_t epd_supported;
}; };
/** /**
@ -392,7 +455,8 @@ struct cam_tfe_csid_cid_data {
* one more frame than pix. * one more frame than pix.
* @res_sof_cnt path resource sof count value. it used for initial * @res_sof_cnt path resource sof count value. it used for initial
* frame drop * 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 cam_tfe_csid_path_cfg {
struct vc_dt_data vc_dt[CAM_ISP_TFE_VC_DT_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 usage_type;
uint32_t init_frame_drop; uint32_t init_frame_drop;
uint32_t res_sof_cnt; 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 * @in_res_id: csid in resource type
* @csi2_rx_cfg: csi2 rx decoder configuration for csid * @csi2_rx_cfg: csi2 rx decoder configuration for csid
* @csi2_rx_reserve_cnt: csi2 reservations count value * @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 * @ipp_res: image pixel path resource
* @ppp_res: PD pixel path resource
* @rdi_res: raw dump image path resources * @rdi_res: raw dump image path resources
* @cid_res: cid resources values * @cid_res: cid resources values
* @csid_top_reset_complete: csid top reset completion * @csid_top_reset_complete: csid top reset completion
* @csid_csi2_reset_complete: csi2 reset completion * @csid_csi2_reset_complete: csi2 reset completion
* @csid_ipp_reset_complete: ipp reset completion * @csid_ipp_reset_complete: ipp reset completion
* @csid_ppp_complete: ppp reset completion
* @csid_rdin_reset_complete: rdi n completion * @csid_rdin_reset_complete: rdi n completion
* @csid_debug: csid debug information to enable the SOT, EOT, * @csid_debug: csid debug information to enable the SOT, EOT,
* SOF, EOF, measure etc in the csid hw * SOF, EOF, measure etc in the csid hw
@ -477,6 +544,8 @@ struct cam_csid_evt_payload {
* or not * or not
* @prev_boot_timestamp previous frame bootime stamp * @prev_boot_timestamp previous frame bootime stamp
* @prev_qtimer_ts previous frame qtimer csid timestamp * @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 { struct cam_tfe_csid_hw {
@ -491,11 +560,13 @@ struct cam_tfe_csid_hw {
uint32_t csi2_reserve_cnt; uint32_t csi2_reserve_cnt;
uint32_t pxl_pipe_enable; uint32_t pxl_pipe_enable;
struct cam_isp_resource_node ipp_res; 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_isp_resource_node rdi_res[CAM_TFE_CSID_RDI_MAX];
struct cam_tfe_csid_cid_data cid_res[CAM_TFE_CSID_CID_MAX]; struct cam_tfe_csid_cid_data cid_res[CAM_TFE_CSID_CID_MAX];
struct completion csid_top_complete; struct completion csid_top_complete;
struct completion csid_csi2_complete; struct completion csid_csi2_complete;
struct completion csid_ipp_complete; struct completion csid_ipp_complete;
struct completion csid_ppp_complete;
struct completion csid_rdin_complete[CAM_TFE_CSID_RDI_MAX]; struct completion csid_rdin_complete[CAM_TFE_CSID_RDI_MAX];
uint64_t csid_debug; uint64_t csid_debug;
uint64_t clk_rate; uint64_t clk_rate;
@ -511,6 +582,8 @@ struct cam_tfe_csid_hw {
bool ppi_enable; bool ppi_enable;
uint64_t prev_boot_timestamp; uint64_t prev_boot_timestamp;
uint64_t prev_qtimer_ts; 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, 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 // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * 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/slab.h>
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <dt-bindings/msm-camera.h>
#include "cam_tfe_csid_core.h" #include "cam_tfe_csid_core.h"
#include "cam_tfe_csid_dev.h" #include "cam_tfe_csid_dev.h"
#include "cam_tfe_csid_hw_intf.h" #include "cam_tfe_csid_hw_intf.h"
#include "cam_debug_util.h" #include "cam_debug_util.h"
#include "camera_main.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] = { static struct cam_hw_intf *cam_tfe_csid_hw_list[CAM_TFE_CSID_HW_NUM_MAX] = {
0, 0, 0}; 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; struct cam_tfe_csid_hw *csid_dev = NULL;
const struct of_device_id *match_dev = NULL; const struct of_device_id *match_dev = NULL;
struct cam_tfe_csid_hw_info *csid_hw_data = 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; int rc = 0;
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
CAM_DBG(CAM_ISP, "probe called"); 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); csid_hw_intf = kzalloc(sizeof(*csid_hw_intf), GFP_KERNEL);
if (!csid_hw_intf) { if (!csid_hw_intf) {
rc = -ENOMEM; rc = -ENOMEM;
@ -48,8 +64,6 @@ static int cam_tfe_csid_component_bind(struct device *dev,
goto free_hw_info; 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 */ /* get tfe csid hw information */
match_dev = of_match_device(pdev->dev.driver->of_match_table, match_dev = of_match_device(pdev->dev.driver->of_match_table,
&pdev->dev); &pdev->dev);
@ -107,6 +121,12 @@ void cam_tfe_csid_component_unbind(struct device *dev,
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
csid_dev = (struct cam_tfe_csid_hw *)platform_get_drvdata(pdev); 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_intf = csid_dev->hw_intf;
csid_hw_info = csid_dev->hw_info; 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; soc_info->soc_private = soc_private;
rc = cam_soc_util_get_dt_properties(soc_info); rc = cam_soc_util_get_dt_properties(soc_info);
if (rc < 0) if (rc < 0)
return rc; 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++) for (i = 0; i < soc_info->irq_count; i++)
irq_data[i] = data; 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 */ /* 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])); rc = cam_soc_util_request_platform_resource(soc_info, csid_irq_handler, &(irq_data[0]));
if (rc < 0) { if (rc < 0) {

View File

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

View File

@ -1,11 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * 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 <linux/module.h>
#include "cam_tfe530.h" #include "cam_tfe530.h"
#include "cam_tfe640.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_hw_intf.h"
#include "cam_tfe_core.h" #include "cam_tfe_core.h"
#include "cam_tfe_dev.h" #include "cam_tfe_dev.h"
@ -20,6 +25,22 @@ static const struct of_device_id cam_tfe_dt_match[] = {
.compatible = "qcom,tfe640", .compatible = "qcom,tfe640",
.data = &cam_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); 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, .stats_feature = 0x0000100C,
.zoom_feature = 0x00001010, .zoom_feature = 0x00001010,
.global_reset_cmd = 0x00001014, .global_reset_cmd = 0x00001014,
.core_cgc_ctrl = 0x00001018, .core_cgc_ctrl_0 = 0x00001018,
.ahb_cgc_ctrl = 0x0000101C, .ahb_cgc_ctrl = 0x0000101C,
.core_cfg_0 = 0x00001024, .core_cfg_0 = 0x00001024,
.core_cfg_1 = 0x00001028, .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_neq_hbi_shift = 14,
.diag_sensor_hbi_mask = 0x3FFF, .diag_sensor_hbi_mask = 0x3FFF,
.serializer_supported = false, .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 = { 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, .enable_diagnostic_hw = 0x1,
.diag_sensor_sel = 0x3, .diag_sensor_sel = 0x3,
.diag_sensor_shift = 0x1, .diag_sensor_shift = 0x1,
}; };
static struct cam_tfe_clc_hw_status tfe530_clc_hw_info[CAM_TFE_MAX_CLC] = { 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, .max_bw_counter_limit = 0xFF,
.counter_limit_shift = 1, .counter_limit_shift = 1,
.counter_limit_mask = 0xF, .counter_limit_mask = 0xF,
.mode_cfg_shift = 16,
.height_shift = 16,
}; };
struct cam_tfe_hw_info cam_tfe530 = { 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, .stats_feature = 0x0000180C,
.zoom_feature = 0x00001810, .zoom_feature = 0x00001810,
.global_reset_cmd = 0x00001814, .global_reset_cmd = 0x00001814,
.core_cgc_ctrl = 0x00001818, .core_cgc_ctrl_0 = 0x00001818,
.ahb_cgc_ctrl = 0x0000181C, .ahb_cgc_ctrl = 0x0000181C,
.core_cfg_0 = 0x00001824, .core_cfg_0 = 0x00001824,
.reg_update_cmd = 0x0000182C, .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_neq_hbi_shift = 14,
.diag_sensor_hbi_mask = 0x3FFF, .diag_sensor_hbi_mask = 0x3FFF,
.serializer_supported = true, .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 = { 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, .enable_diagnostic_hw = 0x1,
.diag_sensor_sel = 0x3, .diag_sensor_sel = 0x3,
.diag_sensor_shift = 0x1, .diag_sensor_shift = 0x1,
}; };
static struct cam_tfe_clc_hw_status tfe640_clc_hw_info[CAM_TFE_MAX_CLC] = { 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, .max_bw_counter_limit = 0xFF,
.counter_limit_shift = 1, .counter_limit_shift = 1,
.counter_limit_mask = 0xF, .counter_limit_mask = 0xF,
.mode_cfg_shift = 16,
.height_shift = 16,
}; };
struct cam_tfe_hw_info cam_tfe640 = { 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 // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * 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> #include <linux/ratelimit.h>
@ -71,6 +71,8 @@ struct cam_tfe_bus_common_data {
uint32_t num_sec_out; uint32_t num_sec_out;
uint32_t comp_done_shift; uint32_t comp_done_shift;
uint32_t rdi_width; uint32_t rdi_width;
uint32_t mode_cfg_shift;
uint32_t height_shift;
bool is_lite; bool is_lite;
bool support_consumed_addr; bool support_consumed_addr;
cam_hw_mgr_event_cb_func event_cb; 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 max_bw_counter_limit;
uint32_t counter_limit_shift; uint32_t counter_limit_shift;
uint32_t counter_limit_mask; uint32_t counter_limit_mask;
uint32_t pack_align_shift;
}; };
struct cam_tfe_bus_wm_resource_data { 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_width;
uint32_t acquired_height; uint32_t acquired_height;
uint32_t acquired_stride; uint32_t acquired_stride;
uint32_t buffer_offset;
bool is_buffer_aligned;
bool limiter_blob_status; bool limiter_blob_status;
bool is_dim_update;
}; };
struct cam_tfe_bus_comp_grp_data { struct cam_tfe_bus_comp_grp_data {
@ -152,6 +160,7 @@ struct cam_tfe_bus_tfe_out_data {
void *priv; void *priv;
cam_hw_mgr_event_cb_func event_cb; cam_hw_mgr_event_cb_func event_cb;
uint32_t mid[CAM_TFE_BUS_MAX_MID_PER_PORT]; uint32_t mid[CAM_TFE_BUS_MAX_MID_PER_PORT];
uint64_t pid_mask;
}; };
struct cam_tfe_bus_priv { struct cam_tfe_bus_priv {
@ -173,6 +182,7 @@ struct cam_tfe_bus_priv {
uint32_t comp_buf_done_mask; uint32_t comp_buf_done_mask;
uint32_t comp_rup_done_mask; uint32_t comp_rup_done_mask;
uint32_t bus_irq_error_mask[CAM_TFE_BUS_IRQ_REGISTERS_MAX]; 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) 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_DS4:
case CAM_TFE_BUS_TFE_OUT_DS16: case CAM_TFE_BUS_TFE_OUT_DS16:
case CAM_TFE_BUS_TFE_OUT_AI: 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; return true;
case CAM_TFE_BUS_TFE_OUT_STATS_HDR_BE: 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; return CAM_TFE_BUS_TFE_OUT_DS16;
case CAM_ISP_TFE_OUT_RES_AI: case CAM_ISP_TFE_OUT_RES_AI:
return CAM_TFE_BUS_TFE_OUT_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: default:
return CAM_TFE_BUS_TFE_OUT_MAX; return CAM_TFE_BUS_TFE_OUT_MAX;
} }
@ -323,7 +342,7 @@ static int cam_tfe_bus_get_num_wm(
switch (format) { switch (format) {
case CAM_FORMAT_NV12: case CAM_FORMAT_NV12:
case CAM_FORMAT_TP10: case CAM_FORMAT_TP10:
case CAM_FORMAT_PD10: case CAM_FORMAT_PLAIN16_10:
return 2; return 2;
default: default:
break; break;
@ -350,6 +369,17 @@ static int cam_tfe_bus_get_num_wm(
break; break;
} }
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: default:
break; break;
} }
@ -360,6 +390,47 @@ static int cam_tfe_bus_get_num_wm(
return -EINVAL; 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( static int cam_tfe_bus_get_wm_idx(
enum cam_tfe_bus_tfe_out_id tfe_out_res_id, enum cam_tfe_bus_tfe_out_id tfe_out_res_id,
enum cam_tfe_bus_plane_type plane, enum cam_tfe_bus_plane_type plane,
@ -510,6 +581,33 @@ static int cam_tfe_bus_get_wm_idx(
break; break;
} }
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: default:
break; break;
} }
@ -561,6 +659,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
{ {
int pack_fmt = 0; int pack_fmt = 0;
int rdi_width = rsrc_data->common_data->rdi_width; int rdi_width = rsrc_data->common_data->rdi_width;
int mode_cfg_shift = rsrc_data->common_data->mode_cfg_shift;
if (rdi_width == 64) if (rdi_width == 64)
pack_fmt = 0xa; pack_fmt = 0xa;
@ -581,7 +680,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0; rsrc_data->height = 0;
rsrc_data->stride = rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE; CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1; rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
} }
break; break;
case CAM_FORMAT_MIPI_RAW_8: case CAM_FORMAT_MIPI_RAW_8:
@ -598,7 +697,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0; rsrc_data->height = 0;
rsrc_data->stride = rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE; CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1; rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
} }
break; break;
case CAM_FORMAT_MIPI_RAW_10: case CAM_FORMAT_MIPI_RAW_10:
@ -614,7 +713,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0; rsrc_data->height = 0;
rsrc_data->stride = rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE; CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1; rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
} }
break; break;
case CAM_FORMAT_MIPI_RAW_12: case CAM_FORMAT_MIPI_RAW_12:
@ -630,7 +729,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0; rsrc_data->height = 0;
rsrc_data->stride = rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE; CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1; rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
} }
break; break;
case CAM_FORMAT_MIPI_RAW_14: case CAM_FORMAT_MIPI_RAW_14:
@ -646,7 +745,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0; rsrc_data->height = 0;
rsrc_data->stride = rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE; CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1; rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
} }
break; break;
case CAM_FORMAT_PLAIN16_10: case CAM_FORMAT_PLAIN16_10:
@ -666,7 +765,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0; rsrc_data->height = 0;
rsrc_data->stride = rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE; CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1; rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
} }
break; break;
@ -684,7 +783,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
rsrc_data->height = 0; rsrc_data->height = 0;
rsrc_data->stride = rsrc_data->stride =
CAM_TFE_RDI_BUS_DEFAULT_STRIDE; CAM_TFE_RDI_BUS_DEFAULT_STRIDE;
rsrc_data->en_cfg = (0x1 << 16) | 0x1; rsrc_data->en_cfg = (0x1 << mode_cfg_shift) | 0x1;
} }
break; break;
default: default:
@ -711,14 +810,16 @@ static int cam_tfe_bus_acquire_wm(
struct cam_tfe_bus_wm_resource_data *rsrc_data = NULL; struct cam_tfe_bus_wm_resource_data *rsrc_data = NULL;
uint32_t wm_idx = 0; uint32_t wm_idx = 0;
int rc = 0; int rc = 0;
*wm_res = NULL; *wm_res = NULL;
/* No need to allocate for BUS TFE OUT to WM is fixed. */ /* 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, if (bus_priv->common_data.is_lite)
bus_priv->common_data.pdaf_rdi2_mux_en); 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) { if (wm_idx < 0 || wm_idx >= bus_priv->num_client) {
CAM_ERR(CAM_ISP, "Unsupported TFE out %d plane %d", CAM_ERR(CAM_ISP, "Unsupported TFE out %d plane %d wm id %d num client %d",
tfe_out_res_id, plane); tfe_out_res_id, plane, wm_idx, bus_priv->num_client);
return -EINVAL; return -EINVAL;
} }
@ -754,8 +855,8 @@ static int cam_tfe_bus_acquire_wm(
/* Set WM offset value to default */ /* Set WM offset value to default */
rsrc_data->offset = 0; rsrc_data->offset = 0;
if (((rsrc_data->index >= 7) && (rsrc_data->index <= 9)) && if (bus_priv->common_data.is_lite || (((rsrc_data->index >= 7) &&
(tfe_out_res_id != CAM_TFE_BUS_TFE_OUT_PDAF)) { (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 */ /* WM 7-9 refers to RDI 0/ RDI 1/RDI 2 */
rc = cam_tfe_bus_acquire_rdi_wm(rsrc_data); rc = cam_tfe_bus_acquire_rdi_wm(rsrc_data);
if (rc) if (rc)
@ -781,6 +882,21 @@ static int cam_tfe_bus_acquire_wm(
case CAM_FORMAT_PLAIN16_10: case CAM_FORMAT_PLAIN16_10:
rsrc_data->pack_fmt = 0x5; rsrc_data->pack_fmt = 0x5;
rsrc_data->pack_fmt |= 0x10; 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; break;
case CAM_FORMAT_PLAIN16_12: case CAM_FORMAT_PLAIN16_12:
rsrc_data->pack_fmt = 0x6; rsrc_data->pack_fmt = 0x6;
@ -818,11 +934,52 @@ static int cam_tfe_bus_acquire_wm(
rsrc_data->width = 0; rsrc_data->width = 0;
rsrc_data->height = 0; rsrc_data->height = 0;
rsrc_data->stride = 1; 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*/ /*RS state packet format*/
if (rsrc_data->index == 15) if (rsrc_data->index == 15)
rsrc_data->pack_fmt = 0x9; 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 { } else {
CAM_ERR(CAM_ISP, "Invalid WM:%d requested", rsrc_data->index); CAM_ERR(CAM_ISP, "Invalid WM:%d requested", rsrc_data->index);
return -EINVAL; return -EINVAL;
@ -859,6 +1016,8 @@ static int cam_tfe_bus_release_wm(void *bus_priv,
rsrc_data->en_cfg = 0; rsrc_data->en_cfg = 0;
rsrc_data->is_dual = 0; rsrc_data->is_dual = 0;
rsrc_data->limiter_blob_status = false; rsrc_data->limiter_blob_status = false;
rsrc_data->is_buffer_aligned = false;
rsrc_data->buffer_offset = 0;
wm_res->tasklet_info = NULL; wm_res->tasklet_info = NULL;
wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; 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; wm_res->res_priv;
struct cam_tfe_bus_common_data *common_data = struct cam_tfe_bus_common_data *common_data =
rsrc_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 */ /* Skip to overwrite if wm bandwidth limiter blob already sent */
if (!rsrc_data->limiter_blob_status) if (!rsrc_data->limiter_blob_status)
cam_io_w(rsrc_data->common_data->counter_limit_mask, cam_io_w(rsrc_data->common_data->counter_limit_mask,
common_data->mem_base + rsrc_data->hw_regs->bw_limit); 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); common_data->mem_base + rsrc_data->hw_regs->image_cfg_0);
cam_io_w(rsrc_data->pack_fmt, cam_io_w(rsrc_data->pack_fmt,
common_data->mem_base + rsrc_data->hw_regs->packer_cfg); 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); 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", CAM_DBG(CAM_ISP, "TFE:%d WM:%d width = %d, height = %d",
common_data->core_index, rsrc_data->index, common_data->core_index, rsrc_data->index,
rsrc_data->width, rsrc_data->height); 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); INIT_LIST_HEAD(&comp_grp->list);
comp_grp->res_id = index; 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->common_data = &bus_priv->common_data;
rsrc_data->max_wm_per_comp_grp = rsrc_data->max_wm_per_comp_grp =
bus_priv->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++) 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->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; tfe_out->hw_intf = bus_priv->common_data.hw_intf;
return 0; return 0;
@ -1745,6 +1906,8 @@ static const char *cam_tfe_bus_rup_type(
return "RDI1 RUP"; return "RDI1 RUP";
case CAM_ISP_HW_TFE_IN_RDI2: case CAM_ISP_HW_TFE_IN_RDI2:
return "RDI2 RUP"; return "RDI2 RUP";
case CAM_ISP_HW_TFE_IN_PDLIB:
return "PDLIB RUP";
default: default:
return "invalid rup group"; 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_bus_priv *bus_priv,
struct cam_tfe_irq_evt_payload *evt_payload) 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 = NULL;
struct cam_tfe_bus_tfe_out_data *out_rsrc_data;
struct cam_isp_hw_event_info evt_info; struct cam_isp_hw_event_info evt_info;
uint32_t i, j; uint32_t i, j;
common_data = &bus_priv->common_data;
evt_info.hw_idx = bus_priv->common_data.core_index; evt_info.hw_idx = bus_priv->common_data.core_index;
evt_info.res_type = CAM_ISP_RESOURCE_TFE_OUT; evt_info.res_type = CAM_ISP_RESOURCE_TFE_OUT;
@ -1768,17 +1929,20 @@ static int cam_tfe_bus_rup_bottom_half(
break; break;
if (evt_payload->bus_irq_val[0] & BIT(i)) { 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 = out_rsrc_data =
(struct cam_tfe_bus_tfe_out_data *) (struct cam_tfe_bus_tfe_out_data *)
bus_priv->tfe_out[j].res_priv; bus_priv->tfe_out[j].res_priv;
if (!out_rsrc_data)
break;
if ((out_rsrc_data->rup_group_id == i) && if ((out_rsrc_data->rup_group_id == i) &&
(bus_priv->tfe_out[j].res_state == (bus_priv->tfe_out[j].res_state ==
CAM_ISP_RESOURCE_STATE_STREAMING)) CAM_ISP_RESOURCE_STATE_STREAMING))
break; break;
} }
if (j == CAM_TFE_BUS_TFE_OUT_MAX) { if (j == bus_priv->num_out) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"TFE:%d out rsc active status[0]:0x%x", "TFE:%d out rsc active status[0]:0x%x",
bus_priv->common_data.core_index, bus_priv->common_data.core_index,
@ -1790,6 +1954,13 @@ static int cam_tfe_bus_rup_bottom_half(
bus_priv->common_data.core_index, bus_priv->common_data.core_index,
cam_tfe_bus_rup_type(i)); cam_tfe_bus_rup_type(i));
evt_info.res_id = 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) { if (out_rsrc_data->event_cb) {
out_rsrc_data->event_cb( out_rsrc_data->event_cb(
out_rsrc_data->priv, 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_isp_resource_node *rsrc_node = NULL;
struct cam_tfe_bus_tfe_out_data *rsrc_data = NULL; struct cam_tfe_bus_tfe_out_data *rsrc_data = NULL;
struct cam_tfe_bus_wm_resource_data *wm_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); CAM_ERR(CAM_ISP, "invalid out_id:%u", out_id);
return 0; 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; rsrc_data = rsrc_node->res_priv;
wm_rsrc_data = rsrc_data->wm_res[PLANE_Y]->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->common_data->mem_base +
wm_rsrc_data->hw_regs->addr_status_0); 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; 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_tfe_bus_comp_grp_data *comp_rsrc_data;
struct cam_isp_hw_bufdone_event_info bufdone_evt_info = {0}; struct cam_isp_hw_bufdone_event_info bufdone_evt_info = {0};
uint32_t i; uint32_t i;
struct cam_tfe_bus_wm_resource_data *wm_rsrc_data = NULL;
common_data = &bus_priv->common_data; 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 *) comp_rsrc_data = (struct cam_tfe_bus_comp_grp_data *)
bus_priv->comp_grp[i].res_priv; 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] & if (evt_payload->bus_irq_val[0] &
BIT(comp_rsrc_data->comp_grp_id + BIT(comp_rsrc_data->comp_grp_id +
bus_priv->common_data.comp_done_shift)) { bus_priv->common_data.comp_done_shift)) {
out_rsrc = comp_rsrc_data->out_rsrc[0]; out_rsrc = comp_rsrc_data->out_rsrc[0];
out_rsrc_data = out_rsrc->res_priv; out_rsrc_data = out_rsrc->res_priv;
evt_info.res_type = out_rsrc->res_type; evt_info.res_type = out_rsrc->res_type;
evt_info.hw_idx = out_rsrc->hw_intf->hw_idx; evt_info.hw_idx = out_rsrc->hw_intf->hw_idx;
evt_info.res_id = out_rsrc->res_id; evt_info.res_id = out_rsrc->res_id;
bufdone_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.comp_grp_id = comp_rsrc_data->comp_grp_id;
bufdone_evt_info.last_consumed_addr = wm_rsrc_data = out_rsrc_data->wm_res[PLANE_Y]->res_priv;
cam_tfe_bus_get_last_consumed_addr( bufdone_evt_info.last_consumed_addr = cam_io_r_mb(
out_rsrc_data->bus_priv, wm_rsrc_data->common_data->mem_base +
out_rsrc_data->out_id); wm_rsrc_data->hw_regs->addr_status_0);
evt_info.event_data = (void *)&bufdone_evt_info; evt_info.event_data = (void *)&bufdone_evt_info;
if (out_rsrc_data->event_cb) if (out_rsrc_data->event_cb)
out_rsrc_data->event_cb(out_rsrc_data->priv, out_rsrc_data->event_cb(out_rsrc_data->priv,
CAM_ISP_HW_EVENT_DONE, CAM_ISP_HW_EVENT_DONE,
(void *)&evt_info); (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; 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, static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
uint32_t arg_size) 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_buf_io_cfg *io_cfg;
struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL; struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL;
struct cam_tfe_bus_wm_resource_data *wm_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 *reg_val_pair;
uint32_t num_regval_pairs = 0; uint32_t num_regval_pairs = 0;
uint32_t i, j, size = 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 *) tfe_out_data = (struct cam_tfe_bus_tfe_out_data *)
update_buf->res->res_priv; update_buf->res->res_priv;
cdm_util_ops = tfe_out_data->cdm_util_ops; if (!tfe_out_data || !(tfe_out_data->cdm_util_ops)) {
CAM_ERR(CAM_ISP, "Failed! invalid data");
if (!tfe_out_data || !cdm_util_ops) {
CAM_ERR(CAM_ISP, "Failed! Invalid data");
return -EINVAL; return -EINVAL;
} }
cdm_util_ops = tfe_out_data->cdm_util_ops;
if (update_buf->wm_update->num_buf != tfe_out_data->num_wm) { if (update_buf->wm_update->num_buf != tfe_out_data->num_wm) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"Failed! Invalid number buffers:%d required:%d", "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; wm_data = tfe_out_data->wm_res[i]->res_priv;
/* update width register */ /* 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, CAM_TFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->image_cfg_0, val); wm_data->hw_regs->image_cfg_0, val);
CAM_DBG(CAM_ISP, "WM:%d image height and width 0x%x", 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) && if ((wm_data->index < 7) || ((wm_data->index >= 7) &&
(wm_data->mode == CAM_ISP_TFE_WM_LINE_BASED_MODE)) || (wm_data->mode == CAM_ISP_TFE_WM_LINE_BASED_MODE)) ||
(wm_data->out_id == CAM_TFE_BUS_TFE_OUT_PDAF) || (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, CAM_TFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->image_cfg_2, wm_data->hw_regs->image_cfg_2,
io_cfg->planes[i].plane_stride); 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 * frame_inc = io_cfg->planes[i].plane_stride *
io_cfg->planes[i].slice_height; 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, CAM_TFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->image_addr, wm_data->hw_regs->image_addr,
update_buf->wm_update->image_buf[i]); 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; 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, static int cam_tfe_bus_update_hfr(void *priv, void *cmd_args,
uint32_t arg_size) 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_isp_hw_get_cmd_update *update_hfr;
struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL; struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL;
struct cam_tfe_bus_wm_resource_data *wm_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; struct cam_isp_tfe_port_hfr_config *hfr_cfg = NULL;
uint32_t *reg_val_pair; uint32_t *reg_val_pair;
uint32_t num_regval_pairs = 0; 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 *) tfe_out_data = (struct cam_tfe_bus_tfe_out_data *)
update_hfr->res->res_priv; update_hfr->res->res_priv;
cdm_util_ops = tfe_out_data->cdm_util_ops; if (!tfe_out_data || !(tfe_out_data->cdm_util_ops)) {
CAM_ERR(CAM_ISP, "Failed! invalid data");
if (!tfe_out_data || !cdm_util_ops) {
CAM_ERR(CAM_ISP, "Failed! Invalid data");
return -EINVAL; return -EINVAL;
} }
cdm_util_ops = tfe_out_data->cdm_util_ops;
reg_val_pair = &tfe_out_data->common_data->io_buf_update[0]; reg_val_pair = &tfe_out_data->common_data->io_buf_update[0];
hfr_cfg = (struct cam_isp_tfe_port_hfr_config *)update_hfr->data; 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_update =
(struct cam_isp_hw_get_cmd_update *)cmd_args; (struct cam_isp_hw_get_cmd_update *)cmd_args;
struct cam_isp_hw_get_res_for_mid *get_res = NULL; 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; int i, j;
bool pid_found = false;
get_res = (struct cam_isp_hw_get_res_for_mid *)cmd_update->data; get_res = (struct cam_isp_hw_get_res_for_mid *)cmd_update->data;
if (!get_res) { 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++) { for (j = 0; j < CAM_TFE_BUS_MAX_MID_PER_PORT; j++) {
if (tfe_out_data->mid[j] == get_res->mid) 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, CAM_ERR(CAM_ISP,
"mid:%d does not match with any out resource", "mid:%d does not match with any out resource",
get_res->mid); get_res->mid);
@ -2326,9 +2651,8 @@ static int cam_tfe_bus_get_res_id_for_mid(
} }
end: end:
CAM_INFO(CAM_ISP, "match mid :%d out resource:%d found", CAM_INFO(CAM_ISP, "match mid :%d out resource:%d found, is pid found %d",
get_res->mid, bus_priv->tfe_out[i].res_id); get_res->mid, get_res->out_res_id, pid_found);
get_res->out_res_id = bus_priv->tfe_out[i].res_id;
return 0; return 0;
} }
@ -2549,15 +2873,49 @@ static int cam_tfe_bus_deinit_hw(void *hw_priv,
return rc; 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, static int cam_tfe_bus_process_cmd(void *priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size) uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{ {
struct cam_tfe_bus_priv *bus_priv; struct cam_tfe_bus_priv *bus_priv;
int rc = -EINVAL; int rc = 0;
uint32_t i, val; uint32_t i, val;
bool *support_consumed_addr;
bool *pdaf_rdi2_mux_en; bool *pdaf_rdi2_mux_en;
struct cam_isp_hw_done_event_data *done; struct cam_isp_hw_done_event_data *done;
struct cam_isp_hw_cap *tfe_bus_cap;
if (!priv || !cmd_args) { if (!priv || !cmd_args) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid input arguments"); 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]); bus_priv->common_data.common_reg->irq_mask[i]);
} }
break; 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; bus_priv = (struct cam_tfe_bus_priv *) priv;
support_consumed_addr = (bool *)cmd_args; tfe_bus_cap = (struct cam_isp_hw_cap *) cmd_args;
*support_consumed_addr = 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; bus_priv->common_data.support_consumed_addr;
break; break;
case CAM_ISP_HW_CMD_GET_RES_FOR_MID: 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( done->last_consumed_addr = cam_tfe_bus_get_last_consumed_addr(
bus_priv, done->resource_handle); bus_priv, done->resource_handle);
break; 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: default:
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d", CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
cmd_type); cmd_type);
rc = -EINVAL;
break; break;
} }
@ -2635,6 +3007,7 @@ int cam_tfe_bus_init(
struct cam_tfe_bus_priv *bus_priv = NULL; struct cam_tfe_bus_priv *bus_priv = NULL;
struct cam_tfe_bus *tfe_bus_local; struct cam_tfe_bus *tfe_bus_local;
struct cam_tfe_bus_hw_info *hw_info = bus_hw_info; 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) { if (!soc_info || !hw_intf || !bus_hw_info) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
@ -2644,6 +3017,13 @@ int cam_tfe_bus_init(
goto end; 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); tfe_bus_local = kzalloc(sizeof(struct cam_tfe_bus), GFP_KERNEL);
if (!tfe_bus_local) { if (!tfe_bus_local) {
CAM_DBG(CAM_ISP, "Failed to alloc for tfe_bus"); 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->num_comp_grp = hw_info->num_comp_grp;
bus_priv->max_wm_per_comp_grp = hw_info->max_wm_per_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->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.comp_done_shift = hw_info->comp_done_shift;
bus_priv->common_data.num_sec_out = 0; 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.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_shift = hw_info->counter_limit_shift;
bus_priv->common_data.counter_limit_mask = hw_info->counter_limit_mask; 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++) for (i = 0; i < CAM_TFE_BUS_IRQ_REGISTERS_MAX; i++)
bus_priv->bus_irq_error_mask[i] = bus_priv->bus_irq_error_mask[i] =
hw_info->bus_irq_error_mask[i]; hw_info->bus_irq_error_mask[i];
if (strnstr(soc_info->compatible, "lite", bus_priv->common_data.is_lite = soc_private->is_tfe_lite;
strlen(soc_info->compatible)) != NULL)
bus_priv->common_data.is_lite = true;
else
bus_priv->common_data.is_lite = false;
for (i = 0; i < CAM_TFE_BUS_RUP_GRP_MAX; i++) for (i = 0; i < CAM_TFE_BUS_RUP_GRP_MAX; i++)
bus_priv->common_data.rup_irq_enable[i] = false; 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); "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( rc = cam_tfe_bus_deinit_tfe_out_resource(
&bus_priv->tfe_out[i]); &bus_priv->tfe_out[i]);
if (rc < 0) if (rc < 0)

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * 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_isp_hw.h"
#include "cam_tfe_hw_intf.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_SUB_GRPS 4
#define CAM_TFE_BUS_MAX_PERF_CNT_REG 8 #define CAM_TFE_BUS_MAX_PERF_CNT_REG 8
#define CAM_TFE_BUS_MAX_IRQ_REGISTERS 2 #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_8,
CAM_TFE_BUS_COMP_GRP_9, CAM_TFE_BUS_COMP_GRP_9,
CAM_TFE_BUS_COMP_GRP_10, CAM_TFE_BUS_COMP_GRP_10,
CAM_TFE_BUS_COMP_GRP_11,
CAM_TFE_BUS_COMP_GRP_MAX, 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_1,
CAM_TFE_BUS_RUP_GRP_2, CAM_TFE_BUS_RUP_GRP_2,
CAM_TFE_BUS_RUP_GRP_3, CAM_TFE_BUS_RUP_GRP_3,
CAM_TFE_BUS_RUP_GRP_4,
CAM_TFE_BUS_RUP_GRP_MAX, 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_DS4,
CAM_TFE_BUS_TFE_OUT_DS16, CAM_TFE_BUS_TFE_OUT_DS16,
CAM_TFE_BUS_TFE_OUT_AI, 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, 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 irq_subsample_pattern;
uint32_t framedrop_period; uint32_t framedrop_period;
uint32_t framedrop_pattern; uint32_t framedrop_pattern;
uint32_t system_cache_cfg;
uint32_t addr_status_0; uint32_t addr_status_0;
uint32_t addr_status_1; uint32_t addr_status_1;
uint32_t addr_status_2; 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: * struct cam_tfe_bus_tfe_out_hw_info:
* *
* @Brief: HW capability of TFE Bus Client * @Brief: HW capability of TFE Bus Client
* tfe_out_id Tfe out port id * tfe_out_id: Tfe out port id
* max_width Max width supported by the outport * max_width: Max width supported by the outport
* max_height Max height supported by outport * max_height: Max height supported by outport
* composite_group Out port composite group id * composite_group: Out port composite group id
* rup_group_id Reg update group of outport id * rup_group_id: Reg update group of outport id
* mid: ouport mid value * mid: ouport mid value
* pid: pid associated with mid
*/ */
struct cam_tfe_bus_tfe_out_hw_info { struct cam_tfe_bus_tfe_out_hw_info {
enum cam_tfe_bus_tfe_out_id tfe_out_id; 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 composite_group;
uint32_t rup_group_id; uint32_t rup_group_id;
uint32_t mid[CAM_TFE_BUS_MAX_MID_PER_PORT]; 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 * @num_comp_grp: Number of composite group
* @max_wm_per_comp_grp: Max number of wm associated with one 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 * @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 * @top_bus_wr_irq_shift: Mask shift for top level BUS WR irq
* @comp_buf_done_mask: Composite buf done bits mask * @comp_buf_done_mask: Composite buf done bits mask
* @comp_rup_done_mask: Reg update done 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 * @max_bw_counter_limit: Max BW counter limit
* @counter_limit_shift: Mask shift for BW counter limit * @counter_limit_shift: Mask shift for BW counter limit
* @counter_limit_mask: Default Mask of BW limit counter * @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_hw_info {
struct cam_tfe_bus_reg_offset_common common_reg; 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 num_comp_grp;
uint32_t max_wm_per_comp_grp; uint32_t max_wm_per_comp_grp;
uint32_t comp_done_shift; uint32_t comp_done_shift;
uint32_t mode_cfg_shift;
uint32_t height_shift;
uint32_t top_bus_wr_irq_shift; uint32_t top_bus_wr_irq_shift;
uint32_t comp_buf_done_mask; uint32_t comp_buf_done_mask;
uint32_t comp_rup_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 max_bw_counter_limit;
uint32_t counter_limit_shift; uint32_t counter_limit_shift;
uint32_t counter_limit_mask; 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