Add 'techpack/camera/' from tag 'LA.UM.9.14.r1-18300-LAHAINA.0'

git-subtree-dir: techpack/camera
git-subtree-mainline: 8051403212
git-subtree-split: 702b632d40
Change-Id: If66513d1d1363aba05aa7b5457e54d0ac051b190
This commit is contained in:
Michael Bestas 2022-05-19 00:02:58 +03:00
commit 39f18e3259
No known key found for this signature in database
GPG key ID: CC95044519BE6669
478 changed files with 231390 additions and 0 deletions

101
techpack/camera/Makefile Normal file
View file

@ -0,0 +1,101 @@
# SPDX-License-Identifier: GPL-2.0-only
# auto-detect subdirs
ifneq ($(CONFIG_ARCH_QTI_VM), y)
ifeq ($(CONFIG_ARCH_KONA), y)
include $(srctree)/techpack/camera/config/konacamera.conf
endif
ifeq ($(CONFIG_ARCH_LITO), y)
include $(srctree)/techpack/camera/config/litocamera.conf
endif
ifeq ($(CONFIG_ARCH_BENGAL), y)
include $(srctree)/techpack/camera/config/bengalcamera.conf
endif
ifeq ($(CONFIG_ARCH_MONACO), y)
include $(srctree)/techpack/camera/config/monacocamera.conf
endif
ifeq ($(CONFIG_ARCH_LAHAINA), y)
include $(srctree)/techpack/camera/config/lahainacamera.conf
endif
ifeq ($(CONFIG_ARCH_HOLI), y)
include $(srctree)/techpack/camera/config/holicamera.conf
endif
ifeq ($(CONFIG_ARCH_BLAIR), y)
include $(srctree)/techpack/camera/config/blaircamera.conf
endif
ifeq ($(CONFIG_ARCH_SHIMA), y)
include $(srctree)/techpack/camera/config/shimacamera.conf
endif
ifeq ($(CONFIG_ARCH_YUPIK), y)
include $(srctree)/techpack/camera/config/yupikcamera.conf
endif
ifeq ($(CONFIG_ARCH_KONA), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/konacameraconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/litocameraconf.h
endif
ifeq ($(CONFIG_ARCH_BENGAL), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/bengalcameraconf.h
endif
ifeq ($(CONFIG_ARCH_MONACO), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/monacocameraconf.h
endif
ifeq ($(CONFIG_ARCH_LAHAINA), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/lahainacameraconf.h
endif
ifeq ($(CONFIG_ARCH_HOLI), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/holicameraconf.h
endif
ifeq ($(CONFIG_ARCH_BLAIR), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/blaircameraconf.h
endif
ifeq ($(CONFIG_ARCH_SHIMA), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/shimacameraconf.h
endif
ifeq ($(CONFIG_ARCH_YUPIK), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/camera/config/yupikcameraconf.h
endif
endif
ifneq (,$(filter $(CONFIG_SPECTRA_CAMERA), y m))
# Use USERINCLUDE when you must reference the UAPI directories only.
USERINCLUDE += \
-I$(srctree)/techpack/camera/include/uapi
# Use LINUXINCLUDE when you must reference the include/ directory.
# Needed to be compatible with the O= option
LINUXINCLUDE += \
-I$(srctree)/techpack/camera/include/uapi \
-I$(srctree)/techpack/camera/include
obj-y += drivers/
else
$(info Target not found)
endif

View file

@ -0,0 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2019,2021 The Linux Foundation. All rights reserved.
$(info "BENGAL SPECTRA_CAMERA IS MODULAR")
export CONFIG_SPECTRA_CAMERA=m
ifneq (,$(filter $(CONFIG_SPECTRA_CAMERA), y m))
export CONFIG_SPECTRA_TFE=y
export CONFIG_SPECTRA_ISP=y
export CONFIG_SPECTRA_SENSOR=y
export CONFIG_SPECTRA_OPE=y
endif

View file

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

View file

@ -0,0 +1,17 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2021, The Linux Foundation. All rights reserved.
ifeq ($(CONFIG_QGKI),y)
export CONFIG_SPECTRA_CAMERA=m
$(info "SPECTRA_CAMERA IS STATIC")
else
$(info "SPECTRA_CAMERA IS MODULAR")
export CONFIG_SPECTRA_CAMERA=m
endif
ifneq (,$(filter $(CONFIG_SPECTRA_CAMERA), y m))
export CONFIG_SPECTRA_ISP=y
export CONFIG_SPECTRA_OPE=y
export CONFIG_SPECTRA_TFE=y
export CONFIG_SPECTRA_SENSOR=y
endif

View file

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

View file

@ -0,0 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2020, The Linux Foundation. All rights reserved.
$(info "HOLI SPECTRA_CAMERA IS MODULAR")
export CONFIG_SPECTRA_CAMERA=m
ifneq (,$(filter $(CONFIG_SPECTRA_CAMERA), y m))
export CONFIG_SPECTRA_ISP=y
export CONFIG_SPECTRA_OPE=y
export CONFIG_SPECTRA_TFE=y
export CONFIG_SPECTRA_SENSOR=y
endif

View file

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

View file

@ -0,0 +1,6 @@
export CONFIG_SPECTRA_CAMERA=y
export CONFIG_SPECTRA_ISP=y
export CONFIG_SPECTRA_SENSOR=y
export CONFIG_SPECTRA_ICP=y
export CONFIG_SPECTRA_JPEG=y
export CONFIG_SPECTRA_FD=y

View file

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

View file

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

View file

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

View file

@ -0,0 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2019, The Linux Foundation. All rights reserved.
export CONFIG_SPECTRA_CAMERA=y
export CONFIG_SPECTRA_ISP=y
export CONFIG_SPECTRA_SENSOR=y
export CONFIG_SPECTRA_ICP=y
export CONFIG_SPECTRA_JPEG=y
export CONFIG_SPECTRA_LRME=y
export CONFIG_SPECTRA_FD=y

View file

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

View file

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

View file

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

View file

@ -0,0 +1,17 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2020, The Linux Foundation. All rights reserved.
ifeq ($(CONFIG_QGKI),y)
export CONFIG_SPECTRA_CAMERA=m
$(info "SPECTRA_CAMERA IS MODULAR")
else
$(info "SPECTRA_CAMERA IS MODULAR")
export CONFIG_SPECTRA_CAMERA=m
endif
ifneq (,$(filter $(CONFIG_SPECTRA_CAMERA), y m))
export CONFIG_SPECTRA_ISP=y
export CONFIG_SPECTRA_SENSOR=y
export CONFIG_SPECTRA_ICP=y
export CONFIG_SPECTRA_JPEG=y
endif

View file

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

View file

@ -0,0 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2020, The Linux Foundation. All rights reserved.
export CONFIG_SPECTRA_CAMERA=m
export CONFIG_SPECTRA_ISP=y
export CONFIG_SPECTRA_SFE=y
export CONFIG_SPECTRA_SENSOR=y
export CONFIG_SPECTRA_ICP=y
export CONFIG_SPECTRA_JPEG=y

View file

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

View file

@ -0,0 +1,18 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2020, The Linux Foundation. All rights reserved.
ifeq ($(CONFIG_QGKI),y)
export CONFIG_SPECTRA_CAMERA=m
$(info "SPECTRA_CAMERA IS MODULAR")
else
$(info "SPECTRA_CAMERA IS MODULAR")
export CONFIG_SPECTRA_CAMERA=m
endif
ifneq (,$(filter $(CONFIG_SPECTRA_CAMERA), y m))
export CONFIG_SPECTRA_ISP=y
export CONFIG_SPECTRA_SENSOR=y
export CONFIG_SPECTRA_ICP=y
export CONFIG_SPECTRA_JPEG=y
export CONFIG_SPECTRA_LRME=y
endif

View file

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

View file

@ -0,0 +1,230 @@
# SPDX-License-Identifier: GPL-2.0-only
cameratree := $(srctree)/techpack/camera/drivers
cam_include_dirs := $(shell dirname `find $(cameratree) -name '*.h'` | uniq)
ccflags-y += $(addprefix -I,$(cam_include_dirs))
ifneq (,$(filter $(CONFIG_MSM_GLOBAL_SYNX), y m))
ccflags-y += -I$(srctree)/drivers/media/platform/msm/synx
endif
ccflags-y += -I$(srctree)/techpack/camera/include/uapi/camera
ccflags-y += -I$(srctree)
camera-y := \
cam_req_mgr/cam_req_mgr_core.o \
cam_req_mgr/cam_req_mgr_dev.o \
cam_req_mgr/cam_req_mgr_util.o \
cam_req_mgr/cam_mem_mgr.o \
cam_req_mgr/cam_req_mgr_workq.o \
cam_req_mgr/cam_req_mgr_timer.o \
cam_req_mgr/cam_req_mgr_debug.o \
cam_utils/cam_soc_util.o \
cam_utils/cam_io_util.o \
cam_utils/cam_packet_util.o \
cam_utils/cam_debug_util.o \
cam_utils/cam_trace.o \
cam_utils/cam_common_util.o \
cam_utils/cam_compat.o \
cam_core/cam_context.o \
cam_core/cam_context_utils.o \
cam_core/cam_node.o \
cam_core/cam_subdev.o \
cam_smmu/cam_smmu_api.o \
cam_sync/cam_sync.o \
cam_sync/cam_sync_util.o \
cam_cpas/cpas_top/cam_cpastop_hw.o \
cam_cpas/camss_top/cam_camsstop_hw.o \
cam_cpas/cam_cpas_soc.o \
cam_cpas/cam_cpas_intf.o \
cam_cpas/cam_cpas_hw.o \
cam_cdm/cam_cdm_soc.o \
cam_cdm/cam_cdm_util.o \
cam_cdm/cam_cdm_intf.o \
cam_cdm/cam_cdm_core_common.o \
cam_cdm/cam_cdm_virtual_core.o \
cam_cdm/cam_cdm_hw_core.o
ifneq (,$(filter $(CONFIG_QCOM_CX_IPEAK),y m))
camera-y += cam_utils/cam_cx_ipeak.o
endif
ifneq (,$(filter $(CONFIG_QCOM_BUS_SCALING),y m))
camera-y += cam_utils/cam_soc_bus.o
endif
ifneq (,$(filter $(CONFIG_INTERCONNECT_QCOM),y m))
camera-y += cam_utils/cam_soc_icc.o
endif
camera-$(CONFIG_SPECTRA_ISP) += \
cam_isp/isp_hw_mgr/hw_utils/cam_tasklet_util.o \
cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.o \
cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.o \
cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_dev.o \
cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.o \
cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.o \
cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid17x.o \
cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite17x.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_rd_ver1.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver2.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_common.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_fe_ver1.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.o \
cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe.o \
cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe_soc.o \
cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe_dev.o \
cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe_core.o \
cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.o \
cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus.o \
cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_rd.o \
cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_wr.o \
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_dev.o \
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_soc.o \
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.o \
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.o \
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver2.o \
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.o \
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.o \
cam_isp/isp_hw_mgr/cam_isp_hw_mgr.o \
cam_isp/isp_hw_mgr/cam_ife_hw_mgr.o \
cam_isp/cam_isp_dev.o \
cam_isp/cam_isp_context.o
camera-$(CONFIG_SPECTRA_ICP) += \
cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.o \
cam_icp/icp_hw/ipe_hw/ipe_dev.o \
cam_icp/icp_hw/ipe_hw/ipe_core.o \
cam_icp/icp_hw/ipe_hw/ipe_soc.o \
cam_icp/icp_hw/a5_hw/a5_dev.o \
cam_icp/icp_hw/a5_hw/a5_core.o \
cam_icp/icp_hw/a5_hw/a5_soc.o \
cam_icp/icp_hw/bps_hw/bps_dev.o \
cam_icp/icp_hw/bps_hw/bps_core.o \
cam_icp/icp_hw/bps_hw/bps_soc.o \
cam_icp/cam_icp_subdev.o \
cam_icp/cam_icp_context.o \
cam_icp/hfi.o
camera-$(CONFIG_SPECTRA_JPEG) += \
cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.o \
cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.o \
cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.o \
cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.o \
cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.o \
cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.o \
cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.o \
cam_jpeg/cam_jpeg_dev.o \
cam_jpeg/cam_jpeg_context.o
camera-$(CONFIG_SPECTRA_FD) += \
cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.o \
cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_core.o \
cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.o \
cam_fd/fd_hw_mgr/cam_fd_hw_mgr.o \
cam_fd/cam_fd_dev.o \
cam_fd/cam_fd_context.o
camera-$(CONFIG_SPECTRA_LRME) += \
cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_dev.o \
cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.o \
cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.o \
cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.o \
cam_lrme/cam_lrme_dev.o \
cam_lrme/cam_lrme_context.o
camera-$(CONFIG_SPECTRA_SENSOR) += \
cam_sensor_module/cam_actuator/cam_actuator_dev.o \
cam_sensor_module/cam_actuator/cam_actuator_core.o \
cam_sensor_module/cam_actuator/cam_actuator_soc.o \
cam_sensor_module/cam_cci/cam_cci_dev.o \
cam_sensor_module/cam_cci/cam_cci_core.o \
cam_sensor_module/cam_cci/cam_cci_soc.o \
cam_sensor_module/cam_csiphy/cam_csiphy_soc.o \
cam_sensor_module/cam_csiphy/cam_csiphy_dev.o \
cam_sensor_module/cam_csiphy/cam_csiphy_core.o \
cam_sensor_module/cam_eeprom/cam_eeprom_dev.o \
cam_sensor_module/cam_eeprom/cam_eeprom_core.o \
cam_sensor_module/cam_eeprom/cam_eeprom_soc.o \
cam_sensor_module/cam_ois/cam_ois_dev.o \
cam_sensor_module/cam_ois/cam_ois_core.o \
cam_sensor_module/cam_ois/cam_ois_soc.o \
cam_sensor_module/cam_sensor/cam_sensor_dev.o \
cam_sensor_module/cam_sensor/cam_sensor_core.o \
cam_sensor_module/cam_sensor/cam_sensor_soc.o \
cam_sensor_module/cam_sensor_io/cam_sensor_io.o \
cam_sensor_module/cam_sensor_io/cam_sensor_cci_i2c.o \
cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.o \
cam_sensor_module/cam_sensor_io/cam_sensor_spi.o \
cam_sensor_module/cam_sensor_utils/cam_sensor_util.o \
cam_sensor_module/cam_res_mgr/cam_res_mgr.o
camera-$(CONFIG_LEDS_QPNP_FLASH_V2) += \
cam_sensor_module/cam_flash/cam_flash_dev.o \
cam_sensor_module/cam_flash/cam_flash_core.o \
cam_sensor_module/cam_flash/cam_flash_soc.o
ifneq (,$(filter $(CONFIG_LEDS_QTI_FLASH),y m))
camera-y += \
cam_sensor_module/cam_flash/cam_flash_dev.o \
cam_sensor_module/cam_flash/cam_flash_core.o \
cam_sensor_module/cam_flash/cam_flash_soc.o
endif
camera-$(CONFIG_SPECTRA_CUSTOM) += \
cam_cust/cam_custom_hw_mgr/cam_custom_hw1/cam_custom_sub_mod_soc.o \
cam_cust/cam_custom_hw_mgr/cam_custom_hw1/cam_custom_sub_mod_dev.o \
cam_cust/cam_custom_hw_mgr/cam_custom_hw1/cam_custom_sub_mod_core.o \
cam_cust/cam_custom_hw_mgr/cam_custom_csid/cam_custom_csid_dev.o \
cam_cust/cam_custom_hw_mgr/cam_custom_hw_mgr.o \
cam_cust/cam_custom_dev.o \
cam_cust/cam_custom_context.o
camera-$(CONFIG_SPECTRA_OPE) += \
cam_ope/cam_ope_subdev.o \
cam_ope/cam_ope_context.o \
cam_ope/ope_hw_mgr/cam_ope_hw_mgr.o \
cam_ope/ope_hw_mgr/ope_hw/ope_dev.o \
cam_ope/ope_hw_mgr/ope_hw/ope_soc.o \
cam_ope/ope_hw_mgr/ope_hw/ope_core.o \
cam_ope/ope_hw_mgr/ope_hw/top/ope_top.o \
cam_ope/ope_hw_mgr/ope_hw/bus_rd/ope_bus_rd.o\
cam_ope/ope_hw_mgr/ope_hw/bus_wr/ope_bus_wr.o
camera-$(CONFIG_SPECTRA_TFE) += \
cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.o \
cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_dev.o \
cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi100.o \
cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.o \
cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_dev.o \
cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.o \
cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.o \
cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe.o \
cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_dev.o \
cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_soc.o \
cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.o \
cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.o \
cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.o
camera-y += camera_main.o
obj-$(CONFIG_SPECTRA_CAMERA) += camera.o
ifeq ($(CONFIG_SPECTRA_CAMERA),m)
$(info "SPECTRA CAMERA IS BUILT AS DLKM")
BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/camera.ko
endif

View file

@ -0,0 +1,577 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CDM_H_
#define _CAM_CDM_H_
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/random.h>
#include <linux/spinlock_types.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <linux/bug.h>
#include "cam_cdm_intf_api.h"
#include "cam_soc_util.h"
#include "cam_cpas_api.h"
#include "cam_hw_intf.h"
#include "cam_hw.h"
#include "cam_debug_util.h"
#define CAM_MAX_SW_CDM_VERSION_SUPPORTED 1
#define CAM_SW_CDM_INDEX 0
#define CAM_CDM_INFLIGHT_WORKS 5
#define CAM_CDM_HW_RESET_TIMEOUT 300
/*
* Macros to get prepare and get information
* from client CDM handles.
*/
#define CAM_CDM_HW_ID_MASK 0xF
#define CAM_CDM_HW_ID_SHIFT 0x10
#define CAM_CDM_CLIENTS_ID_MASK 0xFF
#define CAM_CDM_BL_FIFO_ID_MASK 0xF
#define CAM_CDM_BL_FIFO_ID_SHIFT 0x8
#define CAM_CDM_GET_HW_IDX(x) (((x) >> CAM_CDM_HW_ID_SHIFT) & \
CAM_CDM_HW_ID_MASK)
#define CAM_CDM_GET_BLFIFO_IDX(x) (((x) >> CAM_CDM_BL_FIFO_ID_SHIFT) & \
CAM_CDM_BL_FIFO_ID_MASK)
#define CAM_CDM_CREATE_CLIENT_HANDLE(hw_idx, priority, client_idx) \
((((hw_idx) & CAM_CDM_HW_ID_MASK) << CAM_CDM_HW_ID_SHIFT) | \
(((priority) & CAM_CDM_BL_FIFO_ID_MASK) << CAM_CDM_BL_FIFO_ID_SHIFT)| \
((client_idx) & CAM_CDM_CLIENTS_ID_MASK))
#define CAM_CDM_GET_CLIENT_IDX(x) ((x) & CAM_CDM_CLIENTS_ID_MASK)
#define CAM_PER_CDM_MAX_REGISTERED_CLIENTS (CAM_CDM_CLIENTS_ID_MASK + 1)
#define CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM (CAM_CDM_HW_ID_MASK + 1)
/* Number of FIFO supported on CDM */
#define CAM_CDM_NUM_BL_FIFO 0x4
/* Max number of register set for different CDM */
#define CAM_CDM_BL_FIFO_REG_NUM 0x4
#define CAM_CDM_BL_FIFO_IRQ_REG_NUM 0x4
#define CAM_CDM_BL_FIFO_PENDING_REQ_REG_NUM 0x2
#define CAM_CDM_SCRATCH_REG_NUM 0xc
#define CAM_CDM_COMP_WAIT_STATUS_REG_NUM 0x2
#define CAM_CDM_PERF_MON_REG_NUM 0x2
/* BL_FIFO configurations*/
#define CAM_CDM_BL_FIFO_LENGTH_MAX_DEFAULT 0x40
#define CAM_CDM_BL_FIFO_LENGTH_CFG_SHIFT 0x10
#define CAM_CDM_BL_FIFO_FLUSH_SHIFT 0x3
#define CAM_CDM_BL_FIFO_REQ_SIZE_MAX 0x00
#define CAM_CDM_BL_FIFO_REQ_SIZE_MAX_DIV2 0x01
#define CAM_CDM_BL_FIFO_REQ_SIZE_MAX_DIV4 0x10
#define CAM_CDM_BL_FIFO_REQ_SIZE_MAX_DIV8 0x11
/* CDM core status bitmap */
#define CAM_CDM_HW_INIT_STATUS 0x0
#define CAM_CDM_FIFO_0_BLDONE_STATUS 0x0
#define CAM_CDM_FIFO_1_BLDONE_STATUS 0x1
#define CAM_CDM_FIFO_2_BLDONE_STATUS 0x2
#define CAM_CDM_FIFO_3_BLDONE_STATUS 0x3
#define CAM_CDM_RESET_HW_STATUS 0x4
#define CAM_CDM_ERROR_HW_STATUS 0x5
#define CAM_CDM_FLUSH_HW_STATUS 0x6
#define CAM_CDM_RESET_ERR_STATUS 0x7
/* Curent BL command masks and shifts */
#define CAM_CDM_CURRENT_BL_LEN 0xFFFFF
#define CAM_CDM_CURRENT_BL_ARB 0x100000
#define CAM_CDM_CURRENT_BL_FIFO 0xC00000
#define CAM_CDM_CURRENT_BL_TAG 0xFF000000
#define CAM_CDM_CURRENT_BL_ARB_SHIFT 0x14
#define CAM_CDM_CURRENT_BL_FIFO_SHIFT 0x16
#define CAM_CDM_CURRENT_BL_TAG_SHIFT 0x18
/* IRQ bit-masks */
#define CAM_CDM_IRQ_STATUS_RST_DONE_MASK 0x1
#define CAM_CDM_IRQ_STATUS_INLINE_IRQ_MASK 0x2
#define CAM_CDM_IRQ_STATUS_BL_DONE_MASK 0x4
#define CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK 0x10000
#define CAM_CDM_IRQ_STATUS_ERROR_OVER_FLOW_MASK 0x20000
#define CAM_CDM_IRQ_STATUS_ERROR_AHB_BUS_MASK 0x40000
#define CAM_CDM_IRQ_STATUS_USR_DATA_MASK 0xFF
#define CAM_CDM_IRQ_STATUS_ERRORS \
(CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK | \
CAM_CDM_IRQ_STATUS_ERROR_OVER_FLOW_MASK | \
CAM_CDM_IRQ_STATUS_ERROR_AHB_BUS_MASK)
struct cam_cdm_pid_mid_data {
int cdm_pid;
int cdm_mid;
int ope_cdm_pid;
int ope_cdm_mid;
};
/* Structure to store hw version info */
struct cam_version_reg {
uint32_t hw_version;
};
/**
* struct cam_cdm_irq_regs - CDM IRQ registers
*
* @irq_mask: register offset for irq_mask
* @irq_clear: register offset for irq_clear
* @irq_clear_cmd: register offset to initiate irq clear
* @irq_set: register offset to set irq
* @irq_set_cmd: register offset to issue set_irq from irq_set
* @irq_status: register offset to look which irq is received
*/
struct cam_cdm_irq_regs {
uint32_t irq_mask;
uint32_t irq_clear;
uint32_t irq_clear_cmd;
uint32_t irq_set;
uint32_t irq_set_cmd;
uint32_t irq_status;
};
/**
* struct cam_cdm_bl_fifo_regs - BL_FIFO registers
*
* @bl_fifo_base: register offset to write bl_cmd base address
* @bl_fifo_len: register offset to write bl_cmd length
* @bl_fifo_store: register offset to commit the BL cmd
* @bl_fifo_cfg: register offset to config BL_FIFO depth, etc.
*/
struct cam_cdm_bl_fifo_regs {
uint32_t bl_fifo_base;
uint32_t bl_fifo_len;
uint32_t bl_fifo_store;
uint32_t bl_fifo_cfg;
};
/**
* struct cam_cdm_bl_pending_req_reg_params - BL_FIFO pending registers
*
* @rb_offset: register offset pending bl request in BL_FIFO
* @rb_mask: mask to get number of pending BLs in BL_FIFO
* @rb_num_fifo: number of BL_FIFO's information in the register
* @rb_next_fifo_shift: shift to get next fifo's pending BLs.
*/
struct cam_cdm_bl_pending_req_reg_params {
uint32_t rb_offset;
uint32_t rb_mask;
uint32_t rb_num_fifo;
uint32_t rb_next_fifo_shift;
};
/**
* struct cam_cdm_scratch_reg - scratch register
*
* @scratch_reg: offset of scratch register
*/
struct cam_cdm_scratch_reg {
uint32_t scratch_reg;
};
/* struct cam_cdm_perf_mon_regs - perf_mon registers */
struct cam_cdm_perf_mon_regs {
uint32_t perf_mon_ctrl;
uint32_t perf_mon_0;
uint32_t perf_mon_1;
uint32_t perf_mon_2;
};
/**
* struct cam_cdm_perf_mon_regs - perf mon counter's registers
*
* @count_cfg_0: register offset to configure perf measures
* @always_count_val: register offset for always count value
* @busy_count_val: register offset to get busy count
* @stall_axi_count_val: register offset to get axi stall counts
* @count_status: register offset to know if count status finished
* for stall, busy and always.
*/
struct cam_cdm_perf_regs {
uint32_t count_cfg_0;
uint32_t always_count_val;
uint32_t busy_count_val;
uint32_t stall_axi_count_val;
uint32_t count_status;
};
/**
* struct cam_cdm_icl_data_regs - CDM icl data registers
*
* @icl_last_data_0: register offset to log last known good command
* @icl_last_data_1: register offset to log last known good command 1
* @icl_last_data_2: register offset to log last known good command 2
* @icl_inv_data: register offset to log CDM cmd that triggered
* invalid command.
*/
struct cam_cdm_icl_data_regs {
uint32_t icl_last_data_0;
uint32_t icl_last_data_1;
uint32_t icl_last_data_2;
uint32_t icl_inv_data;
};
/**
* struct cam_cdm_icl_misc_regs - CDM icl misc registers
*
* @icl_inv_bl_addr: register offset to give address of bl_cmd that
* gave invalid command
* @icl_status: register offset for context that gave good BL
* command and invalid command.
*/
struct cam_cdm_icl_misc_regs {
uint32_t icl_inv_bl_addr;
uint32_t icl_status;
};
/**
* struct cam_cdm_icl_regs - CDM icl registers
*
* @data_regs: structure with registers of all cdm good and invalid
* BL command information.
* @misc_regs: structure with registers for invalid command address
* and context
*/
struct cam_cdm_icl_regs {
struct cam_cdm_icl_data_regs *data_regs;
struct cam_cdm_icl_misc_regs *misc_regs;
};
/**
* struct cam_cdm_comp_wait_status - BL_FIFO comp_event status register
*
* @comp_wait_status: register offset to give information on whether the
* CDM is waiting for an event from another module
*/
struct cam_cdm_comp_wait_status {
uint32_t comp_wait_status;
};
/**
* struct cam_cdm_common_reg_data - structure for register data
*
* @num_bl_fifo: number of FIFO are there in CDM
* @num_bl_fifo_irq: number of FIFO irqs in CDM
* @num_bl_pending_req_reg: number of pending_requests register in CDM
* @num_scratch_reg: number of scratch registers in CDM
*/
struct cam_cdm_common_reg_data {
uint32_t num_bl_fifo;
uint32_t num_bl_fifo_irq;
uint32_t num_bl_pending_req_reg;
uint32_t num_scratch_reg;
};
/**
* struct cam_cdm_common_regs - common structure to get common registers
* of CDM
*
* @cdm_hw_version: offset to read cdm_hw_version
* @cam_version: offset to read the camera Titan architecture version
* @rst_cmd: offset to reset the CDM
* @cgc_cfg: offset to configure CDM CGC logic
* @core_cfg: offset to configure CDM core with ARB_SEL, implicit
* wait, etc.
* @core_en: offset to pause/enable CDM
* @fe_cfg: offset to configure CDM fetch engine
* @irq_context_status offset to read back irq context status
* @bl_fifo_rb: offset to set BL_FIFO read back
* @bl_fifo_base_rb: offset to read back base address on offset set by
* bl_fifo_rb
* @bl_fifo_len_rb: offset to read back base len and tag on offset set by
* bl_fifo_rb
* @usr_data: offset to read user data from GEN_IRQ commands
* @wait_status: offset to read status for last WAIT command
* @last_ahb_addr: offset to read back last AHB address generated by CDM
* @last_ahb_data: offset to read back last AHB data generated by CDM
* @core_debug: offset to configure CDM debug bus and debug features
* @last_ahb_err_addr: offset to read back last AHB Error address generated
* by CDM
* @last_ahb_err_data: offset to read back last AHB Error data generated
* by CDM
* @current_bl_base: offset to read back current command buffer BASE address
* value out of BL_FIFO
* @current_bl_len: offset to read back current command buffer len, TAG,
* context ID ARB value out of BL_FIFO
* @current_used_ahb_base: offset to read back current base address used by
* CDM to access camera register
* @debug_status: offset to read back current CDM status
* @bus_misr_cfg0: offset to enable bus MISR and configure sampling mode
* @bus_misr_cfg1: offset to select from one of the six MISR's for reading
* signature value
* @bus_misr_rd_val: offset to read MISR signature
* @pending_req: registers to read pending request in FIFO
* @comp_wait: registers to read comp_event CDM is waiting for
* @perf_mon: registers to read perf_mon information
* @scratch: registers to read scratch register value
* @perf_reg: registers to read performance counters value
* @icl_reg: registers to read information related to good
* and invalid commands in FIFO
* @spare: spare register
* @priority_group_bit_offset offset of priority group bits
*
*/
struct cam_cdm_common_regs {
uint32_t cdm_hw_version;
const struct cam_version_reg *cam_version;
uint32_t rst_cmd;
uint32_t cgc_cfg;
uint32_t core_cfg;
uint32_t core_en;
uint32_t fe_cfg;
uint32_t irq_context_status;
uint32_t bl_fifo_rb;
uint32_t bl_fifo_base_rb;
uint32_t bl_fifo_len_rb;
uint32_t usr_data;
uint32_t wait_status;
uint32_t last_ahb_addr;
uint32_t last_ahb_data;
uint32_t core_debug;
uint32_t last_ahb_err_addr;
uint32_t last_ahb_err_data;
uint32_t current_bl_base;
uint32_t current_bl_len;
uint32_t current_used_ahb_base;
uint32_t debug_status;
uint32_t bus_misr_cfg0;
uint32_t bus_misr_cfg1;
uint32_t bus_misr_rd_val;
const struct cam_cdm_bl_pending_req_reg_params
*pending_req[CAM_CDM_BL_FIFO_PENDING_REQ_REG_NUM];
const struct cam_cdm_comp_wait_status
*comp_wait[CAM_CDM_COMP_WAIT_STATUS_REG_NUM];
const struct cam_cdm_perf_mon_regs
*perf_mon[CAM_CDM_PERF_MON_REG_NUM];
const struct cam_cdm_scratch_reg
*scratch[CAM_CDM_SCRATCH_REG_NUM];
const struct cam_cdm_perf_regs *perf_reg;
const struct cam_cdm_icl_regs *icl_reg;
uint32_t spare;
uint32_t priority_group_bit_offset;
struct cam_cdm_pid_mid_data *cdm_pid_mid_info;
};
/**
* struct cam_cdm_hw_reg_offset - BL_FIFO comp_event status register
*
* @cmn_reg: pointer to structure to get common registers of a CDM
* @bl_fifo_reg: pointer to structure to get BL_FIFO registers of a CDM
* @irq_reg: pointer to structure to get IRQ registers of a CDM
* @reg_data: pointer to structure to reg_data related to CDM
* registers
*/
struct cam_cdm_hw_reg_offset {
const struct cam_cdm_common_regs *cmn_reg;
const struct cam_cdm_bl_fifo_regs *bl_fifo_reg[CAM_CDM_BL_FIFO_REG_NUM];
const struct cam_cdm_irq_regs *irq_reg[CAM_CDM_BL_FIFO_IRQ_REG_NUM];
const struct cam_cdm_common_reg_data *reg_data;
};
/* enum cam_cdm_hw_process_intf_cmd - interface commands.*/
enum cam_cdm_hw_process_intf_cmd {
CAM_CDM_HW_INTF_CMD_ACQUIRE,
CAM_CDM_HW_INTF_CMD_RELEASE,
CAM_CDM_HW_INTF_CMD_SUBMIT_BL,
CAM_CDM_HW_INTF_CMD_RESET_HW,
CAM_CDM_HW_INTF_CMD_FLUSH_HW,
CAM_CDM_HW_INTF_CMD_HANDLE_ERROR,
CAM_CDM_HW_INTF_CMD_HANG_DETECT,
CAM_CDM_HW_INTF_DUMP_DBG_REGS,
CAM_CDM_HW_INTF_CMD_INVALID,
};
/* enum cam_cdm_flags - Bit fields for CDM flags used */
enum cam_cdm_flags {
CAM_CDM_FLAG_SHARED_CDM,
CAM_CDM_FLAG_PRIVATE_CDM,
};
/* enum cam_cdm_type - Enum for possible CAM CDM types */
enum cam_cdm_type {
CAM_VIRTUAL_CDM,
CAM_HW_CDM,
};
/* enum cam_cdm_mem_base_index - Enum for possible CAM CDM types */
enum cam_cdm_mem_base_index {
CAM_HW_CDM_BASE_INDEX,
CAM_HW_CDM_MAX_INDEX = CAM_SOC_MAX_BLOCK,
};
/* enum cam_cdm_bl_cb_type - Enum for possible CAM CDM cb request types */
enum cam_cdm_bl_cb_type {
CAM_HW_CDM_BL_CB_CLIENT = 1,
CAM_HW_CDM_BL_CB_INTERNAL,
};
/* enum cam_cdm_arbitration - Enum type of arbitration */
enum cam_cdm_arbitration {
CAM_CDM_ARBITRATION_NONE,
CAM_CDM_ARBITRATION_ROUND_ROBIN,
CAM_CDM_ARBITRATION_PRIORITY_BASED,
CAM_CDM_ARBITRATION_MAX,
};
enum cam_cdm_hw_version {
CAM_CDM_VERSION = 0,
CAM_CDM_VERSION_1_0 = 0x10000000,
CAM_CDM_VERSION_1_1 = 0x10010000,
CAM_CDM_VERSION_1_2 = 0x10020000,
CAM_CDM_VERSION_2_0 = 0x20000000,
CAM_CDM_VERSION_2_1 = 0x20010000,
CAM_CDM_VERSION_MAX,
};
/* struct cam_cdm_client - struct for cdm clients data.*/
struct cam_cdm_client {
struct cam_cdm_acquire_data data;
void __iomem *changebase_addr;
uint32_t stream_on;
uint32_t refcount;
struct mutex lock;
uint32_t handle;
};
/* struct cam_cdm_work_payload - struct for cdm work payload data.*/
struct cam_cdm_work_payload {
struct cam_hw_info *hw;
uint32_t irq_status;
uint32_t irq_data;
int fifo_idx;
ktime_t workq_scheduled_ts;
struct work_struct work;
};
/* struct cam_cdm_bl_cb_request_entry - callback entry for work to process.*/
struct cam_cdm_bl_cb_request_entry {
uint8_t bl_tag;
enum cam_cdm_bl_cb_type request_type;
uint32_t client_hdl;
void *userdata;
uint32_t cookie;
struct list_head entry;
};
/* struct cam_cdm_hw_intf_cmd_submit_bl - cdm interface submit command.*/
struct cam_cdm_hw_intf_cmd_submit_bl {
uint32_t handle;
struct cam_cdm_bl_request *data;
};
/* struct cam_cdm_hw_mem - CDM hw memory struct */
struct cam_cdm_hw_mem {
int32_t handle;
uint32_t vaddr;
uintptr_t kmdvaddr;
size_t size;
};
/* struct cam_cdm_bl_fifo - CDM hw memory struct */
struct cam_cdm_bl_fifo {
struct completion bl_complete;
struct workqueue_struct *work_queue;
struct list_head bl_request_list;
struct mutex fifo_lock;
uint8_t bl_tag;
uint32_t bl_depth;
uint8_t last_bl_tag_done;
atomic_t work_record;
};
/**
* struct cam_cdm - CDM hw device struct
*
* @index: index of CDM hardware
* @name: cdm_name
* @id: enum for possible CDM hardwares
* @flags: enum to tell if CDM is private of shared
* @reset_complete: completion event to make CDM wait for reset
* @work_queue: workqueue to schedule work for virtual CDM
* @bl_request_list: bl_request list for submitted commands in
* virtual CDM
* @version: CDM version with major, minor, incr and reserved
* @hw_version: CDM version as read from the cdm_version register
* @hw_family_version: version of hw family the CDM belongs to
* @iommu_hdl: CDM iommu handle
* @offsets: pointer to structure of CDM registers
* @ops: CDM ops for generating cdm commands
* @clients: CDM clients array currently active on CDM
* @bl_fifo: structure with per fifo related attributes
* @cdm_status: bitfield with bits assigned for different cdm status
* @bl_tag: slot value at which the next bl cmd will be written
* in case of virtual CDM
* @gen_irq: memory region in which gen_irq command will be written
* @cpas_handle: handle for cpas driver
* @arbitration: type of arbitration to be used for the CDM
*/
struct cam_cdm {
uint32_t index;
char name[128];
enum cam_cdm_id id;
enum cam_cdm_flags flags;
struct completion reset_complete;
struct workqueue_struct *work_queue;
struct list_head bl_request_list;
struct cam_hw_version version;
uint32_t hw_version;
uint32_t hw_family_version;
struct cam_iommu_handle iommu_hdl;
struct cam_cdm_hw_reg_offset *offsets;
struct cam_cdm_utils_ops *ops;
struct cam_cdm_client *clients[CAM_PER_CDM_MAX_REGISTERED_CLIENTS];
struct cam_cdm_bl_fifo bl_fifo[CAM_CDM_BL_FIFO_MAX];
unsigned long cdm_status;
uint8_t bl_tag;
struct cam_cdm_hw_mem gen_irq[CAM_CDM_BL_FIFO_MAX];
uint32_t cpas_handle;
enum cam_cdm_arbitration arbitration;
};
/* struct cam_cdm_private_dt_data - CDM hw custom dt data */
struct cam_cdm_private_dt_data {
bool dt_cdm_shared;
bool config_fifo;
bool is_single_ctx_cdm;
uint8_t priority_group;
uint32_t fifo_depth[CAM_CDM_BL_FIFO_MAX];
uint32_t dt_num_supported_clients;
const char *dt_cdm_client_name[CAM_PER_CDM_MAX_REGISTERED_CLIENTS];
};
/* struct cam_cdm_intf_devices - CDM mgr interface devices */
struct cam_cdm_intf_devices {
struct mutex lock;
uint32_t refcount;
struct cam_hw_intf *device;
struct cam_cdm_private_dt_data *data;
};
/* struct cam_cdm_intf_mgr - CDM mgr interface device struct */
struct cam_cdm_intf_mgr {
bool probe_done;
uint32_t cdm_count;
uint32_t dt_supported_hw_cdm;
int32_t refcount;
struct cam_cdm_intf_devices nodes[CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM];
};
int cam_cdm_intf_register_hw_cdm(struct cam_hw_intf *hw,
struct cam_cdm_private_dt_data *data, enum cam_cdm_type type,
uint32_t *index);
int cam_cdm_intf_deregister_hw_cdm(struct cam_hw_intf *hw,
struct cam_cdm_private_dt_data *data, enum cam_cdm_type type,
uint32_t index);
#endif /* _CAM_CDM_H_ */

View file

@ -0,0 +1,847 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include "cam_soc_util.h"
#include "cam_smmu_api.h"
#include "cam_io_util.h"
#include "cam_cdm_intf_api.h"
#include "cam_cdm.h"
#include "cam_cdm_soc.h"
#include "cam_cdm_core_common.h"
static void cam_cdm_get_client_refcount(struct cam_cdm_client *client)
{
mutex_lock(&client->lock);
CAM_DBG(CAM_CDM, "CDM client get refcount=%d",
client->refcount);
client->refcount++;
mutex_unlock(&client->lock);
}
static void cam_cdm_put_client_refcount(struct cam_cdm_client *client)
{
mutex_lock(&client->lock);
CAM_DBG(CAM_CDM, "CDM client put refcount=%d",
client->refcount);
if (client->refcount > 0) {
client->refcount--;
} else {
CAM_ERR(CAM_CDM, "Refcount put when zero");
WARN_ON(1);
}
mutex_unlock(&client->lock);
}
bool cam_cdm_set_cam_hw_version(
uint32_t ver, struct cam_hw_version *cam_version)
{
switch (ver) {
case CAM_CDM100_VERSION:
case CAM_CDM110_VERSION:
case CAM_CDM120_VERSION:
case CAM_CDM200_VERSION:
case CAM_CDM210_VERSION:
cam_version->major = (ver & 0xF0000000);
cam_version->minor = (ver & 0xFFF0000);
cam_version->incr = (ver & 0xFFFF);
cam_version->reserved = 0;
return true;
default:
CAM_ERR(CAM_CDM, "CDM Version=%x not supported in util", ver);
break;
}
return false;
}
bool cam_cdm_cpas_cb(uint32_t client_handle, void *userdata,
struct cam_cpas_irq_data *irq_data)
{
if (!irq_data)
return false;
CAM_DBG(CAM_CDM, "CPAS error callback type=%d", irq_data->irq_type);
return false;
}
struct cam_cdm_utils_ops *cam_cdm_get_ops(
uint32_t ver, struct cam_hw_version *cam_version, bool by_cam_version)
{
if (by_cam_version == false) {
switch (ver) {
case CAM_CDM100_VERSION:
case CAM_CDM110_VERSION:
case CAM_CDM120_VERSION:
case CAM_CDM200_VERSION:
case CAM_CDM210_VERSION:
return &CDM170_ops;
default:
CAM_ERR(CAM_CDM, "CDM Version=%x not supported in util",
ver);
}
} else if (cam_version) {
if (((cam_version->major == 1) &&
(cam_version->minor == 0) &&
(cam_version->incr == 0)) ||
((cam_version->major == 1) &&
(cam_version->minor == 1) &&
(cam_version->incr == 0)) ||
((cam_version->major == 1) &&
(cam_version->minor == 2) &&
(cam_version->incr == 0))) {
CAM_DBG(CAM_CDM,
"cam_hw_version=%x:%x:%x supported",
cam_version->major, cam_version->minor,
cam_version->incr);
return &CDM170_ops;
}
CAM_ERR(CAM_CDM, "cam_hw_version=%x:%x:%x not supported",
cam_version->major, cam_version->minor,
cam_version->incr);
}
return NULL;
}
struct cam_cdm_bl_cb_request_entry *cam_cdm_find_request_by_bl_tag(
uint32_t tag, struct list_head *bl_list)
{
struct cam_cdm_bl_cb_request_entry *node;
list_for_each_entry(node, bl_list, entry) {
if (node->bl_tag == tag)
return node;
}
CAM_ERR(CAM_CDM, "Could not find the bl request for tag=%x", tag);
return NULL;
}
int cam_cdm_get_caps(void *hw_priv,
void *get_hw_cap_args, uint32_t arg_size)
{
struct cam_hw_info *cdm_hw = hw_priv;
struct cam_cdm *cdm_core;
if ((cdm_hw) && (cdm_hw->core_info) && (get_hw_cap_args) &&
(sizeof(struct cam_iommu_handle) == arg_size)) {
cdm_core = (struct cam_cdm *)cdm_hw->core_info;
*((struct cam_iommu_handle *)get_hw_cap_args) =
cdm_core->iommu_hdl;
return 0;
}
return -EINVAL;
}
int cam_cdm_find_free_client_slot(struct cam_cdm *hw)
{
int i;
for (i = 0; i < CAM_PER_CDM_MAX_REGISTERED_CLIENTS; i++) {
if (hw->clients[i] == NULL) {
CAM_DBG(CAM_CDM, "Found client slot %d", i);
return i;
}
}
CAM_ERR(CAM_CDM, "No more client slots");
return -EBUSY;
}
void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
enum cam_cdm_cb_status status, void *data)
{
int i;
struct cam_cdm *core = NULL;
struct cam_cdm_client *client = NULL;
if (!cdm_hw) {
CAM_ERR(CAM_CDM, "CDM Notify called with NULL hw info");
return;
}
core = (struct cam_cdm *)cdm_hw->core_info;
if (status == CAM_CDM_CB_STATUS_BL_SUCCESS) {
int client_idx;
struct cam_cdm_bl_cb_request_entry *node =
(struct cam_cdm_bl_cb_request_entry *)data;
client_idx = CAM_CDM_GET_CLIENT_IDX(node->client_hdl);
mutex_lock(&cdm_hw->hw_mutex);
client = core->clients[client_idx];
if ((!client) || (client->handle != node->client_hdl)) {
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client,
node->client_hdl);
mutex_unlock(&cdm_hw->hw_mutex);
return;
}
cam_cdm_get_client_refcount(client);
mutex_lock(&client->lock);
if (client->data.cam_cdm_callback) {
CAM_DBG(CAM_CDM, "Calling client=%s cb cookie=%d",
client->data.identifier, node->cookie);
client->data.cam_cdm_callback(node->client_hdl,
node->userdata, CAM_CDM_CB_STATUS_BL_SUCCESS,
node->cookie);
CAM_DBG(CAM_CDM, "Exit client cb cookie=%d",
node->cookie);
} else {
CAM_ERR(CAM_CDM, "No cb registered for client hdl=%x",
node->client_hdl);
}
mutex_unlock(&client->lock);
cam_cdm_put_client_refcount(client);
mutex_unlock(&cdm_hw->hw_mutex);
return;
} else if (status == CAM_CDM_CB_STATUS_HW_RESET_DONE ||
status == CAM_CDM_CB_STATUS_HW_FLUSH ||
status == CAM_CDM_CB_STATUS_HW_RESUBMIT ||
status == CAM_CDM_CB_STATUS_INVALID_BL_CMD ||
status == CAM_CDM_CB_STATUS_HW_ERROR) {
int client_idx;
struct cam_cdm_bl_cb_request_entry *node =
(struct cam_cdm_bl_cb_request_entry *)data;
client_idx = CAM_CDM_GET_CLIENT_IDX(node->client_hdl);
client = core->clients[client_idx];
if ((!client) || (client->handle != node->client_hdl)) {
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client,
node->client_hdl);
return;
}
cam_cdm_get_client_refcount(client);
mutex_lock(&client->lock);
if (client->data.cam_cdm_callback) {
client->data.cam_cdm_callback(
client->handle,
client->data.userdata,
status,
node->cookie);
} else {
CAM_ERR(CAM_CDM,
"No cb registered for client: name %s, hdl=%x",
client->data.identifier, client->handle);
}
mutex_unlock(&client->lock);
cam_cdm_put_client_refcount(client);
return;
}
for (i = 0; i < CAM_PER_CDM_MAX_REGISTERED_CLIENTS; i++) {
if (core->clients[i] != NULL) {
mutex_lock(&cdm_hw->hw_mutex);
client = core->clients[i];
cam_cdm_get_client_refcount(client);
mutex_lock(&client->lock);
CAM_DBG(CAM_CDM, "Found client slot %d", i);
if (client->data.cam_cdm_callback) {
if (status == CAM_CDM_CB_STATUS_PAGEFAULT) {
unsigned long iova =
(unsigned long)data;
client->data.cam_cdm_callback(
client->handle,
client->data.userdata,
CAM_CDM_CB_STATUS_PAGEFAULT,
(iova & 0xFFFFFFFF));
}
} else {
CAM_ERR(CAM_CDM,
"No cb registered for client hdl=%x",
client->handle);
}
mutex_unlock(&client->lock);
cam_cdm_put_client_refcount(client);
mutex_unlock(&cdm_hw->hw_mutex);
}
}
}
static int cam_cdm_stream_handle_init(void *hw_priv, bool init)
{
struct cam_hw_info *cdm_hw = hw_priv;
struct cam_cdm *core = NULL;
int rc = -EPERM;
core = (struct cam_cdm *)cdm_hw->core_info;
if (init) {
rc = cam_hw_cdm_init(hw_priv, NULL, 0);
if (rc) {
CAM_ERR(CAM_CDM, "CDM HW init failed");
return rc;
}
if (core->arbitration !=
CAM_CDM_ARBITRATION_PRIORITY_BASED) {
rc = cam_hw_cdm_alloc_genirq_mem(
hw_priv);
if (rc) {
CAM_ERR(CAM_CDM,
"Genirqalloc failed");
cam_hw_cdm_deinit(hw_priv,
NULL, 0);
}
}
} else {
rc = cam_hw_cdm_deinit(hw_priv, NULL, 0);
if (rc)
CAM_ERR(CAM_CDM, "Deinit failed in streamoff");
if (core->arbitration !=
CAM_CDM_ARBITRATION_PRIORITY_BASED) {
if (cam_hw_cdm_release_genirq_mem(hw_priv))
CAM_ERR(CAM_CDM, "Genirq release fail");
}
}
return rc;
}
int cam_cdm_stream_ops_internal(void *hw_priv,
void *start_args, bool operation)
{
struct cam_hw_info *cdm_hw = hw_priv;
struct cam_cdm *core = NULL;
int rc = -EPERM;
int client_idx;
struct cam_cdm_client *client;
uint32_t *handle = start_args;
if (!hw_priv)
return -EINVAL;
core = (struct cam_cdm *)cdm_hw->core_info;
mutex_lock(&cdm_hw->hw_mutex);
client_idx = CAM_CDM_GET_CLIENT_IDX(*handle);
client = core->clients[client_idx];
if (!client) {
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client, *handle);
mutex_unlock(&cdm_hw->hw_mutex);
return -EINVAL;
}
cam_cdm_get_client_refcount(client);
if (*handle != client->handle) {
CAM_ERR(CAM_CDM, "client id given handle=%x invalid", *handle);
rc = -EINVAL;
goto end;
}
if (operation == true) {
if (true == client->stream_on) {
CAM_ERR(CAM_CDM,
"Invalid CDM client is already streamed ON");
goto end;
}
} else {
if (client->stream_on == false) {
CAM_ERR(CAM_CDM,
"Invalid CDM client is already streamed Off");
goto end;
}
}
if (operation == true) {
if (!cdm_hw->open_count) {
struct cam_ahb_vote ahb_vote;
struct cam_axi_vote axi_vote = {0};
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_LOWSVS_VOTE;
axi_vote.num_paths = 1;
axi_vote.axi_path[0].path_data_type =
CAM_AXI_PATH_DATA_ALL;
axi_vote.axi_path[0].transac_type =
CAM_AXI_TRANSACTION_READ;
axi_vote.axi_path[0].camnoc_bw =
CAM_CPAS_DEFAULT_AXI_BW;
axi_vote.axi_path[0].mnoc_ab_bw =
CAM_CPAS_DEFAULT_AXI_BW;
axi_vote.axi_path[0].mnoc_ib_bw =
CAM_CPAS_DEFAULT_AXI_BW;
rc = cam_cpas_start(core->cpas_handle,
&ahb_vote, &axi_vote);
if (rc != 0) {
CAM_ERR(CAM_CDM, "CPAS start failed");
goto end;
}
CAM_DBG(CAM_CDM, "CDM init first time");
if (core->id == CAM_CDM_VIRTUAL) {
CAM_DBG(CAM_CDM,
"Virtual CDM HW init first time");
rc = 0;
} else {
CAM_DBG(CAM_CDM, "CDM HW init first time");
rc = cam_cdm_stream_handle_init(hw_priv, true);
}
if (rc == 0) {
cdm_hw->open_count++;
client->stream_on = true;
} else {
if (cam_cpas_stop(core->cpas_handle))
CAM_ERR(CAM_CDM, "CPAS stop failed");
}
} else {
cdm_hw->open_count++;
CAM_DBG(CAM_CDM, "CDM HW already ON count=%d",
cdm_hw->open_count);
rc = 0;
client->stream_on = true;
}
} else {
if (cdm_hw->open_count) {
cdm_hw->open_count--;
CAM_DBG(CAM_CDM, "stream OFF CDM %d",
cdm_hw->open_count);
if (!cdm_hw->open_count) {
CAM_DBG(CAM_CDM, "CDM Deinit now");
if (core->id == CAM_CDM_VIRTUAL) {
CAM_DBG(CAM_CDM,
"Virtual CDM HW Deinit");
rc = 0;
} else {
CAM_DBG(CAM_CDM, "CDM HW Deinit now");
rc = cam_cdm_stream_handle_init(hw_priv,
false);
}
if (rc == 0) {
client->stream_on = false;
rc = cam_cpas_stop(core->cpas_handle);
if (rc)
CAM_ERR(CAM_CDM,
"CPAS stop failed");
}
} else {
client->stream_on = false;
rc = 0;
CAM_DBG(CAM_CDM,
"Client stream off success =%d",
cdm_hw->open_count);
}
} else {
CAM_DBG(CAM_CDM, "stream OFF CDM Invalid %d",
cdm_hw->open_count);
rc = -ENXIO;
}
}
end:
cam_cdm_put_client_refcount(client);
mutex_unlock(&cdm_hw->hw_mutex);
return rc;
}
int cam_cdm_stream_start(void *hw_priv,
void *start_args, uint32_t size)
{
int rc = 0;
if (!hw_priv)
return -EINVAL;
rc = cam_cdm_stream_ops_internal(hw_priv, start_args, true);
return rc;
}
int cam_cdm_stream_stop(void *hw_priv,
void *start_args, uint32_t size)
{
int rc = 0;
if (!hw_priv)
return -EINVAL;
rc = cam_cdm_stream_ops_internal(hw_priv, start_args, false);
return rc;
}
int cam_cdm_process_cmd(void *hw_priv,
uint32_t cmd, void *cmd_args, uint32_t arg_size)
{
struct cam_hw_info *cdm_hw = hw_priv;
struct cam_hw_soc_info *soc_data = NULL;
struct cam_cdm *core = NULL;
int rc = -EINVAL;
if ((!hw_priv) || (!cmd_args) ||
(cmd >= CAM_CDM_HW_INTF_CMD_INVALID))
return rc;
soc_data = &cdm_hw->soc_info;
core = (struct cam_cdm *)cdm_hw->core_info;
switch (cmd) {
case CAM_CDM_HW_INTF_CMD_SUBMIT_BL: {
struct cam_cdm_hw_intf_cmd_submit_bl *req;
int idx;
struct cam_cdm_client *client;
if (sizeof(struct cam_cdm_hw_intf_cmd_submit_bl) != arg_size) {
CAM_ERR(CAM_CDM, "Invalid CDM cmd %d arg size=%x", cmd,
arg_size);
break;
}
req = (struct cam_cdm_hw_intf_cmd_submit_bl *)cmd_args;
if ((req->data->type < 0) ||
(req->data->type > CAM_CDM_BL_CMD_TYPE_KERNEL_IOVA)) {
CAM_ERR(CAM_CDM, "Invalid req bl cmd addr type=%d",
req->data->type);
break;
}
idx = CAM_CDM_GET_CLIENT_IDX(req->handle);
client = core->clients[idx];
if ((!client) || (req->handle != client->handle)) {
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client,
req->handle);
break;
}
cam_cdm_get_client_refcount(client);
if ((req->data->flag == true) &&
(!client->data.cam_cdm_callback)) {
CAM_ERR(CAM_CDM,
"CDM request cb without registering cb");
cam_cdm_put_client_refcount(client);
break;
}
if (client->stream_on != true) {
CAM_ERR(CAM_CDM,
"Invalid CDM needs to be streamed ON first");
cam_cdm_put_client_refcount(client);
break;
}
if (core->id == CAM_CDM_VIRTUAL)
rc = cam_virtual_cdm_submit_bl(cdm_hw, req, client);
else
rc = cam_hw_cdm_submit_bl(cdm_hw, req, client);
cam_cdm_put_client_refcount(client);
break;
}
case CAM_CDM_HW_INTF_CMD_ACQUIRE: {
struct cam_cdm_acquire_data *data;
int idx;
struct cam_cdm_client *client;
if (sizeof(struct cam_cdm_acquire_data) != arg_size) {
CAM_ERR(CAM_CDM, "Invalid CDM cmd %d arg size=%x", cmd,
arg_size);
break;
}
mutex_lock(&cdm_hw->hw_mutex);
data = (struct cam_cdm_acquire_data *)cmd_args;
CAM_DBG(CAM_CDM, "Trying to acquire client=%s in hw idx=%d",
data->identifier, core->index);
if (data->priority >= CAM_CDM_BL_FIFO_MAX) {
mutex_unlock(&cdm_hw->hw_mutex);
CAM_ERR(CAM_CDM,
"Invalid priority requested %d",
data->priority);
rc = -EINVAL;
break;
}
if (core->id != CAM_CDM_VIRTUAL &&
core->bl_fifo[data->priority].bl_depth == 0) {
mutex_unlock(&cdm_hw->hw_mutex);
CAM_ERR(CAM_CDM,
"FIFO %d not supported for core %d",
data->priority,
core->id);
rc = -EINVAL;
break;
}
idx = cam_cdm_find_free_client_slot(core);
if ((idx < 0) || (core->clients[idx])) {
mutex_unlock(&cdm_hw->hw_mutex);
CAM_ERR(CAM_CDM,
"Fail to client slots, client=%s in hw idx=%d",
data->identifier, core->index);
break;
}
core->clients[idx] = kzalloc(sizeof(struct cam_cdm_client),
GFP_KERNEL);
if (!core->clients[idx]) {
mutex_unlock(&cdm_hw->hw_mutex);
rc = -ENOMEM;
break;
}
mutex_unlock(&cdm_hw->hw_mutex);
client = core->clients[idx];
mutex_init(&client->lock);
data->ops = core->ops;
if (core->id == CAM_CDM_VIRTUAL) {
data->cdm_version.major = 1;
data->cdm_version.minor = 0;
data->cdm_version.incr = 0;
data->cdm_version.reserved = 0;
data->ops = cam_cdm_get_ops(0,
&data->cdm_version, true);
if (!data->ops) {
mutex_destroy(&client->lock);
mutex_lock(&cdm_hw->hw_mutex);
kfree(core->clients[idx]);
core->clients[idx] = NULL;
mutex_unlock(
&cdm_hw->hw_mutex);
rc = -EPERM;
CAM_ERR(CAM_CDM, "Invalid ops for virtual cdm");
break;
}
} else {
data->cdm_version = core->version;
}
cam_cdm_get_client_refcount(client);
mutex_lock(&client->lock);
memcpy(&client->data, data,
sizeof(struct cam_cdm_acquire_data));
client->handle = CAM_CDM_CREATE_CLIENT_HANDLE(
core->index,
data->priority,
idx);
client->stream_on = false;
data->handle = client->handle;
CAM_DBG(CAM_CDM, "Acquired client=%s in hwidx=%d",
data->identifier, core->index);
mutex_unlock(&client->lock);
rc = 0;
break;
}
case CAM_CDM_HW_INTF_CMD_RELEASE: {
uint32_t *handle = cmd_args;
int idx;
struct cam_cdm_client *client;
if (sizeof(uint32_t) != arg_size) {
CAM_ERR(CAM_CDM,
"Invalid CDM cmd %d size=%x for handle=%x",
cmd, arg_size, *handle);
return -EINVAL;
}
idx = CAM_CDM_GET_CLIENT_IDX(*handle);
mutex_lock(&cdm_hw->hw_mutex);
client = core->clients[idx];
if ((!client) || (*handle != client->handle)) {
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x",
client, *handle);
mutex_unlock(&cdm_hw->hw_mutex);
break;
}
cam_cdm_put_client_refcount(client);
mutex_lock(&client->lock);
if (client->refcount != 0) {
CAM_ERR(CAM_CDM, "CDM Client refcount not zero %d",
client->refcount);
rc = -EPERM;
mutex_unlock(&client->lock);
mutex_unlock(&cdm_hw->hw_mutex);
break;
}
core->clients[idx] = NULL;
mutex_unlock(&client->lock);
mutex_destroy(&client->lock);
kfree(client);
mutex_unlock(&cdm_hw->hw_mutex);
rc = 0;
break;
}
case CAM_CDM_HW_INTF_CMD_RESET_HW: {
uint32_t *handle = cmd_args;
int idx;
struct cam_cdm_client *client;
if (sizeof(uint32_t) != arg_size) {
CAM_ERR(CAM_CDM,
"Invalid CDM cmd %d size=%x for handle=%x",
cmd, arg_size, *handle);
return -EINVAL;
}
idx = CAM_CDM_GET_CLIENT_IDX(*handle);
mutex_lock(&cdm_hw->hw_mutex);
client = core->clients[idx];
if (!client) {
CAM_ERR(CAM_CDM,
"Client not present for handle %d",
*handle);
mutex_unlock(&cdm_hw->hw_mutex);
break;
}
if (*handle != client->handle) {
CAM_ERR(CAM_CDM,
"handle mismatch, client handle %d index %d received handle %d",
client->handle, idx, *handle);
mutex_unlock(&cdm_hw->hw_mutex);
break;
}
rc = cam_hw_cdm_reset_hw(cdm_hw, *handle);
if (rc) {
CAM_ERR(CAM_CDM,
"CDM HW reset failed for handle 0x%x rc = %d",
*handle, rc);
} else {
CAM_INFO_RATE_LIMIT(CAM_CDM,
"CDM HW reset done for handle 0x%x",
*handle);
}
mutex_unlock(&cdm_hw->hw_mutex);
break;
}
case CAM_CDM_HW_INTF_CMD_FLUSH_HW: {
uint32_t *handle = cmd_args;
int idx;
struct cam_cdm_client *client;
if (sizeof(uint32_t) != arg_size) {
CAM_ERR(CAM_CDM,
"Invalid CDM cmd %d size=%x for handle=%x",
cmd, arg_size, *handle);
return -EINVAL;
}
idx = CAM_CDM_GET_CLIENT_IDX(*handle);
mutex_lock(&cdm_hw->hw_mutex);
client = core->clients[idx];
if (!client) {
CAM_ERR(CAM_CDM,
"Client not present for handle %d",
*handle);
mutex_unlock(&cdm_hw->hw_mutex);
break;
}
if (*handle != client->handle) {
CAM_ERR(CAM_CDM,
"handle mismatch, client handle %d index %d received handle %d",
client->handle, idx, *handle);
mutex_unlock(&cdm_hw->hw_mutex);
break;
}
rc = cam_hw_cdm_flush_hw(cdm_hw, *handle);
if (rc) {
CAM_ERR(CAM_CDM,
"CDM HW flush failed for handle 0x%x rc = %d",
*handle, rc);
} else {
CAM_INFO_RATE_LIMIT(CAM_CDM,
"CDM HW flush done for handle 0x%x",
*handle);
}
mutex_unlock(&cdm_hw->hw_mutex);
break;
}
case CAM_CDM_HW_INTF_CMD_HANDLE_ERROR: {
uint32_t *handle = cmd_args;
int idx;
struct cam_cdm_client *client;
if (sizeof(uint32_t) != arg_size) {
CAM_ERR(CAM_CDM,
"Invalid CDM cmd %d size=%x for handle=%x",
cmd, arg_size, *handle);
return -EINVAL;
}
idx = CAM_CDM_GET_CLIENT_IDX(*handle);
mutex_lock(&cdm_hw->hw_mutex);
client = core->clients[idx];
if (!client) {
CAM_ERR(CAM_CDM,
"Client not present for handle %d",
*handle);
mutex_unlock(&cdm_hw->hw_mutex);
break;
}
if (*handle != client->handle) {
CAM_ERR(CAM_CDM,
"handle mismatch, client handle %d index %d received handle %d",
client->handle, idx, *handle);
mutex_unlock(&cdm_hw->hw_mutex);
break;
}
rc = cam_hw_cdm_handle_error(cdm_hw, *handle);
if (rc) {
CAM_ERR(CAM_CDM,
"CDM HW handle error failed for handle 0x%x rc = %d",
*handle, rc);
} else {
CAM_INFO_RATE_LIMIT(CAM_CDM,
"CDM HW handle error done for handle 0x%x",
*handle);
}
mutex_unlock(&cdm_hw->hw_mutex);
break;
}
case CAM_CDM_HW_INTF_CMD_HANG_DETECT: {
uint32_t *handle = cmd_args;
int idx;
struct cam_cdm_client *client;
if (sizeof(uint32_t) != arg_size) {
CAM_ERR(CAM_CDM,
"Invalid CDM cmd %d size=%x for handle=%x",
cmd, arg_size, *handle);
return -EINVAL;
}
idx = CAM_CDM_GET_CLIENT_IDX(*handle);
client = core->clients[idx];
if (!client) {
CAM_ERR(CAM_CDM,
"Client not present for handle %d",
*handle);
break;
}
if (*handle != client->handle) {
CAM_ERR(CAM_CDM,
"handle mismatch, client handle %d index %d received handle %d",
client->handle, idx, *handle);
break;
}
rc = cam_hw_cdm_hang_detect(cdm_hw, *handle);
break;
}
case CAM_CDM_HW_INTF_DUMP_DBG_REGS:
{
uint32_t *handle = cmd_args;
if (sizeof(uint32_t) != arg_size) {
CAM_ERR(CAM_CDM,
"Invalid CDM cmd %d size=%x for handle=0x%x",
cmd, arg_size, *handle);
return -EINVAL;
}
mutex_lock(&cdm_hw->hw_mutex);
cam_hw_cdm_dump_core_debug_registers(cdm_hw, true);
mutex_unlock(&cdm_hw->hw_mutex);
break;
}
default:
CAM_ERR(CAM_CDM, "CDM HW intf command not valid =%d", cmd);
break;
}
return rc;
}

View file

@ -0,0 +1,62 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CDM_CORE_COMMON_H_
#define _CAM_CDM_CORE_COMMON_H_
#include "cam_mem_mgr.h"
#define CAM_CDM100_VERSION 0x10000000
#define CAM_CDM110_VERSION 0x10010000
#define CAM_CDM120_VERSION 0x10020000
#define CAM_CDM200_VERSION 0x20000000
#define CAM_CDM210_VERSION 0x20010000
#define CAM_CDM_AHB_BURST_LEN_1 (BIT(1) - 1)
#define CAM_CDM_AHB_BURST_LEN_4 (BIT(2) - 1)
#define CAM_CDM_AHB_BURST_LEN_8 (BIT(3) - 1)
#define CAM_CDM_AHB_BURST_LEN_16 (BIT(4) - 1)
#define CAM_CDM_AHB_BURST_EN BIT(4)
#define CAM_CDM_AHB_STOP_ON_ERROR BIT(8)
#define CAM_CDM_ARB_SEL_RR BIT(16)
#define CAM_CDM_IMPLICIT_WAIT_EN BIT(17)
extern struct cam_cdm_utils_ops CDM170_ops;
int cam_hw_cdm_init(void *hw_priv, void *init_hw_args, uint32_t arg_size);
int cam_hw_cdm_deinit(void *hw_priv, void *init_hw_args, uint32_t arg_size);
int cam_hw_cdm_alloc_genirq_mem(void *hw_priv);
int cam_hw_cdm_release_genirq_mem(void *hw_priv);
int cam_cdm_get_caps(void *hw_priv, void *get_hw_cap_args, uint32_t arg_size);
int cam_cdm_stream_ops_internal(void *hw_priv, void *start_args,
bool operation);
int cam_cdm_stream_start(void *hw_priv, void *start_args, uint32_t size);
int cam_cdm_stream_stop(void *hw_priv, void *start_args, uint32_t size);
int cam_cdm_process_cmd(void *hw_priv, uint32_t cmd, void *cmd_args,
uint32_t arg_size);
bool cam_cdm_set_cam_hw_version(
uint32_t ver, struct cam_hw_version *cam_version);
bool cam_cdm_cpas_cb(uint32_t client_handle, void *userdata,
struct cam_cpas_irq_data *irq_data);
struct cam_cdm_utils_ops *cam_cdm_get_ops(
uint32_t ver, struct cam_hw_version *cam_version, bool by_cam_version);
int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
struct cam_cdm_hw_intf_cmd_submit_bl *req,
struct cam_cdm_client *client);
int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
struct cam_cdm_hw_intf_cmd_submit_bl *req,
struct cam_cdm_client *client);
int cam_hw_cdm_reset_hw(struct cam_hw_info *cdm_hw, uint32_t handle);
int cam_hw_cdm_flush_hw(struct cam_hw_info *cdm_hw, uint32_t handle);
int cam_hw_cdm_handle_error(struct cam_hw_info *cdm_hw, uint32_t handle);
int cam_hw_cdm_hang_detect(struct cam_hw_info *cdm_hw, uint32_t handle);
struct cam_cdm_bl_cb_request_entry *cam_cdm_find_request_by_bl_tag(
uint32_t tag, struct list_head *bl_list);
void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
enum cam_cdm_cb_status status, void *data);
void cam_hw_cdm_dump_core_debug_registers(
struct cam_hw_info *cdm_hw, bool pause_core);
#endif /* _CAM_CDM_CORE_COMMON_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,160 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
#include "cam_cdm.h"
static struct cam_version_reg cdm_hw_1_0_titan_version = {
.hw_version = 0x4,
};
struct cam_cdm_bl_pending_req_reg_params cdm_hw_1_0_bl_pending_req0 = {
.rb_offset = 0x6c,
.rb_mask = 0x7F,
.rb_num_fifo = 0x1,
.rb_next_fifo_shift = 0x0,
};
static struct cam_cdm_irq_regs cdm_hw_1_0_irq0 = {
.irq_mask = 0x30,
.irq_clear = 0x34,
.irq_clear_cmd = 0x38,
.irq_set = 0x3c,
.irq_set_cmd = 0x40,
.irq_status = 0x44,
};
static struct cam_cdm_bl_fifo_regs cdm_hw_1_0_bl_fifo0 = {
.bl_fifo_base = 0x50,
.bl_fifo_len = 0x54,
.bl_fifo_store = 0x58,
.bl_fifo_cfg = 0x5c,
};
static struct cam_cdm_scratch_reg cdm_1_0_scratch_reg0 = {
.scratch_reg = 0x90,
};
static struct cam_cdm_scratch_reg cdm_1_0_scratch_reg1 = {
.scratch_reg = 0x94,
};
static struct cam_cdm_scratch_reg cdm_1_0_scratch_reg2 = {
.scratch_reg = 0x98,
};
static struct cam_cdm_scratch_reg cdm_1_0_scratch_reg3 = {
.scratch_reg = 0x9c,
};
static struct cam_cdm_scratch_reg cdm_1_0_scratch_reg4 = {
.scratch_reg = 0xa0,
};
static struct cam_cdm_scratch_reg cdm_1_0_scratch_reg5 = {
.scratch_reg = 0xa4,
};
static struct cam_cdm_scratch_reg cdm_1_0_scratch_reg6 = {
.scratch_reg = 0xa8,
};
static struct cam_cdm_scratch_reg cdm_1_0_scratch_reg7 = {
.scratch_reg = 0xac,
};
static struct cam_cdm_perf_mon_regs cdm_1_0_perf_mon0 = {
.perf_mon_ctrl = 0x110,
.perf_mon_0 = 0x114,
.perf_mon_1 = 0x118,
.perf_mon_2 = 0x11c,
};
static struct cam_cdm_comp_wait_status cdm_1_0_comp_wait_status0 = {
.comp_wait_status = 0x88,
};
static struct cam_cdm_comp_wait_status cdm_1_0_comp_wait_status1 = {
.comp_wait_status = 0x8c,
};
static struct cam_cdm_common_regs cdm_hw_1_0_cmn_reg_offset = {
.cdm_hw_version = 0x0,
.cam_version = &cdm_hw_1_0_titan_version,
.rst_cmd = 0x10,
.cgc_cfg = 0x14,
.core_cfg = 0x18,
.core_en = 0x1c,
.fe_cfg = 0x20,
.bl_fifo_rb = 0x60,
.bl_fifo_base_rb = 0x64,
.bl_fifo_len_rb = 0x68,
.usr_data = 0x80,
.wait_status = 0x84,
.last_ahb_addr = 0xd0,
.last_ahb_data = 0xd4,
.core_debug = 0xd8,
.last_ahb_err_addr = 0xe0,
.last_ahb_err_data = 0xe4,
.current_bl_base = 0xe8,
.current_bl_len = 0xec,
.current_used_ahb_base = 0xf0,
.debug_status = 0xf4,
.bus_misr_cfg0 = 0x100,
.bus_misr_cfg1 = 0x104,
.bus_misr_rd_val = 0x108,
.pending_req = {
&cdm_hw_1_0_bl_pending_req0,
NULL,
},
.comp_wait = {
&cdm_1_0_comp_wait_status0,
&cdm_1_0_comp_wait_status1,
},
.perf_mon = {
&cdm_1_0_perf_mon0,
NULL,
},
.scratch = {
&cdm_1_0_scratch_reg0,
&cdm_1_0_scratch_reg1,
&cdm_1_0_scratch_reg2,
&cdm_1_0_scratch_reg3,
&cdm_1_0_scratch_reg4,
&cdm_1_0_scratch_reg5,
&cdm_1_0_scratch_reg6,
&cdm_1_0_scratch_reg7,
NULL,
NULL,
NULL,
NULL,
},
.perf_reg = NULL,
.icl_reg = NULL,
.spare = 0x200,
};
static struct cam_cdm_common_reg_data cdm_hw_1_0_cmn_reg_data = {
.num_bl_fifo = 0x1,
.num_bl_fifo_irq = 0x1,
.num_bl_pending_req_reg = 0x1,
.num_scratch_reg = 0x8,
};
static struct cam_cdm_hw_reg_offset cam_cdm_1_0_reg_offset = {
.cmn_reg = &cdm_hw_1_0_cmn_reg_offset,
.bl_fifo_reg = {
&cdm_hw_1_0_bl_fifo0,
NULL,
NULL,
NULL,
},
.irq_reg = {
&cdm_hw_1_0_irq0,
NULL,
NULL,
NULL,
},
.reg_data = &cdm_hw_1_0_cmn_reg_data,
};

View file

@ -0,0 +1,160 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#include "cam_cdm.h"
static struct cam_version_reg cdm_hw_1_1_titan_version = {
.hw_version = 0x4,
};
struct cam_cdm_bl_pending_req_reg_params cdm_hw_1_1_bl_pending_req0 = {
.rb_offset = 0x6c,
.rb_mask = 0x7f,
.rb_num_fifo = 0x1,
.rb_next_fifo_shift = 0x0,
};
static struct cam_cdm_irq_regs cdm_hw_1_1_irq0 = {
.irq_mask = 0x30,
.irq_clear = 0x34,
.irq_clear_cmd = 0x38,
.irq_set = 0x3c,
.irq_set_cmd = 0x40,
.irq_status = 0x44,
};
static struct cam_cdm_bl_fifo_regs cdm_hw_1_1_bl_fifo0 = {
.bl_fifo_base = 0x50,
.bl_fifo_len = 0x54,
.bl_fifo_store = 0x58,
.bl_fifo_cfg = 0x5c,
};
static struct cam_cdm_scratch_reg cdm_1_1_scratch_reg0 = {
.scratch_reg = 0x90,
};
static struct cam_cdm_scratch_reg cdm_1_1_scratch_reg1 = {
.scratch_reg = 0x94,
};
static struct cam_cdm_scratch_reg cdm_1_1_scratch_reg2 = {
.scratch_reg = 0x98,
};
static struct cam_cdm_scratch_reg cdm_1_1_scratch_reg3 = {
.scratch_reg = 0x9c,
};
static struct cam_cdm_scratch_reg cdm_1_1_scratch_reg4 = {
.scratch_reg = 0xa0,
};
static struct cam_cdm_scratch_reg cdm_1_1_scratch_reg5 = {
.scratch_reg = 0xa4,
};
static struct cam_cdm_scratch_reg cdm_1_1_scratch_reg6 = {
.scratch_reg = 0xa8,
};
static struct cam_cdm_scratch_reg cdm_1_1_scratch_reg7 = {
.scratch_reg = 0xac,
};
static struct cam_cdm_perf_mon_regs cdm_1_1_perf_mon0 = {
.perf_mon_ctrl = 0x110,
.perf_mon_0 = 0x114,
.perf_mon_1 = 0x118,
.perf_mon_2 = 0x11c,
};
static struct cam_cdm_comp_wait_status cdm_1_1_comp_wait_status0 = {
.comp_wait_status = 0x88,
};
static struct cam_cdm_comp_wait_status cdm_1_1_comp_wait_status1 = {
.comp_wait_status = 0x8c,
};
static struct cam_cdm_common_regs cdm_hw_1_1_cmn_reg_offset = {
.cdm_hw_version = 0x0,
.cam_version = &cdm_hw_1_1_titan_version,
.rst_cmd = 0x10,
.cgc_cfg = 0x14,
.core_cfg = 0x18,
.core_en = 0x1c,
.fe_cfg = 0x20,
.bl_fifo_rb = 0x60,
.bl_fifo_base_rb = 0x64,
.bl_fifo_len_rb = 0x68,
.usr_data = 0x80,
.wait_status = 0x84,
.last_ahb_addr = 0xd0,
.last_ahb_data = 0xd4,
.core_debug = 0xd8,
.last_ahb_err_addr = 0xe0,
.last_ahb_err_data = 0xe4,
.current_bl_base = 0xe8,
.current_bl_len = 0xec,
.current_used_ahb_base = 0xf0,
.debug_status = 0xf4,
.bus_misr_cfg0 = 0x100,
.bus_misr_cfg1 = 0x104,
.bus_misr_rd_val = 0x108,
.pending_req = {
&cdm_hw_1_1_bl_pending_req0,
NULL,
},
.comp_wait = {
&cdm_1_1_comp_wait_status0,
&cdm_1_1_comp_wait_status1,
},
.perf_mon = {
&cdm_1_1_perf_mon0,
NULL,
},
.scratch = {
&cdm_1_1_scratch_reg0,
&cdm_1_1_scratch_reg1,
&cdm_1_1_scratch_reg2,
&cdm_1_1_scratch_reg3,
&cdm_1_1_scratch_reg4,
&cdm_1_1_scratch_reg5,
&cdm_1_1_scratch_reg6,
&cdm_1_1_scratch_reg7,
NULL,
NULL,
NULL,
NULL,
},
.perf_reg = NULL,
.icl_reg = NULL,
.spare = 0x1fc,
};
static struct cam_cdm_common_reg_data cdm_hw_1_1_cmn_reg_data = {
.num_bl_fifo = 0x1,
.num_bl_fifo_irq = 0x1,
.num_bl_pending_req_reg = 0x1,
.num_scratch_reg = 0x8,
};
struct cam_cdm_hw_reg_offset cam_cdm_1_1_reg_offset = {
.cmn_reg = &cdm_hw_1_1_cmn_reg_offset,
.bl_fifo_reg = {
&cdm_hw_1_1_bl_fifo0,
NULL,
NULL,
NULL,
},
.irq_reg = {
&cdm_hw_1_1_irq0,
NULL,
NULL,
NULL,
},
.reg_data = &cdm_hw_1_1_cmn_reg_data,
};

View file

@ -0,0 +1,180 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#include "cam_cdm.h"
static struct cam_version_reg cdm_hw_1_2_titan_version = {
.hw_version = 0x4,
};
struct cam_cdm_bl_pending_req_reg_params cdm_hw_1_2_bl_pending_req0 = {
.rb_offset = 0x6c,
.rb_mask = 0x7f,
.rb_num_fifo = 0x1,
.rb_next_fifo_shift = 0x0,
};
static struct cam_cdm_irq_regs cdm_hw_1_2_irq0 = {
.irq_mask = 0x30,
.irq_clear = 0x34,
.irq_clear_cmd = 0x38,
.irq_set = 0x3c,
.irq_set_cmd = 0x40,
.irq_status = 0x44,
};
static struct cam_cdm_bl_fifo_regs cdm_hw_1_2_bl_fifo0 = {
.bl_fifo_base = 0x50,
.bl_fifo_len = 0x54,
.bl_fifo_store = 0x58,
.bl_fifo_cfg = 0x5c,
};
static struct cam_cdm_scratch_reg cdm_1_2_scratch_reg0 = {
.scratch_reg = 0x90,
};
static struct cam_cdm_scratch_reg cdm_1_2_scratch_reg1 = {
.scratch_reg = 0x94,
};
static struct cam_cdm_scratch_reg cdm_1_2_scratch_reg2 = {
.scratch_reg = 0x98,
};
static struct cam_cdm_scratch_reg cdm_1_2_scratch_reg3 = {
.scratch_reg = 0x9c,
};
static struct cam_cdm_scratch_reg cdm_1_2_scratch_reg4 = {
.scratch_reg = 0xa0,
};
static struct cam_cdm_scratch_reg cdm_1_2_scratch_reg5 = {
.scratch_reg = 0xa4,
};
static struct cam_cdm_scratch_reg cdm_1_2_scratch_reg6 = {
.scratch_reg = 0xa8,
};
static struct cam_cdm_scratch_reg cdm_1_2_scratch_reg7 = {
.scratch_reg = 0xac,
};
static struct cam_cdm_perf_mon_regs cdm_1_2_perf_mon0 = {
.perf_mon_ctrl = 0x110,
.perf_mon_0 = 0x114,
.perf_mon_1 = 0x118,
.perf_mon_2 = 0x11c,
};
static struct cam_cdm_comp_wait_status cdm_1_2_comp_wait_status0 = {
.comp_wait_status = 0x88,
};
static struct cam_cdm_comp_wait_status cdm_1_2_comp_wait_status1 = {
.comp_wait_status = 0x8c,
};
static struct cam_cdm_perf_regs cdm_1_2_perf = {
.count_cfg_0 = 0x180,
.always_count_val = 0x184,
.busy_count_val = 0x188,
.stall_axi_count_val = 0x18c,
.count_status = 0x190,
};
static struct cam_cdm_icl_data_regs cdm_1_2_icl_data = {
.icl_last_data_0 = 0x1c0,
.icl_last_data_1 = 0x1c4,
.icl_last_data_2 = 0x1c8,
.icl_inv_data = 0x1cc,
};
static struct cam_cdm_icl_regs cdm_1_2_icl = {
.data_regs = &cdm_1_2_icl_data,
.misc_regs = NULL,
};
static struct cam_cdm_common_regs cdm_hw_1_2_cmn_reg_offset = {
.cdm_hw_version = 0x0,
.cam_version = &cdm_hw_1_2_titan_version,
.rst_cmd = 0x10,
.cgc_cfg = 0x14,
.core_cfg = 0x18,
.core_en = 0x1c,
.fe_cfg = 0x20,
.bl_fifo_rb = 0x60,
.bl_fifo_base_rb = 0x64,
.bl_fifo_len_rb = 0x68,
.usr_data = 0x80,
.wait_status = 0x84,
.last_ahb_addr = 0xd0,
.last_ahb_data = 0xd4,
.core_debug = 0xd8,
.last_ahb_err_addr = 0xe0,
.last_ahb_err_data = 0xe4,
.current_bl_base = 0xe8,
.current_bl_len = 0xec,
.current_used_ahb_base = 0xf0,
.debug_status = 0xf4,
.bus_misr_cfg0 = 0x100,
.bus_misr_cfg1 = 0x104,
.bus_misr_rd_val = 0x108,
.pending_req = {
&cdm_hw_1_2_bl_pending_req0,
NULL,
},
.comp_wait = {
&cdm_1_2_comp_wait_status0,
&cdm_1_2_comp_wait_status1,
},
.perf_mon = {
&cdm_1_2_perf_mon0,
NULL,
},
.scratch = {
&cdm_1_2_scratch_reg0,
&cdm_1_2_scratch_reg1,
&cdm_1_2_scratch_reg2,
&cdm_1_2_scratch_reg3,
&cdm_1_2_scratch_reg4,
&cdm_1_2_scratch_reg5,
&cdm_1_2_scratch_reg6,
&cdm_1_2_scratch_reg7,
NULL,
NULL,
NULL,
NULL,
},
.perf_reg = &cdm_1_2_perf,
.icl_reg = &cdm_1_2_icl,
.spare = 0x1fc,
};
static struct cam_cdm_common_reg_data cdm_hw_1_2_cmn_reg_data = {
.num_bl_fifo = 0x1,
.num_bl_fifo_irq = 0x1,
.num_bl_pending_req_reg = 0x1,
.num_scratch_reg = 0x8,
};
struct cam_cdm_hw_reg_offset cam_cdm_1_2_reg_offset = {
.cmn_reg = &cdm_hw_1_2_cmn_reg_offset,
.bl_fifo_reg = {
&cdm_hw_1_2_bl_fifo0,
NULL,
NULL,
NULL,
},
.irq_reg = {
&cdm_hw_1_2_irq0,
NULL,
NULL,
NULL,
},
.reg_data = &cdm_hw_1_2_cmn_reg_data,
};

View file

@ -0,0 +1,251 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#include "cam_cdm.h"
struct cam_cdm_bl_pending_req_reg_params cdm_hw_2_0_bl_pending_req0 = {
.rb_offset = 0x6c,
.rb_mask = 0x1ff,
.rb_num_fifo = 0x2,
.rb_next_fifo_shift = 0x10,
};
struct cam_cdm_bl_pending_req_reg_params cdm_hw_2_0_bl_pending_req1 = {
.rb_offset = 0x70,
.rb_mask = 0x1ff,
.rb_num_fifo = 0x2,
.rb_next_fifo_shift = 0x10,
};
static struct cam_cdm_irq_regs cdm_hw_2_0_irq0 = {
.irq_mask = 0x30,
.irq_clear = 0x34,
.irq_clear_cmd = 0x38,
.irq_set = 0x3c,
.irq_set_cmd = 0x40,
.irq_status = 0x44,
};
static struct cam_cdm_irq_regs cdm_hw_2_0_irq1 = {
.irq_mask = 0x130,
.irq_clear = 0x134,
.irq_clear_cmd = 0x138,
.irq_set = 0x13c,
.irq_set_cmd = 0x140,
.irq_status = 0x144,
};
static struct cam_cdm_irq_regs cdm_hw_2_0_irq2 = {
.irq_mask = 0x230,
.irq_clear = 0x234,
.irq_clear_cmd = 0x238,
.irq_set = 0x23c,
.irq_set_cmd = 0x240,
.irq_status = 0x244,
};
static struct cam_cdm_irq_regs cdm_hw_2_0_irq3 = {
.irq_mask = 0x330,
.irq_clear = 0x334,
.irq_clear_cmd = 0x338,
.irq_set = 0x33c,
.irq_set_cmd = 0x340,
.irq_status = 0x344,
};
static struct cam_cdm_bl_fifo_regs cdm_hw_2_0_bl_fifo0 = {
.bl_fifo_base = 0x50,
.bl_fifo_len = 0x54,
.bl_fifo_store = 0x58,
.bl_fifo_cfg = 0x5c,
};
static struct cam_cdm_bl_fifo_regs cdm_hw_2_0_bl_fifo1 = {
.bl_fifo_base = 0x150,
.bl_fifo_len = 0x154,
.bl_fifo_store = 0x158,
.bl_fifo_cfg = 0x15c,
};
static struct cam_cdm_bl_fifo_regs cdm_hw_2_0_bl_fifo2 = {
.bl_fifo_base = 0x250,
.bl_fifo_len = 0x254,
.bl_fifo_store = 0x258,
.bl_fifo_cfg = 0x25c,
};
static struct cam_cdm_bl_fifo_regs cdm_hw_2_0_bl_fifo3 = {
.bl_fifo_base = 0x350,
.bl_fifo_len = 0x354,
.bl_fifo_store = 0x358,
.bl_fifo_cfg = 0x35c,
};
static struct cam_cdm_scratch_reg cdm_2_0_scratch_reg0 = {
.scratch_reg = 0x90,
};
static struct cam_cdm_scratch_reg cdm_2_0_scratch_reg1 = {
.scratch_reg = 0x94,
};
static struct cam_cdm_scratch_reg cdm_2_0_scratch_reg2 = {
.scratch_reg = 0x98,
};
static struct cam_cdm_scratch_reg cdm_2_0_scratch_reg3 = {
.scratch_reg = 0x9c,
};
static struct cam_cdm_scratch_reg cdm_2_0_scratch_reg4 = {
.scratch_reg = 0xa0,
};
static struct cam_cdm_scratch_reg cdm_2_0_scratch_reg5 = {
.scratch_reg = 0xa4,
};
static struct cam_cdm_scratch_reg cdm_2_0_scratch_reg6 = {
.scratch_reg = 0xa8,
};
static struct cam_cdm_scratch_reg cdm_2_0_scratch_reg7 = {
.scratch_reg = 0xac,
};
static struct cam_cdm_scratch_reg cdm_2_0_scratch_reg8 = {
.scratch_reg = 0xb0,
};
static struct cam_cdm_scratch_reg cdm_2_0_scratch_reg9 = {
.scratch_reg = 0xb4,
};
static struct cam_cdm_scratch_reg cdm_2_0_scratch_reg10 = {
.scratch_reg = 0xb8,
};
static struct cam_cdm_scratch_reg cdm_2_0_scratch_reg11 = {
.scratch_reg = 0xbc,
};
static struct cam_cdm_perf_mon_regs cdm_2_0_perf_mon0 = {
.perf_mon_ctrl = 0x110,
.perf_mon_0 = 0x114,
.perf_mon_1 = 0x118,
.perf_mon_2 = 0x11c,
};
static struct cam_cdm_perf_mon_regs cdm_2_0_perf_mon1 = {
.perf_mon_ctrl = 0x120,
.perf_mon_0 = 0x124,
.perf_mon_1 = 0x128,
.perf_mon_2 = 0x12c,
};
static struct cam_cdm_comp_wait_status cdm_2_0_comp_wait_status0 = {
.comp_wait_status = 0x88,
};
static struct cam_cdm_comp_wait_status cdm_2_0_comp_wait_status1 = {
.comp_wait_status = 0x8c,
};
static struct cam_cdm_icl_data_regs cdm_2_0_icl_data = {
.icl_last_data_0 = 0x1c0,
.icl_last_data_1 = 0x1c4,
.icl_last_data_2 = 0x1c8,
.icl_inv_data = 0x1cc,
};
static struct cam_cdm_icl_misc_regs cdm_2_0_icl_misc = {
.icl_inv_bl_addr = 0x1d0,
.icl_status = 0x1d4,
};
static struct cam_cdm_icl_regs cdm_2_0_icl = {
.data_regs = &cdm_2_0_icl_data,
.misc_regs = &cdm_2_0_icl_misc,
};
static struct cam_cdm_common_regs cdm_hw_2_0_cmn_reg_offset = {
.cdm_hw_version = 0x0,
.cam_version = NULL,
.rst_cmd = 0x10,
.cgc_cfg = 0x14,
.core_cfg = 0x18,
.core_en = 0x1c,
.fe_cfg = 0x20,
.bl_fifo_rb = 0x60,
.bl_fifo_base_rb = 0x64,
.bl_fifo_len_rb = 0x68,
.usr_data = 0x80,
.wait_status = 0x84,
.last_ahb_addr = 0xd0,
.last_ahb_data = 0xd4,
.core_debug = 0xd8,
.last_ahb_err_addr = 0xe0,
.last_ahb_err_data = 0xe4,
.current_bl_base = 0xe8,
.current_bl_len = 0xec,
.current_used_ahb_base = 0xf0,
.debug_status = 0xf4,
.bus_misr_cfg0 = 0x100,
.bus_misr_cfg1 = 0x104,
.bus_misr_rd_val = 0x108,
.pending_req = {
&cdm_hw_2_0_bl_pending_req0,
&cdm_hw_2_0_bl_pending_req1,
},
.comp_wait = {
&cdm_2_0_comp_wait_status0,
&cdm_2_0_comp_wait_status1,
},
.perf_mon = {
&cdm_2_0_perf_mon0,
&cdm_2_0_perf_mon1,
},
.scratch = {
&cdm_2_0_scratch_reg0,
&cdm_2_0_scratch_reg1,
&cdm_2_0_scratch_reg2,
&cdm_2_0_scratch_reg3,
&cdm_2_0_scratch_reg4,
&cdm_2_0_scratch_reg5,
&cdm_2_0_scratch_reg6,
&cdm_2_0_scratch_reg7,
&cdm_2_0_scratch_reg8,
&cdm_2_0_scratch_reg9,
&cdm_2_0_scratch_reg10,
&cdm_2_0_scratch_reg11,
},
.perf_reg = NULL,
.icl_reg = &cdm_2_0_icl,
.spare = 0x1fc,
};
static struct cam_cdm_common_reg_data cdm_hw_2_0_cmn_reg_data = {
.num_bl_fifo = 0x4,
.num_bl_fifo_irq = 0x4,
.num_bl_pending_req_reg = 0x2,
.num_scratch_reg = 0xc,
};
struct cam_cdm_hw_reg_offset cam_cdm_2_0_reg_offset = {
.cmn_reg = &cdm_hw_2_0_cmn_reg_offset,
.bl_fifo_reg = {
&cdm_hw_2_0_bl_fifo0,
&cdm_hw_2_0_bl_fifo1,
&cdm_hw_2_0_bl_fifo2,
&cdm_hw_2_0_bl_fifo3,
},
.irq_reg = {
&cdm_hw_2_0_irq0,
&cdm_hw_2_0_irq1,
&cdm_hw_2_0_irq2,
&cdm_hw_2_0_irq3,
},
.reg_data = &cdm_hw_2_0_cmn_reg_data,
};

View file

@ -0,0 +1,261 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#include "cam_cdm.h"
struct cam_cdm_pid_mid_data cdm_hw_2_1_pid_mid_data = {
.cdm_pid = 2,
.cdm_mid = 0,
.ope_cdm_pid = 0,
.ope_cdm_mid = 2,
};
struct cam_cdm_bl_pending_req_reg_params cdm_hw_2_1_bl_pending_req0 = {
.rb_offset = 0x6c,
.rb_mask = 0x1ff,
.rb_num_fifo = 0x2,
.rb_next_fifo_shift = 0x10,
};
struct cam_cdm_bl_pending_req_reg_params cdm_hw_2_1_bl_pending_req1 = {
.rb_offset = 0x70,
.rb_mask = 0x1ff,
.rb_num_fifo = 0x2,
.rb_next_fifo_shift = 0x10,
};
static struct cam_cdm_irq_regs cdm_hw_2_1_irq0 = {
.irq_mask = 0x30,
.irq_clear = 0x34,
.irq_clear_cmd = 0x38,
.irq_set = 0x3c,
.irq_set_cmd = 0x40,
.irq_status = 0x44,
};
static struct cam_cdm_irq_regs cdm_hw_2_1_irq1 = {
.irq_mask = 0x130,
.irq_clear = 0x134,
.irq_clear_cmd = 0x138,
.irq_set = 0x13c,
.irq_set_cmd = 0x140,
.irq_status = 0x144,
};
static struct cam_cdm_irq_regs cdm_hw_2_1_irq2 = {
.irq_mask = 0x230,
.irq_clear = 0x234,
.irq_clear_cmd = 0x238,
.irq_set = 0x23c,
.irq_set_cmd = 0x240,
.irq_status = 0x244,
};
static struct cam_cdm_irq_regs cdm_hw_2_1_irq3 = {
.irq_mask = 0x330,
.irq_clear = 0x334,
.irq_clear_cmd = 0x338,
.irq_set = 0x33c,
.irq_set_cmd = 0x340,
.irq_status = 0x344,
};
static struct cam_cdm_bl_fifo_regs cdm_hw_2_1_bl_fifo0 = {
.bl_fifo_base = 0x50,
.bl_fifo_len = 0x54,
.bl_fifo_store = 0x58,
.bl_fifo_cfg = 0x5c,
};
static struct cam_cdm_bl_fifo_regs cdm_hw_2_1_bl_fifo1 = {
.bl_fifo_base = 0x150,
.bl_fifo_len = 0x154,
.bl_fifo_store = 0x158,
.bl_fifo_cfg = 0x15c,
};
static struct cam_cdm_bl_fifo_regs cdm_hw_2_1_bl_fifo2 = {
.bl_fifo_base = 0x250,
.bl_fifo_len = 0x254,
.bl_fifo_store = 0x258,
.bl_fifo_cfg = 0x25c,
};
static struct cam_cdm_bl_fifo_regs cdm_hw_2_1_bl_fifo3 = {
.bl_fifo_base = 0x350,
.bl_fifo_len = 0x354,
.bl_fifo_store = 0x358,
.bl_fifo_cfg = 0x35c,
};
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg0 = {
.scratch_reg = 0x90,
};
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg1 = {
.scratch_reg = 0x94,
};
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg2 = {
.scratch_reg = 0x98,
};
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg3 = {
.scratch_reg = 0x9c,
};
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg4 = {
.scratch_reg = 0xa0,
};
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg5 = {
.scratch_reg = 0xa4,
};
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg6 = {
.scratch_reg = 0xa8,
};
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg7 = {
.scratch_reg = 0xac,
};
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg8 = {
.scratch_reg = 0xb0,
};
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg9 = {
.scratch_reg = 0xb4,
};
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg10 = {
.scratch_reg = 0xb8,
};
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg11 = {
.scratch_reg = 0xbc,
};
static struct cam_cdm_perf_mon_regs cdm_2_1_perf_mon0 = {
.perf_mon_ctrl = 0x110,
.perf_mon_0 = 0x114,
.perf_mon_1 = 0x118,
.perf_mon_2 = 0x11c,
};
static struct cam_cdm_perf_mon_regs cdm_2_1_perf_mon1 = {
.perf_mon_ctrl = 0x120,
.perf_mon_0 = 0x124,
.perf_mon_1 = 0x128,
.perf_mon_2 = 0x12c,
};
static struct cam_cdm_comp_wait_status cdm_2_1_comp_wait_status0 = {
.comp_wait_status = 0x88,
};
static struct cam_cdm_comp_wait_status cdm_2_1_comp_wait_status1 = {
.comp_wait_status = 0x8c,
};
static struct cam_cdm_icl_data_regs cdm_2_1_icl_data = {
.icl_last_data_0 = 0x1c0,
.icl_last_data_1 = 0x1c4,
.icl_last_data_2 = 0x1c8,
.icl_inv_data = 0x1cc,
};
static struct cam_cdm_icl_misc_regs cdm_2_1_icl_misc = {
.icl_inv_bl_addr = 0x1d0,
.icl_status = 0x1d8,
};
static struct cam_cdm_icl_regs cdm_2_1_icl = {
.data_regs = &cdm_2_1_icl_data,
.misc_regs = &cdm_2_1_icl_misc,
};
static struct cam_cdm_common_regs cdm_hw_2_1_cmn_reg_offset = {
.cdm_hw_version = 0x0,
.cam_version = NULL,
.rst_cmd = 0x10,
.cgc_cfg = 0x14,
.core_cfg = 0x18,
.core_en = 0x1c,
.fe_cfg = 0x20,
.irq_context_status = 0x2c,
.bl_fifo_rb = 0x60,
.bl_fifo_base_rb = 0x64,
.bl_fifo_len_rb = 0x68,
.usr_data = 0x80,
.wait_status = 0x84,
.last_ahb_addr = 0xd0,
.last_ahb_data = 0xd4,
.core_debug = 0xd8,
.last_ahb_err_addr = 0xe0,
.last_ahb_err_data = 0xe4,
.current_bl_base = 0xe8,
.current_bl_len = 0xec,
.current_used_ahb_base = 0xf0,
.debug_status = 0xf4,
.bus_misr_cfg0 = 0x100,
.bus_misr_cfg1 = 0x104,
.bus_misr_rd_val = 0x108,
.pending_req = {
&cdm_hw_2_1_bl_pending_req0,
&cdm_hw_2_1_bl_pending_req1,
},
.comp_wait = {
&cdm_2_1_comp_wait_status0,
&cdm_2_1_comp_wait_status1,
},
.perf_mon = {
&cdm_2_1_perf_mon0,
&cdm_2_1_perf_mon1,
},
.scratch = {
&cdm_2_1_scratch_reg0,
&cdm_2_1_scratch_reg1,
&cdm_2_1_scratch_reg2,
&cdm_2_1_scratch_reg3,
&cdm_2_1_scratch_reg4,
&cdm_2_1_scratch_reg5,
&cdm_2_1_scratch_reg6,
&cdm_2_1_scratch_reg7,
&cdm_2_1_scratch_reg8,
&cdm_2_1_scratch_reg9,
&cdm_2_1_scratch_reg10,
&cdm_2_1_scratch_reg11,
},
.perf_reg = NULL,
.icl_reg = &cdm_2_1_icl,
.spare = 0x3fc,
.priority_group_bit_offset = 20,
.cdm_pid_mid_info = &cdm_hw_2_1_pid_mid_data,
};
static struct cam_cdm_common_reg_data cdm_hw_2_1_cmn_reg_data = {
.num_bl_fifo = 0x4,
.num_bl_fifo_irq = 0x4,
.num_bl_pending_req_reg = 0x2,
.num_scratch_reg = 0xc,
};
struct cam_cdm_hw_reg_offset cam_cdm_2_1_reg_offset = {
.cmn_reg = &cdm_hw_2_1_cmn_reg_offset,
.bl_fifo_reg = {
&cdm_hw_2_1_bl_fifo0,
&cdm_hw_2_1_bl_fifo1,
&cdm_hw_2_1_bl_fifo2,
&cdm_hw_2_1_bl_fifo3,
},
.irq_reg = {
&cdm_hw_2_1_irq0,
&cdm_hw_2_1_irq1,
&cdm_hw_2_1_irq2,
&cdm_hw_2_1_irq3,
},
.reg_data = &cdm_hw_2_1_cmn_reg_data,
};

View file

@ -0,0 +1,749 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include "cam_cdm_intf_api.h"
#include "cam_cdm.h"
#include "cam_cdm_virtual.h"
#include "cam_soc_util.h"
#include "cam_cdm_soc.h"
#include "cam_cdm_core_common.h"
#include "camera_main.h"
static struct cam_cdm_intf_mgr cdm_mgr;
static DEFINE_MUTEX(cam_cdm_mgr_lock);
static const struct of_device_id msm_cam_cdm_intf_dt_match[] = {
{ .compatible = "qcom,cam-cdm-intf", },
{}
};
static int get_cdm_mgr_refcount(void)
{
int rc = 0;
mutex_lock(&cam_cdm_mgr_lock);
if (cdm_mgr.probe_done == false) {
CAM_ERR(CAM_CDM, "CDM intf mgr not probed yet");
rc = -EPERM;
} else {
CAM_DBG(CAM_CDM, "CDM intf mgr get refcount=%d",
cdm_mgr.refcount);
cdm_mgr.refcount++;
}
mutex_unlock(&cam_cdm_mgr_lock);
return rc;
}
static void put_cdm_mgr_refcount(void)
{
mutex_lock(&cam_cdm_mgr_lock);
if (cdm_mgr.probe_done == false) {
CAM_ERR(CAM_CDM, "CDM intf mgr not probed yet");
} else {
CAM_DBG(CAM_CDM, "CDM intf mgr put refcount=%d",
cdm_mgr.refcount);
if (cdm_mgr.refcount > 0) {
cdm_mgr.refcount--;
} else {
CAM_ERR(CAM_CDM, "Refcount put when zero");
WARN_ON(1);
}
}
mutex_unlock(&cam_cdm_mgr_lock);
}
static int get_cdm_iommu_handle(struct cam_iommu_handle *cdm_handles,
uint32_t hw_idx)
{
int rc = -EPERM;
struct cam_hw_intf *hw = cdm_mgr.nodes[hw_idx].device;
if (hw->hw_ops.get_hw_caps) {
rc = hw->hw_ops.get_hw_caps(hw->hw_priv, cdm_handles,
sizeof(struct cam_iommu_handle));
}
return rc;
}
static int get_cdm_index_by_id(char *identifier,
uint32_t cell_index, uint32_t *hw_index)
{
int rc = -EPERM, i, j;
char client_name[128], name_index[160];
snprintf(client_name, sizeof(client_name), "%s", identifier);
snprintf(name_index, sizeof(name_index), "%s%d",
identifier, cell_index);
CAM_DBG(CAM_CDM,
"Looking for HW id of =%s or %s and index=%d cdm_count %d",
identifier, name_index, cell_index, cdm_mgr.cdm_count);
mutex_lock(&cam_cdm_mgr_lock);
for (i = 0; i < cdm_mgr.cdm_count; i++) {
mutex_lock(&cdm_mgr.nodes[i].lock);
CAM_DBG(CAM_CDM, "dt_num_supported_clients=%d",
cdm_mgr.nodes[i].data->dt_num_supported_clients);
for (j = 0; j <
cdm_mgr.nodes[i].data->dt_num_supported_clients; j++) {
CAM_DBG(CAM_CDM, "client name:%s dev Index: %d",
cdm_mgr.nodes[i].data->dt_cdm_client_name[j],
i);
if (!strcmp(
cdm_mgr.nodes[i].data->dt_cdm_client_name[j],
client_name) || !strcmp(
cdm_mgr.nodes[i].data->dt_cdm_client_name[j],
name_index)) {
rc = 0;
*hw_index = i;
break;
}
}
mutex_unlock(&cdm_mgr.nodes[i].lock);
if (rc == 0)
break;
}
mutex_unlock(&cam_cdm_mgr_lock);
return rc;
}
int cam_cdm_get_iommu_handle(char *identifier,
struct cam_iommu_handle *cdm_handles)
{
int i, j, rc = -EPERM;
if ((!identifier) || (!cdm_handles))
return -EINVAL;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
return rc;
}
CAM_DBG(CAM_CDM, "Looking for Iommu handle of %s", identifier);
for (i = 0; i < cdm_mgr.cdm_count; i++) {
mutex_lock(&cdm_mgr.nodes[i].lock);
if (!cdm_mgr.nodes[i].data) {
mutex_unlock(&cdm_mgr.nodes[i].lock);
continue;
}
CAM_DBG(CAM_CDM, "dt_num_supported_clients=%d",
cdm_mgr.nodes[i].data->dt_num_supported_clients);
for (j = 0; j <
cdm_mgr.nodes[i].data->dt_num_supported_clients;
j++) {
CAM_DBG(CAM_CDM, "client name:%s dev Index: %d",
cdm_mgr.nodes[i].data->dt_cdm_client_name[j],
i);
if (!strcmp(
cdm_mgr.nodes[i].data->dt_cdm_client_name[j],
identifier)) {
rc = get_cdm_iommu_handle(cdm_handles, i);
break;
}
}
mutex_unlock(&cdm_mgr.nodes[i].lock);
if (rc == 0)
break;
}
put_cdm_mgr_refcount();
return rc;
}
EXPORT_SYMBOL(cam_cdm_get_iommu_handle);
int cam_cdm_acquire(struct cam_cdm_acquire_data *data)
{
int rc = -EPERM;
struct cam_hw_intf *hw;
struct cam_hw_info *cdm_hw;
struct cam_cdm *core = NULL;
uint32_t hw_index = 0;
if ((!data) || (!data->base_array_cnt))
return -EINVAL;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
return rc;
}
if (data->id > CAM_CDM_HW_ANY) {
CAM_ERR(CAM_CDM,
"only CAM_CDM_VIRTUAL/CAM_CDM_HW_ANY is supported");
rc = -EPERM;
goto end;
}
rc = get_cdm_index_by_id(data->identifier, data->cell_index,
&hw_index);
if ((rc < 0) && (hw_index < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM)) {
CAM_ERR(CAM_CDM, "Failed to identify associated hw id");
goto end;
} else {
hw = cdm_mgr.nodes[hw_index].device;
if (hw && hw->hw_ops.process_cmd) {
cdm_hw = hw->hw_priv;
core = (struct cam_cdm *)cdm_hw->core_info;
data->id = core->id;
CAM_DBG(CAM_CDM,
"Device = %s, hw_index = %d, CDM id = %d",
data->identifier, hw_index, data->id);
rc = hw->hw_ops.process_cmd(hw->hw_priv,
CAM_CDM_HW_INTF_CMD_ACQUIRE, data,
sizeof(struct cam_cdm_acquire_data));
if (rc < 0) {
CAM_ERR(CAM_CDM, "CDM hw acquire failed");
goto end;
}
} else {
CAM_ERR(CAM_CDM, "idx %d doesn't have acquire ops",
hw_index);
rc = -EPERM;
}
}
end:
if (rc < 0) {
CAM_ERR(CAM_CDM, "CDM acquire failed for id=%d name=%s, idx=%d",
data->id, data->identifier, data->cell_index);
put_cdm_mgr_refcount();
}
return rc;
}
EXPORT_SYMBOL(cam_cdm_acquire);
struct cam_cdm_utils_ops *cam_cdm_publish_ops(void)
{
struct cam_hw_version cdm_version;
cdm_version.major = 1;
cdm_version.minor = 0;
cdm_version.incr = 0;
cdm_version.reserved = 0;
return cam_cdm_get_ops(0, &cdm_version, true);
}
EXPORT_SYMBOL(cam_cdm_publish_ops);
int cam_cdm_release(uint32_t handle)
{
uint32_t hw_index;
int rc = -EPERM;
struct cam_hw_intf *hw;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
return rc;
}
hw_index = CAM_CDM_GET_HW_IDX(handle);
if (hw_index < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM) {
hw = cdm_mgr.nodes[hw_index].device;
if (hw && hw->hw_ops.process_cmd) {
rc = hw->hw_ops.process_cmd(hw->hw_priv,
CAM_CDM_HW_INTF_CMD_RELEASE, &handle,
sizeof(handle));
if (rc < 0)
CAM_ERR(CAM_CDM,
"hw release failed for handle=%x",
handle);
} else
CAM_ERR(CAM_CDM, "hw idx %d doesn't have release ops",
hw_index);
}
put_cdm_mgr_refcount();
if (rc == 0)
put_cdm_mgr_refcount();
return rc;
}
EXPORT_SYMBOL(cam_cdm_release);
int cam_cdm_submit_bls(uint32_t handle, struct cam_cdm_bl_request *data)
{
uint32_t hw_index;
int rc = -EINVAL;
struct cam_hw_intf *hw;
if (!data)
return rc;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
rc = -EPERM;
return rc;
}
hw_index = CAM_CDM_GET_HW_IDX(handle);
if (hw_index < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM) {
struct cam_cdm_hw_intf_cmd_submit_bl req;
hw = cdm_mgr.nodes[hw_index].device;
if (hw && hw->hw_ops.process_cmd) {
req.data = data;
req.handle = handle;
rc = hw->hw_ops.process_cmd(hw->hw_priv,
CAM_CDM_HW_INTF_CMD_SUBMIT_BL, &req,
sizeof(struct cam_cdm_hw_intf_cmd_submit_bl));
if (rc < 0)
CAM_ERR(CAM_CDM,
"hw submit bl failed for handle=%x",
handle);
} else {
CAM_ERR(CAM_CDM, "hw idx %d doesn't have submit ops",
hw_index);
}
}
put_cdm_mgr_refcount();
return rc;
}
EXPORT_SYMBOL(cam_cdm_submit_bls);
int cam_cdm_stream_on(uint32_t handle)
{
uint32_t hw_index;
int rc = -EINVAL;
struct cam_hw_intf *hw;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
rc = -EPERM;
return rc;
}
hw_index = CAM_CDM_GET_HW_IDX(handle);
if (hw_index < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM) {
hw = cdm_mgr.nodes[hw_index].device;
if (hw && hw->hw_ops.start) {
rc = hw->hw_ops.start(hw->hw_priv, &handle,
sizeof(uint32_t));
if (rc < 0)
CAM_ERR(CAM_CDM,
"hw start failed handle=%x",
handle);
} else {
CAM_ERR(CAM_CDM,
"hw idx %d doesn't have start ops",
hw_index);
}
}
put_cdm_mgr_refcount();
return rc;
}
EXPORT_SYMBOL(cam_cdm_stream_on);
int cam_cdm_stream_off(uint32_t handle)
{
uint32_t hw_index;
int rc = -EINVAL;
struct cam_hw_intf *hw;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
rc = -EPERM;
return rc;
}
hw_index = CAM_CDM_GET_HW_IDX(handle);
if (hw_index < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM) {
hw = cdm_mgr.nodes[hw_index].device;
if (hw && hw->hw_ops.stop) {
rc = hw->hw_ops.stop(hw->hw_priv, &handle,
sizeof(uint32_t));
if (rc < 0)
CAM_ERR(CAM_CDM, "hw stop failed handle=%x",
handle);
} else {
CAM_ERR(CAM_CDM, "hw idx %d doesn't have stop ops",
hw_index);
}
}
put_cdm_mgr_refcount();
return rc;
}
EXPORT_SYMBOL(cam_cdm_stream_off);
int cam_cdm_reset_hw(uint32_t handle)
{
uint32_t hw_index;
int rc = -EINVAL;
struct cam_hw_intf *hw;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
rc = -EPERM;
return rc;
}
hw_index = CAM_CDM_GET_HW_IDX(handle);
if (hw_index < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM) {
hw = cdm_mgr.nodes[hw_index].device;
if (hw && hw->hw_ops.process_cmd) {
rc = hw->hw_ops.process_cmd(hw->hw_priv,
CAM_CDM_HW_INTF_CMD_RESET_HW, &handle,
sizeof(handle));
if (rc < 0)
CAM_ERR(CAM_CDM,
"CDM hw release failed for handle=%x",
handle);
} else {
CAM_ERR(CAM_CDM, "hw idx %d doesn't have release ops",
hw_index);
}
}
put_cdm_mgr_refcount();
return rc;
}
EXPORT_SYMBOL(cam_cdm_reset_hw);
int cam_cdm_flush_hw(uint32_t handle)
{
uint32_t hw_index;
int rc = -EINVAL;
struct cam_hw_intf *hw;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
rc = -EPERM;
return rc;
}
hw_index = CAM_CDM_GET_HW_IDX(handle);
if (hw_index < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM) {
hw = cdm_mgr.nodes[hw_index].device;
if (hw && hw->hw_ops.process_cmd) {
rc = hw->hw_ops.process_cmd(hw->hw_priv,
CAM_CDM_HW_INTF_CMD_FLUSH_HW, &handle,
sizeof(handle));
if (rc < 0)
CAM_ERR(CAM_CDM,
"CDM hw release failed for handle=%x",
handle);
} else {
CAM_ERR(CAM_CDM, "hw idx %d doesn't have release ops",
hw_index);
}
}
put_cdm_mgr_refcount();
return rc;
}
EXPORT_SYMBOL(cam_cdm_flush_hw);
int cam_cdm_handle_error(uint32_t handle)
{
uint32_t hw_index;
int rc = -EINVAL;
struct cam_hw_intf *hw;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
rc = -EPERM;
return rc;
}
hw_index = CAM_CDM_GET_HW_IDX(handle);
if (hw_index < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM) {
hw = cdm_mgr.nodes[hw_index].device;
if (hw && hw->hw_ops.process_cmd) {
rc = hw->hw_ops.process_cmd(hw->hw_priv,
CAM_CDM_HW_INTF_CMD_HANDLE_ERROR,
&handle,
sizeof(handle));
if (rc < 0)
CAM_ERR(CAM_CDM,
"CDM hw release failed for handle=%x",
handle);
} else {
CAM_ERR(CAM_CDM, "hw idx %d doesn't have release ops",
hw_index);
}
}
put_cdm_mgr_refcount();
return rc;
}
EXPORT_SYMBOL(cam_cdm_handle_error);
int cam_cdm_detect_hang_error(uint32_t handle)
{
uint32_t hw_index;
int rc = -EINVAL;
struct cam_hw_intf *hw;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
rc = -EPERM;
return rc;
}
hw_index = CAM_CDM_GET_HW_IDX(handle);
if (hw_index < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM) {
hw = cdm_mgr.nodes[hw_index].device;
if (hw && hw->hw_ops.process_cmd)
rc = hw->hw_ops.process_cmd(hw->hw_priv,
CAM_CDM_HW_INTF_CMD_HANG_DETECT,
&handle,
sizeof(handle));
}
put_cdm_mgr_refcount();
return rc;
}
EXPORT_SYMBOL(cam_cdm_detect_hang_error);
int cam_cdm_dump_debug_registers(uint32_t handle)
{
uint32_t hw_index;
int rc = -EINVAL;
struct cam_hw_intf *hw;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
rc = -EPERM;
return rc;
}
hw_index = CAM_CDM_GET_HW_IDX(handle);
if (hw_index < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM) {
hw = cdm_mgr.nodes[hw_index].device;
if (hw && hw->hw_ops.process_cmd)
rc = hw->hw_ops.process_cmd(hw->hw_priv,
CAM_CDM_HW_INTF_DUMP_DBG_REGS,
&handle,
sizeof(handle));
}
put_cdm_mgr_refcount();
return rc;
}
int cam_cdm_intf_register_hw_cdm(struct cam_hw_intf *hw,
struct cam_cdm_private_dt_data *data, enum cam_cdm_type type,
uint32_t *index)
{
int rc = -EINVAL;
if ((!hw) || (!data) || (!index))
return rc;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
return rc;
}
mutex_lock(&cam_cdm_mgr_lock);
if ((type == CAM_VIRTUAL_CDM) &&
(!cdm_mgr.nodes[CAM_SW_CDM_INDEX].device)) {
mutex_lock(&cdm_mgr.nodes[CAM_SW_CDM_INDEX].lock);
cdm_mgr.nodes[CAM_SW_CDM_INDEX].device = hw;
cdm_mgr.nodes[CAM_SW_CDM_INDEX].data = data;
*index = cdm_mgr.cdm_count;
mutex_unlock(&cdm_mgr.nodes[CAM_SW_CDM_INDEX].lock);
cdm_mgr.cdm_count++;
rc = 0;
} else if ((type == CAM_HW_CDM) && (cdm_mgr.cdm_count > 0)) {
mutex_lock(&cdm_mgr.nodes[cdm_mgr.cdm_count].lock);
cdm_mgr.nodes[cdm_mgr.cdm_count].device = hw;
cdm_mgr.nodes[cdm_mgr.cdm_count].data = data;
*index = cdm_mgr.cdm_count;
mutex_unlock(&cdm_mgr.nodes[cdm_mgr.cdm_count].lock);
cdm_mgr.cdm_count++;
rc = 0;
} else {
CAM_ERR(CAM_CDM, "CDM registration failed type=%d count=%d",
type, cdm_mgr.cdm_count);
}
mutex_unlock(&cam_cdm_mgr_lock);
put_cdm_mgr_refcount();
return rc;
}
int cam_cdm_intf_deregister_hw_cdm(struct cam_hw_intf *hw,
struct cam_cdm_private_dt_data *data, enum cam_cdm_type type,
uint32_t index)
{
int rc = -EINVAL;
if ((!hw) || (!data))
return rc;
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
rc = -EPERM;
return rc;
}
mutex_lock(&cam_cdm_mgr_lock);
if ((type == CAM_VIRTUAL_CDM) &&
(hw == cdm_mgr.nodes[CAM_SW_CDM_INDEX].device) &&
(index == CAM_SW_CDM_INDEX)) {
mutex_lock(&cdm_mgr.nodes[cdm_mgr.cdm_count].lock);
cdm_mgr.nodes[CAM_SW_CDM_INDEX].device = NULL;
cdm_mgr.nodes[CAM_SW_CDM_INDEX].data = NULL;
mutex_unlock(&cdm_mgr.nodes[cdm_mgr.cdm_count].lock);
rc = 0;
} else if ((type == CAM_HW_CDM) &&
(hw == cdm_mgr.nodes[index].device)) {
mutex_lock(&cdm_mgr.nodes[index].lock);
cdm_mgr.nodes[index].device = NULL;
cdm_mgr.nodes[index].data = NULL;
mutex_unlock(&cdm_mgr.nodes[index].lock);
cdm_mgr.cdm_count--;
rc = 0;
} else {
CAM_ERR(CAM_CDM, "CDM Deregistration failed type=%d index=%d",
type, index);
}
mutex_unlock(&cam_cdm_mgr_lock);
put_cdm_mgr_refcount();
return rc;
}
static int cam_cdm_intf_component_bind(struct device *dev,
struct device *master_dev, void *data)
{
int i, rc;
struct platform_device *pdev = to_platform_device(dev);
rc = cam_cdm_intf_mgr_soc_get_dt_properties(pdev, &cdm_mgr);
if (rc) {
CAM_ERR(CAM_CDM, "Failed to get dt properties");
return rc;
}
mutex_lock(&cam_cdm_mgr_lock);
for (i = 0 ; i < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM; i++) {
mutex_init(&cdm_mgr.nodes[i].lock);
cdm_mgr.nodes[i].device = NULL;
cdm_mgr.nodes[i].data = NULL;
cdm_mgr.nodes[i].refcount = 0;
}
cdm_mgr.probe_done = true;
cdm_mgr.refcount = 0;
mutex_unlock(&cam_cdm_mgr_lock);
rc = cam_virtual_cdm_probe(pdev);
if (rc) {
mutex_lock(&cam_cdm_mgr_lock);
cdm_mgr.probe_done = false;
for (i = 0 ; i < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM; i++) {
if (cdm_mgr.nodes[i].device || cdm_mgr.nodes[i].data ||
(cdm_mgr.nodes[i].refcount != 0))
CAM_ERR(CAM_CDM,
"Valid node present in index=%d", i);
mutex_destroy(&cdm_mgr.nodes[i].lock);
cdm_mgr.nodes[i].device = NULL;
cdm_mgr.nodes[i].data = NULL;
cdm_mgr.nodes[i].refcount = 0;
}
mutex_unlock(&cam_cdm_mgr_lock);
}
CAM_DBG(CAM_CDM, "CDM Intf component bound successfully");
return rc;
}
static void cam_cdm_intf_component_unbind(struct device *dev,
struct device *master_dev, void *data)
{
int i;
struct platform_device *pdev = to_platform_device(dev);
if (get_cdm_mgr_refcount()) {
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
return;
}
if (cam_virtual_cdm_remove(pdev)) {
CAM_ERR(CAM_CDM, "Virtual CDM remove failed");
return;
}
put_cdm_mgr_refcount();
mutex_lock(&cam_cdm_mgr_lock);
if (cdm_mgr.refcount != 0) {
CAM_ERR(CAM_CDM, "cdm manger refcount not zero %d",
cdm_mgr.refcount);
goto end;
}
for (i = 0 ; i < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM; i++) {
if (cdm_mgr.nodes[i].device || cdm_mgr.nodes[i].data ||
(cdm_mgr.nodes[i].refcount != 0)) {
CAM_ERR(CAM_CDM, "Valid node present in index=%d", i);
goto end;
}
mutex_destroy(&cdm_mgr.nodes[i].lock);
cdm_mgr.nodes[i].device = NULL;
cdm_mgr.nodes[i].data = NULL;
cdm_mgr.nodes[i].refcount = 0;
}
cdm_mgr.probe_done = false;
end:
mutex_unlock(&cam_cdm_mgr_lock);
}
const static struct component_ops cam_cdm_intf_component_ops = {
.bind = cam_cdm_intf_component_bind,
.unbind = cam_cdm_intf_component_unbind,
};
static int cam_cdm_intf_probe(struct platform_device *pdev)
{
int rc = 0;
CAM_DBG(CAM_CDM, "Adding CDM INTF component");
rc = component_add(&pdev->dev, &cam_cdm_intf_component_ops);
if (rc)
CAM_ERR(CAM_CDM, "failed to add component rc: %d", rc);
return rc;
}
static int cam_cdm_intf_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &cam_cdm_intf_component_ops);
return 0;
}
struct platform_driver cam_cdm_intf_driver = {
.probe = cam_cdm_intf_probe,
.remove = cam_cdm_intf_remove,
.driver = {
.name = "msm_cam_cdm_intf",
.owner = THIS_MODULE,
.of_match_table = msm_cam_cdm_intf_dt_match,
.suppress_bind_attrs = true,
},
};
int cam_cdm_intf_init_module(void)
{
return platform_driver_register(&cam_cdm_intf_driver);
}
void cam_cdm_intf_exit_module(void)
{
platform_driver_unregister(&cam_cdm_intf_driver);
}
MODULE_DESCRIPTION("MSM Camera CDM Intf driver");
MODULE_LICENSE("GPL v2");

View file

@ -0,0 +1,339 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CDM_API_H_
#define _CAM_CDM_API_H_
#include <media/cam_defs.h>
#include "cam_cdm_util.h"
#include "cam_soc_util.h"
#define CAM_CDM_BL_CMD_MAX 25
/* enum cam_cdm_id - Enum for possible CAM CDM hardwares */
enum cam_cdm_id {
CAM_CDM_VIRTUAL,
CAM_CDM_HW_ANY,
CAM_CDM_CPAS,
CAM_CDM_IFE,
CAM_CDM_TFE,
CAM_CDM_OPE,
CAM_CDM_IPE0,
CAM_CDM_IPE1,
CAM_CDM_BPS,
CAM_CDM_VFE,
CAM_CDM_RT,
CAM_CDM_MAX
};
/* enum cam_cdm_cb_status - Enum for possible CAM CDM callback */
enum cam_cdm_cb_status {
CAM_CDM_CB_STATUS_BL_SUCCESS,
CAM_CDM_CB_STATUS_INVALID_BL_CMD,
CAM_CDM_CB_STATUS_PAGEFAULT,
CAM_CDM_CB_STATUS_HW_RESET_ONGOING,
CAM_CDM_CB_STATUS_HW_RESET_DONE,
CAM_CDM_CB_STATUS_HW_FLUSH,
CAM_CDM_CB_STATUS_HW_RESUBMIT,
CAM_CDM_CB_STATUS_HW_ERROR,
CAM_CDM_CB_STATUS_UNKNOWN_ERROR,
};
/* enum cam_cdm_bl_cmd_addr_type - Enum for possible CDM bl cmd addr types */
enum cam_cdm_bl_cmd_addr_type {
CAM_CDM_BL_CMD_TYPE_MEM_HANDLE,
CAM_CDM_BL_CMD_TYPE_HW_IOVA,
CAM_CDM_BL_CMD_TYPE_KERNEL_IOVA,
};
/* enum cam_cdm_bl_fifo - interface commands.*/
enum cam_cdm_bl_fifo_queue {
CAM_CDM_BL_FIFO_0,
CAM_CDM_BL_FIFO_1,
CAM_CDM_BL_FIFO_2,
CAM_CDM_BL_FIFO_3,
CAM_CDM_BL_FIFO_MAX,
};
/**
* struct cam_cdm_acquire_data - Cam CDM acquire data structure
*
* @identifier : Input identifier string which is the device label from dt
* like vfe, ife, jpeg etc
* @cell_index : Input integer identifier pointing to the cell index from dt
* of the device. This can be used to form a unique string
* with @identifier like vfe0, ife1, jpeg0 etc
* @id : ID of a specific or any CDM HW which needs to be acquired.
* @userdata : Input private data which will be returned as part
* of callback.
* @cam_cdm_callback : Input callback pointer for triggering the
* callbacks from CDM driver
* @handle : CDM Client handle
* @userdata : Private data given at the time of acquire
* @status : Callback status
* @cookie : Cookie if the callback is gen irq status
* @base_array_cnt : Input number of ioremapped address pair pointing
* in base_array, needed only if selected cdm is a virtual.
* @base_array : Input pointer to ioremapped address pair arrary
* needed only if selected cdm is a virtual.
* @priority : Priority of the client.
* @cdm_version : CDM version is output while acquiring HW cdm and
* it is Input while acquiring virtual cdm.
* Currently fixing it to one version below
* acquire API.
* @ops : Output pointer updated by cdm driver to the CDM
* util ops for this HW version of CDM acquired.
* @handle : Output Unique handle generated for this acquire
*
*/
struct cam_cdm_acquire_data {
char identifier[128];
uint32_t cell_index;
enum cam_cdm_id id;
void *userdata;
void (*cam_cdm_callback)(uint32_t handle, void *userdata,
enum cam_cdm_cb_status status, uint64_t cookie);
uint32_t base_array_cnt;
struct cam_soc_reg_map *base_array[CAM_SOC_MAX_BLOCK];
enum cam_cdm_bl_fifo_queue priority;
struct cam_hw_version cdm_version;
struct cam_cdm_utils_ops *ops;
uint32_t handle;
};
/**
* struct cam_cdm_bl_cmd - Cam CDM HW bl command
*
* @bl_addr : Union of all three type for CDM BL commands
* @mem_handle : Input mem handle of bl cmd
* @offset : Input offset of the actual bl cmd in the memory pointed
* by mem_handle
* @len : Input length of the BL command, Cannot be more than 1MB and
* this is will be validated with offset+size of the memory pointed
* by mem_handle
* @enable_debug_gen_irq : bool flag to submit extra gen_irq afteR bl_command
* @arbitrate : bool flag to arbitrate on submitted BL boundary
*/
struct cam_cdm_bl_cmd {
union {
int32_t mem_handle;
uint32_t *hw_iova;
uintptr_t kernel_iova;
} bl_addr;
uint32_t offset;
uint32_t len;
bool enable_debug_gen_irq;
bool arbitrate;
};
/**
* struct cam_cdm_bl_request - Cam CDM HW base & length (BL) request
*
* @flag : 1 for callback needed and 0 for no callback when this BL
* request is done
* @userdata :Input private data which will be returned as part
* of callback if request for this bl request in flags.
* @cookie : Cookie if the callback is gen irq status
* @type : type of the submitted bl cmd address.
* @cmd_arrary_count : Input number of BL commands to be submitted to CDM
* @gen_irq_arb : enum for setting arbitration in gen_irq
* @bl_cmd_array : Input payload holding the BL cmd's arrary
* to be sumbitted.
*
*/
struct cam_cdm_bl_request {
int flag;
void *userdata;
uint64_t cookie;
enum cam_cdm_bl_cmd_addr_type type;
uint32_t cmd_arrary_count;
bool gen_irq_arb;
struct cam_cdm_bl_cmd cmd[1];
};
/**
* struct cam_cdm_bl_data - last submiited CDM BL data
*
* @mem_handle : Input mem handle of bl cmd
* @hw_addr : Hw address of submitted Bl command
* @offset : Input offset of the actual bl cmd in the memory pointed
* by mem_handle
* @len : length of submitted Bl command to CDM.
* @input_len : Input length of the BL command, Cannot be more than 1MB and
* this is will be validated with offset+size of the memory pointed
* by mem_handle
* @type : CDM bl cmd addr types.
*/
struct cam_cdm_bl_data {
int32_t mem_handle;
dma_addr_t hw_addr;
uint32_t offset;
size_t len;
uint32_t input_len;
enum cam_cdm_bl_cmd_addr_type type;
};
/**
* struct cam_cdm_bl_info
*
* @bl_count : No. of Bl commands submiited to CDM.
* @cmd : payload holding the BL cmd's arrary
* that is sumbitted.
*
*/
struct cam_cdm_bl_info {
int32_t bl_count;
struct cam_cdm_bl_data cmd[CAM_CDM_BL_CMD_MAX];
};
/**
* @brief : API to get the CDM capabilities for a camera device type
*
* @identifier : Input pointer to a string which is the device label from dt
* like vfe, ife, jpeg etc, We do not need cell index
* assuming all devices of a single type maps to one SMMU
* client
* @cdm_handles : Input iommu handle memory pointer to update handles
*
* @return 0 on success
*/
int cam_cdm_get_iommu_handle(char *identifier,
struct cam_iommu_handle *cdm_handles);
/**
* @brief : API to acquire a CDM
*
* @data : Input data for the CDM to be acquired
*
* @return 0 on success
*/
int cam_cdm_acquire(struct cam_cdm_acquire_data *data);
/**
* @brief : API to release a previously acquired CDM
*
* @handle : Input handle for the CDM to be released
*
* @return 0 on success
*/
int cam_cdm_release(uint32_t handle);
/**
* @brief : API to submit the base & length (BL's) for acquired CDM
*
* @handle : Input cdm handle to which the BL's needs to be sumbitted.
* @data : Input pointer to the BL's to be sumbitted
*
* @return 0 on success
*/
int cam_cdm_submit_bls(uint32_t handle, struct cam_cdm_bl_request *data);
/**
* @brief : API to stream ON a previously acquired CDM,
* during this we turn on/off clocks/power based on active clients.
*
* @handle : Input handle for the CDM to be released
*
* @return 0 on success
*/
int cam_cdm_stream_on(uint32_t handle);
/**
* @brief : API to stream OFF a previously acquired CDM,
* during this we turn on/off clocks/power based on active clients.
*
* @handle : Input handle for the CDM to be released
*
* @return 0 on success
*/
int cam_cdm_stream_off(uint32_t handle);
/**
* @brief : API to reset previously acquired CDM,
* this should be only performed only if the CDM is private.
*
* @handle : Input handle of the CDM to reset
*
* @return 0 on success
*/
int cam_cdm_reset_hw(uint32_t handle);
/**
* @brief : API to publish CDM ops to HW blocks like IFE
*
* @return : CDM operations
*
*/
struct cam_cdm_utils_ops *cam_cdm_publish_ops(void);
/**
* @brief : API to register CDM hw to platform framework.
* @return struct platform_device pointer on on success, or ERR_PTR() on error.
*/
int cam_hw_cdm_init_module(void);
/**
* @brief : API to register CDM interface to platform framework.
* @return struct platform_device pointer on on success, or ERR_PTR() on error.
*/
int cam_cdm_intf_init_module(void);
/**
* @brief : API to remove CDM interface from platform framework.
*/
void cam_cdm_intf_exit_module(void);
/**
* @brief : API to remove CDM hw from platform framework.
*/
void cam_hw_cdm_exit_module(void);
/**
* @brief : API to flush previously acquired CDM,
* this should be only performed only if the CDM is private.
*
* @handle : Input handle of the CDM to reset
*
* @return 0 on success
*/
int cam_cdm_flush_hw(uint32_t handle);
/**
* @brief : API to detect culprit bl_tag in previously acquired CDM,
* this should be only performed only if the CDM is private.
*
* @handle : Input handle of the CDM to reset
*
* @return 0 on success
*/
int cam_cdm_handle_error(uint32_t handle);
/**
* @brief : API get CDM ops
*
* @return : CDM operations
*
*/
struct cam_cdm_utils_ops *cam_cdm_publish_ops(void);
/**
* @brief : API to detect hang in previously acquired CDM,
* this should be only performed only if the CDM is private.
*
* @handle : Input handle of the CDM to detect hang
*
* @return 0 on success
*/
int cam_cdm_detect_hang_error(uint32_t handle);
/**
* @brief : API to dump the CDM Debug registers
*
* @handle : Input handle of the CDM to dump the registers
*
* @return 0 on success
*/
int cam_cdm_dump_debug_registers(uint32_t handle);
#endif /* _CAM_CDM_API_H_ */

View file

@ -0,0 +1,235 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include "cam_soc_util.h"
#include "cam_smmu_api.h"
#include "cam_cdm.h"
#include "cam_soc_util.h"
#include "cam_io_util.h"
#include "cam_cdm_soc.h"
#define CAM_CDM_OFFSET_FROM_REG(x, y) ((x)->offsets[y].offset)
#define CAM_CDM_ATTR_FROM_REG(x, y) ((x)->offsets[y].attribute)
bool cam_cdm_read_hw_reg(struct cam_hw_info *cdm_hw,
uint32_t reg, uint32_t *value)
{
void __iomem *reg_addr;
void __iomem *base =
cdm_hw->soc_info.reg_map[CAM_HW_CDM_BASE_INDEX].mem_base;
resource_size_t mem_len =
cdm_hw->soc_info.reg_map[CAM_HW_CDM_BASE_INDEX].size;
CAM_DBG(CAM_CDM, "E: b=%pK blen=%d off=%x", (void __iomem *)base,
(int)mem_len, reg);
reg_addr = (base + reg);
if (reg_addr > (base + mem_len)) {
CAM_ERR_RATE_LIMIT(CAM_CDM,
"Invalid mapped region %d", reg);
goto permission_error;
}
*value = cam_io_r_mb(reg_addr);
CAM_DBG(CAM_CDM, "X b=%pK off=%x val=%x",
(void __iomem *)base, reg,
*value);
return false;
permission_error:
*value = 0;
return true;
}
bool cam_cdm_write_hw_reg(struct cam_hw_info *cdm_hw,
uint32_t reg, uint32_t value)
{
void __iomem *reg_addr;
void __iomem *base =
cdm_hw->soc_info.reg_map[CAM_HW_CDM_BASE_INDEX].mem_base;
resource_size_t mem_len =
cdm_hw->soc_info.reg_map[CAM_HW_CDM_BASE_INDEX].size;
CAM_DBG(CAM_CDM, "E: b=%pK off=%x val=%x", (void __iomem *)base,
reg, value);
reg_addr = (base + reg);
if (reg_addr > (base + mem_len)) {
CAM_ERR_RATE_LIMIT(CAM_CDM,
"Accessing invalid region:%d\n",
reg);
goto permission_error;
}
cam_io_w_mb(value, reg_addr);
return false;
permission_error:
return true;
}
int cam_cdm_soc_load_dt_private(struct platform_device *pdev,
struct cam_cdm_private_dt_data *cdm_pvt_data)
{
int i, rc = -EINVAL, num_fifo_entries = 0, num_clients = 0;
num_clients = of_property_count_strings(
pdev->dev.of_node, "cdm-client-names");
if ((num_clients <= 0) ||
(num_clients > CAM_PER_CDM_MAX_REGISTERED_CLIENTS)) {
CAM_ERR(CAM_CDM, "Invalid count of client names count=%d",
num_clients);
rc = -EINVAL;
goto end;
}
cdm_pvt_data->dt_num_supported_clients = (uint32_t)num_clients;
CAM_DBG(CAM_CDM, "Num supported cdm_client = %u",
cdm_pvt_data->dt_num_supported_clients);
cdm_pvt_data->dt_cdm_shared = true;
for (i = 0; i < cdm_pvt_data->dt_num_supported_clients; i++) {
rc = of_property_read_string_index(pdev->dev.of_node,
"cdm-client-names", i,
&(cdm_pvt_data->dt_cdm_client_name[i]));
CAM_DBG(CAM_CDM, "cdm-client-names[%d] = %s", i,
cdm_pvt_data->dt_cdm_client_name[i]);
if (rc < 0) {
CAM_ERR(CAM_CDM,
"Reading cdm-client-names failed for client: %d",
i);
goto end;
}
}
cdm_pvt_data->is_single_ctx_cdm =
of_property_read_bool(pdev->dev.of_node,
"single-context-cdm");
rc = of_property_read_u8(pdev->dev.of_node, "cdm-priority-group",
&cdm_pvt_data->priority_group);
if (rc < 0) {
cdm_pvt_data->priority_group = 0;
rc = 0;
}
cdm_pvt_data->config_fifo = of_property_read_bool(pdev->dev.of_node,
"config-fifo");
if (cdm_pvt_data->config_fifo) {
num_fifo_entries = of_property_count_u32_elems(
pdev->dev.of_node,
"fifo-depths");
if (num_fifo_entries != CAM_CDM_NUM_BL_FIFO) {
CAM_ERR(CAM_CDM,
"Wrong number of configurable FIFOs %d",
num_fifo_entries);
rc = -EINVAL;
goto end;
}
for (i = 0; i < num_fifo_entries; i++) {
rc = of_property_read_u32_index(pdev->dev.of_node,
"fifo-depths", i, &cdm_pvt_data->fifo_depth[i]);
if (rc < 0) {
CAM_ERR(CAM_CDM,
"Unable to read fifo-depth rc %d",
rc);
goto end;
}
CAM_DBG(CAM_CDM, "FIFO%d depth is %d",
i, cdm_pvt_data->fifo_depth[i]);
}
} else {
for (i = 0; i < CAM_CDM_BL_FIFO_MAX; i++) {
cdm_pvt_data->fifo_depth[i] =
CAM_CDM_BL_FIFO_LENGTH_MAX_DEFAULT;
CAM_DBG(CAM_CDM, "FIFO%d depth is %d",
i, cdm_pvt_data->fifo_depth[i]);
}
}
end:
return rc;
}
int cam_hw_cdm_soc_get_dt_properties(struct cam_hw_info *cdm_hw,
const struct of_device_id *table)
{
int rc;
struct cam_hw_soc_info *soc_ptr;
const struct of_device_id *id;
struct cam_cdm *cdm_core = NULL;
if (!cdm_hw || (cdm_hw->soc_info.soc_private)
|| !(cdm_hw->soc_info.pdev))
return -EINVAL;
cdm_core = cdm_hw->core_info;
soc_ptr = &cdm_hw->soc_info;
rc = cam_soc_util_get_dt_properties(soc_ptr);
if (rc != 0) {
CAM_ERR(CAM_CDM, "Failed to retrieve the CDM dt properties");
goto end;
}
soc_ptr->soc_private = kzalloc(
sizeof(struct cam_cdm_private_dt_data),
GFP_KERNEL);
if (!soc_ptr->soc_private)
return -ENOMEM;
rc = cam_cdm_soc_load_dt_private(soc_ptr->pdev,
soc_ptr->soc_private);
if (rc != 0) {
CAM_ERR(CAM_CDM, "Failed to load CDM dt private data");
goto error;
}
id = of_match_node(table, soc_ptr->pdev->dev.of_node);
if ((!id) || !(id->data)) {
CAM_ERR(CAM_CDM, "Failed to retrieve the CDM id table");
goto error;
}
cdm_core->offsets =
(struct cam_cdm_hw_reg_offset *)id->data;
CAM_DBG(CAM_CDM, "name %s", cdm_core->name);
snprintf(cdm_core->name, sizeof(cdm_core->name), "%s%d",
id->compatible, soc_ptr->index);
CAM_DBG(CAM_CDM, "name %s", cdm_core->name);
goto end;
error:
rc = -EINVAL;
kfree(soc_ptr->soc_private);
soc_ptr->soc_private = NULL;
end:
return rc;
}
int cam_cdm_intf_mgr_soc_get_dt_properties(
struct platform_device *pdev, struct cam_cdm_intf_mgr *mgr)
{
int rc;
rc = of_property_read_u32(pdev->dev.of_node,
"num-hw-cdm", &mgr->dt_supported_hw_cdm);
CAM_DBG(CAM_CDM, "Number of HW cdm supported =%d",
mgr->dt_supported_hw_cdm);
return rc;
}

View file

@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CDM_SOC_H_
#define _CAM_CDM_SOC_H_
#define CAM_HW_CDM_CPAS_0_NAME "qcom,cam170-cpas-cdm0"
#define CAM_HW_CDM_CPAS_NAME_1_0 "qcom,cam-cpas-cdm1_0"
#define CAM_HW_CDM_CPAS_NAME_1_1 "qcom,cam-cpas-cdm1_1"
#define CAM_HW_CDM_CPAS_NAME_1_2 "qcom,cam-cpas-cdm1_2"
#define CAM_HW_CDM_IFE_NAME_1_2 "qcom,cam-ife-cdm1_2"
#define CAM_HW_CDM_CPAS_NAME_2_0 "qcom,cam-cpas-cdm2_0"
#define CAM_HW_CDM_OPE_NAME_2_0 "qcom,cam-ope-cdm2_0"
#define CAM_HW_CDM_CPAS_NAME_2_1 "qcom,cam-cpas-cdm2_1"
#define CAM_HW_CDM_RT_NAME_2_1 "qcom,cam-rt-cdm2_1"
#define CAM_HW_CDM_OPE_NAME_2_1 "qcom,cam-ope-cdm2_1"
int cam_hw_cdm_soc_get_dt_properties(struct cam_hw_info *cdm_hw,
const struct of_device_id *table);
bool cam_cdm_read_hw_reg(struct cam_hw_info *cdm_hw,
uint32_t reg, uint32_t *value);
bool cam_cdm_write_hw_reg(struct cam_hw_info *cdm_hw,
uint32_t reg, uint32_t value);
int cam_cdm_intf_mgr_soc_get_dt_properties(
struct platform_device *pdev,
struct cam_cdm_intf_mgr *mgr);
int cam_cdm_soc_load_dt_private(struct platform_device *pdev,
struct cam_cdm_private_dt_data *ptr);
#endif /* _CAM_CDM_SOC_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,255 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CDM_UTIL_H_
#define _CAM_CDM_UTIL_H_
/* Max len for tag name for header while dumping cmd buffer*/
#define CAM_CDM_CMD_TAG_MAX_LEN 32
#include <linux/types.h>
enum cam_cdm_command {
CAM_CDM_CMD_UNUSED = 0x0,
CAM_CDM_CMD_DMI = 0x1,
CAM_CDM_CMD_NOT_DEFINED = 0x2,
CAM_CDM_CMD_REG_CONT = 0x3,
CAM_CDM_CMD_REG_RANDOM = 0x4,
CAM_CDM_CMD_BUFF_INDIRECT = 0x5,
CAM_CDM_CMD_GEN_IRQ = 0x6,
CAM_CDM_CMD_WAIT_EVENT = 0x7,
CAM_CDM_CMD_CHANGE_BASE = 0x8,
CAM_CDM_CMD_PERF_CTRL = 0x9,
CAM_CDM_CMD_DMI_32 = 0xa,
CAM_CDM_CMD_DMI_64 = 0xb,
CAM_CDM_CMD_COMP_WAIT = 0xc,
CAM_CDM_CLEAR_COMP_WAIT = 0xd,
CAM_CDM_WAIT_PREFETCH_DISABLE = 0xe,
CAM_CDM_CMD_PRIVATE_BASE = 0xf,
CAM_CDM_CMD_SWD_DMI_32 = (CAM_CDM_CMD_PRIVATE_BASE + 0x64),
CAM_CDM_CMD_SWD_DMI_64 = (CAM_CDM_CMD_PRIVATE_BASE + 0x65),
CAM_CDM_CMD_PRIVATE_BASE_MAX = 0x7F,
};
/**
* struct cam_cdm_utils_ops - Camera CDM util ops
*
* @cdm_get_cmd_header_size: Returns the size of the given command header
* in DWORDs.
* @command Command ID
* @return Size of the command in DWORDs
*
* @cdm_required_size_reg_continuous: Calculates the size of a reg-continuous
* command in dwords.
* @numVals Number of continuous values
* @return Size in dwords
*
* @cdm_required_size_reg_random: Calculates the size of a reg-random command
* in dwords.
* @numRegVals Number of register/value pairs
* @return Size in dwords
*
* @cdm_required_size_dmi: Calculates the size of a DMI command in dwords.
* @return Size in dwords
*
* @cdm_required_size_genirq: Calculates size of a Genirq command in dwords.
* @return Size in dwords
*
* @cdm_required_size_indirect: Calculates the size of an indirect command
* in dwords.
* @return Size in dwords
*
* @cdm_required_size_comp_wait: Calculates the size of a comp-wait command
* in dwords.
* @return Size in dwords
*
* @cdm_required_size_clear_comp_event: Calculates the size of clear-comp-event
* command in dwords.
* @return Size in dwords
*
* @cdm_required_size_changebase: Calculates the size of a change-base command
* in dwords.
* @return Size in dwords
*
* @cdm_offsetof_dmi_addr: Returns the offset of address field in the DMI
* command header.
* @return Offset of addr field
*
* @cdm_offsetof_indirect_addr: Returns the offset of address field in the
* indirect command header.
* @return Offset of addr field
*
* @cdm_write_regcontinuous: Writes a command into the command buffer.
* @pCmdBuffer: Pointer to command buffer
* @reg: Beginning of the register address range where
* values will be written.
* @numVals: Number of values (registers) that will be written
* @pVals : An array of values that will be written
* @return Pointer in command buffer pointing past the written commands
*
* @cdm_write_regrandom: Writes a command into the command buffer in
* register/value pairs.
* @pCmdBuffer: Pointer to command buffer
* @numRegVals: Number of register/value pairs that will be written
* @pRegVals: An array of register/value pairs that will be written
* The even indices are registers and the odd indices
* arevalues, e.g., {reg1, val1, reg2, val2, ...}.
* @return Pointer in command buffer pointing past the written commands
*
* @cdm_write_dmi: Writes a DMI command into the command bufferM.
* @pCmdBuffer: Pointer to command buffer
* @dmiCmd: DMI command
* @DMIAddr: Address of the DMI
* @DMISel: Selected bank that the DMI will write to
* @length: Size of data in bytes
* @return Pointer in command buffer pointing past the written commands
*
* @cdm_write_indirect: Writes a indirect command into the command buffer.
* @pCmdBuffer: Pointer to command buffer
* @indirectBufferAddr: Device address of the indirect cmd buffer.
* @length: Size of data in bytes
* @return Pointer in command buffer pointing past the written commands
*
* @cdm_write_changebase: Writes a changing CDM (address) base command into
* the command buffer.
* @pCmdBuffer: Pointer to command buffer
* @base: New base (device) address
* @return Pointer in command buffer pointing past the written commands
*
* @cdm_write_genirq: Writes a gen irq command into the command buffer.
* @pCmdBuffer: Pointer to command buffer
* @userdata: userdata or cookie return by hardware during irq.
*
* @cdm_write_wait_comp_event: Writes a wait comp event cmd into the
* command buffer.
* @pCmdBuffer: Pointer to command buffer
* @mask1: This value decides which comp events to wait (0 - 31).
* @mask2: This value decides which comp events to wait (32 - 65).
*
* @cdm_write_clear_comp_event: Writes a clear comp event cmd into the
* command buffer.
* @pCmdBuffer: Pointer to command buffer
* @mask1: This value decides which comp events to clear (0 - 31).
* @mask2: This value decides which comp events to clear (32 - 65).
*/
struct cam_cdm_utils_ops {
uint32_t (*cdm_get_cmd_header_size)(unsigned int command);
uint32_t (*cdm_required_size_dmi)(void);
uint32_t (*cdm_required_size_reg_continuous)(uint32_t numVals);
uint32_t (*cdm_required_size_reg_random)(uint32_t numRegVals);
uint32_t (*cdm_required_size_indirect)(void);
uint32_t (*cdm_required_size_genirq)(void);
uint32_t (*cdm_required_size_wait_event)(void);
uint32_t (*cdm_required_size_changebase)(void);
uint32_t (*cdm_required_size_comp_wait)(void);
uint32_t (*cdm_required_size_clear_comp_event)(void);
uint32_t (*cdm_required_size_prefetch_disable)(void);
uint32_t (*cdm_offsetof_dmi_addr)(void);
uint32_t (*cdm_offsetof_indirect_addr)(void);
uint32_t *(*cdm_write_dmi)(
uint32_t *pCmdBuffer,
uint8_t dmiCmd,
uint32_t DMIAddr,
uint8_t DMISel,
uint32_t dmiBufferAddr,
uint32_t length);
uint32_t* (*cdm_write_regcontinuous)(
uint32_t *pCmdBuffer,
uint32_t reg,
uint32_t numVals,
uint32_t *pVals);
uint32_t *(*cdm_write_regrandom)(
uint32_t *pCmdBuffer,
uint32_t numRegVals,
uint32_t *pRegVals);
uint32_t *(*cdm_write_indirect)(
uint32_t *pCmdBuffer,
uint32_t indirectBufferAddr,
uint32_t length);
void (*cdm_write_genirq)(
uint32_t *pCmdBuffer,
uint32_t userdata,
bool bit_wr_enable,
uint32_t fifo_idx);
uint32_t *(*cdm_write_wait_event)(
uint32_t *pCmdBuffer,
uint32_t iw,
uint32_t id,
uint32_t mask,
uint32_t offset,
uint32_t data);
uint32_t *(*cdm_write_changebase)(
uint32_t *pCmdBuffer,
uint32_t base);
uint32_t *(*cdm_write_wait_comp_event)(
uint32_t *pCmdBuffer,
uint32_t mask1,
uint32_t mask2);
uint32_t *(*cdm_write_clear_comp_event)(
uint32_t *pCmdBuffer,
uint32_t mask1,
uint32_t mask2);
uint32_t *(*cdm_write_wait_prefetch_disable)(
uint32_t *pCmdBuffer,
uint32_t id,
uint32_t mask1,
uint32_t mask2);
};
/**
* struct cam_cdm_cmd_buf_dump_info; - Camera CDM dump info
* @dst_offset: dst offset
* @dst_max_size max size of destination buffer
* @src_start: source start address
* @src_end: source end address
* @dst_start: dst start address
*/
struct cam_cdm_cmd_buf_dump_info {
size_t dst_offset;
size_t dst_max_size;
uint32_t *src_start;
uint32_t *src_end;
uintptr_t dst_start;
};
/**
* struct cam_cdm_cmd_dump_header- Camera CDM dump header
* @tag: tag name for header
* @size: size of data
* @word_size: size of each word
*/
struct cam_cdm_cmd_dump_header {
uint8_t tag[CAM_CDM_CMD_TAG_MAX_LEN];
uint64_t size;
uint32_t word_size;
};
/**
* cam_cdm_util_log_cmd_bufs()
*
* @brief: Util function to log cdm command buffers
*
* @cmd_buffer_start: Pointer to start of cmd buffer
* @cmd_buffer_end: Pointer to end of cmd buffer
*
*/
void cam_cdm_util_dump_cmd_buf(
uint32_t *cmd_buffer_start, uint32_t *cmd_buffer_end);
/**
* cam_cdm_util_dump_cmd_bufs_v2()
*
* @brief: Util function to cdm command buffers
* to a buffer
*
* @dump_info: Information about source and destination buffers
*
* return SUCCESS/FAILURE
*/
int cam_cdm_util_dump_cmd_bufs_v2(
struct cam_cdm_cmd_buf_dump_info *dump_info);
#endif /* _CAM_CDM_UTIL_H_ */

View file

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CDM_VIRTUAL_H_
#define _CAM_CDM_VIRTUAL_H_
#include "cam_cdm_intf_api.h"
int cam_virtual_cdm_probe(struct platform_device *pdev);
int cam_virtual_cdm_remove(struct platform_device *pdev);
int cam_cdm_util_cmd_buf_write(void __iomem **current_device_base,
uint32_t *cmd_buf, uint32_t cmd_buf_size,
struct cam_soc_reg_map *base_table[CAM_SOC_MAX_BLOCK],
uint32_t base_array_size, uint8_t bl_tag);
#endif /* _CAM_CDM_VIRTUAL_H_ */

View file

@ -0,0 +1,392 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include "cam_soc_util.h"
#include "cam_smmu_api.h"
#include "cam_cdm_intf_api.h"
#include "cam_cdm.h"
#include "cam_cdm_util.h"
#include "cam_cdm_virtual.h"
#include "cam_cdm_core_common.h"
#include "cam_cdm_soc.h"
#include "cam_io_util.h"
#include "cam_req_mgr_workq.h"
#include "cam_common_util.h"
#define CAM_CDM_VIRTUAL_NAME "qcom,cam_virtual_cdm"
static void cam_virtual_cdm_work(struct work_struct *work)
{
struct cam_cdm_work_payload *payload;
struct cam_hw_info *cdm_hw;
struct cam_cdm *core;
payload = container_of(work, struct cam_cdm_work_payload, work);
if (payload) {
cdm_hw = payload->hw;
core = (struct cam_cdm *)cdm_hw->core_info;
cam_common_util_thread_switch_delay_detect(
"Virtual CDM workq schedule",
payload->workq_scheduled_ts,
CAM_WORKQ_SCHEDULE_TIME_THRESHOLD);
if (payload->irq_status & 0x2) {
struct cam_cdm_bl_cb_request_entry *node;
CAM_DBG(CAM_CDM, "CDM HW Gen/inline IRQ with data=%x",
payload->irq_data);
mutex_lock(&cdm_hw->hw_mutex);
node = cam_cdm_find_request_by_bl_tag(
payload->irq_data,
&core->bl_request_list);
if (node) {
if (node->request_type ==
CAM_HW_CDM_BL_CB_CLIENT) {
cam_cdm_notify_clients(cdm_hw,
CAM_CDM_CB_STATUS_BL_SUCCESS,
(void *)node);
} else if (node->request_type ==
CAM_HW_CDM_BL_CB_INTERNAL) {
CAM_ERR(CAM_CDM, "Invalid node=%pK %d",
node, node->request_type);
}
list_del_init(&node->entry);
kfree(node);
} else {
CAM_ERR(CAM_CDM, "Invalid node for inline irq");
}
mutex_unlock(&cdm_hw->hw_mutex);
}
if (payload->irq_status & 0x1) {
CAM_DBG(CAM_CDM, "CDM HW reset done IRQ");
complete(&core->reset_complete);
}
kfree(payload);
}
}
int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
struct cam_cdm_hw_intf_cmd_submit_bl *req,
struct cam_cdm_client *client)
{
int i, rc = -EINVAL;
struct cam_cdm_bl_request *cdm_cmd = req->data;
struct cam_cdm *core = (struct cam_cdm *)cdm_hw->core_info;
mutex_lock(&client->lock);
for (i = 0; i < req->data->cmd_arrary_count ; i++) {
uintptr_t vaddr_ptr = 0;
size_t len = 0;
if ((!cdm_cmd->cmd[i].len) &&
(cdm_cmd->cmd[i].len > 0x100000)) {
CAM_ERR(CAM_CDM,
"len(%d) is invalid count=%d total cnt=%d",
cdm_cmd->cmd[i].len, i,
req->data->cmd_arrary_count);
rc = -EINVAL;
break;
}
if (req->data->type == CAM_CDM_BL_CMD_TYPE_MEM_HANDLE) {
rc = cam_mem_get_cpu_buf(
cdm_cmd->cmd[i].bl_addr.mem_handle, &vaddr_ptr,
&len);
} else if (req->data->type ==
CAM_CDM_BL_CMD_TYPE_KERNEL_IOVA) {
rc = 0;
vaddr_ptr = cdm_cmd->cmd[i].bl_addr.kernel_iova;
len = cdm_cmd->cmd[i].offset + cdm_cmd->cmd[i].len;
} else {
CAM_ERR(CAM_CDM,
"Only mem hdl/Kernel va type is supported %d",
req->data->type);
rc = -EINVAL;
break;
}
if ((!rc) && (vaddr_ptr) && (len) &&
(len >= cdm_cmd->cmd[i].offset)) {
if ((len - cdm_cmd->cmd[i].offset) <
cdm_cmd->cmd[i].len) {
CAM_ERR(CAM_CDM, "Not enough buffer");
rc = -EINVAL;
break;
}
CAM_DBG(CAM_CDM,
"hdl=%x vaddr=%pK offset=%d cmdlen=%d:%zu",
cdm_cmd->cmd[i].bl_addr.mem_handle,
(void *)vaddr_ptr, cdm_cmd->cmd[i].offset,
cdm_cmd->cmd[i].len, len);
rc = cam_cdm_util_cmd_buf_write(
&client->changebase_addr,
((uint32_t *)vaddr_ptr +
((cdm_cmd->cmd[i].offset)/4)),
cdm_cmd->cmd[i].len, client->data.base_array,
client->data.base_array_cnt, core->bl_tag);
if (rc) {
CAM_ERR(CAM_CDM,
"write failed for cnt=%d:%d len %u",
i, req->data->cmd_arrary_count,
cdm_cmd->cmd[i].len);
break;
}
} else {
CAM_ERR(CAM_CDM,
"Sanity check failed for hdl=%x len=%zu:%d",
cdm_cmd->cmd[i].bl_addr.mem_handle, len,
cdm_cmd->cmd[i].offset);
CAM_ERR(CAM_CDM,
"Sanity check failed for cmd_count=%d cnt=%d",
i, req->data->cmd_arrary_count);
rc = -EINVAL;
break;
}
if (!rc) {
struct cam_cdm_work_payload *payload;
CAM_DBG(CAM_CDM,
"write BL success for cnt=%d with tag=%d",
i, core->bl_tag);
if ((true == req->data->flag) &&
(i == req->data->cmd_arrary_count)) {
struct cam_cdm_bl_cb_request_entry *node;
node = kzalloc(sizeof(
struct cam_cdm_bl_cb_request_entry),
GFP_KERNEL);
if (!node) {
rc = -ENOMEM;
break;
}
node->request_type = CAM_HW_CDM_BL_CB_CLIENT;
node->client_hdl = req->handle;
node->cookie = req->data->cookie;
node->bl_tag = core->bl_tag;
node->userdata = req->data->userdata;
mutex_lock(&cdm_hw->hw_mutex);
list_add_tail(&node->entry,
&core->bl_request_list);
mutex_unlock(&cdm_hw->hw_mutex);
payload = kzalloc(sizeof(
struct cam_cdm_work_payload),
GFP_ATOMIC);
if (payload) {
payload->irq_status = 0x2;
payload->irq_data = core->bl_tag;
payload->hw = cdm_hw;
INIT_WORK((struct work_struct *)
&payload->work,
cam_virtual_cdm_work);
payload->workq_scheduled_ts =
ktime_get();
queue_work(core->work_queue,
&payload->work);
}
}
core->bl_tag++;
CAM_DBG(CAM_CDM,
"Now commit the BL nothing for virtual");
if (!rc && (core->bl_tag == 63))
core->bl_tag = 0;
}
}
mutex_unlock(&client->lock);
return rc;
}
int cam_virtual_cdm_probe(struct platform_device *pdev)
{
struct cam_hw_info *cdm_hw = NULL;
struct cam_hw_intf *cdm_hw_intf = NULL;
struct cam_cdm *cdm_core = NULL;
struct cam_cdm_private_dt_data *soc_private = NULL;
int rc;
struct cam_cpas_register_params cpas_parms;
cdm_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
if (!cdm_hw_intf)
return -ENOMEM;
cdm_hw = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
if (!cdm_hw) {
kfree(cdm_hw_intf);
return -ENOMEM;
}
cdm_hw->core_info = kzalloc(sizeof(struct cam_cdm), GFP_KERNEL);
if (!cdm_hw->core_info) {
kfree(cdm_hw);
kfree(cdm_hw_intf);
return -ENOMEM;
}
cdm_hw->hw_state = CAM_HW_STATE_POWER_DOWN;
cdm_hw->soc_info.pdev = pdev;
cdm_hw_intf->hw_type = CAM_VIRTUAL_CDM;
cdm_hw->soc_info.soc_private = kzalloc(
sizeof(struct cam_cdm_private_dt_data), GFP_KERNEL);
if (!cdm_hw->soc_info.soc_private) {
rc = -ENOMEM;
goto soc_load_failed;
}
rc = cam_cdm_soc_load_dt_private(pdev, cdm_hw->soc_info.soc_private);
if (rc) {
CAM_ERR(CAM_CDM, "Failed to load CDM dt private data");
kfree(cdm_hw->soc_info.soc_private);
cdm_hw->soc_info.soc_private = NULL;
goto soc_load_failed;
}
cdm_core = (struct cam_cdm *)cdm_hw->core_info;
soc_private = (struct cam_cdm_private_dt_data *)
cdm_hw->soc_info.soc_private;
if (soc_private->dt_cdm_shared == true)
cdm_core->flags = CAM_CDM_FLAG_SHARED_CDM;
else
cdm_core->flags = CAM_CDM_FLAG_PRIVATE_CDM;
cdm_core->bl_tag = 0;
INIT_LIST_HEAD(&cdm_core->bl_request_list);
init_completion(&cdm_core->reset_complete);
cdm_hw_intf->hw_priv = cdm_hw;
cdm_hw_intf->hw_ops.get_hw_caps = cam_cdm_get_caps;
cdm_hw_intf->hw_ops.init = NULL;
cdm_hw_intf->hw_ops.deinit = NULL;
cdm_hw_intf->hw_ops.start = cam_cdm_stream_start;
cdm_hw_intf->hw_ops.stop = cam_cdm_stream_stop;
cdm_hw_intf->hw_ops.read = NULL;
cdm_hw_intf->hw_ops.write = NULL;
cdm_hw_intf->hw_ops.process_cmd = cam_cdm_process_cmd;
CAM_DBG(CAM_CDM, "type %d index %d", cdm_hw_intf->hw_type,
cdm_hw_intf->hw_idx);
platform_set_drvdata(pdev, cdm_hw_intf);
cdm_hw->open_count = 0;
cdm_core->iommu_hdl.non_secure = -1;
cdm_core->iommu_hdl.secure = -1;
mutex_init(&cdm_hw->hw_mutex);
spin_lock_init(&cdm_hw->hw_lock);
init_completion(&cdm_hw->hw_complete);
mutex_lock(&cdm_hw->hw_mutex);
cdm_core->id = CAM_CDM_VIRTUAL;
memcpy(cdm_core->name, CAM_CDM_VIRTUAL_NAME,
sizeof(CAM_CDM_VIRTUAL_NAME));
cdm_core->work_queue = alloc_workqueue(cdm_core->name,
WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS,
CAM_CDM_INFLIGHT_WORKS);
cdm_core->ops = NULL;
cpas_parms.cam_cpas_client_cb = cam_cdm_cpas_cb;
cpas_parms.cell_index = cdm_hw->soc_info.index;
cpas_parms.dev = &pdev->dev;
cpas_parms.userdata = cdm_hw_intf;
strlcpy(cpas_parms.identifier, "cam-cdm-intf",
CAM_HW_IDENTIFIER_LENGTH);
rc = cam_cpas_register_client(&cpas_parms);
if (rc) {
CAM_ERR(CAM_CDM, "Virtual CDM CPAS registration failed");
goto cpas_registration_failed;
}
CAM_DBG(CAM_CDM, "CPAS registration successful handle=%d",
cpas_parms.client_handle);
cdm_core->cpas_handle = cpas_parms.client_handle;
CAM_DBG(CAM_CDM, "CDM%d probe successful", cdm_hw_intf->hw_idx);
rc = cam_cdm_intf_register_hw_cdm(cdm_hw_intf,
soc_private, CAM_VIRTUAL_CDM, &cdm_core->index);
if (rc) {
CAM_ERR(CAM_CDM, "Virtual CDM Interface registration failed");
goto intf_registration_failed;
}
CAM_DBG(CAM_CDM, "CDM%d registered to intf successful",
cdm_hw_intf->hw_idx);
mutex_unlock(&cdm_hw->hw_mutex);
return 0;
intf_registration_failed:
cam_cpas_unregister_client(cdm_core->cpas_handle);
cpas_registration_failed:
kfree(cdm_hw->soc_info.soc_private);
flush_workqueue(cdm_core->work_queue);
destroy_workqueue(cdm_core->work_queue);
mutex_unlock(&cdm_hw->hw_mutex);
mutex_destroy(&cdm_hw->hw_mutex);
soc_load_failed:
kfree(cdm_hw->core_info);
kfree(cdm_hw);
kfree(cdm_hw_intf);
return rc;
}
int cam_virtual_cdm_remove(struct platform_device *pdev)
{
struct cam_hw_info *cdm_hw = NULL;
struct cam_hw_intf *cdm_hw_intf = NULL;
struct cam_cdm *cdm_core = NULL;
int rc = -EBUSY;
cdm_hw_intf = platform_get_drvdata(pdev);
if (!cdm_hw_intf) {
CAM_ERR(CAM_CDM, "Failed to get dev private data");
return rc;
}
cdm_hw = cdm_hw_intf->hw_priv;
if (!cdm_hw) {
CAM_ERR(CAM_CDM,
"Failed to get virtual private data for type=%d idx=%d",
cdm_hw_intf->hw_type, cdm_hw_intf->hw_idx);
return rc;
}
cdm_core = cdm_hw->core_info;
if (!cdm_core) {
CAM_ERR(CAM_CDM,
"Failed to get virtual core data for type=%d idx=%d",
cdm_hw_intf->hw_type, cdm_hw_intf->hw_idx);
return rc;
}
rc = cam_cpas_unregister_client(cdm_core->cpas_handle);
if (rc) {
CAM_ERR(CAM_CDM, "CPAS unregister failed");
return rc;
}
rc = cam_cdm_intf_deregister_hw_cdm(cdm_hw_intf,
cdm_hw->soc_info.soc_private, CAM_VIRTUAL_CDM,
cdm_core->index);
if (rc) {
CAM_ERR(CAM_CDM,
"Virtual CDM Interface de-registration failed");
return rc;
}
flush_workqueue(cdm_core->work_queue);
destroy_workqueue(cdm_core->work_queue);
mutex_destroy(&cdm_hw->hw_mutex);
kfree(cdm_hw->soc_info.soc_private);
kfree(cdm_hw->core_info);
kfree(cdm_hw);
kfree(cdm_hw_intf);
rc = 0;
return rc;
}

View file

@ -0,0 +1,768 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/refcount.h>
#include "cam_context.h"
#include "cam_debug_util.h"
#include "cam_node.h"
static int cam_context_handle_hw_event(void *context, uint32_t evt_id,
void *evt_data)
{
int rc = 0;
struct cam_context *ctx = (struct cam_context *)context;
if (!ctx || !ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (ctx->state_machine[ctx->state].irq_ops)
rc = ctx->state_machine[ctx->state].irq_ops(ctx, evt_id,
evt_data);
else
CAM_DBG(CAM_CORE,
"No function to handle event %d in dev %d, state %d",
evt_id, ctx->dev_hdl, ctx->state);
return rc;
}
int cam_context_shutdown(struct cam_context *ctx)
{
int rc = 0;
struct cam_release_dev_cmd cmd;
if (ctx->state > CAM_CTX_AVAILABLE && ctx->state < CAM_CTX_STATE_MAX) {
cmd.session_handle = ctx->session_hdl;
cmd.dev_handle = ctx->dev_hdl;
rc = cam_context_handle_release_dev(ctx, &cmd);
if (rc)
CAM_ERR(CAM_CORE,
"context release failed for dev_name %s",
ctx->dev_name);
else
cam_context_putref(ctx);
} else {
CAM_WARN(CAM_CORE,
"dev %s context id %u state %d invalid to release hdl",
ctx->dev_name, ctx->ctx_id, ctx->state);
rc = -EINVAL;
}
if (ctx->dev_hdl != -1) {
rc = cam_destroy_device_hdl(ctx->dev_hdl);
if (rc)
CAM_ERR(CAM_CORE,
"destroy device hdl failed for node %s",
ctx->dev_name);
else
ctx->dev_hdl = -1;
}
return rc;
}
int cam_context_handle_crm_get_dev_info(struct cam_context *ctx,
struct cam_req_mgr_device_info *info)
{
int rc;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!info) {
CAM_ERR(CAM_CORE, "Invalid get device info payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].crm_ops.get_dev_info) {
rc = ctx->state_machine[ctx->state].crm_ops.get_dev_info(
ctx, info);
} else {
CAM_ERR(CAM_CORE, "No get device info in dev %d, state %d",
ctx->dev_hdl, ctx->state);
rc = -EPROTO;
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_crm_link(struct cam_context *ctx,
struct cam_req_mgr_core_dev_link_setup *link)
{
int rc;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!link) {
CAM_ERR(CAM_CORE, "Invalid link payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].crm_ops.link) {
rc = ctx->state_machine[ctx->state].crm_ops.link(ctx, link);
} else {
CAM_ERR(CAM_CORE, "No crm link in dev %d, state %d",
ctx->dev_hdl, ctx->state);
rc = -EPROTO;
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_crm_unlink(struct cam_context *ctx,
struct cam_req_mgr_core_dev_link_setup *unlink)
{
int rc;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!unlink) {
CAM_ERR(CAM_CORE, "Invalid unlink payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].crm_ops.unlink) {
rc = ctx->state_machine[ctx->state].crm_ops.unlink(
ctx, unlink);
} else {
CAM_ERR(CAM_CORE, "No crm unlink in dev %d, name %s, state %d",
ctx->dev_hdl, ctx->dev_name, ctx->state);
rc = -EPROTO;
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_crm_apply_req(struct cam_context *ctx,
struct cam_req_mgr_apply_request *apply)
{
int rc;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!apply) {
CAM_ERR(CAM_CORE, "Invalid apply request payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].crm_ops.apply_req) {
rc = ctx->state_machine[ctx->state].crm_ops.apply_req(ctx,
apply);
} else {
CAM_ERR(CAM_CORE, "No crm apply req in dev %d, state %d",
ctx->dev_hdl, ctx->state);
rc = -EPROTO;
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_crm_notify_frame_skip(
struct cam_context *ctx,
struct cam_req_mgr_apply_request *apply)
{
int rc = 0;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!apply) {
CAM_ERR(CAM_CORE, "Invalid apply request payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].crm_ops.notify_frame_skip)
rc = ctx->state_machine[ctx->state].crm_ops.notify_frame_skip(
ctx, apply);
else
CAM_DBG(CAM_CORE,
"No crm notify_frame_skip in dev %d, state %d",
ctx->dev_hdl, ctx->state);
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_crm_flush_req(struct cam_context *ctx,
struct cam_req_mgr_flush_request *flush)
{
int rc;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].crm_ops.flush_req) {
rc = ctx->state_machine[ctx->state].crm_ops.flush_req(ctx,
flush);
} else {
CAM_ERR(CAM_CORE, "No crm flush req in dev %d, state %d",
ctx->dev_hdl, ctx->state);
rc = -EPROTO;
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_crm_process_evt(struct cam_context *ctx,
struct cam_req_mgr_link_evt_data *process_evt)
{
int rc = 0;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].crm_ops.process_evt) {
rc = ctx->state_machine[ctx->state].crm_ops.process_evt(ctx,
process_evt);
} else {
/* handling of this message is optional */
CAM_DBG(CAM_CORE, "No crm process evt in dev %d, state %d",
ctx->dev_hdl, ctx->state);
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_crm_dump_req(struct cam_context *ctx,
struct cam_req_mgr_dump_info *dump)
{
int rc = 0;
if (!ctx) {
CAM_ERR(CAM_CORE, "Invalid Context");
return -EINVAL;
}
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context %s ctx_id %d is not ready",
ctx->dev_name, ctx->ctx_id);
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].crm_ops.dump_req)
rc = ctx->state_machine[ctx->state].crm_ops.dump_req(ctx,
dump);
else
CAM_ERR(CAM_CORE, "No crm dump req for %s dev %d, state %d",
ctx->dev_name, ctx->dev_hdl, ctx->state);
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_dump_pf_info(struct cam_context *ctx,
struct cam_smmu_pf_info *pf_info)
{
int rc = 0;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if ((ctx->state > CAM_CTX_AVAILABLE) &&
(ctx->state < CAM_CTX_STATE_MAX)) {
if (ctx->state_machine[ctx->state].pagefault_ops) {
rc = ctx->state_machine[ctx->state].pagefault_ops(
ctx, pf_info);
} else {
CAM_WARN(CAM_CORE, "No dump ctx in dev %d, state %d",
ctx->dev_hdl, ctx->state);
}
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_message(struct cam_context *ctx,
uint32_t msg_type, uint32_t *data)
{
int rc = 0;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if ((ctx->state > CAM_CTX_AVAILABLE) &&
(ctx->state < CAM_CTX_STATE_MAX)) {
if (ctx->state_machine[ctx->state].msg_cb_ops) {
rc = ctx->state_machine[ctx->state].msg_cb_ops(
ctx, msg_type, data);
} else {
CAM_WARN(CAM_CORE,
"No message handler for ctx %d, state %d msg_type :%d",
ctx->dev_hdl, ctx->state, msg_type);
}
}
return rc;
}
int cam_context_handle_acquire_dev(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd)
{
int rc;
int i;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!cmd) {
CAM_ERR(CAM_CORE, "Invalid acquire device command payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].ioctl_ops.acquire_dev) {
rc = ctx->state_machine[ctx->state].ioctl_ops.acquire_dev(
ctx, cmd);
} else {
CAM_ERR(CAM_CORE, "No acquire device in dev %d, state %d",
cmd->dev_handle, ctx->state);
rc = -EPROTO;
}
INIT_LIST_HEAD(&ctx->active_req_list);
INIT_LIST_HEAD(&ctx->wait_req_list);
INIT_LIST_HEAD(&ctx->pending_req_list);
INIT_LIST_HEAD(&ctx->free_req_list);
for (i = 0; i < ctx->req_size; i++) {
INIT_LIST_HEAD(&ctx->req_list[i].list);
list_add_tail(&ctx->req_list[i].list, &ctx->free_req_list);
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_acquire_hw(struct cam_context *ctx,
void *args)
{
int rc;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!args) {
CAM_ERR(CAM_CORE, "Invalid acquire device hw command payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].ioctl_ops.acquire_hw) {
rc = ctx->state_machine[ctx->state].ioctl_ops.acquire_hw(
ctx, args);
} else {
CAM_ERR(CAM_CORE, "No acquire hw for dev %s, state %d",
ctx->dev_name, ctx->state);
rc = -EPROTO;
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_release_dev(struct cam_context *ctx,
struct cam_release_dev_cmd *cmd)
{
int rc;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!cmd) {
CAM_ERR(CAM_CORE, "Invalid release device command payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].ioctl_ops.release_dev) {
rc = ctx->state_machine[ctx->state].ioctl_ops.release_dev(
ctx, cmd);
} else {
CAM_ERR(CAM_CORE, "No release device in dev %d, state %d",
ctx->dev_hdl, ctx->state);
rc = -EPROTO;
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_release_hw(struct cam_context *ctx,
void *args)
{
int rc;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!args) {
CAM_ERR(CAM_CORE, "Invalid release HW command payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].ioctl_ops.release_hw) {
rc = ctx->state_machine[ctx->state].ioctl_ops.release_hw(
ctx, args);
} else {
CAM_ERR(CAM_CORE, "No release hw for dev %s, state %d",
ctx->dev_name, ctx->state);
rc = -EPROTO;
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_flush_dev(struct cam_context *ctx,
struct cam_flush_dev_cmd *cmd)
{
int rc = 0;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!cmd) {
CAM_ERR(CAM_CORE, "Invalid flush device command payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].ioctl_ops.flush_dev) {
rc = ctx->state_machine[ctx->state].ioctl_ops.flush_dev(
ctx, cmd);
} else {
CAM_WARN(CAM_CORE, "No flush device in dev %d, state %d",
ctx->dev_hdl, ctx->state);
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_config_dev(struct cam_context *ctx,
struct cam_config_dev_cmd *cmd)
{
int rc;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "context is not ready");
return -EINVAL;
}
if (!cmd) {
CAM_ERR(CAM_CORE, "Invalid config device command payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].ioctl_ops.config_dev) {
rc = ctx->state_machine[ctx->state].ioctl_ops.config_dev(
ctx, cmd);
} else {
CAM_ERR(CAM_CORE, "No config device in dev %d, state %d",
ctx->dev_hdl, ctx->state);
rc = -EPROTO;
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_start_dev(struct cam_context *ctx,
struct cam_start_stop_dev_cmd *cmd)
{
int rc = 0;
if (!ctx || !ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!cmd) {
CAM_ERR(CAM_CORE, "Invalid start device command payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].ioctl_ops.start_dev)
rc = ctx->state_machine[ctx->state].ioctl_ops.start_dev(
ctx, cmd);
else
/* start device can be optional for some driver */
CAM_DBG(CAM_CORE, "No start device in dev %d, state %d",
ctx->dev_hdl, ctx->state);
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_stop_dev(struct cam_context *ctx,
struct cam_start_stop_dev_cmd *cmd)
{
int rc = 0;
if (!ctx || !ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!cmd) {
CAM_ERR(CAM_CORE, "Invalid stop device command payload");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].ioctl_ops.stop_dev)
rc = ctx->state_machine[ctx->state].ioctl_ops.stop_dev(
ctx, cmd);
else
/* stop device can be optional for some driver */
CAM_WARN(CAM_CORE, "No stop device in dev %d, name %s state %d",
ctx->dev_hdl, ctx->dev_name, ctx->state);
ctx->last_flush_req = 0;
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_shutdown_dev(struct cam_context *ctx,
struct cam_control *cmd, struct v4l2_subdev_fh *fh)
{
int rc = 0;
if (!ctx || !ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
if (!cmd) {
CAM_ERR(CAM_CORE, "Invalid stop device command payload");
return -EINVAL;
}
if (ctx->state_machine[ctx->state].ioctl_ops.shutdown_dev)
rc = ctx->state_machine[ctx->state].ioctl_ops.shutdown_dev(
(struct v4l2_subdev *)cmd->handle, fh);
else
CAM_WARN(CAM_CORE, "No shutdown device in dev %d, state %d",
ctx->dev_hdl, ctx->state);
return rc;
}
int cam_context_handle_info_dump(void *context,
enum cam_context_dump_id id)
{
int rc = 0;
struct cam_context *ctx = (struct cam_context *)context;
if (!ctx || !ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].dumpinfo_ops)
rc = ctx->state_machine[ctx->state].dumpinfo_ops(ctx,
id);
mutex_unlock(&ctx->ctx_mutex);
if (rc)
CAM_WARN(CAM_CORE,
"Dump for id %u failed on ctx_id %u name %s state %d",
id, ctx->ctx_id, ctx->dev_name, ctx->state);
return rc;
}
int cam_context_handle_dump_dev(struct cam_context *ctx,
struct cam_dump_req_cmd *cmd)
{
int rc = 0;
if (!ctx) {
CAM_ERR(CAM_CORE, "Invalid Context");
return -EINVAL;
}
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context %s ctx_id %d is not ready",
ctx->dev_name, ctx->ctx_id);
return -EINVAL;
}
if (!cmd) {
CAM_ERR(CAM_CORE,
"Context %s ctx_id %d Invalid dump command payload",
ctx->dev_name, ctx->ctx_id);
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
CAM_DBG(CAM_CORE, "dump device in dev %d, name %s state %d",
ctx->dev_hdl, ctx->dev_name, ctx->state);
if (ctx->state_machine[ctx->state].ioctl_ops.dump_dev)
rc = ctx->state_machine[ctx->state].ioctl_ops.dump_dev(
ctx, cmd);
else
CAM_WARN(CAM_CORE, "No dump device in dev %d, name %s state %d",
ctx->dev_hdl, ctx->dev_name, ctx->state);
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_init(struct cam_context *ctx,
const char *dev_name,
uint64_t dev_id,
uint32_t ctx_id,
struct cam_req_mgr_kmd_ops *crm_node_intf,
struct cam_hw_mgr_intf *hw_mgr_intf,
struct cam_ctx_request *req_list,
uint32_t req_size)
{
int i;
/* crm_node_intf is optinal */
if (!ctx || !hw_mgr_intf || !req_list) {
CAM_ERR(CAM_CORE, "Invalid input parameters");
return -EINVAL;
}
memset(ctx, 0, sizeof(*ctx));
ctx->dev_hdl = -1;
ctx->link_hdl = -1;
ctx->session_hdl = -1;
INIT_LIST_HEAD(&ctx->list);
mutex_init(&ctx->ctx_mutex);
mutex_init(&ctx->sync_mutex);
spin_lock_init(&ctx->lock);
strlcpy(ctx->dev_name, dev_name, CAM_CTX_DEV_NAME_MAX_LENGTH);
ctx->dev_id = dev_id;
ctx->ctx_id = ctx_id;
ctx->last_flush_req = 0;
ctx->ctx_crm_intf = NULL;
ctx->crm_ctx_intf = crm_node_intf;
ctx->hw_mgr_intf = hw_mgr_intf;
ctx->irq_cb_intf = cam_context_handle_hw_event;
INIT_LIST_HEAD(&ctx->active_req_list);
INIT_LIST_HEAD(&ctx->wait_req_list);
INIT_LIST_HEAD(&ctx->pending_req_list);
INIT_LIST_HEAD(&ctx->free_req_list);
ctx->req_list = req_list;
ctx->req_size = req_size;
for (i = 0; i < req_size; i++) {
INIT_LIST_HEAD(&ctx->req_list[i].list);
list_add_tail(&ctx->req_list[i].list, &ctx->free_req_list);
ctx->req_list[i].ctx = ctx;
}
ctx->state = CAM_CTX_AVAILABLE;
ctx->state_machine = NULL;
ctx->ctx_priv = NULL;
return 0;
}
int cam_context_deinit(struct cam_context *ctx)
{
if (!ctx)
return -EINVAL;
/**
* This is called from platform device remove.
* Everyting should be released at this moment.
* so we just free the memory for the context
*/
if (ctx->state != CAM_CTX_AVAILABLE)
CAM_ERR(CAM_CORE, "Device did not shutdown cleanly");
memset(ctx, 0, sizeof(*ctx));
return 0;
}
void cam_context_putref(struct cam_context *ctx)
{
if (kref_read(&ctx->refcount))
kref_put(&ctx->refcount, cam_node_put_ctxt_to_free_list);
else
WARN(1, "ctx %s %d state %d devhdl %X\n", ctx->dev_name,
ctx->ctx_id, ctx->state, ctx->dev_hdl);
CAM_DBG(CAM_CORE,
"ctx device hdl %ld, ref count %d, dev_name %s",
ctx->dev_hdl, refcount_read(&(ctx->refcount.refcount)),
ctx->dev_name);
}
void cam_context_getref(struct cam_context *ctx)
{
if (kref_get_unless_zero(&ctx->refcount) == 0) {
/* should never happen */
WARN(1, "%s fail\n", __func__);
}
CAM_DBG(CAM_CORE,
"ctx device hdl %ld, ref count %d, dev_name %s",
ctx->dev_hdl, refcount_read(&(ctx->refcount.refcount)),
ctx->dev_name);
}

View file

@ -0,0 +1,578 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CONTEXT_H_
#define _CAM_CONTEXT_H_
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/kref.h>
#include <media/v4l2-subdev.h>
#include "cam_req_mgr_interface.h"
#include "cam_hw_mgr_intf.h"
#include "cam_smmu_api.h"
/* Forward declarations */
struct cam_context;
/* max device name string length*/
#define CAM_CTX_DEV_NAME_MAX_LENGTH 20
/* max request number */
#define CAM_CTX_REQ_MAX 20
#define CAM_CTX_ICP_REQ_MAX 40
#define CAM_CTX_CFG_MAX 20
#define CAM_CTX_RES_MAX 20
/* max tag dump header string length*/
#define CAM_CTXT_DUMP_TAG_MAX_LEN 32
/* Number of words to be dumped for context*/
#define CAM_CTXT_DUMP_NUM_WORDS 10
/**
* enum cam_ctx_state - context top level states
*
*/
enum cam_context_state {
CAM_CTX_UNINIT = 0,
CAM_CTX_AVAILABLE = 1,
CAM_CTX_ACQUIRED = 2,
CAM_CTX_READY = 3,
CAM_CTX_FLUSHED = 4,
CAM_CTX_ACTIVATED = 5,
CAM_CTX_STATE_MAX = 6,
};
/**
* struct cam_ctx_request - Common request structure for the context
*
* @list: Link list entry
* @status: Request status
* @request_id: Request id
* @req_priv: Derived request object
* @hw_update_entries: Hardware update entries
* @num_hw_update_entries: Number of hardware update entries
* @in_map_entries: Entries for in fences
* @num_in_map_entries: Number of in map entries
* @out_map_entries: Entries for out fences
* @num_out_map_entries: Number of out map entries
* @num_in_acked: Number of in fence acked
* @num_out_acked: Number of out fence acked
* @flushed: Request is flushed
* @ctx: The context to which this request belongs
* @pf_data page fault debug data
*
*/
struct cam_ctx_request {
struct list_head list;
uint32_t status;
uint64_t request_id;
void *req_priv;
struct cam_hw_update_entry hw_update_entries[CAM_CTX_CFG_MAX];
uint32_t num_hw_update_entries;
struct cam_hw_fence_map_entry in_map_entries[CAM_CTX_CFG_MAX];
uint32_t num_in_map_entries;
struct cam_hw_fence_map_entry out_map_entries[CAM_CTX_CFG_MAX];
uint32_t num_out_map_entries;
atomic_t num_in_acked;
uint32_t num_out_acked;
int flushed;
struct cam_context *ctx;
struct cam_hw_mgr_dump_pf_data pf_data;
};
/**
* struct cam_ctx_ioctl_ops - Function table for handling IOCTL calls
*
* @acquire_dev: Function pointer for acquire device
* @release_dev: Function pointer for release device
* @config_dev: Function pointer for config device
* @start_dev: Function pointer for start device
* @stop_dev: Function pointer for stop device
* @flush_dev: Function pointer for flush device
* @acquire_hw: Function pointer for acquire hw
* @release_hw: Function pointer for release hw
* @dump_dev: Function pointer for dump dev
* @shutdown_dev: Function pointer for shutdown dev
*
*/
struct cam_ctx_ioctl_ops {
int (*acquire_dev)(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd);
int (*release_dev)(struct cam_context *ctx,
struct cam_release_dev_cmd *cmd);
int (*config_dev)(struct cam_context *ctx,
struct cam_config_dev_cmd *cmd);
int (*start_dev)(struct cam_context *ctx,
struct cam_start_stop_dev_cmd *cmd);
int (*stop_dev)(struct cam_context *ctx,
struct cam_start_stop_dev_cmd *cmd);
int (*flush_dev)(struct cam_context *ctx,
struct cam_flush_dev_cmd *cmd);
int (*acquire_hw)(struct cam_context *ctx, void *args);
int (*release_hw)(struct cam_context *ctx, void *args);
int (*dump_dev)(struct cam_context *ctx,
struct cam_dump_req_cmd *cmd);
int (*shutdown_dev)(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh);
};
/**
* struct cam_ctx_crm_ops - Function table for handling CRM to context calls
*
* @get_dev_info: Get device informaiton
* @link: Link the context
* @unlink: Unlink the context
* @apply_req: Apply setting for the context
* @notify_frame_skip: Notify device that a frame is skipped
* @flush_req: Flush request to remove request ids
* @process_evt: Handle event notification from CRM.(optional)
* @dump_req: Dump information for the issue request
*
*/
struct cam_ctx_crm_ops {
int (*get_dev_info)(struct cam_context *ctx,
struct cam_req_mgr_device_info *device_info);
int (*link)(struct cam_context *ctx,
struct cam_req_mgr_core_dev_link_setup *link);
int (*unlink)(struct cam_context *ctx,
struct cam_req_mgr_core_dev_link_setup *unlink);
int (*apply_req)(struct cam_context *ctx,
struct cam_req_mgr_apply_request *apply);
int (*notify_frame_skip)(struct cam_context *ctx,
struct cam_req_mgr_apply_request *apply);
int (*flush_req)(struct cam_context *ctx,
struct cam_req_mgr_flush_request *flush);
int (*process_evt)(struct cam_context *ctx,
struct cam_req_mgr_link_evt_data *evt_data);
int (*dump_req)(struct cam_context *ctx,
struct cam_req_mgr_dump_info *dump);
};
/**
* struct cam_ctx_ops - Collection of the interface funciton tables
*
* @ioctl_ops: Ioctl funciton table
* @crm_ops: CRM to context interface function table
* @irq_ops: Hardware event handle function
* @pagefault_ops: Function to be called on page fault
* @dumpinfo_ops: Function to be invoked for dumping any
* context info
* @msg_cb_ops: Function to be called on any message from
* other subdev notifications
*
*/
struct cam_ctx_ops {
struct cam_ctx_ioctl_ops ioctl_ops;
struct cam_ctx_crm_ops crm_ops;
cam_hw_event_cb_func irq_ops;
cam_hw_pagefault_cb_func pagefault_ops;
cam_ctx_info_dump_cb_func dumpinfo_ops;
cam_ctx_message_cb_func msg_cb_ops;
};
/**
* struct cam_context - camera context object for the subdevice node
*
* @dev_name: String giving name of device associated
* @dev_id: ID of device associated
* @ctx_id: ID for this context
* @list: Link list entry
* @sessoin_hdl: Session handle
* @dev_hdl: Device handle
* @link_hdl: Link handle
* @ctx_mutex: Mutex for ioctl calls
* @lock: Spin lock
* @active_req_list: Requests pending for done event
* @pending_req_list: Requests pending for reg upd event
* @wait_req_list: Requests waiting for apply
* @free_req_list: Requests that are free
* @req_list: Reference to the request storage
* @req_size: Size of the request storage
* @hw_mgr_intf: Context to HW interface
* @ctx_crm_intf: Context to CRM interface
* @crm_ctx_intf: CRM to context interface
* @irq_cb_intf: HW to context callback interface
* @state: Current state for top level state machine
* @state_machine: Top level state machine
* @ctx_priv: Private context pointer
* @ctxt_to_hw_map: Context to hardware mapping pointer
* @refcount: Context object refcount
* @node: The main node to which this context belongs
* @sync_mutex: mutex to sync with sync cb thread
* @last_flush_req: Last request to flush
*
*/
struct cam_context {
char dev_name[CAM_CTX_DEV_NAME_MAX_LENGTH];
uint64_t dev_id;
uint32_t ctx_id;
struct list_head list;
int32_t session_hdl;
int32_t dev_hdl;
int32_t link_hdl;
struct mutex ctx_mutex;
spinlock_t lock;
struct list_head active_req_list;
struct list_head pending_req_list;
struct list_head wait_req_list;
struct list_head free_req_list;
struct cam_ctx_request *req_list;
uint32_t req_size;
struct cam_hw_mgr_intf *hw_mgr_intf;
struct cam_req_mgr_crm_cb *ctx_crm_intf;
struct cam_req_mgr_kmd_ops *crm_ctx_intf;
cam_hw_event_cb_func irq_cb_intf;
enum cam_context_state state;
struct cam_ctx_ops *state_machine;
void *ctx_priv;
void *ctxt_to_hw_map;
struct kref refcount;
void *node;
struct mutex sync_mutex;
uint32_t last_flush_req;
};
/**
* struct cam_context_dump_header - Function for context dump header
*
* @tag : Tag for context dump header
* @size : Size of data
* @word_size : Word size of data
*/
struct cam_context_dump_header {
uint8_t tag[CAM_CTXT_DUMP_TAG_MAX_LEN];
uint64_t size;
uint32_t word_size;
};
/**
* cam_context_shutdown()
*
* @brief: Calls while device close or shutdown
*
* @ctx: Object pointer for cam_context
*
*/
int cam_context_shutdown(struct cam_context *ctx);
/**
* cam_context_handle_crm_get_dev_info()
*
* @brief: Handle get device information command
*
* @ctx: Object pointer for cam_context
* @info: Device information returned
*
*/
int cam_context_handle_crm_get_dev_info(struct cam_context *ctx,
struct cam_req_mgr_device_info *info);
/**
* cam_context_handle_crm_link()
*
* @brief: Handle link command
*
* @ctx: Object pointer for cam_context
* @link: Link command payload
*
*/
int cam_context_handle_crm_link(struct cam_context *ctx,
struct cam_req_mgr_core_dev_link_setup *link);
/**
* cam_context_handle_crm_unlink()
*
* @brief: Handle unlink command
*
* @ctx: Object pointer for cam_context
* @unlink: Unlink command payload
*
*/
int cam_context_handle_crm_unlink(struct cam_context *ctx,
struct cam_req_mgr_core_dev_link_setup *unlink);
/**
* cam_context_handle_crm_apply_req()
*
* @brief: Handle apply request command
*
* @ctx: Object pointer for cam_context
* @apply: Apply request command payload
*
*/
int cam_context_handle_crm_apply_req(struct cam_context *ctx,
struct cam_req_mgr_apply_request *apply);
/**
* cam_context_handle_crm_notify_frame_skip()
*
* @brief: Handle notify frame skip command
*
* @ctx: Object pointer for cam_context
* @apply: Notify frame skip command payload
*
*/
int cam_context_handle_crm_notify_frame_skip(
struct cam_context *ctx, struct cam_req_mgr_apply_request *apply);
/**
* cam_context_handle_crm_flush_req()
*
* @brief: Handle flush request command
*
* @ctx: Object pointer for cam_context
* @apply: Flush request command payload
*
*/
int cam_context_handle_crm_flush_req(struct cam_context *ctx,
struct cam_req_mgr_flush_request *apply);
/**
* cam_context_handle_crm_process_evt()
*
* @brief: Handle process event command
*
* @ctx: Object pointer for cam_context
* @process_evt: process event command payload
*
*/
int cam_context_handle_crm_process_evt(struct cam_context *ctx,
struct cam_req_mgr_link_evt_data *process_evt);
/**
* cam_context_handle_crm_dump_req()
*
* @brief: Handle CRM dump request
*
* @ctx: Object pointer for cam_context
* @dump: Dump request command payload
*
*/
int cam_context_handle_crm_dump_req(struct cam_context *ctx,
struct cam_req_mgr_dump_info *dump);
/**
* cam_context_dump_pf_info()
*
* @brief: Handle dump active request request command
*
* @ctx: Object pointer for cam_context
* @pf_info: Smmu page fault info
*
*/
int cam_context_dump_pf_info(struct cam_context *ctx,
struct cam_smmu_pf_info *pf_info);
/**
* 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, uint32_t *data);
/**
* cam_context_handle_acquire_dev()
*
* @brief: Handle acquire device command
*
* @ctx: Object pointer for cam_context
* @cmd: Acquire device command payload
*
*/
int cam_context_handle_acquire_dev(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd);
/**
* cam_context_handle_acquire_hw()
*
* @brief: Handle acquire HW command
*
* @ctx: Object pointer for cam_context
* @cmd: Acquire HW command payload
*
*/
int cam_context_handle_acquire_hw(struct cam_context *ctx,
void *cmd);
/**
* cam_context_handle_release_dev()
*
* @brief: Handle release device command
*
* @ctx: Object pointer for cam_context
* @cmd: Release device command payload
*
*/
int cam_context_handle_release_dev(struct cam_context *ctx,
struct cam_release_dev_cmd *cmd);
/**
* cam_context_handle_release_hw()
*
* @brief: Handle release HW command
*
* @ctx: Object pointer for cam_context
* @cmd: Release HW command payload
*
*/
int cam_context_handle_release_hw(struct cam_context *ctx,
void *cmd);
/**
* cam_context_handle_config_dev()
*
* @brief: Handle config device command
*
* @ctx: Object pointer for cam_context
* @cmd: Config device command payload
*
*/
int cam_context_handle_config_dev(struct cam_context *ctx,
struct cam_config_dev_cmd *cmd);
/**
* cam_context_handle_flush_dev()
*
* @brief: Handle flush device command
*
* @ctx: Object pointer for cam_context
* @cmd: Flush device command payload
*
*/
int cam_context_handle_flush_dev(struct cam_context *ctx,
struct cam_flush_dev_cmd *cmd);
/**
* cam_context_handle_start_dev()
*
* @brief: Handle start device command
*
* @ctx: Object pointer for cam_context
* @cmd: Start device command payload
*
*/
int cam_context_handle_start_dev(struct cam_context *ctx,
struct cam_start_stop_dev_cmd *cmd);
/**
* cam_context_handle_stop_dev()
*
* @brief: Handle stop device command
*
* @ctx: Object pointer for cam_context
* @cmd: Stop device command payload
*
*/
int cam_context_handle_stop_dev(struct cam_context *ctx,
struct cam_start_stop_dev_cmd *cmd);
/**
* cam_context_handle_shutdown_dev()
*
* @brief: Handle shutdown device command
*
* @ctx: Object pointer for cam_context
* @cmd: Shutdown device command payload
* @fh: Pointer to struct v4l2_subdev_fh
*
*/
int cam_context_handle_shutdown_dev(struct cam_context *ctx,
struct cam_control *cmd, struct v4l2_subdev_fh *fh);
/**
* cam_context_handle_dump_dev()
*
* @brief: Handle dump device command
*
* @ctx: Object pointer for cam_context
* @cmd: Dump device command payload
*
*/
int cam_context_handle_dump_dev(struct cam_context *ctx,
struct cam_dump_req_cmd *cmd);
/**
* cam_context_handle_info_dump()
*
* @brief: Handle any dump info for the context
*
* @ctx: Object pointer for cam_context
* @id: To indicate which info pertaining
* to that ctx needs to be dumped
*
*/
int cam_context_handle_info_dump(void *context,
enum cam_context_dump_id id);
/**
* cam_context_deinit()
*
* @brief: Camera context deinitialize function
*
* @ctx: Object pointer for cam_context
*
*/
int cam_context_deinit(struct cam_context *ctx);
/**
* cam_context_init()
*
* @brief: Camera context initialize function
*
* @ctx: Object pointer for cam_context
* @dev_name: String giving name of device associated
* @dev_id: ID of the device associated
* @ctx_id: ID for this context
* @crm_node_intf: Function table for crm to context interface
* @hw_mgr_intf: Function table for context to hw interface
* @req_list: Requests storage
* @req_size: Size of the request storage
*
*/
int cam_context_init(struct cam_context *ctx,
const char *dev_name,
uint64_t dev_id,
uint32_t ctx_id,
struct cam_req_mgr_kmd_ops *crm_node_intf,
struct cam_hw_mgr_intf *hw_mgr_intf,
struct cam_ctx_request *req_list,
uint32_t req_size);
/**
* cam_context_putref()
*
* @brief: Put back context reference.
*
* @ctx: Context for which ref is returned
*
*/
void cam_context_putref(struct cam_context *ctx);
/**
* cam_context_getref()
*
* @brief: Get back context reference.
*
* @ctx: Context for which ref is taken
*
*/
void cam_context_getref(struct cam_context *ctx);
#endif /* _CAM_CONTEXT_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,37 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CONTEXT_UTILS_H_
#define _CAM_CONTEXT_UTILS_H_
#include <linux/types.h>
#include "cam_smmu_api.h"
int cam_context_buf_done_from_hw(struct cam_context *ctx,
void *done_event_data, uint32_t evt_id);
int32_t cam_context_release_dev_to_hw(struct cam_context *ctx,
struct cam_release_dev_cmd *cmd);
int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
struct cam_config_dev_cmd *cmd);
int32_t cam_context_config_dev_to_hw(
struct cam_context *ctx, struct cam_config_dev_cmd *cmd);
int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd);
int32_t cam_context_start_dev_to_hw(struct cam_context *ctx,
struct cam_start_stop_dev_cmd *cmd);
int32_t cam_context_stop_dev_to_hw(struct cam_context *ctx);
int32_t cam_context_flush_dev_to_hw(struct cam_context *ctx,
struct cam_flush_dev_cmd *cmd);
int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx);
int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
struct cam_flush_dev_cmd *cmd);
int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
struct cam_hw_mgr_dump_pf_data *pf_data, bool *mem_found, bool *ctx_found,
uint32_t *resource_type,
struct cam_smmu_pf_info *pf_info);
int32_t cam_context_dump_hw_acq_info(struct cam_context *ctx);
int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx,
struct cam_dump_req_cmd *cmd);
#endif /* _CAM_CONTEXT_UTILS_H_ */

View file

@ -0,0 +1,46 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_HW_H_
#define _CAM_HW_H_
#include "cam_soc_util.h"
/*
* This file declares Enums, Structures and APIs to be used as template
* when writing any HW driver in the camera subsystem.
*/
/* Hardware state enum */
enum cam_hw_state {
CAM_HW_STATE_POWER_DOWN,
CAM_HW_STATE_POWER_UP,
};
/**
* struct cam_hw_info - Common hardware information
*
* @hw_mutex: Hardware mutex
* @hw_lock: Hardware spinlock
* @hw_complete: Hardware Completion
* @open_count: Count to track the HW enable from the client
* @hw_state: Hardware state
* @soc_info: Platform SOC properties for hardware
* @node_info: Private HW data related to nodes
* @core_info: Private HW data related to core logic
*
*/
struct cam_hw_info {
struct mutex hw_mutex;
spinlock_t hw_lock;
struct completion hw_complete;
uint32_t open_count;
enum cam_hw_state hw_state;
struct cam_hw_soc_info soc_info;
void *node_info;
void *core_info;
};
#endif /* _CAM_HW_H_ */

View file

@ -0,0 +1,80 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_HW_INTF_H_
#define _CAM_HW_INTF_H_
#include <linux/types.h>
/*
* This file declares Constants, Enums, Structures and APIs to be used as
* Interface between HW driver and HW Manager.
*/
/**
* struct cam_hw_ops - Hardware layer interface functions
*
* @get_hw_caps: Function pointer for get hw caps
* @init: Function poniter for initialize hardware
* @deinit: Function pointer for deinitialize hardware
* @reset: Function pointer for reset hardware
* @reserve: Function pointer for reserve hardware
* @release: Function pointer for release hardware
* @start: Function pointer for start hardware
* @stop: Function pointer for stop hardware
* @read: Function pointer for read hardware registers
* @write: Function pointer for Write hardware registers
* @process_cmd: Function pointer for additional hardware controls
* @flush_cmd: Function pointer for flush requests
*
*/
struct cam_hw_ops {
int (*get_hw_caps)(void *hw_priv,
void *get_hw_cap_args, uint32_t arg_size);
int (*init)(void *hw_priv,
void *init_hw_args, uint32_t arg_size);
int (*deinit)(void *hw_priv,
void *init_hw_args, uint32_t arg_size);
int (*reset)(void *hw_priv,
void *reset_core_args, uint32_t arg_size);
int (*reserve)(void *hw_priv,
void *reserve_args, uint32_t arg_size);
int (*release)(void *hw_priv,
void *release_args, uint32_t arg_size);
int (*start)(void *hw_priv,
void *start_args, uint32_t arg_size);
int (*stop)(void *hw_priv,
void *stop_args, uint32_t arg_size);
int (*read)(void *hw_priv,
void *read_args, uint32_t arg_size);
int (*write)(void *hw_priv,
void *write_args, uint32_t arg_size);
int (*process_cmd)(void *hw_priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size);
int (*flush)(void *hw_priv,
void *flush_args, uint32_t arg_size);
};
/**
* struct cam_hw_intf - Common hardware node
*
* @hw_type: Hardware type
* @hw_idx: Hardware ID
* @hw_ops: Hardware interface function table
* @hw_priv: Private hardware node pointer
*
*/
struct cam_hw_intf {
uint32_t hw_type;
uint32_t hw_idx;
struct cam_hw_ops hw_ops;
void *hw_priv;
};
/* hardware event callback function type */
typedef int (*cam_hw_mgr_event_cb_func)(void *priv, uint32_t evt_id,
void *evt_data);
#endif /* _CAM_HW_INTF_H_ */

View file

@ -0,0 +1,434 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_HW_MGR_INTF_H_
#define _CAM_HW_MGR_INTF_H_
#include <linux/time.h>
#include <linux/types.h>
#include <media/cam_defs.h>
#include "cam_smmu_api.h"
/*
* This file declares Constants, Enums, Structures and APIs to be used as
* Interface between HW Manager and Context.
*/
/* maximum context numbers */
#define CAM_CTX_MAX 8
/* maximum buf done irqs */
#define CAM_NUM_OUT_PER_COMP_IRQ_MAX 12
/* Maximum reg dump cmd buffer entries in a context */
#define CAM_REG_DUMP_MAX_BUF_ENTRIES 10
/**
* enum cam_context_dump_id -
* context dump type
*
*/
enum cam_context_dump_id {
CAM_CTX_DUMP_TYPE_NONE,
CAM_CTX_DUMP_ACQ_INFO,
CAM_CTX_DUMP_TYPE_MAX,
};
#define CAM_CTX_EVT_ID_SUCCESS 0
#define CAM_CTX_EVT_ID_ERROR 1
#define CAM_CTX_EVT_ID_CANCEL 2
/* hardware event callback function type */
typedef int (*cam_hw_event_cb_func)(void *context, uint32_t evt_id,
void *evt_data);
/* hardware page fault callback function type */
typedef int (*cam_hw_pagefault_cb_func)(void *context,
struct cam_smmu_pf_info *pf_info);
/* ctx dump callback function type */
typedef int (*cam_ctx_info_dump_cb_func)(void *context,
enum cam_context_dump_id dump_id);
/* message callback function type */
typedef int (*cam_ctx_message_cb_func)(void *context,
uint32_t message_type, uint32_t *data);
/**
* struct cam_hw_update_entry - Entry for hardware config
*
* @handle: Memory handle for the configuration
* @offset: Memory offset
* @len: Size of the configuration
* @flags: Flags for the config entry(eg. DMI)
* @addr: Address of hardware update entry
*
*/
struct cam_hw_update_entry {
int handle;
uint32_t offset;
uint32_t len;
uint32_t flags;
uintptr_t addr;
};
/**
* struct cam_hw_fence_map_entry - Entry for the resource to sync id map
*
* @resrouce_handle: Resource port id for the buffer
* @sync_id: Sync id
* @image_buf_addr: Image buffer address array
*
*/
struct cam_hw_fence_map_entry {
uint32_t resource_handle;
int32_t sync_id;
int32_t image_buf_addr[CAM_PACKET_MAX_PLANES];
};
/**
* struct cam_hw_done_event_data - Payload for hw done event
*
* @num_handles: number of handles in the event
* @resrouce_handle: list of the resource handle
* @timestamp: time stamp
* @request_id: request identifier
* @evt_param: event parameter
*
*/
struct cam_hw_done_event_data {
uint32_t num_handles;
uint32_t resource_handle[CAM_NUM_OUT_PER_COMP_IRQ_MAX];
struct timeval timestamp;
uint64_t request_id;
uint32_t evt_param;
};
/**
* struct cam_hw_acquire_args - Payload for acquire command
*
* @context_data: Context data pointer for the callback function
* @event_cb: Callback function array
* @num_acq: Total number of acquire in the payload
* @acquire_info: Acquired resource array pointer
* @ctxt_to_hw_map: HW context (returned)
* @custom_enabled: ctx has custom enabled
* @use_frame_header_ts: Use frame header for qtimer ts
* @support_consumed_addr: The platform has last consumed addr register
* @acquired_hw_id: Acquired hardware mask
* @acquired_hw_path: Acquired path mask for an input
* if input splits into multiple paths,
* its updated per hardware
* valid_acquired_hw: Valid num of acquired hardware
*
*/
struct cam_hw_acquire_args {
void *context_data;
cam_hw_event_cb_func event_cb;
uint32_t num_acq;
uint32_t acquire_info_size;
uintptr_t acquire_info;
void *ctxt_to_hw_map;
bool custom_enabled;
bool use_frame_header_ts;
bool support_consumed_addr;
uint32_t acquired_hw_id[CAM_MAX_ACQ_RES];
uint32_t acquired_hw_path[CAM_MAX_ACQ_RES][CAM_MAX_HW_SPLIT];
uint32_t valid_acquired_hw;
};
/**
* struct cam_hw_release_args - Payload for release command
*
* @ctxt_to_hw_map: HW context from the acquire
* @active_req: Active request flag
*
*/
struct cam_hw_release_args {
void *ctxt_to_hw_map;
bool active_req;
};
/**
* struct cam_hw_start_args - Payload for start command
*
* @ctxt_to_hw_map: HW context from the acquire
* @num_hw_update_entries: Number of Hardware configuration
* @hw_update_entries: Hardware configuration list
*
*/
struct cam_hw_start_args {
void *ctxt_to_hw_map;
uint32_t num_hw_update_entries;
struct cam_hw_update_entry *hw_update_entries;
};
/**
* struct cam_hw_stop_args - Payload for stop command
*
* @ctxt_to_hw_map: HW context from the acquire
* @args: Arguments to pass for stop
*
*/
struct cam_hw_stop_args {
void *ctxt_to_hw_map;
void *args;
};
/**
* struct cam_hw_mgr_dump_pf_data - page fault debug data
*
* @packet: pointer to packet
* @req: pointer to req (HW specific)
*/
struct cam_hw_mgr_dump_pf_data {
void *packet;
void *req;
};
/**
* struct cam_hw_prepare_update_args - Payload for prepare command
*
* @packet: CSL packet from user mode driver
* @remain_len Remaining length of CPU buffer after config offset
* @ctxt_to_hw_map: HW context from the acquire
* @max_hw_update_entries: Maximum hardware update entries supported
* @hw_update_entries: Actual hardware update configuration (returned)
* @num_hw_update_entries: Number of actual hardware update entries (returned)
* @max_out_map_entries: Maximum output fence mapping supported
* @out_map_entries: Actual output fence mapping list (returned)
* @num_out_map_entries: Number of actual output fence mapping (returned)
* @max_in_map_entries: Maximum input fence mapping supported
* @in_map_entries: Actual input fence mapping list (returned)
* @num_in_map_entries: Number of acutal input fence mapping (returned)
* @reg_dump_buf_desc: cmd buffer descriptors for reg dump
* @num_reg_dump_buf: Count of descriptors in reg_dump_buf_desc
* @priv: Private pointer of hw update
* @pf_data: Debug data for page fault
*
*/
struct cam_hw_prepare_update_args {
struct cam_packet *packet;
size_t remain_len;
void *ctxt_to_hw_map;
uint32_t max_hw_update_entries;
struct cam_hw_update_entry *hw_update_entries;
uint32_t num_hw_update_entries;
uint32_t max_out_map_entries;
struct cam_hw_fence_map_entry *out_map_entries;
uint32_t num_out_map_entries;
uint32_t max_in_map_entries;
struct cam_hw_fence_map_entry *in_map_entries;
uint32_t num_in_map_entries;
struct cam_cmd_buf_desc reg_dump_buf_desc[
CAM_REG_DUMP_MAX_BUF_ENTRIES];
uint32_t num_reg_dump_buf;
void *priv;
struct cam_hw_mgr_dump_pf_data *pf_data;
};
/**
* struct cam_hw_stream_setttings - Payload for config stream command
*
* @packet: CSL packet from user mode driver
* @ctxt_to_hw_map: HW context from the acquire
* @priv: Private pointer of hw update
*
*/
struct cam_hw_stream_setttings {
struct cam_packet *packet;
void *ctxt_to_hw_map;
void *priv;
};
/**
* struct cam_hw_config_args - Payload for config command
*
* @ctxt_to_hw_map: HW context from the acquire
* @num_hw_update_entries: Number of hardware update entries
* @hw_update_entries: Hardware update list
* @out_map_entries: Out map info
* @num_out_map_entries: Number of out map entries
* @priv: Private pointer
* @request_id: Request ID
* @reapply: True if reapplying after bubble
* @cdm_reset_before_apply: True is need to reset CDM before re-apply bubble
* request
*
*/
struct cam_hw_config_args {
void *ctxt_to_hw_map;
uint32_t num_hw_update_entries;
struct cam_hw_update_entry *hw_update_entries;
struct cam_hw_fence_map_entry *out_map_entries;
uint32_t num_out_map_entries;
void *priv;
uint64_t request_id;
bool init_packet;
bool reapply;
bool cdm_reset_before_apply;
};
/**
* struct cam_hw_flush_args - Flush arguments
*
* @ctxt_to_hw_map: HW context from the acquire
* @num_req_pending: Num request to flush, valid when flush type is REQ
* @flush_req_pending: Request pending pointers to flush
* @num_req_active: Num request to flush, valid when flush type is REQ
* @flush_req_active: Request active pointers to flush
* @flush_type: The flush type
* @last_flush_req: last flush req_id notified to hw_mgr for the
* given stream
*
*/
struct cam_hw_flush_args {
void *ctxt_to_hw_map;
uint32_t num_req_pending;
void *flush_req_pending[20];
uint32_t num_req_active;
void *flush_req_active[20];
enum flush_type_t flush_type;
uint32_t last_flush_req;
};
/**
* struct cam_hw_dump_pf_args - Payload for dump pf info command
*
* @pf_data: Debug data for page fault
* @iova: Page fault address
* @buf_info: Info about memory buffer where page
* fault occurred
* @mem_found: If fault memory found in current
* request
* @ctx_found If fault pid found in context acquired hardware
* @resource_type Resource type of the port which caused pf
* @bid: Indicate the bus id
* @pid: Indicates unique hw group ports
* @mid: Indicates port id of the camera hw
*
*/
struct cam_hw_dump_pf_args {
struct cam_hw_mgr_dump_pf_data pf_data;
unsigned long iova;
uint32_t buf_info;
bool *mem_found;
bool *ctx_found;
uint32_t *resource_type;
uint32_t bid;
uint32_t pid;
uint32_t mid;
};
/**
* struct cam_hw_reset_args -hw reset arguments
*
* @ctxt_to_hw_map: HW context from the acquire
*
*/
struct cam_hw_reset_args {
void *ctxt_to_hw_map;
};
/**
* struct cam_hw_dump_args - Dump arguments
*
* @request_id: request_id
* @offset: Buffer offset. This is updated by the drivers.
* @buf_handle: Buffer handle
* @error_type: Error type, to be used to extend dump information
* @ctxt_to_hw_map: HW context from the acquire
*/
struct cam_hw_dump_args {
uint64_t request_id;
size_t offset;
uint32_t buf_handle;
uint32_t error_type;
void *ctxt_to_hw_map;
};
/* enum cam_hw_mgr_command - Hardware manager command type */
enum cam_hw_mgr_command {
CAM_HW_MGR_CMD_INTERNAL,
CAM_HW_MGR_CMD_DUMP_PF_INFO,
CAM_HW_MGR_CMD_REG_DUMP_ON_FLUSH,
CAM_HW_MGR_CMD_REG_DUMP_ON_ERROR,
CAM_HW_MGR_CMD_DUMP_ACQ_INFO,
};
/**
* struct cam_hw_cmd_args - Payload for hw manager command
*
* @ctxt_to_hw_map: HW context from the acquire
* @cmd_type HW command type
* @internal_args Arguments for internal command
* @pf_args Arguments for Dump PF info command
*
*/
struct cam_hw_cmd_args {
void *ctxt_to_hw_map;
uint32_t cmd_type;
union {
void *internal_args;
struct cam_hw_dump_pf_args pf_args;
} u;
};
/**
* cam_hw_mgr_intf - HW manager interface
*
* @hw_mgr_priv: HW manager object
* @hw_get_caps: Function pointer for get hw caps
* args = cam_query_cap_cmd
* @hw_acquire: Function poniter for acquire hw resources
* args = cam_hw_acquire_args
* @hw_release: Function pointer for release hw device resource
* args = cam_hw_release_args
* @hw_start: Function pointer for start hw devices
* args = cam_hw_start_args
* @hw_stop: Function pointer for stop hw devices
* args = cam_hw_stop_args
* @hw_prepare_update: Function pointer for prepare hw update for hw
* devices args = cam_hw_prepare_update_args
* @hw_config_stream_settings: Function pointer for configure stream for hw
* devices args = cam_hw_stream_setttings
* @hw_config: Function pointer for configure hw devices
* args = cam_hw_config_args
* @hw_read: Function pointer for read hardware registers
* @hw_write: Function pointer for Write hardware registers
* @hw_cmd: Function pointer for any customized commands for
* the hardware manager
* @hw_open: Function pointer for HW init
* @hw_close: Function pointer for HW deinit
* @hw_flush: Function pointer for HW flush
* @hw_reset: Function pointer for HW reset
* @hw_dump: Function pointer for HW dump
*
*/
struct cam_hw_mgr_intf {
void *hw_mgr_priv;
int (*hw_get_caps)(void *hw_priv, void *hw_caps_args);
int (*hw_acquire)(void *hw_priv, void *hw_acquire_args);
int (*hw_release)(void *hw_priv, void *hw_release_args);
int (*hw_start)(void *hw_priv, void *hw_start_args);
int (*hw_stop)(void *hw_priv, void *hw_stop_args);
int (*hw_prepare_update)(void *hw_priv, void *hw_prepare_update_args);
int (*hw_config_stream_settings)(void *hw_priv,
void *hw_stream_settings);
int (*hw_config)(void *hw_priv, void *hw_config_args);
int (*hw_read)(void *hw_priv, void *read_args);
int (*hw_write)(void *hw_priv, void *write_args);
int (*hw_cmd)(void *hw_priv, void *write_args);
int (*hw_open)(void *hw_priv, void *fw_download_args);
int (*hw_close)(void *hw_priv, void *hw_close_args);
int (*hw_flush)(void *hw_priv, void *hw_flush_args);
int (*hw_reset)(void *hw_priv, void *hw_reset_args);
int (*hw_dump)(void *hw_priv, void *hw_dump_args);
};
#endif /* _CAM_HW_MGR_INTF_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,129 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_NODE_H_
#define _CAM_NODE_H_
#include <linux/kref.h>
#include "cam_context.h"
#include "cam_hw_mgr_intf.h"
#include "cam_req_mgr_interface.h"
#define CAM_NODE_STATE_UNINIT 0
#define CAM_NODE_STATE_INIT 1
/**
* struct cam_node - Singleton Node for camera HW devices
*
* @name: Name for struct cam_node
* @state: Node state:
* 0 = uninitialized, 1 = initialized
* @list_mutex: Mutex for the context pool
* @free_ctx_list: Free context pool list
* @ctx_list: Context list
* @ctx_size: Context list size
* @hw_mgr_intf: Interface for cam_node to HW
* @crm_node_intf: Interface for the CRM to cam_node
*
*/
struct cam_node {
char name[CAM_CTX_DEV_NAME_MAX_LENGTH];
uint32_t state;
/* context pool */
struct mutex list_mutex;
struct list_head free_ctx_list;
struct cam_context *ctx_list;
uint32_t ctx_size;
/* interfaces */
struct cam_hw_mgr_intf hw_mgr_intf;
struct cam_req_mgr_kmd_ops crm_node_intf;
};
/**
* cam_node_handle_ioctl()
*
* @brief: Handle ioctl commands
*
* @node: Node handle
* @cmd: IOCTL command
*
*/
int cam_node_handle_ioctl(struct cam_node *node, struct cam_control *cmd);
/**
* cam_node_deinit()
*
* @brief: Deinitialization function for the Node interface
*
* @node: Node handle
*
*/
int cam_node_deinit(struct cam_node *node);
/**
* cam_node_shutdown()
*
* @brief: Shutdowns/Closes the cam node.
*
* @node: Cam_node pointer
*
*/
int cam_node_shutdown(struct cam_node *node);
/**
* cam_node_init()
*
* @brief: Initialization function for the Node interface.
*
* @node: Cam_node pointer
* @hw_mgr_intf: HW manager interface blob
* @ctx_list: List of cam_contexts to be added
* @ctx_size: Size of the cam_context
* @name: Name for the node
*
*/
int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf,
struct cam_context *ctx_list, uint32_t ctx_size, char *name);
/**
* cam_node_put_ctxt_to_free_list()
*
* @brief: Put context in node free list.
*
* @ref: Context's kref object
*
*/
void cam_node_put_ctxt_to_free_list(struct kref *ref);
/**
* cam_get_dev_handle_info()
*
* @brief: provides the active dev index.
*
* @handle: pointer to struct v4l2_dev
* @ctx: pointer to struct cam_context
* @dev_index: dev index
*
*/
int32_t cam_get_dev_handle_info(uint64_t handle,
struct cam_context **ctx, int32_t dev_index);
/**
* cam_node_handle_shutdown_dev()
*
* @brief: Shutdowns all the active devices.
*
* @node: pointer to struct node
* @cmd: pointer to struct cmd
* @fh: pointer to struct v4l2_subdev_fh
*
*/
int cam_node_handle_shutdown_dev(struct cam_node *node,
struct cam_control *cmd, struct v4l2_subdev_fh *fh);
#endif /* _CAM_NODE_H_ */

View file

@ -0,0 +1,169 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#include "cam_subdev.h"
#include "cam_node.h"
#include "cam_debug_util.h"
/**
* cam_subdev_subscribe_event()
*
* @brief: function to subscribe to v4l2 events
*
* @sd: Pointer to struct v4l2_subdev.
* @fh: Pointer to struct v4l2_fh.
* @sub: Pointer to struct v4l2_event_subscription.
*/
static int cam_subdev_subscribe_event(struct v4l2_subdev *sd,
struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
return v4l2_event_subscribe(fh, sub, CAM_SUBDEVICE_EVENT_MAX, NULL);
}
/**
* cam_subdev_unsubscribe_event()
*
* @brief: function to unsubscribe from v4l2 events
*
* @sd: Pointer to struct v4l2_subdev.
* @fh: Pointer to struct v4l2_fh.
* @sub: Pointer to struct v4l2_event_subscription.
*/
static int cam_subdev_unsubscribe_event(struct v4l2_subdev *sd,
struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
return v4l2_event_unsubscribe(fh, sub);
}
static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
void *arg)
{
long rc;
struct cam_node *node =
(struct cam_node *) v4l2_get_subdevdata(sd);
struct v4l2_subdev_fh *fh = (struct v4l2_subdev_fh *)arg;
struct cam_control cntrl_cmd;
if (!node || node->state == CAM_NODE_STATE_UNINIT) {
rc = -EINVAL;
goto end;
}
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = cam_node_handle_ioctl(node,
(struct cam_control *) arg);
break;
case CAM_SD_SHUTDOWN:
if (!cam_req_mgr_is_shutdown()) {
CAM_WARN(CAM_CORE, "SD shouldn't come from user space");
return 0;
}
cntrl_cmd.op_code = CAM_SD_SHUTDOWN;
cntrl_cmd.handle = (uint64_t)sd;
rc = cam_node_handle_shutdown_dev(node, &cntrl_cmd, fh);
if (rc)
CAM_ERR(CAM_CORE, "shutdown device failed(rc = %d)",
rc);
break;
default:
CAM_ERR(CAM_CORE, "Invalid command %d for %s", cmd,
node->name);
rc = -EINVAL;
}
end:
return rc;
}
#ifdef CONFIG_COMPAT
static long cam_subdev_compat_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, unsigned long arg)
{
struct cam_control cmd_data;
int rc;
if (copy_from_user(&cmd_data, (void __user *)arg,
sizeof(cmd_data))) {
CAM_ERR(CAM_CORE, "Failed to copy from user_ptr=%pK size=%zu",
(void __user *)arg, sizeof(cmd_data));
return -EFAULT;
}
rc = cam_subdev_ioctl(sd, cmd, &cmd_data);
if (!rc) {
if (copy_to_user((void __user *)arg, &cmd_data,
sizeof(cmd_data))) {
CAM_ERR(CAM_CORE,
"Failed to copy to user_ptr=%pK size=%zu",
(void __user *)arg, sizeof(cmd_data));
rc = -EFAULT;
}
}
return rc;
}
#endif
const struct v4l2_subdev_core_ops cam_subdev_core_ops = {
.ioctl = cam_subdev_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl32 = cam_subdev_compat_ioctl,
#endif
.subscribe_event = cam_subdev_subscribe_event,
.unsubscribe_event = cam_subdev_unsubscribe_event,
};
static const struct v4l2_subdev_ops cam_subdev_ops = {
.core = &cam_subdev_core_ops,
};
int cam_subdev_remove(struct cam_subdev *sd)
{
if (!sd)
return -EINVAL;
cam_unregister_subdev(sd);
cam_node_deinit((struct cam_node *)sd->token);
kfree(sd->token);
return 0;
}
int cam_subdev_probe(struct cam_subdev *sd, struct platform_device *pdev,
char *name, uint32_t dev_type)
{
int rc;
struct cam_node *node = NULL;
if (!sd || !pdev || !name)
return -EINVAL;
node = kzalloc(sizeof(*node), GFP_KERNEL);
if (!node)
return -ENOMEM;
/* Setup camera v4l2 subdevice */
sd->pdev = pdev;
sd->name = name;
sd->ops = &cam_subdev_ops;
sd->token = node;
sd->sd_flags =
V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
sd->ent_function = dev_type;
rc = cam_register_subdev(sd);
if (rc) {
CAM_ERR(CAM_CORE, "cam_register_subdev() failed for dev: %s",
sd->name);
goto err;
}
platform_set_drvdata(sd->pdev, sd);
return rc;
err:
kfree(node);
return rc;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,301 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CPAS_HW_H_
#define _CAM_CPAS_HW_H_
#include <dt-bindings/msm/msm-camera.h>
#include "cam_cpas_api.h"
#include "cam_cpas_hw_intf.h"
#include "cam_common_util.h"
#include "cam_soc_bus.h"
#define CAM_CPAS_INFLIGHT_WORKS 5
#define CAM_CPAS_MAX_CLIENTS 40
#define CAM_CPAS_MAX_AXI_PORTS 6
#define CAM_CPAS_MAX_TREE_LEVELS 4
#define CAM_CPAS_MAX_GRAN_PATHS_PER_CLIENT 32
#define CAM_CPAS_PATH_DATA_MAX 38
#define CAM_CPAS_TRANSACTION_MAX 2
#define CAM_CPAS_AXI_MIN_MNOC_AB_BW (2048 * 1024)
#define CAM_CPAS_AXI_MIN_MNOC_IB_BW (2048 * 1024)
#define CAM_CPAS_AXI_MIN_CAMNOC_AB_BW (2048 * 1024)
#define CAM_CPAS_AXI_MIN_CAMNOC_IB_BW (3000000000UL)
#define CAM_CPAS_GET_CLIENT_IDX(handle) (handle)
#define CAM_CPAS_GET_CLIENT_HANDLE(indx) (indx)
#define CAM_CPAS_CLIENT_VALID(indx) \
((indx >= 0) && (indx < CAM_CPAS_MAX_CLIENTS))
#define CAM_CPAS_CLIENT_REGISTERED(cpas_core, indx) \
((CAM_CPAS_CLIENT_VALID(indx)) && \
(cpas_core->cpas_client[indx]->registered))
#define CAM_CPAS_CLIENT_STARTED(cpas_core, indx) \
((CAM_CPAS_CLIENT_REGISTERED(cpas_core, indx)) && \
(cpas_core->cpas_client[indx]->started))
/* Array indices to represent corresponding RPMH BCM info */
#define CAM_RPMH_NUMBER_OF_BCMS 0
#define CAM_RPMH_BCM_FE_OFFSET 1
#define CAM_RPMH_BCM_BE_OFFSET 2
#define CAM_RPMH_BCM_DDR_INDEX 3
#define CAM_RPMH_BCM_MNOC_INDEX 4
#define CAM_RPMH_BCM_INFO_MAX 5
#define CAM_CPAS_MONITOR_MAX_ENTRIES 60
#define CAM_CPAS_INC_MONITOR_HEAD(head, ret) \
div_u64_rem(atomic64_add_return(1, head),\
CAM_CPAS_MONITOR_MAX_ENTRIES, (ret))
/**
* enum cam_cpas_access_type - Enum for Register access type
*/
enum cam_cpas_access_type {
CAM_REG_TYPE_READ,
CAM_REG_TYPE_WRITE,
CAM_REG_TYPE_READ_WRITE,
};
/**
* struct cam_cpas_internal_ops - CPAS Hardware layer internal ops
*
* @get_hw_info: Function pointer for get hw info
* @init_hw_version: Function pointer for hw init based on version
* @handle_irq: Function poniter for irq handling
* @setup_regbase: Function pointer for setup rebase indices
* @power_on: Function pointer for hw core specific power on settings
* @power_off: Function pointer for hw core specific power off settings
* @setup_qos_settings: Function pointer for hw to select a specific qos header
* @print_poweron_settings: Function pointer for hw to print poweron settings
* @qchannel_handshake: Function pointer for hw core specific qchannel
* handshake settings
*
*/
struct cam_cpas_internal_ops {
int (*get_hw_info)(struct cam_hw_info *cpas_hw,
struct cam_cpas_hw_caps *hw_caps);
int (*init_hw_version)(struct cam_hw_info *cpas_hw,
struct cam_cpas_hw_caps *hw_caps);
irqreturn_t (*handle_irq)(int irq_num, void *data);
int (*setup_regbase)(struct cam_hw_soc_info *soc_info,
int32_t regbase_index[], int32_t num_reg_map);
int (*power_on)(struct cam_hw_info *cpas_hw);
int (*power_off)(struct cam_hw_info *cpas_hw);
int (*setup_qos_settings)(struct cam_hw_info *cpas_hw,
uint32_t selection_mask);
int (*print_poweron_settings)(struct cam_hw_info *cpas_hw);
int (*qchannel_handshake)(struct cam_hw_info *cpas_hw, bool power_on);
};
/**
* struct cam_cpas_reg : CPAS register info
*
* @enable: Whether this reg info need to be enabled
* @is_fuse_based : Whether this reg info need to be enabled based on fuse
* @access_type: Register access type
* @masked_value: Whether this register write/read is based on mask, shift
* @mask: Mask for this register value
* @shift: Shift for this register value
* @value: Register value
*
*/
struct cam_cpas_reg {
bool enable;
bool is_fuse_based;
enum cam_cpas_access_type access_type;
bool masked_value;
uint32_t offset;
uint32_t mask;
uint32_t shift;
uint32_t value;
};
/**
* struct cam_cpas_client : CPAS Client structure info
*
* @data: Client register params
* @registered: Whether client has registered with cpas
* @started: Whether client has streamed on
* @tree_node_valid: Indicates whether tree node has at least one valid node
* @ahb_level: Determined/Applied ahb level for the client
* @axi_vote: Determined/Applied axi vote for the client
* @axi_port: Client's parent axi port
* @tree_node: All granular path voting nodes for the client
*
*/
struct cam_cpas_client {
struct cam_cpas_register_params data;
bool registered;
bool started;
bool tree_node_valid;
enum cam_vote_level ahb_level;
struct cam_axi_vote axi_vote;
struct cam_cpas_axi_port *axi_port;
struct cam_cpas_tree_node *tree_node[CAM_CPAS_PATH_DATA_MAX]
[CAM_CPAS_TRANSACTION_MAX];
};
/**
* struct cam_cpas_bus_client : Bus client information
*
* @valid: Whether bus client is valid
* @name: Name of the bus client
* @lock: Mutex lock used while voting on this client
* @curr_vote_level: current voted index
* @common_data: Common data fields for bus client
* @soc_bus_client: Bus client private information
*/
struct cam_cpas_bus_client {
bool valid;
struct mutex lock;
unsigned int curr_vote_level;
struct cam_soc_bus_client_common_data common_data;
void *soc_bus_client;
};
/**
* struct cam_cpas_axi_port : AXI port information
*
* @axi_port_name: Name of this AXI port
* @bus_client: bus client info for this port
* @ib_bw_voting_needed: if this port can update ib bw dynamically
* @axi_port_node: Node representing AXI Port info in device tree
* @ab_bw: AB bw value for this port
* @ib_bw: IB bw value for this port
* @camnoc_bw: CAMNOC bw value for this port
* @additional_bw: Additional bandwidth to cover non-hw cpas clients
* @applied_ab_bw: applied ab bw for this port
* @applied_ib_bw: applied ib bw for this port
*/
struct cam_cpas_axi_port {
const char *axi_port_name;
struct cam_cpas_bus_client bus_client;
bool ib_bw_voting_needed;
struct device_node *axi_port_node;
uint64_t ab_bw;
uint64_t ib_bw;
uint64_t camnoc_bw;
uint64_t additional_bw;
uint64_t applied_ab_bw;
uint64_t applied_ib_bw;
};
/**
* struct cam_cpas_axi_port_debug_info : AXI port information
*
* @axi_port_name: Name of this AXI port
* @ab_bw: AB bw value for this port
* @ib_bw: IB bw value for this port
* @camnoc_bw: CAMNOC bw value for this port
* @applied_ab_bw: applied ab bw for this port
* @applied_ib_bw: applied ib bw for this port
*/
struct cam_cpas_axi_port_debug_info {
const char *axi_port_name;
uint64_t ab_bw;
uint64_t ib_bw;
uint64_t camnoc_bw;
uint64_t applied_ab_bw;
uint64_t applied_ib_bw;
};
/**
* struct cam_cpas_monitor : CPAS monitor array
*
* @timestamp: Timestamp at which this monitor entry is saved
* @axi_info: AXI port information
* @identifier_string: String passed by caller
* @identifier_value: Identifier value passed by caller
* @applied_camnoc_clk: Applied camnoc axi clock rate
* @applied_ahb_level: Applied camcc ahb level
* @fe_ddr: RPMH DDR BCM FE (front-end) status register value.
* This indicates requested clock plan
* @be_ddr: RPMH DDR BCM BE (back-end) status register value.
* This indicates actual current clock plan
* @fe_mnoc: RPMH MNOC BCM FE (front-end) status register value.
* This indicates requested clock plan
* @be_mnoc: RPMH MNOC BCM BE (back-end) status register value.
* This indicates actual current clock plan
* @camnoc_fill_level: Camnoc fill level register info
*/
struct cam_cpas_monitor {
struct timespec64 timestamp;
char identifier_string[128];
int32_t identifier_value;
struct cam_cpas_axi_port_debug_info axi_info[CAM_CPAS_MAX_AXI_PORTS];
uint64_t applied_camnoc_clk;
unsigned int applied_ahb_level;
uint32_t fe_ddr;
uint32_t be_ddr;
uint32_t fe_mnoc;
uint32_t be_mnoc;
uint32_t camnoc_fill_level[5];
};
/**
* struct cam_cpas : CPAS core data structure info
*
* @hw_caps: CPAS hw capabilities
* @cpas_client: Array of pointers to CPAS clients info
* @client_mutex: Mutex for accessing client info
* @tree_lock: Mutex lock for accessing CPAS node tree
* @num_clients: Total number of clients that CPAS supports
* @num_axi_ports: Total number of axi ports found in device tree
* @num_camnoc_axi_ports: Total number of camnoc axi ports found in device tree
* @registered_clients: Number of Clients registered currently
* @streamon_clients: Number of Clients that are in start state currently
* @regbase_index: Register base indices for CPAS register base IDs
* @ahb_bus_client: AHB Bus client info
* @axi_port: AXI port info for a specific axi index
* @camnoc_axi_port: CAMNOC AXI port info for a specific camnoc axi index
* @internal_ops: CPAS HW internal ops
* @work_queue: Work queue handle
* @irq_count: atomic irq count
* @irq_count_wq: wait variable to ensure all irq's are handled
* @dentry: debugfs file entry
* @ahb_bus_scaling_disable: ahb scaling based on src clk corner for bus
* @applied_camnoc_axi_rate: applied camnoc axi clock rate
* @monitor_head: Monitor array head
* @monitor_entries: cpas monitor array
* @full_state_dump: Whether to enable full cpas state dump or not
*/
struct cam_cpas {
struct cam_cpas_hw_caps hw_caps;
struct cam_cpas_client *cpas_client[CAM_CPAS_MAX_CLIENTS];
struct mutex client_mutex[CAM_CPAS_MAX_CLIENTS];
struct mutex tree_lock;
uint32_t num_clients;
uint32_t num_axi_ports;
uint32_t num_camnoc_axi_ports;
uint32_t registered_clients;
uint32_t streamon_clients;
int32_t regbase_index[CAM_CPAS_REG_MAX];
struct cam_cpas_bus_client ahb_bus_client;
struct cam_cpas_axi_port axi_port[CAM_CPAS_MAX_AXI_PORTS];
struct cam_cpas_axi_port camnoc_axi_port[CAM_CPAS_MAX_AXI_PORTS];
struct cam_cpas_internal_ops internal_ops;
struct workqueue_struct *work_queue;
atomic_t irq_count;
wait_queue_head_t irq_count_wq;
struct dentry *dentry;
bool ahb_bus_scaling_disable;
uint64_t applied_camnoc_axi_rate;
atomic64_t monitor_head;
struct cam_cpas_monitor monitor_entries[CAM_CPAS_MONITOR_MAX_ENTRIES];
bool full_state_dump;
};
int cam_camsstop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops);
int cam_cpastop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops);
int cam_cpas_util_reg_update(struct cam_hw_info *cpas_hw,
enum cam_cpas_reg_base reg_base, struct cam_cpas_reg *reg_info);
int cam_cpas_util_reg_read(struct cam_hw_info *cpas_hw,
enum cam_cpas_reg_base reg_base, struct cam_cpas_reg *reg_info);
int cam_cpas_util_client_cleanup(struct cam_hw_info *cpas_hw);
#endif /* _CAM_CPAS_HW_H_ */

View file

@ -0,0 +1,157 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CPAS_HW_INTF_H_
#define _CAM_CPAS_HW_INTF_H_
#include <linux/platform_device.h>
#include "cam_cpas_api.h"
#include "cam_hw.h"
#include "cam_hw_intf.h"
#include "cam_debug_util.h"
/* Number of times to retry while polling */
#define CAM_CPAS_POLL_RETRY_CNT 5
/* Minimum usecs to sleep while polling */
#define CAM_CPAS_POLL_MIN_USECS 200
/* Maximum usecs to sleep while polling */
#define CAM_CPAS_POLL_MAX_USECS 250
/* Number of times to retry while polling */
#define CAM_CPAS_POLL_QH_RETRY_CNT 50
/**
* enum cam_cpas_hw_type - Enum for CPAS HW type
*/
enum cam_cpas_hw_type {
CAM_HW_CPASTOP,
CAM_HW_CAMSSTOP,
};
/**
* enum cam_cpas_hw_cmd_process - Enum for CPAS HW process command type
*/
enum cam_cpas_hw_cmd_process {
CAM_CPAS_HW_CMD_REGISTER_CLIENT,
CAM_CPAS_HW_CMD_UNREGISTER_CLIENT,
CAM_CPAS_HW_CMD_REG_WRITE,
CAM_CPAS_HW_CMD_REG_READ,
CAM_CPAS_HW_CMD_AHB_VOTE,
CAM_CPAS_HW_CMD_AXI_VOTE,
CAM_CPAS_HW_CMD_LOG_VOTE,
CAM_CPAS_HW_CMD_SELECT_QOS,
CAM_CPAS_HW_CMD_LOG_EVENT,
CAM_CPAS_HW_CMD_INVALID,
};
/**
* struct cam_cpas_hw_cmd_reg_read_write : CPAS cmd struct for reg read, write
*
* @client_handle: Client handle
* @reg_base: Register base type
* @offset: Register offset
* @value: Register value
* @mb: Whether to do operation with memory barrier
*
*/
struct cam_cpas_hw_cmd_reg_read_write {
uint32_t client_handle;
enum cam_cpas_reg_base reg_base;
uint32_t offset;
uint32_t value;
bool mb;
};
/**
* struct cam_cpas_hw_cmd_ahb_vote : CPAS cmd struct for AHB vote
*
* @client_handle: Client handle
* @ahb_vote: AHB voting info
*
*/
struct cam_cpas_hw_cmd_ahb_vote {
uint32_t client_handle;
struct cam_ahb_vote *ahb_vote;
};
/**
* struct cam_cpas_hw_cmd_axi_vote : CPAS cmd struct for AXI vote
*
* @client_handle: Client handle
* @axi_vote: axi bandwidth vote
*
*/
struct cam_cpas_hw_cmd_axi_vote {
uint32_t client_handle;
struct cam_axi_vote *axi_vote;
};
/**
* struct cam_cpas_hw_cmd_start : CPAS cmd struct for start
*
* @client_handle: Client handle
*
*/
struct cam_cpas_hw_cmd_start {
uint32_t client_handle;
struct cam_ahb_vote *ahb_vote;
struct cam_axi_vote *axi_vote;
};
/**
* struct cam_cpas_hw_cmd_stop : CPAS cmd struct for stop
*
* @client_handle: Client handle
*
*/
struct cam_cpas_hw_cmd_stop {
uint32_t client_handle;
};
/**
* struct cam_cpas_hw_cmd_notify_event : CPAS cmd struct for notify event
*
* @identifier_string: Identifier string passed by caller
* @identifier_value: Identifier value passed by caller
*
*/
struct cam_cpas_hw_cmd_notify_event {
const char *identifier_string;
int32_t identifier_value;
};
/**
* struct cam_cpas_hw_caps : CPAS HW capabilities
*
* @camera_family: Camera family type
* @camera_version: Camera version
* @cpas_version: CPAS version
* @camera_capability: Camera hw capabilities
* @fuse_info: Fuse information
*
*/
struct cam_cpas_hw_caps {
uint32_t camera_family;
struct cam_hw_version camera_version;
struct cam_hw_version cpas_version;
uint32_t camera_capability;
struct cam_cpas_fuse_info fuse_info;
};
int cam_cpas_hw_probe(struct platform_device *pdev,
struct cam_hw_intf **hw_intf);
int cam_cpas_hw_remove(struct cam_hw_intf *cpas_hw_intf);
/**
* @brief : API to register CPAS hw to platform framework.
* @return struct platform_device pointer on on success, or ERR_PTR() on error.
*/
int cam_cpas_dev_init_module(void);
/**
* @brief : API to remove CPAS interface from platform framework.
*/
void cam_cpas_dev_exit_module(void);
#endif /* _CAM_CPAS_HW_INTF_H_ */

View file

@ -0,0 +1,981 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/of.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-subdev.h>
#include <media/cam_cpas.h>
#include <media/cam_req_mgr.h>
#include <dt-bindings/msm/msm-camera.h>
#include "cam_subdev.h"
#include "cam_cpas_hw_intf.h"
#include "cam_cpas_soc.h"
#include "camera_main.h"
#include "cam_cpas_api.h"
#define CAM_CPAS_DEV_NAME "cam-cpas"
#define CAM_CPAS_INTF_INITIALIZED() (g_cpas_intf && g_cpas_intf->probe_done)
/**
* struct cam_cpas_intf : CPAS interface
*
* @pdev: Platform device
* @subdev: Subdev info
* @hw_intf: CPAS HW interface
* @hw_caps: CPAS HW capabilities
* @intf_lock: CPAS interface mutex
* @open_cnt: CPAS subdev open count
* @probe_done: Whether CPAS prove completed
*
*/
struct cam_cpas_intf {
struct platform_device *pdev;
struct cam_subdev subdev;
struct cam_hw_intf *hw_intf;
struct cam_cpas_hw_caps hw_caps;
struct mutex intf_lock;
uint32_t open_cnt;
bool probe_done;
};
static struct cam_cpas_intf *g_cpas_intf;
const char *cam_cpas_axi_util_path_type_to_string(
uint32_t path_data_type)
{
switch (path_data_type) {
/* IFE Paths */
case CAM_AXI_PATH_DATA_IFE_LINEAR:
return "IFE_LINEAR";
case CAM_AXI_PATH_DATA_IFE_VID:
return "IFE_VID";
case CAM_AXI_PATH_DATA_IFE_DISP:
return "IFE_DISP";
case CAM_AXI_PATH_DATA_IFE_STATS:
return "IFE_STATS";
case CAM_AXI_PATH_DATA_IFE_RDI0:
return "IFE_RDI0";
case CAM_AXI_PATH_DATA_IFE_RDI1:
return "IFE_RDI1";
case CAM_AXI_PATH_DATA_IFE_RDI2:
return "IFE_RDI2";
case CAM_AXI_PATH_DATA_IFE_RDI3:
return "IFE_RDI3";
case CAM_AXI_PATH_DATA_IFE_PDAF:
return "IFE_PDAF";
case CAM_AXI_PATH_DATA_IFE_PIXEL_RAW:
return "IFE_PIXEL_RAW";
/* IPE Paths */
case CAM_AXI_PATH_DATA_IPE_RD_IN:
return "IPE_RD_IN";
case CAM_AXI_PATH_DATA_IPE_RD_REF:
return "IPE_RD_REF";
case CAM_AXI_PATH_DATA_IPE_WR_VID:
return "IPE_WR_VID";
case CAM_AXI_PATH_DATA_IPE_WR_DISP:
return "IPE_WR_DISP";
case CAM_AXI_PATH_DATA_IPE_WR_REF:
return "IPE_WR_REF";
/* OPE Paths */
case CAM_AXI_PATH_DATA_OPE_RD_IN:
return "OPE_RD_IN";
case CAM_AXI_PATH_DATA_OPE_RD_REF:
return "OPE_RD_REF";
case CAM_AXI_PATH_DATA_OPE_WR_VID:
return "OPE_WR_VID";
case CAM_AXI_PATH_DATA_OPE_WR_DISP:
return "OPE_WR_DISP";
case CAM_AXI_PATH_DATA_OPE_WR_REF:
return "OPE_WR_REF";
/* SFE Paths */
case CAM_AXI_PATH_DATA_SFE_NRDI:
return "SFE_NRDI";
case CAM_AXI_PATH_DATA_SFE_RDI0:
return "IFE_RDI0";
case CAM_AXI_PATH_DATA_SFE_RDI1:
return "IFE_RDI1";
case CAM_AXI_PATH_DATA_SFE_RDI2:
return "IFE_RDI2";
case CAM_AXI_PATH_DATA_SFE_RDI3:
return "IFE_RDI3";
case CAM_AXI_PATH_DATA_SFE_RDI4:
return "IFE_RDI4";
case CAM_AXI_PATH_DATA_SFE_STATS:
return "SFE_STATS";
/* Common Paths */
case CAM_AXI_PATH_DATA_ALL:
return "DATA_ALL";
default:
return "IFE_PATH_INVALID";
}
}
EXPORT_SYMBOL(cam_cpas_axi_util_path_type_to_string);
const char *cam_cpas_axi_util_trans_type_to_string(
uint32_t transac_type)
{
switch (transac_type) {
case CAM_AXI_TRANSACTION_READ:
return "TRANSAC_READ";
case CAM_AXI_TRANSACTION_WRITE:
return "TRANSAC_WRITE";
default:
return "TRANSAC_INVALID";
}
}
EXPORT_SYMBOL(cam_cpas_axi_util_trans_type_to_string);
bool cam_cpas_is_feature_supported(uint32_t flag, uint32_t hw_map,
uint32_t *fuse_val)
{
struct cam_hw_info *cpas_hw = NULL;
struct cam_cpas_private_soc *soc_private = NULL;
bool supported = true;
int32_t i;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return false;
}
cpas_hw = (struct cam_hw_info *) g_cpas_intf->hw_intf->hw_priv;
soc_private =
(struct cam_cpas_private_soc *)cpas_hw->soc_info.soc_private;
if (flag >= CAM_CPAS_FUSE_FEATURE_MAX) {
CAM_ERR(CAM_CPAS, "Unknown feature flag %x", flag);
return false;
}
for (i = 0; i < soc_private->num_feature_info; i++)
if (soc_private->feature_info[i].feature == flag)
break;
if (i == soc_private->num_feature_info)
goto end;
if (soc_private->feature_info[i].type == CAM_CPAS_FEATURE_TYPE_DISABLE
|| (soc_private->feature_info[i].type ==
CAM_CPAS_FEATURE_TYPE_ENABLE)) {
if ((soc_private->feature_info[i].hw_map & hw_map) == hw_map)
supported = soc_private->feature_info[i].enable;
} else {
if (!fuse_val) {
CAM_ERR(CAM_CPAS,
"Invalid arg fuse_val");
} else {
*fuse_val = soc_private->feature_info[i].value;
}
}
end:
return supported;
}
EXPORT_SYMBOL(cam_cpas_is_feature_supported);
int cam_cpas_get_cpas_hw_version(uint32_t *hw_version)
{
struct cam_hw_info *cpas_hw = NULL;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
if (!hw_version) {
CAM_ERR(CAM_CPAS, "invalid input %pK", hw_version);
return -EINVAL;
}
cpas_hw = (struct cam_hw_info *) g_cpas_intf->hw_intf->hw_priv;
*hw_version = cpas_hw->soc_info.hw_version;
if (*hw_version == CAM_CPAS_TITAN_NONE) {
CAM_DBG(CAM_CPAS, "Didn't find a valid HW Version %d",
*hw_version);
}
return 0;
}
int cam_cpas_get_camnoc_fifo_fill_level_info(
uint32_t cpas_version,
uint32_t client_handle)
{
int rc = 0;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
rc = cam_cpas_hw_get_camnoc_fill_level_info(cpas_version,
client_handle);
if (rc)
CAM_ERR(CAM_CPAS, "Failed to dump fifo reg rc %d", rc);
return rc;
}
int cam_cpas_get_hw_info(uint32_t *camera_family,
struct cam_hw_version *camera_version,
struct cam_hw_version *cpas_version,
uint32_t *cam_caps,
struct cam_cpas_fuse_info *cam_fuse_info)
{
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
if (!camera_family || !camera_version || !cpas_version || !cam_caps) {
CAM_ERR(CAM_CPAS, "invalid input %pK %pK %pK %pK",
camera_family, camera_version, cpas_version, cam_caps);
return -EINVAL;
}
*camera_family = g_cpas_intf->hw_caps.camera_family;
*camera_version = g_cpas_intf->hw_caps.camera_version;
*cpas_version = g_cpas_intf->hw_caps.cpas_version;
*cam_caps = g_cpas_intf->hw_caps.camera_capability;
if (cam_fuse_info)
*cam_fuse_info = g_cpas_intf->hw_caps.fuse_info;
CAM_DBG(CAM_CPAS, "Family %d, version %d.%d cam_caps %d",
*camera_family, camera_version->major,
camera_version->minor, *cam_caps);
return 0;
}
EXPORT_SYMBOL(cam_cpas_get_hw_info);
int cam_cpas_reg_write(uint32_t client_handle,
enum cam_cpas_reg_base reg_base, uint32_t offset, bool mb,
uint32_t value)
{
int rc;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
struct cam_cpas_hw_cmd_reg_read_write cmd_reg_write;
cmd_reg_write.client_handle = client_handle;
cmd_reg_write.reg_base = reg_base;
cmd_reg_write.offset = offset;
cmd_reg_write.value = value;
cmd_reg_write.mb = mb;
rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
g_cpas_intf->hw_intf->hw_priv,
CAM_CPAS_HW_CMD_REG_WRITE, &cmd_reg_write,
sizeof(struct cam_cpas_hw_cmd_reg_read_write));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
} else {
CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
rc = -EINVAL;
}
return rc;
}
EXPORT_SYMBOL(cam_cpas_reg_write);
int cam_cpas_reg_read(uint32_t client_handle,
enum cam_cpas_reg_base reg_base, uint32_t offset, bool mb,
uint32_t *value)
{
int rc;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
if (!value) {
CAM_ERR(CAM_CPAS, "Invalid arg value");
return -EINVAL;
}
if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
struct cam_cpas_hw_cmd_reg_read_write cmd_reg_read;
cmd_reg_read.client_handle = client_handle;
cmd_reg_read.reg_base = reg_base;
cmd_reg_read.offset = offset;
cmd_reg_read.mb = mb;
cmd_reg_read.value = 0;
rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
g_cpas_intf->hw_intf->hw_priv,
CAM_CPAS_HW_CMD_REG_READ, &cmd_reg_read,
sizeof(struct cam_cpas_hw_cmd_reg_read_write));
if (rc) {
CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
return rc;
}
*value = cmd_reg_read.value;
} else {
CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
rc = -EINVAL;
}
return rc;
}
EXPORT_SYMBOL(cam_cpas_reg_read);
int cam_cpas_update_axi_vote(uint32_t client_handle,
struct cam_axi_vote *axi_vote)
{
int rc;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
if (!axi_vote) {
CAM_ERR(CAM_CPAS, "NULL axi vote");
return -EINVAL;
}
if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
struct cam_cpas_hw_cmd_axi_vote cmd_axi_vote;
cmd_axi_vote.client_handle = client_handle;
cmd_axi_vote.axi_vote = axi_vote;
rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
g_cpas_intf->hw_intf->hw_priv,
CAM_CPAS_HW_CMD_AXI_VOTE, &cmd_axi_vote,
sizeof(struct cam_cpas_hw_cmd_axi_vote));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
} else {
CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
rc = -EINVAL;
}
return rc;
}
EXPORT_SYMBOL(cam_cpas_update_axi_vote);
int cam_cpas_update_ahb_vote(uint32_t client_handle,
struct cam_ahb_vote *ahb_vote)
{
int rc;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
struct cam_cpas_hw_cmd_ahb_vote cmd_ahb_vote;
cmd_ahb_vote.client_handle = client_handle;
cmd_ahb_vote.ahb_vote = ahb_vote;
rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
g_cpas_intf->hw_intf->hw_priv,
CAM_CPAS_HW_CMD_AHB_VOTE, &cmd_ahb_vote,
sizeof(struct cam_cpas_hw_cmd_ahb_vote));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
} else {
CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
rc = -EINVAL;
}
return rc;
}
EXPORT_SYMBOL(cam_cpas_update_ahb_vote);
int cam_cpas_stop(uint32_t client_handle)
{
int rc;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
if (g_cpas_intf->hw_intf->hw_ops.stop) {
struct cam_cpas_hw_cmd_stop cmd_hw_stop;
cmd_hw_stop.client_handle = client_handle;
rc = g_cpas_intf->hw_intf->hw_ops.stop(
g_cpas_intf->hw_intf->hw_priv, &cmd_hw_stop,
sizeof(struct cam_cpas_hw_cmd_stop));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in stop, rc=%d", rc);
} else {
CAM_ERR(CAM_CPAS, "Invalid stop ops");
rc = -EINVAL;
}
return rc;
}
EXPORT_SYMBOL(cam_cpas_stop);
int cam_cpas_start(uint32_t client_handle,
struct cam_ahb_vote *ahb_vote, struct cam_axi_vote *axi_vote)
{
int rc;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
if (!axi_vote) {
CAM_ERR(CAM_CPAS, "NULL axi vote");
return -EINVAL;
}
if (g_cpas_intf->hw_intf->hw_ops.start) {
struct cam_cpas_hw_cmd_start cmd_hw_start;
cmd_hw_start.client_handle = client_handle;
cmd_hw_start.ahb_vote = ahb_vote;
cmd_hw_start.axi_vote = axi_vote;
rc = g_cpas_intf->hw_intf->hw_ops.start(
g_cpas_intf->hw_intf->hw_priv, &cmd_hw_start,
sizeof(struct cam_cpas_hw_cmd_start));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in start, rc=%d", rc);
} else {
CAM_ERR(CAM_CPAS, "Invalid start ops");
rc = -EINVAL;
}
return rc;
}
EXPORT_SYMBOL(cam_cpas_start);
void cam_cpas_log_votes(void)
{
uint32_t dummy_args;
int rc;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return;
}
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_LOG_VOTE, &dummy_args,
sizeof(dummy_args));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
} else {
CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
}
}
EXPORT_SYMBOL(cam_cpas_log_votes);
int cam_cpas_select_qos_settings(uint32_t selection_mask)
{
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_SELECT_QOS, &selection_mask,
sizeof(selection_mask));
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_select_qos_settings);
int cam_cpas_notify_event(const char *identifier_string,
int32_t identifier_value)
{
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) {
struct cam_cpas_hw_cmd_notify_event event = { 0 };
event.identifier_string = identifier_string;
event.identifier_value = identifier_value;
rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
g_cpas_intf->hw_intf->hw_priv,
CAM_CPAS_HW_CMD_LOG_EVENT, &event,
sizeof(event));
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_notify_event);
int cam_cpas_unregister_client(uint32_t client_handle)
{
int rc;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
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_UNREGISTER_CLIENT,
&client_handle, sizeof(uint32_t));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
} else {
CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
rc = -EINVAL;
}
return rc;
}
EXPORT_SYMBOL(cam_cpas_unregister_client);
int cam_cpas_register_client(
struct cam_cpas_register_params *register_params)
{
int rc;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
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_REGISTER_CLIENT, register_params,
sizeof(struct cam_cpas_register_params));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
} else {
CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
rc = -EINVAL;
}
return rc;
}
EXPORT_SYMBOL(cam_cpas_register_client);
int cam_cpas_subdev_cmd(struct cam_cpas_intf *cpas_intf,
struct cam_control *cmd)
{
int rc = 0;
if (!cmd) {
CAM_ERR(CAM_CPAS, "Invalid input cmd");
return -EINVAL;
}
switch (cmd->op_code) {
case CAM_QUERY_CAP: {
struct cam_cpas_query_cap query;
rc = copy_from_user(&query, u64_to_user_ptr(cmd->handle),
sizeof(query));
if (rc) {
CAM_ERR(CAM_CPAS, "Failed in copy from user, rc=%d",
rc);
break;
}
rc = cam_cpas_get_hw_info(&query.camera_family,
&query.camera_version, &query.cpas_version,
&query.reserved, NULL);
if (rc)
break;
rc = copy_to_user(u64_to_user_ptr(cmd->handle), &query,
sizeof(query));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in copy to user, rc=%d", rc);
break;
}
case CAM_QUERY_CAP_V2: {
struct cam_cpas_query_cap_v2 query;
rc = copy_from_user(&query, u64_to_user_ptr(cmd->handle),
sizeof(query));
if (rc) {
CAM_ERR(CAM_CPAS, "Failed in copy from user, rc=%d",
rc);
break;
}
rc = cam_cpas_get_hw_info(&query.camera_family,
&query.camera_version, &query.cpas_version,
&query.reserved,
&query.fuse_info);
if (rc)
break;
rc = copy_to_user(u64_to_user_ptr(cmd->handle), &query,
sizeof(query));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in copy to user, rc=%d", rc);
break;
}
case CAM_SD_SHUTDOWN:
break;
default:
CAM_ERR(CAM_CPAS, "Unknown op code %d for CPAS", cmd->op_code);
rc = -EINVAL;
break;
}
return rc;
}
static int cam_cpas_subdev_open(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_cpas_intf *cpas_intf = v4l2_get_subdevdata(sd);
if (!cpas_intf || !cpas_intf->probe_done) {
CAM_ERR(CAM_CPAS, "CPAS not initialized");
return -ENODEV;
}
mutex_lock(&cpas_intf->intf_lock);
cpas_intf->open_cnt++;
CAM_DBG(CAM_CPAS, "CPAS Subdev open count %d", cpas_intf->open_cnt);
mutex_unlock(&cpas_intf->intf_lock);
return 0;
}
static int __cam_cpas_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_cpas_intf *cpas_intf = v4l2_get_subdevdata(sd);
if (!cpas_intf || !cpas_intf->probe_done) {
CAM_ERR(CAM_CPAS, "CPAS not initialized");
return -ENODEV;
}
mutex_lock(&cpas_intf->intf_lock);
if (cpas_intf->open_cnt <= 0) {
CAM_WARN(CAM_CPAS, "device already closed, open_cnt: %d", cpas_intf->open_cnt);
mutex_unlock(&cpas_intf->intf_lock);
return 0;
}
cpas_intf->open_cnt--;
CAM_DBG(CAM_CPAS, "CPAS Subdev close count %d", cpas_intf->open_cnt);
mutex_unlock(&cpas_intf->intf_lock);
return 0;
}
static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_CPAS);
if (crm_active) {
CAM_DBG(CAM_CPAS, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return __cam_cpas_subdev_close(sd, fh);
}
static long cam_cpas_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
int32_t rc;
struct cam_cpas_intf *cpas_intf = v4l2_get_subdevdata(sd);
if (!cpas_intf || !cpas_intf->probe_done) {
CAM_ERR(CAM_CPAS, "CPAS not initialized");
return -ENODEV;
}
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = cam_cpas_subdev_cmd(cpas_intf, (struct cam_control *) arg);
break;
case CAM_SD_SHUTDOWN:
rc = __cam_cpas_subdev_close(sd, NULL);
break;
default:
CAM_ERR(CAM_CPAS, "Invalid command %d for CPAS!", cmd);
rc = -EINVAL;
break;
}
return rc;
}
#ifdef CONFIG_COMPAT
static long cam_cpas_subdev_compat_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, unsigned long arg)
{
struct cam_control cmd_data;
int32_t rc;
struct cam_cpas_intf *cpas_intf = v4l2_get_subdevdata(sd);
if (!cpas_intf || !cpas_intf->probe_done) {
CAM_ERR(CAM_CPAS, "CPAS not initialized");
return -ENODEV;
}
if (copy_from_user(&cmd_data, (void __user *)arg,
sizeof(cmd_data))) {
CAM_ERR(CAM_CPAS, "Failed to copy from user_ptr=%pK size=%zu",
(void __user *)arg, sizeof(cmd_data));
return -EFAULT;
}
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = cam_cpas_subdev_cmd(cpas_intf, &cmd_data);
break;
default:
CAM_ERR(CAM_CPAS, "Invalid command %d for CPAS!", cmd);
rc = -EINVAL;
break;
}
if (!rc) {
if (copy_to_user((void __user *)arg, &cmd_data,
sizeof(cmd_data))) {
CAM_ERR(CAM_CPAS,
"Failed to copy to user_ptr=%pK size=%zu",
(void __user *)arg, sizeof(cmd_data));
rc = -EFAULT;
}
}
return rc;
}
#endif
static struct v4l2_subdev_core_ops cpas_subdev_core_ops = {
.ioctl = cam_cpas_subdev_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl32 = cam_cpas_subdev_compat_ioctl,
#endif
};
static const struct v4l2_subdev_ops cpas_subdev_ops = {
.core = &cpas_subdev_core_ops,
};
static const struct v4l2_subdev_internal_ops cpas_subdev_intern_ops = {
.open = cam_cpas_subdev_open,
.close = cam_cpas_subdev_close,
};
static int cam_cpas_subdev_register(struct platform_device *pdev)
{
int rc;
struct cam_subdev *subdev;
if (!g_cpas_intf)
return -EINVAL;
subdev = &g_cpas_intf->subdev;
subdev->name = CAM_CPAS_DEV_NAME;
subdev->pdev = pdev;
subdev->ops = &cpas_subdev_ops;
subdev->internal_ops = &cpas_subdev_intern_ops;
subdev->token = g_cpas_intf;
subdev->sd_flags =
V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
subdev->ent_function = CAM_CPAS_DEVICE_TYPE;
subdev->close_seq_prior = CAM_SD_CLOSE_LOW_PRIORITY;
rc = cam_register_subdev(subdev);
if (rc) {
CAM_ERR(CAM_CPAS, "failed register subdev: %s!",
CAM_CPAS_DEV_NAME);
return rc;
}
platform_set_drvdata(g_cpas_intf->pdev, g_cpas_intf);
return rc;
}
static int cam_cpas_dev_component_bind(struct device *dev,
struct device *master_dev, void *data)
{
struct cam_cpas_hw_caps *hw_caps;
struct cam_hw_intf *hw_intf;
int rc;
struct platform_device *pdev = to_platform_device(dev);
if (g_cpas_intf) {
CAM_ERR(CAM_CPAS, "cpas component already binded");
return -EALREADY;
}
g_cpas_intf = kzalloc(sizeof(*g_cpas_intf), GFP_KERNEL);
if (!g_cpas_intf)
return -ENOMEM;
mutex_init(&g_cpas_intf->intf_lock);
g_cpas_intf->pdev = pdev;
rc = cam_cpas_hw_probe(pdev, &g_cpas_intf->hw_intf);
if (rc || (g_cpas_intf->hw_intf == NULL)) {
CAM_ERR(CAM_CPAS, "Failed in hw probe, rc=%d", rc);
goto error_destroy_mem;
}
hw_intf = g_cpas_intf->hw_intf;
hw_caps = &g_cpas_intf->hw_caps;
if (hw_intf->hw_ops.get_hw_caps) {
rc = hw_intf->hw_ops.get_hw_caps(hw_intf->hw_priv,
hw_caps, sizeof(struct cam_cpas_hw_caps));
if (rc) {
CAM_ERR(CAM_CPAS, "Failed in get_hw_caps, rc=%d", rc);
goto error_hw_remove;
}
} else {
CAM_ERR(CAM_CPAS, "Invalid get_hw_caps ops");
goto error_hw_remove;
}
rc = cam_cpas_subdev_register(pdev);
if (rc)
goto error_hw_remove;
g_cpas_intf->probe_done = true;
CAM_DBG(CAM_CPAS,
"Component bound successfully %d, %d.%d.%d, %d.%d.%d, 0x%x",
hw_caps->camera_family, hw_caps->camera_version.major,
hw_caps->camera_version.minor, hw_caps->camera_version.incr,
hw_caps->cpas_version.major, hw_caps->cpas_version.minor,
hw_caps->cpas_version.incr, hw_caps->camera_capability);
return rc;
error_hw_remove:
cam_cpas_hw_remove(g_cpas_intf->hw_intf);
error_destroy_mem:
mutex_destroy(&g_cpas_intf->intf_lock);
kfree(g_cpas_intf);
g_cpas_intf = NULL;
CAM_ERR(CAM_CPAS, "CPAS component bind failed");
return rc;
}
static void cam_cpas_dev_component_unbind(struct device *dev,
struct device *master_dev, void *data)
{
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return;
}
mutex_lock(&g_cpas_intf->intf_lock);
g_cpas_intf->probe_done = false;
cam_unregister_subdev(&g_cpas_intf->subdev);
cam_cpas_hw_remove(g_cpas_intf->hw_intf);
mutex_unlock(&g_cpas_intf->intf_lock);
mutex_destroy(&g_cpas_intf->intf_lock);
kfree(g_cpas_intf);
g_cpas_intf = NULL;
}
const static struct component_ops cam_cpas_dev_component_ops = {
.bind = cam_cpas_dev_component_bind,
.unbind = cam_cpas_dev_component_unbind,
};
static int cam_cpas_dev_probe(struct platform_device *pdev)
{
int rc = 0;
CAM_DBG(CAM_CPAS, "Adding CPAS INTF component");
rc = component_add(&pdev->dev, &cam_cpas_dev_component_ops);
if (rc)
CAM_ERR(CAM_CPAS, "failed to add component rc: %d", rc);
return rc;
}
static int cam_cpas_dev_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &cam_cpas_dev_component_ops);
return 0;
}
static const struct of_device_id cam_cpas_dt_match[] = {
{.compatible = "qcom,cam-cpas"},
{}
};
struct platform_driver cam_cpas_driver = {
.probe = cam_cpas_dev_probe,
.remove = cam_cpas_dev_remove,
.driver = {
.name = CAM_CPAS_DEV_NAME,
.owner = THIS_MODULE,
.of_match_table = cam_cpas_dt_match,
.suppress_bind_attrs = true,
},
};
int cam_cpas_dev_init_module(void)
{
return platform_driver_register(&cam_cpas_driver);
}
void cam_cpas_dev_exit_module(void)
{
platform_driver_unregister(&cam_cpas_driver);
}
MODULE_DESCRIPTION("MSM CPAS driver");
MODULE_LICENSE("GPL v2");

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,152 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CPAS_SOC_H_
#define _CAM_CPAS_SOC_H_
#include "cam_soc_util.h"
#include "cam_cpas_hw.h"
#define CAM_REGULATOR_LEVEL_MAX 16
#define CAM_CPAS_MAX_TREE_NODES 50
#define CAM_CPAS_MAX_FUSE_FEATURE 10
/**
* struct cam_cpas_vdd_ahb_mapping : Voltage to ahb level mapping
*
* @vdd_corner : Voltage corner value
* @ahb_level : AHB vote level corresponds to this vdd_corner
*
*/
struct cam_cpas_vdd_ahb_mapping {
unsigned int vdd_corner;
enum cam_vote_level ahb_level;
};
/**
* struct cpas_tree_node: Generic cpas tree node for BW voting
*
* @cell_idx: Index to identify node from device tree and its parent
* @level_idx: Index to identify at what level the node is present
* @axi_port_idx: Index to identify which axi port to vote the consolidated bw
* @camnoc_axi_port_idx: Index to find which axi port to vote consolidated bw
* @path_data_type: Traffic type info from device tree (ife-vid, ife-disp etc)
* @path_trans_type: Transaction type info from device tree (rd, wr)
* @merge_type: Traffic merge type (calculation info) from device tree
* @bus_width_factor: Factor for accounting bus width in CAMNOC bw calculation
* @camnoc_bw: CAMNOC bw value at current node
* @mnoc_ab_bw: MNOC AB bw value at current node
* @mnoc_ib_bw: MNOC IB bw value at current node
* @ddr_ab_bw: DDR AB bw value at current node
* @ddr_ib_bw: DDR IB bw value at current node
* @camnoc_max_needed: If node is needed for CAMNOC BW calculation then true
* @constituent_paths: Constituent paths presence info from device tree
* Ex: For CAM_CPAS_PATH_DATA_IFE_UBWC_STATS, index corresponding to
* CAM_CPAS_PATH_DATA_IFE_VID, CAM_CPAS_PATH_DATA_IFE_DISP and
* CAM_CPAS_PATH_DATA_IFE_STATS
* @tree_dev_node: Device node from devicetree for current tree node
* @parent_node: Pointer to node one or more level above the current level
* (starting from end node of cpas client)
*
*/
struct cam_cpas_tree_node {
uint32_t cell_idx;
uint32_t level_idx;
int axi_port_idx;
int camnoc_axi_port_idx;
const char *node_name;
uint32_t path_data_type;
uint32_t path_trans_type;
uint32_t merge_type;
uint32_t bus_width_factor;
uint64_t camnoc_bw;
uint64_t mnoc_ab_bw;
uint64_t mnoc_ib_bw;
uint64_t ddr_ab_bw;
uint64_t ddr_ib_bw;
bool camnoc_max_needed;
bool constituent_paths[CAM_CPAS_PATH_DATA_MAX];
struct device_node *tree_dev_node;
struct cam_cpas_tree_node *parent_node;
};
/**
* struct cam_cpas_feature_info : CPAS fuse feature info
* @feature: Identifier for feature
* @type: Type of feature
* @value: Fuse value
* @enable: Feature enable or disable
* @hw_map: Each bit position indicates if the hw_id for the feature
*/
struct cam_cpas_feature_info {
uint32_t feature;
uint32_t type;
uint32_t value;
bool enable;
uint32_t hw_map;
};
/**
* struct cam_cpas_private_soc : CPAS private DT info
*
* @arch_compat: ARCH compatible string
* @client_id_based: Whether clients are id based
* @bus_icc_based: Interconnect based bus interaction
* @num_clients: Number of clients supported
* @client_name: Client names
* @tree_node: Array of pointers to all tree nodes required to calculate
* axi bw, arranged with help of cell index in device tree
* @camera_bus_node: Device tree node from cpas node
* @level_node: Device tree node for each level in camera_bus_node
* @num_vdd_ahb_mapping : Number of vdd to ahb level mapping supported
* @vdd_ahb : AHB level mapping info for the supported vdd levels
* @control_camnoc_axi_clk : Whether CPAS driver need to set camnoc axi clk freq
* @camnoc_bus_width : CAMNOC Bus width
* @camnoc_axi_clk_bw_margin : BW Margin in percentage to add while calculating
* camnoc axi clock
* @camnoc_axi_min_ib_bw: Min camnoc BW which varies based on target
* @fuse_info: fuse information
* @rpmh_info: RPMH BCM info
* @num_feature_info: number of feature_info entries
* @feature_info: Structure for storing feature information
*/
struct cam_cpas_private_soc {
const char *arch_compat;
bool client_id_based;
bool bus_icc_based;
uint32_t num_clients;
const char *client_name[CAM_CPAS_MAX_CLIENTS];
struct cam_cpas_tree_node *tree_node[CAM_CPAS_MAX_TREE_NODES];
struct device_node *camera_bus_node;
struct device_node *level_node[CAM_CPAS_MAX_TREE_LEVELS];
uint32_t num_vdd_ahb_mapping;
struct cam_cpas_vdd_ahb_mapping vdd_ahb[CAM_REGULATOR_LEVEL_MAX];
bool control_camnoc_axi_clk;
uint32_t camnoc_bus_width;
uint32_t camnoc_axi_clk_bw_margin;
uint64_t camnoc_axi_min_ib_bw;
struct cam_cpas_fuse_info fuse_info;
uint32_t rpmh_info[CAM_RPMH_BCM_INFO_MAX];
uint32_t num_feature_info;
struct cam_cpas_feature_info feature_info[CAM_CPAS_MAX_FUSE_FEATURE];
};
void cam_cpas_util_debug_parse_data(struct cam_cpas_private_soc *soc_private);
void cam_cpas_dump_axi_vote_info(
const struct cam_cpas_client *cpas_client,
const char *identifier,
struct cam_axi_vote *axi_vote);
int cam_cpas_node_tree_cleanup(struct cam_cpas *cpas_core,
struct cam_cpas_private_soc *soc_private);
int cam_cpas_soc_init_resources(struct cam_hw_soc_info *soc_info,
irq_handler_t vfe_irq_handler, struct cam_hw_info *cpas_hw);
int cam_cpas_soc_deinit_resources(struct cam_hw_soc_info *soc_info);
int cam_cpas_soc_enable_resources(struct cam_hw_soc_info *soc_info,
enum cam_vote_level default_level);
int cam_cpas_soc_disable_resources(struct cam_hw_soc_info *soc_info,
bool disable_clocks, bool disable_irq);
int cam_cpas_soc_disable_irq(struct cam_hw_soc_info *soc_info);
#endif /* _CAM_CPAS_SOC_H_ */

View file

@ -0,0 +1,85 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved.
*/
#include "cam_cpas_hw_intf.h"
#include "cam_cpas_hw.h"
#include "cam_cpas_soc.h"
int cam_camsstop_get_hw_info(struct cam_hw_info *cpas_hw,
struct cam_cpas_hw_caps *hw_caps)
{
struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info;
int32_t reg_indx = cpas_core->regbase_index[CAM_CPAS_REG_CAMSS];
uint32_t reg_value;
if (reg_indx == -1)
return -EINVAL;
hw_caps->camera_family = CAM_FAMILY_CAMERA_SS;
reg_value = cam_io_r_mb(soc_info->reg_map[reg_indx].mem_base + 0x0);
hw_caps->camera_version.major =
CAM_BITS_MASK_SHIFT(reg_value, 0xf0000000, 0x1c);
hw_caps->camera_version.minor =
CAM_BITS_MASK_SHIFT(reg_value, 0xfff0000, 0x10);
hw_caps->camera_version.incr =
CAM_BITS_MASK_SHIFT(reg_value, 0xffff, 0x0);
CAM_DBG(CAM_FD, "Family %d, version %d.%d.%d",
hw_caps->camera_family, hw_caps->camera_version.major,
hw_caps->camera_version.minor, hw_caps->camera_version.incr);
return 0;
}
int cam_camsstop_setup_regbase_indices(struct cam_hw_soc_info *soc_info,
int32_t regbase_index[], int32_t num_reg_map)
{
uint32_t index;
int rc;
if (num_reg_map > CAM_CPAS_REG_MAX) {
CAM_ERR(CAM_CPAS, "invalid num_reg_map=%d", num_reg_map);
return -EINVAL;
}
if (soc_info->num_mem_block > CAM_SOC_MAX_BLOCK) {
CAM_ERR(CAM_CPAS, "invalid num_mem_block=%d",
soc_info->num_mem_block);
return -EINVAL;
}
rc = cam_common_util_get_string_index(soc_info->mem_block_name,
soc_info->num_mem_block, "cam_camss", &index);
if ((rc == 0) && (index < num_reg_map)) {
regbase_index[CAM_CPAS_REG_CAMSS] = index;
} else {
CAM_ERR(CAM_CPAS, "regbase not found for CAM_CPAS_REG_CAMSS");
return -EINVAL;
}
return 0;
}
int cam_camsstop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops)
{
if (!internal_ops) {
CAM_ERR(CAM_CPAS, "invalid NULL param");
return -EINVAL;
}
internal_ops->get_hw_info = cam_camsstop_get_hw_info;
internal_ops->init_hw_version = NULL;
internal_ops->handle_irq = NULL;
internal_ops->setup_regbase = cam_camsstop_setup_regbase_indices;
internal_ops->power_on = NULL;
internal_ops->power_off = NULL;
internal_ops->setup_qos_settings = NULL;
internal_ops->print_poweron_settings = NULL;
internal_ops->qchannel_handshake = NULL;
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,401 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CPASTOP_HW_H_
#define _CAM_CPASTOP_HW_H_
#include "cam_cpas_api.h"
#include "cam_cpas_hw.h"
/**
* enum cam_camnoc_hw_irq_type - Enum for camnoc error types
*
* @CAM_CAMNOC_HW_IRQ_SLAVE_ERROR : Each slave port in CAMNOC
* (3 QSB ports and 1 QHB port)
* has an error logger. The
* error observed at any slave
* port is logged into the
* error logger register and
* an IRQ is triggered
* @CAM_CAMNOC_HW_IRQ_IFE_UBWC_ENCODE_ERROR : Triggered if any error
* detected in the IFE UBWC
* encoder instance
* @CAM_CAMNOC_HW_IRQ_IFE_UBWC_STATS_ENCODE_ERROR : Triggered if any error
* detected in the IFE UBWC-
* Stats encoder instance
* @CAM_CAMNOC_HW_IRQ_IFE_UBWC_STATS_1_ENCODE_ERROR: Triggered if any error
* detected in the IFE UBWC-
* Stats 1 encoder instance
* @CAM_CAMNOC_HW_IRQ_IFE02_UBWC_ENCODE_ERROR : Triggered if any error
* detected in the IFE0 UBWC
* encoder instance
* @CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR : Triggered if any error
* detected in the IFE1 or
* IFE3 UBWC encoder instance
* @CAM_CAMNOC_HW_IRQ_IFE0_UBWC_ENCODE_ERROR : Triggered if any UBWC error
* is detected in IFE0 write
* path
* @CAM_CAMNOC_HW_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR : Triggered if any UBWC error
* is detected in IFE1 write
* path slave times out after
* 4000 AHB cycles
* @CAM_CAMNOC_HW_IRQ_IPE_UBWC_ENCODE_ERROR : Triggered if any error
* detected in the IPE
* UBWC encoder instance
* @CAM_CAMNOC_HW_IRQ_BPS_UBWC_ENCODE_ERROR : Triggered if any error
* detected in the BPS
* UBWC encoder instance
* @CAM_CAMNOC_HW_IRQ_IPE1_BPS_UBWC_DECODE_ERROR : Triggered if any error
* detected in the IPE1/BPS
* read path decoder instance
* @CAM_CAMNOC_HW_IRQ_IPE0_UBWC_DECODE_ERROR : Triggered if any error
* detected in the IPE0 read
* path decoder instance
* @CAM_CAMNOC_HW_IRQ_IPE1_UBWC_DECODE_ERROR : Triggered if any error
* detected in the IPE1 read
* path decoder instance
* @CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR : Triggered if any error
* detected in the IPE/BPS
* UBWC decoder instance
* @CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR : Triggered if any error
* detected in the IPE/BPS
* UBWC encoder instance
* @CAM_CAMNOC_HW_IRQ_RESERVED1 : Reserved
* @CAM_CAMNOC_HW_IRQ_RESERVED2 : Reserved
* @CAM_CAMNOC_HW_IRQ_CAMNOC_TEST : To test the IRQ logic
*/
enum cam_camnoc_hw_irq_type {
CAM_CAMNOC_HW_IRQ_SLAVE_ERROR =
CAM_CAMNOC_IRQ_SLAVE_ERROR,
CAM_CAMNOC_HW_IRQ_IFE_UBWC_ENCODE_ERROR =
CAM_CAMNOC_IRQ_IFE_UBWC_ENCODE_ERROR,
CAM_CAMNOC_HW_IRQ_IFE_UBWC_STATS_ENCODE_ERROR =
CAM_CAMNOC_IRQ_IFE_UBWC_STATS_ENCODE_ERROR,
CAM_CAMNOC_HW_IRQ_IFE_UBWC_STATS_1_ENCODE_ERROR =
CAM_CAMNOC_IRQ_IFE_UBWC_STATS_1_ENCODE_ERROR,
CAM_CAMNOC_HW_IRQ_IFE02_UBWC_ENCODE_ERROR =
CAM_CAMNOC_IRQ_IFE02_UBWC_ENCODE_ERROR,
CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR =
CAM_CAMNOC_IRQ_IFE13_UBWC_ENCODE_ERROR,
CAM_CAMNOC_HW_IRQ_IFE0_UBWC_ENCODE_ERROR =
CAM_CAMNOC_IRQ_IFE0_UBWC_ENCODE_ERROR,
CAM_CAMNOC_HW_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR =
CAM_CAMNOC_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR,
CAM_CAMNOC_HW_IRQ_IPE_UBWC_ENCODE_ERROR =
CAM_CAMNOC_IRQ_IPE_UBWC_ENCODE_ERROR,
CAM_CAMNOC_HW_IRQ_BPS_UBWC_ENCODE_ERROR =
CAM_CAMNOC_IRQ_BPS_UBWC_ENCODE_ERROR,
CAM_CAMNOC_HW_IRQ_IPE1_BPS_UBWC_DECODE_ERROR =
CAM_CAMNOC_IRQ_IPE1_BPS_UBWC_DECODE_ERROR,
CAM_CAMNOC_HW_IRQ_IPE0_UBWC_DECODE_ERROR =
CAM_CAMNOC_IRQ_IPE0_UBWC_DECODE_ERROR,
CAM_CAMNOC_HW_IRQ_IPE1_UBWC_DECODE_ERROR =
CAM_CAMNOC_IRQ_IPE1_UBWC_DECODE_ERROR,
CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR =
CAM_CAMNOC_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR =
CAM_CAMNOC_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT =
CAM_CAMNOC_IRQ_AHB_TIMEOUT,
CAM_CAMNOC_HW_IRQ_RESERVED1,
CAM_CAMNOC_HW_IRQ_RESERVED2,
CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
};
/**
* enum cam_camnoc_port_type - Enum for different camnoc hw ports. All CAMNOC
* settings like QoS, LUT mappings need to be configured for
* each of these ports.
*
* @CAM_CAMNOC_CDM: Indicates CDM HW connection to camnoc
* @CAM_CAMNOC_SFE_RD: Indicates read data from all SFEs to cammnoc
* @CAM_CAMNOC_IFE02: Indicates IFE0, IFE2 HW connection to camnoc
* @CAM_CAMNOC_IFE13: Indicates IFE1, IFE3 HW connection to camnoc
* @CAM_CAMNOC_IFE_LITE: Indicates all IFE lites connection to camnoc
* @CAM_CAMNOC_IFE_LINEAR: Indicates linear data from all IFEs to cammnoc
* @CAM_CAMNOC_IFE_LINEAR_STATS: Indicates linear and stats data from certan
* IFEs to cammnoc
* @CAM_CAMNOC_IFE_LINEAR_STATS_1: Indicates linear and stats data from certan
* IFEs to cammnoc
* @CAM_CAMNOC_IFE_PDAF: Indicates pdaf data from all IFEs to cammnoc
* @CAM_CAMNOC_IFE_UBWC: Indicates ubwc from all IFEs to cammnoc
* @CAM_CAMNOC_IFE_UBWC_STATS: Indicates ubwc+stats from certain IFEs to cammnoc
* @CAM_CAMNOC_IFE_UBWC_STATS_1: Indicates ubwc+stats from certain
* IFEs to cammnoc
* @CAM_CAMNOC_IFE_RDI_WR: Indicates RDI write data from certain IFEs to cammnoc
* @CAM_CAMNOC_IFE_RDI_WR_1: Indicates RDI write data from certain
* IFEs to cammnoc
* @CAM_CAMNOC_IFE_RDI_RD: Indicates RDI read data from all IFEs to cammnoc
* @CAM_CAMNOC_IFE0123_RDI_WRITE: RDI write only for all IFEx
* @CAM_CAMNOC_IFE0_NRDI_WRITE: IFE0 non-RDI write
* @CAM_CAMNOC_IFE01_RDI_READ: IFE0/1 RDI READ
* @CAM_CAMNOC_IFE1_NRDI_WRITE: IFE1 non-RDI write
* @CAM_CAMNOC_IPE_BPS_LRME_READ: Indicates IPE, BPS, LRME Read HW
* connection to camnoc
* @CAM_CAMNOC_IPE_BPS_LRME_WRITE: Indicates IPE, BPS, LRME Write HW
* connection to camnoc
* @CAM_CAMNOC_IPE_VID_DISP_WRITE: Indicates IPE's VID/DISP Wrire HW
* connection to camnoc
* @CAM_CAMNOC_IPE_WR: Indicates IPE HW's write connection to camnoc
* @CAM_CAMNOC_IPE0_RD: Indicates IPE's Read0 HW connection to camnoc
* @CAM_CAMNOC_IPE1_RD: Indicates IPE's Read1 HW connection to camnoc
* @CAM_CAMNOC_IPE1_BPS_RD: Indicates IPE's Read1 + BPS Read HW connection
* to camnoc
* @CAM_CAMNOC_IPE_BPS_WR: Indicates IPE+BPS Write HW connection to camnoc
* @CAM_CAMNOC_BPS_WR: Indicates BPS HW's write connection to camnoc
* @CAM_CAMNOC_BPS_RD: Indicates BPS HW's read connection to camnoc
* @CAM_CAMNOC_JPEG: Indicates JPEG HW connection to camnoc
* @CAM_CAMNOC_FD: Indicates FD HW connection to camnoc
* @CAM_CAMNOC_ICP: Indicates ICP HW connection to camnoc
* @CAM_CAMNOC_TFE: Indicates TFE0 HW connection to camnoc
* @CAM_CAMNOC_TFE_1: Indicates TFE1 HW connection to camnoc
* @CAM_CAMNOC_TFE_2: Indicates TFE2 HW connection to camnoc
* @CAM_CAMNOC_OPE: Indicates OPE HW connection to camnoc
*/
enum cam_camnoc_port_type {
CAM_CAMNOC_CDM,
CAM_CAMNOC_SFE_RD,
CAM_CAMNOC_IFE02,
CAM_CAMNOC_IFE13,
CAM_CAMNOC_IFE_LITE,
CAM_CAMNOC_IFE_LINEAR,
CAM_CAMNOC_IFE_LINEAR_STATS,
CAM_CAMNOC_IFE_LINEAR_STATS_1,
CAM_CAMNOC_IFE_PDAF,
CAM_CAMNOC_IFE_UBWC,
CAM_CAMNOC_IFE_UBWC_STATS,
CAM_CAMNOC_IFE_UBWC_STATS_1,
CAM_CAMNOC_IFE_RDI_WR,
CAM_CAMNOC_IFE_RDI_WR_1,
CAM_CAMNOC_IFE_RDI_RD,
CAM_CAMNOC_IFE0123_RDI_WRITE,
CAM_CAMNOC_IFE0_NRDI_WRITE,
CAM_CAMNOC_IFE01_RDI_READ,
CAM_CAMNOC_IFE1_NRDI_WRITE,
CAM_CAMNOC_IPE_BPS_LRME_READ,
CAM_CAMNOC_IPE_BPS_LRME_WRITE,
CAM_CAMNOC_IPE_VID_DISP_WRITE,
CAM_CAMNOC_IPE_WR,
CAM_CAMNOC_IPE0_RD,
CAM_CAMNOC_IPE1_RD,
CAM_CAMNOC_IPE1_BPS_RD,
CAM_CAMNOC_IPE_BPS_WR,
CAM_CAMNOC_BPS_WR,
CAM_CAMNOC_BPS_RD,
CAM_CAMNOC_JPEG,
CAM_CAMNOC_FD,
CAM_CAMNOC_ICP,
CAM_CAMNOC_TFE,
CAM_CAMNOC_TFE_1,
CAM_CAMNOC_TFE_2,
CAM_CAMNOC_OPE,
CAM_CAMNOC_IFE01234_RDI_WRITE,
CAM_CAMNOC_IFE01_NRDI_WRITE,
CAM_CAMNOC_IFE2_NRDI_WRITE,
};
/**
* struct cam_camnoc_specific : CPAS camnoc specific settings
*
* @port_type: Port type
* @enable: Whether to enable settings for this connection
* @priority_lut_low: Priority Low LUT mapping for this connection
* @priority_lut_high: Priority High LUT mapping for this connection
* @urgency: Urgency (QoS) settings for this connection
* @danger_lut: Danger LUT mapping for this connection
* @safe_lut: Safe LUT mapping for this connection
* @ubwc_ctl: UBWC control settings for this connection
* @qosgen_mainctl: qosgen shaping control configuration for this connection
* @qosgen_shaping_low: qosgen shaping low configuration for this connection
* @qosgen_shaping_high: qosgen shaping high configuration for this connection
*
*/
struct cam_camnoc_specific {
enum cam_camnoc_port_type port_type;
bool enable;
struct cam_cpas_reg priority_lut_low;
struct cam_cpas_reg priority_lut_high;
struct cam_cpas_reg urgency;
struct cam_cpas_reg danger_lut;
struct cam_cpas_reg safe_lut;
struct cam_cpas_reg ubwc_ctl;
struct cam_cpas_reg flag_out_set0_low;
struct cam_cpas_reg qosgen_mainctl;
struct cam_cpas_reg qosgen_shaping_low;
struct cam_cpas_reg qosgen_shaping_high;
};
/**
* struct cam_camnoc_irq_sbm : Sideband manager settings for all CAMNOC IRQs
*
* @sbm_enable: SBM settings for IRQ enable
* @sbm_status: SBM settings for IRQ status
* @sbm_clear: SBM settings for IRQ clear
*
*/
struct cam_camnoc_irq_sbm {
struct cam_cpas_reg sbm_enable;
struct cam_cpas_reg sbm_status;
struct cam_cpas_reg sbm_clear;
};
/**
* struct cam_camnoc_irq_err : Error settings specific to each CAMNOC IRQ
*
* @irq_type: Type of IRQ
* @enable: Whether to enable error settings for this IRQ
* @sbm_port: Corresponding SBM port for this IRQ
* @err_enable: Error enable settings for this IRQ
* @err_status: Error status settings for this IRQ
* @err_clear: Error clear settings for this IRQ
*
*/
struct cam_camnoc_irq_err {
enum cam_camnoc_hw_irq_type irq_type;
bool enable;
uint32_t sbm_port;
struct cam_cpas_reg err_enable;
struct cam_cpas_reg err_status;
struct cam_cpas_reg err_clear;
};
/**
* struct cam_cpas_hw_errata_wa : Struct for HW errata workaround info
*
* @enable: Whether to enable this errata workround
* @data: HW Errata workaround data
*
*/
struct cam_cpas_hw_errata_wa {
bool enable;
union {
struct cam_cpas_reg reg_info;
} data;
};
/**
* struct cam_cpas_hw_errata_wa_list : List of HW Errata workaround info
*
* @camnoc_flush_slave_pending_trans: Errata workaround info for flushing
* camnoc slave pending transactions before turning off CPAS_TOP gdsc
* @tcsr_camera_hf_sf_ares_glitch: Errata workaround info from ignoring
* erroneous signals at camera start
*/
struct cam_cpas_hw_errata_wa_list {
struct cam_cpas_hw_errata_wa camnoc_flush_slave_pending_trans;
struct cam_cpas_hw_errata_wa tcsr_camera_hf_sf_ares_glitch;
};
/**
* struct cam_camnoc_err_logger_info : CAMNOC error logger register offsets
*
* @mainctrl: Register offset for mainctrl
* @errvld: Register offset for errvld
* @errlog0_low: Register offset for errlog0_low
* @errlog0_high: Register offset for errlog0_high
* @errlog1_low: Register offset for errlog1_low
* @errlog1_high: Register offset for errlog1_high
* @errlog2_low: Register offset for errlog2_low
* @errlog2_high: Register offset for errlog2_high
* @errlog3_low: Register offset for errlog3_low
* @errlog3_high: Register offset for errlog3_high
*
*/
struct cam_camnoc_err_logger_info {
uint32_t mainctrl;
uint32_t errvld;
uint32_t errlog0_low;
uint32_t errlog0_high;
uint32_t errlog1_low;
uint32_t errlog1_high;
uint32_t errlog2_low;
uint32_t errlog2_high;
uint32_t errlog3_low;
uint32_t errlog3_high;
};
/**
* struct cam_camnoc_fifo_lvl_info : Struct for fifo fill level registers
* @IFE0_nRDI_maxwr_offset: Register offset for fill level for IFE0
* @IFE1_nRDI_maxwr_offset: Register offset for fill level for IFE1
* @IFE0123_RDI_maxwr_low_offset: Register offset for RDI
* @ife_linear: Register offset for ife linear
* @ife_rdi_wr: Register offset for rdi wr
* @ife_ubwc_stats: Register offset for ubwc stats
* @IFE02_MAXWR_LOW: Register offset for IFE02
* @IFE13_MAXWR_LOW: Register offset for IFE13
* @IFE01_MAXWR_LOW: Register offset for IFE01
* @IFE23_MAXWR_LOW: Register offset for IFE23
*/
struct cam_camnoc_fifo_lvl_info {
uint32_t IFE0_nRDI_maxwr_offset;
uint32_t IFE1_nRDI_maxwr_offset;
uint32_t IFE0123_RDI_maxwr_offset;
uint32_t ife_linear;
uint32_t ife_rdi_wr;
uint32_t ife_ubwc_stats;
uint32_t IFE02_MAXWR_LOW;
uint32_t IFE13_MAXWR_LOW;
uint32_t IFE01_MAXWR_LOW;
uint32_t IFE23_MAXWR_LOW;
uint32_t IFE0_MAXWR_LOW;
uint32_t IFE1_MAXWR_LOW;
};
/**
* struct cam_camnoc_info : Overall CAMNOC settings info
*
* @specific: Pointer to CAMNOC SPECIFICTONTTPTR settings
* @specific_size: Array size of SPECIFICTONTTPTR settings
* @irq_sbm: Pointer to CAMNOC IRQ SBM settings
* @irq_err: Pointer to CAMNOC IRQ Error settings
* @irq_err_size: Array size of IRQ Error settings
* @err_logger: Pointer to CAMNOC IRQ Error logger read registers
* @errata_wa_list: HW Errata workaround info
* @fill_level_register: Fill level registers
*
*/
struct cam_camnoc_info {
struct cam_camnoc_specific *specific;
int specific_size;
struct cam_camnoc_irq_sbm *irq_sbm;
struct cam_camnoc_irq_err *irq_err;
int irq_err_size;
struct cam_camnoc_err_logger_info *err_logger;
struct cam_cpas_hw_errata_wa_list *errata_wa_list;
struct cam_camnoc_fifo_lvl_info *fill_lvl_register;
};
/**
* struct cam_cpas_work_payload : Struct for cpas work payload data
*
* @hw: Pointer to HW info
* @irq_status: IRQ status value
* @irq_data: IRQ data
* @workq_scheduled_ts: workqueue scheduled timestamp
* @work: Work handle
*
*/
struct cam_cpas_work_payload {
struct cam_hw_info *hw;
uint32_t irq_status;
uint32_t irq_data;
ktime_t workq_scheduled_ts;
struct work_struct work;
};
/**
* struct cam_cpas_camnoc_qchannel : Cpas camnoc qchannel info
*
* @qchannel_ctrl: offset to configure to control camnoc qchannel interface
* @qchannel_status: offset to read camnoc qchannel interface status
*
*/
struct cam_cpas_camnoc_qchannel {
uint32_t qchannel_ctrl;
uint32_t qchannel_status;
};
#endif /* _CAM_CPASTOP_HW_H_ */

View file

@ -0,0 +1,566 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP100_H_
#define _CPASTOP100_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas100_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2040, /* SBM_FAULTINEN0_LOW */
.value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
(TEST_IRQ_ENABLE ?
0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2048, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2080, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
}
};
static struct cam_camnoc_irq_err
cam_cpas100_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = true,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2718, /* ERRLOGGER_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE02_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 = 0x5a0, /* SPECIFIC_IFE02_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x590, /* SPECIFIC_IFE02_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x598, /* SPECIFIC_IFE02_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x9a0, /* SPECIFIC_IFE13_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x990, /* SPECIFIC_IFE13_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x998, /* SPECIFIC_IFE13_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0xd20, /* SPECIFIC_IBL_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0xd10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0xd18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x11a0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x1190,
/* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x1198, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = true,
.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x100, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
.value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas100_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x30, /* SPECIFIC_CDM_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x34, /* SPECIFIC_CDM_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x38, /* SPECIFIC_CDM_URGENCY_LOW */
.mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */
.shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */
.value = 0,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x40, /* SPECIFIC_CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x48, /* SPECIFIC_CDM_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
},
{
.port_type = CAM_CAMNOC_IFE02,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x430, /* SPECIFIC_IFE02_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x434, /* SPECIFIC_IFE02_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x438, /* SPECIFIC_IFE02_URGENCY_LOW */
/* SPECIFIC_IFE02_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE02_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x440, /* SPECIFIC_IFE02_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x448, /* SPECIFIC_IFE02_SAFELUT_LOW */
.value = 0x3,
},
.ubwc_ctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x588, /* SPECIFIC_IFE02_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IFE13,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x830, /* SPECIFIC_IFE13_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x834, /* SPECIFIC_IFE13_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x838, /* SPECIFIC_IFE13_URGENCY_LOW */
/* SPECIFIC_IFE13_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE13_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x840, /* SPECIFIC_IFE13_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x848, /* SPECIFIC_IFE13_SAFELUT_LOW */
.value = 0x3,
},
.ubwc_ctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x988, /* SPECIFIC_IFE13_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc30, /* SPECIFIC_IBL_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc34, /* SPECIFIC_IBL_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0xc38, /* SPECIFIC_IBL_RD_URGENCY_LOW */
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_MASK */
.mask = 0x7,
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_SHIFT */
.shift = 0x0,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc40, /* SPECIFIC_IBL_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc48, /* SPECIFIC_IBL_RD_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xd08, /* SPECIFIC_IBL_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1030, /* SPECIFIC_IBL_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1034, /* SPECIFIC_IBL_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x1038, /* SPECIFIC_IBL_WR_URGENCY_LOW */
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1040, /* SPECIFIC_IBL_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1048, /* SPECIFIC_IBL_WR_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1188, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1430, /* SPECIFIC_JPEG_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1434, /* SPECIFIC_JPEG_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1438, /* SPECIFIC_JPEG_URGENCY_LOW */
.value = 0x22,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1440, /* SPECIFIC_JPEG_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1448, /* SPECIFIC_JPEG_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_FD,
.enable = false,
},
{
.port_type = CAM_CAMNOC_ICP,
.enable = false,
}
};
static struct cam_camnoc_err_logger_info cam170_cpas100_err_logger_offsets = {
.mainctrl = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x2720, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x2724, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x2728, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x272c, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x2730, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x2734, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x2738, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x273c, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam170_cpas100_errata_wa_list = {
.camnoc_flush_slave_pending_trans = {
.enable = true,
.data.reg_info = {
.access_type = CAM_REG_TYPE_READ,
.offset = 0x2100, /* SidebandManager_SenseIn0_Low */
.mask = 0xE0000, /* Bits 17, 18, 19 */
.value = 0, /* expected to be 0 */
},
},
};
struct cam_camnoc_info cam170_cpas100_camnoc_info = {
.specific = &cam_cpas100_camnoc_specific[0],
.specific_size = sizeof(cam_cpas100_camnoc_specific) /
sizeof(cam_cpas100_camnoc_specific[0]),
.irq_sbm = &cam_cpas100_irq_sbm,
.irq_err = &cam_cpas100_irq_err[0],
.irq_err_size = sizeof(cam_cpas100_irq_err) /
sizeof(cam_cpas100_irq_err[0]),
.err_logger = &cam170_cpas100_err_logger_offsets,
.errata_wa_list = &cam170_cpas100_errata_wa_list,
};
#endif /* _CPASTOP100_H_ */

View file

@ -0,0 +1,569 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP_V150_100_H_
#define _CPASTOP_V150_100_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v150_100_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2040, /* SBM_FAULTINEN0_LOW */
.value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
(TEST_IRQ_ENABLE ?
0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2048, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2080, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v150_100_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = true,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2718, /* ERRLOGGER_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE02_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 = 0x5a0, /* SPECIFIC_IFE02_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x590, /* SPECIFIC_IFE02_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x598, /* SPECIFIC_IFE02_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x9a0, /* SPECIFIC_IFE13_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x990, /* SPECIFIC_IFE13_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x998, /* SPECIFIC_IFE13_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0xd20, /* SPECIFIC_IBL_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0xd10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0xd18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x11a0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x1190,
/* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x1198, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = true,
.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x100, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
.value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas_v150_100_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x30, /* SPECIFIC_CDM_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x34, /* SPECIFIC_CDM_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x38, /* SPECIFIC_CDM_URGENCY_LOW */
.mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */
.shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */
.value = 0x2,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x40, /* SPECIFIC_CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x48, /* SPECIFIC_CDM_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
},
{
.port_type = CAM_CAMNOC_IFE02,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x430, /* SPECIFIC_IFE02_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x434, /* SPECIFIC_IFE02_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x438, /* SPECIFIC_IFE02_URGENCY_LOW */
/* SPECIFIC_IFE02_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE02_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x440, /* SPECIFIC_IFE02_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x448, /* SPECIFIC_IFE02_SAFELUT_LOW */
.value = 0x1,
},
.ubwc_ctl = {
.enable = false,
},
},
{
.port_type = CAM_CAMNOC_IFE13,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x830, /* SPECIFIC_IFE13_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x834, /* SPECIFIC_IFE13_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x838, /* SPECIFIC_IFE13_URGENCY_LOW */
/* SPECIFIC_IFE13_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE13_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x840, /* SPECIFIC_IFE13_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x848, /* SPECIFIC_IFE13_SAFELUT_LOW */
.value = 0x1,
},
.ubwc_ctl = {
.enable = false,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc30, /* SPECIFIC_IBL_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc34, /* SPECIFIC_IBL_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0xc38, /* SPECIFIC_IBL_RD_URGENCY_LOW */
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_MASK */
.mask = 0x7,
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_SHIFT */
.shift = 0x0,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc40, /* SPECIFIC_IBL_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc48, /* SPECIFIC_IBL_RD_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xd08, /* SPECIFIC_IBL_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1030, /* SPECIFIC_IBL_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1034, /* SPECIFIC_IBL_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x1038, /* SPECIFIC_IBL_WR_URGENCY_LOW */
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1040, /* SPECIFIC_IBL_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1048, /* SPECIFIC_IBL_WR_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1188, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
.value = 0x5,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1430, /* SPECIFIC_JPEG_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1434, /* SPECIFIC_JPEG_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1438, /* SPECIFIC_JPEG_URGENCY_LOW */
.value = 0x22,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1440, /* SPECIFIC_JPEG_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1448, /* SPECIFIC_JPEG_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
},
{
.port_type = CAM_CAMNOC_FD,
.enable = false,
},
{
.port_type = CAM_CAMNOC_ICP,
.enable = true,
.flag_out_set0_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x2088,
.value = 0x100000,
},
},
};
static struct cam_camnoc_err_logger_info cam150_cpas100_err_logger_offsets = {
.mainctrl = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x2720, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x2724, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x2728, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x272c, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x2730, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x2734, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x2738, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x273c, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam150_cpas100_errata_wa_list = {
.camnoc_flush_slave_pending_trans = {
.enable = false,
.data.reg_info = {
.access_type = CAM_REG_TYPE_READ,
.offset = 0x2100, /* SidebandManager_SenseIn0_Low */
.mask = 0xE0000, /* Bits 17, 18, 19 */
.value = 0, /* expected to be 0 */
},
},
};
struct cam_camnoc_fifo_lvl_info cam150_cpas100_camnoc_fifo_info = {
.IFE02_MAXWR_LOW = 0x420,
.IFE13_MAXWR_LOW = 0x820,
};
static struct cam_camnoc_info cam150_cpas100_camnoc_info = {
.specific = &cam_cpas_v150_100_camnoc_specific[0],
.specific_size = sizeof(cam_cpas_v150_100_camnoc_specific) /
sizeof(cam_cpas_v150_100_camnoc_specific[0]),
.irq_sbm = &cam_cpas_v150_100_irq_sbm,
.irq_err = &cam_cpas_v150_100_irq_err[0],
.irq_err_size = sizeof(cam_cpas_v150_100_irq_err) /
sizeof(cam_cpas_v150_100_irq_err[0]),
.err_logger = &cam150_cpas100_err_logger_offsets,
.errata_wa_list = &cam150_cpas100_errata_wa_list,
.fill_lvl_register = &cam150_cpas100_camnoc_fifo_info,
};
#endif /* _CPASTOP_V150_100_H_ */

View file

@ -0,0 +1,722 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP_V165_100_H_
#define _CPASTOP_V165_100_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v165_100_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2240, /* SBM_FAULTINEN0_LOW */
.value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
(TEST_IRQ_ENABLE ?
0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2248, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2280, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v165_100_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = true,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x4F08, /* ERL_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x4F10, /* ERL_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x4F18, /* ERL_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE0_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 = 0x3BA0, /* SPECIFIC_IFE0_MAIN_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x3B90,
/* SPECIFIC_IFE0_MAIN_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x3B98, /* SPECIFIC_IFE0_MAIN_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x55A0, /* SPECIFIC_IFE1_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x5590, /* SPECIFIC_IFE1_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x5598, /* SPECIFIC_IFE1_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2F20, /* SPECIFIC_IBL_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2F10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2F18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2BA0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2B90,
/* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2B98, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = false,
.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2288, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2290, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x40, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2288, /* SBM_FLAGOUTSET0_LOW */
.value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2290, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas_v165_100_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4230, /* CDM_PRIORITYLUT_LOW */
.value = 0x0,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4234, /* CDM_PRIORITYLUT_HIGH */
.value = 0x0,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0, /* CDM_Urgency_Low */
.offset = 0x4238,
.mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */
.shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4240, /* CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4248, /* CDM_SAFELUT_LOW */
.value = 0xFFFF,
},
.ubwc_ctl = {
.enable = false,
},
},
{
.port_type = CAM_CAMNOC_IFE01234_RDI_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3630, /* IFE01234_RDI_PRIORITYLUT_LOW */
.value = 0x55554433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3634, /* IFE01234_RDI_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3638, /* IFE01234_RDI_LINEAR_URGENCY_LOW */
.mask = 0x1FF0,
.shift = 0x4,
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3640, /* IFE01234_RDI_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3648, /* IFE01234_RDI_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 = true,
.is_fuse_based = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4808, /* IFE01234_RDI_QOSGEN_MAINCTL */
.value = 0x2,
},
.qosgen_shaping_low = {
.enable = true,
.is_fuse_based = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4820, /* IFE01234_RDI_QOSGEN_SHAPING_LOW */
.value = 0x07070707,
},
.qosgen_shaping_high = {
.enable = true,
.is_fuse_based = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4824, /* IFE01234_RDI_QOSGEN_SHAPING_HIGH */
.value = 0x07070707,
},
},
{
.port_type = CAM_CAMNOC_IFE01_NRDI_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3A30, /* IFE01_NRDI_PRIORITYLUT_LOW */
.value = 0x55554433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3A34, /* IFE01_NRDI_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x3A38, /* IFE01_NRDI_URGENCY_LOW */
/* IFE01_NRDI_URGENCY_LOW_WRITE_MASK */
.mask = 0x1FF0,
/* IFE01_NRDI_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3A40, /* IFE01_NRDI_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3A48, /* IFE01_NRDI_SAFELUT_LOW */
.value = 0xF,
},
/* no reg for this */
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3B88, /* IFE01_NRDI_ENCCTL_LOW */
.value = 1,
},
.qosgen_mainctl = {
.enable = true,
.is_fuse_based = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4708, /* IFE01_NRDI_QOSGEN_MAINCTL */
.value = 0x2,
},
.qosgen_shaping_low = {
.enable = true,
.is_fuse_based = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4720, /* IFE01_NRDI_QOSGEN_SHAPING_LOW */
.value = 0x07070707,
},
.qosgen_shaping_high = {
.enable = true,
.is_fuse_based = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4724, /* IFE01_NRDI_QOSGEN_SHAPING_HIGH */
.value = 0x07070707,
},
},
{
.port_type = CAM_CAMNOC_IFE2_NRDI_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5430, /* IFE2_NDRI_PRIORITYLUT_LOW */
.value = 0x55554433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* IFE2_NRDI_PRIORITYLUT_HIGH */
.offset = 0x5434,
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x5438, /* IFE2_NRDI_URGENCY_LOW */
/* IFE2_NRDI_URGENCY_LOW_WRITE_MASK */
.mask = 0x1FF0,
/* IFE2_NRDI_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x5440, /* IFE2_NRDI_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x5448, /* IFE2_NRDI_SAFELUT_LOW */
.value = 0xF,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5588, /* IFE2_NRDI_ENCCTL_LOW */
.value = 0,
},
.qosgen_mainctl = {
.enable = true,
.is_fuse_based = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5188, /* IFE2_NRDI_QOSGEN_MAINCTL */
.value = 0x2,
},
.qosgen_shaping_low = {
.enable = true,
.is_fuse_based = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x51A0, /* IFE2_NRDI_QOSGEN_SHAPING_LOW */
.value = 0x07070707,
},
.qosgen_shaping_high = {
.enable = true,
.is_fuse_based = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x51A4, /* IFE2_NRDI_QOSGEN_SHAPING_HIGH */
.value = 0x07070707,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E30, /* IPE_BPS_LRME_RD_PRIORITYLUT_LOW */
.value = 0x33333333, /*Value is 0 in excel sheet */
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E34, /* IPE_BPS_LRME_RD_PRIORITYLUT_HIGH */
.value = 0x33333333, /*Value is 0 in excel sheet */
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x2E38, /* IPE_BPS_LRME_RD_URGENCY_LOW */
/* IPE_BPS_LRME_RD_URGENCY_LOW_READ_MASK */
.mask = 0x7,
/* IPE_BPS_LRME_RD_URGENCY_LOW_READ_SHIFT */
.shift = 0x0,
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E40, /* IPE_BPS_LRME_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E48, /* IPE_BPS_LRME_RD_SAFELUT_LOW */
.value = 0xFFFF,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2F08, /* IPE_BPS_LRME_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2A30, /* IPE_BPS_LRME_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2A34, /* IPE_BPS_LRME_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x2A38, /* IPE_BPS_LRME_WR_URGENCY_LOW */
/* IPE_BPS_LRME_WR_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* IPE_BPS_LRME_WR_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 0x30,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2A40, /* IPE_BPS_LRME_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2A48, /* IPE_BPS_LRME_WR_SAFELUT_LOW */
.value = 0xFFFF,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2B88, /* IPE_BPS_LRME_WR_ENCCTL_LOW */
.value = 0,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2630, /* JPEG_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2634, /* JPEG_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x2638, /* JPEG_URGENCY_LOW */
.mask = 0x3F,
.shift = 0x0,
.value = 0x22,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2640, /* JPEG_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2648, /* JPEG_SAFELUT_LOW */
.value = 0xFFFF,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
/*SidebandManager_main_SidebandManager_FlagOutSet0_Low*/
.port_type = CAM_CAMNOC_ICP,
.enable = false,
.flag_out_set0_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x5088,
.value = 0x50,
},
},
};
static struct cam_camnoc_err_logger_info cam165_cpas100_err_logger_offsets = {
.mainctrl = 0x4F08, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x4F10, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x4F20, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x4F24, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x4F28, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x4F2C, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x4F30, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x4F34, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x4F38, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x4F3C, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam165_cpas100_errata_wa_list = {
.camnoc_flush_slave_pending_trans = {
.enable = false,
.data.reg_info = {
.access_type = CAM_REG_TYPE_READ,
.offset = 0x2300, /* sbm_SenseIn0_Low */
.mask = 0xE0000, /* Bits 17, 18, 19 */
.value = 0, /* expected to be 0 */
},
},
};
struct cam_camnoc_fifo_lvl_info cam165_cpas100_camnoc_fifo_info = {
.IFE0_MAXWR_LOW = 0x3A20,
.IFE1_MAXWR_LOW = 0x5420,
};
static struct cam_camnoc_info cam165_cpas100_camnoc_info = {
.specific = &cam_cpas_v165_100_camnoc_specific[0],
.specific_size = ARRAY_SIZE(cam_cpas_v165_100_camnoc_specific),
.irq_sbm = &cam_cpas_v165_100_irq_sbm,
.irq_err = &cam_cpas_v165_100_irq_err[0],
.irq_err_size = ARRAY_SIZE(cam_cpas_v165_100_irq_err),
.err_logger = &cam165_cpas100_err_logger_offsets,
.errata_wa_list = &cam165_cpas100_errata_wa_list,
.fill_lvl_register = &cam165_cpas100_camnoc_fifo_info,
};
#endif /* _CPASTOP_V165_100_H_ */

View file

@ -0,0 +1,580 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP_V170_110_H_
#define _CPASTOP_V170_110_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas110_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2040, /* SBM_FAULTINEN0_LOW */
.value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
(TEST_IRQ_ENABLE ?
0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2048, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2080, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
}
};
static struct cam_camnoc_irq_err
cam_cpas110_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = true,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2718, /* ERRLOGGER_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE02_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 = 0x5a0, /* SPECIFIC_IFE02_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x590, /* SPECIFIC_IFE02_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x598, /* SPECIFIC_IFE02_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x9a0, /* SPECIFIC_IFE13_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x990, /* SPECIFIC_IFE13_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x998, /* SPECIFIC_IFE13_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0xd20, /* SPECIFIC_IBL_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0xd10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0xd18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x11a0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x1190,
/* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x1198, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = true,
.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x100, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
.value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas110_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x30, /* SPECIFIC_CDM_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x34, /* SPECIFIC_CDM_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x38, /* SPECIFIC_CDM_URGENCY_LOW */
.mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */
.shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */
.value = 0x2,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x40, /* SPECIFIC_CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x48, /* SPECIFIC_CDM_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
},
},
{
.port_type = CAM_CAMNOC_IFE02,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x430, /* SPECIFIC_IFE02_PRIORITYLUT_LOW */
.value = 0x66666543,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x434, /* SPECIFIC_IFE02_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x438, /* SPECIFIC_IFE02_URGENCY_LOW */
/* SPECIFIC_IFE02_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE02_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x440, /* SPECIFIC_IFE02_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x448, /* SPECIFIC_IFE02_SAFELUT_LOW */
.value = 0x1,
},
.ubwc_ctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x588, /* SPECIFIC_IFE02_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IFE13,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x830, /* SPECIFIC_IFE13_PRIORITYLUT_LOW */
.value = 0x66666543,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x834, /* SPECIFIC_IFE13_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x838, /* SPECIFIC_IFE13_URGENCY_LOW */
/* SPECIFIC_IFE13_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE13_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x840, /* SPECIFIC_IFE13_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x848, /* SPECIFIC_IFE13_SAFELUT_LOW */
.value = 0x1,
},
.ubwc_ctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x988, /* SPECIFIC_IFE13_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc30, /* SPECIFIC_IBL_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc34, /* SPECIFIC_IBL_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0xc38, /* SPECIFIC_IBL_RD_URGENCY_LOW */
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_MASK */
.mask = 0x7,
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_SHIFT */
.shift = 0x0,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc40, /* SPECIFIC_IBL_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc48, /* SPECIFIC_IBL_RD_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xd08, /* SPECIFIC_IBL_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1030, /* SPECIFIC_IBL_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1034, /* SPECIFIC_IBL_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x1038, /* SPECIFIC_IBL_WR_URGENCY_LOW */
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1040, /* SPECIFIC_IBL_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1048, /* SPECIFIC_IBL_WR_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1188, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1430, /* SPECIFIC_JPEG_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1434, /* SPECIFIC_JPEG_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1438, /* SPECIFIC_JPEG_URGENCY_LOW */
.value = 0x22,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1440, /* SPECIFIC_JPEG_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1448, /* SPECIFIC_JPEG_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_FD,
.enable = false,
},
{
.port_type = CAM_CAMNOC_ICP,
.enable = true,
.flag_out_set0_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x2088,
.value = 0x100000,
},
},
};
static struct cam_camnoc_err_logger_info cam170_cpas110_err_logger_offsets = {
.mainctrl = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x2720, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x2724, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x2728, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x272c, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x2730, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x2734, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x2738, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x273c, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam170_cpas110_errata_wa_list = {
.camnoc_flush_slave_pending_trans = {
.enable = false,
.data.reg_info = {
.access_type = CAM_REG_TYPE_READ,
.offset = 0x2100, /* SidebandManager_SenseIn0_Low */
.mask = 0xE0000, /* Bits 17, 18, 19 */
.value = 0, /* expected to be 0 */
},
},
};
struct cam_camnoc_fifo_lvl_info cam170_cpas110_camnoc_fifo_info = {
.IFE02_MAXWR_LOW = 0x420,
.IFE13_MAXWR_LOW = 0x820,
};
static struct cam_camnoc_info cam170_cpas110_camnoc_info = {
.specific = &cam_cpas110_camnoc_specific[0],
.specific_size = sizeof(cam_cpas110_camnoc_specific) /
sizeof(cam_cpas110_camnoc_specific[0]),
.irq_sbm = &cam_cpas110_irq_sbm,
.irq_err = &cam_cpas110_irq_err[0],
.irq_err_size = sizeof(cam_cpas110_irq_err) /
sizeof(cam_cpas110_irq_err[0]),
.err_logger = &cam170_cpas110_err_logger_offsets,
.errata_wa_list = &cam170_cpas110_errata_wa_list,
.fill_lvl_register = &cam170_cpas110_camnoc_fifo_info,
};
#endif /* _CPASTOP_V170_110_H_ */

View file

@ -0,0 +1,581 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP_V170_200_H_
#define _CPASTOP_V170_200_H_
#define TEST_IRQ_ENABLE 0
#define TCSR_CONN_RESET 0x0
#define TCSR_CONN_SET 0x3
static struct cam_camnoc_irq_sbm cam_cpas_v170_200_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2040, /* SBM_FAULTINEN0_LOW */
.value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
(TEST_IRQ_ENABLE ?
0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2048, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2080, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v170_200_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = true,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2718, /* ERRLOGGER_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE02_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 = 0x5a0, /* SPECIFIC_IFE02_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x590, /* SPECIFIC_IFE02_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x598, /* SPECIFIC_IFE02_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x9a0, /* SPECIFIC_IFE13_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x990, /* SPECIFIC_IFE13_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x998, /* SPECIFIC_IFE13_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0xd20, /* SPECIFIC_IBL_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0xd10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0xd18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x11a0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x1190,
/* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x1198, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = true,
.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x100, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
.value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas_v170_200_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x30, /* SPECIFIC_CDM_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x34, /* SPECIFIC_CDM_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x38, /* SPECIFIC_CDM_URGENCY_LOW */
.mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */
.shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */
.value = 0x2,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x40, /* SPECIFIC_CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x48, /* SPECIFIC_CDM_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE02,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x430, /* SPECIFIC_IFE02_PRIORITYLUT_LOW */
.value = 0x66666543,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x434, /* SPECIFIC_IFE02_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x438, /* SPECIFIC_IFE02_URGENCY_LOW */
/* SPECIFIC_IFE02_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE02_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x440, /* SPECIFIC_IFE02_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x448, /* SPECIFIC_IFE02_SAFELUT_LOW */
.value = 0x1,
},
.ubwc_ctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x588, /* SPECIFIC_IFE02_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IFE13,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x830, /* SPECIFIC_IFE13_PRIORITYLUT_LOW */
.value = 0x66666543,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x834, /* SPECIFIC_IFE13_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x838, /* SPECIFIC_IFE13_URGENCY_LOW */
/* SPECIFIC_IFE13_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE13_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x840, /* SPECIFIC_IFE13_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x848, /* SPECIFIC_IFE13_SAFELUT_LOW */
.value = 0x1,
},
.ubwc_ctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x988, /* SPECIFIC_IFE13_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc30, /* SPECIFIC_IBL_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc34, /* SPECIFIC_IBL_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0xc38, /* SPECIFIC_IBL_RD_URGENCY_LOW */
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_MASK */
.mask = 0x7,
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_SHIFT */
.shift = 0x0,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc40, /* SPECIFIC_IBL_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc48, /* SPECIFIC_IBL_RD_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xd08, /* SPECIFIC_IBL_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1030, /* SPECIFIC_IBL_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1034, /* SPECIFIC_IBL_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x1038, /* SPECIFIC_IBL_WR_URGENCY_LOW */
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1040, /* SPECIFIC_IBL_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1048, /* SPECIFIC_IBL_WR_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1188, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1430, /* SPECIFIC_JPEG_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1434, /* SPECIFIC_JPEG_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1438, /* SPECIFIC_JPEG_URGENCY_LOW */
.value = 0x22,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1440, /* SPECIFIC_JPEG_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1448, /* SPECIFIC_JPEG_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_FD,
.enable = false,
},
{
.port_type = CAM_CAMNOC_ICP,
.enable = true,
.flag_out_set0_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x2088,
.value = 0x100000,
},
},
};
static struct cam_camnoc_err_logger_info cam170_cpas200_err_logger_offsets = {
.mainctrl = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x2720, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x2724, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x2728, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x272c, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x2730, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x2734, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x2738, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x273c, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam170_cpas200_errata_wa_list = {
.camnoc_flush_slave_pending_trans = {
.enable = false,
.data.reg_info = {
.access_type = CAM_REG_TYPE_READ,
.offset = 0x2100, /* SidebandManager_SenseIn0_Low */
.mask = 0xE0000, /* Bits 17, 18, 19 */
.value = 0, /* expected to be 0 */
},
},
};
struct cam_camnoc_fifo_lvl_info cam170_cpas200_camnoc_fifo_info = {
.IFE01_MAXWR_LOW = 0x2420,
.IFE23_MAXWR_LOW = 0x2620,
};
static struct cam_camnoc_info cam170_cpas200_camnoc_info = {
.specific = &cam_cpas_v170_200_camnoc_specific[0],
.specific_size = ARRAY_SIZE(cam_cpas_v170_200_camnoc_specific),
.irq_sbm = &cam_cpas_v170_200_irq_sbm,
.irq_err = &cam_cpas_v170_200_irq_err[0],
.irq_err_size = ARRAY_SIZE(cam_cpas_v170_200_irq_err),
.err_logger = &cam170_cpas200_err_logger_offsets,
.errata_wa_list = &cam170_cpas200_errata_wa_list,
.fill_lvl_register = &cam170_cpas200_camnoc_fifo_info,
};
#endif /* _CPASTOP_V170_200_H_ */

View file

@ -0,0 +1,601 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP_V175_100_H_
#define _CPASTOP_V175_100_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v175_100_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2040, /* SBM_FAULTINEN0_LOW */
.value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
(TEST_IRQ_ENABLE ?
0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2048, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2080, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v175_100_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = true,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2718, /* ERRLOGGER_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE02_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 = 0x5a0, /* SPECIFIC_IFE02_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x590, /* SPECIFIC_IFE02_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x598, /* SPECIFIC_IFE02_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x9a0, /* SPECIFIC_IFE13_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x990, /* SPECIFIC_IFE13_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x998, /* SPECIFIC_IFE13_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0xd20, /* SPECIFIC_IBL_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0xd10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0xd18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x11a0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x1190,
/* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x1198, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = true,
.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x100, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
.value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas_v175_100_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x30, /* SPECIFIC_CDM_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x34, /* SPECIFIC_CDM_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x38, /* SPECIFIC_CDM_URGENCY_LOW */
.mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */
.shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */
.value = 0x2,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x40, /* SPECIFIC_CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x48, /* SPECIFIC_CDM_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE02,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x430, /* SPECIFIC_IFE02_PRIORITYLUT_LOW */
.value = 0x66666543,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x434, /* SPECIFIC_IFE02_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x438, /* SPECIFIC_IFE02_URGENCY_LOW */
/* SPECIFIC_IFE02_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE02_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x440, /* SPECIFIC_IFE02_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x448, /* SPECIFIC_IFE02_SAFELUT_LOW */
.value = 0x1,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x588, /* SPECIFIC_IFE02_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IFE13,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x830, /* SPECIFIC_IFE13_PRIORITYLUT_LOW */
.value = 0x66666543,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x834, /* SPECIFIC_IFE13_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x838, /* SPECIFIC_IFE13_URGENCY_LOW */
/* SPECIFIC_IFE13_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE13_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x840, /* SPECIFIC_IFE13_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x848, /* SPECIFIC_IFE13_SAFELUT_LOW */
.value = 0x1,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x988, /* SPECIFIC_IFE13_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc30, /* SPECIFIC_IBL_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc34, /* SPECIFIC_IBL_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0xc38, /* SPECIFIC_IBL_RD_URGENCY_LOW */
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_MASK */
.mask = 0x7,
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_SHIFT */
.shift = 0x0,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc40, /* SPECIFIC_IBL_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc48, /* SPECIFIC_IBL_RD_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xd08, /* SPECIFIC_IBL_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1030, /* SPECIFIC_IBL_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1034, /* SPECIFIC_IBL_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x1038, /* SPECIFIC_IBL_WR_URGENCY_LOW */
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1040, /* SPECIFIC_IBL_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1048, /* SPECIFIC_IBL_WR_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1188, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1430, /* SPECIFIC_JPEG_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1434, /* SPECIFIC_JPEG_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1438, /* SPECIFIC_JPEG_URGENCY_LOW */
.value = 0x22,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1440, /* SPECIFIC_JPEG_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1448, /* SPECIFIC_JPEG_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_FD,
.enable = false,
},
{
.port_type = CAM_CAMNOC_ICP,
.enable = true,
.flag_out_set0_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x2088,
.value = 0x100000,
},
},
};
static struct cam_camnoc_err_logger_info cam175_cpas100_err_logger_offsets = {
.mainctrl = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x2720, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x2724, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x2728, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x272c, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x2730, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x2734, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x2738, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x273c, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam175_cpas100_errata_wa_list = {
.camnoc_flush_slave_pending_trans = {
.enable = false,
.data.reg_info = {
.access_type = CAM_REG_TYPE_READ,
.offset = 0x2100, /* SidebandManager_SenseIn0_Low */
.mask = 0xE0000, /* Bits 17, 18, 19 */
.value = 0, /* expected to be 0 */
},
},
};
struct cam_camnoc_fifo_lvl_info cam175_cpas100_camnoc_fifo_info = {
.IFE02_MAXWR_LOW = 0x420,
.IFE13_MAXWR_LOW = 0x820,
};
static struct cam_camnoc_info cam175_cpas100_camnoc_info = {
.specific = &cam_cpas_v175_100_camnoc_specific[0],
.specific_size = sizeof(cam_cpas_v175_100_camnoc_specific) /
sizeof(cam_cpas_v175_100_camnoc_specific[0]),
.irq_sbm = &cam_cpas_v175_100_irq_sbm,
.irq_err = &cam_cpas_v175_100_irq_err[0],
.irq_err_size = sizeof(cam_cpas_v175_100_irq_err) /
sizeof(cam_cpas_v175_100_irq_err[0]),
.err_logger = &cam175_cpas100_err_logger_offsets,
.errata_wa_list = &cam175_cpas100_errata_wa_list,
.fill_lvl_register = &cam175_cpas100_camnoc_fifo_info,
};
#endif /* _CPASTOP_V175_100_H_ */

View file

@ -0,0 +1,601 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP_V175_101_H_
#define _CPASTOP_V175_101_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v175_101_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2040, /* SBM_FAULTINEN0_LOW */
.value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
(TEST_IRQ_ENABLE ?
0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2048, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2080, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v175_101_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = true,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2718, /* ERRLOGGER_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE02_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 = 0x5a0, /* SPECIFIC_IFE02_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x590, /* SPECIFIC_IFE02_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x598, /* SPECIFIC_IFE02_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x9a0, /* SPECIFIC_IFE13_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x990, /* SPECIFIC_IFE13_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x998, /* SPECIFIC_IFE13_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0xd20, /* SPECIFIC_IBL_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0xd10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0xd18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x11a0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x1190,
/* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x1198, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = true,
.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x100, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
.value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas_v175_101_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x30, /* SPECIFIC_CDM_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x34, /* SPECIFIC_CDM_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x38, /* SPECIFIC_CDM_URGENCY_LOW */
.mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */
.shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */
.value = 0x2,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x40, /* SPECIFIC_CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x48, /* SPECIFIC_CDM_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE02,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x430, /* SPECIFIC_IFE02_PRIORITYLUT_LOW */
.value = 0x66666543,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x434, /* SPECIFIC_IFE02_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x438, /* SPECIFIC_IFE02_URGENCY_LOW */
/* SPECIFIC_IFE02_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE02_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x440, /* SPECIFIC_IFE02_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x448, /* SPECIFIC_IFE02_SAFELUT_LOW */
.value = 0x1,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x588, /* SPECIFIC_IFE02_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IFE13,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x830, /* SPECIFIC_IFE13_PRIORITYLUT_LOW */
.value = 0x66666543,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x834, /* SPECIFIC_IFE13_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x838, /* SPECIFIC_IFE13_URGENCY_LOW */
/* SPECIFIC_IFE13_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE13_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x840, /* SPECIFIC_IFE13_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x848, /* SPECIFIC_IFE13_SAFELUT_LOW */
.value = 0x1,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x988, /* SPECIFIC_IFE13_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc30, /* SPECIFIC_IBL_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc34, /* SPECIFIC_IBL_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0xc38, /* SPECIFIC_IBL_RD_URGENCY_LOW */
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_MASK */
.mask = 0x7,
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_SHIFT */
.shift = 0x0,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc40, /* SPECIFIC_IBL_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xc48, /* SPECIFIC_IBL_RD_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xd08, /* SPECIFIC_IBL_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1030, /* SPECIFIC_IBL_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1034, /* SPECIFIC_IBL_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x1038, /* SPECIFIC_IBL_WR_URGENCY_LOW */
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1040, /* SPECIFIC_IBL_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1048, /* SPECIFIC_IBL_WR_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1188, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1430, /* SPECIFIC_JPEG_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1434, /* SPECIFIC_JPEG_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1438, /* SPECIFIC_JPEG_URGENCY_LOW */
.value = 0x22,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1440, /* SPECIFIC_JPEG_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1448, /* SPECIFIC_JPEG_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_FD,
.enable = false,
},
{
.port_type = CAM_CAMNOC_ICP,
.enable = true,
.flag_out_set0_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x2088,
.value = 0x100000,
},
},
};
static struct cam_camnoc_err_logger_info cam175_cpas101_err_logger_offsets = {
.mainctrl = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x2720, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x2724, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x2728, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x272c, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x2730, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x2734, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x2738, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x273c, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam175_cpas101_errata_wa_list = {
.camnoc_flush_slave_pending_trans = {
.enable = false,
.data.reg_info = {
.access_type = CAM_REG_TYPE_READ,
.offset = 0x2100, /* SidebandManager_SenseIn0_Low */
.mask = 0xE0000, /* Bits 17, 18, 19 */
.value = 0, /* expected to be 0 */
},
},
};
struct cam_camnoc_fifo_lvl_info cam175_cpas101_camnoc_fifo_info = {
.IFE02_MAXWR_LOW = 0x420,
.IFE13_MAXWR_LOW = 0x820,
};
static struct cam_camnoc_info cam175_cpas101_camnoc_info = {
.specific = &cam_cpas_v175_101_camnoc_specific[0],
.specific_size = sizeof(cam_cpas_v175_101_camnoc_specific) /
sizeof(cam_cpas_v175_101_camnoc_specific[0]),
.irq_sbm = &cam_cpas_v175_101_irq_sbm,
.irq_err = &cam_cpas_v175_101_irq_err[0],
.irq_err_size = sizeof(cam_cpas_v175_101_irq_err) /
sizeof(cam_cpas_v175_101_irq_err[0]),
.err_logger = &cam175_cpas101_err_logger_offsets,
.errata_wa_list = &cam175_cpas101_errata_wa_list,
.fill_lvl_register = &cam175_cpas101_camnoc_fifo_info,
};
#endif /* _CPASTOP_V175_101_H_ */

View file

@ -0,0 +1,828 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP_V175_120_H_
#define _CPASTOP_V175_120_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v175_120_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2240, /* SBM_FAULTINEN0_LOW */
.value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
(TEST_IRQ_ENABLE ?
0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2248, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2280, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v175_120_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = true,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x4F08, /* ERRORLOGGER_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x4F10, /* ERRORLOGGER_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x4F18, /* ERRORLOGGER_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE0_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 = 0x3BA0, /* SPECIFIC_IFE02_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x3B90, /* SPECIFIC_IFE02_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x3B98, /* SPECIFIC_IFE02_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x55a0, /* SPECIFIC_IFE13_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x5590, /* SPECIFIC_IFE13_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x5598, /* SPECIFIC_IFE13_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2F20, /* SPECIFIC_IBL_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2F10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2F18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2Ba0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2B90,
/* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2B98, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = true,
.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2288, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2290, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x100, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2288, /* SBM_FLAGOUTSET0_LOW */
.value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2290, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas_v175_120_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4230, /* SPECIFIC_CDM_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4234, /* SPECIFIC_CDM_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
/* cdm_main_SpecificToNttpTr_Urgency_Low */
.offset = 0x4238,
.mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */
.shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */
.value = 0x2,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4240, /* SPECIFIC_CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4248, /* SPECIFIC_CDM_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE0123_RDI_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC_IFE0123_PRIORITYLUT_LOW */
.offset = 0x3630,
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC_IFE0123_PRIORITYLUT_HIGH */
.offset = 0x3634,
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x3638, /* SPECIFIC_IFE0123_URGENCY_LOW */
/* SPECIFIC_IFE0123_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE0123_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3640, /* SPECIFIC_IFE0123_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3648, /* SPECIFIC_IFE0123_SAFELUT_LOW */
.value = 0xF,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE0_NRDI_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3A30, /* SPECIFIC_IFE0_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3A34, /* SPECIFIC_IFE0_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x3A38, /* SPECIFIC_IFE0_URGENCY_LOW */
/* SPECIFIC_IFE0_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE0_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3A40, /* SPECIFIC_IFE0_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3A48, /* SPECIFIC_IFE0_SAFELUT_LOW */
.value = 0xF,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3B88, /* SPECIFIC_IFE0_ENCCTL_LOW */
.value = 1,
},
},
{
/* IFE0/1 RDI READ PATH */
.port_type = CAM_CAMNOC_IFE01_RDI_READ,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3230, /* SPECIFIC_IFE1_PRIORITYLUT_LOW */
.value = 0x44443333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3234, /* SPECIFIC_IFE1_PRIORITYLUT_HIGH */
.value = 0x66665555,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x3238, /* SPECIFIC_IFE1_URGENCY_LOW */
/* SPECIFIC_IFE1_URGENCY_LOW_WRITE_MASK */
.mask = 0x7,
/* SPECIFIC_IFE1_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x0,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3240, /* SPECIFIC_IFE1_DANGERLUT_LOW */
.value = 0x00000000,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3248, /* SPECIFIC_IFE1_SAFELUT_LOW */
.value = 0xF,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE1_NRDI_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5430, /* SPECIFIC_IFE1_WR_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC_IFE1_WR_PRIORITYLUT_HIGH */
.offset = 0x5434,
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x5438, /* SPECIFIC_IFE1_WR_URGENCY_LOW */
/* SPECIFIC_IFE1_WR_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE1_WR_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x5440, /* SPECIFIC_IFE1_WR_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x5448, /* SPECIFIC_IFE1_WR_SAFELUT_LOW */
.value = 0xF,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5588, /* SPECIFIC_IFE1_WR_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E30, /* SPECIFIC_IBL_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E34, /* SPECIFIC_IBL_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x2E38, /* SPECIFIC_IBL_RD_URGENCY_LOW */
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_MASK */
.mask = 0x7,
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_SHIFT */
.shift = 0x0,
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E40, /* SPECIFIC_IBL_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E48, /* SPECIFIC_IBL_RD_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2F08, /* SPECIFIC_IBL_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2A30, /* SPECIFIC_IBL_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2A34, /* SPECIFIC_IBL_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x2A38, /* SPECIFIC_IBL_WR_URGENCY_LOW */
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2A40, /* SPECIFIC_IBL_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2A48, /* SPECIFIC_IBL_WR_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2B88, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
.value = 0,
},
},
{
.port_type = CAM_CAMNOC_IPE_VID_DISP_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC_IPE_VID_DISP_PRIORITYLUT_LOW */
.offset = 0x5E30,
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC_IPE_VID_DISP_PRIORITYLUT_HIGH */
.offset = 0x5E34,
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
/* SPECIFIC_IPE_VID_DISP_URGENCY_LOW */
.offset = 0x5E38,
/* SPECIFIC_IPE_VID_DISP_URGENCY_LOW_READ_MASK */
.mask = 0x70,
/* SPECIFIC_IPE_VID_DISP_URGENCY_LOW_READ_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC__IPE_VID_DISP_DANGERLUT_LOW */
.offset = 0x5E40,
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC_IPE_VID_DISP_SAFELUT_LOW */
.offset = 0x5E48,
.value = 0x0,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5F88, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2630, /* SPECIFIC_JPEG_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2634, /* SPECIFIC_JPEG_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2638, /* SPECIFIC_JPEG_URGENCY_LOW */
.value = 0x22,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2640, /* SPECIFIC_JPEG_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2648, /* SPECIFIC_JPEG_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_FD,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3E30, /* SPECIFIC_FD_PRIORITYLUT_LOW */
.value = 0x44444444,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3E34, /* SPECIFIC_FD_PRIORITYLUT_HIGH */
.value = 0x44444444,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3E38, /* SPECIFIC_FD_URGENCY_LOW */
.value = 0x44,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3E40, /* SPECIFIC_FD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3E48, /* SPECIFIC_FD_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
/*SidebandManager_main_SidebandManager_FlagOutSet0_Low*/
.port_type = CAM_CAMNOC_ICP,
.enable = true,
.flag_out_set0_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x2288,
.value = 0x100000,
},
},
};
static struct cam_camnoc_err_logger_info cam175_cpas120_err_logger_offsets = {
.mainctrl = 0x4F08, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x4F10, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x4F20, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x4F24, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x4F28, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x4F2c, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x4F30, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x4F34, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x4F38, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x4F3c, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam175_cpas120_errata_wa_list = {
.camnoc_flush_slave_pending_trans = {
.enable = false,
.data.reg_info = {
.access_type = CAM_REG_TYPE_READ,
.offset = 0x2300, /* SidebandManager_SenseIn0_Low */
.mask = 0xE0000, /* Bits 17, 18, 19 */
.value = 0, /* expected to be 0 */
},
},
};
static struct cam_camnoc_fifo_lvl_info cam175_cpas120_camnoc_fifo_info = {
.IFE0_nRDI_maxwr_offset = 0x3A20,
.IFE1_nRDI_maxwr_offset = 0x5420,
.IFE0123_RDI_maxwr_offset = 0x3620,
};
static struct cam_camnoc_info cam175_cpas120_camnoc_info = {
.specific = &cam_cpas_v175_120_camnoc_specific[0],
.specific_size = ARRAY_SIZE(cam_cpas_v175_120_camnoc_specific),
.irq_sbm = &cam_cpas_v175_120_irq_sbm,
.irq_err = &cam_cpas_v175_120_irq_err[0],
.irq_err_size = ARRAY_SIZE(cam_cpas_v175_120_irq_err),
.err_logger = &cam175_cpas120_err_logger_offsets,
.errata_wa_list = &cam175_cpas120_errata_wa_list,
.fill_lvl_register = &cam175_cpas120_camnoc_fifo_info,
};
#endif /* _CPASTOP_V175_120_H_ */

View file

@ -0,0 +1,841 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP_V175_130_H_
#define _CPASTOP_V175_130_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v175_130_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2240, /* SBM_FAULTINEN0_LOW */
.value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
(TEST_IRQ_ENABLE ?
0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2248, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2280, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v175_130_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = true,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x4F08, /* ERRORLOGGER_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x4F10, /* ERRORLOGGER_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x4F18, /* ERRORLOGGER_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE0_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 = 0x3BA0, /* SPECIFIC_IFE0_MAIN_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
/* SPECIFIC_IFE0_MAIN_ENCERRSTATUS_LOW */
.offset = 0x3B90,
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x3B98, /* SPECIFIC_IFE0_MAIN_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x55A0, /* SPECIFIC_IFE1_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
/* SPECIFIC_IFE1_WR_ENCERRSTATUS_LOW */
.offset = 0x5590,
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x5598, /* SPECIFIC_IFE1_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2F20, /* SPECIFIC_IBL_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2F10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2F18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2BA0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2B90,
/* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2B98, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = true,
.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2288, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2290, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x100, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2288, /* SBM_FLAGOUTSET0_LOW */
.value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2290, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas_v175_130_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4230, /* SPECIFIC_CDM_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4234, /* SPECIFIC_CDM_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
/* cdm_main_SpecificToNttpTr_Urgency_Low */
.offset = 0x4238,
.mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */
.shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */
.value = 0x2,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4240, /* SPECIFIC_CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x4248, /* SPECIFIC_CDM_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE0123_RDI_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC_IFE0123_PRIORITYLUT_LOW */
.offset = 0x3630,
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC_IFE0123_PRIORITYLUT_HIGH */
.offset = 0x3634,
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x3638, /* SPECIFIC_IFE0123_URGENCY_LOW */
/* SPECIFIC_IFE0123_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE0123_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3640, /* SPECIFIC_IFE0123_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3648, /* SPECIFIC_IFE0123_SAFELUT_LOW */
.value = 0xF,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE0_NRDI_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3A30, /* SPECIFIC_IFE0_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3A34, /* SPECIFIC_IFE0_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x3A38, /* SPECIFIC_IFE0_URGENCY_LOW */
/* SPECIFIC_IFE0_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE0_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3A40, /* SPECIFIC_IFE0_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3A48, /* SPECIFIC_IFE0_SAFELUT_LOW */
.value = 0xF,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3B88, /* SPECIFIC_IFE0_ENCCTL_LOW */
.value = 1,
},
},
{
/* IFE0/1 RDI READ PATH */
.port_type = CAM_CAMNOC_IFE01_RDI_READ,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3230, /* SPECIFIC_IFE1_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3234, /* SPECIFIC_IFE1_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x3238, /* SPECIFIC_IFE1_URGENCY_LOW */
/* SPECIFIC_IFE1_URGENCY_LOW_WRITE_MASK */
.mask = 0x7,
/* SPECIFIC_IFE1_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x0,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3240, /* SPECIFIC_IFE1_DANGERLUT_LOW */
.value = 0x00000000,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x3248, /* SPECIFIC_IFE1_SAFELUT_LOW */
.value = 0xFFFFFFFF,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE1_NRDI_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5430, /* SPECIFIC_IFE1_WR_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC_IFE1_WR_PRIORITYLUT_HIGH */
.offset = 0x5434,
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x5438, /* SPECIFIC_IFE1_WR_URGENCY_LOW */
/* SPECIFIC_IFE1_WR_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IFE1_WR_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x5440, /* SPECIFIC_IFE1_WR_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x5448, /* SPECIFIC_IFE1_WR_SAFELUT_LOW */
.value = 0xF,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5588, /* SPECIFIC_IFE1_WR_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E30, /* SPECIFIC_IBL_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E34, /* SPECIFIC_IBL_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x2E38, /* SPECIFIC_IBL_RD_URGENCY_LOW */
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_MASK */
.mask = 0x7,
/* SPECIFIC_IBL_RD_URGENCY_LOW_READ_SHIFT */
.shift = 0x0,
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E40, /* SPECIFIC_IBL_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E48, /* SPECIFIC_IBL_RD_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2F08, /* SPECIFIC_IBL_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2A30, /* SPECIFIC_IBL_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2A34, /* SPECIFIC_IBL_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
.offset = 0x2A38, /* SPECIFIC_IBL_WR_URGENCY_LOW */
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_MASK */
.mask = 0x70,
/* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_SHIFT */
.shift = 0x4,
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2A40, /* SPECIFIC_IBL_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2A48, /* SPECIFIC_IBL_WR_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2B88, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
.value = 0,
},
},
{
.port_type = CAM_CAMNOC_IPE_VID_DISP_WRITE,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC_IPE_VID_DISP_PRIORITYLUT_LOW */
.offset = 0x5E30,
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC_IPE_VID_DISP_PRIORITYLUT_HIGH */
.offset = 0x5E34,
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 1,
/* SPECIFIC_IPE_VID_DISP_URGENCY_LOW */
.offset = 0x5E38,
/* SPECIFIC_IPE_VID_DISP_URGENCY_LOW_READ_MASK */
.mask = 0x70,
/* SPECIFIC_IPE_VID_DISP_URGENCY_LOW_READ_SHIFT */
.shift = 0x4,
.value = 3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC__IPE_VID_DISP_DANGERLUT_LOW */
.offset = 0x5E40,
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
/* SPECIFIC_IPE_VID_DISP_SAFELUT_LOW */
.offset = 0x5E48,
.value = 0x0,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x5F88, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2630, /* SPECIFIC_JPEG_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2634, /* SPECIFIC_JPEG_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2638, /* SPECIFIC_JPEG_URGENCY_LOW */
.value = 0x22,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2640, /* SPECIFIC_JPEG_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2648, /* SPECIFIC_JPEG_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_FD,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3E30, /* SPECIFIC_FD_PRIORITYLUT_LOW */
.value = 0x44444444,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3E34, /* SPECIFIC_FD_PRIORITYLUT_HIGH */
.value = 0x44444444,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3E38, /* SPECIFIC_FD_URGENCY_LOW */
.value = 0x44,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3E40, /* SPECIFIC_FD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3E48, /* SPECIFIC_FD_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
/*SidebandManager_main_SidebandManager_FlagOutSet0_Low*/
.port_type = CAM_CAMNOC_ICP,
.enable = true,
.flag_out_set0_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x2288,
.value = 0x100000,
},
},
};
static struct cam_camnoc_err_logger_info cam175_cpas130_err_logger_offsets = {
.mainctrl = 0x4F08, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x4F10, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x4F20, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x4F24, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x4F28, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x4F2c, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x4F30, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x4F34, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x4F38, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x4F3c, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam175_cpas130_errata_wa_list = {
.camnoc_flush_slave_pending_trans = {
.enable = false,
.data.reg_info = {
.access_type = CAM_REG_TYPE_READ,
.offset = 0x2300, /* SidebandManager_SenseIn0_Low */
.mask = 0xE0000, /* Bits 17, 18, 19 */
.value = 0, /* expected to be 0 */
},
},
/* TZ owned register */
.tcsr_camera_hf_sf_ares_glitch = {
.enable = true,
.data.reg_info = {
.enable = true,
.access_type = CAM_REG_TYPE_READ_WRITE,
/* TCSR_CAMERA_HF_SF_ARES_GLITCH_MASK */
.offset = 0x01FCA08C,
.value = 0x4, /* set bit[2] to 1 */
},
},
};
static struct cam_camnoc_fifo_lvl_info cam175_cpas130_camnoc_fifo_info = {
.IFE0_nRDI_maxwr_offset = 0x3A20,
.IFE1_nRDI_maxwr_offset = 0x5420,
.IFE0123_RDI_maxwr_offset = 0x3620,
};
static struct cam_camnoc_info cam175_cpas130_camnoc_info = {
.specific = &cam_cpas_v175_130_camnoc_specific[0],
.specific_size = ARRAY_SIZE(cam_cpas_v175_130_camnoc_specific),
.irq_sbm = &cam_cpas_v175_130_irq_sbm,
.irq_err = &cam_cpas_v175_130_irq_err[0],
.irq_err_size = ARRAY_SIZE(cam_cpas_v175_130_irq_err),
.err_logger = &cam175_cpas130_err_logger_offsets,
.errata_wa_list = &cam175_cpas130_errata_wa_list,
.fill_lvl_register = &cam175_cpas130_camnoc_fifo_info,
};
#endif /* _CPASTOP_V175_130_H_ */

View file

@ -0,0 +1,779 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP_V480_100_H_
#define _CPASTOP_V480_100_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v480_100_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x3840, /* SBM_FAULTINEN0_LOW */
.value = 0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
(TEST_IRQ_ENABLE ?
0x40 : /* SBM_FAULTINEN0_LOW_PORT6_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x3848, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x3880, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x5 : 0x1,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v480_100_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = false,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x7008, /* ERL_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x7010, /* ERL_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x7018, /* ERL_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE_UBWC_STATS_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT1_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x1BA0, /* IFE_UBWC_STATS_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x1B90, /* IFE_UBWC_STATS_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x1B98, /* IFE_UBWC_STATS_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE1_BPS_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 = 0x2520, /* IPE1_BPS_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2510, /* IPE1_BPS_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2518, /* IPE1_BPS_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE0_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x1F20, /* IPE0_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x1F10, /* IPE0_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x1F18, /* IPE0_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x29A0, /* IPE_BPS_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2990,
/* IPE_BPS_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2998, /* IPE_BPS_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = false,
.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x3888, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x3890, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x40, /* SBM_FAULTINSTATUS0_LOW_PORT6_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x3888, /* SBM_FLAGOUTSET0_LOW */
.value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x3890, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas_v480_100_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x30, /* CDM_PRIORITYLUT_LOW */
.value = 0x0,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x34, /* CDM_PRIORITYLUT_HIGH */
.value = 0x0,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x38, /* CDM_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x40, /* CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x48, /* CDM_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_FD,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x630, /* FD_PRIORITYLUT_LOW */
.value = 0x0,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x634, /* FD_PRIORITYLUT_HIGH */
.value = 0x0,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x638, /* FD_URGENCY_LOW */
.value = 0x33,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x640, /* FD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x648, /* FD_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE_LINEAR,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xA30, /* IFE_LINEAR_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xA34, /* IFE_LINEAR_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xA38, /* IFE_LINEAR_URGENCY_LOW */
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0xA40, /* IFE_LINEAR_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0xA48, /* IFE_LINEAR_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,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE_RDI_RD,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1030, /* IFE_RDI_RD_PRIORITYLUT_LOW */
.value = 0x0,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1034, /* IFE_RDI_RD_PRIORITYLUT_HIGH */
.value = 0x0,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1038, /* IFE_RDI_RD_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1040, /* IFE_RDI_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1048, /* IFE_RDI_RD_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,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE_RDI_WR,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1430, /* IFE_RDI_WR_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1434, /* IFE_RDI_WR_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1438, /* IFE_RDI_WR_URGENCY_LOW */
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1440, /* IFE_RDI_WR_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1448, /* IFE_RDI_WR_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,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE_UBWC_STATS,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1A30, /* IFE_UBWC_STATS_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1A34, /* IFE_UBWC_STATS_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1A38, /* IFE_UBWC_STATS_URGENCY_LOW */
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1A40, /* IFE_UBWC_STATS_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1A48, /* IFE_UBWC_STATS_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1B88, /* IFE_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE0_RD,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E30, /* IPE0_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E34, /* IPE0_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E38, /* IPE0_RD_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E40, /* IPE0_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E48, /* IPE0_RD_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1F08, /* IPE0_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE1_BPS_RD,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2430, /* IPE1_BPS_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2434, /* IPE1_BPS_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2438, /* IPE1_BPS_RD_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2440, /* IPE1_BPS_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2448, /* IPE1_BPS_RD_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2508, /* IPE1_BPS_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_WR,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2830, /* IPE_BPS_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2834, /* IPE_BPS_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2838, /* IPE_BPS_WR_URGENCY_LOW */
.value = 0x30,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2840, /* IPE_BPS_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2848, /* IPE_BPS_WR_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2988, /* IPE_BPS_WR_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E30, /* JPEG_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E34, /* JPEG_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E38, /* JPEG_URGENCY_LOW */
.value = 0x22,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E40, /* JPEG_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E48, /* JPEG_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_ICP,
.enable = true,
.flag_out_set0_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x2088,
.value = 0x100000,
},
},
};
static struct cam_camnoc_err_logger_info cam480_cpas100_err_logger_offsets = {
.mainctrl = 0x7008, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x7010, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x7020, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x7024, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x7028, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x702c, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x7030, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x7034, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x7038, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x703c, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam480_cpas100_errata_wa_list = {
.camnoc_flush_slave_pending_trans = {
.enable = false,
.data.reg_info = {
.access_type = CAM_REG_TYPE_READ,
.offset = 0x2100, /* SidebandManager_SenseIn0_Low */
.mask = 0xE0000, /* Bits 17, 18, 19 */
.value = 0, /* expected to be 0 */
},
},
};
struct cam_camnoc_fifo_lvl_info cam480_cpas100_camnoc_fifo_info = {
.ife_linear = 0xA20,
.ife_rdi_wr = 0x1420,
.ife_ubwc_stats = 0x1A20,
};
static struct cam_camnoc_info cam480_cpas100_camnoc_info = {
.specific = &cam_cpas_v480_100_camnoc_specific[0],
.specific_size = ARRAY_SIZE(cam_cpas_v480_100_camnoc_specific),
.irq_sbm = &cam_cpas_v480_100_irq_sbm,
.irq_err = &cam_cpas_v480_100_irq_err[0],
.irq_err_size = ARRAY_SIZE(cam_cpas_v480_100_irq_err),
.err_logger = &cam480_cpas100_err_logger_offsets,
.errata_wa_list = &cam480_cpas100_errata_wa_list,
.fill_lvl_register = &cam480_cpas100_camnoc_fifo_info,
};
#endif /* _CPASTOP_V480_100_H_ */

View file

@ -0,0 +1,772 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP_V480_CUSTOM_H_
#define _CPASTOP_V480_CUSTOM_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v480_custom_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x3840, /* SBM_FAULTINEN0_LOW */
.value = 0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
(TEST_IRQ_ENABLE ?
0x40 : /* SBM_FAULTINEN0_LOW_PORT6_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x3848, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x3880, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x5 : 0x1,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v480_custom_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = false,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x7008, /* ERL_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x7010, /* ERL_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x7018, /* ERL_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE_UBWC_STATS_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT1_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x1BA0, /* IFE_UBWC_STATS_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x1B90, /* IFE_UBWC_STATS_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x1B98, /* IFE_UBWC_STATS_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE1_BPS_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 = 0x2520, /* IPE1_BPS_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2510, /* IPE1_BPS_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2518, /* IPE1_BPS_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE0_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x1F20, /* IPE0_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x1F10, /* IPE0_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x1F18, /* IPE0_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x29A0, /* IPE_BPS_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2990,
/* IPE_BPS_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2998, /* IPE_BPS_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = false,
.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x3888, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x3890, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x40, /* SBM_FAULTINSTATUS0_LOW_PORT6_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x3888, /* SBM_FLAGOUTSET0_LOW */
.value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x3890, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas_v480_custom_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x30, /* CDM_PRIORITYLUT_LOW */
.value = 0x0,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x34, /* CDM_PRIORITYLUT_HIGH */
.value = 0x0,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x38, /* CDM_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x40, /* CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x48, /* CDM_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_FD,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x630, /* FD_PRIORITYLUT_LOW */
.value = 0x0,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x634, /* FD_PRIORITYLUT_HIGH */
.value = 0x0,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x638, /* FD_URGENCY_LOW */
.value = 0x33,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x640, /* FD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x648, /* FD_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE_LINEAR,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xA30, /* IFE_LINEAR_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xA34, /* IFE_LINEAR_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xA38, /* IFE_LINEAR_URGENCY_LOW */
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0xA40, /* IFE_LINEAR_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0xA48, /* IFE_LINEAR_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,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE_RDI_RD,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1030, /* IFE_RDI_RD_PRIORITYLUT_LOW */
.value = 0x0,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1034, /* IFE_RDI_RD_PRIORITYLUT_HIGH */
.value = 0x0,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1038, /* IFE_RDI_RD_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1040, /* IFE_RDI_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1048, /* IFE_RDI_RD_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,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE_RDI_WR,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1430, /* IFE_RDI_WR_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1434, /* IFE_RDI_WR_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1438, /* IFE_RDI_WR_URGENCY_LOW */
.value = 0x1070,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1440, /* IFE_RDI_WR_DANGERLUT_LOW */
.value = 0xFFFFFFF0,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1448, /* IFE_RDI_WR_SAFELUT_LOW */
.value = 0x1,
},
.ubwc_ctl = {
/*
* Do not explicitly set ubwc config register.
* Power on default values are taking care of required
* register settings.
*/
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_IFE_UBWC_STATS,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1A30, /* IFE_UBWC_STATS_PRIORITYLUT_LOW */
.value = 0x66665433,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1A34, /* IFE_UBWC_STATS_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1A38, /* IFE_UBWC_STATS_URGENCY_LOW */
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1A40, /* IFE_UBWC_STATS_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1A48, /* IFE_UBWC_STATS_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1B88, /* IFE_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE0_RD,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E30, /* IPE0_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E34, /* IPE0_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E38, /* IPE0_RD_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E40, /* IPE0_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E48, /* IPE0_RD_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1F08, /* IPE0_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE1_BPS_RD,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2430, /* IPE1_BPS_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2434, /* IPE1_BPS_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2438, /* IPE1_BPS_RD_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2440, /* IPE1_BPS_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2448, /* IPE1_BPS_RD_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2508, /* IPE1_BPS_RD_DECCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_WR,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2830, /* IPE_BPS_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2834, /* IPE_BPS_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2838, /* IPE_BPS_WR_URGENCY_LOW */
.value = 0x30,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2840, /* IPE_BPS_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2848, /* IPE_BPS_WR_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2988, /* IPE_BPS_WR_ENCCTL_LOW */
.value = 1,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E30, /* JPEG_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E34, /* JPEG_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E38, /* JPEG_URGENCY_LOW */
.value = 0x22,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E40, /* JPEG_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E48, /* JPEG_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
},
{
.port_type = CAM_CAMNOC_ICP,
.enable = true,
.flag_out_set0_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x2088,
.value = 0x100000,
},
},
};
static struct cam_camnoc_err_logger_info cam480_custom_err_logger_offsets = {
.mainctrl = 0x7008, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x7010, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x7020, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x7024, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x7028, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x702c, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x7030, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x7034, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x7038, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x703c, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam480_custom_errata_wa_list = {
.camnoc_flush_slave_pending_trans = {
.enable = false,
.data.reg_info = {
.access_type = CAM_REG_TYPE_READ,
.offset = 0x2100, /* SidebandManager_SenseIn0_Low */
.mask = 0xE0000, /* Bits 17, 18, 19 */
.value = 0, /* expected to be 0 */
},
},
};
static struct cam_camnoc_info cam480_custom_camnoc_info = {
.specific = &cam_cpas_v480_custom_camnoc_specific[0],
.specific_size = ARRAY_SIZE(cam_cpas_v480_custom_camnoc_specific),
.irq_sbm = &cam_cpas_v480_custom_irq_sbm,
.irq_err = &cam_cpas_v480_custom_irq_err[0],
.irq_err_size = ARRAY_SIZE(cam_cpas_v480_custom_irq_err),
.err_logger = &cam480_custom_err_logger_offsets,
.errata_wa_list = &cam480_cpas100_errata_wa_list,
};
#endif /* _CPASTOP_V480_CUSTOM_H_ */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,974 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CPASTOP_V570_200_H_
#define _CPASTOP_V570_200_H_
#define TEST_IRQ_ENABLE 0
static struct cam_camnoc_irq_sbm cam_cpas_v570_200_irq_sbm = {
.sbm_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x3840, /* SBM_FAULTINEN0_LOW */
.value = 0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
0x1000 | /* SBM_FAULTINEN0_LOW_PORT12_MASK */
(TEST_IRQ_ENABLE ?
0x40 : /* SBM_FAULTINEN0_LOW_PORT6_MASK */
0x0),
},
.sbm_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x3848, /* SBM_FAULTINSTATUS0_LOW */
},
.sbm_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x3880, /* SBM_FLAGOUTCLR0_LOW */
.value = TEST_IRQ_ENABLE ? 0x5 : 0x1,
}
};
static struct cam_camnoc_irq_err
cam_cpas_v570_200_irq_err[] = {
{
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
.enable = false,
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x7008, /* ERL_MAINCTL_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x7010, /* ERL_ERRVLD_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x7018, /* ERL_ERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IFE_UBWC_STATS_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT1_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x1BA0, /* IFE_UBWC_STATS_0_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x1B90,
/* IFE_UBWC_STATS_0_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x1B98, /* IFE_UBWC_STATS_0_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE1_BPS_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 = 0x2520, /* IPE1_BPS_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2510, /* IPE1_BPS_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2518, /* IPE1_BPS_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE0_UBWC_DECODE_ERROR,
.enable = true,
.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x1F20, /* IPE0_RD_DECERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x1F10, /* IPE0_RD_DECERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x1F18, /* IPE0_RD_DECERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
.enable = true,
.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x29A0, /* IPE_BPS_WR_ENCERREN_LOW */
.value = 1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x2990,
/* IPE_BPS_WR_ENCERRSTATUS_LOW */
},
.err_clear = {
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2998, /* IPE_BPS_WR_ENCERRCLR_LOW */
.value = 1,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
.enable = false,
.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x3888, /* SBM_FLAGOUTSET0_LOW */
.value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x3890, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
.enable = false,
},
{
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
.enable = TEST_IRQ_ENABLE ? true : false,
.sbm_port = 0x40, /* SBM_FAULTINSTATUS0_LOW_PORT6_MASK */
.err_enable = {
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x3888, /* SBM_FLAGOUTSET0_LOW */
.value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
.enable = true,
.offset = 0x3890, /* SBM_FLAGOUTSTATUS0_LOW */
},
.err_clear = {
.enable = false,
},
},
};
static struct cam_camnoc_specific
cam_cpas_v570_200_camnoc_specific[] = {
{
.port_type = CAM_CAMNOC_CDM,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x30, /* CDM_PRIORITYLUT_LOW */
.value = 0x0,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x34, /* CDM_PRIORITYLUT_HIGH */
.value = 0x0,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x38, /* CDM_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x40, /* CDM_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x48, /* CDM_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
.qosgen_mainctl = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x408, /* CDM_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x420, /* CDM_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x424, /* CDM_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_IFE_LINEAR,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xA30, /* IFE_LINEAR_PRIORITYLUT_LOW */
.value = 0x66666666,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xA34, /* IFE_LINEAR_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xA38, /* IFE_LINEAR_URGENCY_LOW */
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0xA40, /* IFE_LINEAR_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0xA48, /* IFE_LINEAR_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,
.is_fuse_based = false,
},
.qosgen_mainctl = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xE08, /* IFE_LINEAR_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xE20, /* IFE_LINEAR_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xE24, /* IFE_LINEAR_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_IFE_RDI_RD,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1030, /* IFE_RDI_RD_PRIORITYLUT_LOW */
.value = 0x0,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1034, /* IFE_RDI_RD_PRIORITYLUT_HIGH */
.value = 0x0,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1038, /* IFE_RDI_RD_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1040, /* IFE_RDI_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1048, /* IFE_RDI_RD_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,
.is_fuse_based = false,
},
.qosgen_mainctl = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xF08, /* IFE_RDI_RD_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xF20, /* IFE_RDI_RD_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xF24, /* IFE_RDI_RD_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_IFE_RDI_WR,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1430, /* IFE_RDI_WR_0_PRIORITYLUT_LOW */
.value = 0x66666666,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1434, /* IFE_RDI_WR_0_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1438, /* IFE_RDI_WR_0_URGENCY_LOW */
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1440, /* IFE_RDI_WR_0_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1448, /* IFE_RDI_WR_0_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,
.is_fuse_based = false,
},
.qosgen_mainctl = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1808, /* IFE_RDI_WR_0_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1820, /* IFE_RDI_WR_0_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1824, /* IFE_RDI_WR_0_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_IFE_UBWC_STATS,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1A30, /* IFE_UBWC_STATS_0_PRIORITYLUT_LOW */
.value = 0x66666666,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1A34,
/* IFE_UBWC_STATS_0_PRIORITYLUT_HIGH */
.value = 0x66666666,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1A38, /* IFE_UBWC_STATS_0_URGENCY_LOW */
.value = 0x1030,
},
.danger_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1A40, /* IFE_UBWC_STATS_0_DANGERLUT_LOW */
.value = 0xFFFFFF00,
},
.safe_lut = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.offset = 0x1A48, /* IFE_UBWC_STATS_0_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1B88, /* IFE_UBWC_STATS_0_ENCCTL_LOW */
.value = 1,
},
.qosgen_mainctl = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1908, /* IFE_UBWC_STATS_0_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1920,
/* IFE_UBWC_STATS_0_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1924,
/* IFE_UBWC_STATS_0_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_IPE0_RD,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E30, /* IPE0_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E34, /* IPE0_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E38, /* IPE0_RD_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E40, /* IPE0_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1E48, /* IPE0_RD_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1F08, /* IPE0_RD_DECCTL_LOW */
.value = 1,
},
.qosgen_mainctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2208, /* IPE0_RD_QOSGEN_MAINCTL */
.value = 0x2,
},
.qosgen_shaping_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2220, /* IPE0_RD_QOSGEN_SHAPING_LOW */
.value = 0x12121212,
},
.qosgen_shaping_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2224, /* IPE0_RD_QOSGEN_SHAPING_HIGH */
.value = 0x12121212,
},
},
{
.port_type = CAM_CAMNOC_IPE1_BPS_RD,
.enable = true,
.priority_lut_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2430, /* IPE1_BPS_RD_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2434, /* IPE1_BPS_RD_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2438, /* IPE1_BPS_RD_URGENCY_LOW */
.value = 0x3,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2440, /* IPE1_BPS_RD_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2448, /* IPE1_BPS_RD_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2508, /* IPE1_BPS_RD_DECCTL_LOW */
.value = 1,
},
.qosgen_mainctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2308, /* IPE1_BPS_RD_QOSGEN_MAINCTL */
.value = 0x2,
},
// TITAN_A_CAMNOC_cam_noc_amm_nrt_niu_0_qosgen_Shaping_Low
.qosgen_shaping_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2320, /* IPE1_BPS_RD_QOSGEN_SHAPING_LOW */
.value = 0x23232323,
},
.qosgen_shaping_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2324, /* IPE1_BPS_RD_QOSGEN_SHAPING_HIGH */
.value = 0x23232323,
},
},
{
.port_type = CAM_CAMNOC_IPE_BPS_WR,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2830, /* IPE_BPS_WR_PRIORITYLUT_LOW */
.value = 0x33333333,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2834, /* IPE_BPS_WR_PRIORITYLUT_HIGH */
.value = 0x33333333,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2838, /* IPE_BPS_WR_URGENCY_LOW */
.value = 0x30,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2840, /* IPE_BPS_WR_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2848, /* IPE_BPS_WR_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,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2988, /* IPE_BPS_WR_ENCCTL_LOW */
.value = 1,
},
.qosgen_mainctl = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2C08, /* IPE_BPS_WR_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2C20, /* IPE_BPS_WR_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2C24, /* IPE_BPS_WR_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
{
.port_type = CAM_CAMNOC_JPEG,
.enable = true,
.priority_lut_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E30, /* JPEG_PRIORITYLUT_LOW */
.value = 0x22222222,
},
.priority_lut_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E34, /* JPEG_PRIORITYLUT_HIGH */
.value = 0x22222222,
},
.urgency = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E38, /* JPEG_URGENCY_LOW */
.value = 0x22,
},
.danger_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E40, /* JPEG_DANGERLUT_LOW */
.value = 0x0,
},
.safe_lut = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2E48, /* JPEG_SAFELUT_LOW */
.value = 0x0,
},
.ubwc_ctl = {
.enable = false,
.is_fuse_based = false,
},
.qosgen_mainctl = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2D08, /* JPEG_QOSGEN_MAINCTL */
.value = 0x2,
},
.qosgen_shaping_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2D20, /* JPEG_QOSGEN_SHAPING_LOW */
.value = 0xA0A0A0A,
},
.qosgen_shaping_high = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x2D24, /* JPEG_QOSGEN_SHAPING_HIGH */
.value = 0xA0A0A0A,
},
},
{
.port_type = CAM_CAMNOC_ICP,
.enable = true,
.flag_out_set0_low = {
.enable = true,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_WRITE,
.masked_value = 0,
.offset = 0x3888,
.value = 0x100000,
},
.qosgen_mainctl = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x3488, /* ICP_QOSGEN_MAINCTL */
.value = 0x0,
},
.qosgen_shaping_low = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x34A0, /* ICP_QOSGEN_SHAPING_LOW */
.value = 0x0,
},
.qosgen_shaping_high = {
.enable = false,
.is_fuse_based = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x34A4, /* ICP_QOSGEN_SHAPING_HIGH */
.value = 0x0,
},
},
};
static struct cam_camnoc_err_logger_info cam570_cpas200_err_logger_offsets = {
.mainctrl = 0x7008, /* ERRLOGGER_MAINCTL_LOW */
.errvld = 0x7010, /* ERRLOGGER_ERRVLD_LOW */
.errlog0_low = 0x7020, /* ERRLOGGER_ERRLOG0_LOW */
.errlog0_high = 0x7024, /* ERRLOGGER_ERRLOG0_HIGH */
.errlog1_low = 0x7028, /* ERRLOGGER_ERRLOG1_LOW */
.errlog1_high = 0x702c, /* ERRLOGGER_ERRLOG1_HIGH */
.errlog2_low = 0x7030, /* ERRLOGGER_ERRLOG2_LOW */
.errlog2_high = 0x7034, /* ERRLOGGER_ERRLOG2_HIGH */
.errlog3_low = 0x7038, /* ERRLOGGER_ERRLOG3_LOW */
.errlog3_high = 0x703c, /* ERRLOGGER_ERRLOG3_HIGH */
};
static struct cam_cpas_hw_errata_wa_list cam570_cpas200_errata_wa_list = {
.camnoc_flush_slave_pending_trans = {
.enable = false,
.data.reg_info = {
.access_type = CAM_REG_TYPE_READ,
.offset = 0x3900, /* sbm_SenseIn0_Low */
.mask = 0xE0000, /* Bits 17, 18, 19 */
.value = 0, /* expected to be 0 */
},
},
};
static struct cam_camnoc_info cam570_cpas200_camnoc_info = {
.specific = &cam_cpas_v570_200_camnoc_specific[0],
.specific_size = ARRAY_SIZE(cam_cpas_v570_200_camnoc_specific),
.irq_sbm = &cam_cpas_v570_200_irq_sbm,
.irq_err = &cam_cpas_v570_200_irq_err[0],
.irq_err_size = ARRAY_SIZE(cam_cpas_v570_200_irq_err),
.err_logger = &cam570_cpas200_err_logger_offsets,
.errata_wa_list = &cam570_cpas200_errata_wa_list,
};
static struct cam_cpas_camnoc_qchannel cam570_cpas200_qchannel_info = {
.qchannel_ctrl = 0x5C,
.qchannel_status = 0x60,
};
#endif /* _CPASTOP_V570_200_H_ */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,753 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CPAS_API_H_
#define _CAM_CPAS_API_H_
#include <linux/device.h>
#include <linux/platform_device.h>
#include <media/cam_cpas.h>
#include "cam_soc_util.h"
#define CAM_HW_IDENTIFIER_LENGTH 128
/* Default AXI Bandwidth vote */
#define CAM_CPAS_DEFAULT_AXI_BW 1024
#define CAM_CPAS_MAX_PATHS_PER_CLIENT 15
#define CAM_CPAS_API_PATH_DATA_STD_START 512
/* Qos Selection mask */
#define CAM_CPAS_QOS_DEFAULT_SETTINGS_MASK 0x1
#define CAM_CPAS_QOS_CUSTOM_SETTINGS_MASK 0x2
/**
* enum cam_cpas_reg_base - Enum for register base identifier. These
* are the identifiers used in generic register
* write/read APIs provided by cpas driver.
*/
enum cam_cpas_reg_base {
CAM_CPAS_REG_CPASTOP,
CAM_CPAS_REG_CAMNOC,
CAM_CPAS_REG_CAMSS,
CAM_CPAS_REG_RPMH,
CAM_CPAS_REG_MAX
};
/**
* enum cam_cpas_hw_index - Enum for identify HW index
*/
enum cam_cpas_hw_index {
CAM_CPAS_HW_IDX_ANY = 0,
CAM_CPAS_HW_IDX_0 = 1<<0,
CAM_CPAS_HW_IDX_1 = 1<<1,
CAM_CPAS_HW_IDX_2 = 1<<2,
CAM_CPAS_HW_IDX_3 = 1<<3,
CAM_CPAS_HW_IDX_4 = 1<<4,
CAM_CPAS_HW_IDX_5 = 1<<5,
CAM_CPAS_HW_IDX_6 = 1<<6,
CAM_CPAS_HW_IDX_7 = 1<<7,
CAM_CPAS_HW_IDX_MAX = 1<<8
};
/**
* enum cam_cpas_camera_version Enum for Titan Camera Versions
*/
enum cam_cpas_camera_version {
CAM_CPAS_CAMERA_VERSION_NONE = 0,
CAM_CPAS_CAMERA_VERSION_150 = 0x00010500,
CAM_CPAS_CAMERA_VERSION_170 = 0x00010700,
CAM_CPAS_CAMERA_VERSION_175 = 0x00010705,
CAM_CPAS_CAMERA_VERSION_480 = 0x00040800,
CAM_CPAS_CAMERA_VERSION_520 = 0x00050200,
CAM_CPAS_CAMERA_VERSION_540 = 0x00050400,
CAM_CPAS_CAMERA_VERSION_580 = 0x00050800,
CAM_CPAS_CAMERA_VERSION_545 = 0x00050405,
CAM_CPAS_CAMERA_VERSION_570 = 0x00050700,
CAM_CPAS_CAMERA_VERSION_680 = 0x00060800,
CAM_CPAS_CAMERA_VERSION_165 = 0x00010605,
CAM_CPAS_CAMERA_VERSION_MAX
};
/**
* enum cam_cpas_version Enum for Titan CPAS Versions
*/
enum cam_cpas_version {
CAM_CPAS_VERSION_NONE = 0,
CAM_CPAS_VERSION_100 = 0x10000000,
CAM_CPAS_VERSION_101 = 0x10000001,
CAM_CPAS_VERSION_110 = 0x10010000,
CAM_CPAS_VERSION_120 = 0x10020000,
CAM_CPAS_VERSION_130 = 0x10030000,
CAM_CPAS_VERSION_200 = 0x20000000,
CAM_CPAS_VERSION_MAX
};
/**
* enum cam_cpas_camera_version_map_id Enum for camera version map id
* This enum is mapped with cam_cpas_camera_version
*/
enum cam_cpas_camera_version_map_id {
CAM_CPAS_CAMERA_VERSION_ID_150 = 0x0,
CAM_CPAS_CAMERA_VERSION_ID_170 = 0x1,
CAM_CPAS_CAMERA_VERSION_ID_175 = 0x2,
CAM_CPAS_CAMERA_VERSION_ID_480 = 0x3,
CAM_CPAS_CAMERA_VERSION_ID_580 = 0x4,
CAM_CPAS_CAMERA_VERSION_ID_520 = 0x5,
CAM_CPAS_CAMERA_VERSION_ID_540 = 0x6,
CAM_CPAS_CAMERA_VERSION_ID_545 = 0x7,
CAM_CPAS_CAMERA_VERSION_ID_570 = 0x8,
CAM_CPAS_CAMERA_VERSION_ID_680 = 0x9,
CAM_CPAS_CAMERA_VERSION_ID_165 = 0xA,
CAM_CPAS_CAMERA_VERSION_ID_MAX
};
/**
* enum cam_cpas_version_map_id Enum for cpas version map id
* This enum is mapped with cam_cpas_version
*/
enum cam_cpas_version_map_id {
CAM_CPAS_VERSION_ID_100 = 0x0,
CAM_CPAS_VERSION_ID_101 = 0x1,
CAM_CPAS_VERSION_ID_110 = 0x2,
CAM_CPAS_VERSION_ID_120 = 0x3,
CAM_CPAS_VERSION_ID_130 = 0x4,
CAM_CPAS_VERSION_ID_200 = 0x5,
CAM_CPAS_VERSION_ID_MAX
};
/**
* enum cam_cpas_hw_version - Enum for Titan CPAS HW Versions
*/
enum cam_cpas_hw_version {
CAM_CPAS_TITAN_NONE = 0,
CAM_CPAS_TITAN_150_V100 = 0x150100,
CAM_CPAS_TITAN_165_V100 = 0x165100,
CAM_CPAS_TITAN_170_V100 = 0x170100,
CAM_CPAS_TITAN_170_V110 = 0x170110,
CAM_CPAS_TITAN_170_V120 = 0x170120,
CAM_CPAS_TITAN_170_V200 = 0x170200,
CAM_CPAS_TITAN_175_V100 = 0x175100,
CAM_CPAS_TITAN_175_V101 = 0x175101,
CAM_CPAS_TITAN_175_V120 = 0x175120,
CAM_CPAS_TITAN_175_V130 = 0x175130,
CAM_CPAS_TITAN_480_V100 = 0x480100,
CAM_CPAS_TITAN_580_V100 = 0x580100,
CAM_CPAS_TITAN_540_V100 = 0x540100,
CAM_CPAS_TITAN_520_V100 = 0x520100,
CAM_CPAS_TITAN_520_V110 = 0x520110,
CAM_CPAS_TITAN_545_V100 = 0x545100,
CAM_CPAS_TITAN_545_V110 = 0x545110,
CAM_CPAS_TITAN_570_V200 = 0x570200,
CAM_CPAS_TITAN_680_V100 = 0x680100,
CAM_CPAS_TITAN_MAX
};
/**
* enum cam_camnoc_irq_type - Enum for camnoc irq types
*
* @CAM_CAMNOC_IRQ_SLAVE_ERROR: Each slave port in CAMNOC (3 QSB ports and
* 1 QHB port) has an error logger. The error
* observed at any slave port is logged into
* the error logger register and an IRQ is
* triggered
* @CAM_CAMNOC_IRQ_IFE_UBWC_ENCODE_ERROR : Triggered if any error detected
* in the IFE UBWC encoder instance
* @CAM_CAMNOC_IRQ_IFE_UBWC_STATS_ENCODE_ERROR: Triggered if any error detected
* in the IFE UBWC-Stats encoder
* instance
* @CAM_CAMNOC_IRQ_IFE02_UBWC_ENCODE_ERROR : Triggered if any error detected
* in the IFE0 UBWC encoder instance
* @CAM_CAMNOC_IRQ_IFE13_UBWC_ENCODE_ERROR : Triggered if any error detected
* in the IFE1 or IFE3 UBWC encoder
* instance
* @CAM_CAMNOC_IRQ_IFE0_UBWC_ENCODE_ERROR : Triggered if any error detected
* in the IFE0 UBWC encoder instance
* @CAM_CAMNOC_IRQ_IFE1_WR_UBWC_ENCODE_ERROR : Triggered if any error detected
* in the IFE1 UBWC encoder
* instance
* @CAM_CAMNOC_IRQ_IPE_UBWC_ENCODE_ERROR : Triggered if any error detected
* in the IPE write path encoder
* instance
* @CAM_CAMNOC_IRQ_BPS_UBWC_ENCODE_ERROR : Triggered if any error detected
* in the BPS write path encoder
* instance
* @CAM_CAMNOC_IRQ_IPE1_BPS_UBWC_DECODE_ERROR: Triggered if any error detected
* in the IPE1/BPS read path decoder
* instance
* @CAM_CAMNOC_IRQ_IPE0_UBWC_DECODE_ERROR : Triggered if any error detected
* in the IPE0 read path decoder
* instance
* @CAM_CAMNOC_IRQ_IPE1_UBWC_DECODE_ERROR : Triggered if any error detected
* in the IPE1 read path decoder
* instance
* @CAM_CAMNOC_IRQ_IPE_BPS_UBWC_DECODE_ERROR: Triggered if any error detected
* in the IPE/BPS UBWC decoder
* instance
* @CAM_CAMNOC_IRQ_IPE_BPS_UBWC_ENCODE_ERROR: Triggered if any error detected
* in the IPE/BPS UBWC encoder
* instance
* @CAM_CAMNOC_IRQ_AHB_TIMEOUT : Triggered when the QHS_ICP slave
* times out after 4000 AHB cycles
*/
enum cam_camnoc_irq_type {
CAM_CAMNOC_IRQ_SLAVE_ERROR,
CAM_CAMNOC_IRQ_IFE_UBWC_ENCODE_ERROR,
CAM_CAMNOC_IRQ_IFE_UBWC_STATS_ENCODE_ERROR,
CAM_CAMNOC_IRQ_IFE_UBWC_STATS_1_ENCODE_ERROR,
CAM_CAMNOC_IRQ_IFE02_UBWC_ENCODE_ERROR,
CAM_CAMNOC_IRQ_IFE13_UBWC_ENCODE_ERROR,
CAM_CAMNOC_IRQ_IFE0_UBWC_ENCODE_ERROR,
CAM_CAMNOC_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR,
CAM_CAMNOC_IRQ_IPE_UBWC_ENCODE_ERROR,
CAM_CAMNOC_IRQ_BPS_UBWC_ENCODE_ERROR,
CAM_CAMNOC_IRQ_IPE1_BPS_UBWC_DECODE_ERROR,
CAM_CAMNOC_IRQ_IPE0_UBWC_DECODE_ERROR,
CAM_CAMNOC_IRQ_IPE1_UBWC_DECODE_ERROR,
CAM_CAMNOC_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
CAM_CAMNOC_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
CAM_CAMNOC_IRQ_AHB_TIMEOUT,
};
/**
* struct cam_camnoc_irq_slave_err_data : Data for Slave error.
*
* @mainctrl : Err logger mainctrl info
* @errvld : Err logger errvld info
* @errlog0_low : Err logger errlog0_low info
* @errlog0_high : Err logger errlog0_high info
* @errlog1_low : Err logger errlog1_low info
* @errlog1_high : Err logger errlog1_high info
* @errlog2_low : Err logger errlog2_low info
* @errlog2_high : Err logger errlog2_high info
* @errlog3_low : Err logger errlog3_low info
* @errlog3_high : Err logger errlog3_high info
*
*/
struct cam_camnoc_irq_slave_err_data {
union {
struct {
uint32_t stall_en : 1; /* bit 0 */
uint32_t fault_en : 1; /* bit 1 */
uint32_t rsv : 30; /* bits 2-31 */
};
uint32_t value;
} mainctrl;
union {
struct {
uint32_t err_vld : 1; /* bit 0 */
uint32_t rsv : 31; /* bits 1-31 */
};
uint32_t value;
} errvld;
union {
struct {
uint32_t loginfo_vld : 1; /* bit 0 */
uint32_t word_error : 1; /* bit 1 */
uint32_t non_secure : 1; /* bit 2 */
uint32_t device : 1; /* bit 3 */
uint32_t opc : 3; /* bits 4 - 6 */
uint32_t rsv0 : 1; /* bit 7 */
uint32_t err_code : 3; /* bits 8 - 10 */
uint32_t sizef : 3; /* bits 11 - 13 */
uint32_t rsv1 : 2; /* bits 14 - 15 */
uint32_t addr_space : 6; /* bits 16 - 21 */
uint32_t rsv2 : 10; /* bits 22 - 31 */
};
uint32_t value;
} errlog0_low;
union {
struct {
uint32_t len1 : 10; /* bits 0 - 9 */
uint32_t rsv : 22; /* bits 10 - 31 */
};
uint32_t value;
} errlog0_high;
union {
struct {
uint32_t path : 16; /* bits 0 - 15 */
uint32_t rsv : 16; /* bits 16 - 31 */
};
uint32_t value;
} errlog1_low;
union {
struct {
uint32_t extid : 18; /* bits 0 - 17 */
uint32_t rsv : 14; /* bits 18 - 31 */
};
uint32_t value;
} errlog1_high;
union {
struct {
uint32_t errlog2_lsb : 32; /* bits 0 - 31 */
};
uint32_t value;
} errlog2_low;
union {
struct {
uint32_t errlog2_msb : 16; /* bits 0 - 16 */
uint32_t rsv : 16; /* bits 16 - 31 */
};
uint32_t value;
} errlog2_high;
union {
struct {
uint32_t errlog3_lsb : 32; /* bits 0 - 31 */
};
uint32_t value;
} errlog3_low;
union {
struct {
uint32_t errlog3_msb : 32; /* bits 0 - 31 */
};
uint32_t value;
} errlog3_high;
};
/**
* struct cam_camnoc_irq_ubwc_enc_data : Data for UBWC Encode error.
*
* @encerr_status : Encode error status
*
*/
struct cam_camnoc_irq_ubwc_enc_data {
union {
struct {
uint32_t encerrstatus : 3; /* bits 0 - 2 */
uint32_t rsv : 29; /* bits 3 - 31 */
};
uint32_t value;
} encerr_status;
};
/**
* struct cam_camnoc_irq_ubwc_dec_data : Data for UBWC Decode error.
*
* @decerr_status : Decoder error status
* @thr_err : Set to 1 if
* At least one of the bflc_len fields in the bit steam exceeds
* its threshold value. This error is possible only for
* RGBA1010102, TP10, and RGB565 formats
* @fcl_err : Set to 1 if
* Fast clear with a legal non-RGB format
* @len_md_err : Set to 1 if
* The calculated burst length does not match burst length
* specified by the metadata value
* @format_err : Set to 1 if
* Illegal format
* 1. bad format :2,3,6
* 2. For 32B MAL, metadata=6
* 3. For 32B MAL RGB565, Metadata != 0,1,7
* 4. For 64B MAL RGB565, metadata[3:1] == 1,2
*
*/
struct cam_camnoc_irq_ubwc_dec_data {
union {
struct {
uint32_t thr_err : 1; /* bit 0 */
uint32_t fcl_err : 1; /* bit 1 */
uint32_t len_md_err : 1; /* bit 2 */
uint32_t format_err : 1; /* bit 3 */
uint32_t rsv : 28; /* bits 4 - 31 */
};
uint32_t value;
} decerr_status;
};
struct cam_camnoc_irq_ahb_timeout_data {
uint32_t data;
};
/**
* struct cam_cpas_irq_data : CAMNOC IRQ data
*
* @irq_type : To identify the type of IRQ
* @u : Union of irq err data information
* @slave_err : Data for Slave error.
* Valid if type is CAM_CAMNOC_IRQ_SLAVE_ERROR
* @enc_err : Data for UBWC Encode error.
* Valid if type is one of below:
* CAM_CAMNOC_IRQ_IFE02_UBWC_ENCODE_ERROR
* CAM_CAMNOC_IRQ_IFE13_UBWC_ENCODE_ERROR
* CAM_CAMNOC_IRQ_IPE_BPS_UBWC_ENCODE_ERROR
* @dec_err : Data for UBWC Decode error.
* Valid if type is CAM_CAMNOC_IRQ_IPE_BPS_UBWC_DECODE_ERROR
* @ahb_err : Data for Slave error.
* Valid if type is CAM_CAMNOC_IRQ_AHB_TIMEOUT
*
*/
struct cam_cpas_irq_data {
enum cam_camnoc_irq_type irq_type;
union {
struct cam_camnoc_irq_slave_err_data slave_err;
struct cam_camnoc_irq_ubwc_enc_data enc_err;
struct cam_camnoc_irq_ubwc_dec_data dec_err;
struct cam_camnoc_irq_ahb_timeout_data ahb_err;
} u;
};
/**
* struct cam_cpas_register_params : Register params for cpas client
*
* @identifier : Input identifier string which is the device label
* from dt like vfe, ife, jpeg etc
* @cell_index : Input integer identifier pointing to the cell index
* from dt of the device. This can be used to form a
* unique string with @identifier like vfe0, ife1,
* jpeg0, etc
* @dev : device handle
* @userdata : Input private data which will be passed as
* an argument while callback.
* @cam_cpas_callback : Input callback pointer for triggering the
* callbacks from CPAS driver.
* @client_handle : CPAS client handle
* @userdata : User data given at the time of register
* @event_type : event type
* @event_data : event data
* @client_handle : Output Unique handle generated for this register
*
*/
struct cam_cpas_register_params {
char identifier[CAM_HW_IDENTIFIER_LENGTH];
uint32_t cell_index;
struct device *dev;
void *userdata;
bool (*cam_cpas_client_cb)(
uint32_t client_handle,
void *userdata,
struct cam_cpas_irq_data *irq_data);
uint32_t client_handle;
};
/**
* enum cam_vote_type - Enum for voting type
*
* @CAM_VOTE_ABSOLUTE : Absolute vote
* @CAM_VOTE_DYNAMIC : Dynamic vote
*/
enum cam_vote_type {
CAM_VOTE_ABSOLUTE,
CAM_VOTE_DYNAMIC,
};
/**
* struct cam_ahb_vote : AHB vote
*
* @type : AHB voting type.
* CAM_VOTE_ABSOLUTE : vote based on the value 'level' is set
* CAM_VOTE_DYNAMIC : vote calculated dynamically using 'freq'
* and 'dev' handle is set
* @level : AHB vote level
* @freq : AHB vote dynamic frequency
*
*/
struct cam_ahb_vote {
enum cam_vote_type type;
union {
enum cam_vote_level level;
unsigned long freq;
} vote;
};
/**
* struct cam_axi_vote : AXI vote
*
* @num_paths: Number of paths on which BW vote is sent to CPAS
* @axi_path: Per path BW vote info
*
*/
struct cam_axi_vote {
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_CPAS_MAX_PATHS_PER_CLIENT];
};
/**
* cam_cpas_register_client()
*
* @brief: API to register cpas client
*
* @register_params: Input params to register as a client to CPAS
*
* @return 0 on success.
*
*/
int cam_cpas_register_client(
struct cam_cpas_register_params *register_params);
/**
* cam_cpas_unregister_client()
*
* @brief: API to unregister cpas client
*
* @client_handle: Client handle to be unregistered
*
* @return 0 on success.
*
*/
int cam_cpas_unregister_client(uint32_t client_handle);
/**
* cam_cpas_start()
*
* @brief: API to start cpas client hw. Clients have to vote for minimal
* bandwidth requirements for AHB, AXI. Use cam_cpas_update_ahb_vote
* to scale bandwidth after start.
*
* @client_handle: client cpas handle
* @ahb_vote : Pointer to ahb vote info
* @axi_vote : Pointer to axi bandwidth vote info
*
* If AXI vote is not applicable to a particular client, use the value exposed
* by CAM_CPAS_DEFAULT_AXI_BW as the default vote request.
*
* @return 0 on success.
*
*/
int cam_cpas_start(
uint32_t client_handle,
struct cam_ahb_vote *ahb_vote,
struct cam_axi_vote *axi_vote);
/**
* cam_cpas_stop()
*
* @brief: API to stop cpas client hw. Bandwidth for AHB, AXI votes
* would be removed for this client on this call. Clients should not
* use cam_cpas_update_ahb_vote or cam_cpas_update_axi_vote
* to remove their bandwidth vote.
*
* @client_handle: client cpas handle
*
* @return 0 on success.
*
*/
int cam_cpas_stop(uint32_t client_handle);
/**
* cam_cpas_update_ahb_vote()
*
* @brief: API to update AHB vote requirement. Use this function only
* between cam_cpas_start and cam_cpas_stop in case clients wants
* to scale to different vote level. Do not use this function to de-vote,
* removing client's vote is implicit on cam_cpas_stop
*
* @client_handle : Client cpas handle
* @ahb_vote : Pointer to ahb vote info
*
* @return 0 on success.
*
*/
int cam_cpas_update_ahb_vote(
uint32_t client_handle,
struct cam_ahb_vote *ahb_vote);
/**
* cam_cpas_update_axi_vote()
*
* @brief: API to update AXI vote requirement. Use this function only
* between cam_cpas_start and cam_cpas_stop in case clients wants
* to scale to different vote level. Do not use this function to de-vote,
* removing client's vote is implicit on cam_cpas_stop
*
* @client_handle : Client cpas handle
* @axi_vote : Pointer to axi bandwidth vote info
*
* @return 0 on success.
*
*/
int cam_cpas_update_axi_vote(
uint32_t client_handle,
struct cam_axi_vote *axi_vote);
/**
* cam_cpas_reg_write()
*
* @brief: API to write a register value in CPAS register space
*
* @client_handle : Client cpas handle
* @reg_base : Register base identifier
* @offset : Offset from the register base address
* @mb : Whether to do reg write with memory barrier
* @value : Value to be written in register
*
* @return 0 on success.
*
*/
int cam_cpas_reg_write(
uint32_t client_handle,
enum cam_cpas_reg_base reg_base,
uint32_t offset,
bool mb,
uint32_t value);
/**
* cam_cpas_reg_read()
*
* @brief: API to read a register value from CPAS register space
*
* @client_handle : Client cpas handle
* @reg_base : Register base identifier
* @offset : Offset from the register base address
* @mb : Whether to do reg read with memory barrier
* @value : Value to be red from register
*
* @return 0 on success.
*
*/
int cam_cpas_reg_read(
uint32_t client_handle,
enum cam_cpas_reg_base reg_base,
uint32_t offset,
bool mb,
uint32_t *value);
/**
* cam_cpas_get_hw_info()
*
* @brief: API to get camera hw information
*
* @camera_family : Camera family type. One of
* CAM_FAMILY_CAMERA_SS
* CAM_FAMILY_CPAS_SS
* @camera_version : Camera platform version
* @cpas_version : Camera cpas version
* @cam_caps : Camera capability
* @cam_fuse_info : Camera fuse info
*
* @return 0 on success.
*
*/
int cam_cpas_get_hw_info(
uint32_t *camera_family,
struct cam_hw_version *camera_version,
struct cam_hw_version *cpas_version,
uint32_t *cam_caps,
struct cam_cpas_fuse_info *cam_fuse_info);
/**
* cam_cpas_get_cpas_hw_version()
*
* @brief: API to get camera cpas hw version
*
* @hw_version : Camera cpas hw version
*
* @return 0 on success.
*
*/
int cam_cpas_get_cpas_hw_version(
uint32_t *hw_version);
/**
* cam_cpas_get_camnoc_fifo_fill_level_info()
*
* @brief: API to get camera camnoc hw version
*
* @cpas_version: hw version
* @client_handle: cpas client handle
*
* @return 0 on success.
*
*/
int cam_cpas_get_camnoc_fifo_fill_level_info(
uint32_t cpas_version,
uint32_t client_handle);
/**
* cam_cpas_is_feature_supported()
*
* @brief: API to get camera features
*
* @flag : Camera hw features to check
*
* @hw_map : To indicate which HWs are supported
*
* @fule_val : Return fule value in case of value type feature
*
* @return 1 if feature is supported
*
*/
bool cam_cpas_is_feature_supported(uint32_t flag, uint32_t hw_map,
uint32_t *fuse_val);
/**
* cam_cpas_axi_util_path_type_to_string()
*
* @brief: API to get string for given path type
*
* @path_data_type : Path type
*
* @return string.
*
*/
const char *cam_cpas_axi_util_path_type_to_string(
uint32_t path_data_type);
/**
* cam_cpas_axi_util_trans_type_to_string()
*
* @brief: API to get string for given transaction type
*
* @path_data_type : Transaction type
*
* @return string.
*
*/
const char *cam_cpas_axi_util_trans_type_to_string(
uint32_t path_data_type);
/**
* cam_cpas_log_votes()
*
* @brief: API to print the all bw votes of axi client. It also print the
* applied camnoc axi clock vote value and ahb vote value
*
* @return 0 on success.
*
*/
void cam_cpas_log_votes(void);
/**
* cam_cpas_select_qos_settings()
*
* @brief: API to select specific qos settings based on usecase requirements
*
* @return 0 on success.
*
*/
int cam_cpas_select_qos_settings(uint32_t selection_mask);
/**
* cam_cpas_notify_event()
*
* @brief: API that clients can notify about their events. CPAS save the event
* and any other useful information related to this event. This will
* be printed while cpas state dump - cam_cpas_log_votes.
* One such example is IFE notifiying SOF or EPOCH to cpas and cpas
* saving axi clock information (camnoc_axi, mnoc_hf) at that point
* and printing latest history on IFE overflow.
*
* @identifier_string: Identifier string passed by caller
* @identifier_value: Identifier value passed by caller
*/
int cam_cpas_notify_event(const char *identifier_string,
int32_t identifier_value);
/*
* cam_cpas_hw_get_camnoc_fill_level_info()
*
* @brief: API to get camnoc info
*
* @cpas_version: cpas hw version
* @client_handle: cpas client handle
*
* @return 0 on success.
*
*/
int cam_cpas_hw_get_camnoc_fill_level_info(
uint32_t cpas_version,
uint32_t client_handle);
#endif /* _CAM_CPAS_API_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,165 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CUSTOM_CONTEXT_H_
#define _CAM_CUSTOM_CONTEXT_H_
#include <linux/spinlock.h>
#include <media/cam_custom.h>
#include <media/cam_defs.h>
#include "cam_context.h"
#include "cam_custom_hw_mgr_intf.h"
/*
* Maximum hw resource - This number is based on the maximum
* output port resource. The current maximum resource number
* is 2.
*/
#define CAM_CUSTOM_DEV_CTX_RES_MAX 1
#define CAM_CUSTOM_CTX_CFG_MAX 8
/* forward declaration */
struct cam_custom_context;
/* cam custom context irq handling function type */
typedef int (*cam_custom_hw_event_cb_func)(
struct cam_custom_context *custom_ctx, void *evt_data);
/**
* enum cam_custom_ctx_activated_substate - sub states for activated
*
*/
enum cam_custom_ctx_activated_substate {
CAM_CUSTOM_CTX_ACTIVATED_SOF,
CAM_CUSTOM_CTX_ACTIVATED_APPLIED,
CAM_CUSTOM_CTX_ACTIVATED_HW_ERROR,
CAM_CUSTOM_CTX_ACTIVATED_HALT,
CAM_CUSTOM_CTX_ACTIVATED_MAX,
};
/**
* struct cam_custom_ctx_irq_ops - Function table for handling IRQ callbacks
*
* @irq_ops: Array of handle function pointers.
*
*/
struct cam_custom_ctx_irq_ops {
cam_custom_hw_event_cb_func irq_ops[CAM_CUSTOM_HW_EVENT_MAX];
};
/**
* struct cam_custom_dev_ctx_req - Custom context request object
*
* @base: Common request object pointer
* @cfg: Custom hardware configuration array
* @num_cfg: Number of custom hardware configuration entries
* @fence_map_out: Output fence mapping array
* @num_fence_map_out: Number of the output fence map
* @fence_map_in: Input fence mapping array
* @num_fence_map_in: Number of input fence map
* @num_acked: Count to track acked entried for output.
* If count equals the number of fence out, it means
* the request has been completed.
* @bubble_report: If bubble recovery is needed
* @bubble_detected: request has bubbled
* @hw_update_data: HW update data for this request
*
*/
struct cam_custom_dev_ctx_req {
struct cam_ctx_request *base;
struct cam_hw_update_entry cfg
[CAM_CUSTOM_CTX_CFG_MAX];
uint32_t num_cfg;
struct cam_hw_fence_map_entry fence_map_out
[CAM_CUSTOM_DEV_CTX_RES_MAX];
uint32_t num_fence_map_out;
struct cam_hw_fence_map_entry fence_map_in
[CAM_CUSTOM_DEV_CTX_RES_MAX];
uint32_t num_fence_map_in;
uint32_t num_acked;
int32_t bubble_report;
bool bubble_detected;
struct cam_custom_prepare_hw_update_data hw_update_data;
};
/**
* struct cam_custom_context - Custom device context
* @base: custom device context object
* @state_machine: state machine for Custom device context
* @state: Common context state
* @hw_ctx: HW object returned by the acquire device command
* @init_received: Indicate whether init config packet is received
* @active_req_cnt: Counter for the active request
* @frame_id: Frame id tracking for the custom context
* @hw_acquired: Flag to indicate if HW is acquired for this context
* @process_bubble: If ctx currently processing bubble
* @substate_actiavted: Current substate for the activated state.
* @substate_machine: Custom substate machine for external interface
* @substate_machine_irq: Custom substate machine for irq handling
* @req_base: common request structure
* @req_custom: custom request structure
*
*/
struct cam_custom_context {
struct cam_context *base;
struct cam_ctx_ops *state_machine;
uint32_t state;
void *hw_ctx;
bool init_received;
uint32_t active_req_cnt;
int64_t frame_id;
bool hw_acquired;
uint32_t substate_activated;
atomic_t process_bubble;
struct cam_ctx_ops *substate_machine;
struct cam_custom_ctx_irq_ops *substate_machine_irq;
struct cam_ctx_request req_base[CAM_CTX_REQ_MAX];
struct cam_custom_dev_ctx_req req_custom[CAM_CTX_REQ_MAX];
};
/**
* cam_custom_dev_context_init()
*
* @brief: Initialization function for the custom context
*
* @ctx: Custom context obj to be initialized
* @bridge_ops: Bridge call back funciton
* @hw_intf: Cust hw manager interface
* @ctx_id: ID for this context
*
*/
int cam_custom_dev_context_init(struct cam_custom_context *ctx,
struct cam_context *ctx_base,
struct cam_req_mgr_kmd_ops *bridge_ops,
struct cam_hw_mgr_intf *hw_intf,
uint32_t ctx_id);
/**
* cam_custom_dev_context_deinit()
*
* @brief: Deinitialize function for the Custom context
*
* @ctx: Custom context obj to be deinitialized
*
*/
int cam_custom_dev_context_deinit(struct cam_custom_context *ctx);
/**
* cam_custom_subdev_close_internal()
*
* @brief: Close function for the Custom context
*
* @sd: Pointer to struct v4l2_subdev
* @fh: Pointer to struct v4l2_subdev_fh
*
*/
int cam_custom_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh);
#endif /* _CAM_CUSTOM_CONTEXT_H_ */

View file

@ -0,0 +1,234 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/ion.h>
#include <linux/iommu.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include <media/cam_req_mgr.h>
#include "cam_custom_dev.h"
#include "cam_hw_mgr_intf.h"
#include "cam_custom_hw_mgr_intf.h"
#include "cam_node.h"
#include "cam_debug_util.h"
#include "cam_smmu_api.h"
#include "camera_main.h"
static struct cam_custom_dev g_custom_dev;
static void cam_custom_dev_iommu_fault_handler(
struct cam_smmu_pf_info *pf_info)
{
int i = 0;
struct cam_node *node = NULL;
if (!pf_info || !pf_info->token) {
CAM_ERR(CAM_CUSTOM, "invalid token in page handler cb");
return;
}
node = (struct cam_node *)pf_info->token;
for (i = 0; i < node->ctx_size; i++)
cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
}
static const struct of_device_id cam_custom_dt_match[] = {
{
.compatible = "qcom,cam-custom"
},
{}
};
static int cam_custom_subdev_open(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
mutex_lock(&g_custom_dev.custom_dev_mutex);
g_custom_dev.open_cnt++;
mutex_unlock(&g_custom_dev.custom_dev_mutex);
return 0;
}
int cam_custom_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
int rc = 0;
struct cam_node *node = v4l2_get_subdevdata(sd);
mutex_lock(&g_custom_dev.custom_dev_mutex);
if (g_custom_dev.open_cnt <= 0) {
CAM_DBG(CAM_CUSTOM, "Custom subdev is already closed");
rc = -EINVAL;
goto end;
}
g_custom_dev.open_cnt--;
if (!node) {
CAM_ERR(CAM_CUSTOM, "Node ptr is NULL");
rc = -EINVAL;
goto end;
}
if (g_custom_dev.open_cnt == 0)
cam_node_shutdown(node);
end:
mutex_unlock(&g_custom_dev.custom_dev_mutex);
return rc;
}
static int cam_custom_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_CUSTOM);
if (crm_active) {
CAM_DBG(CAM_CUSTOM, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_custom_subdev_close_internal(sd, fh);
}
static const struct v4l2_subdev_internal_ops cam_custom_subdev_internal_ops = {
.close = cam_custom_subdev_close,
.open = cam_custom_subdev_open,
};
static int cam_custom_component_bind(struct device *dev,
struct device *master_dev, void *data)
{
int rc = -EINVAL;
int i;
struct cam_hw_mgr_intf hw_mgr_intf;
struct cam_node *node;
int iommu_hdl = -1;
struct platform_device *pdev = to_platform_device(dev);
g_custom_dev.sd.internal_ops = &cam_custom_subdev_internal_ops;
g_custom_dev.sd.close_seq_prior = CAM_SD_CLOSE_HIGH_PRIORITY;
rc = cam_subdev_probe(&g_custom_dev.sd, pdev, CAM_CUSTOM_DEV_NAME,
CAM_CUSTOM_DEVICE_TYPE);
if (rc) {
CAM_ERR(CAM_CUSTOM, "Custom device cam_subdev_probe failed!");
goto err;
}
node = (struct cam_node *) g_custom_dev.sd.token;
memset(&hw_mgr_intf, 0, sizeof(hw_mgr_intf));
rc = cam_custom_hw_mgr_init(pdev->dev.of_node,
&hw_mgr_intf, &iommu_hdl);
if (rc != 0) {
CAM_ERR(CAM_CUSTOM, "Can not initialized Custom HW manager!");
goto unregister;
}
for (i = 0; i < CAM_CUSTOM_HW_MAX_INSTANCES; i++) {
rc = cam_custom_dev_context_init(&g_custom_dev.ctx_custom[i],
&g_custom_dev.ctx[i],
&node->crm_node_intf,
&node->hw_mgr_intf,
i);
if (rc) {
CAM_ERR(CAM_CUSTOM, "Custom context init failed!");
goto unregister;
}
}
rc = cam_node_init(node, &hw_mgr_intf, g_custom_dev.ctx,
CAM_CUSTOM_HW_MAX_INSTANCES, CAM_CUSTOM_DEV_NAME);
if (rc) {
CAM_ERR(CAM_CUSTOM, "Custom HW node init failed!");
goto unregister;
}
cam_smmu_set_client_page_fault_handler(iommu_hdl,
cam_custom_dev_iommu_fault_handler, node);
mutex_init(&g_custom_dev.custom_dev_mutex);
CAM_DBG(CAM_CUSTOM, "%s component bound successfully", pdev->name);
return 0;
unregister:
rc = cam_subdev_remove(&g_custom_dev.sd);
err:
return rc;
}
static void cam_custom_component_unbind(struct device *dev,
struct device *master_dev, void *data)
{
int rc = 0;
int i;
/* clean up resources */
for (i = 0; i < CAM_CUSTOM_HW_MAX_INSTANCES; i++) {
rc = cam_custom_dev_context_deinit(&g_custom_dev.ctx_custom[i]);
if (rc)
CAM_ERR(CAM_CUSTOM,
"Custom context %d deinit failed", i);
}
rc = cam_subdev_remove(&g_custom_dev.sd);
if (rc)
CAM_ERR(CAM_CUSTOM, "Unregister failed");
memset(&g_custom_dev, 0, sizeof(g_custom_dev));
}
const static struct component_ops cam_custom_component_ops = {
.bind = cam_custom_component_bind,
.unbind = cam_custom_component_unbind,
};
static int cam_custom_dev_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &cam_custom_component_ops);
return 0;
}
static int cam_custom_dev_probe(struct platform_device *pdev)
{
int rc = 0;
CAM_DBG(CAM_CUSTOM, "Adding Custom HW component");
rc = component_add(&pdev->dev, &cam_custom_component_ops);
if (rc)
CAM_ERR(CAM_CUSTOM, "failed to add component rc: %d", rc);
return rc;
}
struct platform_driver custom_driver = {
.probe = cam_custom_dev_probe,
.remove = cam_custom_dev_remove,
.driver = {
.name = "cam_custom",
.of_match_table = cam_custom_dt_match,
.suppress_bind_attrs = true,
},
};
int cam_custom_dev_init_module(void)
{
return platform_driver_register(&custom_driver);
}
void cam_custom_dev_exit_module(void)
{
platform_driver_unregister(&custom_driver);
}
MODULE_DESCRIPTION("MSM CUSTOM driver");
MODULE_LICENSE("GPL v2");

View file

@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CUSTOM_DEV_H_
#define _CAM_CUSTOM_DEV_H_
#include "cam_subdev.h"
#include "cam_hw_mgr_intf.h"
#include "cam_custom_hw_mgr.h"
#include "cam_context.h"
#include "cam_custom_context.h"
#define CAM_CUSTOM_HW_MAX_INSTANCES 3
/**
* struct cam_custom_dev - Camera Custom V4l2 device node
*
* @sd: Common camera subdevice node
* @ctx: Custom base context storage
* @ctx_custom: Custom private context storage
* @custom_dev_mutex: Custom dev mutex
* @open_cnt: Open device count
*/
struct cam_custom_dev {
struct cam_subdev sd;
struct cam_context ctx[CAM_CUSTOM_HW_MAX_INSTANCES];
struct cam_custom_context ctx_custom[CAM_CUSTOM_HW_MAX_INSTANCES];
struct mutex custom_dev_mutex;
int32_t open_cnt;
};
/**
* @brief : API to register Custom hw to platform framework.
* @return struct platform_device pointer on on success, or ERR_PTR() on error.
*/
int cam_custom_dev_init_module(void);
/**
* @brief : API to remove Custom hw interface from platform framework.
*/
void cam_custom_dev_exit_module(void);
#endif /* _CAM_CUSTOM_DEV_H_ */

View file

@ -0,0 +1,272 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CUSTOM_CSID_480_H_
#define _CAM_CUSTOM_CSID_480_H_
#include "cam_ife_csid_core.h"
#define CAM_CSID_VERSION_V480 0x40080000
static struct cam_ife_csid_udi_reg_offset
cam_custom_csid_480_udi_0_reg_offset = {
.csid_udi_irq_status_addr = 0x30,
.csid_udi_irq_mask_addr = 0x34,
.csid_udi_irq_clear_addr = 0x38,
.csid_udi_irq_set_addr = 0x3c,
.csid_udi_cfg0_addr = 0x200,
.csid_udi_cfg1_addr = 0x204,
.csid_udi_ctrl_addr = 0x208,
.csid_udi_frm_drop_pattern_addr = 0x20c,
.csid_udi_frm_drop_period_addr = 0x210,
.csid_udi_irq_subsample_pattern_addr = 0x214,
.csid_udi_irq_subsample_period_addr = 0x218,
.csid_udi_rpp_hcrop_addr = 0x21c,
.csid_udi_rpp_vcrop_addr = 0x220,
.csid_udi_rpp_pix_drop_pattern_addr = 0x224,
.csid_udi_rpp_pix_drop_period_addr = 0x228,
.csid_udi_rpp_line_drop_pattern_addr = 0x22c,
.csid_udi_rpp_line_drop_period_addr = 0x230,
.csid_udi_rst_strobes_addr = 0x240,
.csid_udi_status_addr = 0x250,
.csid_udi_misr_val0_addr = 0x254,
.csid_udi_misr_val1_addr = 0x258,
.csid_udi_misr_val2_addr = 0x25c,
.csid_udi_misr_val3_addr = 0x260,
.csid_udi_format_measure_cfg0_addr = 0x270,
.csid_udi_format_measure_cfg1_addr = 0x274,
.csid_udi_format_measure0_addr = 0x278,
.csid_udi_format_measure1_addr = 0x27c,
.csid_udi_format_measure2_addr = 0x280,
.csid_udi_timestamp_curr0_sof_addr = 0x290,
.csid_udi_timestamp_curr1_sof_addr = 0x294,
.csid_udi_timestamp_prev0_sof_addr = 0x298,
.csid_udi_timestamp_prev1_sof_addr = 0x29c,
.csid_udi_timestamp_curr0_eof_addr = 0x2a0,
.csid_udi_timestamp_curr1_eof_addr = 0x2a4,
.csid_udi_timestamp_prev0_eof_addr = 0x2a8,
.csid_udi_timestamp_prev1_eof_addr = 0x2ac,
.csid_udi_err_recovery_cfg0_addr = 0x2b0,
.csid_udi_err_recovery_cfg1_addr = 0x2b4,
.csid_udi_err_recovery_cfg2_addr = 0x2b8,
.csid_udi_multi_vcdt_cfg0_addr = 0x2bc,
.csid_udi_byte_cntr_ping_addr = 0x2e0,
.csid_udi_byte_cntr_pong_addr = 0x2e4,
/* configurations */
.ccif_violation_en = 1,
.overflow_ctrl_en = 0,
};
static struct cam_ife_csid_udi_reg_offset
cam_custom_csid_480_udi_1_reg_offset = {
.csid_udi_irq_status_addr = 0x40,
.csid_udi_irq_mask_addr = 0x44,
.csid_udi_irq_clear_addr = 0x48,
.csid_udi_irq_set_addr = 0x4c,
.csid_udi_cfg0_addr = 0x300,
.csid_udi_cfg1_addr = 0x304,
.csid_udi_ctrl_addr = 0x308,
.csid_udi_frm_drop_pattern_addr = 0x30c,
.csid_udi_frm_drop_period_addr = 0x310,
.csid_udi_irq_subsample_pattern_addr = 0x314,
.csid_udi_irq_subsample_period_addr = 0x318,
.csid_udi_rpp_hcrop_addr = 0x31c,
.csid_udi_rpp_vcrop_addr = 0x320,
.csid_udi_rpp_pix_drop_pattern_addr = 0x324,
.csid_udi_rpp_pix_drop_period_addr = 0x328,
.csid_udi_rpp_line_drop_pattern_addr = 0x32c,
.csid_udi_rpp_line_drop_period_addr = 0x330,
.csid_udi_rst_strobes_addr = 0x340,
.csid_udi_status_addr = 0x350,
.csid_udi_misr_val0_addr = 0x354,
.csid_udi_misr_val1_addr = 0x358,
.csid_udi_misr_val2_addr = 0x35c,
.csid_udi_misr_val3_addr = 0x360,
.csid_udi_format_measure_cfg0_addr = 0x370,
.csid_udi_format_measure_cfg1_addr = 0x374,
.csid_udi_format_measure0_addr = 0x378,
.csid_udi_format_measure1_addr = 0x37c,
.csid_udi_format_measure2_addr = 0x380,
.csid_udi_timestamp_curr0_sof_addr = 0x390,
.csid_udi_timestamp_curr1_sof_addr = 0x394,
.csid_udi_timestamp_prev0_sof_addr = 0x398,
.csid_udi_timestamp_prev1_sof_addr = 0x39c,
.csid_udi_timestamp_curr0_eof_addr = 0x3a0,
.csid_udi_timestamp_curr1_eof_addr = 0x3a4,
.csid_udi_timestamp_prev0_eof_addr = 0x3a8,
.csid_udi_timestamp_prev1_eof_addr = 0x3ac,
.csid_udi_err_recovery_cfg0_addr = 0x3b0,
.csid_udi_err_recovery_cfg1_addr = 0x3b4,
.csid_udi_err_recovery_cfg2_addr = 0x3b8,
.csid_udi_multi_vcdt_cfg0_addr = 0x3bc,
.csid_udi_byte_cntr_ping_addr = 0x3e0,
.csid_udi_byte_cntr_pong_addr = 0x3e4,
/* configurations */
.ccif_violation_en = 1,
.overflow_ctrl_en = 0,
};
static struct cam_ife_csid_udi_reg_offset
cam_custom_csid_480_udi_2_reg_offset = {
.csid_udi_irq_status_addr = 0x50,
.csid_udi_irq_mask_addr = 0x54,
.csid_udi_irq_clear_addr = 0x58,
.csid_udi_irq_set_addr = 0x5c,
.csid_udi_cfg0_addr = 0x400,
.csid_udi_cfg1_addr = 0x404,
.csid_udi_ctrl_addr = 0x408,
.csid_udi_frm_drop_pattern_addr = 0x40c,
.csid_udi_frm_drop_period_addr = 0x410,
.csid_udi_irq_subsample_pattern_addr = 0x414,
.csid_udi_irq_subsample_period_addr = 0x418,
.csid_udi_rpp_hcrop_addr = 0x41c,
.csid_udi_rpp_vcrop_addr = 0x420,
.csid_udi_rpp_pix_drop_pattern_addr = 0x424,
.csid_udi_rpp_pix_drop_period_addr = 0x428,
.csid_udi_rpp_line_drop_pattern_addr = 0x42c,
.csid_udi_rpp_line_drop_period_addr = 0x430,
.csid_udi_yuv_chroma_conversion_addr = 0x434,
.csid_udi_rst_strobes_addr = 0x440,
.csid_udi_status_addr = 0x450,
.csid_udi_misr_val0_addr = 0x454,
.csid_udi_misr_val1_addr = 0x458,
.csid_udi_misr_val2_addr = 0x45c,
.csid_udi_misr_val3_addr = 0x460,
.csid_udi_format_measure_cfg0_addr = 0x470,
.csid_udi_format_measure_cfg1_addr = 0x474,
.csid_udi_format_measure0_addr = 0x478,
.csid_udi_format_measure1_addr = 0x47c,
.csid_udi_format_measure2_addr = 0x480,
.csid_udi_timestamp_curr0_sof_addr = 0x490,
.csid_udi_timestamp_curr1_sof_addr = 0x494,
.csid_udi_timestamp_prev0_sof_addr = 0x498,
.csid_udi_timestamp_prev1_sof_addr = 0x49c,
.csid_udi_timestamp_curr0_eof_addr = 0x4a0,
.csid_udi_timestamp_curr1_eof_addr = 0x4a4,
.csid_udi_timestamp_prev0_eof_addr = 0x4a8,
.csid_udi_timestamp_prev1_eof_addr = 0x4ac,
.csid_udi_err_recovery_cfg0_addr = 0x4b0,
.csid_udi_err_recovery_cfg1_addr = 0x4b4,
.csid_udi_err_recovery_cfg2_addr = 0x4b8,
.csid_udi_multi_vcdt_cfg0_addr = 0x4bc,
.csid_udi_byte_cntr_ping_addr = 0x4e0,
.csid_udi_byte_cntr_pong_addr = 0x4e4,
/* configurations */
.ccif_violation_en = 1,
.overflow_ctrl_en = 0,
};
static struct cam_ife_csid_csi2_rx_reg_offset
cam_custom_csid_480_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 */
.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_de_scramble_cfg0_addr = 0x114,
.csid_csi2_rx_de_scramble_cfg1_addr = 0x118,
.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_lane0_misr_addr = 0x150,
.csid_csi2_rx_lane1_misr_addr = 0x154,
.csid_csi2_rx_lane2_misr_addr = 0x158,
.csid_csi2_rx_lane3_misr_addr = 0x15c,
.csid_csi2_rx_total_pkts_rcvd_addr = 0x160,
.csid_csi2_rx_stats_ecc_addr = 0x164,
.csid_csi2_rx_total_crc_err_addr = 0x168,
.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 = 15,
.csi2_capture_cphy_pkt_dt_shift = 20,
.csi2_capture_cphy_pkt_vc_shift = 26,
.csi2_rx_phy_num_mask = 0x3,
};
static struct cam_ife_csid_common_reg_offset
cam_custom_csid_480_cmn_reg_offset = {
.csid_hw_version_addr = 0x0,
.csid_cfg0_addr = 0x4,
.csid_ctrl_addr = 0x8,
.csid_reset_addr = 0xc,
.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 = 1,
.minor_version = 7,
.version_incr = 0,
.num_udis = 3,
.num_rdis = 0,
.num_pix = 0,
.num_ppp = 0,
.csid_reg_rst_stb = 1,
.csid_rst_stb = 0x1e,
.csid_rst_stb_sw_all = 0x1f,
.path_rst_stb_all = 0x7f,
.path_rst_done_shift_val = 1,
.path_en_shift_val = 31,
.dt_id_shift_val = 27,
.vc_shift_val = 22,
.dt_shift_val = 16,
.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 = 0,
.rdi_irq_mask_all = 0,
.ppp_irq_mask_all = 0,
.udi_irq_mask_all = 0x7FFF,
.measure_en_hbi_vbi_cnt_mask = 0xC,
.format_measure_en_val = 1,
.num_bytes_out_shift_val = 3,
};
static struct cam_ife_csid_reg_offset cam_custom_csid_480_reg_offset = {
.cmn_reg = &cam_custom_csid_480_cmn_reg_offset,
.csi2_reg = &cam_custom_csid_480_csi2_reg_offset,
.ipp_reg = NULL,
.ppp_reg = NULL,
.rdi_reg = {
NULL,
NULL,
NULL,
NULL,
},
.udi_reg = {
&cam_custom_csid_480_udi_0_reg_offset,
&cam_custom_csid_480_udi_1_reg_offset,
&cam_custom_csid_480_udi_2_reg_offset,
},
.tpg_reg = NULL,
};
#endif /*_CAM_IFE_CSID_480_H_ */

View file

@ -0,0 +1,220 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/slab.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include "linux/module.h"
#include "cam_custom_csid_dev.h"
#include "cam_ife_csid_core.h"
#include "cam_hw.h"
#include "cam_hw_intf.h"
#include "cam_custom_csid480.h"
#include "cam_debug_util.h"
#include "camera_main.h"
#define CAM_CUSTOM_CSID_DRV_NAME "custom_csid"
static struct cam_hw_intf *cam_custom_csid_hw_list[CAM_IFE_CSID_HW_NUM_MAX] = {
0, 0, 0, 0};
static char csid_dev_name[16];
static struct cam_ife_csid_hw_info cam_custom_csid480_hw_info = {
.csid_reg = &cam_custom_csid_480_reg_offset,
.hw_dts_version = CAM_CSID_VERSION_V480,
};
static int cam_custom_csid_component_bind(struct device *dev,
struct device *master_dev, void *data)
{
struct cam_hw_intf *csid_hw_intf;
struct cam_hw_info *csid_hw_info;
struct cam_ife_csid_hw *csid_dev = NULL;
const struct of_device_id *match_dev = NULL;
struct cam_ife_csid_hw_info *csid_hw_data = NULL;
uint32_t csid_dev_idx;
int rc = 0;
struct platform_device *pdev = to_platform_device(dev);
csid_hw_intf = kzalloc(sizeof(*csid_hw_intf), GFP_KERNEL);
if (!csid_hw_intf) {
rc = -ENOMEM;
goto err;
}
csid_hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
if (!csid_hw_info) {
rc = -ENOMEM;
goto free_hw_intf;
}
csid_dev = kzalloc(sizeof(struct cam_ife_csid_hw), GFP_KERNEL);
if (!csid_dev) {
rc = -ENOMEM;
goto free_hw_info;
}
/* get custom csid hw index */
of_property_read_u32(pdev->dev.of_node, "cell-index", &csid_dev_idx);
/* get custom csid hw information */
match_dev = of_match_device(pdev->dev.driver->of_match_table,
&pdev->dev);
if (!match_dev) {
CAM_ERR(CAM_CUSTOM,
"No matching table for the CUSTOM CSID HW!");
rc = -EINVAL;
goto free_dev;
}
memset(csid_dev_name, 0, sizeof(csid_dev_name));
snprintf(csid_dev_name, sizeof(csid_dev_name),
"csid-custom%1u", csid_dev_idx);
csid_hw_intf->hw_idx = csid_dev_idx;
csid_hw_intf->hw_type = CAM_ISP_HW_TYPE_IFE_CSID;
csid_hw_intf->hw_priv = csid_hw_info;
csid_hw_info->core_info = csid_dev;
csid_hw_info->soc_info.pdev = pdev;
csid_hw_info->soc_info.dev = &pdev->dev;
csid_hw_info->soc_info.dev_name = csid_dev_name;
csid_hw_info->soc_info.index = csid_dev_idx;
csid_hw_data = (struct cam_ife_csid_hw_info *)match_dev->data;
csid_dev->csid_info = csid_hw_data;
rc = cam_ife_csid_hw_probe_init(csid_hw_intf, csid_dev_idx, true);
if (rc)
goto free_dev;
platform_set_drvdata(pdev, csid_dev);
if (csid_hw_intf->hw_idx < CAM_IFE_CSID_HW_NUM_MAX)
cam_custom_csid_hw_list[csid_hw_intf->hw_idx] = csid_hw_intf;
else
goto free_dev;
CAM_DBG(CAM_CUSTOM, "CSID:%d component bound successfully",
csid_hw_intf->hw_idx);
return 0;
free_dev:
kfree(csid_dev);
free_hw_info:
kfree(csid_hw_info);
free_hw_intf:
kfree(csid_hw_intf);
err:
return rc;
}
static void cam_custom_csid_component_unbind(struct device *dev,
struct device *master_dev, void *data)
{
struct cam_ife_csid_hw *csid_dev = NULL;
struct cam_hw_intf *csid_hw_intf;
struct cam_hw_info *csid_hw_info;
struct platform_device *pdev = to_platform_device(dev);
csid_dev = (struct cam_ife_csid_hw *)platform_get_drvdata(pdev);
csid_hw_intf = csid_dev->hw_intf;
csid_hw_info = csid_dev->hw_info;
CAM_DBG(CAM_CUSTOM, "CSID:%d component unbind",
csid_dev->hw_intf->hw_idx);
cam_ife_csid_hw_deinit(csid_dev);
/*release the csid device memory */
kfree(csid_dev);
kfree(csid_hw_info);
kfree(csid_hw_intf);
}
const static struct component_ops cam_custom_csid_component_ops = {
.bind = cam_custom_csid_component_bind,
.unbind = cam_custom_csid_component_unbind,
};
static int cam_custom_csid_probe(struct platform_device *pdev)
{
int rc = 0;
CAM_DBG(CAM_CUSTOM, "Adding Custom CSID component");
rc = component_add(&pdev->dev, &cam_custom_csid_component_ops);
if (rc)
CAM_ERR(CAM_CUSTOM, "failed to add component rc: %d", rc);
return rc;
}
static int cam_custom_csid_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &cam_custom_csid_component_ops);
return 0;
}
static const struct of_device_id cam_custom_csid_dt_match[] = {
{
.compatible = "qcom,csid-custom480",
.data = &cam_custom_csid480_hw_info
},
{
.compatible = "qcom,csid-custom580",
.data = &cam_custom_csid480_hw_info
},
{}
};
MODULE_DEVICE_TABLE(of, cam_custom_csid_dt_match);
struct platform_driver cam_custom_csid_driver = {
.probe = cam_custom_csid_probe,
.driver = {
.name = "qcom,custom-csid",
.of_match_table = cam_custom_csid_dt_match,
.suppress_bind_attrs = true,
},
.remove = cam_custom_csid_remove,
};
int cam_custom_csid_driver_init(void)
{
int32_t rc = 0;
rc = platform_driver_register(&cam_custom_csid_driver);
if (rc < 0)
CAM_ERR(CAM_CUSTOM, "platform_driver_register Failed: rc = %d",
rc);
return rc;
}
int cam_custom_csid_hw_init(struct cam_hw_intf **custom_csid_hw,
uint32_t hw_idx)
{
int rc = 0;
if (cam_custom_csid_hw_list[hw_idx]) {
*custom_csid_hw = cam_custom_csid_hw_list[hw_idx];
} else {
*custom_csid_hw = NULL;
rc = -1;
}
return rc;
}
void cam_custom_csid_driver_exit(void)
{
platform_driver_unregister(&cam_custom_csid_driver);
}
MODULE_DESCRIPTION("cam_custom_csid_driver");
MODULE_LICENSE("GPL v2");

View file

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CUSTOM_CSID_DEV_H_
#define _CAM_CUSTOM_CSID_DEV_H_
#include "cam_debug_util.h"
#include "cam_custom_hw_mgr_intf.h"
/**
* @brief : API to register Custom CSID hw to platform framework.
* @return struct platform_device pointer on on success, or ERR_PTR() on error.
*/
int cam_custom_csid_driver_init(void);
/**
* @brief : API to remove Custom CSID hw interface from platform framework.
*/
void cam_custom_csid_driver_exit(void);
#endif /*_CAM_CUSTOM_CSID_DEV_H_ */

View file

@ -0,0 +1,335 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/ratelimit.h>
#include "cam_custom_sub_mod_core.h"
int cam_custom_hw_sub_mod_get_hw_caps(void *hw_priv,
void *get_hw_cap_args, uint32_t arg_size)
{
int rc = 0;
if (!hw_priv) {
CAM_ERR(CAM_CUSTOM, "Invalid arguments");
return -EINVAL;
}
/* Add HW Capabilities to be published */
return rc;
}
int cam_custom_hw_sub_mod_init_hw(void *hw_priv,
void *init_hw_args, uint32_t arg_size)
{
struct cam_hw_info *custom_hw = hw_priv;
struct cam_hw_soc_info *soc_info = NULL;
struct cam_custom_resource_node *custom_res = NULL;
int rc = 0;
if (!hw_priv) {
CAM_ERR(CAM_CUSTOM, "Invalid arguments");
return -EINVAL;
}
mutex_lock(&custom_hw->hw_mutex);
custom_hw->open_count++;
if (custom_hw->open_count > 1) {
mutex_unlock(&custom_hw->hw_mutex);
CAM_DBG(CAM_CUSTOM,
"Cam Custom has already been initialized cnt %d",
custom_hw->open_count);
return 0;
}
mutex_unlock(&custom_hw->hw_mutex);
soc_info = &custom_hw->soc_info;
/* Turn ON Regulators, Clocks and other SOC resources */
rc = cam_custom_hw_sub_mod_enable_soc_resources(soc_info);
if (rc) {
CAM_ERR(CAM_CUSTOM, "Enable SOC failed");
rc = -EFAULT;
goto decrement_open_cnt;
}
custom_res = (struct cam_custom_resource_node *)init_hw_args;
if (custom_res && custom_res->init) {
rc = custom_res->init(custom_res, NULL, 0);
if (rc) {
CAM_ERR(CAM_CUSTOM, "init Failed rc=%d", rc);
goto decrement_open_cnt;
}
}
rc = cam_custom_hw_sub_mod_reset(hw_priv, NULL, 0);
if (rc < 0) {
CAM_ERR(CAM_CUSTOM, "Custom HW reset failed : %d", rc);
goto decrement_open_cnt;
}
/* Initialize all resources here */
custom_hw->hw_state = CAM_HW_STATE_POWER_UP;
return rc;
decrement_open_cnt:
mutex_lock(&custom_hw->hw_mutex);
custom_hw->open_count--;
mutex_unlock(&custom_hw->hw_mutex);
return rc;
}
int cam_custom_hw_sub_mod_deinit_hw(void *hw_priv,
void *deinit_hw_args, uint32_t arg_size)
{
struct cam_hw_info *custom_hw = hw_priv;
struct cam_hw_soc_info *soc_info = NULL;
struct cam_custom_resource_node *custom_res = NULL;
int rc = 0;
if (!hw_priv) {
CAM_ERR(CAM_CUSTOM, "Invalid arguments");
return -EINVAL;
}
mutex_lock(&custom_hw->hw_mutex);
if (!custom_hw->open_count) {
mutex_unlock(&custom_hw->hw_mutex);
CAM_ERR(CAM_CUSTOM, "Error! Unbalanced deinit");
return -EFAULT;
}
custom_hw->open_count--;
if (custom_hw->open_count) {
mutex_unlock(&custom_hw->hw_mutex);
CAM_DBG(CAM_CUSTOM,
"open_cnt non-zero =%d", custom_hw->open_count);
return 0;
}
mutex_unlock(&custom_hw->hw_mutex);
soc_info = &custom_hw->soc_info;
custom_res = (struct cam_custom_resource_node *)deinit_hw_args;
if (custom_res && custom_res->deinit) {
rc = custom_res->deinit(custom_res, NULL, 0);
if (rc)
CAM_ERR(CAM_CUSTOM, "deinit failed");
}
rc = cam_custom_hw_sub_mod_reset(hw_priv, NULL, 0);
/* Turn OFF Regulators, Clocks and other SOC resources */
CAM_DBG(CAM_CUSTOM, "Disable SOC resource");
rc = cam_custom_hw_sub_mod_disable_soc_resources(soc_info);
if (rc)
CAM_ERR(CAM_CUSTOM, "Disable SOC failed");
custom_hw->hw_state = CAM_HW_STATE_POWER_DOWN;
return rc;
}
int cam_custom_hw_sub_mod_reset(void *hw_priv,
void *reserve_args, uint32_t arg_size)
{
struct cam_hw_info *custom_hw = hw_priv;
struct cam_hw_soc_info *soc_info = NULL;
int rc = 0;
if (!hw_priv) {
CAM_ERR(CAM_CUSTOM, "Invalid input arguments");
return -EINVAL;
}
soc_info = &custom_hw->soc_info;
/* Do Reset of HW */
return rc;
}
int cam_custom_hw_sub_mod_reserve(void *hw_priv,
void *reserve_args, uint32_t arg_size)
{
int rc = 0;
if (!hw_priv || !reserve_args) {
CAM_ERR(CAM_CUSTOM, "Invalid input arguments");
return -EINVAL;
}
/*Reserve Args */
return rc;
}
int cam_custom_hw_sub_mod_release(void *hw_priv,
void *release_args, uint32_t arg_size)
{
struct cam_hw_info *custom_hw = hw_priv;
int rc = 0;
if (!hw_priv || !release_args) {
CAM_ERR(CAM_CUSTOM, "Invalid input arguments");
return -EINVAL;
}
mutex_lock(&custom_hw->hw_mutex);
/* Release Resources */
mutex_unlock(&custom_hw->hw_mutex);
return rc;
}
int cam_custom_hw_sub_mod_start(void *hw_priv,
void *start_args, uint32_t arg_size)
{
struct cam_hw_info *custom_hw = hw_priv;
int rc = 0;
if (!hw_priv || !start_args) {
CAM_ERR(CAM_CUSTOM, "Invalid input arguments");
return -EINVAL;
}
mutex_lock(&custom_hw->hw_mutex);
/* Start HW -- Stream On*/
mutex_unlock(&custom_hw->hw_mutex);
return rc;
}
int cam_custom_hw_sub_mod_stop(void *hw_priv,
void *stop_args, uint32_t arg_size)
{
struct cam_hw_info *custom_hw = hw_priv;
int rc = 0;
if (!hw_priv || !stop_args) {
CAM_ERR(CAM_CUSTOM, "Invalid input arguments");
return -EINVAL;
}
mutex_lock(&custom_hw->hw_mutex);
/* Stop HW */
mutex_unlock(&custom_hw->hw_mutex);
return rc;
}
int cam_custom_hw_sub_mod_read(void *hw_priv,
void *read_args, uint32_t arg_size)
{
return -EPERM;
}
int cam_custom_hw_sub_mod_write(void *hw_priv,
void *write_args, uint32_t arg_size)
{
return -EPERM;
}
int cam_custom_hw_submit_req(void *hw_priv, void *hw_submit_args,
uint32_t arg_size)
{
struct cam_hw_info *custom_dev = hw_priv;
struct cam_custom_sub_mod_req_to_dev *submit_req =
(struct cam_custom_sub_mod_req_to_dev *)hw_submit_args;
struct cam_custom_sub_mod_core_info *core_info = NULL;
core_info =
(struct cam_custom_sub_mod_core_info *)custom_dev->core_info;
spin_lock(&custom_dev->hw_lock);
if (core_info->curr_req) {
CAM_WARN(CAM_CUSTOM, "Req %lld still processed by %s",
core_info->curr_req->req_id,
custom_dev->soc_info.dev_name);
spin_unlock(&custom_dev->hw_lock);
return -EAGAIN;
}
core_info->curr_req = submit_req;
spin_unlock(&custom_dev->hw_lock);
/* Do other submit procedures */
return 0;
}
irqreturn_t cam_custom_hw_sub_mod_irq(int irq_num, void *data)
{
struct cam_hw_info *custom_dev = data;
struct cam_hw_soc_info *soc_info = NULL;
struct cam_custom_hw_cb_args cb_args;
struct cam_custom_sub_mod_core_info *core_info = NULL;
uint32_t irq_status = 0;
if (!data) {
CAM_ERR(CAM_CUSTOM, "Invalid custom_dev_info");
return IRQ_HANDLED;
}
soc_info = &custom_dev->soc_info;
core_info =
(struct cam_custom_sub_mod_core_info *)custom_dev->core_info;
irq_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
core_info->device_hw_info->irq_status);
cam_io_w_mb(irq_status,
soc_info->reg_map[0].mem_base +
core_info->device_hw_info->irq_clear);
spin_lock(&custom_dev->hw_lock);
core_info->curr_req = NULL;
if (core_info->irq_cb.custom_hw_mgr_cb)
core_info->irq_cb.custom_hw_mgr_cb(
core_info->irq_cb.data, &cb_args);
spin_unlock(&custom_dev->hw_lock);
return IRQ_HANDLED;
}
int cam_custom_hw_sub_mod_process_cmd(void *hw_priv, uint32_t cmd_type,
void *cmd_args, uint32_t arg_size)
{
struct cam_hw_info *hw = hw_priv;
struct cam_hw_soc_info *soc_info = NULL;
struct cam_custom_sub_mod_core_info *core_info = NULL;
unsigned long flag = 0;
int rc = 0;
if (!hw_priv || !cmd_args) {
CAM_ERR(CAM_CUSTOM, "Invalid arguments");
return -EINVAL;
}
soc_info = &hw->soc_info;
core_info = hw->core_info;
/* Handle any custom process cmds */
switch (cmd_type) {
case CAM_CUSTOM_SET_IRQ_CB: {
struct cam_custom_sub_mod_set_irq_cb *irq_cb = cmd_args;
/* This can be deprecated */
CAM_DBG(CAM_CUSTOM, "Setting irq cb");
spin_lock_irqsave(&hw->hw_lock, flag);
core_info->irq_cb.custom_hw_mgr_cb = irq_cb->custom_hw_mgr_cb;
core_info->irq_cb.data = irq_cb->data;
spin_unlock_irqrestore(&hw->hw_lock, flag);
break;
}
case CAM_CUSTOM_SUBMIT_REQ: {
rc = cam_custom_hw_submit_req(hw_priv, cmd_args, arg_size);
break;
}
default:
break;
}
return rc;
}

View file

@ -0,0 +1,81 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CUSTOM_SUB_MOD_CORE_H_
#define _CAM_CUSTOM_SUB_MOD_CORE_H_
#include "cam_debug_util.h"
#include "cam_custom_hw.h"
#include "cam_custom_sub_mod_soc.h"
#include "cam_custom_hw_mgr_intf.h"
struct cam_custom_sub_mod_set_irq_cb {
int32_t (*custom_hw_mgr_cb)(void *data,
struct cam_custom_hw_cb_args *cb_args);
void *data;
};
struct cam_custom_sub_mod_req_to_dev {
uint64_t req_id;
uint32_t ctx_idx;
uint32_t dev_idx;
};
struct cam_custom_device_hw_info {
uint32_t hw_ver;
uint32_t irq_status;
uint32_t irq_mask;
uint32_t irq_clear;
};
struct cam_custom_sub_mod_core_info {
uint32_t cpas_handle;
bool cpas_start;
bool clk_enable;
struct cam_custom_sub_mod_set_irq_cb irq_cb;
struct cam_custom_sub_mod_req_to_dev *curr_req;
struct cam_custom_device_hw_info *device_hw_info;
struct cam_hw_info *custom_hw_info;
};
enum cam_custom_hw_resource_type {
CAM_CUSTOM_HW_RESOURCE_UNINT,
CAM_CUSTOM_HW_RESOURCE_SRC,
CAM_CUSTOM_HW_RESOURCE_MAX,
};
struct cam_custom_sub_mod_acq {
enum cam_custom_hw_resource_type rsrc_type;
int32_t acq;
cam_hw_mgr_event_cb_func event_cb;
void *priv;
struct cam_custom_resource_node *rsrc_node;
};
int cam_custom_hw_sub_mod_get_hw_caps(void *hw_priv,
void *get_hw_cap_args, uint32_t arg_size);
int cam_custom_hw_sub_mod_init_hw(void *hw_priv,
void *init_hw_args, uint32_t arg_size);
int cam_custom_hw_sub_mod_deinit_hw(void *hw_priv,
void *deinit_hw_args, uint32_t arg_size);
int cam_custom_hw_sub_mod_reset(void *hw_priv,
void *deinit_hw_args, uint32_t arg_size);
int cam_custom_hw_sub_mod_reserve(void *hw_priv,
void *reserve_args, uint32_t arg_size);
int cam_custom_hw_sub_mod_release(void *hw_priv,
void *release_args, uint32_t arg_size);
int cam_custom_hw_sub_mod_start(void *hw_priv,
void *start_args, uint32_t arg_size);
int cam_custom_hw_sub_mod_stop(void *hw_priv,
void *stop_args, uint32_t arg_size);
int cam_custom_hw_sub_mod_read(void *hw_priv,
void *read_args, uint32_t arg_size);
int cam_custom_hw_sub_mod_write(void *hw_priv,
void *write_args, uint32_t arg_size);
int cam_custom_hw_sub_mod_process_cmd(void *hw_priv, uint32_t cmd_type,
void *cmd_args, uint32_t arg_size);
irqreturn_t cam_custom_hw_sub_mod_irq(int irq_num, void *data);
#endif /* _CAM_CUSTOM_SUB_MOD_CORE_H_ */

View file

@ -0,0 +1,188 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/slab.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include "cam_custom_sub_mod_dev.h"
#include "cam_custom_sub_mod_core.h"
#include "cam_custom_sub_mod_soc.h"
#include "cam_debug_util.h"
#include "camera_main.h"
static struct cam_hw_intf *cam_custom_hw_sub_mod_list
[CAM_CUSTOM_SUB_MOD_MAX_INSTANCES] = {0, 0};
static char cam_custom_hw_sub_mod_name[8];
struct cam_custom_device_hw_info cam_custom_hw_info = {
.hw_ver = 0x0,
.irq_status = 0x0,
.irq_mask = 0x0,
.irq_clear = 0x0,
};
EXPORT_SYMBOL(cam_custom_hw_info);
int cam_custom_hw_sub_mod_init(struct cam_hw_intf **custom_hw, uint32_t hw_idx)
{
int rc = 0;
if (cam_custom_hw_sub_mod_list[hw_idx]) {
*custom_hw = cam_custom_hw_sub_mod_list[hw_idx];
rc = 0;
} else {
*custom_hw = NULL;
rc = -ENODEV;
}
return 0;
}
static int cam_custom_hw_sub_mod_component_bind(struct device *dev,
struct device *master_dev, void *data)
{
struct cam_hw_info *hw = NULL;
struct cam_hw_intf *hw_intf = NULL;
struct cam_custom_sub_mod_core_info *core_info = NULL;
int rc = 0;
struct platform_device *pdev = to_platform_device(dev);
hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
if (!hw_intf)
return -ENOMEM;
of_property_read_u32(pdev->dev.of_node,
"cell-index", &hw_intf->hw_idx);
hw = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
if (!hw) {
rc = -ENOMEM;
goto free_hw_intf;
}
memset(cam_custom_hw_sub_mod_name, 0,
sizeof(cam_custom_hw_sub_mod_name));
snprintf(cam_custom_hw_sub_mod_name, sizeof(cam_custom_hw_sub_mod_name),
"custom_hw%1u", hw_intf->hw_idx);
hw->soc_info.pdev = pdev;
hw->soc_info.dev = &pdev->dev;
hw->soc_info.dev_name = cam_custom_hw_sub_mod_name;
hw_intf->hw_priv = hw;
hw_intf->hw_ops.get_hw_caps = cam_custom_hw_sub_mod_get_hw_caps;
hw_intf->hw_ops.init = cam_custom_hw_sub_mod_init_hw;
hw_intf->hw_ops.deinit = cam_custom_hw_sub_mod_deinit_hw;
hw_intf->hw_ops.reset = cam_custom_hw_sub_mod_reset;
hw_intf->hw_ops.reserve = cam_custom_hw_sub_mod_reserve;
hw_intf->hw_ops.release = cam_custom_hw_sub_mod_release;
hw_intf->hw_ops.start = cam_custom_hw_sub_mod_start;
hw_intf->hw_ops.stop = cam_custom_hw_sub_mod_stop;
hw_intf->hw_ops.read = cam_custom_hw_sub_mod_read;
hw_intf->hw_ops.write = cam_custom_hw_sub_mod_write;
hw_intf->hw_ops.process_cmd = cam_custom_hw_sub_mod_process_cmd;
hw_intf->hw_type = CAM_CUSTOM_HW_TYPE_1;
platform_set_drvdata(pdev, hw_intf);
hw->core_info = kzalloc(sizeof(struct cam_custom_sub_mod_core_info),
GFP_KERNEL);
if (!hw->core_info) {
CAM_DBG(CAM_CUSTOM, "Failed to alloc for core");
rc = -ENOMEM;
goto free_hw;
}
core_info = (struct cam_custom_sub_mod_core_info *)hw->core_info;
core_info->custom_hw_info = hw;
rc = cam_custom_hw_sub_mod_init_soc_resources(&hw->soc_info,
cam_custom_hw_sub_mod_irq, hw);
if (rc < 0) {
CAM_ERR(CAM_CUSTOM, "Failed to init soc rc=%d", rc);
goto free_core_info;
}
/* Initialize HW */
hw->hw_state = CAM_HW_STATE_POWER_DOWN;
mutex_init(&hw->hw_mutex);
spin_lock_init(&hw->hw_lock);
init_completion(&hw->hw_complete);
if (hw_intf->hw_idx < CAM_CUSTOM_HW_SUB_MOD_MAX)
cam_custom_hw_sub_mod_list[hw_intf->hw_idx] = hw_intf;
/* needs to be invoked when custom hw is in place */
//cam_custom_hw_sub_mod_init_hw(hw, NULL, 0);
CAM_DBG(CAM_CUSTOM, "HW idx:%d component bound successfully",
hw_intf->hw_idx);
return rc;
free_core_info:
kfree(hw->core_info);
free_hw:
kfree(hw);
free_hw_intf:
kfree(hw_intf);
return rc;
}
static void cam_custom_hw_sub_mod_component_unbind(
struct device *dev, struct device *master_dev, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
CAM_DBG(CAM_CUSTOM, "Unbinding component: %s", pdev->name);
}
const static struct component_ops cam_custom_hw_sub_mod_component_ops = {
.bind = cam_custom_hw_sub_mod_component_bind,
.unbind = cam_custom_hw_sub_mod_component_unbind,
};
int cam_custom_hw_sub_mod_probe(struct platform_device *pdev)
{
int rc = 0;
CAM_DBG(CAM_CUSTOM, "Adding Custom HW sub module component");
rc = component_add(&pdev->dev, &cam_custom_hw_sub_mod_component_ops);
if (rc)
CAM_ERR(CAM_CUSTOM, "failed to add component rc: %d", rc);
return rc;
}
static const struct of_device_id cam_custom_hw_sub_mod_dt_match[] = {
{
.compatible = "qcom,cam_custom_hw_sub_mod",
.data = &cam_custom_hw_info,
},
{}
};
MODULE_DEVICE_TABLE(of, cam_custom_hw_sub_mod_dt_match);
struct platform_driver cam_custom_hw_sub_mod_driver = {
.probe = cam_custom_hw_sub_mod_probe,
.driver = {
.name = CAM_CUSTOM_SUB_MOD_NAME,
.of_match_table = cam_custom_hw_sub_mod_dt_match,
.suppress_bind_attrs = true,
},
};
int cam_custom_hw_sub_module_init(void)
{
return platform_driver_register(&cam_custom_hw_sub_mod_driver);
}
void cam_custom_hw_sub_module_exit(void)
{
platform_driver_unregister(&cam_custom_hw_sub_mod_driver);
}
MODULE_DESCRIPTION("CAM CUSTOM HW SUB MODULE driver");
MODULE_LICENSE("GPL v2");

View file

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CUSTOM_SUB_MOD_DEV_H_
#define _CAM_CUSTOM_SUB_MOD_DEV_H_
#include "cam_custom_hw_mgr_intf.h"
#define CAM_CUSTOM_SUB_MOD_NAME "cam_custom_sub_mod"
#define CAM_CUSTOM_SUB_MOD_MAX_INSTANCES 2
/**
* @brief : API to register Custom submodule to platform framework.
* @return struct platform_device pointer on on success, or ERR_PTR() on error.
*/
int cam_custom_hw_sub_module_init(void);
/**
* @brief : API to remove Custom submodule interface from platform framework.
*/
void cam_custom_hw_sub_module_exit(void);
#endif /* _CAM_CUSTOM_SUB_MOD_DEV_H_ */

View file

@ -0,0 +1,174 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/slab.h>
#include "cam_cpas_api.h"
#include "cam_custom_sub_mod_soc.h"
#include "cam_debug_util.h"
int cam_custom_hw_sub_mod_init_soc_resources(struct cam_hw_soc_info *soc_info,
irq_handler_t irq_handler, void *irq_data)
{
int rc = 0;
struct cam_custom_hw_soc_private *soc_private = NULL;
struct cam_cpas_register_params cpas_register_param;
rc = cam_soc_util_get_dt_properties(soc_info);
if (rc < 0) {
CAM_ERR(CAM_CUSTOM,
"Error! Get DT properties failed rc=%d", rc);
/* For Test Purposes */
return 0;
}
soc_private = kzalloc(sizeof(struct cam_custom_hw_soc_private),
GFP_KERNEL);
if (!soc_private) {
CAM_DBG(CAM_CUSTOM, "Error! soc_private Alloc Failed");
return -ENOMEM;
}
soc_info->soc_private = soc_private;
rc = cam_soc_util_request_platform_resource(soc_info, irq_handler,
irq_data);
if (rc < 0) {
CAM_ERR(CAM_CUSTOM,
"Error! Request platform resources failed rc=%d", rc);
return rc;
}
memset(&cpas_register_param, 0, sizeof(cpas_register_param));
strlcpy(cpas_register_param.identifier, "custom",
CAM_HW_IDENTIFIER_LENGTH);
cpas_register_param.cell_index = soc_info->index;
cpas_register_param.dev = soc_info->dev;
cpas_register_param.cam_cpas_client_cb = NULL;
cpas_register_param.userdata = soc_info;
rc = cam_cpas_register_client(&cpas_register_param);
if (rc < 0)
goto release_soc;
soc_private->cpas_handle =
cpas_register_param.client_handle;
rc = cam_cpas_select_qos_settings(CAM_CPAS_QOS_CUSTOM_SETTINGS_MASK);
if (rc) {
CAM_ERR(CAM_CPAS, "Custom QoS selection failed %d", rc);
goto unregister_cpas;
}
return rc;
unregister_cpas:
if (cam_cpas_unregister_client(soc_private->cpas_handle))
CAM_ERR(CAM_CUSTOM, "CPAS0 unregistration failed");
release_soc:
if (cam_soc_util_release_platform_resource(soc_info))
CAM_ERR(CAM_CUSTOM, "CPAS0 release resource failed");
return rc;
}
int cam_custom_hw_sub_mod_deinit_soc_resources(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
struct cam_custom_hw_soc_private *soc_private = NULL;
if (!soc_info) {
CAM_ERR(CAM_CUSTOM, "Error! soc_info NULL");
return -ENODEV;
}
soc_private = soc_info->soc_private;
if (!soc_private) {
CAM_ERR(CAM_CUSTOM, "Error! soc_private NULL");
return -ENODEV;
}
rc = cam_cpas_unregister_client(soc_private->cpas_handle);
if (rc)
CAM_ERR(CAM_CUSTOM, "CPAS0 unregistration failed rc=%d", rc);
rc = cam_soc_util_release_platform_resource(soc_info);
if (rc < 0)
CAM_ERR(CAM_CUSTOM,
"Error! Release platform resources failed rc=%d", rc);
kfree(soc_private);
return rc;
}
int cam_custom_hw_sub_mod_enable_soc_resources(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
struct cam_custom_hw_soc_private *soc_private = soc_info->soc_private;
struct cam_ahb_vote ahb_vote;
struct cam_axi_vote axi_vote = {0};
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_LOWSVS_VOTE;
axi_vote.num_paths = 2;
axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_READ;
axi_vote.axi_path[0].camnoc_bw = 7200000;
axi_vote.axi_path[0].mnoc_ab_bw = 7200000;
axi_vote.axi_path[0].mnoc_ib_bw = 7200000;
axi_vote.axi_path[1].path_data_type = CAM_AXI_PATH_DATA_ALL;
axi_vote.axi_path[1].transac_type = CAM_AXI_TRANSACTION_WRITE;
axi_vote.axi_path[1].camnoc_bw = 512000000;
axi_vote.axi_path[1].mnoc_ab_bw = 512000000;
axi_vote.axi_path[1].mnoc_ib_bw = 512000000;
rc = cam_cpas_start(soc_private->cpas_handle, &ahb_vote, &axi_vote);
if (rc) {
CAM_ERR(CAM_CUSTOM, "Error! CPAS0 start failed rc=%d", rc);
rc = -EFAULT;
goto end;
}
rc = cam_soc_util_enable_platform_resource(soc_info, true,
CAM_TURBO_VOTE, true);
if (rc) {
CAM_ERR(CAM_CUSTOM, "Error! enable platform failed rc=%d", rc);
goto stop_cpas;
}
return 0;
stop_cpas:
cam_cpas_stop(soc_private->cpas_handle);
end:
return rc;
}
int cam_custom_hw_sub_mod_disable_soc_resources(
struct cam_hw_soc_info *soc_info)
{
int rc = 0;
struct cam_custom_hw_soc_private *soc_private;
if (!soc_info) {
CAM_ERR(CAM_CUSTOM, "Error! Invalid params");
rc = -EINVAL;
return rc;
}
soc_private = soc_info->soc_private;
rc = cam_soc_util_disable_platform_resource(soc_info, true, true);
if (rc) {
CAM_ERR(CAM_CUSTOM, "Disable platform failed rc=%d", rc);
return rc;
}
rc = cam_cpas_stop(soc_private->cpas_handle);
if (rc) {
CAM_ERR(CAM_CUSTOM, "Error! CPAS stop failed rc=%d", rc);
return rc;
}
return rc;
}

View file

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CUSTOM_HW_SUB_MOD_SOC_H_
#define _CAM_CUSTOM_HW_SUB_MOD_SOC_H_
#include "cam_soc_util.h"
/*
* struct cam_custom_hw_soc_private:
*
* @Brief: Private SOC data specific to Custom HW Driver
*
* @cpas_handle: Handle returned on registering with CPAS driver.
* This handle is used for all further interface
* with CPAS.
*/
struct cam_custom_hw_soc_private {
uint32_t cpas_handle;
};
int cam_custom_hw_sub_mod_init_soc_resources(struct cam_hw_soc_info *soc_info,
irq_handler_t irq_handler, void *irq_data);
int cam_custom_hw_sub_mod_deinit_soc_resources(
struct cam_hw_soc_info *soc_info);
int cam_custom_hw_sub_mod_enable_soc_resources(
struct cam_hw_soc_info *soc_info);
int cam_custom_hw_sub_mod_disable_soc_resources(
struct cam_hw_soc_info *soc_info);
#endif /* _CAM_CUSTOM_HW_SUB_MOD_SOC_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,185 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CUSTOM_HW_MGR_H_
#define _CAM_CUSTOM_HW_MGR_H_
#include <linux/completion.h>
#include "cam_custom_hw_mgr_intf.h"
#include "cam_custom_sub_mod_core.h"
#include "cam_ife_csid_hw_intf.h"
#include "cam_isp_hw.h"
#include "cam_custom_hw.h"
#include <media/cam_defs.h>
#include <media/cam_custom.h>
enum cam_custom_hw_mgr_res_type {
CAM_CUSTOM_HW_SUB_MODULE,
CAM_CUSTOM_CID_HW,
CAM_CUSTOM_CSID_HW,
CAM_CUSTOM_HW_MAX,
};
/* Needs to be suitably defined */
#define CAM_CUSTOM_HW_OUT_RES_MAX 1
/**
* struct cam_custom_hw_mgr_res - HW resources for the Custom manager
*
* @list: used by the resource list
* @res_type: Custom manager resource type
* @res_id: resource id based on the resource type for root or
* leaf resource, it matches the KMD interface port id.
* For branch resource, it is defined by the Custom HW
* layer
* @rsrc_node: isp hw layer resource for csid/cid
* @hw_res: hw layer resource array.
*/
struct cam_custom_hw_mgr_res {
struct list_head list;
enum cam_custom_hw_mgr_res_type res_type;
uint32_t res_id;
void *rsrc_node;
struct cam_custom_resource_node *hw_res;
};
/**
* struct ctx_base_info - Base hardware information for the context
*
* @idx: Base resource index
*
*/
struct ctx_base_info {
uint32_t idx;
};
/**
* struct cam_custom_hw_mgr_ctx - Custom HW manager ctx object
*
* @list: used by the ctx list.
* @ctx_index: acquired context id.
* @hw_mgr: Custom hw mgr which owns this context
* @ctx_in_use: flag to tell whether context is active
* @res_list_custom_csid: custom csid modules for this context
* @res_list_custom_cid: custom cid modules for this context
* @sub_hw_list: HW submodules for this context
* @free_res_list: Free resources list for the branch node
* @res_pool: memory storage for the free resource list
* @base: device base index array contain the all
* Custom HW instance associated with this ctx.
* @num_base: number of valid base data in the base array
* @init_done: indicate whether init hw is done
* @event_cb: event_cb to ctx
* @scratch_buffer_addr: scratch buffer address
* @task_type: Custom HW task type
* @cb_priv: data sent back with event_cb
*
*/
struct cam_custom_hw_mgr_ctx {
struct list_head list;
uint32_t ctx_index;
struct cam_custom_hw_mgr *hw_mgr;
uint32_t ctx_in_use;
struct list_head res_list_custom_csid;
struct list_head res_list_custom_cid;
struct cam_custom_hw_mgr_res sub_hw_list[
CAM_CUSTOM_HW_RES_MAX];
struct list_head free_res_list;
struct cam_custom_hw_mgr_res res_pool[CAM_CUSTOM_HW_RES_MAX];
struct ctx_base_info base[CAM_CUSTOM_HW_SUB_MOD_MAX];
uint32_t num_base;
bool init_done;
cam_hw_event_cb_func event_cb;
uint64_t scratch_buffer_addr;
enum cam_custom_hw_task_type task_type;
void *cb_priv;
};
/**
* struct cam_custom_hw_mgr - Custom HW Manager
*
* @img_iommu_hdl: iommu handle
* @custom_hw: Custom device instances array. This will be filled by
* HW layer during initialization
* @csid_devices: Custom csid device instance array
* @ctx_mutex: mutex for the hw context pool
* @free_ctx_list: free hw context list
* @used_ctx_list: used hw context list
* @ctx_pool: context storage
*
*/
struct cam_custom_hw_mgr {
int img_iommu_hdl;
struct cam_hw_intf *custom_hw[CAM_CUSTOM_HW_SUB_MOD_MAX];
struct cam_hw_intf *csid_devices[CAM_CUSTOM_CSID_HW_MAX];
struct mutex ctx_mutex;
struct list_head free_ctx_list;
struct list_head used_ctx_list;
struct cam_custom_hw_mgr_ctx ctx_pool[CAM_CTX_MAX];
};
/**
* cam_custom_hw_mgr_init()
*
* @brief: Initialize the Custom hardware manger. This is the
* etnry functinon for the Cust HW manager.
*
* @of_node: Device node
* @hw_mgr_intf: Custom hardware manager object returned
* @iommu_hdl: Iommu handle to be returned
*
*/
int cam_custom_hw_mgr_init(struct device_node *of_node,
struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl);
/* Utility APIs */
/**
* cam_custom_hw_mgr_get_custom_res_state()
*
* @brief: Obtain equivalent custom rsrc state
* from isp rsrc state
*
* @in_rsrc_state: isp rsrc state
*
*/
enum cam_custom_hw_resource_state
cam_custom_hw_mgr_get_custom_res_state(
uint32_t in_rsrc_state);
/**
* cam_custom_hw_mgr_get_isp_res_state()
*
* @brief: Obtain equivalent isp rsrc state
* from custom rsrc state
*
* @in_rsrc_state: custom rsrc state
*
*/
enum cam_isp_resource_state
cam_custom_hw_mgr_get_isp_res_state(
uint32_t in_rsrc_state);
/**
* cam_custom_hw_mgr_get_isp_res_type()
*
* @brief: Obtain equivalent isp rsrc type
* from custom rsrc type
*
* @res_type: custom rsrc type
*
*/
enum cam_isp_resource_type
cam_custom_hw_mgr_get_isp_res_type(
enum cam_custom_hw_mgr_res_type res_type);
#endif /* _CAM_CUSTOM_HW_MGR_H_ */

View file

@ -0,0 +1,80 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CUSTOM_HW_H_
#define _CAM_CUSTOM_HW_H_
#include <linux/of.h>
#include <linux/time.h>
#include <linux/list.h>
#include <media/cam_custom.h>
enum cam_custom_hw_resource_state {
CAM_CUSTOM_HW_RESOURCE_STATE_UNAVAILABLE = 0,
CAM_CUSTOM_HW_RESOURCE_STATE_AVAILABLE = 1,
CAM_CUSTOM_HW_RESOURCE_STATE_RESERVED = 2,
CAM_CUSTOM_HW_RESOURCE_STATE_INIT_HW = 3,
CAM_CUSTOM_HW_RESOURCE_STATE_STREAMING = 4,
};
enum cam_custom_hw_task_type {
CAM_CUSTOM_EVENT_INVALID,
CAM_CUSTOM_EVENT_TASK1,
CAM_CUSTOM_EVENT_TASK2,
CAM_CUSTOM_EVENT_TASK3,
CAM_CUSTOM_EVENT_MAX,
};
/*
* struct cam_custom_hw_event_info:
*
* @Brief: Structure to pass event details to hw mgr
*
* @task_type: Type of CUSTOM HW Task
* @err_type: Error type if any
*
*/
struct cam_custom_hw_event_info {
enum cam_custom_hw_task_type task_type;
uint32_t err_type;
};
/*
* struct cam_custom_resource_node:
*
* @Brief: Structure representing HW resource object
*
* @res_id: Unique resource ID within res_type objects
* for a particular HW
* @res_state: State of the resource
* @hw_intf: HW Interface of HW to which this resource
* belongs
* @res_priv: Private data of the resource
* @irq_handle: handle returned on subscribing for IRQ event
* @init: function pointer to init the HW resource
* @deinit: function pointer to deinit the HW resource
* @start: function pointer to start the HW resource
* @stop: function pointer to stop the HW resource
* @process_cmd: function pointer for processing commands
* specific to the resource
*/
struct cam_custom_resource_node {
uint32_t res_id;
enum cam_custom_hw_resource_state res_state;
struct cam_hw_intf *hw_intf;
void *res_priv;
int irq_handle;
int (*init)(struct cam_custom_resource_node *rsrc_node,
void *init_args, uint32_t arg_size);
int (*deinit)(struct cam_custom_resource_node *rsrc_node,
void *deinit_args, uint32_t arg_size);
int (*start)(struct cam_custom_resource_node *rsrc_node);
int (*stop)(struct cam_custom_resource_node *rsrc_node);
int (*process_cmd)(struct cam_custom_resource_node *rsrc_node,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size);
};
#endif /* _CAM_CUSTOM_HW_H_ */

View file

@ -0,0 +1,172 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CUSTOM_HW_MGR_INTF_H_
#define _CAM_CUSTOM_HW_MGR_INTF_H_
#include <linux/of.h>
#include <linux/time.h>
#include <linux/list.h>
#include <media/cam_custom.h>
#include "cam_hw.h"
#include "cam_hw_mgr_intf.h"
#include "cam_hw_intf.h"
#include "cam_custom_hw.h"
#define CAM_CUSTOM_HW_TYPE_1 1
#define CAM_CUSTOM_HW_RES_MAX 32
#define CAM_CUSTOM_HW_SUB_MOD_MAX 1
#define CAM_CUSTOM_CSID_HW_MAX 1
enum cam_custom_hw_event_type {
CAM_CUSTOM_HW_EVENT_ERROR,
CAM_CUSTOM_HW_EVENT_RUP_DONE,
CAM_CUSTOM_HW_EVENT_FRAME_DONE,
CAM_CUSTOM_HW_EVENT_MAX
};
enum cam_custom_cmd_types {
CAM_CUSTOM_CMD_NONE,
CAM_CUSTOM_SET_IRQ_CB,
CAM_CUSTOM_SUBMIT_REQ,
};
enum cam_custom_hw_mgr_cmd {
CAM_CUSTOM_HW_MGR_CMD_NONE,
CAM_CUSTOM_HW_MGR_PROG_DEFAULT_CONFIG,
};
/**
* struct cam_custom_hw_cmd_args - Payload for hw manager command
*
* @cmd_type HW command type
* @reserved any other required data
*/
struct cam_custom_hw_cmd_args {
uint32_t cmd_type;
uint32_t reserved;
};
/**
* struct cam_custom_hw_sof_event_data - Event payload for CAM_HW_EVENT_SOF
*
* @timestamp: Time stamp for the sof event
* @boot_time: Boot time stamp for the sof event
*
*/
struct cam_custom_hw_sof_event_data {
uint64_t timestamp;
uint64_t boot_time;
};
/**
* struct cam_custom_hw_reg_update_event_data - Event payload for
* CAM_HW_EVENT_REG_UPDATE
*
* @timestamp: Time stamp for the reg update event
*
*/
struct cam_custom_hw_reg_update_event_data {
uint64_t timestamp;
};
/**
* struct cam_custom_hw_done_event_data - Event payload for CAM_HW_EVENT_DONE
*
* @num_handles: Number of resource handeles
* @resource_handle: Resource handle array
*
*/
struct cam_custom_hw_done_event_data {
uint32_t num_handles;
uint32_t resource_handle[CAM_NUM_OUT_PER_COMP_IRQ_MAX];
};
/**
* struct cam_custom_hw_error_event_data - Event payload for CAM_HW_EVENT_ERROR
*
* @error_type: Error type for the error event
* @timestamp: Timestamp for the error event
*/
struct cam_custom_hw_error_event_data {
uint32_t error_type;
uint64_t timestamp;
};
/**
* struct cam_custom_stop_args - hardware stop arguments
*
* @stop_only Send stop only to hw drivers. No Deinit to be
* done.
*/
struct cam_custom_stop_args {
bool stop_only;
};
/**
* struct cam_custom_start_args - custom hardware start arguments
*
* @hw_config: Hardware configuration commands.
* @start_only Send start only to hw drivers. No init to
* be done.
*
*/
struct cam_custom_start_args {
struct cam_hw_config_args hw_config;
bool start_only;
};
/**
* struct cam_custom_prepare_hw_update_data - hw prepare data
*
* @packet_opcode_type: Packet header opcode in the packet header
* this opcode defines, packet is init packet or
* update packet
* @buffer_addr: IO Buffer address
*
*/
struct cam_custom_prepare_hw_update_data {
uint32_t packet_opcode_type;
uint32_t num_cfg;
uint64_t io_addr[CAM_PACKET_MAX_PLANES];
};
/**
* struct cam_custom_hw_cb_args : HW manager callback args
*
* @res_type : resource type
* @err_type : error type
*/
struct cam_custom_hw_cb_args {
uint32_t res_type;
uint32_t err_type;
};
/**
* cam_custom_hw_sub_mod_init()
*
* @Brief: Initialize Custom HW device
*
* @custom_hw: cust_hw interface to fill in and return on
* successful initialization
* @hw_idx: Index of Custom HW
*/
int cam_custom_hw_sub_mod_init(struct cam_hw_intf **custom_hw, uint32_t hw_idx);
/**
* cam_custom_csid_hw_init()
*
* @Brief: Initialize Custom HW device
*
* @custom_hw: cust_hw interface to fill in and return on
* successful initialization
* @hw_idx: Index of Custom HW
*/
int cam_custom_csid_hw_init(
struct cam_hw_intf **custom_hw, uint32_t hw_idx);
#endif /* _CAM_CUSTOM_HW_MGR_INTF_H_ */

View file

@ -0,0 +1,287 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include "cam_debug_util.h"
#include "cam_fd_context.h"
#include "cam_trace.h"
static const char fd_dev_name[] = "cam-fd";
/* Functions in Available state */
static int __cam_fd_ctx_acquire_dev_in_available(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd)
{
int rc;
rc = cam_context_acquire_dev_to_hw(ctx, cmd);
if (rc) {
CAM_ERR(CAM_FD, "Failed in Acquire dev, rc=%d", rc);
return rc;
}
ctx->state = CAM_CTX_ACQUIRED;
trace_cam_context_state("FD", ctx);
return rc;
}
/* Functions in Acquired state */
static int __cam_fd_ctx_release_dev_in_acquired(struct cam_context *ctx,
struct cam_release_dev_cmd *cmd)
{
int rc;
rc = cam_context_release_dev_to_hw(ctx, cmd);
if (rc) {
CAM_ERR(CAM_FD, "Failed in Release dev, rc=%d", rc);
return rc;
}
ctx->state = CAM_CTX_AVAILABLE;
trace_cam_context_state("FD", ctx);
return rc;
}
static int __cam_fd_ctx_config_dev_in_acquired(struct cam_context *ctx,
struct cam_config_dev_cmd *cmd)
{
int rc;
rc = cam_context_prepare_dev_to_hw(ctx, cmd);
if (rc) {
CAM_ERR(CAM_FD, "Failed in Prepare dev, rc=%d", rc);
return rc;
}
return rc;
}
static int __cam_fd_ctx_start_dev_in_acquired(struct cam_context *ctx,
struct cam_start_stop_dev_cmd *cmd)
{
int rc;
rc = cam_context_start_dev_to_hw(ctx, cmd);
if (rc) {
CAM_ERR(CAM_FD, "Failed in Start dev, rc=%d", rc);
return rc;
}
ctx->state = CAM_CTX_ACTIVATED;
trace_cam_context_state("FD", ctx);
return rc;
}
/* Functions in Activated state */
static int __cam_fd_ctx_stop_dev_in_activated(struct cam_context *ctx,
struct cam_start_stop_dev_cmd *cmd)
{
int rc;
rc = cam_context_stop_dev_to_hw(ctx);
if (rc) {
CAM_ERR(CAM_FD, "Failed in Stop dev, rc=%d", rc);
return rc;
}
ctx->state = CAM_CTX_ACQUIRED;
trace_cam_context_state("FD", ctx);
return rc;
}
static int __cam_fd_ctx_release_dev_in_activated(struct cam_context *ctx,
struct cam_release_dev_cmd *cmd)
{
int rc;
rc = __cam_fd_ctx_stop_dev_in_activated(ctx, NULL);
if (rc) {
CAM_ERR(CAM_FD, "Failed in Stop dev, rc=%d", rc);
return rc;
}
rc = __cam_fd_ctx_release_dev_in_acquired(ctx, cmd);
if (rc) {
CAM_ERR(CAM_FD, "Failed in Release dev, rc=%d", rc);
return rc;
}
return rc;
}
static int __cam_fd_ctx_dump_dev_in_activated(
struct cam_context *ctx,
struct cam_dump_req_cmd *cmd)
{
int rc;
rc = cam_context_dump_dev_to_hw(ctx, cmd);
if (rc)
CAM_ERR(CAM_FD, "Failed to dump device, rc=%d", rc);
return rc;
}
static int __cam_fd_ctx_flush_dev_in_activated(struct cam_context *ctx,
struct cam_flush_dev_cmd *cmd)
{
int rc;
rc = cam_context_flush_dev_to_hw(ctx, cmd);
if (rc)
CAM_ERR(CAM_ICP, "Failed to flush device, rc=%d", rc);
return rc;
}
static int __cam_fd_ctx_config_dev_in_activated(
struct cam_context *ctx, struct cam_config_dev_cmd *cmd)
{
int rc;
rc = cam_context_prepare_dev_to_hw(ctx, cmd);
if (rc) {
CAM_ERR(CAM_FD, "Failed in Prepare dev, rc=%d", rc);
return rc;
}
return rc;
}
static int __cam_fd_ctx_handle_irq_in_activated(void *context,
uint32_t evt_id, void *evt_data)
{
int rc;
rc = cam_context_buf_done_from_hw(context, evt_data, evt_id);
if (rc) {
CAM_ERR(CAM_FD, "Failed in buf done, rc=%d", rc);
return rc;
}
return rc;
}
static int __cam_fd_shutdown_dev(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
int rc = -EINVAL;
if (!sd || !fh) {
CAM_ERR(CAM_FD, "Invalid input pointer");
return rc;
}
return cam_fd_dev_close_internal(sd, fh);
}
/* top state machine */
static struct cam_ctx_ops
cam_fd_ctx_state_machine[CAM_CTX_STATE_MAX] = {
/* Uninit */
{
.ioctl_ops = {},
.crm_ops = {},
.irq_ops = NULL,
},
/* Available */
{
.ioctl_ops = {
.acquire_dev = __cam_fd_ctx_acquire_dev_in_available,
.shutdown_dev = __cam_fd_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
},
/* Acquired */
{
.ioctl_ops = {
.release_dev = __cam_fd_ctx_release_dev_in_acquired,
.config_dev = __cam_fd_ctx_config_dev_in_acquired,
.start_dev = __cam_fd_ctx_start_dev_in_acquired,
.shutdown_dev = __cam_fd_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
},
/* Ready */
{
.ioctl_ops = {
.shutdown_dev = __cam_fd_shutdown_dev,
},
.crm_ops = {},
.irq_ops = NULL,
},
/* Flushed */
{
.ioctl_ops = {
.shutdown_dev = __cam_fd_shutdown_dev,
},
},
/* Activated */
{
.ioctl_ops = {
.stop_dev = __cam_fd_ctx_stop_dev_in_activated,
.release_dev = __cam_fd_ctx_release_dev_in_activated,
.config_dev = __cam_fd_ctx_config_dev_in_activated,
.flush_dev = __cam_fd_ctx_flush_dev_in_activated,
.dump_dev = __cam_fd_ctx_dump_dev_in_activated,
.shutdown_dev = __cam_fd_shutdown_dev,
},
.crm_ops = {},
.irq_ops = __cam_fd_ctx_handle_irq_in_activated,
},
};
int cam_fd_context_init(struct cam_fd_context *fd_ctx,
struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf,
uint32_t ctx_id)
{
int rc;
if (!base_ctx || !fd_ctx) {
CAM_ERR(CAM_FD, "Invalid Context %pK %pK", base_ctx, fd_ctx);
return -EINVAL;
}
memset(fd_ctx, 0, sizeof(*fd_ctx));
rc = cam_context_init(base_ctx, fd_dev_name, CAM_FD, ctx_id,
NULL, hw_intf, fd_ctx->req_base, CAM_CTX_REQ_MAX);
if (rc) {
CAM_ERR(CAM_FD, "Camera Context Base init failed, rc=%d", rc);
return rc;
}
fd_ctx->base = base_ctx;
base_ctx->ctx_priv = fd_ctx;
base_ctx->state_machine = cam_fd_ctx_state_machine;
return rc;
}
int cam_fd_context_deinit(struct cam_fd_context *fd_ctx)
{
int rc = 0;
if (!fd_ctx || !fd_ctx->base) {
CAM_ERR(CAM_FD, "Invalid inputs %pK", fd_ctx);
return -EINVAL;
}
rc = cam_context_deinit(fd_ctx->base);
if (rc)
CAM_ERR(CAM_FD, "Error in base deinit, rc=%d", rc);
memset(fd_ctx, 0, sizeof(*fd_ctx));
return rc;
}

View file

@ -0,0 +1,41 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_FD_CONTEXT_H_
#define _CAM_FD_CONTEXT_H_
#include "cam_context.h"
#include "cam_context_utils.h"
#include "cam_hw_mgr_intf.h"
#include "cam_req_mgr_interface.h"
/**
* struct cam_fd_context - Face Detection context information
*
* @base : Base context pointer for this FD context
* @req_base : List of base requests for this FD context
*/
struct cam_fd_context {
struct cam_context *base;
struct cam_ctx_request req_base[CAM_CTX_REQ_MAX];
};
int cam_fd_context_init(struct cam_fd_context *fd_ctx,
struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf,
uint32_t ctx_id);
int cam_fd_context_deinit(struct cam_fd_context *ctx);
/**
* cam_fd_dev_close_internal()
*
* @brief: Close function for the fd dev
*
* @sd: Pointer to struct v4l2_subdev
* @fh: Pointer to struct v4l2_subdev_fh
*/
int cam_fd_dev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh);
#endif /* _CAM_FD_CONTEXT_H_ */

View file

@ -0,0 +1,249 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include "cam_subdev.h"
#include "cam_node.h"
#include "cam_fd_context.h"
#include "cam_fd_hw_mgr.h"
#include "cam_fd_hw_mgr_intf.h"
#include "camera_main.h"
#define CAM_FD_DEV_NAME "cam-fd"
/**
* struct cam_fd_dev - FD device information
*
* @sd: Subdev information
* @base_ctx: List of base contexts
* @fd_ctx: List of FD contexts
* @lock: Mutex handle
* @open_cnt: FD subdev open count
* @probe_done: Whether FD probe is completed
*/
struct cam_fd_dev {
struct cam_subdev sd;
struct cam_context base_ctx[CAM_CTX_MAX];
struct cam_fd_context fd_ctx[CAM_CTX_MAX];
struct mutex lock;
uint32_t open_cnt;
bool probe_done;
};
static struct cam_fd_dev g_fd_dev;
static int cam_fd_dev_open(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_fd_dev *fd_dev = &g_fd_dev;
if (!fd_dev->probe_done) {
CAM_ERR(CAM_FD, "FD Dev not initialized, fd_dev=%pK", fd_dev);
return -ENODEV;
}
mutex_lock(&fd_dev->lock);
fd_dev->open_cnt++;
CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt);
mutex_unlock(&fd_dev->lock);
return 0;
}
static int cam_fd_dev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct cam_fd_dev *fd_dev = &g_fd_dev;
struct cam_node *node = v4l2_get_subdevdata(sd);
if (!fd_dev->probe_done) {
CAM_ERR(CAM_FD, "FD Dev not initialized, fd_dev=%pK", fd_dev);
return -ENODEV;
}
mutex_lock(&fd_dev->lock);
if (fd_dev->open_cnt == 0) {
CAM_WARN(CAM_FD, "device already closed");
mutex_unlock(&fd_dev->lock);
return 0;
}
fd_dev->open_cnt--;
CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt);
mutex_unlock(&fd_dev->lock);
if (!node) {
CAM_ERR(CAM_FD, "Node ptr is NULL");
return -EINVAL;
}
cam_node_shutdown(node);
return 0;
}
static int cam_fd_dev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
bool crm_active = cam_req_mgr_is_open(CAM_FD);
if (crm_active) {
CAM_DBG(CAM_FD, "CRM is ACTIVE, close should be from CRM");
return 0;
}
return cam_fd_dev_close_internal(sd, fh);
}
static const struct v4l2_subdev_internal_ops cam_fd_subdev_internal_ops = {
.open = cam_fd_dev_open,
.close = cam_fd_dev_close,
};
static int cam_fd_dev_component_bind(struct device *dev,
struct device *master_dev, void *data)
{
int rc;
int i;
struct cam_hw_mgr_intf hw_mgr_intf;
struct cam_node *node;
struct platform_device *pdev = to_platform_device(dev);
g_fd_dev.sd.internal_ops = &cam_fd_subdev_internal_ops;
g_fd_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
/* Initialize the v4l2 subdevice first. (create cam_node) */
rc = cam_subdev_probe(&g_fd_dev.sd, pdev, CAM_FD_DEV_NAME,
CAM_FD_DEVICE_TYPE);
if (rc) {
CAM_ERR(CAM_FD, "FD cam_subdev_probe failed, rc=%d", rc);
return rc;
}
node = (struct cam_node *) g_fd_dev.sd.token;
rc = cam_fd_hw_mgr_init(pdev->dev.of_node, &hw_mgr_intf);
if (rc) {
CAM_ERR(CAM_FD, "Failed in initializing FD HW manager, rc=%d",
rc);
goto unregister_subdev;
}
for (i = 0; i < CAM_CTX_MAX; i++) {
rc = cam_fd_context_init(&g_fd_dev.fd_ctx[i],
&g_fd_dev.base_ctx[i], &node->hw_mgr_intf, i);
if (rc) {
CAM_ERR(CAM_FD, "FD context init failed i=%d, rc=%d",
i, rc);
goto deinit_ctx;
}
}
rc = cam_node_init(node, &hw_mgr_intf, g_fd_dev.base_ctx, CAM_CTX_MAX,
CAM_FD_DEV_NAME);
if (rc) {
CAM_ERR(CAM_FD, "FD node init failed, rc=%d", rc);
goto deinit_ctx;
}
mutex_init(&g_fd_dev.lock);
g_fd_dev.probe_done = true;
CAM_DBG(CAM_FD, "Component bound successfully");
return 0;
deinit_ctx:
for (--i; i >= 0; i--) {
if (cam_fd_context_deinit(&g_fd_dev.fd_ctx[i]))
CAM_ERR(CAM_FD, "FD context %d deinit failed", i);
}
unregister_subdev:
if (cam_subdev_remove(&g_fd_dev.sd))
CAM_ERR(CAM_FD, "Failed in subdev remove");
return rc;
}
static void cam_fd_dev_component_unbind(struct device *dev,
struct device *master_dev, void *data)
{
int i, rc;
struct platform_device *pdev = to_platform_device(dev);
for (i = 0; i < CAM_CTX_MAX; i++) {
rc = cam_fd_context_deinit(&g_fd_dev.fd_ctx[i]);
if (rc)
CAM_ERR(CAM_FD, "FD context %d deinit failed, rc=%d",
i, rc);
}
rc = cam_fd_hw_mgr_deinit(pdev->dev.of_node);
if (rc)
CAM_ERR(CAM_FD, "Failed in hw mgr deinit, rc=%d", rc);
rc = cam_subdev_remove(&g_fd_dev.sd);
if (rc)
CAM_ERR(CAM_FD, "Unregister failed, rc=%d", rc);
mutex_destroy(&g_fd_dev.lock);
g_fd_dev.probe_done = false;
}
const static struct component_ops cam_fd_dev_component_ops = {
.bind = cam_fd_dev_component_bind,
.unbind = cam_fd_dev_component_unbind,
};
static int cam_fd_dev_probe(struct platform_device *pdev)
{
int rc = 0;
CAM_DBG(CAM_FD, "Adding FD dev component");
rc = component_add(&pdev->dev, &cam_fd_dev_component_ops);
if (rc)
CAM_ERR(CAM_FD, "failed to add component rc: %d", rc);
return rc;
}
static int cam_fd_dev_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &cam_fd_dev_component_ops);
return 0;
}
static const struct of_device_id cam_fd_dt_match[] = {
{
.compatible = "qcom,cam-fd"
},
{}
};
struct platform_driver cam_fd_driver = {
.probe = cam_fd_dev_probe,
.remove = cam_fd_dev_remove,
.driver = {
.name = "cam_fd",
.owner = THIS_MODULE,
.of_match_table = cam_fd_dt_match,
.suppress_bind_attrs = true,
},
};
int cam_fd_dev_init_module(void)
{
return platform_driver_register(&cam_fd_driver);
}
void cam_fd_dev_exit_module(void)
{
platform_driver_unregister(&cam_fd_driver);
}
MODULE_DESCRIPTION("MSM FD driver");
MODULE_LICENSE("GPL v2");

View file

@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_FD_DEV_H_
#define _CAM_FD_DEV_H_
/**
* @brief : API to register FD Dev to platform framework.
* @return struct platform_device pointer on on success, or ERR_PTR() on error.
*/
int cam_fd_dev_init_module(void);
/**
* @brief : API to remove FD Dev interface from platform framework.
*/
void cam_fd_dev_exit_module(void);
#endif /* _CAM_FD_DEV_H_ */

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