msm: camera: isp: Add support for SFE HW layer in ISP driver
Add support for SFE TOP, SFE BUS_WR & SFE BUS_RD in ISP driver. CRs-Fixed: 2733230 Change-Id: I85d356d28879b5cf9144a459fcdbd9f57526fa91 Signed-off-by: Karthik Anantha Ram <kartanan@codeaurora.org>
This commit is contained in:
10
config/waipiocamera.conf
Normal file
10
config/waipiocamera.conf
Normal 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
|
11
config/waipiocameraconf.h
Normal file
11
config/waipiocameraconf.h
Normal 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
|
@@ -85,6 +85,13 @@ camera-$(CONFIG_SPECTRA_ISP) += \
|
||||
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 \
|
||||
@@ -97,11 +104,6 @@ camera-$(CONFIG_SPECTRA_ISP) += \
|
||||
cam_isp/cam_isp_dev.o \
|
||||
cam_isp/cam_isp_context.o
|
||||
|
||||
camera-$(CONFIG_SPECTRA_SFE) += \
|
||||
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
|
||||
|
||||
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 \
|
||||
|
@@ -86,6 +86,9 @@ enum cam_isp_resource_type {
|
||||
CAM_ISP_RESOURCE_TPG,
|
||||
CAM_ISP_RESOURCE_TFE_IN,
|
||||
CAM_ISP_RESOURCE_TFE_OUT,
|
||||
CAM_ISP_RESOURCE_SFE_IN,
|
||||
CAM_ISP_RESOURCE_SFE_RD,
|
||||
CAM_ISP_RESOURCE_SFE_OUT,
|
||||
CAM_ISP_RESOURCE_MAX,
|
||||
};
|
||||
|
||||
@@ -131,6 +134,7 @@ enum cam_isp_hw_cmd_type {
|
||||
CAM_ISP_HW_CMD_TPG_CORE_CFG_CMD,
|
||||
CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE,
|
||||
CAM_ISP_HW_CMD_DISABLE_UBWC_COMP,
|
||||
CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG,
|
||||
CAM_ISP_HW_CMD_MAX,
|
||||
};
|
||||
|
||||
@@ -245,6 +249,10 @@ struct cam_isp_hw_cmd_buf_update {
|
||||
* @ num_buf: Number of buffers in the image_buf array
|
||||
* @ frame_header: frame header iova
|
||||
* @ local_id: local id for the wm
|
||||
* @ width: width of scratch buffer
|
||||
* @ height: height of scratch buffer
|
||||
* @ stride: stride of scratch buffer
|
||||
* @ slice_height: slice height of scratch buffer
|
||||
* @ io_cfg: IO buffer config information sent from UMD
|
||||
*
|
||||
*/
|
||||
@@ -254,6 +262,10 @@ struct cam_isp_hw_get_wm_update {
|
||||
uint32_t num_buf;
|
||||
uint64_t frame_header;
|
||||
uint32_t local_id;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t stride;
|
||||
uint32_t slice_height;
|
||||
struct cam_buf_io_cfg *io_cfg;
|
||||
};
|
||||
|
||||
@@ -278,8 +290,9 @@ struct cam_isp_hw_get_res_for_mid {
|
||||
*
|
||||
* @res: Resource node
|
||||
* @cmd_type: Command type for which to get update
|
||||
* @cdm_id : CDM id
|
||||
* @cdm_id: CDM id
|
||||
* @cmd: Command buffer information
|
||||
* @use_scratch_cfg: To indicate if it's scratch buffer config
|
||||
*
|
||||
*/
|
||||
struct cam_isp_hw_get_cmd_update {
|
||||
@@ -287,6 +300,7 @@ struct cam_isp_hw_get_cmd_update {
|
||||
enum cam_isp_hw_cmd_type cmd_type;
|
||||
enum cam_cdm_id cdm_id;
|
||||
struct cam_isp_hw_cmd_buf_update cmd;
|
||||
bool use_scratch_cfg;
|
||||
union {
|
||||
void *data;
|
||||
struct cam_isp_hw_get_wm_update *wm_update;
|
||||
|
@@ -8,8 +8,9 @@
|
||||
|
||||
#include "cam_isp_hw.h"
|
||||
|
||||
#define CAM_SFE_HW_NUM_MAX 2
|
||||
#define SFE_CORE_BASE_IDX 0
|
||||
#define SFE_RT_CDM_BASE_IDX 1
|
||||
#define CAM_SFE_HW_NUM_MAX 2
|
||||
|
||||
enum cam_isp_hw_sfe_in {
|
||||
CAM_ISP_HW_SFE_IN_PIX,
|
||||
@@ -32,6 +33,86 @@ enum cam_sfe_hw_irq_status {
|
||||
CAM_SFE_IRQ_STATUS_MAX,
|
||||
};
|
||||
|
||||
enum cam_sfe_bw_control_action {
|
||||
CAM_SFE_BW_CONTROL_EXCLUDE,
|
||||
CAM_SFE_BW_CONTROL_INCLUDE,
|
||||
};
|
||||
|
||||
enum cam_sfe_hw_irq_regs {
|
||||
CAM_SFE_IRQ_TOP_REG_STATUS0,
|
||||
CAM_SFE_IRQ_REGISTERS_MAX,
|
||||
};
|
||||
|
||||
enum cam_sfe_bus_irq_regs {
|
||||
CAM_SFE_IRQ_BUS_REG_STATUS0,
|
||||
CAM_SFE_BUS_IRQ_REGISTERS_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_fe_update_args:
|
||||
*
|
||||
* @node_res: Resource to get fetch configuration
|
||||
* @fe_config: fetch engine configuration
|
||||
*
|
||||
*/
|
||||
struct cam_sfe_fe_update_args {
|
||||
struct cam_isp_resource_node *node_res;
|
||||
struct cam_fe_config fe_config;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_clock_update_args:
|
||||
*
|
||||
* @node_res: ISP Resource
|
||||
* @clk_rate: Clock rate requested
|
||||
*/
|
||||
struct cam_sfe_clock_update_args {
|
||||
struct cam_isp_resource_node *node_res;
|
||||
uint64_t clk_rate;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_core_config_args:
|
||||
*
|
||||
* @node_res: ISP Resource
|
||||
* @core_config: Core config for SFE
|
||||
*/
|
||||
struct cam_sfe_core_config_args {
|
||||
struct cam_isp_resource_node *node_res;
|
||||
struct cam_isp_sfe_core_config core_config;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_irq_evt_payload:
|
||||
*
|
||||
* @Brief: This structure is used to save payload for IRQ
|
||||
* related to SFE resources
|
||||
*
|
||||
* @list: list_head node for the payload
|
||||
* @core_index: Index of SFE HW that generated this IRQ event
|
||||
* @evt_id: IRQ event
|
||||
* @irq_reg_val: IRQ and Error register values, read when IRQ was
|
||||
* handled
|
||||
* @bus_irq_val Bus irq register status
|
||||
* @ccif_violation_status ccif violation status
|
||||
* @overflow_status bus overflow status
|
||||
* @image_size_vio_sts image size violations status
|
||||
* @error_type: Identify different errors
|
||||
* @ts: Timestamp
|
||||
*/
|
||||
struct cam_sfe_irq_evt_payload {
|
||||
struct list_head list;
|
||||
uint32_t core_index;
|
||||
uint32_t evt_id;
|
||||
uint32_t irq_reg_val[CAM_SFE_IRQ_REGISTERS_MAX];
|
||||
uint32_t bus_irq_val[CAM_SFE_BUS_IRQ_REGISTERS_MAX];
|
||||
uint32_t ccif_violation_status;
|
||||
uint32_t overflow_status;
|
||||
uint32_t image_size_vio_sts;
|
||||
uint32_t error_type;
|
||||
struct cam_isp_timestamp ts;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_hw_get_hw_cap:
|
||||
*
|
||||
@@ -54,18 +135,18 @@ struct cam_sfe_hw_get_hw_cap {
|
||||
* is successful
|
||||
* @res_id: Unique Identity of port to associate with this
|
||||
* resource.
|
||||
* @is_dual: Flag to indicate dual SFE usecase
|
||||
* @cdm_ops: CDM operations
|
||||
* @unpacket_fmt: Unpacker format for read engine
|
||||
* @is_offline: Flag to indicate offline usecase
|
||||
* @secure_mode: If fetch is from secure/non-secure buffer
|
||||
*/
|
||||
struct cam_sfe_hw_sfe_bus_rd_acquire_args {
|
||||
struct cam_isp_resource_node *rsrc_node;
|
||||
uint32_t res_id;
|
||||
uint32_t is_dual;
|
||||
struct cam_cdm_utils_ops *cdm_ops;
|
||||
uint32_t unpacker_fmt;
|
||||
bool is_offline;
|
||||
bool secure_mode;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -77,9 +158,7 @@ struct cam_sfe_hw_sfe_bus_rd_acquire_args {
|
||||
* resource.
|
||||
* @cdm_ops: CDM operations
|
||||
* @is_dual: Dual mode usecase
|
||||
* @sync_mode: If in dual mode, indicates master/slave
|
||||
* @in_port: in port info
|
||||
* @is_fe_enabled: Flag to indicate if FE is enabled
|
||||
* @is_offline: Flag to indicate Offline IFE
|
||||
*/
|
||||
struct cam_sfe_hw_sfe_in_acquire_args {
|
||||
@@ -87,9 +166,7 @@ struct cam_sfe_hw_sfe_in_acquire_args {
|
||||
uint32_t res_id;
|
||||
struct cam_cdm_utils_ops *cdm_ops;
|
||||
uint32_t is_dual;
|
||||
enum cam_isp_hw_sync_mode sync_mode;
|
||||
struct cam_isp_in_port_generic_info *in_port;
|
||||
bool is_fe_enabled;
|
||||
bool is_offline;
|
||||
};
|
||||
|
||||
@@ -126,6 +203,7 @@ struct cam_sfe_hw_sfe_out_acquire_args {
|
||||
* with this resource.
|
||||
* @priv: Context data
|
||||
* @event_cb: Callback function to hw mgr in case of hw events
|
||||
* @buf_done_controller: Buf done controller
|
||||
* @sfe_out: Acquire args for SFE_OUT
|
||||
* @sfe_bus_rd Acquire args for SFE_BUS_READ
|
||||
* @sfe_in: Acquire args for SFE_IN
|
||||
@@ -135,6 +213,7 @@ struct cam_sfe_acquire_args {
|
||||
void *tasklet;
|
||||
void *priv;
|
||||
cam_hw_mgr_event_cb_func event_cb;
|
||||
void *buf_done_controller;
|
||||
union {
|
||||
struct cam_sfe_hw_sfe_out_acquire_args sfe_out;
|
||||
struct cam_sfe_hw_sfe_in_acquire_args sfe_in;
|
||||
|
695
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe680.h
Normal file
695
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe680.h
Normal file
@@ -0,0 +1,695 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_SFE680_H_
|
||||
#define _CAM_SFE680_H_
|
||||
#include "cam_sfe_core.h"
|
||||
#include "cam_sfe_bus.h"
|
||||
#include "cam_sfe_bus_rd.h"
|
||||
#include "cam_sfe_bus_wr.h"
|
||||
|
||||
static struct cam_sfe_top_common_reg_offset sfe680_top_commong_reg = {
|
||||
.hw_version = 0x00000000,
|
||||
.hw_capability = 0x00000004,
|
||||
.stats_feature = 0x00000008,
|
||||
.core_cgc_ctrl = 0x00000010,
|
||||
.ahb_clk_ovd = 0x00000014,
|
||||
.core_cfg = 0x00000018,
|
||||
.violation_status = 0x00000030,
|
||||
.diag_config = 0x00000034,
|
||||
.diag_sensor_status_0 = 0x00000038,
|
||||
.diag_sensor_status_1 = 0x0000003C,
|
||||
.diag_sensor_frame_cnt_status0 = 0x00000040,
|
||||
.diag_sensor_frame_cnt_status1 = 0x00000044,
|
||||
.top_debug_0 = 0x0000004C,
|
||||
.top_debug_1 = 0x00000050,
|
||||
.top_debug_2 = 0x00000054,
|
||||
.top_debug_3 = 0x00000058,
|
||||
.top_debug_4 = 0x0000005C,
|
||||
.top_debug_5 = 0x00000060,
|
||||
.top_debug_6 = 0x00000064,
|
||||
.top_debug_7 = 0x00000068,
|
||||
.top_debug_8 = 0x0000006C,
|
||||
.top_debug_9 = 0x00000070,
|
||||
.top_debug_10 = 0x00000074,
|
||||
.top_debug_11 = 0x00000078,
|
||||
.top_debug_cfg = 0x0000007C,
|
||||
.stats_ch2_throttle_cfg = 0x000000B0,
|
||||
.stats_ch1_throttle_cfg = 0x000000B4,
|
||||
.stats_ch0_throttle_cfg = 0x000000B8,
|
||||
.lcr_throttle_cfg = 0x000000BC,
|
||||
.hdr_throttle_cfg = 0x000000C0,
|
||||
.sfe_op_throttle_cfg = 0x000000C4,
|
||||
};
|
||||
|
||||
static struct cam_sfe_modules_common_reg_offset sfe680_modules_common_reg = {
|
||||
.demux_module_cfg = 0x00003060,
|
||||
.demux_qcfa_cfg = 0x00003064,
|
||||
.demux_hdr_cfg = 0x00003074,
|
||||
.demux_lcr_sel = 0x00003078,
|
||||
.hdrc_remo_mod_cfg = 0x00005860,
|
||||
.hdrc_remo_qcfa_bin_cfg = 0x00005A78,
|
||||
.qcfa_hdrc_remo_out_mux_cfg = 0x00005A74,
|
||||
};
|
||||
|
||||
static struct cam_sfe_path_common_reg_data sfe_680_pix_reg_data = {
|
||||
.sof_irq_mask = 0x4,
|
||||
.eof_irq_mask = 0x8,
|
||||
.error_irq_mask = 0x1C000,
|
||||
.subscribe_irq_mask = 0xC,
|
||||
.enable_diagnostic_hw = 0x1,
|
||||
.top_debug_cfg_en = 0x3,
|
||||
};
|
||||
|
||||
static struct cam_sfe_path_common_reg_data sfe_680_rdi0_reg_data = {
|
||||
.sof_irq_mask = 0x10,
|
||||
.eof_irq_mask = 0x20,
|
||||
.error_irq_mask = 0x1C000,
|
||||
.subscribe_irq_mask = 0x30,
|
||||
.enable_diagnostic_hw = 0x1,
|
||||
.top_debug_cfg_en = 0x3,
|
||||
};
|
||||
|
||||
static struct cam_sfe_path_common_reg_data sfe_680_rdi1_reg_data = {
|
||||
.sof_irq_mask = 0x40,
|
||||
.eof_irq_mask = 0x80,
|
||||
.error_irq_mask = 0x1C000,
|
||||
.subscribe_irq_mask = 0xC0,
|
||||
.enable_diagnostic_hw = 0x1,
|
||||
.top_debug_cfg_en = 0x3,
|
||||
};
|
||||
|
||||
static struct cam_sfe_path_common_reg_data sfe_680_rdi2_reg_data = {
|
||||
.sof_irq_mask = 0x100,
|
||||
.eof_irq_mask = 0x200,
|
||||
.error_irq_mask = 0x1C000,
|
||||
.subscribe_irq_mask = 0x300,
|
||||
.enable_diagnostic_hw = 0x1,
|
||||
.top_debug_cfg_en = 0x3,
|
||||
};
|
||||
|
||||
static struct cam_sfe_path_common_reg_data sfe_680_rdi3_reg_data = {
|
||||
.sof_irq_mask = 0x400,
|
||||
.eof_irq_mask = 0x800,
|
||||
.error_irq_mask = 0x1C000,
|
||||
.subscribe_irq_mask = 0xC00,
|
||||
.enable_diagnostic_hw = 0x1,
|
||||
.top_debug_cfg_en = 0x3,
|
||||
};
|
||||
|
||||
static struct cam_sfe_path_common_reg_data sfe_680_rdi4_reg_data = {
|
||||
.sof_irq_mask = 0x1000,
|
||||
.eof_irq_mask = 0x2000,
|
||||
.error_irq_mask = 0x1C000,
|
||||
.subscribe_irq_mask = 0x3000,
|
||||
.enable_diagnostic_hw = 0x1,
|
||||
.top_debug_cfg_en = 0x3,
|
||||
};
|
||||
|
||||
static struct cam_sfe_top_hw_info sfe680_top_hw_info = {
|
||||
.common_reg = &sfe680_top_commong_reg,
|
||||
.modules_hw_info = &sfe680_modules_common_reg,
|
||||
.pix_reg_data = &sfe_680_pix_reg_data,
|
||||
.rdi_reg_data[0] = &sfe_680_rdi0_reg_data,
|
||||
.rdi_reg_data[1] = &sfe_680_rdi1_reg_data,
|
||||
.rdi_reg_data[2] = &sfe_680_rdi2_reg_data,
|
||||
.rdi_reg_data[3] = &sfe_680_rdi3_reg_data,
|
||||
.rdi_reg_data[4] = &sfe_680_rdi4_reg_data,
|
||||
.num_inputs = 6,
|
||||
.input_type = {
|
||||
CAM_SFE_PIX_VER_1_0,
|
||||
CAM_SFE_RDI_VER_1_0,
|
||||
CAM_SFE_RDI_VER_1_0,
|
||||
CAM_SFE_RDI_VER_1_0,
|
||||
CAM_SFE_RDI_VER_1_0,
|
||||
CAM_SFE_RDI_VER_1_0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct cam_sfe_bus_rd_hw_info sfe680_bus_rd_hw_info = {
|
||||
.common_reg = {
|
||||
.hw_version = 0x00000400,
|
||||
.misr_reset = 0x0000041C,
|
||||
.pwr_iso_cfg = 0x00000424,
|
||||
.input_if_cmd = 0x00000414,
|
||||
.test_bus_ctrl = 0x0000042C,
|
||||
.security_cfg = 0x00000420,
|
||||
},
|
||||
.num_client = 3,
|
||||
.bus_client_reg = {
|
||||
/* BUS Client 0 */
|
||||
{
|
||||
.cfg = 0x00000450,
|
||||
.image_addr = 0x00000458,
|
||||
.buf_width = 0x0000045C,
|
||||
.buf_height = 0x00000460,
|
||||
.stride = 0x00000464,
|
||||
.unpacker_cfg = 0x00000468,
|
||||
.latency_buf_allocation = 0x0000047C,
|
||||
},
|
||||
/* BUS Client 1 */
|
||||
{
|
||||
.cfg = 0x000004F0,
|
||||
.image_addr = 0x000004F8,
|
||||
.buf_width = 0x000004FC,
|
||||
.buf_height = 0x00000500,
|
||||
.stride = 0x00000504,
|
||||
.unpacker_cfg = 0x00000508,
|
||||
.latency_buf_allocation = 0x0000051C,
|
||||
},
|
||||
/* BUS Client 2 */
|
||||
{
|
||||
.cfg = 0x00000590,
|
||||
.image_addr = 0x00000598,
|
||||
.buf_width = 0x0000059C,
|
||||
.buf_height = 0x000005A0,
|
||||
.stride = 0x000005A4,
|
||||
.unpacker_cfg = 0x000005A8,
|
||||
.latency_buf_allocation = 0x000005BC,
|
||||
},
|
||||
},
|
||||
.num_bus_rd_resc = 3,
|
||||
.sfe_bus_rd_info = {
|
||||
{
|
||||
.sfe_bus_rd_type = CAM_SFE_BUS_RD_RDI0,
|
||||
.max_width = -1,
|
||||
.max_height = -1,
|
||||
},
|
||||
{
|
||||
.sfe_bus_rd_type = CAM_SFE_BUS_RD_RDI1,
|
||||
.max_width = -1,
|
||||
.max_height = -1,
|
||||
},
|
||||
{
|
||||
.sfe_bus_rd_type = CAM_SFE_BUS_RD_RDI2,
|
||||
.max_width = -1,
|
||||
.max_height = -1,
|
||||
},
|
||||
},
|
||||
.top_irq_shift = 0x1,
|
||||
};
|
||||
|
||||
static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
||||
.common_reg = {
|
||||
.hw_version = 0x00000800,
|
||||
.cgc_ovd = 0x00000808,
|
||||
.if_frameheader_cfg = {
|
||||
0x00000834,
|
||||
0x00000838,
|
||||
0x0000083C,
|
||||
0x00000840,
|
||||
0x00000844,
|
||||
0x00000848,
|
||||
},
|
||||
.pwr_iso_cfg = 0x0000085C,
|
||||
.overflow_status_clear = 0x00000860,
|
||||
.ccif_violation_status = 0x00000864,
|
||||
.overflow_status = 0x00000868,
|
||||
.image_size_violation_status = 0x00000870,
|
||||
.debug_status_top_cfg = 0x000008D4,
|
||||
.debug_status_top = 0x000008D8,
|
||||
.test_bus_ctrl = 0x000008DC,
|
||||
.top_irq_mask_0 = 0x00000818,
|
||||
},
|
||||
.num_client = 13,
|
||||
.bus_client_reg = {
|
||||
/* BUS Client 0 REMOSAIC */
|
||||
{
|
||||
.cfg = 0x00000A00,
|
||||
.image_addr = 0x00000A04,
|
||||
.frame_incr = 0x00000A08,
|
||||
.image_cfg_0 = 0x00000A0C,
|
||||
.image_cfg_1 = 0x00000A10,
|
||||
.image_cfg_2 = 0x00000A14,
|
||||
.packer_cfg = 0x00000A18,
|
||||
.frame_header_addr = 0x00000A20,
|
||||
.frame_header_incr = 0x00000A24,
|
||||
.frame_header_cfg = 0x00000A28,
|
||||
.line_done_cfg = 0,
|
||||
.irq_subsample_period = 0x00000A30,
|
||||
.irq_subsample_pattern = 0x00000A34,
|
||||
.framedrop_period = 0x00000A38,
|
||||
.framedrop_pattern = 0x00000A3C,
|
||||
.system_cache_cfg = 0x00000A68,
|
||||
.addr_status_0 = 0x00000A70,
|
||||
.addr_status_1 = 0x00000A74,
|
||||
.addr_status_2 = 0x00000A78,
|
||||
.addr_status_3 = 0x00000A7C,
|
||||
.debug_status_cfg = 0x00000A80,
|
||||
.debug_status_0 = 0x00000A84,
|
||||
.debug_status_1 = 0x00000A88,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_0,
|
||||
},
|
||||
/* BUS Client 1 LCR */
|
||||
{
|
||||
.cfg = 0x00000B00,
|
||||
.image_addr = 0x00000B04,
|
||||
.frame_incr = 0x00000B08,
|
||||
.image_cfg_0 = 0x00000B0C,
|
||||
.image_cfg_1 = 0x00000B10,
|
||||
.image_cfg_2 = 0x00000B14,
|
||||
.packer_cfg = 0x00000B18,
|
||||
.frame_header_addr = 0x00000B20,
|
||||
.frame_header_incr = 0x00000B24,
|
||||
.frame_header_cfg = 0x00000B28,
|
||||
.line_done_cfg = 0,
|
||||
.irq_subsample_period = 0x00000B30,
|
||||
.irq_subsample_pattern = 0x00000B34,
|
||||
.framedrop_period = 0x00000B38,
|
||||
.framedrop_pattern = 0x00000B3C,
|
||||
.system_cache_cfg = 0x00000B68,
|
||||
.addr_status_0 = 0x00000B70,
|
||||
.addr_status_1 = 0x00000B74,
|
||||
.addr_status_2 = 0x00000B78,
|
||||
.addr_status_3 = 0x00000B7C,
|
||||
.debug_status_cfg = 0x00000B80,
|
||||
.debug_status_0 = 0x00000B84,
|
||||
.debug_status_1 = 0x00000B88,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_1,
|
||||
},
|
||||
/* BUS Client 2 STATS_BE_0 */
|
||||
{
|
||||
.cfg = 0x00000C00,
|
||||
.image_addr = 0x00000C04,
|
||||
.frame_incr = 0x00000C08,
|
||||
.image_cfg_0 = 0x00000C0C,
|
||||
.image_cfg_1 = 0x00000C10,
|
||||
.image_cfg_2 = 0x00000C14,
|
||||
.packer_cfg = 0x00000C18,
|
||||
.frame_header_addr = 0x00000C20,
|
||||
.frame_header_incr = 0x00000C24,
|
||||
.frame_header_cfg = 0x00000C28,
|
||||
.line_done_cfg = 0,
|
||||
.irq_subsample_period = 0x00000C30,
|
||||
.irq_subsample_pattern = 0x00000C34,
|
||||
.framedrop_period = 0x00000C38,
|
||||
.framedrop_pattern = 0x00000C3C,
|
||||
.system_cache_cfg = 0x00000C68,
|
||||
.addr_status_0 = 0x00000C70,
|
||||
.addr_status_1 = 0x00000C74,
|
||||
.addr_status_2 = 0x00000C78,
|
||||
.addr_status_3 = 0x00000C7C,
|
||||
.debug_status_cfg = 0x00000C80,
|
||||
.debug_status_0 = 0x00000C84,
|
||||
.debug_status_1 = 0x00000C88,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_2,
|
||||
},
|
||||
/* BUS Client 3 STATS_BHIST_0 */
|
||||
{
|
||||
.cfg = 0x00000D00,
|
||||
.image_addr = 0x00000D04,
|
||||
.frame_incr = 0x00000D08,
|
||||
.image_cfg_0 = 0x00000D0C,
|
||||
.image_cfg_1 = 0x00000D10,
|
||||
.image_cfg_2 = 0x00000D14,
|
||||
.packer_cfg = 0x00000D18,
|
||||
.frame_header_addr = 0x00000D20,
|
||||
.frame_header_incr = 0x00000D24,
|
||||
.frame_header_cfg = 0x00000D28,
|
||||
.line_done_cfg = 0,
|
||||
.irq_subsample_period = 0x00000D30,
|
||||
.irq_subsample_pattern = 0x00000D34,
|
||||
.framedrop_period = 0x00000D38,
|
||||
.framedrop_pattern = 0x00000D3C,
|
||||
.system_cache_cfg = 0x00000D68,
|
||||
.addr_status_0 = 0x00000D70,
|
||||
.addr_status_1 = 0x00000D74,
|
||||
.addr_status_2 = 0x00000D78,
|
||||
.addr_status_3 = 0x00000D7C,
|
||||
.debug_status_cfg = 0x00000D80,
|
||||
.debug_status_0 = 0x00000D84,
|
||||
.debug_status_1 = 0x00000D88,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_2,
|
||||
},
|
||||
/* BUS Client 4 STATS_BE_1 */
|
||||
{
|
||||
.cfg = 0x00000E00,
|
||||
.image_addr = 0x00000E04,
|
||||
.frame_incr = 0x00000E08,
|
||||
.image_cfg_0 = 0x00000E0C,
|
||||
.image_cfg_1 = 0x00000E10,
|
||||
.image_cfg_2 = 0x00000E14,
|
||||
.packer_cfg = 0x00000E18,
|
||||
.frame_header_addr = 0x00000E20,
|
||||
.frame_header_incr = 0x00000E24,
|
||||
.frame_header_cfg = 0x00000E28,
|
||||
.line_done_cfg = 0,
|
||||
.irq_subsample_period = 0x00000E30,
|
||||
.irq_subsample_pattern = 0x00000E34,
|
||||
.framedrop_period = 0x00000E38,
|
||||
.framedrop_pattern = 0x00000E3C,
|
||||
.system_cache_cfg = 0x00000E68,
|
||||
.addr_status_0 = 0x00000E70,
|
||||
.addr_status_1 = 0x00000E74,
|
||||
.addr_status_2 = 0x00000E78,
|
||||
.addr_status_3 = 0x00000E7C,
|
||||
.debug_status_cfg = 0x00000E80,
|
||||
.debug_status_0 = 0x00000E84,
|
||||
.debug_status_1 = 0x00000E88,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_3,
|
||||
},
|
||||
/* BUS Client 5 STATS_BHIST_1 */
|
||||
{
|
||||
.cfg = 0x00000F00,
|
||||
.image_addr = 0x00000F04,
|
||||
.frame_incr = 0x00000F08,
|
||||
.image_cfg_0 = 0x00000F0C,
|
||||
.image_cfg_1 = 0x00000F10,
|
||||
.image_cfg_2 = 0x00000F14,
|
||||
.packer_cfg = 0x00000F18,
|
||||
.frame_header_addr = 0x00000F20,
|
||||
.frame_header_incr = 0x00000F24,
|
||||
.frame_header_cfg = 0x00000F28,
|
||||
.line_done_cfg = 0,
|
||||
.irq_subsample_period = 0x00000F30,
|
||||
.irq_subsample_pattern = 0x00000F34,
|
||||
.framedrop_period = 0x00000F38,
|
||||
.framedrop_pattern = 0x00000F3C,
|
||||
.system_cache_cfg = 0x00000F68,
|
||||
.addr_status_0 = 0x00000F70,
|
||||
.addr_status_1 = 0x00000F74,
|
||||
.addr_status_2 = 0x00000F78,
|
||||
.addr_status_3 = 0x00000F7C,
|
||||
.debug_status_cfg = 0x00000F80,
|
||||
.debug_status_0 = 0x00000F84,
|
||||
.debug_status_1 = 0x00000F88,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_3,
|
||||
},
|
||||
/* BUS Client 6 STATS_BE_2 */
|
||||
{
|
||||
.cfg = 0x00001000,
|
||||
.image_addr = 0x00001004,
|
||||
.frame_incr = 0x00001008,
|
||||
.image_cfg_0 = 0x0000100C,
|
||||
.image_cfg_1 = 0x00001010,
|
||||
.image_cfg_2 = 0x00001014,
|
||||
.packer_cfg = 0x00001018,
|
||||
.frame_header_addr = 0x00001020,
|
||||
.frame_header_incr = 0x00001024,
|
||||
.frame_header_cfg = 0x00001028,
|
||||
.line_done_cfg = 0,
|
||||
.irq_subsample_period = 0x00001030,
|
||||
.irq_subsample_pattern = 0x00001034,
|
||||
.framedrop_period = 0x00001038,
|
||||
.framedrop_pattern = 0x0000103C,
|
||||
.system_cache_cfg = 0x00001068,
|
||||
.addr_status_0 = 0x00001070,
|
||||
.addr_status_1 = 0x00001074,
|
||||
.addr_status_2 = 0x00001078,
|
||||
.addr_status_3 = 0x0000107C,
|
||||
.debug_status_cfg = 0x00001080,
|
||||
.debug_status_0 = 0x00001084,
|
||||
.debug_status_1 = 0x00001088,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_4,
|
||||
},
|
||||
/* BUS Client 7 STATS_BHIST_2 */
|
||||
{
|
||||
.cfg = 0x00001100,
|
||||
.image_addr = 0x00001104,
|
||||
.frame_incr = 0x00001108,
|
||||
.image_cfg_0 = 0x0000110C,
|
||||
.image_cfg_1 = 0x00001110,
|
||||
.image_cfg_2 = 0x00001114,
|
||||
.packer_cfg = 0x00001118,
|
||||
.frame_header_addr = 0x00001120,
|
||||
.frame_header_incr = 0x00001124,
|
||||
.frame_header_cfg = 0x00001128,
|
||||
.line_done_cfg = 0,
|
||||
.irq_subsample_period = 0x00001130,
|
||||
.irq_subsample_pattern = 0x00001134,
|
||||
.framedrop_period = 0x00001138,
|
||||
.framedrop_pattern = 0x0000113C,
|
||||
.system_cache_cfg = 0x00001168,
|
||||
.addr_status_0 = 0x00001170,
|
||||
.addr_status_1 = 0x00001174,
|
||||
.addr_status_2 = 0x00001178,
|
||||
.addr_status_3 = 0x0000117C,
|
||||
.debug_status_cfg = 0x00001180,
|
||||
.debug_status_0 = 0x00001184,
|
||||
.debug_status_1 = 0x00001188,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_4,
|
||||
},
|
||||
/* BUS Client 8 RDI0 */
|
||||
{
|
||||
.cfg = 0x00001200,
|
||||
.image_addr = 0x00001204,
|
||||
.frame_incr = 0x00001208,
|
||||
.image_cfg_0 = 0x0000120C,
|
||||
.image_cfg_1 = 0x00001210,
|
||||
.image_cfg_2 = 0x00001214,
|
||||
.packer_cfg = 0x00001218,
|
||||
.frame_header_addr = 0x00001220,
|
||||
.frame_header_incr = 0x00001224,
|
||||
.frame_header_cfg = 0x00001228,
|
||||
.line_done_cfg = 0x0000122C,
|
||||
.irq_subsample_period = 0x00001230,
|
||||
.irq_subsample_pattern = 0x00001234,
|
||||
.framedrop_period = 0x00001238,
|
||||
.framedrop_pattern = 0x0000123C,
|
||||
.system_cache_cfg = 0x00001268,
|
||||
.addr_status_0 = 0x00001270,
|
||||
.addr_status_1 = 0x00001274,
|
||||
.addr_status_2 = 0x00001278,
|
||||
.addr_status_3 = 0x0000127C,
|
||||
.debug_status_cfg = 0x00001280,
|
||||
.debug_status_0 = 0x00001284,
|
||||
.debug_status_1 = 0x00001288,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_5,
|
||||
},
|
||||
/* BUS Client 9 RDI1 */
|
||||
{
|
||||
.cfg = 0x00001300,
|
||||
.image_addr = 0x00001304,
|
||||
.frame_incr = 0x00001308,
|
||||
.image_cfg_0 = 0x0000130C,
|
||||
.image_cfg_1 = 0x00001310,
|
||||
.image_cfg_2 = 0x00001314,
|
||||
.packer_cfg = 0x00001318,
|
||||
.frame_header_addr = 0x00001320,
|
||||
.frame_header_incr = 0x00001324,
|
||||
.frame_header_cfg = 0x00001328,
|
||||
.line_done_cfg = 0x0000132C,
|
||||
.irq_subsample_period = 0x00001330,
|
||||
.irq_subsample_pattern = 0x00001334,
|
||||
.framedrop_period = 0x00001338,
|
||||
.framedrop_pattern = 0x0000133C,
|
||||
.system_cache_cfg = 0x00001368,
|
||||
.addr_status_0 = 0x00001370,
|
||||
.addr_status_1 = 0x00001374,
|
||||
.addr_status_2 = 0x00001378,
|
||||
.addr_status_3 = 0x0000137C,
|
||||
.debug_status_cfg = 0x00001380,
|
||||
.debug_status_0 = 0x00001384,
|
||||
.debug_status_1 = 0x00001388,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_6,
|
||||
},
|
||||
/* BUS Client 10 RDI2 */
|
||||
{
|
||||
.cfg = 0x00001400,
|
||||
.image_addr = 0x00001404,
|
||||
.frame_incr = 0x00001408,
|
||||
.image_cfg_0 = 0x0000140C,
|
||||
.image_cfg_1 = 0x00001410,
|
||||
.image_cfg_2 = 0x00001414,
|
||||
.packer_cfg = 0x00001418,
|
||||
.frame_header_addr = 0x00001420,
|
||||
.frame_header_incr = 0x00001424,
|
||||
.frame_header_cfg = 0x00001428,
|
||||
.line_done_cfg = 0x0000142C,
|
||||
.irq_subsample_period = 0x00001430,
|
||||
.irq_subsample_pattern = 0x00001434,
|
||||
.framedrop_period = 0x00001438,
|
||||
.framedrop_pattern = 0x0000143C,
|
||||
.system_cache_cfg = 0x00001468,
|
||||
.addr_status_0 = 0x00001470,
|
||||
.addr_status_1 = 0x00001474,
|
||||
.addr_status_2 = 0x00001478,
|
||||
.addr_status_3 = 0x0000147C,
|
||||
.debug_status_cfg = 0x00001480,
|
||||
.debug_status_0 = 0x00001484,
|
||||
.debug_status_1 = 0x00001488,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_7,
|
||||
},
|
||||
/* BUS Client 11 RDI3 */
|
||||
{
|
||||
.cfg = 0x00001500,
|
||||
.image_addr = 0x00001504,
|
||||
.frame_incr = 0x00001508,
|
||||
.image_cfg_0 = 0x0000150C,
|
||||
.image_cfg_1 = 0x00001510,
|
||||
.image_cfg_2 = 0x00001514,
|
||||
.packer_cfg = 0x00001518,
|
||||
.frame_header_addr = 0x00001520,
|
||||
.frame_header_incr = 0x00001524,
|
||||
.frame_header_cfg = 0x00001528,
|
||||
.line_done_cfg = 0x0000152C,
|
||||
.irq_subsample_period = 0x00001530,
|
||||
.irq_subsample_pattern = 0x00001534,
|
||||
.framedrop_period = 0x00001538,
|
||||
.framedrop_pattern = 0x0000153C,
|
||||
.system_cache_cfg = 0x00001568,
|
||||
.addr_status_0 = 0x00001570,
|
||||
.addr_status_1 = 0x00001574,
|
||||
.addr_status_2 = 0x00001578,
|
||||
.addr_status_3 = 0x0000157C,
|
||||
.debug_status_cfg = 0x00001580,
|
||||
.debug_status_0 = 0x00001584,
|
||||
.debug_status_1 = 0x00001588,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_8,
|
||||
},
|
||||
/* BUS Client 12 RDI4 */
|
||||
{
|
||||
.cfg = 0x00001600,
|
||||
.image_addr = 0x00001604,
|
||||
.frame_incr = 0x00001608,
|
||||
.image_cfg_0 = 0x0000160C,
|
||||
.image_cfg_1 = 0x00001610,
|
||||
.image_cfg_2 = 0x00001614,
|
||||
.packer_cfg = 0x00001618,
|
||||
.frame_header_addr = 0x00001620,
|
||||
.frame_header_incr = 0x00001624,
|
||||
.frame_header_cfg = 0x00001628,
|
||||
.line_done_cfg = 0x0000162C,
|
||||
.irq_subsample_period = 0x00001630,
|
||||
.irq_subsample_pattern = 0x00001634,
|
||||
.framedrop_period = 0x00001638,
|
||||
.framedrop_pattern = 0x0000163C,
|
||||
.system_cache_cfg = 0x00001668,
|
||||
.addr_status_0 = 0x00001670,
|
||||
.addr_status_1 = 0x00001674,
|
||||
.addr_status_2 = 0x00001678,
|
||||
.addr_status_3 = 0x0000167C,
|
||||
.debug_status_cfg = 0x00001680,
|
||||
.debug_status_0 = 0x00001684,
|
||||
.debug_status_1 = 0x00001688,
|
||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_9,
|
||||
},
|
||||
},
|
||||
.num_out = 13,
|
||||
.sfe_out_hw_info = {
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_RDI0,
|
||||
.max_width = -1,
|
||||
.max_height = -1,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_1,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 8,
|
||||
},
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_RDI1,
|
||||
.max_width = -1,
|
||||
.max_height = -1,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_2,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 9,
|
||||
},
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_RDI2,
|
||||
.max_width = -1,
|
||||
.max_height = -1,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_3,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 10,
|
||||
},
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_RDI3,
|
||||
.max_width = -1,
|
||||
.max_height = -1,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_4,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 11,
|
||||
},
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_RDI4,
|
||||
.max_width = -1,
|
||||
.max_height = -1,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_4,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 12,
|
||||
},
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_RAW_DUMP,
|
||||
.max_width = 9312,
|
||||
.max_height = 6992,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_0,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 0,
|
||||
},
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_LCR,
|
||||
.max_width = 9312,
|
||||
.max_height = 2048,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_0,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 1,
|
||||
},
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_BE_0,
|
||||
.max_width = 7296,
|
||||
.max_height = 5472,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_0,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 2,
|
||||
},
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_BHIST_0,
|
||||
.max_width = 7296,
|
||||
.max_height = 5472,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_0,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 3,
|
||||
},
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_BE_1,
|
||||
.max_width = 7296,
|
||||
.max_height = 5472,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_0,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 4,
|
||||
},
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_BHIST_1,
|
||||
.max_width = 7296,
|
||||
.max_height = 5472,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_0,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 5,
|
||||
},
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_BE_2,
|
||||
.max_width = 7296,
|
||||
.max_height = 5472,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_0,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 6,
|
||||
},
|
||||
{
|
||||
.sfe_out_type = CAM_SFE_BUS_SFE_OUT_BHIST_2,
|
||||
.max_width = 7296,
|
||||
.max_height = 5472,
|
||||
.source_group = CAM_SFE_BUS_WR_SRC_GRP_0,
|
||||
.num_wm = 1,
|
||||
.wm_idx = 7,
|
||||
},
|
||||
},
|
||||
.num_comp_grp = 10,
|
||||
.comp_done_shift = 17,
|
||||
.top_irq_shift = 0x0,
|
||||
};
|
||||
|
||||
struct cam_sfe_hw_info cam_sfe680_hw_info = {
|
||||
.irq_reg_info = NULL,
|
||||
|
||||
.bus_wr_version = CAM_SFE_BUS_WR_VER_1_0,
|
||||
.bus_wr_hw_info = &sfe680_bus_wr_hw_info,
|
||||
|
||||
.bus_rd_version = CAM_SFE_BUS_RD_VER_1_0,
|
||||
.bus_rd_hw_info = &sfe680_bus_rd_hw_info,
|
||||
|
||||
.top_version = CAM_SFE_TOP_VER_1_0,
|
||||
.top_hw_info = &sfe680_top_hw_info,
|
||||
};
|
||||
|
||||
#endif /* _CAM_SFE680_H_ */
|
@@ -12,12 +12,29 @@
|
||||
#include "cam_debug_util.h"
|
||||
|
||||
static const char drv_name[] = "sfe";
|
||||
#define SFE_CORE_BASE_IDX 0
|
||||
|
||||
int cam_sfe_get_hw_caps(void *hw_priv, void *get_hw_cap_args, uint32_t arg_size)
|
||||
int cam_sfe_get_hw_caps(void *device_priv,
|
||||
void *get_hw_cap_args, uint32_t arg_size)
|
||||
{
|
||||
CAM_DBG(CAM_SFE, "Enter");
|
||||
return 0;
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
int cam_sfe_reset(void *device_priv,
|
||||
void *reset_core_args, uint32_t arg_size)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
int cam_sfe_read(void *device_priv,
|
||||
void *read_args, uint32_t arg_size)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
int cam_sfe_write(void *device_priv,
|
||||
void *write_args, uint32_t arg_size)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
int cam_sfe_init_hw(void *hw_priv, void *init_hw_args, uint32_t arg_size)
|
||||
@@ -25,10 +42,8 @@ int cam_sfe_init_hw(void *hw_priv, void *init_hw_args, uint32_t arg_size)
|
||||
struct cam_hw_info *sfe_hw = hw_priv;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
struct cam_sfe_hw_core_info *core_info = NULL;
|
||||
struct cam_isp_resource_node *isp_res = NULL;
|
||||
int rc = 0;
|
||||
|
||||
CAM_DBG(CAM_SFE, "Enter");
|
||||
if (!hw_priv) {
|
||||
CAM_ERR(CAM_SFE, "Invalid arguments");
|
||||
return -EINVAL;
|
||||
@@ -38,7 +53,7 @@ int cam_sfe_init_hw(void *hw_priv, void *init_hw_args, uint32_t arg_size)
|
||||
sfe_hw->open_count++;
|
||||
if (sfe_hw->open_count > 1) {
|
||||
mutex_unlock(&sfe_hw->hw_mutex);
|
||||
CAM_DBG(CAM_SFE, "SFE has already been initialized cnt %d",
|
||||
CAM_DBG(CAM_SFE, "SFE has already been initialized cnt: %d",
|
||||
sfe_hw->open_count);
|
||||
return 0;
|
||||
}
|
||||
@@ -55,30 +70,34 @@ int cam_sfe_init_hw(void *hw_priv, void *init_hw_args, uint32_t arg_size)
|
||||
goto decrement_open_cnt;
|
||||
}
|
||||
|
||||
isp_res = (struct cam_isp_resource_node *)init_hw_args;
|
||||
if (isp_res && isp_res->init) {
|
||||
rc = isp_res->init(isp_res, NULL, 0);
|
||||
CAM_DBG(CAM_SFE, "SFE SOC resource enabled");
|
||||
|
||||
/* Async Reset as part of power ON */
|
||||
/* Sync Reset in CSID */
|
||||
|
||||
/* INIT SFE BUS WR */
|
||||
rc = core_info->sfe_bus_wr->hw_ops.init(
|
||||
core_info->sfe_bus_wr->bus_priv, NULL, 0);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SFE, "init Failed rc=%d", rc);
|
||||
CAM_ERR(CAM_SFE,
|
||||
"SFE bus wr init failed rc: %d", rc);
|
||||
goto disable_soc;
|
||||
}
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_SFE, "Enable soc done");
|
||||
|
||||
/* Do HW Reset */
|
||||
rc = cam_sfe_reset(hw_priv, NULL, 0);
|
||||
/* INIT SFE BUS RD */
|
||||
rc = core_info->sfe_bus_rd->hw_ops.init(
|
||||
core_info->sfe_bus_rd->bus_priv, NULL, 0);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SFE, "Reset Failed rc=%d", rc);
|
||||
goto deinit_sfe_res;
|
||||
CAM_ERR(CAM_SFE, "SFE bus rd init failed rc: %d", rc);
|
||||
goto deinit_bus_wr;
|
||||
}
|
||||
|
||||
sfe_hw->hw_state = CAM_HW_STATE_POWER_UP;
|
||||
return rc;
|
||||
|
||||
deinit_sfe_res:
|
||||
if (isp_res && isp_res->deinit)
|
||||
isp_res->deinit(isp_res, NULL, 0);
|
||||
deinit_bus_wr:
|
||||
core_info->sfe_bus_wr->hw_ops.deinit(
|
||||
core_info->sfe_bus_wr->bus_priv, NULL, 0);
|
||||
disable_soc:
|
||||
cam_sfe_disable_soc_resources(soc_info);
|
||||
decrement_open_cnt:
|
||||
@@ -93,10 +112,8 @@ int cam_sfe_deinit_hw(void *hw_priv, void *deinit_hw_args, uint32_t arg_size)
|
||||
struct cam_hw_info *sfe_hw = hw_priv;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
struct cam_sfe_hw_core_info *core_info = NULL;
|
||||
struct cam_isp_resource_node *isp_res = NULL;
|
||||
int rc = 0;
|
||||
|
||||
CAM_DBG(CAM_SFE, "Enter");
|
||||
if (!hw_priv) {
|
||||
CAM_ERR(CAM_SFE, "Invalid arguments");
|
||||
return -EINVAL;
|
||||
@@ -105,13 +122,15 @@ int cam_sfe_deinit_hw(void *hw_priv, void *deinit_hw_args, uint32_t arg_size)
|
||||
mutex_lock(&sfe_hw->hw_mutex);
|
||||
if (!sfe_hw->open_count) {
|
||||
mutex_unlock(&sfe_hw->hw_mutex);
|
||||
CAM_ERR(CAM_SFE, "Error! Unbalanced deinit");
|
||||
CAM_ERR(CAM_SFE, "Unbalanced deinit");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
sfe_hw->open_count--;
|
||||
if (sfe_hw->open_count) {
|
||||
mutex_unlock(&sfe_hw->hw_mutex);
|
||||
CAM_DBG(CAM_SFE, "open_cnt non-zero =%d", sfe_hw->open_count);
|
||||
CAM_DBG(CAM_SFE, "open_cnt non-zero: %d",
|
||||
sfe_hw->open_count);
|
||||
return 0;
|
||||
}
|
||||
mutex_unlock(&sfe_hw->hw_mutex);
|
||||
@@ -119,63 +138,196 @@ int cam_sfe_deinit_hw(void *hw_priv, void *deinit_hw_args, uint32_t arg_size)
|
||||
soc_info = &sfe_hw->soc_info;
|
||||
core_info = (struct cam_sfe_hw_core_info *)sfe_hw->core_info;
|
||||
|
||||
isp_res = (struct cam_isp_resource_node *)deinit_hw_args;
|
||||
if (isp_res && isp_res->deinit) {
|
||||
rc = isp_res->deinit(isp_res, NULL, 0);
|
||||
rc = core_info->sfe_bus_wr->hw_ops.deinit(
|
||||
core_info->sfe_bus_wr->bus_priv, NULL, 0);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SFE, "deinit failed");
|
||||
}
|
||||
CAM_ERR(CAM_SFE, "SFE bus wr deinit failed rc: %d",
|
||||
rc);
|
||||
|
||||
rc = core_info->sfe_bus_rd->hw_ops.deinit(
|
||||
core_info->sfe_bus_rd->bus_priv, NULL, 0);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SFE, "SFE bus rd deinit failed rc: %d",
|
||||
rc);
|
||||
|
||||
/* Turn OFF Regulators, Clocks and other SOC resources */
|
||||
CAM_DBG(CAM_SFE, "Disable SOC resource");
|
||||
CAM_DBG(CAM_SFE, "Disable SFE SOC resource");
|
||||
rc = cam_sfe_disable_soc_resources(soc_info);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SFE, "Disable SOC failed");
|
||||
|
||||
sfe_hw->hw_state = CAM_HW_STATE_POWER_DOWN;
|
||||
|
||||
CAM_DBG(CAM_SFE, "Exit");
|
||||
CAM_DBG(CAM_SFE, "SFE deinit done rc: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size)
|
||||
{
|
||||
CAM_DBG(CAM_SFE, "Enter");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cam_sfe_reserve(void *hw_priv, void *reserve_args, uint32_t arg_size)
|
||||
{
|
||||
CAM_DBG(CAM_SFE, "Enter");
|
||||
return 0;
|
||||
struct cam_sfe_hw_core_info *core_info = NULL;
|
||||
struct cam_hw_info *sfe_hw = hw_priv;
|
||||
struct cam_sfe_acquire_args *acquire;
|
||||
int rc = -ENODEV;
|
||||
|
||||
if (!hw_priv || !reserve_args || (arg_size !=
|
||||
sizeof(struct cam_sfe_acquire_args))) {
|
||||
CAM_ERR(CAM_SFE, "Invalid input arguments");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core_info = (struct cam_sfe_hw_core_info *)sfe_hw->core_info;
|
||||
acquire = (struct cam_sfe_acquire_args *)reserve_args;
|
||||
|
||||
CAM_DBG(CAM_SFE, "SFE acquire for res type: %d",
|
||||
acquire->rsrc_type);
|
||||
|
||||
mutex_lock(&sfe_hw->hw_mutex);
|
||||
if (acquire->rsrc_type == CAM_ISP_RESOURCE_SFE_IN)
|
||||
rc = core_info->sfe_top->hw_ops.reserve(
|
||||
core_info->sfe_top->top_priv,
|
||||
reserve_args, arg_size);
|
||||
else if (acquire->rsrc_type == CAM_ISP_RESOURCE_SFE_OUT)
|
||||
rc = core_info->sfe_bus_wr->hw_ops.reserve(
|
||||
core_info->sfe_bus_wr->bus_priv, acquire,
|
||||
sizeof(*acquire));
|
||||
else if (acquire->rsrc_type == CAM_ISP_RESOURCE_SFE_RD)
|
||||
rc = core_info->sfe_bus_rd->hw_ops.reserve(
|
||||
core_info->sfe_bus_rd->bus_priv, acquire,
|
||||
sizeof(*acquire));
|
||||
else
|
||||
CAM_ERR(CAM_SFE, "Invalid SFE res_type: %d",
|
||||
acquire->rsrc_type);
|
||||
mutex_unlock(&sfe_hw->hw_mutex);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_release(void *hw_priv, void *release_args, uint32_t arg_size)
|
||||
{
|
||||
CAM_DBG(CAM_SFE, "Enter");
|
||||
return 0;
|
||||
struct cam_sfe_hw_core_info *core_info = NULL;
|
||||
struct cam_hw_info *sfe_hw = hw_priv;
|
||||
struct cam_isp_resource_node *sfe_res;
|
||||
int rc = -ENODEV;
|
||||
|
||||
if (!hw_priv || !release_args ||
|
||||
(arg_size != sizeof(struct cam_isp_resource_node))) {
|
||||
CAM_ERR(CAM_SFE, "Invalid input arguments");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core_info = (struct cam_sfe_hw_core_info *) sfe_hw->core_info;
|
||||
sfe_res = (struct cam_isp_resource_node *) release_args;
|
||||
|
||||
CAM_DBG(CAM_SFE, "SFE release for res type: %d",
|
||||
sfe_res->res_type);
|
||||
|
||||
mutex_lock(&sfe_hw->hw_mutex);
|
||||
if (sfe_res->res_type == CAM_ISP_RESOURCE_SFE_IN)
|
||||
rc = core_info->sfe_top->hw_ops.release(
|
||||
core_info->sfe_top->top_priv, sfe_res,
|
||||
sizeof(struct cam_isp_resource_node));
|
||||
else if (sfe_res->res_type == CAM_ISP_RESOURCE_SFE_OUT)
|
||||
rc = core_info->sfe_bus_wr->hw_ops.release(
|
||||
core_info->sfe_bus_wr->bus_priv, sfe_res,
|
||||
sizeof(*sfe_res));
|
||||
else if (sfe_res->res_type == CAM_ISP_RESOURCE_SFE_RD)
|
||||
rc = core_info->sfe_bus_rd->hw_ops.release(
|
||||
core_info->sfe_bus_rd->bus_priv, sfe_res,
|
||||
sizeof(*sfe_res));
|
||||
else
|
||||
CAM_ERR(CAM_SFE, "Invalid SFE res type: %d",
|
||||
sfe_res->res_type);
|
||||
mutex_unlock(&sfe_hw->hw_mutex);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_start(void *hw_priv, void *start_args, uint32_t arg_size)
|
||||
{
|
||||
CAM_DBG(CAM_SFE, "Enter");
|
||||
return 0;
|
||||
struct cam_sfe_hw_core_info *core_info = NULL;
|
||||
struct cam_hw_info *sfe_hw = hw_priv;
|
||||
struct cam_isp_resource_node *sfe_res;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
int rc;
|
||||
|
||||
if (!hw_priv || !start_args ||
|
||||
(arg_size != sizeof(struct cam_isp_resource_node))) {
|
||||
CAM_ERR(CAM_SFE, "Invalid input arguments");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
soc_info = &sfe_hw->soc_info;
|
||||
core_info = (struct cam_sfe_hw_core_info *)sfe_hw->core_info;
|
||||
sfe_res = (struct cam_isp_resource_node *)start_args;
|
||||
core_info->tasklet_info = sfe_res->tasklet_info;
|
||||
|
||||
mutex_lock(&sfe_hw->hw_mutex);
|
||||
if (sfe_res->res_type == CAM_ISP_RESOURCE_SFE_IN) {
|
||||
rc = core_info->sfe_top->hw_ops.start(
|
||||
core_info->sfe_top->top_priv, sfe_res,
|
||||
sizeof(struct cam_isp_resource_node));
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SFE, "Failed to start SFE IN rc: %d", rc);
|
||||
} else if (sfe_res->res_type == CAM_ISP_RESOURCE_SFE_OUT) {
|
||||
rc = core_info->sfe_bus_wr->hw_ops.start(sfe_res, NULL, 0);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SFE, "Failed to start SFE BUS WR rc: %d",
|
||||
rc);
|
||||
} else if (sfe_res->res_type == CAM_ISP_RESOURCE_SFE_RD) {
|
||||
rc = core_info->sfe_bus_rd->hw_ops.start(sfe_res,
|
||||
NULL, 0);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SFE, "Failed to start SFE BUS RD rc: %d",
|
||||
rc);
|
||||
} else {
|
||||
CAM_ERR(CAM_SFE, "Invalid SFE res type:%d",
|
||||
sfe_res->res_type);
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&sfe_hw->hw_mutex);
|
||||
CAM_DBG(CAM_SFE,
|
||||
"Start for SFE res type: %u res id: %u res_state: %d rc: %d",
|
||||
sfe_res->res_type, sfe_res->res_id,
|
||||
sfe_res->res_state, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_stop(void *hw_priv, void *stop_args, uint32_t arg_size)
|
||||
{
|
||||
CAM_DBG(CAM_SFE, "Enter");
|
||||
return 0;
|
||||
}
|
||||
struct cam_sfe_hw_core_info *core_info = NULL;
|
||||
struct cam_hw_info *sfe_hw = hw_priv;
|
||||
struct cam_isp_resource_node *sfe_res;
|
||||
int rc = -EINVAL;
|
||||
|
||||
int cam_sfe_read(void *hw_priv, void *read_args, uint32_t arg_size)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
if (!hw_priv || !stop_args ||
|
||||
(arg_size != sizeof(struct cam_isp_resource_node))) {
|
||||
CAM_ERR(CAM_SFE, "Invalid input arguments");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int cam_sfe_write(void *hw_priv, void *write_args, uint32_t arg_size)
|
||||
{
|
||||
return -EPERM;
|
||||
core_info = (struct cam_sfe_hw_core_info *)sfe_hw->core_info;
|
||||
sfe_res = (struct cam_isp_resource_node *)stop_args;
|
||||
mutex_lock(&sfe_hw->hw_mutex);
|
||||
|
||||
if (sfe_res->res_type == CAM_ISP_RESOURCE_SFE_IN)
|
||||
rc = core_info->sfe_top->hw_ops.stop(
|
||||
core_info->sfe_top->top_priv, sfe_res,
|
||||
sizeof(struct cam_isp_resource_node));
|
||||
else if (sfe_res->res_type == CAM_ISP_RESOURCE_SFE_OUT)
|
||||
rc = core_info->sfe_bus_wr->hw_ops.stop(sfe_res, NULL, 0);
|
||||
else if (sfe_res->res_type == CAM_ISP_RESOURCE_SFE_RD)
|
||||
rc = core_info->sfe_bus_rd->hw_ops.stop(sfe_res, NULL, 0);
|
||||
else
|
||||
CAM_ERR(CAM_SFE, "Invalid SFE res type: %d", sfe_res->res_type);
|
||||
|
||||
mutex_unlock(&sfe_hw->hw_mutex);
|
||||
CAM_DBG(CAM_SFE,
|
||||
"Stop for SFE res type: %u res id: %u res_state: %d rc: %d",
|
||||
sfe_res->res_type, sfe_res->res_id,
|
||||
sfe_res->res_state, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
||||
@@ -185,7 +337,7 @@ int cam_sfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
struct cam_sfe_hw_core_info *core_info = NULL;
|
||||
struct cam_sfe_hw_info *hw_info = NULL;
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
if (!hw_priv) {
|
||||
CAM_ERR(CAM_SFE, "Invalid arguments");
|
||||
@@ -198,12 +350,35 @@ int cam_sfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
||||
|
||||
switch (cmd_type) {
|
||||
case CAM_ISP_HW_CMD_GET_CHANGE_BASE:
|
||||
case CAM_ISP_HW_CMD_GET_REG_UPDATE:
|
||||
rc = 0;
|
||||
case CAM_ISP_HW_CMD_CLOCK_UPDATE:
|
||||
case CAM_ISP_HW_CMD_BW_UPDATE_V2:
|
||||
case CAM_ISP_HW_CMD_BW_CONTROL:
|
||||
case CAM_ISP_HW_CMD_CORE_CONFIG:
|
||||
rc = core_info->sfe_top->hw_ops.process_cmd(
|
||||
core_info->sfe_top->top_priv, cmd_type,
|
||||
cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_GET_BUF_UPDATE:
|
||||
case CAM_ISP_HW_CMD_GET_HFR_UPDATE:
|
||||
case CAM_ISP_HW_CMD_STRIPE_UPDATE:
|
||||
case CAM_ISP_HW_CMD_WM_CONFIG_UPDATE:
|
||||
case CAM_ISP_HW_CMD_GET_SECURE_MODE:
|
||||
rc = core_info->sfe_bus_wr->hw_ops.process_cmd(
|
||||
core_info->sfe_bus_wr->bus_priv, cmd_type,
|
||||
cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_GET_HFR_UPDATE_RM:
|
||||
case CAM_ISP_HW_CMD_GET_BUF_UPDATE_RM:
|
||||
case CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD:
|
||||
rc = core_info->sfe_bus_rd->hw_ops.process_cmd(
|
||||
core_info->sfe_bus_rd->bus_priv, cmd_type,
|
||||
cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ:
|
||||
/* Needs to be handled based on hw_mgr change */
|
||||
break;
|
||||
|
||||
default:
|
||||
CAM_ERR(CAM_SFE, "Invalid cmd type:%d", cmd_type);
|
||||
CAM_ERR(CAM_SFE, "Invalid cmd type: %d", cmd_type);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
@@ -232,32 +407,80 @@ int cam_sfe_core_init(
|
||||
struct cam_hw_intf *hw_intf,
|
||||
struct cam_sfe_hw_info *sfe_hw_info)
|
||||
{
|
||||
int rc;
|
||||
|
||||
CAM_DBG(CAM_SFE, "Enter");
|
||||
rc = cam_sfe_top_init(sfe_hw_info->top_version, soc_info, hw_intf,
|
||||
sfe_hw_info->top_hw_info, &core_info->sfe_top);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SFE, "SFE top init failed rc: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_sfe_bus_init(sfe_hw_info->bus_wr_version, BUS_TYPE_SFE_WR,
|
||||
soc_info, hw_intf, sfe_hw_info->bus_wr_hw_info,
|
||||
&core_info->sfe_bus_wr);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SFE, "SFE bus wr init failed rc: %d", rc);
|
||||
goto deinit_top;
|
||||
}
|
||||
|
||||
rc = cam_sfe_bus_init(sfe_hw_info->bus_rd_version, BUS_TYPE_SFE_RD,
|
||||
soc_info, hw_intf, sfe_hw_info->bus_rd_hw_info,
|
||||
&core_info->sfe_bus_rd);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SFE, "SFE bus rd init failed rc: %d", rc);
|
||||
goto deinit_bus_wr;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&core_info->free_payload_list);
|
||||
spin_lock_init(&core_info->spin_lock);
|
||||
CAM_DBG(CAM_SFE, "SFE device [%u] INIT success",
|
||||
hw_intf->hw_idx);
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
deinit_bus_wr:
|
||||
cam_sfe_bus_deinit(BUS_TYPE_SFE_WR,
|
||||
sfe_hw_info->bus_wr_version,
|
||||
&core_info->sfe_bus_wr);
|
||||
deinit_top:
|
||||
cam_sfe_top_deinit(sfe_hw_info->top_version,
|
||||
&core_info->sfe_top);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_core_deinit(
|
||||
struct cam_sfe_hw_core_info *core_info,
|
||||
struct cam_sfe_hw_info *sfe_hw_info)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
int rc = -EINVAL, i;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&core_info->spin_lock, flags);
|
||||
|
||||
INIT_LIST_HEAD(&core_info->free_payload_list);
|
||||
for (i = 0; i < CAM_SFE_EVT_MAX; i++)
|
||||
INIT_LIST_HEAD(&core_info->evt_payload[i].list);
|
||||
|
||||
rc = cam_irq_controller_deinit(&core_info->sfe_irq_controller);
|
||||
rc = cam_sfe_bus_deinit(BUS_TYPE_SFE_RD,
|
||||
sfe_hw_info->bus_rd_version,
|
||||
&core_info->sfe_bus_rd);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SFE,
|
||||
"Error cam_irq_controller_deinit failed rc=%d", rc);
|
||||
"SFE bus rd deinit failed rc: %d", rc);
|
||||
|
||||
rc = cam_sfe_bus_deinit(BUS_TYPE_SFE_WR,
|
||||
sfe_hw_info->bus_wr_version,
|
||||
&core_info->sfe_bus_wr);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SFE,
|
||||
"SFE bus wr deinit failed rc: %d", rc);
|
||||
|
||||
rc = cam_sfe_top_deinit(sfe_hw_info->top_version,
|
||||
&core_info->sfe_top);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SFE,
|
||||
"SFE top deinit failed rc: %d", rc);
|
||||
|
||||
spin_unlock_irqrestore(&core_info->spin_lock, flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@@ -9,30 +9,48 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include "cam_hw_intf.h"
|
||||
#include "cam_sfe_hw_intf.h"
|
||||
|
||||
struct cam_sfe_hw_info {
|
||||
struct cam_irq_controller_reg_info *irq_reg_info;
|
||||
};
|
||||
#include "cam_sfe_bus.h"
|
||||
#include "cam_sfe_top.h"
|
||||
|
||||
#define CAM_SFE_EVT_MAX 256
|
||||
|
||||
struct cam_sfe_hw_info {
|
||||
struct cam_irq_controller_reg_info *irq_reg_info;
|
||||
|
||||
uint32_t bus_wr_version;
|
||||
void *bus_wr_hw_info;
|
||||
|
||||
uint32_t bus_rd_version;
|
||||
void *bus_rd_hw_info;
|
||||
|
||||
uint32_t top_version;
|
||||
void *top_hw_info;
|
||||
};
|
||||
|
||||
struct cam_sfe_hw_core_info {
|
||||
struct cam_sfe_hw_info *sfe_hw_info;
|
||||
struct cam_sfe_top *sfe_top;
|
||||
struct cam_sfe_bus *sfe_bus_wr;
|
||||
struct cam_sfe_bus *sfe_bus_rd;
|
||||
void *sfe_irq_controller;
|
||||
void *tasklet_info;
|
||||
struct cam_sfe_irq_evt_payload evt_payload[CAM_SFE_EVT_MAX];
|
||||
struct list_head free_payload_list;
|
||||
spinlock_t spin_lock;
|
||||
int irq_handle;
|
||||
};
|
||||
|
||||
int cam_sfe_get_hw_caps(void *device_priv,
|
||||
void *get_hw_cap_args, uint32_t arg_size);
|
||||
int cam_sfe_reset(void *device_priv,
|
||||
void *reset_core_args, uint32_t arg_size);
|
||||
int cam_sfe_read(void *device_priv,
|
||||
void *read_args, uint32_t arg_size);
|
||||
int cam_sfe_write(void *device_priv,
|
||||
void *write_args, uint32_t arg_size);
|
||||
int cam_sfe_init_hw(void *device_priv,
|
||||
void *init_hw_args, uint32_t arg_size);
|
||||
int cam_sfe_deinit_hw(void *hw_priv,
|
||||
void *deinit_hw_args, uint32_t arg_size);
|
||||
int cam_sfe_reset(void *device_priv,
|
||||
void *reset_core_args, uint32_t arg_size);
|
||||
int cam_sfe_reserve(void *device_priv,
|
||||
void *reserve_args, uint32_t arg_size);
|
||||
int cam_sfe_release(void *device_priv,
|
||||
@@ -41,10 +59,6 @@ int cam_sfe_start(void *device_priv,
|
||||
void *start_args, uint32_t arg_size);
|
||||
int cam_sfe_stop(void *device_priv,
|
||||
void *stop_args, uint32_t arg_size);
|
||||
int cam_sfe_read(void *device_priv,
|
||||
void *read_args, uint32_t arg_size);
|
||||
int cam_sfe_write(void *device_priv,
|
||||
void *write_args, uint32_t arg_size);
|
||||
int cam_sfe_process_cmd(void *device_priv, uint32_t cmd_type,
|
||||
void *cmd_args, uint32_t arg_size);
|
||||
|
||||
|
@@ -6,65 +6,71 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/module.h>
|
||||
#include "cam_sfe_dev.h"
|
||||
#include "cam_sfe_core.h"
|
||||
#include "cam_sfe_soc.h"
|
||||
#include "cam_sfe_hw_intf.h"
|
||||
#include "cam_sfe680.h"
|
||||
#include "cam_debug_util.h"
|
||||
#include "camera_main.h"
|
||||
|
||||
static struct cam_hw_intf *sfe_instance;
|
||||
static struct cam_hw_intf *cam_sfe_hw_list[CAM_SFE_HW_NUM_MAX];
|
||||
|
||||
static char sfe_dev_name[8];
|
||||
|
||||
int cam_sfe_probe(struct platform_device *pdev)
|
||||
static int cam_sfe_component_bind(struct device *dev,
|
||||
struct device *master_dev, void *data)
|
||||
{
|
||||
|
||||
struct cam_hw_info *sfe_info = NULL;
|
||||
struct cam_hw_intf *sfe_intf = NULL;
|
||||
struct cam_hw_intf *sfe_hw_intf = NULL;
|
||||
const struct of_device_id *match_dev = NULL;
|
||||
struct cam_sfe_hw_core_info *core_info = NULL;
|
||||
struct cam_sfe_hw_info *hw_info = NULL;
|
||||
struct platform_device *pdev = NULL;
|
||||
int rc = 0;
|
||||
|
||||
sfe_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
|
||||
if (!sfe_intf) {
|
||||
pdev = to_platform_device(dev);
|
||||
sfe_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
|
||||
if (!sfe_hw_intf) {
|
||||
rc = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
of_property_read_u32(pdev->dev.of_node,
|
||||
"cell-index", &sfe_intf->hw_idx);
|
||||
"cell-index", &sfe_hw_intf->hw_idx);
|
||||
|
||||
sfe_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
|
||||
if (!sfe_info) {
|
||||
rc = -ENOMEM;
|
||||
goto free_sfe_intf;
|
||||
goto free_sfe_hw_intf;
|
||||
}
|
||||
|
||||
memset(sfe_dev_name, 0, sizeof(sfe_dev_name));
|
||||
snprintf(sfe_dev_name, sizeof(sfe_dev_name),
|
||||
"sfe%1u", sfe_intf->hw_idx);
|
||||
"sfe%1u", sfe_hw_intf->hw_idx);
|
||||
|
||||
sfe_info->soc_info.pdev = pdev;
|
||||
sfe_info->soc_info.dev = &pdev->dev;
|
||||
sfe_info->soc_info.dev_name = sfe_dev_name;
|
||||
sfe_intf->hw_priv = sfe_info;
|
||||
sfe_intf->hw_ops.get_hw_caps = cam_sfe_get_hw_caps;
|
||||
sfe_intf->hw_ops.init = cam_sfe_init_hw;
|
||||
sfe_intf->hw_ops.deinit = cam_sfe_deinit_hw;
|
||||
sfe_intf->hw_ops.reset = cam_sfe_reset;
|
||||
sfe_intf->hw_ops.reserve = cam_sfe_reserve;
|
||||
sfe_intf->hw_ops.release = cam_sfe_release;
|
||||
sfe_intf->hw_ops.start = cam_sfe_start;
|
||||
sfe_intf->hw_ops.stop = cam_sfe_stop;
|
||||
sfe_intf->hw_ops.read = cam_sfe_read;
|
||||
sfe_intf->hw_ops.write = cam_sfe_write;
|
||||
sfe_intf->hw_ops.process_cmd = cam_sfe_process_cmd;
|
||||
sfe_intf->hw_type = CAM_ISP_HW_TYPE_SFE;
|
||||
sfe_hw_intf->hw_priv = sfe_info;
|
||||
sfe_hw_intf->hw_ops.get_hw_caps = cam_sfe_get_hw_caps;
|
||||
sfe_hw_intf->hw_ops.init = cam_sfe_init_hw;
|
||||
sfe_hw_intf->hw_ops.deinit = cam_sfe_deinit_hw;
|
||||
sfe_hw_intf->hw_ops.reset = cam_sfe_reset;
|
||||
sfe_hw_intf->hw_ops.reserve = cam_sfe_reserve;
|
||||
sfe_hw_intf->hw_ops.release = cam_sfe_release;
|
||||
sfe_hw_intf->hw_ops.start = cam_sfe_start;
|
||||
sfe_hw_intf->hw_ops.stop = cam_sfe_stop;
|
||||
sfe_hw_intf->hw_ops.read = cam_sfe_read;
|
||||
sfe_hw_intf->hw_ops.write = cam_sfe_write;
|
||||
sfe_hw_intf->hw_ops.process_cmd = cam_sfe_process_cmd;
|
||||
sfe_hw_intf->hw_type = CAM_ISP_HW_TYPE_SFE;
|
||||
|
||||
CAM_DBG(CAM_SFE, "type %d index %d",
|
||||
sfe_intf->hw_type, sfe_intf->hw_idx);
|
||||
CAM_DBG(CAM_SFE, "SFE component bind type %d index %d",
|
||||
sfe_hw_intf->hw_type, sfe_hw_intf->hw_idx);
|
||||
|
||||
platform_set_drvdata(pdev, sfe_intf);
|
||||
platform_set_drvdata(pdev, sfe_hw_intf);
|
||||
|
||||
sfe_info->core_info = kzalloc(sizeof(struct cam_sfe_hw_core_info),
|
||||
GFP_KERNEL);
|
||||
@@ -93,7 +99,7 @@ int cam_sfe_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
rc = cam_sfe_core_init(core_info, &sfe_info->soc_info,
|
||||
sfe_intf, hw_info);
|
||||
sfe_hw_intf, hw_info);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_SFE, "Failed to init core rc=%d", rc);
|
||||
goto deinit_soc;
|
||||
@@ -104,9 +110,11 @@ int cam_sfe_probe(struct platform_device *pdev)
|
||||
spin_lock_init(&sfe_info->hw_lock);
|
||||
init_completion(&sfe_info->hw_complete);
|
||||
|
||||
sfe_instance = sfe_intf;
|
||||
if (sfe_hw_intf->hw_idx < CAM_SFE_HW_NUM_MAX)
|
||||
cam_sfe_hw_list[sfe_hw_intf->hw_idx] = sfe_hw_intf;
|
||||
|
||||
CAM_DBG(CAM_SFE, "SFE%d probe successful", sfe_intf->hw_idx);
|
||||
CAM_DBG(CAM_SFE, "SFE%d bound successfully",
|
||||
sfe_hw_intf->hw_idx);
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -117,40 +125,45 @@ free_core_info:
|
||||
kfree(sfe_info->core_info);
|
||||
free_sfe_hw:
|
||||
kfree(sfe_info);
|
||||
free_sfe_intf:
|
||||
kfree(sfe_intf);
|
||||
free_sfe_hw_intf:
|
||||
kfree(sfe_hw_intf);
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_remove(struct platform_device *pdev)
|
||||
static void cam_sfe_component_unbind(struct device *dev,
|
||||
struct device *master_dev, void *data)
|
||||
{
|
||||
|
||||
struct cam_hw_info *sfe_info = NULL;
|
||||
struct cam_hw_intf *sfe_intf = NULL;
|
||||
struct cam_hw_intf *sfe_hw_intf = NULL;
|
||||
struct cam_sfe_hw_core_info *core_info = NULL;
|
||||
struct platform_device *pdev = NULL;
|
||||
int rc = 0;
|
||||
|
||||
sfe_intf = platform_get_drvdata(pdev);
|
||||
if (!sfe_intf) {
|
||||
pdev = to_platform_device(dev);
|
||||
sfe_hw_intf = platform_get_drvdata(pdev);
|
||||
if (!sfe_hw_intf) {
|
||||
CAM_ERR(CAM_SFE, "Error! No data in pdev");
|
||||
return -EINVAL;
|
||||
return;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_SFE, "type %d index %d",
|
||||
sfe_intf->hw_type, sfe_intf->hw_idx);
|
||||
CAM_DBG(CAM_SFE, "SFE component unbound type %d index %d",
|
||||
sfe_hw_intf->hw_type, sfe_hw_intf->hw_idx);
|
||||
|
||||
sfe_instance = NULL;
|
||||
if (sfe_hw_intf->hw_idx < CAM_SFE_HW_NUM_MAX)
|
||||
cam_sfe_hw_list[sfe_hw_intf->hw_idx] = NULL;
|
||||
|
||||
sfe_info = sfe_intf->hw_priv;
|
||||
sfe_info = sfe_hw_intf->hw_priv;
|
||||
if (!sfe_info) {
|
||||
CAM_ERR(CAM_SFE, "Error! HW data is NULL");
|
||||
CAM_ERR(CAM_SFE, "HW data is NULL");
|
||||
rc = -ENODEV;
|
||||
goto free_sfe_intf;
|
||||
goto free_sfe_hw_intf;
|
||||
}
|
||||
|
||||
core_info = (struct cam_sfe_hw_core_info *)sfe_info->core_info;
|
||||
if (!core_info) {
|
||||
CAM_ERR(CAM_SFE, "Error! core data NULL");
|
||||
CAM_ERR(CAM_SFE, "core data NULL");
|
||||
rc = -EINVAL;
|
||||
goto deinit_soc;
|
||||
}
|
||||
@@ -169,25 +182,80 @@ deinit_soc:
|
||||
mutex_destroy(&sfe_info->hw_mutex);
|
||||
kfree(sfe_info);
|
||||
|
||||
CAM_DBG(CAM_SFE, "SFE%d remove successful", sfe_intf->hw_idx);
|
||||
CAM_DBG(CAM_SFE, "SFE%d remove successful", sfe_hw_intf->hw_idx);
|
||||
|
||||
free_sfe_intf:
|
||||
kfree(sfe_intf);
|
||||
free_sfe_hw_intf:
|
||||
kfree(sfe_hw_intf);
|
||||
}
|
||||
|
||||
const static struct component_ops cam_sfe_component_ops = {
|
||||
.bind = cam_sfe_component_bind,
|
||||
.unbind = cam_sfe_component_unbind,
|
||||
};
|
||||
|
||||
int cam_sfe_probe(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
CAM_DBG(CAM_SFE, "Adding SFE component");
|
||||
rc = component_add(&pdev->dev, &cam_sfe_component_ops);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SFE, "failed to add component rc: %d", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_hw_init(struct cam_hw_intf **sfe_intf, uint32_t hw_idx)
|
||||
int cam_sfe_remove(struct platform_device *pdev)
|
||||
{
|
||||
component_del(&pdev->dev, &cam_sfe_component_ops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cam_sfe_hw_init(struct cam_hw_intf **sfe_hw, uint32_t hw_idx)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (sfe_instance) {
|
||||
*sfe_intf = sfe_instance;
|
||||
if (cam_sfe_hw_list[hw_idx]) {
|
||||
*sfe_hw = cam_sfe_hw_list[hw_idx];
|
||||
rc = 0;
|
||||
} else {
|
||||
*sfe_intf = NULL;
|
||||
*sfe_hw = NULL;
|
||||
rc = -ENODEV;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct of_device_id cam_sfe_dt_match[] = {
|
||||
{
|
||||
.compatible = "",
|
||||
.data = &cam_sfe680_hw_info,
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cam_sfe_dt_match);
|
||||
|
||||
struct platform_driver cam_sfe_driver = {
|
||||
.probe = cam_sfe_probe,
|
||||
.remove = cam_sfe_remove,
|
||||
.driver = {
|
||||
.name = "cam_sfe",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = cam_sfe_dt_match,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
};
|
||||
|
||||
int cam_sfe_init_module(void)
|
||||
{
|
||||
return platform_driver_register(&cam_sfe_driver);
|
||||
}
|
||||
|
||||
|
||||
void cam_sfe_exit_module(void)
|
||||
{
|
||||
platform_driver_unregister(&cam_sfe_driver);
|
||||
}
|
||||
|
||||
MODULE_DESCRIPTION("CAM SFE driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -6,30 +6,18 @@
|
||||
#ifndef _CAM_SFE_DEV_H_
|
||||
#define _CAM_SFE_DEV_H_
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
/*
|
||||
* cam_sfe_probe()
|
||||
*
|
||||
* @brief: Driver probe function called on Boot
|
||||
*
|
||||
* @pdev: Platform Device pointer
|
||||
*
|
||||
/**
|
||||
* @brief : API to register SFE hw to platform framework.
|
||||
* @Return: 0: Success
|
||||
* Non-zero: Failure
|
||||
*/
|
||||
int cam_sfe_probe(struct platform_device *pdev);
|
||||
int cam_sfe_init_module(void);
|
||||
|
||||
/*
|
||||
* cam_sfe_remove()
|
||||
*
|
||||
* @brief: Driver remove function
|
||||
*
|
||||
* @pdev: Platform Device pointer
|
||||
*
|
||||
/**
|
||||
* @brief : API to remove SFE Hw from platform framework.
|
||||
* @Return: 0: Success
|
||||
* Non-zero: Failure
|
||||
*/
|
||||
int cam_sfe_remove(struct platform_device *pdev);
|
||||
void cam_sfe_exit_module(void);
|
||||
|
||||
#endif /* _CAM_SFE_DEV_H_ */
|
||||
|
@@ -50,11 +50,26 @@ int cam_sfe_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
||||
irq_handler_t irq_handler_func, void *irq_data)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_sfe_soc_private *soc_private;
|
||||
struct cam_cpas_register_params cpas_register_param;
|
||||
|
||||
soc_private = kzalloc(sizeof(struct cam_sfe_soc_private),
|
||||
GFP_KERNEL);
|
||||
if (!soc_private)
|
||||
return -ENOMEM;
|
||||
|
||||
soc_info->soc_private = soc_private;
|
||||
rc = cam_cpas_get_cpas_hw_version(&soc_private->cpas_version);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SFE, "Error! Invalid cpas version rc=%d", rc);
|
||||
goto free_soc_private;
|
||||
}
|
||||
soc_info->hw_version = soc_private->cpas_version;
|
||||
|
||||
rc = cam_sfe_get_dt_properties(soc_info);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_SFE, "Error Get DT properties failed rc=%d", rc);
|
||||
goto end;
|
||||
goto free_soc_private;
|
||||
}
|
||||
|
||||
rc = cam_sfe_request_platform_resource(soc_info,
|
||||
@@ -62,41 +77,104 @@ int cam_sfe_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_SFE,
|
||||
"Error Request platform resources failed rc=%d", rc);
|
||||
goto end;
|
||||
goto free_soc_private;
|
||||
}
|
||||
|
||||
end:
|
||||
memset(&cpas_register_param, 0, sizeof(cpas_register_param));
|
||||
strlcpy(cpas_register_param.identifier, "sfe",
|
||||
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) {
|
||||
CAM_ERR(CAM_SFE, "CPAS registration failed rc=%d", rc);
|
||||
goto release_soc;
|
||||
} else {
|
||||
soc_private->cpas_handle = cpas_register_param.client_handle;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
release_soc:
|
||||
cam_soc_util_release_platform_resource(soc_info);
|
||||
free_soc_private:
|
||||
kfree(soc_private);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_deinit_soc_resources(struct cam_hw_soc_info *soc_info)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_sfe_soc_private *soc_private;
|
||||
|
||||
if (!soc_info) {
|
||||
CAM_ERR(CAM_SFE, "Error soc_info NULL");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
soc_private = soc_info->soc_private;
|
||||
if (!soc_private) {
|
||||
CAM_ERR(CAM_SFE, "Error! soc_private NULL");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rc = cam_cpas_unregister_client(soc_private->cpas_handle);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SFE, "CPAS unregistration failed rc=%d", rc);
|
||||
|
||||
rc = cam_sfe_release_platform_resource(soc_info);
|
||||
if (rc < 0)
|
||||
CAM_ERR(CAM_SFE,
|
||||
"Error Release platform resources failed rc=%d", rc);
|
||||
|
||||
kfree(soc_private);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_enable_soc_resources(struct cam_hw_soc_info *soc_info)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_sfe_soc_private *soc_private;
|
||||
struct cam_ahb_vote ahb_vote;
|
||||
struct cam_axi_vote axi_vote = {0};
|
||||
|
||||
rc = cam_soc_util_enable_platform_resource(soc_info, true,
|
||||
CAM_TURBO_VOTE, true);
|
||||
if (!soc_info) {
|
||||
CAM_ERR(CAM_SFE, "Error! Invalid params");
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
soc_private = soc_info->soc_private;
|
||||
|
||||
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_SFE_NRDI;
|
||||
axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_WRITE;
|
||||
axi_vote.axi_path[0].camnoc_bw = 10640000000L;
|
||||
axi_vote.axi_path[0].mnoc_ab_bw = 10640000000L;
|
||||
axi_vote.axi_path[0].mnoc_ib_bw = 10640000000L;
|
||||
|
||||
rc = cam_cpas_start(soc_private->cpas_handle,
|
||||
&ahb_vote, &axi_vote);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SFE, "Error enable platform failed rc=%d", rc);
|
||||
CAM_ERR(CAM_SFE, "CPAS start failed rc=%d", rc);
|
||||
rc = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
rc = cam_soc_util_enable_platform_resource(soc_info, true,
|
||||
CAM_LOWSVS_VOTE, true);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SFE, "Enable platform failed rc=%d", rc);
|
||||
goto stop_cpas;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
stop_cpas:
|
||||
cam_cpas_stop(soc_private->cpas_handle);
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
@@ -113,14 +191,26 @@ int cam_sfe_soc_disable_clk(struct cam_hw_soc_info *soc_info,
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
|
||||
int cam_sfe_disable_soc_resources(struct cam_hw_soc_info *soc_info)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_sfe_soc_private *soc_private;
|
||||
|
||||
if (!soc_info) {
|
||||
CAM_ERR(CAM_SFE, "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_SFE, "Disable platform failed rc=%d", rc);
|
||||
|
||||
rc = cam_cpas_stop(soc_private->cpas_handle);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SFE, "CPAS stop failed rc=%d", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ struct cam_sfe_soc_private {
|
||||
* Non-zero: Failure
|
||||
*/
|
||||
int cam_sfe_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
||||
irq_handler_t vfe_irq_handler, void *irq_data);
|
||||
irq_handler_t sfe_irq_handler, void *irq_data);
|
||||
|
||||
/*
|
||||
* cam_sfe_deinit_soc_resources()
|
||||
|
@@ -0,0 +1,91 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "cam_sfe_bus.h"
|
||||
#include "cam_sfe_bus_rd.h"
|
||||
#include "cam_sfe_bus_wr.h"
|
||||
#include "cam_debug_util.h"
|
||||
|
||||
int cam_sfe_bus_init(
|
||||
uint32_t bus_version,
|
||||
int bus_type,
|
||||
struct cam_hw_soc_info *soc_info,
|
||||
struct cam_hw_intf *hw_intf,
|
||||
void *bus_hw_info,
|
||||
struct cam_sfe_bus **sfe_bus)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
|
||||
switch (bus_type) {
|
||||
case BUS_TYPE_SFE_WR:
|
||||
switch (bus_version) {
|
||||
case CAM_SFE_BUS_WR_VER_1_0:
|
||||
rc = cam_sfe_bus_wr_init(soc_info, hw_intf,
|
||||
bus_hw_info, sfe_bus);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_SFE, "Unsupported Bus WR Version 0x%x",
|
||||
bus_version);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BUS_TYPE_SFE_RD:
|
||||
switch (bus_version) {
|
||||
case CAM_SFE_BUS_RD_VER_1_0:
|
||||
rc = cam_sfe_bus_rd_init(soc_info, hw_intf,
|
||||
bus_hw_info, sfe_bus);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_SFE, "Unsupported Bus RD Version 0x%x",
|
||||
bus_version);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_SFE, "Unsupported Bus type %d", bus_type);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_bus_deinit(
|
||||
uint32_t bus_version,
|
||||
int bus_type,
|
||||
struct cam_sfe_bus **sfe_bus)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
|
||||
switch (bus_type) {
|
||||
case BUS_TYPE_SFE_WR:
|
||||
switch (bus_version) {
|
||||
case CAM_SFE_BUS_WR_VER_1_0:
|
||||
rc = cam_sfe_bus_wr_deinit(sfe_bus);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_SFE, "Unsupported Bus WR Version 0x%x",
|
||||
bus_version);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BUS_TYPE_SFE_RD:
|
||||
switch (bus_version) {
|
||||
case CAM_SFE_BUS_RD_VER_1_0:
|
||||
rc = cam_sfe_bus_rd_deinit(sfe_bus);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_SFE, "Unsupported Bus RD Version 0x%x",
|
||||
bus_version);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_SFE, "Unsupported Bus type %d", bus_type);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
1144
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_rd.c
Normal file
1144
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_rd.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,115 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_SFE_BUS_RD_H_
|
||||
#define _CAM_SFE_BUS_RD_H_
|
||||
|
||||
#include "cam_sfe_bus.h"
|
||||
|
||||
#define CAM_SFE_BUS_RD_MAX_CLIENTS 3
|
||||
|
||||
enum cam_sfe_bus_rd_type {
|
||||
CAM_SFE_BUS_RD_RDI0,
|
||||
CAM_SFE_BUS_RD_RDI1,
|
||||
CAM_SFE_BUS_RD_RDI2,
|
||||
CAM_SFE_BUS_RD_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_bus_rd_reg_offset_common:
|
||||
*
|
||||
* @Brief: Common registers across BUS RD Clients
|
||||
*/
|
||||
struct cam_sfe_bus_rd_reg_offset_common {
|
||||
uint32_t hw_version;
|
||||
uint32_t misr_reset;
|
||||
uint32_t pwr_iso_cfg;
|
||||
uint32_t input_if_cmd;
|
||||
uint32_t test_bus_ctrl;
|
||||
uint32_t security_cfg;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_bus_rd_reg_offset_bus_client:
|
||||
*
|
||||
* @Brief: Register offsets for BUS RD Clients
|
||||
*/
|
||||
struct cam_sfe_bus_rd_reg_offset_bus_client {
|
||||
uint32_t cfg;
|
||||
uint32_t image_addr;
|
||||
uint32_t buf_width;
|
||||
uint32_t buf_height;
|
||||
uint32_t stride;
|
||||
uint32_t unpacker_cfg;
|
||||
uint32_t latency_buf_allocation;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_bus_rd_hw_info:
|
||||
*
|
||||
* @Brief: HW capability of SFE Bus RD Client
|
||||
*/
|
||||
struct cam_sfe_bus_rd_info {
|
||||
enum cam_sfe_bus_rd_type sfe_bus_rd_type;
|
||||
uint32_t max_width;
|
||||
uint32_t max_height;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_bus_rd_hw_info:
|
||||
*
|
||||
* @Brief: HW register info for entire Bus
|
||||
*
|
||||
* @common_reg: Common register details
|
||||
* @num_client: Number of bus rd clients
|
||||
* @bus_client_reg: Bus client register info
|
||||
* @num_bus_rd_resc: Number of SFE BUS RD masters
|
||||
* @sfe_bus_rd_info: SFE bus rd client info
|
||||
* @top_irq_shift: Top irq shift val
|
||||
*/
|
||||
struct cam_sfe_bus_rd_hw_info {
|
||||
struct cam_sfe_bus_rd_reg_offset_common common_reg;
|
||||
uint32_t num_client;
|
||||
struct cam_sfe_bus_rd_reg_offset_bus_client
|
||||
bus_client_reg[CAM_SFE_BUS_RD_MAX_CLIENTS];
|
||||
uint32_t num_bus_rd_resc;
|
||||
struct cam_sfe_bus_rd_info
|
||||
sfe_bus_rd_info[CAM_SFE_BUS_RD_MAX];
|
||||
uint32_t top_irq_shift;
|
||||
};
|
||||
|
||||
/*
|
||||
* cam_sfe_bus_rd_init()
|
||||
*
|
||||
* @Brief: Initialize Bus layer
|
||||
*
|
||||
* @soc_info: Soc Information for the associated HW
|
||||
* @hw_intf: HW Interface of HW to which this resource belongs
|
||||
* @bus_hw_info: BUS HW info that contains details of BUS registers
|
||||
* @sfe_bus: Pointer to sfe_bus structure which will be filled
|
||||
* and returned on successful initialize
|
||||
*
|
||||
* @Return: 0: Success
|
||||
* Non-zero: Failure
|
||||
*/
|
||||
int cam_sfe_bus_rd_init(
|
||||
struct cam_hw_soc_info *soc_info,
|
||||
struct cam_hw_intf *hw_intf,
|
||||
void *bus_hw_info,
|
||||
struct cam_sfe_bus **sfe_bus);
|
||||
|
||||
/*
|
||||
* cam_sfe_bus_rd_deinit()
|
||||
*
|
||||
* @Brief: Deinitialize Bus layer
|
||||
*
|
||||
* @vfe_bus: Pointer to sfe_bus structure to deinitialize
|
||||
*
|
||||
* @Return: 0: Success
|
||||
* Non-zero: Failure
|
||||
*/
|
||||
int cam_sfe_bus_rd_deinit(struct cam_sfe_bus **sfe_bus);
|
||||
|
||||
#endif /* _CAM_SFE_BUS_RD_H_ */
|
1995
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_wr.c
Normal file
1995
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_wr.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,181 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CAM_SFE_BUS_WR_H_
|
||||
#define _CAM_SFE_BUS_WR_H_
|
||||
|
||||
#include "cam_irq_controller.h"
|
||||
#include "cam_sfe_bus.h"
|
||||
|
||||
#define CAM_SFE_BUS_WR_MAX_CLIENTS 13
|
||||
#define CAM_SFE_BUS_WR_MAX_SUB_GRPS 6
|
||||
|
||||
enum cam_sfe_bus_wr_src_grp {
|
||||
CAM_SFE_BUS_WR_SRC_GRP_0,
|
||||
CAM_SFE_BUS_WR_SRC_GRP_1,
|
||||
CAM_SFE_BUS_WR_SRC_GRP_2,
|
||||
CAM_SFE_BUS_WR_SRC_GRP_3,
|
||||
CAM_SFE_BUS_WR_SRC_GRP_4,
|
||||
CAM_SFE_BUS_WR_SRC_GRP_5,
|
||||
CAM_SFE_BUS_WR_SRC_GRP_MAX,
|
||||
};
|
||||
|
||||
enum cam_sfe_bus_wr_comp_grp_type {
|
||||
CAM_SFE_BUS_WR_COMP_GRP_0,
|
||||
CAM_SFE_BUS_WR_COMP_GRP_1,
|
||||
CAM_SFE_BUS_WR_COMP_GRP_2,
|
||||
CAM_SFE_BUS_WR_COMP_GRP_3,
|
||||
CAM_SFE_BUS_WR_COMP_GRP_4,
|
||||
CAM_SFE_BUS_WR_COMP_GRP_5,
|
||||
CAM_SFE_BUS_WR_COMP_GRP_6,
|
||||
CAM_SFE_BUS_WR_COMP_GRP_7,
|
||||
CAM_SFE_BUS_WR_COMP_GRP_8,
|
||||
CAM_SFE_BUS_WR_COMP_GRP_9,
|
||||
CAM_SFE_BUS_WR_COMP_GRP_MAX,
|
||||
};
|
||||
|
||||
enum cam_sfe_bus_sfe_out_type {
|
||||
CAM_SFE_BUS_SFE_OUT_RDI0,
|
||||
CAM_SFE_BUS_SFE_OUT_RDI1,
|
||||
CAM_SFE_BUS_SFE_OUT_RDI2,
|
||||
CAM_SFE_BUS_SFE_OUT_RDI3,
|
||||
CAM_SFE_BUS_SFE_OUT_RDI4,
|
||||
CAM_SFE_BUS_SFE_OUT_RAW_DUMP,
|
||||
CAM_SFE_BUS_SFE_OUT_LCR,
|
||||
CAM_SFE_BUS_SFE_OUT_BE_0,
|
||||
CAM_SFE_BUS_SFE_OUT_BHIST_0,
|
||||
CAM_SFE_BUS_SFE_OUT_BE_1,
|
||||
CAM_SFE_BUS_SFE_OUT_BHIST_1,
|
||||
CAM_SFE_BUS_SFE_OUT_BE_2,
|
||||
CAM_SFE_BUS_SFE_OUT_BHIST_2,
|
||||
CAM_SFE_BUS_SFE_OUT_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_bus_reg_offset_common:
|
||||
*
|
||||
* @Brief: Common registers across all BUS Clients
|
||||
*/
|
||||
struct cam_sfe_bus_reg_offset_common {
|
||||
uint32_t hw_version;
|
||||
uint32_t cgc_ovd;
|
||||
uint32_t if_frameheader_cfg[CAM_SFE_BUS_WR_MAX_SUB_GRPS];
|
||||
uint32_t pwr_iso_cfg;
|
||||
uint32_t overflow_status_clear;
|
||||
uint32_t ccif_violation_status;
|
||||
uint32_t overflow_status;
|
||||
uint32_t image_size_violation_status;
|
||||
uint32_t debug_status_top_cfg;
|
||||
uint32_t debug_status_top;
|
||||
uint32_t test_bus_ctrl;
|
||||
uint32_t top_irq_mask_0;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_bus_reg_offset_bus_client:
|
||||
*
|
||||
* @Brief: Register offsets for BUS Clients
|
||||
*/
|
||||
struct cam_sfe_bus_reg_offset_bus_client {
|
||||
uint32_t cfg;
|
||||
uint32_t image_addr;
|
||||
uint32_t frame_incr;
|
||||
uint32_t image_cfg_0;
|
||||
uint32_t image_cfg_1;
|
||||
uint32_t image_cfg_2;
|
||||
uint32_t packer_cfg;
|
||||
uint32_t frame_header_addr;
|
||||
uint32_t frame_header_incr;
|
||||
uint32_t frame_header_cfg;
|
||||
uint32_t line_done_cfg;
|
||||
uint32_t irq_subsample_period;
|
||||
uint32_t irq_subsample_pattern;
|
||||
uint32_t framedrop_period;
|
||||
uint32_t framedrop_pattern;
|
||||
uint32_t system_cache_cfg;
|
||||
uint32_t addr_status_0;
|
||||
uint32_t addr_status_1;
|
||||
uint32_t addr_status_2;
|
||||
uint32_t addr_status_3;
|
||||
uint32_t debug_status_cfg;
|
||||
uint32_t debug_status_0;
|
||||
uint32_t debug_status_1;
|
||||
uint32_t comp_group;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_bus_sfe_out_hw_info:
|
||||
*
|
||||
* @Brief: HW capability of SFE Bus Client
|
||||
*/
|
||||
struct cam_sfe_bus_sfe_out_hw_info {
|
||||
enum cam_sfe_bus_sfe_out_type sfe_out_type;
|
||||
uint32_t max_width;
|
||||
uint32_t max_height;
|
||||
uint32_t source_group;
|
||||
uint32_t num_wm;
|
||||
uint32_t wm_idx;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_bus_wr_hw_info:
|
||||
*
|
||||
* @Brief: HW register info for entire Bus
|
||||
*
|
||||
* @common_reg: Common register details
|
||||
* @num_client: Total number of write clients
|
||||
* @bus_client_reg: Bus client register info
|
||||
* @sfe_out_hw_info: SFE output capability
|
||||
* @num_comp_grp: Number of composite groups
|
||||
* @comp_done_shift: Mask shift for comp done mask
|
||||
* @top_irq_shift: Mask shift for top level BUS WR irq
|
||||
*/
|
||||
struct cam_sfe_bus_wr_hw_info {
|
||||
struct cam_sfe_bus_reg_offset_common common_reg;
|
||||
uint32_t num_client;
|
||||
struct cam_sfe_bus_reg_offset_bus_client
|
||||
bus_client_reg[CAM_SFE_BUS_WR_MAX_CLIENTS];
|
||||
uint32_t num_out;
|
||||
struct cam_sfe_bus_sfe_out_hw_info
|
||||
sfe_out_hw_info[CAM_SFE_BUS_SFE_OUT_MAX];
|
||||
uint32_t num_comp_grp;
|
||||
uint32_t comp_done_shift;
|
||||
uint32_t top_irq_shift;
|
||||
};
|
||||
|
||||
/*
|
||||
* cam_sfe_bus_wr_init()
|
||||
*
|
||||
* @Brief: Initialize Bus layer
|
||||
*
|
||||
* @soc_info: Soc Information for the associated HW
|
||||
* @hw_intf: HW Interface of HW to which this resource belongs
|
||||
* @bus_hw_info: BUS HW info that contains details of BUS registers
|
||||
* @sfe_bus: Pointer to sfe_bus structure which will be filled
|
||||
* and returned on successful initialize
|
||||
*
|
||||
* @Return: 0: Success
|
||||
* Non-zero: Failure
|
||||
*/
|
||||
int cam_sfe_bus_wr_init(
|
||||
struct cam_hw_soc_info *soc_info,
|
||||
struct cam_hw_intf *hw_intf,
|
||||
void *bus_hw_info,
|
||||
struct cam_sfe_bus **sfe_bus);
|
||||
|
||||
/*
|
||||
* cam_sfe_bus_wr_deinit()
|
||||
*
|
||||
* @Brief: Deinitialize Bus layer
|
||||
*
|
||||
* @sfe_bus: Pointer to sfe_bus structure to deinitialize
|
||||
*
|
||||
* @Return: 0: Success
|
||||
* Non-zero: Failure
|
||||
*/
|
||||
int cam_sfe_bus_wr_deinit(struct cam_sfe_bus **sfe_bus);
|
||||
|
||||
#endif /* _CAM_SFE_BUS_WR_H_ */
|
@@ -0,0 +1,99 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_SFE_BUS_H_
|
||||
#define _CAM_SFE_BUS_H_
|
||||
|
||||
#include "cam_isp_hw.h"
|
||||
#include "cam_sfe_hw_intf.h"
|
||||
|
||||
#define CAM_SFE_BUS_WR_VER_1_0 0x1000
|
||||
#define CAM_SFE_BUS_RD_VER_1_0 0x1000
|
||||
|
||||
#define CAM_SFE_ADD_REG_VAL_PAIR(buf_array, index, offset, val) \
|
||||
do { \
|
||||
buf_array[(index)++] = offset; \
|
||||
buf_array[(index)++] = val; \
|
||||
} while (0)
|
||||
|
||||
#define ALIGNUP(value, alignment) \
|
||||
((value + alignment - 1) / alignment * alignment)
|
||||
|
||||
enum cam_sfe_bus_sfe_core_id {
|
||||
CAM_SFE_BUS_SFE_CORE_0,
|
||||
CAM_SFE_BUS_SFE_CORE_1,
|
||||
CAM_SFE_BUS_SFE_CORE_MAX,
|
||||
};
|
||||
|
||||
enum cam_sfe_bus_plane_type {
|
||||
PLANE_Y,
|
||||
PLANE_C,
|
||||
PLANE_MAX,
|
||||
};
|
||||
|
||||
enum cam_sfe_bus_type {
|
||||
BUS_TYPE_SFE_WR,
|
||||
BUS_TYPE_SFE_RD,
|
||||
BUS_TYPE_SFE_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_bus:
|
||||
*
|
||||
* @Brief: Bus interface structure
|
||||
*
|
||||
* @bus_priv: Private data of BUS
|
||||
* @hw_ops: Hardware interface functions
|
||||
* @top_half_handler: Top Half handler function
|
||||
* @bottom_half_handler: Bottom Half handler function
|
||||
*/
|
||||
struct cam_sfe_bus {
|
||||
void *bus_priv;
|
||||
|
||||
struct cam_hw_ops hw_ops;
|
||||
CAM_IRQ_HANDLER_TOP_HALF top_half_handler;
|
||||
CAM_IRQ_HANDLER_BOTTOM_HALF bottom_half_handler;
|
||||
};
|
||||
|
||||
/*
|
||||
* cam_sfe_bus_init()
|
||||
*
|
||||
* @Brief: Initialize Bus layer
|
||||
*
|
||||
* @bus_version: Version of BUS to initialize
|
||||
* @bus_type: Bus Type RD/WR
|
||||
* @soc_info: Soc Information for the associated HW
|
||||
* @hw_intf: HW Interface of HW to which this resource belongs
|
||||
* @bus_hw_info: BUS HW info that contains details of BUS registers
|
||||
* @sfe_bus: Pointer to sfe_bus structure which will be filled
|
||||
* and returned on successful initialize
|
||||
*
|
||||
* @Return: 0: Success
|
||||
* Non-zero: Failure
|
||||
*/
|
||||
int cam_sfe_bus_init(uint32_t bus_version,
|
||||
int bus_type,
|
||||
struct cam_hw_soc_info *soc_info,
|
||||
struct cam_hw_intf *hw_intf,
|
||||
void *bus_hw_info,
|
||||
struct cam_sfe_bus **sfe_bus);
|
||||
|
||||
/*
|
||||
* cam_sfe_bus_deinit()
|
||||
*
|
||||
* @Brief: Deinitialize Bus layer
|
||||
*
|
||||
* @bus_version: Version of BUS to deinitialize
|
||||
* @sfe_bus: Pointer to sfe_bus structure to deinitialize
|
||||
*
|
||||
* @Return: 0: Success
|
||||
* Non-zero: Failure
|
||||
*/
|
||||
int cam_sfe_bus_deinit(
|
||||
uint32_t bus_version,
|
||||
int bus_type,
|
||||
struct cam_sfe_bus **sfe_bus);
|
||||
|
||||
#endif /* _CAM_SFE_BUS_ */
|
682
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.c
Normal file
682
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.c
Normal file
@@ -0,0 +1,682 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include "cam_io_util.h"
|
||||
#include "cam_cdm_util.h"
|
||||
#include "cam_sfe_hw_intf.h"
|
||||
#include "cam_sfe_top.h"
|
||||
#include "cam_debug_util.h"
|
||||
#include "cam_sfe_soc.h"
|
||||
|
||||
struct cam_sfe_core_cfg {
|
||||
uint32_t mode_sel;
|
||||
uint32_t ops_mode_cfg;
|
||||
uint32_t fs_mode_cfg;
|
||||
};
|
||||
|
||||
struct cam_sfe_top_common_data {
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
struct cam_sfe_top_common_reg_offset *common_reg;
|
||||
};
|
||||
|
||||
struct cam_sfe_top_priv {
|
||||
struct cam_sfe_top_common_data common_data;
|
||||
struct cam_isp_resource_node in_rsrc[CAM_SFE_TOP_IN_PORT_MAX];
|
||||
uint32_t num_in_ports;
|
||||
unsigned long hw_clk_rate;
|
||||
unsigned long req_clk_rate[CAM_SFE_TOP_IN_PORT_MAX];
|
||||
uint32_t last_counter;
|
||||
uint64_t total_bw_applied;
|
||||
struct cam_axi_vote req_axi_vote[CAM_SFE_TOP_IN_PORT_MAX];
|
||||
struct cam_axi_vote last_vote[
|
||||
CAM_SFE_DELAY_BW_REDUCTION_NUM_FRAMES];
|
||||
enum cam_sfe_bw_control_action axi_vote_control[
|
||||
CAM_SFE_TOP_IN_PORT_MAX];
|
||||
struct cam_sfe_core_cfg core_cfg;
|
||||
uint32_t sfe_debug_cfg;
|
||||
};
|
||||
|
||||
struct cam_sfe_path_data {
|
||||
void __iomem *mem_base;
|
||||
void *priv;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
struct cam_sfe_top_common_reg_offset *common_reg;
|
||||
struct cam_sfe_modules_common_reg_offset *modules_reg;
|
||||
struct cam_sfe_path_common_reg_data *path_reg_data;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
uint32_t min_hblank_cnt;
|
||||
cam_hw_mgr_event_cb_func event_cb;
|
||||
};
|
||||
|
||||
static int cam_sfe_top_core_cfg(
|
||||
struct cam_sfe_top_priv *top_priv,
|
||||
void *cmd_args, uint32_t arg_size)
|
||||
{
|
||||
struct cam_sfe_core_config_args *sfe_core_cfg = NULL;
|
||||
|
||||
if ((!cmd_args) ||
|
||||
(arg_size != sizeof(struct cam_sfe_core_config_args))) {
|
||||
CAM_ERR(CAM_SFE, "Invalid inputs");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sfe_core_cfg = (struct cam_sfe_core_config_args *)cmd_args;
|
||||
top_priv->core_cfg.mode_sel =
|
||||
sfe_core_cfg->core_config.mode_sel;
|
||||
top_priv->core_cfg.fs_mode_cfg =
|
||||
sfe_core_cfg->core_config.fs_mode_cfg;
|
||||
top_priv->core_cfg.ops_mode_cfg =
|
||||
sfe_core_cfg->core_config.ops_mode_cfg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_sfe_top_set_hw_clk_rate(
|
||||
struct cam_sfe_top_priv *top_priv)
|
||||
{
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
struct cam_sfe_soc_private *soc_private = NULL;
|
||||
struct cam_ahb_vote ahb_vote;
|
||||
int rc, clk_lvl = -1, i;
|
||||
unsigned long max_clk_rate = 0;
|
||||
|
||||
soc_info = top_priv->common_data.soc_info;
|
||||
for (i = 0; i < top_priv->num_in_ports; i++) {
|
||||
if (top_priv->req_clk_rate[i] > max_clk_rate)
|
||||
max_clk_rate = top_priv->req_clk_rate[i];
|
||||
}
|
||||
|
||||
if (max_clk_rate == top_priv->hw_clk_rate)
|
||||
return 0;
|
||||
|
||||
soc_private = (struct cam_sfe_soc_private *)
|
||||
soc_info->soc_private;
|
||||
CAM_DBG(CAM_PERF, "SFE [%u]: clk: %s idx: %d rate: %llu",
|
||||
soc_info->index,
|
||||
soc_info->clk_name[soc_info->src_clk_idx],
|
||||
soc_info->src_clk_idx, top_priv->req_clk_rate);
|
||||
|
||||
rc = cam_soc_util_set_src_clk_rate(soc_info,
|
||||
max_clk_rate);
|
||||
|
||||
if (!rc) {
|
||||
top_priv->hw_clk_rate = max_clk_rate;
|
||||
rc = cam_soc_util_get_clk_level(soc_info,
|
||||
max_clk_rate,
|
||||
soc_info->src_clk_idx, &clk_lvl);
|
||||
if (rc) {
|
||||
CAM_WARN(CAM_SFE,
|
||||
"Failed to get clk level for %s with clk_rate %llu src_idx %d rc: %d",
|
||||
soc_info->dev_name, max_clk_rate,
|
||||
soc_info->src_clk_idx, rc);
|
||||
rc = 0;
|
||||
goto end;
|
||||
}
|
||||
ahb_vote.type = CAM_VOTE_ABSOLUTE;
|
||||
ahb_vote.vote.level = clk_lvl;
|
||||
cam_cpas_update_ahb_vote(soc_private->cpas_handle, &ahb_vote);
|
||||
} else {
|
||||
CAM_ERR(CAM_PERF,
|
||||
"Set clk rate failed for SFE [%u] clk: %s rate: %llu rc: %d",
|
||||
soc_info->index,
|
||||
soc_info->clk_name[soc_info->src_clk_idx],
|
||||
max_clk_rate, rc);
|
||||
}
|
||||
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_sfe_top_get_base(
|
||||
struct cam_sfe_top_priv *top_priv,
|
||||
void *cmd_args, uint32_t arg_size)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
uint32_t mem_base = 0;
|
||||
struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args;
|
||||
struct cam_cdm_utils_ops *cdm_util_ops = NULL;
|
||||
|
||||
if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) {
|
||||
CAM_ERR(CAM_SFE, "Invalid cmd size");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!cdm_args || !cdm_args->res || !top_priv ||
|
||||
!top_priv->common_data.soc_info) {
|
||||
CAM_ERR(CAM_SFE, "Invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cdm_util_ops =
|
||||
(struct cam_cdm_utils_ops *)cdm_args->res->cdm_ops;
|
||||
|
||||
if (!cdm_util_ops) {
|
||||
CAM_ERR(CAM_SFE, "Invalid CDM ops");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size = cdm_util_ops->cdm_required_size_changebase();
|
||||
if ((size * 4) > cdm_args->cmd.size) {
|
||||
CAM_ERR(CAM_SFE, "buf size: %d is not sufficient, expected: %d",
|
||||
cdm_args->cmd.size, size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mem_base = CAM_SOC_GET_REG_MAP_CAM_BASE(
|
||||
top_priv->common_data.soc_info,
|
||||
SFE_CORE_BASE_IDX);
|
||||
|
||||
if (cdm_args->cdm_id == CAM_CDM_RT)
|
||||
mem_base -= CAM_SOC_GET_REG_MAP_CAM_BASE(
|
||||
top_priv->common_data.soc_info,
|
||||
SFE_RT_CDM_BASE_IDX);
|
||||
|
||||
CAM_DBG(CAM_SFE, "core %d mem_base 0x%x, CDM Id: %d",
|
||||
top_priv->common_data.soc_info->index, mem_base,
|
||||
cdm_args->cdm_id);
|
||||
|
||||
cdm_util_ops->cdm_write_changebase(
|
||||
cdm_args->cmd.cmd_buf_addr, mem_base);
|
||||
cdm_args->cmd.used_bytes = (size * 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_sfe_top_clock_update(
|
||||
struct cam_sfe_top_priv *top_priv,
|
||||
void *cmd_args, uint32_t arg_size)
|
||||
{
|
||||
struct cam_sfe_clock_update_args *clk_update = NULL;
|
||||
struct cam_isp_resource_node *res = NULL;
|
||||
struct cam_hw_info *hw_info = NULL;
|
||||
int rc = 0, i;
|
||||
|
||||
if (arg_size != sizeof(struct cam_sfe_clock_update_args)) {
|
||||
CAM_ERR(CAM_SFE, "Invalid cmd size");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
clk_update =
|
||||
(struct cam_sfe_clock_update_args *)cmd_args;
|
||||
if (!clk_update || !clk_update->node_res || !top_priv ||
|
||||
!top_priv->common_data.soc_info) {
|
||||
CAM_ERR(CAM_SFE, "Invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = clk_update->node_res;
|
||||
|
||||
if (!res || !res->hw_intf->hw_priv) {
|
||||
CAM_ERR(CAM_PERF, "Invalid inputs");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hw_info = res->hw_intf->hw_priv;
|
||||
|
||||
if (res->res_type != CAM_ISP_RESOURCE_SFE_IN ||
|
||||
res->res_id >= CAM_ISP_HW_SFE_IN_MAX) {
|
||||
CAM_ERR(CAM_PERF,
|
||||
"SFE: %d Invalid res_type: %d res_id: %d",
|
||||
res->hw_intf->hw_idx, res->res_type,
|
||||
res->res_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < top_priv->num_in_ports; i++) {
|
||||
if (top_priv->in_rsrc[i].res_id == res->res_id) {
|
||||
top_priv->req_clk_rate[i] = clk_update->clk_rate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
|
||||
CAM_DBG(CAM_PERF,
|
||||
"SFE: %d not ready to set clocks yet :%d",
|
||||
res->hw_intf->hw_idx,
|
||||
hw_info->hw_state);
|
||||
rc = -EAGAIN;
|
||||
} else
|
||||
rc = cam_sfe_top_set_hw_clk_rate(top_priv);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_sfe_set_top_debug(
|
||||
struct cam_sfe_top_priv *top_priv,
|
||||
void *cmd_args)
|
||||
{
|
||||
uint32_t *sfe_debug;
|
||||
|
||||
sfe_debug = (uint32_t *)cmd_args;
|
||||
top_priv->sfe_debug_cfg = *sfe_debug;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cam_sfe_top_process_cmd(void *priv, uint32_t cmd_type,
|
||||
void *cmd_args, uint32_t arg_size)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_sfe_top_priv *top_priv;
|
||||
|
||||
if (!priv) {
|
||||
CAM_ERR(CAM_SFE, "Invalid top_priv");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
top_priv = (struct cam_sfe_top_priv *) priv;
|
||||
|
||||
switch (cmd_type) {
|
||||
case CAM_ISP_HW_CMD_GET_CHANGE_BASE:
|
||||
rc = cam_sfe_top_get_base(top_priv, cmd_args,
|
||||
arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_CLOCK_UPDATE:
|
||||
rc = cam_sfe_top_clock_update(top_priv, cmd_args,
|
||||
arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_BW_UPDATE_V2:
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_BW_CONTROL:
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_CORE_CONFIG:
|
||||
rc = cam_sfe_top_core_cfg(top_priv, cmd_args,
|
||||
arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG:
|
||||
rc = cam_sfe_set_top_debug(top_priv, cmd_args);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_SFE, "Invalid cmd type: %d", cmd_type);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_top_reserve(void *device_priv,
|
||||
void *reserve_args, uint32_t arg_size)
|
||||
{
|
||||
struct cam_sfe_top_priv *top_priv;
|
||||
struct cam_sfe_acquire_args *args;
|
||||
struct cam_sfe_hw_sfe_in_acquire_args *acquire_args;
|
||||
struct cam_sfe_path_data *path_data;
|
||||
int rc = -EINVAL, i;
|
||||
|
||||
if (!device_priv || !reserve_args) {
|
||||
CAM_ERR(CAM_SFE,
|
||||
"Error invalid input arguments");
|
||||
return rc;
|
||||
}
|
||||
|
||||
top_priv = (struct cam_sfe_top_priv *)device_priv;
|
||||
args = (struct cam_sfe_acquire_args *)reserve_args;
|
||||
acquire_args = &args->sfe_in;
|
||||
|
||||
for (i = 0; i < CAM_SFE_TOP_IN_PORT_MAX; i++) {
|
||||
CAM_DBG(CAM_SFE, "i: %d res_id: %d state: %d", i,
|
||||
acquire_args->res_id, top_priv->in_rsrc[i].res_state);
|
||||
|
||||
if ((top_priv->in_rsrc[i].res_id == acquire_args->res_id) &&
|
||||
(top_priv->in_rsrc[i].res_state ==
|
||||
CAM_ISP_RESOURCE_STATE_AVAILABLE)) {
|
||||
path_data = (struct cam_sfe_path_data *)
|
||||
top_priv->in_rsrc[i].res_priv;
|
||||
path_data->event_cb = args->event_cb;
|
||||
path_data->priv = args->priv;
|
||||
CAM_DBG(CAM_SFE,
|
||||
"SFE [%u] for rsrc: %u acquired",
|
||||
top_priv->in_rsrc[i].hw_intf->hw_idx,
|
||||
acquire_args->res_id);
|
||||
|
||||
top_priv->in_rsrc[i].cdm_ops = acquire_args->cdm_ops;
|
||||
top_priv->in_rsrc[i].tasklet_info = args->tasklet;
|
||||
top_priv->in_rsrc[i].res_state =
|
||||
CAM_ISP_RESOURCE_STATE_RESERVED;
|
||||
acquire_args->rsrc_node =
|
||||
&top_priv->in_rsrc[i];
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_top_release(void *device_priv,
|
||||
void *release_args, uint32_t arg_size)
|
||||
{
|
||||
struct cam_sfe_top_priv *top_priv;
|
||||
struct cam_isp_resource_node *in_res;
|
||||
|
||||
if (!device_priv || !release_args) {
|
||||
CAM_ERR(CAM_SFE, "Invalid input arguments");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
top_priv = (struct cam_sfe_top_priv *)device_priv;
|
||||
in_res = (struct cam_isp_resource_node *)release_args;
|
||||
|
||||
CAM_DBG(CAM_SFE,
|
||||
"Release for SFE [%u] resource id: %u in state: %d",
|
||||
in_res->hw_intf->hw_idx, in_res->res_id,
|
||||
in_res->res_state);
|
||||
if (in_res->res_state < CAM_ISP_RESOURCE_STATE_RESERVED) {
|
||||
CAM_ERR(CAM_SFE, "SFE [%u] invalid res_state: %d",
|
||||
in_res->hw_intf->hw_idx, in_res->res_state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
in_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
|
||||
in_res->cdm_ops = NULL;
|
||||
in_res->tasklet_info = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cam_sfe_top_start(
|
||||
void *priv, void *start_args, uint32_t arg_size)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
struct cam_sfe_top_priv *top_priv;
|
||||
struct cam_isp_resource_node *sfe_res;
|
||||
struct cam_hw_info *hw_info = NULL;
|
||||
struct cam_sfe_path_data *path_data;
|
||||
|
||||
if (!priv || !start_args) {
|
||||
CAM_ERR(CAM_SFE, "Invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
top_priv = (struct cam_sfe_top_priv *)priv;
|
||||
sfe_res = (struct cam_isp_resource_node *) start_args;
|
||||
|
||||
hw_info = (struct cam_hw_info *)sfe_res->hw_intf->hw_priv;
|
||||
if (!hw_info) {
|
||||
CAM_ERR(CAM_SFE, "Invalid input");
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
|
||||
CAM_ERR(CAM_SFE, "SFE HW [%u] not powered up",
|
||||
hw_info->soc_info.index);
|
||||
rc = -EPERM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
path_data = (struct cam_sfe_path_data *)sfe_res->res_priv;
|
||||
rc = cam_sfe_top_set_hw_clk_rate(top_priv);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* core cfg updated via CDM */
|
||||
CAM_DBG(CAM_SFE, "SFE HW [%u] core_cfg: 0x%x",
|
||||
hw_info->soc_info.index,
|
||||
cam_io_r_mb(path_data->mem_base +
|
||||
path_data->common_reg->core_cfg));
|
||||
|
||||
/* Enable debug cfg registers */
|
||||
cam_io_w_mb(path_data->path_reg_data->top_debug_cfg_en,
|
||||
path_data->mem_base +
|
||||
path_data->common_reg->top_debug_cfg);
|
||||
|
||||
/* Enable sensor diag info */
|
||||
/* Enable SOF & EOF IRQ based on debug flag */
|
||||
/* Enable error IRQ by default */
|
||||
|
||||
sfe_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cam_sfe_top_stop(
|
||||
void *priv, void *stop_args, uint32_t arg_size)
|
||||
{
|
||||
int i;
|
||||
struct cam_sfe_top_priv *top_priv;
|
||||
struct cam_isp_resource_node *sfe_res;
|
||||
|
||||
if (!priv || !stop_args) {
|
||||
CAM_ERR(CAM_SFE, "Invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
top_priv = (struct cam_sfe_top_priv *)priv;
|
||||
sfe_res = (struct cam_isp_resource_node *) stop_args;
|
||||
|
||||
if (sfe_res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED ||
|
||||
sfe_res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE)
|
||||
return 0;
|
||||
|
||||
/* Unsubscribe for IRQs */
|
||||
sfe_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
|
||||
for (i = 0; i < CAM_SFE_TOP_IN_PORT_MAX; i++) {
|
||||
if (top_priv->in_rsrc[i].res_id == sfe_res->res_id) {
|
||||
top_priv->req_clk_rate[i] = 0;
|
||||
memset(&top_priv->req_axi_vote[i], 0,
|
||||
sizeof(struct cam_axi_vote));
|
||||
top_priv->axi_vote_control[i] =
|
||||
CAM_SFE_BW_CONTROL_EXCLUDE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cam_sfe_top_init(
|
||||
uint32_t hw_version,
|
||||
struct cam_hw_soc_info *soc_info,
|
||||
struct cam_hw_intf *hw_intf,
|
||||
void *top_hw_info,
|
||||
struct cam_sfe_top **sfe_top_ptr)
|
||||
{
|
||||
int i, j, rc = 0;
|
||||
struct cam_sfe_top_priv *top_priv = NULL;
|
||||
struct cam_sfe_path_data *path_data = NULL;
|
||||
struct cam_sfe_top *sfe_top;
|
||||
struct cam_sfe_top_hw_info *sfe_top_hw_info =
|
||||
(struct cam_sfe_top_hw_info *)top_hw_info;
|
||||
|
||||
sfe_top = kzalloc(sizeof(struct cam_sfe_top), GFP_KERNEL);
|
||||
if (!sfe_top) {
|
||||
CAM_DBG(CAM_SFE, "Error, Failed to alloc for sfe_top");
|
||||
rc = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
top_priv = kzalloc(sizeof(struct cam_sfe_top_priv),
|
||||
GFP_KERNEL);
|
||||
if (!top_priv) {
|
||||
rc = -ENOMEM;
|
||||
goto free_sfe_top;
|
||||
}
|
||||
|
||||
sfe_top->top_priv = top_priv;
|
||||
if (sfe_top_hw_info->num_inputs > CAM_SFE_TOP_IN_PORT_MAX) {
|
||||
CAM_ERR(CAM_SFE,
|
||||
"Invalid number of input resources: %d max: %d",
|
||||
sfe_top_hw_info->num_inputs,
|
||||
CAM_SFE_TOP_IN_PORT_MAX);
|
||||
rc = -EINVAL;
|
||||
goto free_top_priv;
|
||||
}
|
||||
|
||||
top_priv->hw_clk_rate = 0;
|
||||
top_priv->num_in_ports = sfe_top_hw_info->num_inputs;
|
||||
memset(top_priv->last_vote, 0x0, sizeof(struct cam_axi_vote) *
|
||||
CAM_SFE_DELAY_BW_REDUCTION_NUM_FRAMES);
|
||||
memset(&top_priv->core_cfg, 0x0,
|
||||
sizeof(struct cam_sfe_core_config_args));
|
||||
|
||||
CAM_DBG(CAM_SFE,
|
||||
"Initializing SFE [%u] top with hw_version: 0x%x",
|
||||
hw_intf->hw_idx, hw_version);
|
||||
for (i = 0, j = 0; i < top_priv->num_in_ports &&
|
||||
j < CAM_SFE_RDI_MAX; i++) {
|
||||
top_priv->in_rsrc[i].res_type =
|
||||
CAM_ISP_RESOURCE_SFE_IN;
|
||||
top_priv->in_rsrc[i].hw_intf = hw_intf;
|
||||
top_priv->in_rsrc[i].res_state =
|
||||
CAM_ISP_RESOURCE_STATE_AVAILABLE;
|
||||
top_priv->req_clk_rate[i] = 0;
|
||||
|
||||
if (sfe_top_hw_info->input_type[i] ==
|
||||
CAM_SFE_PIX_VER_1_0) {
|
||||
top_priv->in_rsrc[i].res_id =
|
||||
CAM_ISP_HW_SFE_IN_PIX;
|
||||
|
||||
path_data = kzalloc(sizeof(struct cam_sfe_path_data),
|
||||
GFP_KERNEL);
|
||||
if (!path_data) {
|
||||
CAM_DBG(CAM_SFE,
|
||||
"Failed to alloc SFE [%u] pix data",
|
||||
hw_intf->hw_idx);
|
||||
goto deinit_resources;
|
||||
}
|
||||
top_priv->in_rsrc[i].res_priv = path_data;
|
||||
path_data->mem_base =
|
||||
soc_info->reg_map[SFE_CORE_BASE_IDX].mem_base;
|
||||
path_data->path_reg_data =
|
||||
sfe_top_hw_info->pix_reg_data;
|
||||
path_data->common_reg = sfe_top_hw_info->common_reg;
|
||||
path_data->modules_reg =
|
||||
sfe_top_hw_info->modules_hw_info;
|
||||
path_data->hw_intf = hw_intf;
|
||||
path_data->soc_info = soc_info;
|
||||
} else if (sfe_top_hw_info->input_type[i] ==
|
||||
CAM_SFE_RDI_VER_1_0) {
|
||||
top_priv->in_rsrc[i].res_id =
|
||||
CAM_ISP_HW_SFE_IN_RDI0 + j;
|
||||
|
||||
path_data = kzalloc(sizeof(struct cam_sfe_path_data),
|
||||
GFP_KERNEL);
|
||||
if (!path_data) {
|
||||
CAM_DBG(CAM_SFE,
|
||||
"Failed to alloc SFE [%u] rdi data res_id: %u",
|
||||
hw_intf->hw_idx,
|
||||
(CAM_ISP_HW_SFE_IN_RDI0 + j));
|
||||
goto deinit_resources;
|
||||
}
|
||||
|
||||
top_priv->in_rsrc[i].res_priv = path_data;
|
||||
|
||||
path_data->mem_base =
|
||||
soc_info->reg_map[SFE_CORE_BASE_IDX].mem_base;
|
||||
path_data->hw_intf = hw_intf;
|
||||
path_data->common_reg = sfe_top_hw_info->common_reg;
|
||||
path_data->modules_reg =
|
||||
sfe_top_hw_info->modules_hw_info;
|
||||
path_data->soc_info = soc_info;
|
||||
path_data->path_reg_data =
|
||||
sfe_top_hw_info->rdi_reg_data[j++];
|
||||
} else {
|
||||
CAM_WARN(CAM_SFE, "Invalid SFE input type: %u",
|
||||
sfe_top_hw_info->input_type[i]);
|
||||
}
|
||||
}
|
||||
|
||||
top_priv->common_data.soc_info = soc_info;
|
||||
top_priv->common_data.hw_intf = hw_intf;
|
||||
top_priv->common_data.common_reg =
|
||||
sfe_top_hw_info->common_reg;
|
||||
|
||||
sfe_top->hw_ops.process_cmd = cam_sfe_top_process_cmd;
|
||||
sfe_top->hw_ops.start = cam_sfe_top_start;
|
||||
sfe_top->hw_ops.stop = cam_sfe_top_stop;
|
||||
sfe_top->hw_ops.reserve = cam_sfe_top_reserve;
|
||||
sfe_top->hw_ops.release = cam_sfe_top_release;
|
||||
*sfe_top_ptr = sfe_top;
|
||||
|
||||
return rc;
|
||||
|
||||
deinit_resources:
|
||||
for (--i; i >= 0; i--) {
|
||||
top_priv->in_rsrc[i].start = NULL;
|
||||
top_priv->in_rsrc[i].stop = NULL;
|
||||
top_priv->in_rsrc[i].process_cmd = NULL;
|
||||
top_priv->in_rsrc[i].top_half_handler = NULL;
|
||||
top_priv->in_rsrc[i].bottom_half_handler = NULL;
|
||||
|
||||
if (!top_priv->in_rsrc[i].res_priv)
|
||||
continue;
|
||||
|
||||
kfree(top_priv->in_rsrc[i].res_priv);
|
||||
top_priv->in_rsrc[i].res_priv = NULL;
|
||||
top_priv->in_rsrc[i].res_state =
|
||||
CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
|
||||
}
|
||||
free_top_priv:
|
||||
kfree(sfe_top->top_priv);
|
||||
sfe_top->top_priv = NULL;
|
||||
free_sfe_top:
|
||||
kfree(sfe_top);
|
||||
end:
|
||||
*sfe_top_ptr = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sfe_top_deinit(
|
||||
uint32_t hw_version,
|
||||
struct cam_sfe_top **sfe_top_ptr)
|
||||
{
|
||||
int i, rc = 0;
|
||||
struct cam_sfe_top *sfe_top;
|
||||
struct cam_sfe_top_priv *top_priv;
|
||||
|
||||
if (!sfe_top_ptr) {
|
||||
CAM_ERR(CAM_SFE, "Error Invalid input");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
sfe_top = *sfe_top_ptr;
|
||||
if (!sfe_top) {
|
||||
CAM_ERR(CAM_SFE, "Error sfe top NULL");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
top_priv = sfe_top->top_priv;
|
||||
if (!top_priv) {
|
||||
CAM_ERR(CAM_SFE, "Error sfe top priv NULL");
|
||||
rc = -ENODEV;
|
||||
goto free_sfe_top;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_SFE,
|
||||
"Deinit SFE [%u] top with hw_version 0x%x",
|
||||
top_priv->common_data.hw_intf->hw_idx,
|
||||
hw_version);
|
||||
|
||||
for (i = 0; i < CAM_SFE_TOP_IN_PORT_MAX; i++) {
|
||||
top_priv->in_rsrc[i].res_state =
|
||||
CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
|
||||
|
||||
top_priv->in_rsrc[i].start = NULL;
|
||||
top_priv->in_rsrc[i].stop = NULL;
|
||||
top_priv->in_rsrc[i].process_cmd = NULL;
|
||||
top_priv->in_rsrc[i].top_half_handler = NULL;
|
||||
top_priv->in_rsrc[i].bottom_half_handler = NULL;
|
||||
|
||||
if (!top_priv->in_rsrc[i].res_priv) {
|
||||
CAM_ERR(CAM_SFE, "Error res_priv is NULL");
|
||||
continue;
|
||||
}
|
||||
|
||||
kfree(top_priv->in_rsrc[i].res_priv);
|
||||
top_priv->in_rsrc[i].res_priv = NULL;
|
||||
}
|
||||
|
||||
kfree(sfe_top->top_priv);
|
||||
|
||||
free_sfe_top:
|
||||
kfree(sfe_top);
|
||||
*sfe_top_ptr = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
102
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.h
Normal file
102
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_SFE_TOP_H_
|
||||
#define _CAM_SFE_TOP_H_
|
||||
|
||||
#include "cam_cpas_api.h"
|
||||
|
||||
#define CAM_SFE_PIX_VER_1_0 0x10
|
||||
#define CAM_SFE_RDI_VER_1_0 0x1000
|
||||
#define CAM_SFE_TOP_VER_1_0 0x10000
|
||||
|
||||
#define CAM_SFE_DELAY_BW_REDUCTION_NUM_FRAMES 18
|
||||
#define CAM_SFE_TOP_IN_PORT_MAX 6
|
||||
#define CAM_SFE_RDI_MAX 5
|
||||
|
||||
#define CAM_SHIFT_TOP_CORE_CFG_MODE_SEL 2
|
||||
#define CAM_SHIFT_TOP_CORE_CFG_OPS_MODE_CFG 1
|
||||
#define CAM_SHIFT_TOP_CORE_CFG_FS_MODE_CFG 0
|
||||
|
||||
struct cam_sfe_top {
|
||||
void *top_priv;
|
||||
struct cam_hw_ops hw_ops;
|
||||
};
|
||||
|
||||
struct cam_sfe_top_common_reg_offset {
|
||||
uint32_t hw_version;
|
||||
uint32_t hw_capability;
|
||||
uint32_t stats_feature;
|
||||
uint32_t core_cgc_ctrl;
|
||||
uint32_t ahb_clk_ovd;
|
||||
uint32_t core_cfg;
|
||||
uint32_t violation_status;
|
||||
uint32_t diag_config;
|
||||
uint32_t diag_sensor_status_0;
|
||||
uint32_t diag_sensor_status_1;
|
||||
uint32_t diag_sensor_frame_cnt_status0;
|
||||
uint32_t diag_sensor_frame_cnt_status1;
|
||||
uint32_t top_debug_0;
|
||||
uint32_t top_debug_1;
|
||||
uint32_t top_debug_2;
|
||||
uint32_t top_debug_3;
|
||||
uint32_t top_debug_4;
|
||||
uint32_t top_debug_5;
|
||||
uint32_t top_debug_6;
|
||||
uint32_t top_debug_7;
|
||||
uint32_t top_debug_8;
|
||||
uint32_t top_debug_9;
|
||||
uint32_t top_debug_10;
|
||||
uint32_t top_debug_11;
|
||||
uint32_t top_debug_cfg;
|
||||
uint32_t stats_ch2_throttle_cfg;
|
||||
uint32_t stats_ch1_throttle_cfg;
|
||||
uint32_t stats_ch0_throttle_cfg;
|
||||
uint32_t lcr_throttle_cfg;
|
||||
uint32_t hdr_throttle_cfg;
|
||||
uint32_t sfe_op_throttle_cfg;
|
||||
};
|
||||
|
||||
struct cam_sfe_modules_common_reg_offset {
|
||||
uint32_t demux_module_cfg;
|
||||
uint32_t demux_qcfa_cfg;
|
||||
uint32_t demux_hdr_cfg;
|
||||
uint32_t demux_lcr_sel;
|
||||
uint32_t hdrc_remo_mod_cfg;
|
||||
uint32_t hdrc_remo_qcfa_bin_cfg;
|
||||
uint32_t qcfa_hdrc_remo_out_mux_cfg;
|
||||
};
|
||||
|
||||
struct cam_sfe_path_common_reg_data {
|
||||
uint32_t sof_irq_mask;
|
||||
uint32_t eof_irq_mask;
|
||||
uint32_t error_irq_mask;
|
||||
uint32_t subscribe_irq_mask;
|
||||
uint32_t enable_diagnostic_hw;
|
||||
uint32_t top_debug_cfg_en;
|
||||
};
|
||||
|
||||
struct cam_sfe_top_hw_info {
|
||||
struct cam_sfe_top_common_reg_offset *common_reg;
|
||||
struct cam_sfe_modules_common_reg_offset *modules_hw_info;
|
||||
struct cam_sfe_path_common_reg_data *pix_reg_data;
|
||||
struct cam_sfe_path_common_reg_data *rdi_reg_data[CAM_SFE_RDI_MAX];
|
||||
uint32_t num_inputs;
|
||||
uint32_t input_type[
|
||||
CAM_SFE_TOP_IN_PORT_MAX];
|
||||
};
|
||||
|
||||
int cam_sfe_top_init(
|
||||
uint32_t hw_version,
|
||||
struct cam_hw_soc_info *soc_info,
|
||||
struct cam_hw_intf *hw_intf,
|
||||
void *top_hw_info,
|
||||
struct cam_sfe_top **sfe_top);
|
||||
|
||||
int cam_sfe_top_deinit(
|
||||
uint32_t hw_version,
|
||||
struct cam_sfe_top **sfe_top);
|
||||
|
||||
#endif /* _CAM_SFE_TOP_H_ */
|
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "cam_ife_csid_dev.h"
|
||||
#include "cam_vfe.h"
|
||||
#include "cam_sfe_dev.h"
|
||||
#include "cam_isp_dev.h"
|
||||
|
||||
#include "cam_res_mgr_api.h"
|
||||
@@ -91,6 +92,9 @@ static const struct camera_submodule_component camera_isp[] = {
|
||||
{&cam_ife_csid17x_init_module, &cam_ife_csid17x_exit_module},
|
||||
{&cam_ife_csid_lite_init_module, &cam_ife_csid_lite_exit_module},
|
||||
{&cam_vfe_init_module, &cam_vfe_exit_module},
|
||||
#ifdef CONFIG_SPECTRA_SFE
|
||||
{&cam_sfe_init_module, &cam_sfe_exit_module},
|
||||
#endif
|
||||
{&cam_isp_dev_init_module, &cam_isp_dev_exit_module},
|
||||
#endif
|
||||
};
|
||||
|
@@ -19,6 +19,9 @@ extern struct platform_driver cam_top_tpg_driver;
|
||||
extern struct platform_driver cam_ife_csid17x_driver;
|
||||
extern struct platform_driver cam_ife_csid_lite_driver;
|
||||
extern struct platform_driver cam_vfe_driver;
|
||||
#ifdef CONFIG_SPECTRA_SFE
|
||||
extern struct platform_driver cam_sfe_driver;
|
||||
#endif
|
||||
extern struct platform_driver isp_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_SPECTRA_TFE
|
||||
@@ -89,6 +92,9 @@ static struct platform_driver *const cam_component_drivers[] = {
|
||||
&cam_ife_csid17x_driver,
|
||||
&cam_ife_csid_lite_driver,
|
||||
&cam_vfe_driver,
|
||||
#ifdef CONFIG_SPECTRA_SFE
|
||||
&cam_sfe_driver,
|
||||
#endif
|
||||
&isp_driver,
|
||||
#endif
|
||||
#ifdef CONFIG_SPECTRA_SENSOR
|
||||
|
Reference in New Issue
Block a user