msm: camera: ife: Add support for csitpg 1.3
Add version_3 files to support next revision of CPHY TPG. Extended capability for Multi-VC mode of operation. Add support to handle IRQ. CRs-Fixed: 2663712 Change-Id: I91864af6e9415e74104a6bce266dd78d5c021dc7 Signed-off-by: Vishalsingh Hajeri <vhajeri@codeaurora.org>
This commit is contained in:
@@ -90,6 +90,7 @@ camera-$(CONFIG_SPECTRA_ISP) += \
|
|||||||
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.o \
|
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.o \
|
||||||
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.o \
|
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.o \
|
||||||
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver2.o \
|
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver2.o \
|
||||||
|
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.o \
|
||||||
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.o \
|
cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.o \
|
||||||
cam_isp/isp_hw_mgr/cam_isp_hw_mgr.o \
|
cam_isp/isp_hw_mgr/cam_isp_hw_mgr.o \
|
||||||
cam_isp/isp_hw_mgr/cam_ife_hw_mgr.o \
|
cam_isp/isp_hw_mgr/cam_ife_hw_mgr.o \
|
||||||
|
@@ -2946,7 +2946,8 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_0) ||
|
if ((in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_0) ||
|
||||||
(in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1))
|
(in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1) ||
|
||||||
|
(in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_2))
|
||||||
rc = cam_ife_hw_mgr_acquire_tpg(ife_ctx, in_port,
|
rc = cam_ife_hw_mgr_acquire_tpg(ife_ctx, in_port,
|
||||||
acquire_hw_info->num_inputs);
|
acquire_hw_info->num_inputs);
|
||||||
|
|
||||||
|
@@ -1146,7 +1146,8 @@ int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw,
|
|||||||
path_data->crop_enable);
|
path_data->crop_enable);
|
||||||
|
|
||||||
if ((reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_0) ||
|
if ((reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_0) ||
|
||||||
(reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1)) {
|
(reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1) ||
|
||||||
|
(reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_2)) {
|
||||||
path_data->dt = CAM_IFE_CPHY_TPG_DT_VAL;
|
path_data->dt = CAM_IFE_CPHY_TPG_DT_VAL;
|
||||||
path_data->vc = CAM_IFE_CPHY_TPG_VC_VAL;
|
path_data->vc = CAM_IFE_CPHY_TPG_VC_VAL;
|
||||||
} else if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
|
} else if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
#include "cam_ife_csid_hw_intf.h"
|
#include "cam_ife_csid_hw_intf.h"
|
||||||
|
|
||||||
/* Max top tpg instance */
|
/* Max top tpg instance */
|
||||||
#define CAM_TOP_TPG_HW_NUM_MAX 2
|
#define CAM_TOP_TPG_HW_NUM_MAX 3
|
||||||
/* Max supported number of DT for TPG */
|
/* Max supported number of DT for TPG */
|
||||||
#define CAM_TOP_TPG_MAX_SUPPORTED_DT 4
|
#define CAM_TOP_TPG_MAX_SUPPORTED_DT 4
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
enum cam_top_tpg_id {
|
enum cam_top_tpg_id {
|
||||||
CAM_TOP_TPG_ID_0,
|
CAM_TOP_TPG_ID_0,
|
||||||
CAM_TOP_TPG_ID_1,
|
CAM_TOP_TPG_ID_1,
|
||||||
|
CAM_TOP_TPG_ID_2,
|
||||||
CAM_TFE_TPG_ID_MAX,
|
CAM_TFE_TPG_ID_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -55,7 +56,7 @@ struct cam_top_tpg_ver1_reserve_args {
|
|||||||
/**
|
/**
|
||||||
* struct cam_top_tpg_ver2_reserve_args
|
* struct cam_top_tpg_ver2_reserve_args
|
||||||
* @num_inport: number of inport
|
* @num_inport: number of inport
|
||||||
* TPG supports 1 VC/DT
|
* TPG supports 1 VC/DT combo
|
||||||
* @in_port : Input port resource info structure pointer
|
* @in_port : Input port resource info structure pointer
|
||||||
* @node_res : Reserved resource structure pointer
|
* @node_res : Reserved resource structure pointer
|
||||||
*
|
*
|
||||||
@@ -66,6 +67,20 @@ struct cam_top_tpg_ver2_reserve_args {
|
|||||||
struct cam_isp_resource_node *node_res;
|
struct cam_isp_resource_node *node_res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cam_top_tpg_ver2_reserve_args
|
||||||
|
* @num_inport: number of inport
|
||||||
|
* TPG supports 4 VC's and 4 DT's per VC
|
||||||
|
* @in_port : Input port resource info structure pointer
|
||||||
|
* @node_res : Reserved resource structure pointer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct cam_top_tpg_ver3_reserve_args {
|
||||||
|
uint32_t num_inport;
|
||||||
|
struct cam_isp_in_port_generic_info *in_port;
|
||||||
|
struct cam_isp_resource_node *node_res;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cam_top_tpg_hw_init()
|
* cam_top_tpg_hw_init()
|
||||||
*
|
*
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include "cam_top_tpg101.h"
|
#include "cam_top_tpg101.h"
|
||||||
#include "cam_top_tpg102.h"
|
#include "cam_top_tpg102.h"
|
||||||
|
#include "cam_top_tpg103.h"
|
||||||
#include "cam_top_tpg_core.h"
|
#include "cam_top_tpg_core.h"
|
||||||
#include "cam_top_tpg_dev.h"
|
#include "cam_top_tpg_dev.h"
|
||||||
#include "camera_main.h"
|
#include "camera_main.h"
|
||||||
@@ -19,6 +20,10 @@ static const struct of_device_id cam_top_tpg_dt_match[] = {
|
|||||||
.compatible = "qcom,tpg102",
|
.compatible = "qcom,tpg102",
|
||||||
.data = &cam_top_tpg102_hw_info,
|
.data = &cam_top_tpg102_hw_info,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.compatible = "qcom,tpg103",
|
||||||
|
.data = &cam_top_tpg103_hw_info,
|
||||||
|
},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -43,8 +43,8 @@ static struct cam_top_tpg_ver2_reg_offset cam_top_tpg102_reg = {
|
|||||||
struct cam_top_tpg_hw_info cam_top_tpg102_hw_info = {
|
struct cam_top_tpg_hw_info cam_top_tpg102_hw_info = {
|
||||||
.tpg_reg = &cam_top_tpg102_reg,
|
.tpg_reg = &cam_top_tpg102_reg,
|
||||||
.hw_dts_version = CAM_TOP_TPG_VERSION_2,
|
.hw_dts_version = CAM_TOP_TPG_VERSION_2,
|
||||||
.csid_max_clk = 426400000,
|
.csid_max_clk = 400000000,
|
||||||
.phy_max_clk = 384000000,
|
.phy_max_clk = 400000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _CAM_TOP_TPG102_H_ */
|
#endif /* _CAM_TOP_TPG102_H_ */
|
||||||
|
124
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg103.h
Normal file
124
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg103.h
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CAM_TOP_TPG103_H_
|
||||||
|
#define _CAM_TOP_TPG103_H_
|
||||||
|
|
||||||
|
#include "cam_top_tpg_ver3.h"
|
||||||
|
#include "cam_top_tpg_core.h"
|
||||||
|
|
||||||
|
static struct cam_top_tpg_ver3_reg_offset cam_top_tpg103_reg = {
|
||||||
|
.tpg_hw_version = 0x0,
|
||||||
|
.tpg_hw_status = 0x4,
|
||||||
|
.tpg_ctrl = 0x64,
|
||||||
|
.tpg_vc0_cfg0 = 0x68,
|
||||||
|
.tpg_vc0_lfsr_seed = 0x6C,
|
||||||
|
.tpg_vc0_hbi_cfg = 0x70,
|
||||||
|
.tpg_vc0_vbi_cfg = 0x74,
|
||||||
|
.tpg_vc0_color_bar_cfg = 0x78,
|
||||||
|
.tpg_vc0_dt_0_cfg_0 = 0x7C,
|
||||||
|
.tpg_vc0_dt_0_cfg_1 = 0x80,
|
||||||
|
.tpg_vc0_dt_0_cfg_2 = 0x84,
|
||||||
|
.tpg_vc0_dt_1_cfg_0 = 0x88,
|
||||||
|
.tpg_vc0_dt_1_cfg_1 = 0x8C,
|
||||||
|
.tpg_vc0_dt_1_cfg_2 = 0x90,
|
||||||
|
.tpg_vc0_dt_2_cfg_0 = 0x94,
|
||||||
|
.tpg_vc0_dt_2_cfg_1 = 0x98,
|
||||||
|
.tpg_vc0_dt_2_cfg_2 = 0x9C,
|
||||||
|
.tpg_vc0_dt_3_cfg_0 = 0xA0,
|
||||||
|
.tpg_vc0_dt_3_cfg_1 = 0xA4,
|
||||||
|
.tpg_vc0_dt_3_cfg_2 = 0xA8,
|
||||||
|
|
||||||
|
.tpg_vc1_cfg0 = 0xC8,
|
||||||
|
.tpg_vc1_lfsr_seed = 0xCC,
|
||||||
|
.tpg_vc1_hbi_cfg = 0xD0,
|
||||||
|
.tpg_vc1_vbi_cfg = 0xD4,
|
||||||
|
.tpg_vc1_color_bar_cfg = 0xD8,
|
||||||
|
.tpg_vc1_dt_0_cfg_0 = 0xDC,
|
||||||
|
.tpg_vc1_dt_0_cfg_1 = 0xE0,
|
||||||
|
.tpg_vc1_dt_0_cfg_2 = 0xE4,
|
||||||
|
.tpg_vc1_dt_1_cfg_0 = 0xE8,
|
||||||
|
.tpg_vc1_dt_1_cfg_1 = 0xEC,
|
||||||
|
.tpg_vc1_dt_1_cfg_2 = 0xF0,
|
||||||
|
.tpg_vc1_dt_2_cfg_0 = 0xF4,
|
||||||
|
.tpg_vc1_dt_2_cfg_1 = 0xF8,
|
||||||
|
.tpg_vc1_dt_2_cfg_2 = 0xFC,
|
||||||
|
.tpg_vc1_dt_3_cfg_0 = 0x100,
|
||||||
|
.tpg_vc1_dt_3_cfg_1 = 0x104,
|
||||||
|
.tpg_vc1_dt_3_cfg_2 = 0x108,
|
||||||
|
|
||||||
|
.tpg_vc2_cfg0 = 0x128,
|
||||||
|
.tpg_vc2_lfsr_seed = 0x12C,
|
||||||
|
.tpg_vc2_hbi_cfg = 0x130,
|
||||||
|
.tpg_vc2_vbi_cfg = 0x134,
|
||||||
|
.tpg_vc2_color_bar_cfg = 0x138,
|
||||||
|
.tpg_vc2_dt_0_cfg_0 = 0x13C,
|
||||||
|
.tpg_vc2_dt_0_cfg_1 = 0x140,
|
||||||
|
.tpg_vc2_dt_0_cfg_2 = 0x144,
|
||||||
|
.tpg_vc2_dt_1_cfg_0 = 0x148,
|
||||||
|
.tpg_vc2_dt_1_cfg_1 = 0x14C,
|
||||||
|
.tpg_vc2_dt_1_cfg_2 = 0x150,
|
||||||
|
.tpg_vc2_dt_2_cfg_0 = 0x154,
|
||||||
|
.tpg_vc2_dt_2_cfg_1 = 0x158,
|
||||||
|
.tpg_vc2_dt_2_cfg_2 = 0x15C,
|
||||||
|
.tpg_vc2_dt_3_cfg_0 = 0x160,
|
||||||
|
.tpg_vc2_dt_3_cfg_1 = 0x164,
|
||||||
|
.tpg_vc2_dt_3_cfg_2 = 0x168,
|
||||||
|
|
||||||
|
.tpg_vc3_cfg0 = 0x188,
|
||||||
|
.tpg_vc3_lfsr_seed = 0x18C,
|
||||||
|
.tpg_vc3_hbi_cfg = 0x190,
|
||||||
|
.tpg_vc3_vbi_cfg = 0x194,
|
||||||
|
.tpg_vc3_color_bar_cfg = 0x198,
|
||||||
|
.tpg_vc3_dt_0_cfg_0 = 0x19C,
|
||||||
|
.tpg_vc3_dt_0_cfg_1 = 0x1A0,
|
||||||
|
.tpg_vc3_dt_0_cfg_2 = 0x1A4,
|
||||||
|
.tpg_vc3_dt_1_cfg_0 = 0x1A8,
|
||||||
|
.tpg_vc3_dt_1_cfg_1 = 0x1AC,
|
||||||
|
.tpg_vc3_dt_1_cfg_2 = 0x1B0,
|
||||||
|
.tpg_vc3_dt_2_cfg_0 = 0x1B4,
|
||||||
|
.tpg_vc3_dt_2_cfg_1 = 0x1B8,
|
||||||
|
.tpg_vc3_dt_2_cfg_2 = 0x1BC,
|
||||||
|
.tpg_vc3_dt_3_cfg_0 = 0x1C0,
|
||||||
|
.tpg_vc3_dt_3_cfg_1 = 0x1C4,
|
||||||
|
.tpg_vc3_dt_3_cfg_2 = 0x1C8,
|
||||||
|
.tpg_throttle = 0x1CC,
|
||||||
|
.tpg_top_irq_status = 0x1E0,
|
||||||
|
.tpg_top_irq_mask = 0x1E4,
|
||||||
|
.tpg_top_irq_clear = 0x1E8,
|
||||||
|
.tpg_top_irq_set = 0x1EC,
|
||||||
|
.tpg_top_irq_cmd = 0x1F0,
|
||||||
|
.tpg_top_clear = 0x1F4,
|
||||||
|
.tpg_test_bus_crtl = 0x1F8,
|
||||||
|
.tpg_spare = 0x1FC,
|
||||||
|
|
||||||
|
/* configurations */
|
||||||
|
.major_version = 2,
|
||||||
|
.minor_version = 0,
|
||||||
|
.version_incr = 0,
|
||||||
|
.tpg_en_shift_val = 0,
|
||||||
|
.tpg_cphy_dphy_sel_shift_val = 3,
|
||||||
|
.tpg_num_active_lanes_shift = 4,
|
||||||
|
.tpg_fe_pkt_en_shift = 2,
|
||||||
|
.tpg_fs_pkt_en_shift = 1,
|
||||||
|
.tpg_line_interleaving_mode_shift = 10,
|
||||||
|
.tpg_num_dts_shift_val = 8,
|
||||||
|
.tpg_v_blank_cnt_shift = 12,
|
||||||
|
.tpg_dt_encode_format_shift = 20,
|
||||||
|
.tpg_payload_mode_color = 0x8,
|
||||||
|
.tpg_split_en_shift = 4,
|
||||||
|
.top_mux_reg_offset = 0x1C,
|
||||||
|
.tpg_vc_dt_pattern_id_shift = 6,
|
||||||
|
.tpg_num_active_vcs_shift = 30,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cam_top_tpg_hw_info cam_top_tpg103_hw_info = {
|
||||||
|
.tpg_reg = &cam_top_tpg103_reg,
|
||||||
|
.hw_dts_version = CAM_TOP_TPG_VERSION_3,
|
||||||
|
.csid_max_clk = 480000000,
|
||||||
|
.phy_max_clk = 480000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _CAM_TOP_TPG103_H_ */
|
@@ -15,6 +15,40 @@
|
|||||||
#include "cam_cpas_api.h"
|
#include "cam_cpas_api.h"
|
||||||
#include "cam_top_tpg_ver1.h"
|
#include "cam_top_tpg_ver1.h"
|
||||||
#include "cam_top_tpg_ver2.h"
|
#include "cam_top_tpg_ver2.h"
|
||||||
|
#include "cam_top_tpg_ver3.h"
|
||||||
|
|
||||||
|
int cam_top_tpg_get_format(
|
||||||
|
uint32_t in_format,
|
||||||
|
uint32_t *tpg_encode_format)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
switch (in_format) {
|
||||||
|
case CAM_FORMAT_MIPI_RAW_6:
|
||||||
|
*tpg_encode_format = 0;
|
||||||
|
break;
|
||||||
|
case CAM_FORMAT_MIPI_RAW_8:
|
||||||
|
*tpg_encode_format = 1;
|
||||||
|
break;
|
||||||
|
case CAM_FORMAT_MIPI_RAW_10:
|
||||||
|
*tpg_encode_format = 2;
|
||||||
|
break;
|
||||||
|
case CAM_FORMAT_MIPI_RAW_12:
|
||||||
|
*tpg_encode_format = 3;
|
||||||
|
break;
|
||||||
|
case CAM_FORMAT_MIPI_RAW_14:
|
||||||
|
*tpg_encode_format = 4;
|
||||||
|
break;
|
||||||
|
case CAM_FORMAT_MIPI_RAW_16:
|
||||||
|
*tpg_encode_format = 5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CAM_ERR(CAM_ISP, "Unsupported input encode format %d",
|
||||||
|
in_format);
|
||||||
|
rc = -EINVAL;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int cam_top_tpg_release(void *hw_priv,
|
static int cam_top_tpg_release(void *hw_priv,
|
||||||
void *release_args, uint32_t arg_size)
|
void *release_args, uint32_t arg_size)
|
||||||
@@ -212,6 +246,42 @@ static int cam_top_tpg_set_phy_clock(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
irqreturn_t cam_top_tpg_irq(int irq_num, void *data)
|
||||||
|
{
|
||||||
|
struct cam_top_tpg_hw *tpg_hw;
|
||||||
|
struct cam_hw_soc_info *soc_info;
|
||||||
|
struct cam_top_tpg_ver3_reg_offset *tpg_reg;
|
||||||
|
uint32_t irq_status_top;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
CAM_ERR(CAM_ISP, "TPG: Invalid arguments");
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tpg_hw = (struct cam_top_tpg_hw *) data;
|
||||||
|
CAM_DBG(CAM_ISP, "CPHY TPG %d IRQ Handling", tpg_hw->hw_intf->hw_idx);
|
||||||
|
|
||||||
|
soc_info = &tpg_hw->hw_info->soc_info;
|
||||||
|
tpg_reg = tpg_hw->tpg_info->tpg_reg;
|
||||||
|
|
||||||
|
irq_status_top = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_top_irq_status);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tpg_hw->hw_info->hw_lock, flags);
|
||||||
|
/* clear */
|
||||||
|
cam_io_w_mb(irq_status_top, soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_top_irq_clear);
|
||||||
|
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_top_irq_cmd);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tpg_hw->hw_info->hw_lock, flags);
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "TPG: irq_status_top = 0x%x", irq_status_top);
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
static int cam_top_tpg_process_cmd(void *hw_priv,
|
static int cam_top_tpg_process_cmd(void *hw_priv,
|
||||||
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
|
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
|
||||||
{
|
{
|
||||||
@@ -272,7 +342,7 @@ int cam_top_tpg_probe_init(struct cam_hw_intf *tpg_hw_intf,
|
|||||||
init_completion(&tpg_hw->tpg_complete);
|
init_completion(&tpg_hw->tpg_complete);
|
||||||
|
|
||||||
rc = cam_top_tpg_init_soc_resources(&tpg_hw->hw_info->soc_info,
|
rc = cam_top_tpg_init_soc_resources(&tpg_hw->hw_info->soc_info,
|
||||||
tpg_hw);
|
cam_top_tpg_irq, tpg_hw);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
CAM_ERR(CAM_ISP, "TPG:%d Failed to init_soc", tpg_idx);
|
CAM_ERR(CAM_ISP, "TPG:%d Failed to init_soc", tpg_idx);
|
||||||
goto err;
|
goto err;
|
||||||
@@ -291,6 +361,8 @@ int cam_top_tpg_probe_init(struct cam_hw_intf *tpg_hw_intf,
|
|||||||
cam_top_tpg_ver1_init(tpg_hw);
|
cam_top_tpg_ver1_init(tpg_hw);
|
||||||
else if (hw_version == CAM_TOP_TPG_VERSION_2)
|
else if (hw_version == CAM_TOP_TPG_VERSION_2)
|
||||||
cam_top_tpg_ver2_init(tpg_hw);
|
cam_top_tpg_ver2_init(tpg_hw);
|
||||||
|
else if (hw_version == CAM_TOP_TPG_VERSION_3)
|
||||||
|
cam_top_tpg_ver3_init(tpg_hw);
|
||||||
|
|
||||||
tpg_hw->tpg_res.res_type = CAM_ISP_RESOURCE_TPG;
|
tpg_hw->tpg_res.res_type = CAM_ISP_RESOURCE_TPG;
|
||||||
tpg_hw->tpg_res.res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
|
tpg_hw->tpg_res.res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
|
||||||
|
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#define CAM_TOP_TPG_VERSION_1 0x10000001
|
#define CAM_TOP_TPG_VERSION_1 0x10000001
|
||||||
#define CAM_TOP_TPG_VERSION_2 0x10000002
|
#define CAM_TOP_TPG_VERSION_2 0x10000002
|
||||||
|
#define CAM_TOP_TPG_VERSION_3 0x20000000
|
||||||
|
|
||||||
|
|
||||||
enum cam_top_tpg_encode_format {
|
enum cam_top_tpg_encode_format {
|
||||||
CAM_TOP_TPG_ENCODE_FORMAT_RAW6,
|
CAM_TOP_TPG_ENCODE_FORMAT_RAW6,
|
||||||
@@ -85,12 +87,13 @@ struct cam_top_tpg_cfg {
|
|||||||
uint32_t pix_pattern;
|
uint32_t pix_pattern;
|
||||||
uint32_t phy_sel;
|
uint32_t phy_sel;
|
||||||
uint32_t num_active_lanes;
|
uint32_t num_active_lanes;
|
||||||
uint32_t vc_num;
|
uint32_t vc_num[4];
|
||||||
uint32_t v_blank_count;
|
uint32_t v_blank_count;
|
||||||
uint32_t h_blank_count;
|
uint32_t h_blank_count;
|
||||||
uint32_t vbi_cnt;
|
uint32_t vbi_cnt;
|
||||||
uint32_t num_active_dts;
|
uint32_t num_active_dts;
|
||||||
uint32_t num_frames;
|
uint32_t num_frames;
|
||||||
|
uint32_t vc_dt_pattern_id;
|
||||||
struct cam_top_tpg_dt_cfg dt_cfg[4];
|
struct cam_top_tpg_dt_cfg dt_cfg[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -117,6 +120,8 @@ struct cam_top_tpg_hw {
|
|||||||
struct completion tpg_complete;
|
struct completion tpg_complete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int cam_top_tpg_get_format(uint32_t in_format, uint32_t *tpg_encode_format);
|
||||||
|
|
||||||
int cam_top_tpg_probe_init(struct cam_hw_intf *tpg_hw_intf,
|
int cam_top_tpg_probe_init(struct cam_hw_intf *tpg_hw_intf,
|
||||||
uint32_t tpg_idx);
|
uint32_t tpg_idx);
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
#include "cam_debug_util.h"
|
#include "cam_debug_util.h"
|
||||||
|
|
||||||
int cam_top_tpg_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
int cam_top_tpg_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
||||||
void *irq_data)
|
irq_handler_t tpg_irq_handler, void *irq_data)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct cam_cpas_register_params cpas_register_param;
|
struct cam_cpas_register_params cpas_register_param;
|
||||||
@@ -26,7 +26,7 @@ int cam_top_tpg_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* Need to see if we want post process the clock list */
|
/* Need to see if we want post process the clock list */
|
||||||
rc = cam_soc_util_request_platform_resource(soc_info, NULL,
|
rc = cam_soc_util_request_platform_resource(soc_info, tpg_irq_handler,
|
||||||
irq_data);
|
irq_data);
|
||||||
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
@@ -37,11 +37,12 @@ struct cam_top_tpg_device_soc_info {
|
|||||||
* @brief: csid initialization function for the soc info
|
* @brief: csid initialization function for the soc info
|
||||||
*
|
*
|
||||||
* @soc_info: soc info structure pointer
|
* @soc_info: soc info structure pointer
|
||||||
|
* @tpg_irq_handler: irq handler function to be registered
|
||||||
* @irq_data: irq data for the callback function
|
* @irq_data: irq data for the callback function
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int cam_top_tpg_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
int cam_top_tpg_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
||||||
void *irq_data);
|
irq_handler_t tpg_irq_handler, void *irq_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cam_top_tpg_deinit_soc_resources()
|
* cam_top_tpg_deinit_soc_resources()
|
||||||
|
@@ -21,39 +21,6 @@ static uint32_t tpg_num_dt_map[CAM_TOP_TPG_MAX_SUPPORTED_DT] = {
|
|||||||
2
|
2
|
||||||
};
|
};
|
||||||
|
|
||||||
static int cam_top_tpg_ver1_get_format(
|
|
||||||
uint32_t in_format,
|
|
||||||
uint32_t *tpg_encode_format)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
switch (in_format) {
|
|
||||||
case CAM_FORMAT_MIPI_RAW_6:
|
|
||||||
*tpg_encode_format = 0;
|
|
||||||
break;
|
|
||||||
case CAM_FORMAT_MIPI_RAW_8:
|
|
||||||
*tpg_encode_format = 1;
|
|
||||||
break;
|
|
||||||
case CAM_FORMAT_MIPI_RAW_10:
|
|
||||||
*tpg_encode_format = 2;
|
|
||||||
break;
|
|
||||||
case CAM_FORMAT_MIPI_RAW_12:
|
|
||||||
*tpg_encode_format = 3;
|
|
||||||
break;
|
|
||||||
case CAM_FORMAT_MIPI_RAW_14:
|
|
||||||
*tpg_encode_format = 4;
|
|
||||||
break;
|
|
||||||
case CAM_FORMAT_MIPI_RAW_16:
|
|
||||||
*tpg_encode_format = 4;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
CAM_ERR(CAM_ISP, "Unsupported input encode format %d",
|
|
||||||
in_format);
|
|
||||||
rc = -EINVAL;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cam_top_tpg_ver1_get_hw_caps(
|
static int cam_top_tpg_ver1_get_hw_caps(
|
||||||
void *hw_priv,
|
void *hw_priv,
|
||||||
void *get_hw_cap_args,
|
void *get_hw_cap_args,
|
||||||
@@ -136,7 +103,7 @@ static int cam_top_tpg_ver1_reserve(
|
|||||||
mutex_unlock(&tpg_hw->hw_info->hw_mutex);
|
mutex_unlock(&tpg_hw->hw_info->hw_mutex);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
rc = cam_top_tpg_ver1_get_format(reserv->in_port[0]->format,
|
rc = cam_top_tpg_get_format(reserv->in_port[0]->format,
|
||||||
&encode_format);
|
&encode_format);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto error;
|
goto error;
|
||||||
@@ -144,7 +111,7 @@ static int cam_top_tpg_ver1_reserve(
|
|||||||
CAM_DBG(CAM_ISP, "TPG: %u enter", tpg_hw->hw_intf->hw_idx);
|
CAM_DBG(CAM_ISP, "TPG: %u enter", tpg_hw->hw_intf->hw_idx);
|
||||||
|
|
||||||
tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv;
|
tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv;
|
||||||
tpg_data->vc_num = reserv->in_port[0]->vc;
|
tpg_data->vc_num[0] = reserv->in_port[0]->vc;
|
||||||
tpg_data->phy_sel = reserv->in_port[0]->lane_type;
|
tpg_data->phy_sel = reserv->in_port[0]->lane_type;
|
||||||
tpg_data->num_active_lanes = reserv->in_port[0]->lane_num;
|
tpg_data->num_active_lanes = reserv->in_port[0]->lane_num;
|
||||||
tpg_data->h_blank_count = reserv->in_port[0]->sensor_hbi;
|
tpg_data->h_blank_count = reserv->in_port[0]->sensor_hbi;
|
||||||
@@ -165,7 +132,7 @@ static int cam_top_tpg_ver1_reserve(
|
|||||||
CAM_DBG(CAM_ISP,
|
CAM_DBG(CAM_ISP,
|
||||||
"TPG:%u vc_num:%d dt:%d phy:%d lines:%d pattern:%d format:%d",
|
"TPG:%u vc_num:%d dt:%d phy:%d lines:%d pattern:%d format:%d",
|
||||||
tpg_hw->hw_intf->hw_idx,
|
tpg_hw->hw_intf->hw_idx,
|
||||||
tpg_data->vc_num, tpg_data->dt_cfg[0].data_type,
|
tpg_data->vc_num[0], tpg_data->dt_cfg[0].data_type,
|
||||||
tpg_data->phy_sel, tpg_data->num_active_lanes,
|
tpg_data->phy_sel, tpg_data->num_active_lanes,
|
||||||
tpg_data->pix_pattern,
|
tpg_data->pix_pattern,
|
||||||
tpg_data->dt_cfg[0].encode_format);
|
tpg_data->dt_cfg[0].encode_format);
|
||||||
@@ -181,7 +148,7 @@ static int cam_top_tpg_ver1_reserve(
|
|||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
for (i = 1; i < reserv->num_inport; i++) {
|
for (i = 1; i < reserv->num_inport; i++) {
|
||||||
if ((tpg_data->vc_num != reserv->in_port[i]->vc) ||
|
if ((tpg_data->vc_num[0] != reserv->in_port[i]->vc) ||
|
||||||
(tpg_data->phy_sel != reserv->in_port[i]->lane_type) ||
|
(tpg_data->phy_sel != reserv->in_port[i]->lane_type) ||
|
||||||
(tpg_data->num_active_lanes !=
|
(tpg_data->num_active_lanes !=
|
||||||
reserv->in_port[i]->lane_num) ||
|
reserv->in_port[i]->lane_num) ||
|
||||||
@@ -193,7 +160,7 @@ static int cam_top_tpg_ver1_reserve(
|
|||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
rc = cam_top_tpg_ver1_get_format(reserv->in_port[0]->format,
|
rc = cam_top_tpg_get_format(reserv->in_port[0]->format,
|
||||||
&encode_format);
|
&encode_format);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
@@ -278,7 +245,7 @@ static int cam_top_tpg_ver1_start(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val = (tpg_num_dt_map[tpg_data->num_active_dts-1] <<
|
val = (tpg_num_dt_map[tpg_data->num_active_dts-1] <<
|
||||||
tpg_reg->tpg_num_dts_shift_val) | tpg_data->vc_num;
|
tpg_reg->tpg_num_dts_shift_val) | tpg_data->vc_num[0];
|
||||||
cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc_cfg0);
|
cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc_cfg0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
345
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.c
Normal file
345
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.c
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/iopoll.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <media/cam_tfe.h>
|
||||||
|
#include <media/cam_defs.h>
|
||||||
|
|
||||||
|
#include "cam_top_tpg_core.h"
|
||||||
|
#include "cam_soc_util.h"
|
||||||
|
#include "cam_io_util.h"
|
||||||
|
#include "cam_debug_util.h"
|
||||||
|
#include "cam_top_tpg_ver3.h"
|
||||||
|
|
||||||
|
static int cam_top_tpg_ver3_get_hw_caps(
|
||||||
|
void *hw_priv,
|
||||||
|
void *get_hw_cap_args,
|
||||||
|
uint32_t arg_size)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct cam_top_tpg_hw_caps *hw_caps;
|
||||||
|
struct cam_top_tpg_hw *tpg_hw;
|
||||||
|
const struct cam_top_tpg_ver3_reg_offset *tpg_reg;
|
||||||
|
struct cam_hw_info *tpg_hw_info;
|
||||||
|
|
||||||
|
if (!hw_priv || !get_hw_cap_args) {
|
||||||
|
CAM_ERR(CAM_ISP, "TPG: Invalid args");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tpg_hw_info = (struct cam_hw_info *)hw_priv;
|
||||||
|
tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info;
|
||||||
|
hw_caps = (struct cam_top_tpg_hw_caps *) get_hw_cap_args;
|
||||||
|
tpg_reg = tpg_hw->tpg_info->tpg_reg;
|
||||||
|
|
||||||
|
hw_caps->major_version = tpg_reg->major_version;
|
||||||
|
hw_caps->minor_version = tpg_reg->minor_version;
|
||||||
|
hw_caps->version_incr = tpg_reg->version_incr;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP,
|
||||||
|
"TPG:%d major:%d minor:%d ver :%d",
|
||||||
|
tpg_hw->hw_intf->hw_idx, hw_caps->major_version,
|
||||||
|
hw_caps->minor_version, hw_caps->version_incr);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cam_top_tpg_ver3_reserve(
|
||||||
|
void *hw_priv,
|
||||||
|
void *reserve_args,
|
||||||
|
uint32_t arg_size)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct cam_top_tpg_hw *tpg_hw;
|
||||||
|
struct cam_hw_info *tpg_hw_info;
|
||||||
|
struct cam_top_tpg_ver3_reserve_args *reserv;
|
||||||
|
struct cam_top_tpg_cfg *tpg_data;
|
||||||
|
uint32_t encode_format = 0;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
if (!hw_priv || !reserve_args || (arg_size !=
|
||||||
|
sizeof(struct cam_top_tpg_ver3_reserve_args))) {
|
||||||
|
CAM_ERR(CAM_ISP, "TPG: Invalid args");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tpg_hw_info = (struct cam_hw_info *)hw_priv;
|
||||||
|
tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info;
|
||||||
|
reserv = (struct cam_top_tpg_ver3_reserve_args *)reserve_args;
|
||||||
|
|
||||||
|
if (reserv->num_inport <= 0 ||
|
||||||
|
reserv->num_inport > CAM_TOP_TPG_MAX_SUPPORTED_DT) {
|
||||||
|
CAM_ERR_RATE_LIMIT(CAM_ISP, "TPG: %u invalid input num port:%d",
|
||||||
|
tpg_hw->hw_intf->hw_idx, reserv->num_inport);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&tpg_hw->hw_info->hw_mutex);
|
||||||
|
if (tpg_hw->tpg_res.res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((reserv->in_port->lane_num <= 0 ||
|
||||||
|
reserv->in_port->lane_num > 4) ||
|
||||||
|
(reserv->in_port->lane_type >= 2)) {
|
||||||
|
CAM_ERR_RATE_LIMIT(CAM_ISP, "TPG:%u invalid input %d %d",
|
||||||
|
tpg_hw->hw_intf->hw_idx,
|
||||||
|
reserv->in_port->lane_num,
|
||||||
|
reserv->in_port->lane_type);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv;
|
||||||
|
|
||||||
|
for (i = 0; i < reserv->in_port->num_valid_vc_dt; i++) {
|
||||||
|
if (reserv->in_port->dt[i] > 0x3f ||
|
||||||
|
reserv->in_port->vc[i] > 0x1f) {
|
||||||
|
CAM_ERR(CAM_ISP, "TPG:%u Invalid vc:%d dt %d",
|
||||||
|
tpg_hw->hw_intf->hw_idx,
|
||||||
|
reserv->in_port->vc[i],
|
||||||
|
reserv->in_port->dt[i]);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
tpg_data->vc_num[i] = reserv->in_port->vc[i];
|
||||||
|
tpg_data->dt_cfg[i].data_type = reserv->in_port->dt[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = cam_top_tpg_get_format(reserv->in_port->format,
|
||||||
|
&encode_format);
|
||||||
|
if (rc)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "TPG: %u enter", tpg_hw->hw_intf->hw_idx);
|
||||||
|
|
||||||
|
tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv;
|
||||||
|
tpg_data->phy_sel = reserv->in_port->lane_type;
|
||||||
|
tpg_data->num_active_lanes = reserv->in_port->lane_num;
|
||||||
|
tpg_data->h_blank_count = reserv->in_port->hbi_cnt;
|
||||||
|
tpg_data->v_blank_count = 600;
|
||||||
|
tpg_data->num_active_dts = reserv->in_port->num_valid_vc_dt;
|
||||||
|
|
||||||
|
for (i = 0; i < reserv->in_port->num_valid_vc_dt; i++) {
|
||||||
|
tpg_data->dt_cfg[i].encode_format = encode_format;
|
||||||
|
tpg_data->dt_cfg[i].frame_height = reserv->in_port->height;
|
||||||
|
|
||||||
|
if (reserv->in_port->usage_type)
|
||||||
|
tpg_data->dt_cfg[i].frame_width =
|
||||||
|
((reserv->in_port->right_stop -
|
||||||
|
reserv->in_port->left_start) + 1);
|
||||||
|
else
|
||||||
|
tpg_data->dt_cfg[i].frame_width =
|
||||||
|
reserv->in_port->left_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP,
|
||||||
|
"TPG:%u vc_num:%d dt:%d phy:%d lines:%d pattern:%d format:%d",
|
||||||
|
tpg_hw->hw_intf->hw_idx,
|
||||||
|
tpg_data->vc_num, tpg_data->dt_cfg[0].data_type,
|
||||||
|
tpg_data->phy_sel, tpg_data->num_active_lanes,
|
||||||
|
tpg_data->pix_pattern,
|
||||||
|
tpg_data->dt_cfg[0].encode_format);
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "TPG:%u height:%d width:%d h blank:%d v blank:%d",
|
||||||
|
tpg_hw->hw_intf->hw_idx,
|
||||||
|
tpg_data->dt_cfg[0].frame_height,
|
||||||
|
tpg_data->dt_cfg[0].frame_width,
|
||||||
|
tpg_data->h_blank_count,
|
||||||
|
tpg_data->v_blank_count);
|
||||||
|
|
||||||
|
reserv->node_res = &tpg_hw->tpg_res;
|
||||||
|
tpg_hw->tpg_res.res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
|
||||||
|
error:
|
||||||
|
mutex_unlock(&tpg_hw->hw_info->hw_mutex);
|
||||||
|
CAM_DBG(CAM_ISP, "exit rc %u", rc);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cam_top_tpg_ver3_start(
|
||||||
|
void *hw_priv,
|
||||||
|
void *start_args,
|
||||||
|
uint32_t arg_size)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct cam_top_tpg_hw *tpg_hw;
|
||||||
|
struct cam_hw_info *tpg_hw_info;
|
||||||
|
struct cam_hw_soc_info *soc_info;
|
||||||
|
struct cam_isp_resource_node *tpg_res;
|
||||||
|
struct cam_top_tpg_ver3_reg_offset *tpg_reg;
|
||||||
|
struct cam_top_tpg_cfg *tpg_data;
|
||||||
|
uint32_t i, val;
|
||||||
|
|
||||||
|
if (!hw_priv || !start_args ||
|
||||||
|
(arg_size != sizeof(struct cam_isp_resource_node))) {
|
||||||
|
CAM_ERR(CAM_ISP, "TPG: Invalid args");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tpg_hw_info = (struct cam_hw_info *)hw_priv;
|
||||||
|
tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info;
|
||||||
|
tpg_reg = tpg_hw->tpg_info->tpg_reg;
|
||||||
|
tpg_res = (struct cam_isp_resource_node *)start_args;
|
||||||
|
tpg_data = (struct cam_top_tpg_cfg *)tpg_res->res_priv;
|
||||||
|
soc_info = &tpg_hw->hw_info->soc_info;
|
||||||
|
|
||||||
|
if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) ||
|
||||||
|
(tpg_res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) {
|
||||||
|
CAM_ERR(CAM_ISP, "TPG:%d Invalid Res type:%d res_state:%d",
|
||||||
|
tpg_hw->hw_intf->hw_idx,
|
||||||
|
tpg_res->res_type, tpg_res->res_state);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
cam_io_w_mb(1, soc_info->reg_map[0].mem_base + tpg_reg->tpg_top_clear);
|
||||||
|
|
||||||
|
for (i = 0; i < tpg_data->num_active_dts; i++) {
|
||||||
|
val = (((tpg_data->dt_cfg[i].frame_width & 0xFFFF) << 16) |
|
||||||
|
(tpg_data->dt_cfg[i].frame_height & 0xFFFF));
|
||||||
|
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_vc0_dt_0_cfg_0 + 0x60 * i);
|
||||||
|
|
||||||
|
cam_io_w_mb(tpg_data->dt_cfg[i].data_type,
|
||||||
|
soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_vc0_dt_0_cfg_1 + 0x60 * i);
|
||||||
|
val = ((tpg_data->dt_cfg[i].encode_format & 0xF) <<
|
||||||
|
tpg_reg->tpg_dt_encode_format_shift) |
|
||||||
|
tpg_reg->tpg_payload_mode_color;
|
||||||
|
|
||||||
|
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_vc0_dt_0_cfg_2 + 0x60 * i);
|
||||||
|
|
||||||
|
val = (1 << tpg_reg->tpg_split_en_shift);
|
||||||
|
val |= tpg_data->pix_pattern;
|
||||||
|
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_vc0_color_bar_cfg + 0x60 * i);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if hblank is notset configureHBlank count 500 and
|
||||||
|
* V blank count is 600
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (tpg_data->h_blank_count)
|
||||||
|
cam_io_w_mb(tpg_data->h_blank_count,
|
||||||
|
soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_vc0_hbi_cfg + 0x60 * i);
|
||||||
|
else
|
||||||
|
cam_io_w_mb(0x1F4,
|
||||||
|
soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_vc0_hbi_cfg + 0x60 * i);
|
||||||
|
|
||||||
|
if (tpg_data->v_blank_count)
|
||||||
|
cam_io_w_mb(tpg_data->h_blank_count,
|
||||||
|
soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_vc0_vbi_cfg + 0x60 * i);
|
||||||
|
else
|
||||||
|
cam_io_w_mb(0x258,
|
||||||
|
soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_vc0_vbi_cfg + 0x60 * i);
|
||||||
|
|
||||||
|
cam_io_w_mb(0x12345678, soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_vc0_lfsr_seed + 0x60 * i);
|
||||||
|
|
||||||
|
val = (((tpg_data->num_active_dts-1) <<
|
||||||
|
tpg_reg->tpg_num_dts_shift_val) | tpg_data->vc_num[i]);
|
||||||
|
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_vc0_cfg0 + 0x60 * i);
|
||||||
|
}
|
||||||
|
|
||||||
|
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_top_irq_mask);
|
||||||
|
|
||||||
|
val = ((tpg_data->num_active_dts - 1) <<
|
||||||
|
(tpg_reg->tpg_num_active_vcs_shift) |
|
||||||
|
(tpg_data->num_active_lanes - 1) <<
|
||||||
|
tpg_reg->tpg_num_active_lanes_shift) |
|
||||||
|
(tpg_data->vc_dt_pattern_id) <<
|
||||||
|
(tpg_reg->tpg_vc_dt_pattern_id_shift) |
|
||||||
|
(tpg_data->phy_sel << tpg_reg->tpg_cphy_dphy_sel_shift_val) |
|
||||||
|
(1 << tpg_reg->tpg_en_shift_val);
|
||||||
|
cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl);
|
||||||
|
|
||||||
|
|
||||||
|
tpg_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
|
||||||
|
|
||||||
|
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_hw_version);
|
||||||
|
CAM_DBG(CAM_ISP, "TPG:%d TPG HW version: 0x%x started",
|
||||||
|
tpg_hw->hw_intf->hw_idx, val);
|
||||||
|
|
||||||
|
end:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cam_top_tpg_ver3_stop(
|
||||||
|
void *hw_priv,
|
||||||
|
void *stop_args,
|
||||||
|
uint32_t arg_size)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct cam_top_tpg_hw *tpg_hw;
|
||||||
|
struct cam_hw_info *tpg_hw_info;
|
||||||
|
struct cam_hw_soc_info *soc_info;
|
||||||
|
struct cam_isp_resource_node *tpg_res;
|
||||||
|
const struct cam_top_tpg_ver3_reg_offset *tpg_reg;
|
||||||
|
struct cam_top_tpg_cfg *tpg_data;
|
||||||
|
|
||||||
|
if (!hw_priv || !stop_args ||
|
||||||
|
(arg_size != sizeof(struct cam_isp_resource_node))) {
|
||||||
|
CAM_ERR(CAM_ISP, "TPG: Invalid args");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tpg_hw_info = (struct cam_hw_info *)hw_priv;
|
||||||
|
tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info;
|
||||||
|
tpg_reg = tpg_hw->tpg_info->tpg_reg;
|
||||||
|
tpg_res = (struct cam_isp_resource_node *) stop_args;
|
||||||
|
tpg_data = (struct cam_top_tpg_cfg *)tpg_res->res_state;
|
||||||
|
soc_info = &tpg_hw->hw_info->soc_info;
|
||||||
|
|
||||||
|
if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) ||
|
||||||
|
(tpg_res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING)) {
|
||||||
|
CAM_DBG(CAM_ISP, "TPG:%d Invalid Res type:%d res_state:%d",
|
||||||
|
tpg_hw->hw_intf->hw_idx,
|
||||||
|
tpg_res->res_type, tpg_res->res_state);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
cam_io_w_mb(0, soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl);
|
||||||
|
|
||||||
|
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_top_irq_mask);
|
||||||
|
|
||||||
|
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_top_irq_clear);
|
||||||
|
|
||||||
|
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
|
||||||
|
tpg_reg->tpg_top_irq_cmd);
|
||||||
|
|
||||||
|
cam_io_w_mb(1, soc_info->reg_map[0].mem_base + tpg_reg->tpg_top_clear);
|
||||||
|
|
||||||
|
tpg_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "TPG:%d stopped", tpg_hw->hw_intf->hw_idx);
|
||||||
|
end:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cam_top_tpg_ver3_init(
|
||||||
|
struct cam_top_tpg_hw *tpg_hw)
|
||||||
|
{
|
||||||
|
tpg_hw->hw_intf->hw_ops.get_hw_caps = cam_top_tpg_ver3_get_hw_caps;
|
||||||
|
tpg_hw->hw_intf->hw_ops.reserve = cam_top_tpg_ver3_reserve;
|
||||||
|
tpg_hw->hw_intf->hw_ops.start = cam_top_tpg_ver3_start;
|
||||||
|
tpg_hw->hw_intf->hw_ops.stop = cam_top_tpg_ver3_stop;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
118
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.h
Normal file
118
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.h
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CAM_TOP_TPG_VER3_H_
|
||||||
|
#define _CAM_TOP_TPG_VER3_H_
|
||||||
|
|
||||||
|
#include "cam_top_tpg_core.h"
|
||||||
|
|
||||||
|
struct cam_top_tpg_ver3_reg_offset {
|
||||||
|
uint32_t tpg_hw_version;
|
||||||
|
uint32_t tpg_hw_status;
|
||||||
|
uint32_t tpg_ctrl;
|
||||||
|
uint32_t tpg_vc0_cfg0;
|
||||||
|
uint32_t tpg_vc0_lfsr_seed;
|
||||||
|
uint32_t tpg_vc0_hbi_cfg;
|
||||||
|
uint32_t tpg_vc0_vbi_cfg;
|
||||||
|
uint32_t tpg_vc0_color_bar_cfg;
|
||||||
|
uint32_t tpg_vc0_dt_0_cfg_0;
|
||||||
|
uint32_t tpg_vc0_dt_0_cfg_1;
|
||||||
|
uint32_t tpg_vc0_dt_0_cfg_2;
|
||||||
|
uint32_t tpg_vc0_dt_1_cfg_0;
|
||||||
|
uint32_t tpg_vc0_dt_1_cfg_1;
|
||||||
|
uint32_t tpg_vc0_dt_1_cfg_2;
|
||||||
|
uint32_t tpg_vc0_dt_2_cfg_0;
|
||||||
|
uint32_t tpg_vc0_dt_2_cfg_1;
|
||||||
|
uint32_t tpg_vc0_dt_2_cfg_2;
|
||||||
|
uint32_t tpg_vc0_dt_3_cfg_0;
|
||||||
|
uint32_t tpg_vc0_dt_3_cfg_1;
|
||||||
|
uint32_t tpg_vc0_dt_3_cfg_2;
|
||||||
|
|
||||||
|
uint32_t tpg_vc1_cfg0;
|
||||||
|
uint32_t tpg_vc1_lfsr_seed;
|
||||||
|
uint32_t tpg_vc1_hbi_cfg;
|
||||||
|
uint32_t tpg_vc1_vbi_cfg;
|
||||||
|
uint32_t tpg_vc1_color_bar_cfg;
|
||||||
|
uint32_t tpg_vc1_dt_0_cfg_0;
|
||||||
|
uint32_t tpg_vc1_dt_0_cfg_1;
|
||||||
|
uint32_t tpg_vc1_dt_0_cfg_2;
|
||||||
|
uint32_t tpg_vc1_dt_1_cfg_0;
|
||||||
|
uint32_t tpg_vc1_dt_1_cfg_1;
|
||||||
|
uint32_t tpg_vc1_dt_1_cfg_2;
|
||||||
|
uint32_t tpg_vc1_dt_2_cfg_0;
|
||||||
|
uint32_t tpg_vc1_dt_2_cfg_1;
|
||||||
|
uint32_t tpg_vc1_dt_2_cfg_2;
|
||||||
|
uint32_t tpg_vc1_dt_3_cfg_0;
|
||||||
|
uint32_t tpg_vc1_dt_3_cfg_1;
|
||||||
|
uint32_t tpg_vc1_dt_3_cfg_2;
|
||||||
|
|
||||||
|
uint32_t tpg_vc2_cfg0;
|
||||||
|
uint32_t tpg_vc2_lfsr_seed;
|
||||||
|
uint32_t tpg_vc2_hbi_cfg;
|
||||||
|
uint32_t tpg_vc2_vbi_cfg;
|
||||||
|
uint32_t tpg_vc2_color_bar_cfg;
|
||||||
|
uint32_t tpg_vc2_dt_0_cfg_0;
|
||||||
|
uint32_t tpg_vc2_dt_0_cfg_1;
|
||||||
|
uint32_t tpg_vc2_dt_0_cfg_2;
|
||||||
|
uint32_t tpg_vc2_dt_1_cfg_0;
|
||||||
|
uint32_t tpg_vc2_dt_1_cfg_1;
|
||||||
|
uint32_t tpg_vc2_dt_1_cfg_2;
|
||||||
|
uint32_t tpg_vc2_dt_2_cfg_0;
|
||||||
|
uint32_t tpg_vc2_dt_2_cfg_1;
|
||||||
|
uint32_t tpg_vc2_dt_2_cfg_2;
|
||||||
|
uint32_t tpg_vc2_dt_3_cfg_0;
|
||||||
|
uint32_t tpg_vc2_dt_3_cfg_1;
|
||||||
|
uint32_t tpg_vc2_dt_3_cfg_2;
|
||||||
|
|
||||||
|
uint32_t tpg_vc3_cfg0;
|
||||||
|
uint32_t tpg_vc3_lfsr_seed;
|
||||||
|
uint32_t tpg_vc3_hbi_cfg;
|
||||||
|
uint32_t tpg_vc3_vbi_cfg;
|
||||||
|
uint32_t tpg_vc3_color_bar_cfg;
|
||||||
|
uint32_t tpg_vc3_dt_0_cfg_0;
|
||||||
|
uint32_t tpg_vc3_dt_0_cfg_1;
|
||||||
|
uint32_t tpg_vc3_dt_0_cfg_2;
|
||||||
|
uint32_t tpg_vc3_dt_1_cfg_0;
|
||||||
|
uint32_t tpg_vc3_dt_1_cfg_1;
|
||||||
|
uint32_t tpg_vc3_dt_1_cfg_2;
|
||||||
|
uint32_t tpg_vc3_dt_2_cfg_0;
|
||||||
|
uint32_t tpg_vc3_dt_2_cfg_1;
|
||||||
|
uint32_t tpg_vc3_dt_2_cfg_2;
|
||||||
|
uint32_t tpg_vc3_dt_3_cfg_0;
|
||||||
|
uint32_t tpg_vc3_dt_3_cfg_1;
|
||||||
|
uint32_t tpg_vc3_dt_3_cfg_2;
|
||||||
|
uint32_t tpg_throttle;
|
||||||
|
uint32_t tpg_top_irq_status;
|
||||||
|
uint32_t tpg_top_irq_mask;
|
||||||
|
uint32_t tpg_top_irq_clear;
|
||||||
|
uint32_t tpg_top_irq_set;
|
||||||
|
uint32_t tpg_top_irq_cmd;
|
||||||
|
uint32_t tpg_top_clear;
|
||||||
|
uint32_t tpg_test_bus_crtl;
|
||||||
|
uint32_t tpg_spare;
|
||||||
|
|
||||||
|
/* configurations */
|
||||||
|
uint32_t major_version;
|
||||||
|
uint32_t minor_version;
|
||||||
|
uint32_t version_incr;
|
||||||
|
uint32_t tpg_en_shift_val;
|
||||||
|
uint32_t tpg_cphy_dphy_sel_shift_val;
|
||||||
|
uint32_t tpg_num_active_lanes_shift;
|
||||||
|
uint32_t tpg_fe_pkt_en_shift;
|
||||||
|
uint32_t tpg_fs_pkt_en_shift;
|
||||||
|
uint32_t tpg_line_interleaving_mode_shift;
|
||||||
|
uint32_t tpg_num_dts_shift_val;
|
||||||
|
uint32_t tpg_v_blank_cnt_shift;
|
||||||
|
uint32_t tpg_dt_encode_format_shift;
|
||||||
|
uint32_t tpg_payload_mode_color;
|
||||||
|
uint32_t tpg_split_en_shift;
|
||||||
|
uint32_t top_mux_reg_offset;
|
||||||
|
uint32_t tpg_vc_dt_pattern_id_shift;
|
||||||
|
uint32_t tpg_num_active_vcs_shift;
|
||||||
|
};
|
||||||
|
|
||||||
|
int cam_top_tpg_ver3_init(struct cam_top_tpg_hw *tpg_hw);
|
||||||
|
|
||||||
|
#endif /* _CAM_TOP_TPG_VER3_H_ */
|
@@ -51,6 +51,7 @@
|
|||||||
#define CAM_ISP_IFE_IN_RES_RD (CAM_ISP_IFE_IN_RES_BASE + 7)
|
#define CAM_ISP_IFE_IN_RES_RD (CAM_ISP_IFE_IN_RES_BASE + 7)
|
||||||
#define CAM_ISP_IFE_IN_RES_CPHY_TPG_0 (CAM_ISP_IFE_IN_RES_BASE + 8)
|
#define CAM_ISP_IFE_IN_RES_CPHY_TPG_0 (CAM_ISP_IFE_IN_RES_BASE + 8)
|
||||||
#define CAM_ISP_IFE_IN_RES_CPHY_TPG_1 (CAM_ISP_IFE_IN_RES_BASE + 9)
|
#define CAM_ISP_IFE_IN_RES_CPHY_TPG_1 (CAM_ISP_IFE_IN_RES_BASE + 9)
|
||||||
#define CAM_ISP_IFE_IN_RES_MAX (CAM_ISP_IFE_IN_RES_BASE + 10)
|
#define CAM_ISP_IFE_IN_RES_CPHY_TPG_2 (CAM_ISP_IFE_IN_RES_BASE + 10)
|
||||||
|
#define CAM_ISP_IFE_IN_RES_MAX (CAM_ISP_IFE_IN_RES_BASE + 11)
|
||||||
|
|
||||||
#endif /* __UAPI_CAM_ISP_IFE_H__ */
|
#endif /* __UAPI_CAM_ISP_IFE_H__ */
|
||||||
|
Reference in New Issue
Block a user