msm: camera: csiphy: Update logic for lane enablement

Currently lane enablement is happening as a part of lanemask
field, which is send by UMD. Lane enablement should be purely
depends on laneCnt and laneAssign attributes. Also, combo mode
sensors needs to come with combo mode flag set from the UMD.
This change updates the logic for lane enablement with respect
to laneAssign and laneCnt, and also covers all combomode selection
as per the request. This change also enables the sensors to acquire
and streamon/streamoff at anytime in session.

CRs-Fixed: 2677450
Change-Id: I4f0d3ffd7245a931c273611c9c4b7e503c038664
Signed-off-by: Jigarkumar Zala <jzala@codeaurora.org>
Dieser Commit ist enthalten in:
Jigarkumar Zala
2020-03-16 12:20:57 -07:00
Ursprung b4f16aace6
Commit fa08068801
8 geänderte Dateien mit 679 neuen und 387 gelöschten Zeilen

Datei-Diff unterdrückt, da er zu groß ist Diff laden

Datei anzeigen

@@ -131,6 +131,7 @@ static int cam_csiphy_component_bind(struct device *dev,
struct csiphy_device *new_csiphy_dev;
int32_t rc = 0;
struct platform_device *pdev = to_platform_device(dev);
int i;
new_csiphy_dev = devm_kzalloc(&pdev->dev,
sizeof(struct csiphy_device), GFP_KERNEL);
@@ -183,18 +184,23 @@ static int cam_csiphy_component_bind(struct device *dev,
platform_set_drvdata(pdev, &(new_csiphy_dev->v4l2_dev_str.sd));
new_csiphy_dev->bridge_intf.device_hdl[0] = -1;
new_csiphy_dev->bridge_intf.device_hdl[1] = -1;
new_csiphy_dev->bridge_intf.ops.get_dev_info =
NULL;
new_csiphy_dev->bridge_intf.ops.link_setup =
NULL;
new_csiphy_dev->bridge_intf.ops.apply_req =
NULL;
for (i = 0; i < CSIPHY_MAX_INSTANCES_PER_PHY; i++) {
new_csiphy_dev->csiphy_info[i].hdl_data.device_hdl = -1;
new_csiphy_dev->csiphy_info[i].hdl_data.session_hdl = -1;
new_csiphy_dev->csiphy_info[i].csiphy_3phase = -1;
new_csiphy_dev->csiphy_info[i].data_rate = 0;
new_csiphy_dev->csiphy_info[i].settle_time = 0;
new_csiphy_dev->csiphy_info[i].lane_cnt = 0;
new_csiphy_dev->csiphy_info[i].lane_assign = 0;
new_csiphy_dev->csiphy_info[i].lane_enable = 0;
}
new_csiphy_dev->ops.get_dev_info = NULL;
new_csiphy_dev->ops.link_setup = NULL;
new_csiphy_dev->ops.apply_req = NULL;
new_csiphy_dev->acquire_count = 0;
new_csiphy_dev->start_dev_count = 0;
new_csiphy_dev->is_acquired_dev_combo_mode = 0;
cpas_parms.cam_cpas_client_cb = NULL;
cpas_parms.cell_index = new_csiphy_dev->soc_info.index;

Datei anzeigen

@@ -29,7 +29,7 @@
#include "cam_context.h"
#define MAX_CSIPHY 6
#define MAX_DPHY_DATA_LN 4
#define MAX_LRME_V4l2_EVENTS 30
#define CSIPHY_NUM_CLK_MAX 16
#define MAX_CSIPHY_REG_ARRAY 70
@@ -41,6 +41,7 @@
#define MAX_DATA_RATE_REGS 30
#define CAMX_CSIPHY_DEV_NAME "cam-csiphy-driver"
#define CAM_CSIPHY_RX_CLK_SRC "cphy_rx_src_clk"
#define CSIPHY_POWER_UP 0
#define CSIPHY_POWER_DOWN 1
@@ -53,20 +54,25 @@
#define CSIPHY_2PH_REGS 5
#define CSIPHY_3PH_REGS 6
#define CSIPHY_MAX_INSTANCES 2
#define CSIPHY_MAX_INSTANCES_PER_PHY 3
#define CAM_CSIPHY_MAX_DPHY_LANES 4
#define CAM_CSIPHY_MAX_CPHY_LANES 3
#define CAM_CSIPHY_MAX_CPHY_DPHY_COMBO_LN 3
#define CAM_CSIPHY_MAX_CPHY_COMBO_LN 3
#define DPHY_LANE_0 BIT(0)
#define CPHY_LANE_0 BIT(1)
#define DPHY_LANE_1 BIT(2)
#define CPHY_LANE_1 BIT(3)
#define DPHY_LANE_2 BIT(4)
#define CPHY_LANE_2 BIT(5)
#define DPHY_LANE_3 BIT(6)
#define DPHY_CLK_LN BIT(7)
#define ENABLE_IRQ false
#undef CDBG
#ifdef CAM_CSIPHY_CORE_DEBUG
#define CDBG(fmt, args...) pr_err(fmt, ##args)
#else
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
#endif
enum cam_csiphy_state {
CAM_CSIPHY_INIT,
CAM_CSIPHY_ACQUIRE,
@@ -111,6 +117,7 @@ struct csiphy_reg_parms_t {
uint32_t csiphy_reset_array_size;
uint32_t csiphy_2ph_config_array_size;
uint32_t csiphy_3ph_config_array_size;
uint32_t csiphy_2ph_3ph_config_array_size;
uint32_t csiphy_cpas_cp_bits_per_phy;
uint32_t csiphy_cpas_cp_is_interleaved;
uint32_t csiphy_cpas_cp_2ph_offset;
@@ -123,22 +130,17 @@ struct csiphy_reg_parms_t {
* struct csiphy_intf_params
* @device_hdl: Device Handle
* @session_hdl: Session Handle
* @ops: KMD operations
* @crm_cb: Callback API pointers
*/
struct csiphy_intf_params {
int32_t device_hdl[CSIPHY_MAX_INSTANCES];
int32_t session_hdl[CSIPHY_MAX_INSTANCES];
int32_t link_hdl[CSIPHY_MAX_INSTANCES];
struct cam_req_mgr_kmd_ops ops;
struct cam_req_mgr_crm_cb *crm_cb;
struct csiphy_hdl_tbl {
int32_t device_hdl;
int32_t session_hdl;
};
/**
* struct csiphy_reg_t
* @reg_addr: Register address
* @reg_data: Register data
* @delay: Delay in us
* @reg_addr: Register address
* @reg_data: Register data
* @delay: Delay in us
* @csiphy_param_type: CSIPhy parameter type
*/
struct csiphy_reg_t {
@@ -200,38 +202,35 @@ struct csiphy_ctrl_t {
struct csiphy_reg_t (*csiphy_2ph_reg)[MAX_SETTINGS_PER_LANE];
struct csiphy_reg_t (*csiphy_2ph_combo_mode_reg)[MAX_SETTINGS_PER_LANE];
struct csiphy_reg_t (*csiphy_3ph_reg)[MAX_SETTINGS_PER_LANE];
struct csiphy_reg_t (*csiphy_3ph_combo_reg)[MAX_SETTINGS_PER_LANE];
struct csiphy_reg_t (*csiphy_2ph_3ph_mode_reg)[MAX_SETTINGS_PER_LANE];
enum cam_vote_level (*getclockvoting)(struct csiphy_device *phy_dev);
enum cam_vote_level (*getclockvoting)(struct csiphy_device *phy_dev,
int32_t index);
struct data_rate_settings_t *data_rates_settings_table;
};
/**
* cam_csiphy_param: Provides cmdbuffer structre
* @lane_mask : Lane mask details
* @lane_assign : Lane sensor will be using
* @csiphy_3phase : Mentions DPHY or CPHY
* @combo_mode : Info regarding combo_mode is enable / disable
* @lane_cnt : Total number of lanes
* @reserved
* @3phase : Details whether 3Phase / 2Phase operation
* @settle_time : Settling time in ms
* @settle_time_combo_sensor : Settling time in ms
* @data_rate : Data rate in mbps
* @data_rate_combo_sensor: data rate of combo sensor
* in the the same phy
*
* cam_csiphy_param : Provides cmdbuffer structure
* @lane_assign : Lane sensor will be using
* @lane_cnt : Total number of lanes
* @secure_mode : To identify whether stream is secure/nonsecure
* @lane_enable : Data Lane selection
* @settle_time : Settling time in ms
* @data_rate : Data rate in mbps
* @csiphy_3phase : To identify DPHY or CPHY
* @csiphy_cpas_cp_reg_mask : CP reg mask for phy instance
* @hdl_data : CSIPHY handle table
*/
struct cam_csiphy_param {
uint16_t lane_mask;
uint16_t lane_assign;
uint8_t csiphy_3phase;
uint8_t combo_mode;
uint8_t lane_cnt;
uint8_t secure_mode[CSIPHY_MAX_INSTANCES];
uint64_t settle_time;
uint64_t settle_time_combo_sensor;
uint64_t data_rate;
uint64_t data_rate_combo_sensor;
uint16_t lane_assign;
uint8_t lane_cnt;
uint8_t secure_mode;
uint32_t lane_enable;
uint64_t settle_time;
uint64_t data_rate;
int csiphy_3phase;
uint64_t csiphy_cpas_cp_reg_mask;
struct csiphy_hdl_tbl hdl_data;
};
/**
@@ -255,41 +254,50 @@ struct cam_csiphy_param {
* @csi_3phase: Is it a 3Phase mode
* @ref_count: Reference count
* @clk_lane: Clock lane
* @rx_clk_src_idx: Phy src clk index
* @acquire_count: Acquire device count
* @start_dev_count: Start count
* @is_acquired_dev_combo_mode: Flag that mentions whether already acquired
* device is for combo mode
* @soc_info: SOC information
* @cpas_handle: CPAS handle
* @config_count: Config reg count
* @csiphy_cpas_cp_reg_mask: CP reg mask for phy instance
* @current_data_rate: Data rate in mbps
* @csiphy_3phase: To identify DPHY or CPHY at top level
* @combo_mode: Info regarding combo_mode is enable / disable
* @ops: KMD operations
* @crm_cb: Callback API pointers
*/
struct csiphy_device {
char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH];
struct mutex mutex;
uint32_t hw_version;
enum cam_csiphy_state csiphy_state;
struct csiphy_ctrl_t *ctrl_reg;
uint32_t csiphy_max_clk;
struct msm_cam_clk_info csiphy_3p_clk_info[2];
struct clk *csiphy_3p_clk[2];
unsigned char csi_3phase;
int32_t ref_count;
uint16_t lane_mask[MAX_CSIPHY];
uint8_t is_csiphy_3phase_hw;
uint8_t is_divisor_32_comp;
uint8_t num_irq_registers;
struct cam_subdev v4l2_dev_str;
struct cam_csiphy_param csiphy_info;
struct csiphy_intf_params bridge_intf;
uint32_t clk_lane;
uint32_t acquire_count;
uint32_t start_dev_count;
uint32_t is_acquired_dev_combo_mode;
struct cam_hw_soc_info soc_info;
uint32_t cpas_handle;
uint32_t config_count;
uint64_t csiphy_cpas_cp_reg_mask[CSIPHY_MAX_INSTANCES];
char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH];
struct mutex mutex;
uint32_t hw_version;
enum cam_csiphy_state csiphy_state;
struct csiphy_ctrl_t *ctrl_reg;
uint32_t csiphy_max_clk;
struct msm_cam_clk_info csiphy_3p_clk_info[2];
struct clk *csiphy_3p_clk[2];
int32_t ref_count;
uint16_t lane_mask[MAX_CSIPHY];
uint8_t is_csiphy_3phase_hw;
uint8_t is_divisor_32_comp;
uint8_t num_irq_registers;
struct cam_subdev v4l2_dev_str;
struct cam_csiphy_param csiphy_info[
CSIPHY_MAX_INSTANCES_PER_PHY];
uint32_t clk_lane;
uint8_t rx_clk_src_idx;
uint32_t acquire_count;
uint32_t start_dev_count;
struct cam_hw_soc_info soc_info;
uint32_t cpas_handle;
uint32_t config_count;
uint64_t current_data_rate;
uint64_t csiphy_cpas_cp_reg_mask[
CSIPHY_MAX_INSTANCES_PER_PHY];
uint8_t session_max_device_support;
uint8_t combo_mode;
uint8_t cphy_dphy_combo_mode;
struct cam_req_mgr_kmd_ops ops;
struct cam_req_mgr_crm_cb *crm_cb;
};
/**

Datei anzeigen

@@ -126,26 +126,25 @@ int32_t cam_csiphy_status_dmp(struct csiphy_device *csiphy_dev)
enum cam_vote_level get_clk_vote_default(struct csiphy_device *csiphy_dev)
enum cam_vote_level get_clk_vote_default(struct csiphy_device *csiphy_dev,
int32_t index)
{
CAM_DBG(CAM_CSIPHY, "voting for SVS");
return CAM_SVS_VOTE;
}
enum cam_vote_level get_clk_voting_dynamic(struct csiphy_device *csiphy_dev)
enum cam_vote_level get_clk_voting_dynamic(
struct csiphy_device *csiphy_dev, int32_t index)
{
uint32_t cam_vote_level = 0;
uint32_t last_valid_vote = 0;
struct cam_hw_soc_info *soc_info;
uint64_t phy_data_rate = csiphy_dev->csiphy_info.data_rate;
uint64_t phy_data_rate = csiphy_dev->csiphy_info[index].data_rate;
soc_info = &csiphy_dev->soc_info;
phy_data_rate = max(phy_data_rate, csiphy_dev->current_data_rate);
if (csiphy_dev->is_acquired_dev_combo_mode)
phy_data_rate = max(phy_data_rate,
csiphy_dev->csiphy_info.data_rate_combo_sensor);
if (csiphy_dev->csiphy_info.csiphy_3phase) {
if (csiphy_dev->csiphy_info[index].csiphy_3phase) {
if (csiphy_dev->is_divisor_32_comp)
do_div(phy_data_rate, CSIPHY_DIVISOR_32);
else
@@ -156,19 +155,21 @@ enum cam_vote_level get_clk_voting_dynamic(struct csiphy_device *csiphy_dev)
/* round off to next integer */
phy_data_rate += 1;
csiphy_dev->current_data_rate = phy_data_rate;
for (cam_vote_level = 0;
cam_vote_level < CAM_MAX_VOTE; cam_vote_level++) {
if (soc_info->clk_level_valid[cam_vote_level] != true)
continue;
if (soc_info->clk_rate[cam_vote_level][0] >
phy_data_rate) {
if (soc_info->clk_rate[cam_vote_level]
[csiphy_dev->rx_clk_src_idx] > phy_data_rate) {
CAM_DBG(CAM_CSIPHY,
"match detected %s : %llu:%d level : %d",
soc_info->clk_name[0],
soc_info->clk_name[csiphy_dev->rx_clk_src_idx],
phy_data_rate,
soc_info->clk_rate[cam_vote_level][0],
soc_info->clk_rate[cam_vote_level]
[csiphy_dev->rx_clk_src_idx],
cam_vote_level);
return cam_vote_level;
}
@@ -177,7 +178,7 @@ enum cam_vote_level get_clk_voting_dynamic(struct csiphy_device *csiphy_dev)
return last_valid_vote;
}
int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev)
int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev, int32_t index)
{
int32_t rc = 0;
struct cam_hw_soc_info *soc_info;
@@ -191,7 +192,7 @@ int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev)
return rc;
}
vote_level = csiphy_dev->ctrl_reg->getclockvoting(csiphy_dev);
vote_level = csiphy_dev->ctrl_reg->getclockvoting(csiphy_dev, index);
rc = cam_soc_util_enable_platform_resource(soc_info, true,
vote_level, ENABLE_IRQ);
if (rc < 0) {
@@ -466,6 +467,10 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
csiphy_dev->csiphy_3p_clk[1] =
soc_info->clk[i];
continue;
} else if (!strcmp(soc_info->clk_name[i],
CAM_CSIPHY_RX_CLK_SRC)) {
csiphy_dev->rx_clk_src_idx = i;
continue;
}
CAM_DBG(CAM_CSIPHY, "clk_rate[%d] = %d", clk_cnt,

Datei anzeigen

@@ -21,9 +21,6 @@
#include "cam_csiphy_dev.h"
#include "cam_csiphy_core.h"
#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
#define CSI_3PHASE_HW 1
#define CSIPHY_VERSION_V35 0x35
#define CSIPHY_VERSION_V10 0x10
@@ -55,7 +52,7 @@ int cam_csiphy_parse_dt_info(struct platform_device *pdev,
*
* This API enables SOC related parameters
*/
int cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev);
int cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev, int32_t index);
/**
* @csiphy_dev: CSIPhy device structure

Datei anzeigen

@@ -16,6 +16,7 @@ struct csiphy_reg_parms_t csiphy_v1_2_3 = {
.csiphy_reset_array_size = 5,
.csiphy_2ph_config_array_size = 16,
.csiphy_3ph_config_array_size = 28,
.csiphy_2ph_3ph_config_array_size = 0,
.csiphy_2ph_clock_lane = 0x1,
.csiphy_2ph_combo_ck_ln = 0x10,
};

Datei anzeigen

@@ -77,11 +77,12 @@ int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
{
int rc = 0;
if (offset >= CSIPHY_MAX_INSTANCES) {
if (offset >= CSIPHY_MAX_INSTANCES_PER_PHY) {
CAM_ERR(CAM_CSIPHY, "Invalid CSIPHY offset");
rc = -EINVAL;
} else if (qcom_scm_camera_protect_phy_lanes(protect,
csiphy_dev->csiphy_cpas_cp_reg_mask[offset])) {
csiphy_dev->csiphy_info[offset]
.csiphy_cpas_cp_reg_mask)) {
CAM_ERR(CAM_CSIPHY, "SCM call to hypervisor failed");
rc = -EINVAL;
}
@@ -158,10 +159,11 @@ int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
struct scm_desc description = {
.arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL),
.args[0] = protect,
.args[1] = csiphy_dev->csiphy_cpas_cp_reg_mask[offset],
.args[1] = csiphy_dev->csiphy_info[offset]
.csiphy_cpas_cp_reg_mask,
};
if (offset >= CSIPHY_MAX_INSTANCES) {
if (offset >= CSIPHY_MAX_INSTANCES_PER_PHY) {
CAM_ERR(CAM_CSIPHY, "Invalid CSIPHY offset");
rc = -EINVAL;
} else if (scm_call2(SCM_SIP_FNID(0x18, 0x7), &description)) {

Datei anzeigen

@@ -324,23 +324,18 @@ struct cam_cmd_unconditional_wait {
} __attribute__((packed));
/**
* cam_csiphy_info: Provides cmdbuffer structre
* @lane_mask : Lane mask details
* @lane_assign : Lane sensor will be using
* @csiphy_3phase : Total number of lanes
* @combo_mode : Info regarding combo_mode is enable / disable
* @lane_cnt : Total number of lanes
* @secure_mode : Secure mode flag to enable / disable
* @3phase : Details whether 3Phase / 2Phase operation
* @settle_time : Settling time in ms
* @data_rate : Data rate
* cam_csiphy_info : Provides cmdbuffer structre
* @lane_assign : Lane sensor will be using
* @lane_cnt : Total number of lanes
* @secure_mode : Secure mode flag to enable / disable
* @settle_time : Settling time in ms
* @data_rate : Data rate
*
*/
struct cam_csiphy_info {
__u16 lane_mask;
__u16 reserved;
__u16 lane_assign;
__u8 csiphy_3phase;
__u8 combo_mode;
__u16 reserved1;
__u8 lane_cnt;
__u8 secure_mode;
__u64 settle_time;
@@ -349,14 +344,18 @@ struct cam_csiphy_info {
/**
* cam_csiphy_acquire_dev_info : Information needed for
* csiphy at the time of acquire
* @combo_mode : Indicates the device mode of operation
* @reserved
* csiphy at the time of acquire
* @combo_mode : Indicates the device mode of operation
* @cphy_dphy_combo_mode : Info regarding cphy_dphy_combo mode
* @csiphy_3phase : Details whether 3Phase / 2Phase operation
* @reserve
*
*/
struct cam_csiphy_acquire_dev_info {
__u32 combo_mode;
__u32 reserved;
__u16 cphy_dphy_combo_mode;
__u8 csiphy_3phase;
__u8 reserve;
} __attribute__((packed));
/**