Merge changes I1b568b90,I632469bc,I53326589,I8ac4820b,I65e97c6e,I4e149fc8,I450049ab,Ic06531a5,Ic96d1edc,I311c7cd8 into camera-kernel.lnx.6.0

* changes:
  Snap for drop 06/09/2022 mainline 783 LA.VENDOR.13.2.0.AU237
  msm: camera: common: Enable config for rpmh calls
  msm: camera: common: Add debug infrastructure for camera drv
  msm: camera: common: Add support for DRV config
  msm: camera: common: Add support for bw update blob v3
  msm: camera: isp: Read back and update top debug cfg register
  msm: camera: icp: Log all active requests on enomem from FW
  msm: camera: csiphy: Add support for RF channel based csiphy settings
  msm: camera: common: Add I3C Driver support
  msm: camera: isp: Remove IFE HW mgr reference from ISP ctx
This commit is contained in:
Abhijit Trivedi
2022-06-14 20:14:09 -07:00
committed by Gerrit - the friendly Code Review server
73 changed files with 3013 additions and 918 deletions

View File

@@ -6,6 +6,7 @@ CONFIG_SPECTRA_ICP := y
CONFIG_SPECTRA_JPEG := y
CONFIG_SPECTRA_CUSTOM := y
CONFIG_SPECTRA_SENSOR := y
CONFIG_USE_RPMH_DRV_API := y
# Flags to pass into C preprocessor
ccflags-y += -DCONFIG_SPECTRA_ISP=1
@@ -13,6 +14,7 @@ ccflags-y += -DCONFIG_SPECTRA_ICP=1
ccflags-y += -DCONFIG_SPECTRA_JPEG=1
ccflags-y += -DCONFIG_SPECTRA_CUSTOM=1
ccflags-y += -DCONFIG_SPECTRA_SENSOR=1
ccflags-y += -DCONFIG_USE_RPMH_DRV_API=1
# External Dependencies
KBUILD_CPPFLAGS += -DCONFIG_MSM_MMRM=1

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,7 @@
#define CAM_CPAS_INFLIGHT_WORKS 5
#define CAM_CPAS_MAX_CLIENTS 42
#define CAM_CPAS_MAX_AXI_PORTS 6
#define CAM_CPAS_MAX_DRV_PORTS 4
#define CAM_CPAS_MAX_TREE_LEVELS 4
#define CAM_CPAS_MAX_RT_WR_NIU_NODES 10
#define CAM_CPAS_MAX_GRAN_PATHS_PER_CLIENT 32
@@ -65,6 +66,66 @@ enum cam_cpas_access_type {
CAM_REG_TYPE_READ_WRITE,
};
/**
* enum cam_cpas_vote_type - Enum for cpas vote type
*/
enum cam_cpas_vote_type {
CAM_CPAS_VOTE_TYPE_HLOS,
CAM_CPAS_VOTE_TYPE_DRV,
};
/**
* struct cam_cpas_vdd_ahb_mapping : Voltage to ahb level mapping
*
* @vdd_corner : Voltage corner value
* @ahb_level : AHB vote level corresponds to this vdd_corner
*
*/
struct cam_cpas_vdd_ahb_mapping {
unsigned int vdd_corner;
enum cam_vote_level ahb_level;
};
/**
* struct cam_cpas_bw_vote : AXI bw vote
*
* @ab: AB bw value
* @ib: IB bw value
*
*/
struct cam_cpas_bw_vote {
uint64_t ab;
uint64_t ib;
};
/**
* struct cam_cpas_drv_vote : DRV bw vote
*
* @high: Active bw values
* @low: Sleep bw values
*
*/
struct cam_cpas_drv_vote {
struct cam_cpas_bw_vote high;
struct cam_cpas_bw_vote low;
};
/**
* struct cam_cpas_axi_bw_info : AXI bw info
*
* @vote_type: HLOS or DRV vote type
* @hlos_vote: HLOS bw values
* @drv_vote: DRV bw values
*
*/
struct cam_cpas_axi_bw_info {
enum cam_cpas_vote_type vote_type;
union {
struct cam_cpas_bw_vote hlos_vote;
struct cam_cpas_drv_vote drv_vote;
};
};
/**
* struct cam_cpas_internal_ops - CPAS Hardware layer internal ops
*
@@ -124,6 +185,7 @@ struct cam_cpas_reg {
* @registered: Whether client has registered with cpas
* @started: Whether client has streamed on
* @tree_node_valid: Indicates whether tree node has at least one valid node
* @is_drv_dyn: Indicates whether this client is DRV dynamic voting client
* @ahb_level: Determined/Applied ahb level for the client
* @axi_vote: Determined/Applied axi vote for the client
* @axi_port: Client's parent axi port
@@ -135,6 +197,7 @@ struct cam_cpas_client {
bool registered;
bool started;
bool tree_node_valid;
bool is_drv_dyn;
enum cam_vote_level ahb_level;
struct cam_axi_vote axi_vote;
struct cam_cpas_axi_port *axi_port;
@@ -168,12 +231,13 @@ struct cam_cpas_bus_client {
* @ib_bw_voting_needed: if this port can update ib bw dynamically
* @is_rt: if this port represents a real time axi port
* @axi_port_node: Node representing AXI Port info in device tree
* @ab_bw: AB bw value for this port
* @ib_bw: IB bw value for this port
* @drv_idx: DRV index for axi port node
* @cam_rsc_dev: Cam RSC device for DRV
* @is_drv_started: Indicates if DRV started for RSC device corresponding to port
* @curr_bw: Current voted bw after cpas consolidation
* @camnoc_bw: CAMNOC bw value for this port
* @additional_bw: Additional bandwidth to cover non-hw cpas clients
* @applied_ab_bw: applied ab bw for this port
* @applied_ib_bw: applied ib bw for this port
* @applied_bw: Actual applied bw to port
*/
struct cam_cpas_axi_port {
const char *axi_port_name;
@@ -181,31 +245,30 @@ struct cam_cpas_axi_port {
bool ib_bw_voting_needed;
bool is_rt;
struct device_node *axi_port_node;
uint64_t ab_bw;
uint64_t ib_bw;
uint32_t drv_idx;
const struct device *cam_rsc_dev;
bool is_drv_started;
struct cam_cpas_axi_bw_info curr_bw;
uint64_t camnoc_bw;
uint64_t additional_bw;
uint64_t applied_ab_bw;
uint64_t applied_ib_bw;
struct cam_cpas_axi_bw_info applied_bw;
};
/**
* struct cam_cpas_axi_port_debug_info : AXI port information
*
* @axi_port_name: Name of this AXI port
* @ab_bw: AB bw value for this port
* @ib_bw: IB bw value for this port
* @curr_bw: Current voted bw after cpas consolidation
* @camnoc_bw: CAMNOC bw value for this port
* @applied_ab_bw: applied ab bw for this port
* @applied_ib_bw: applied ib bw for this port
* @applied_bw: Actual applied bw to port
* @is_drv_started: Indicates if DRV started for RSC device corresponding to port
*/
struct cam_cpas_axi_port_debug_info {
const char *axi_port_name;
uint64_t ab_bw;
uint64_t ib_bw;
struct cam_cpas_axi_bw_info curr_bw;
uint64_t camnoc_bw;
uint64_t applied_ab_bw;
uint64_t applied_ib_bw;
struct cam_cpas_axi_bw_info applied_bw;
bool is_drv_started;
};
/**
@@ -285,6 +348,7 @@ struct cam_cpas_monitor {
* @slave_err_irq_en: Whether slave error irq is enabled to detect memory
* config issues
* @smmu_fault_handled: Handled address decode error, on fault at SMMU
* @force_hlos_drv: Whether to force disable DRV voting
*/
struct cam_cpas {
struct cam_cpas_hw_caps hw_caps;
@@ -315,6 +379,7 @@ struct cam_cpas {
bool smart_qos_dump;
bool slave_err_irq_en;
bool smmu_fault_handled;
bool force_hlos_drv;
};
int cam_camsstop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops);

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_CPAS_HW_INTF_H_
@@ -47,9 +48,26 @@ enum cam_cpas_hw_cmd_process {
CAM_CPAS_HW_CMD_ACTIVATE_LLC,
CAM_CPAS_HW_CMD_DEACTIVATE_LLC,
CAM_CPAS_HW_CMD_DUMP_BUFF_FILL_INFO,
CAM_CPAS_HW_CMD_CSID_INPUT_CORE_INFO_UPDATE,
CAM_CPAS_HW_CMD_CSID_PROCESS_RESUME,
CAM_CPAS_HW_CMD_INVALID,
};
/**
* struct cam_cpas_hw_cmd_csid_input_core_info_update : CPAS cmd struct for updating acquired
* csid core info to cpas
*
* @csid_idx: CSID core index
* @sfe_idx: SFE core index corresponding to CSID core
* @set_port: Indicates whether to set or reset port for given client
*
*/
struct cam_cpas_hw_cmd_csid_input_core_info_update {
int csid_idx;
int sfe_idx;
bool set_port;
};
/**
* struct cam_cpas_hw_cmd_reg_read_write : CPAS cmd struct for reg read, write
*

View File

@@ -144,6 +144,100 @@ const char *cam_cpas_axi_util_trans_type_to_string(
}
EXPORT_SYMBOL(cam_cpas_axi_util_trans_type_to_string);
const char *cam_cpas_axi_util_drv_vote_lvl_to_string(
uint32_t vote_lvl)
{
switch (vote_lvl) {
case CAM_CPAS_VOTE_LEVEL_LOW:
return "VOTE_LVL_LOW";
case CAM_CPAS_VOTE_LEVEL_HIGH:
return "VOTE_LVL_HIGH";
default:
return "VOTE_LVL_INVALID";
}
}
EXPORT_SYMBOL(cam_cpas_axi_util_drv_vote_lvl_to_string);
int cam_cpas_query_drv_enable(bool *is_drv_enabled)
{
struct cam_hw_info *cpas_hw = NULL;
struct cam_cpas_private_soc *soc_private = NULL;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
if (!is_drv_enabled) {
CAM_ERR(CAM_CPAS, "invalid input %pK", is_drv_enabled);
return -EINVAL;
}
cpas_hw = (struct cam_hw_info *) g_cpas_intf->hw_intf->hw_priv;
soc_private = (struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;
*is_drv_enabled = soc_private->enable_cam_ddr_drv;
return 0;
}
EXPORT_SYMBOL(cam_cpas_query_drv_enable);
int cam_cpas_csid_process_resume(uint32_t csid_idx)
{
int rc;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
g_cpas_intf->hw_intf->hw_priv,
CAM_CPAS_HW_CMD_CSID_PROCESS_RESUME, &csid_idx,
sizeof(uint32_t));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
} else {
CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
rc = -EINVAL;
}
return rc;
}
EXPORT_SYMBOL(cam_cpas_csid_process_resume);
int cam_cpas_csid_input_core_info_update(int csid_idx, int sfe_idx, bool set_port)
{
int rc;
if (!CAM_CPAS_INTF_INITIALIZED()) {
CAM_ERR(CAM_CPAS, "cpas intf not initialized");
return -ENODEV;
}
if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
struct cam_cpas_hw_cmd_csid_input_core_info_update core_info_update;
core_info_update.csid_idx = csid_idx;
core_info_update.sfe_idx = sfe_idx;
core_info_update.set_port = set_port;
rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
g_cpas_intf->hw_intf->hw_priv,
CAM_CPAS_HW_CMD_CSID_INPUT_CORE_INFO_UPDATE, &core_info_update,
sizeof(core_info_update));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
} else {
CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
rc = -EINVAL;
}
return rc;
}
EXPORT_SYMBOL(cam_cpas_csid_input_core_info_update);
int cam_cpas_dump_camnoc_buff_fill_info(uint32_t client_handle)
{
int rc;
@@ -485,9 +579,8 @@ int cam_cpas_start(uint32_t client_handle,
}
EXPORT_SYMBOL(cam_cpas_start);
void cam_cpas_log_votes(void)
void cam_cpas_log_votes(bool ddr_only)
{
uint32_t dummy_args;
int rc;
if (!CAM_CPAS_INTF_INITIALIZED()) {
@@ -498,8 +591,8 @@ void cam_cpas_log_votes(void)
if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
g_cpas_intf->hw_intf->hw_priv,
CAM_CPAS_HW_CMD_LOG_VOTE, &dummy_args,
sizeof(dummy_args));
CAM_CPAS_HW_CMD_LOG_VOTE, &ddr_only,
sizeof(ddr_only));
if (rc)
CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
} else {

View File

@@ -17,8 +17,9 @@
#include "cam_cpas_hw_intf.h"
#include "cam_cpas_hw.h"
#include "cam_cpas_soc.h"
#include "cam_compat.h"
static uint cpas_dump;
static uint cpas_dump = 1;
module_param(cpas_dump, uint, 0644);
#define CAM_ICP_CLK_NAME "cam_icp_clk"
@@ -42,11 +43,12 @@ void cam_cpas_dump_axi_vote_info(
for (i = 0; i < axi_vote->num_paths; i++) {
CAM_INFO(CAM_PERF,
"Client [%s][%d] : [%s], Path=[%d] [%d], camnoc[%llu], mnoc_ab[%llu], mnoc_ib[%llu]",
"Client [%s][%d] : [%s], Path=[%d] [%d], [%s], camnoc[%llu], mnoc_ab[%llu], mnoc_ib[%llu]",
cpas_client->data.identifier, cpas_client->data.cell_index,
identifier,
axi_vote->axi_path[i].path_data_type,
axi_vote->axi_path[i].transac_type,
cam_cpas_axi_util_drv_vote_lvl_to_string(axi_vote->axi_path[i].vote_level),
axi_vote->axi_path[i].camnoc_bw,
axi_vote->axi_path[i].mnoc_ab_bw,
axi_vote->axi_path[i].mnoc_ib_bw);
@@ -71,7 +73,7 @@ void cam_cpas_util_debug_parse_data(
CAM_INFO(CAM_CPAS,
"NODE cell_idx: %d, level: %d, name: %s, axi_port_idx: %d, merge_type: %d, parent_name: %s camnoc_max_needed: %d",
curr_node->cell_idx, curr_node->level_idx,
curr_node->node_name, curr_node->axi_port_idx,
curr_node->node_name, curr_node->axi_port_idx_arr[CAM_CPAS_PORT_HLOS_DRV],
curr_node->merge_type, curr_node->parent_node ?
curr_node->parent_node->node_name : "no parent",
curr_node->camnoc_max_needed);
@@ -79,10 +81,10 @@ void cam_cpas_util_debug_parse_data(
if (curr_node->level_idx)
continue;
CAM_INFO(CAM_CPAS, "path_type: %d, transac_type: %s",
CAM_INFO(CAM_CPAS, "path_type: %d, transac_type: %s drv_voting_idx:%d",
curr_node->path_data_type,
cam_cpas_axi_util_trans_type_to_string(
curr_node->path_trans_type));
curr_node->path_trans_type), curr_node->drv_voting_idx);
for (j = 0; j < CAM_CPAS_PATH_DATA_MAX; j++) {
CAM_INFO(CAM_CPAS, "Constituent path: %d",
@@ -100,6 +102,10 @@ int cam_cpas_node_tree_cleanup(struct cam_cpas *cpas_core,
for (i = 0; i < CAM_CPAS_MAX_TREE_NODES; i++) {
if (soc_private->tree_node[i]) {
kfree(soc_private->tree_node[i]->bw_info);
kfree(soc_private->tree_node[i]->axi_port_idx_arr);
soc_private->tree_node[i]->bw_info = NULL;
soc_private->tree_node[i]->axi_port_idx_arr = NULL;
of_node_put(soc_private->tree_node[i]->tree_dev_node);
kfree(soc_private->tree_node[i]);
soc_private->tree_node[i] = NULL;
@@ -182,6 +188,151 @@ static int cam_cpas_update_camnoc_node(struct cam_cpas *cpas_core,
return 0;
}
static int cam_cpas_parse_mnoc_node(struct cam_cpas *cpas_core,
struct cam_cpas_private_soc *soc_private, struct cam_cpas_tree_node *curr_node_ptr,
struct device_node *mnoc_node, int *mnoc_idx)
{
int rc = 0, count = 0, i;
bool ib_voting_needed = false, is_rt_port = false;
struct of_phandle_args src_args = {0}, dst_args = {0};
ib_voting_needed = of_property_read_bool(curr_node_ptr->tree_dev_node,
"ib-bw-voting-needed");
is_rt_port = of_property_read_bool(curr_node_ptr->tree_dev_node, "rt-axi-port");
if (soc_private->bus_icc_based) {
count = of_property_count_strings(mnoc_node, "interconnect-names");
if (count <= 0) {
CAM_ERR(CAM_CPAS, "no interconnect-names found");
count = 0;
return -EINVAL;
} else if (count > CAM_CPAS_MAX_DRV_PORTS) {
CAM_ERR(CAM_CPAS, "Number of interconnects %d greater than max ports %d",
count, CAM_CPAS_MAX_DRV_PORTS);
count = 0;
return -EINVAL;
}
for (i = 0; i < count; i++) {
if ((i > 0) && !soc_private->enable_cam_ddr_drv)
break;
if (*mnoc_idx >= CAM_CPAS_MAX_AXI_PORTS) {
CAM_ERR(CAM_CPAS, "Invalid mnoc index: %d", *mnoc_idx);
return -EINVAL;
}
cpas_core->axi_port[*mnoc_idx].axi_port_node = mnoc_node;
rc = of_property_read_string_index(mnoc_node, "interconnect-names", i,
&cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name);
if (rc) {
CAM_ERR(CAM_CPAS, "failed to read interconnect-names rc=%d", rc);
return rc;
}
rc = of_parse_phandle_with_args(mnoc_node, "interconnects",
"#interconnect-cells", (2 * i), &src_args);
if (rc) {
CAM_ERR(CAM_CPAS,
"failed to read axi bus src info rc=%d",
rc);
return -EINVAL;
}
of_node_put(src_args.np);
if (src_args.args_count != 1) {
CAM_ERR(CAM_CPAS, "Invalid number of axi src args: %d",
src_args.args_count);
return -EINVAL;
}
cpas_core->axi_port[*mnoc_idx].bus_client.common_data.src_id =
src_args.args[0];
rc = of_parse_phandle_with_args(mnoc_node, "interconnects",
"#interconnect-cells", ((2 * i) + 1), &dst_args);
if (rc) {
CAM_ERR(CAM_CPAS, "failed to read axi bus dst info rc=%d", rc);
return -EINVAL;
}
of_node_put(dst_args.np);
if (dst_args.args_count != 1) {
CAM_ERR(CAM_CPAS, "Invalid number of axi dst args: %d",
dst_args.args_count);
return -EINVAL;
}
cpas_core->axi_port[*mnoc_idx].bus_client.common_data.dst_id =
dst_args.args[0];
cpas_core->axi_port[*mnoc_idx].bus_client.common_data.num_usecases = 2;
cpas_core->axi_port[*mnoc_idx].axi_port_name =
cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name;
cpas_core->axi_port[*mnoc_idx].drv_idx = i;
if (i > CAM_CPAS_PORT_HLOS_DRV) {
cpas_core->axi_port[*mnoc_idx].bus_client.common_data.is_drv_port =
true;
cpas_core->axi_port[*mnoc_idx].curr_bw.vote_type =
CAM_CPAS_VOTE_TYPE_DRV;
cpas_core->axi_port[*mnoc_idx].applied_bw.vote_type =
CAM_CPAS_VOTE_TYPE_DRV;
cpas_core->axi_port[*mnoc_idx].cam_rsc_dev =
cam_cpas_get_rsc_dev_for_drv(i - CAM_CPAS_PORT_DRV_0);
if (!cpas_core->axi_port[*mnoc_idx].cam_rsc_dev) {
CAM_ERR(CAM_CPAS,
"Port[%s][%d] Failed to get rsc device drv_idx:%d",
cpas_core->axi_port[*mnoc_idx].axi_port_name,
*mnoc_idx, i);
rc = -ENODEV;
goto err;
}
}
/*
* The indexes of axi_port_idx_arr map to drv_voting_idx,
* with 0 pointing to hlos drv bus ID
*/
curr_node_ptr->axi_port_idx_arr[i] = *mnoc_idx;
cpas_core->axi_port[*mnoc_idx].ib_bw_voting_needed = ib_voting_needed;
cpas_core->axi_port[*mnoc_idx].is_rt = is_rt_port;
CAM_DBG(CAM_PERF, "Adding Bus Client=[%s] : src=%d, dst=%d mnoc_idx:%d",
cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name,
cpas_core->axi_port[*mnoc_idx].bus_client.common_data.src_id,
cpas_core->axi_port[*mnoc_idx].bus_client.common_data.dst_id,
*mnoc_idx);
(*mnoc_idx)++;
cpas_core->num_axi_ports++;
}
} else {
if (soc_private->enable_cam_ddr_drv) {
CAM_ERR(CAM_CPAS, "DRV not supported for old bus scaling clients");
return -EPERM;
}
cpas_core->axi_port[*mnoc_idx].axi_port_node = mnoc_node;
rc = of_property_read_string(curr_node_ptr->tree_dev_node, "qcom,axi-port-name",
&cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name);
if (rc) {
CAM_ERR(CAM_CPAS,
"failed to read mnoc-port-name rc=%d",
rc);
return rc;
}
cpas_core->axi_port[*mnoc_idx].axi_port_name =
cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name;
curr_node_ptr->axi_port_idx_arr[0] = *mnoc_idx;
cpas_core->axi_port[*mnoc_idx].ib_bw_voting_needed = ib_voting_needed;
cpas_core->axi_port[*mnoc_idx].is_rt = is_rt_port;
(*mnoc_idx)++;
cpas_core->num_axi_ports++;
}
err:
return rc;
}
static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
struct device_node *of_node, struct cam_cpas_private_soc *soc_private)
{
@@ -198,7 +349,7 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
const char *client_name = NULL;
uint32_t client_idx = 0, cell_idx = 0;
uint8_t niu_idx = 0;
int rc = 0, count = 0, i;
int rc = 0, count = 0, i, j, num_drv_ports;
camera_bus_node = of_get_child_by_name(of_node, "camera-bus-nodes");
if (!camera_bus_node) {
@@ -209,8 +360,7 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
soc_private->camera_bus_node = camera_bus_node;
for_each_available_child_of_node(camera_bus_node, level_node) {
rc = of_property_read_u32(level_node, "level-index",
&level_idx);
rc = of_property_read_u32(level_node, "level-index", &level_idx);
if (rc) {
CAM_ERR(CAM_CPAS, "Error reading level idx rc: %d", rc);
return rc;
@@ -226,6 +376,11 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
if (soc_private->enable_smart_qos)
soc_private->smart_qos_info->num_rt_wr_nius = 0;
if (soc_private->enable_cam_ddr_drv)
num_drv_ports = CAM_CPAS_MAX_DRV_PORTS;
else
num_drv_ports = 1;
for (level_idx = (CAM_CPAS_MAX_TREE_LEVELS - 1); level_idx >= 0;
level_idx--) {
level_node = soc_private->level_node[level_idx];
@@ -234,12 +389,9 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
CAM_DBG(CAM_CPAS, "Parsing level %d nodes", level_idx);
camnoc_max_needed = of_property_read_bool(level_node,
"camnoc-max-needed");
camnoc_max_needed = of_property_read_bool(level_node, "camnoc-max-needed");
for_each_available_child_of_node(level_node, curr_node) {
curr_node_ptr =
kzalloc(sizeof(struct cam_cpas_tree_node),
GFP_KERNEL);
curr_node_ptr = kzalloc(sizeof(struct cam_cpas_tree_node), GFP_KERNEL);
if (!curr_node_ptr)
return -ENOMEM;
@@ -256,50 +408,54 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
if (curr_node_ptr->cell_idx >=
CAM_CPAS_MAX_TREE_NODES) {
CAM_ERR(CAM_CPAS, "Invalid cell idx: %d",
curr_node_ptr->cell_idx);
CAM_ERR(CAM_CPAS, "Invalid cell idx: %d", curr_node_ptr->cell_idx);
return -EINVAL;
}
soc_private->tree_node[curr_node_ptr->cell_idx] =
curr_node_ptr;
soc_private->tree_node[curr_node_ptr->cell_idx] = curr_node_ptr;
curr_node_ptr->level_idx = level_idx;
rc = of_property_read_string(curr_node, "node-name",
&curr_node_ptr->node_name);
if (rc) {
CAM_ERR(CAM_CPAS,
"failed to read node-name rc=%d",
rc);
CAM_ERR(CAM_CPAS, "failed to read node-name rc=%d", rc);
return rc;
}
if (soc_private->enable_smart_qos &&
(level_idx == 1) &&
curr_node_ptr->bw_info = kzalloc((sizeof(struct cam_cpas_axi_bw_info) *
num_drv_ports), GFP_KERNEL);
if (!curr_node_ptr->bw_info) {
CAM_ERR(CAM_CPAS, "Failed in allocating memory for bw info");
return -ENOMEM;
}
curr_node_ptr->axi_port_idx_arr = kzalloc((sizeof(int) * num_drv_ports),
GFP_KERNEL);
if (!curr_node_ptr->axi_port_idx_arr) {
CAM_ERR(CAM_CPAS, "Failed in allocating memory for port indices");
return -ENOMEM;
}
if (soc_private->enable_smart_qos && (level_idx == 1) &&
of_property_read_bool(curr_node, "rt-wr-niu")) {
rc = of_property_read_u32(curr_node,
"priority-lut-low-offset",
rc = of_property_read_u32(curr_node, "priority-lut-low-offset",
&curr_node_ptr->pri_lut_low_offset);
if (rc) {
CAM_ERR(CAM_CPAS,
"Invalid priority offset rc %d",
rc);
CAM_ERR(CAM_CPAS, "Invalid priority offset rc %d", rc);
return rc;
}
rc = of_property_read_u32(curr_node, "niu-size",
&curr_node_ptr->niu_size);
if (rc || !curr_node_ptr->niu_size) {
CAM_ERR(CAM_CPAS,
"Invalid niu size rc %d", rc);
CAM_ERR(CAM_CPAS, "Invalid niu size rc %d", rc);
return rc;
}
niu_idx = soc_private->smart_qos_info->num_rt_wr_nius;
if (niu_idx >= CAM_CPAS_MAX_RT_WR_NIU_NODES) {
CAM_ERR(CAM_CPAS,
"Invalid number of level1 nodes %d",
CAM_ERR(CAM_CPAS, "Invalid number of level1 nodes %d",
soc_private->smart_qos_info->num_rt_wr_nius);
return -EINVAL;
}
@@ -310,8 +466,7 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
CAM_DBG(CAM_CPAS,
"level1[%d] : Node %s idx %d priority offset 0x%x, NIU size %dKB",
niu_idx,
curr_node_ptr->node_name, curr_node_ptr->cell_idx,
niu_idx, curr_node_ptr->node_name, curr_node_ptr->cell_idx,
curr_node_ptr->pri_lut_low_offset, curr_node_ptr->niu_size);
}
@@ -321,221 +476,130 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
if (rc)
curr_node_ptr->bus_width_factor = 1;
rc = of_property_read_u32(curr_node,
"traffic-merge-type",
rc = of_property_read_u32(curr_node, "traffic-merge-type",
&curr_node_ptr->merge_type);
curr_node_ptr->axi_port_idx = -1;
mnoc_node = of_get_child_by_name(curr_node,
"qcom,axi-port-mnoc");
for (j = 0; j < num_drv_ports; j++)
curr_node_ptr->axi_port_idx_arr[j] = -1;
mnoc_node = of_get_child_by_name(curr_node, "qcom,axi-port-mnoc");
if (mnoc_node) {
if (mnoc_idx >= CAM_CPAS_MAX_AXI_PORTS) {
CAM_ERR(CAM_CPAS,
"Invalid mnoc index: %d",
mnoc_idx);
return -EINVAL;
}
cpas_core->axi_port[mnoc_idx].axi_port_node
= mnoc_node;
if (soc_private->bus_icc_based) {
struct of_phandle_args src_args = {0},
dst_args = {0};
rc = of_property_read_string(mnoc_node,
"interconnect-names",
&cpas_core->axi_port[mnoc_idx]
.bus_client.common_data.name);
if (rc) {
CAM_ERR(CAM_CPAS,
"failed to read interconnect-names rc=%d",
rc);
return rc;
}
rc = of_parse_phandle_with_args(
mnoc_node, "interconnects",
"#interconnect-cells", 0,
&src_args);
if (rc) {
CAM_ERR(CAM_CPAS,
"failed to read axi bus src info rc=%d",
rc);
return -EINVAL;
}
of_node_put(src_args.np);
if (src_args.args_count != 1) {
CAM_ERR(CAM_CPAS,
"Invalid number of axi src args: %d",
src_args.args_count);
return -EINVAL;
}
cpas_core->axi_port[mnoc_idx].bus_client
.common_data.src_id = src_args.args[0];
rc = of_parse_phandle_with_args(
mnoc_node, "interconnects",
"#interconnect-cells", 1,
&dst_args);
if (rc) {
CAM_ERR(CAM_CPAS,
"failed to read axi bus dst info rc=%d",
rc);
return -EINVAL;
}
of_node_put(dst_args.np);
if (dst_args.args_count != 1) {
CAM_ERR(CAM_CPAS,
"Invalid number of axi dst args: %d",
dst_args.args_count);
return -EINVAL;
}
cpas_core->axi_port[mnoc_idx].bus_client
.common_data.dst_id = dst_args.args[0];
cpas_core->axi_port[mnoc_idx].bus_client
.common_data.num_usecases = 2;
} else {
rc = of_property_read_string(
curr_node, "qcom,axi-port-name",
&cpas_core->axi_port[mnoc_idx]
.bus_client.common_data.name);
if (rc) {
CAM_ERR(CAM_CPAS,
"failed to read mnoc-port-name rc=%d",
rc);
return rc;
}
}
cpas_core->axi_port[mnoc_idx].axi_port_name =
cpas_core->axi_port[mnoc_idx]
.bus_client.common_data.name;
cpas_core->axi_port
[mnoc_idx].ib_bw_voting_needed
= of_property_read_bool(curr_node,
"ib-bw-voting-needed");
cpas_core->axi_port
[mnoc_idx].is_rt
= of_property_read_bool(curr_node,
"rt-axi-port");
curr_node_ptr->axi_port_idx = mnoc_idx;
mnoc_idx++;
cpas_core->num_axi_ports++;
}
if (!soc_private->control_camnoc_axi_clk) {
rc = cam_cpas_update_camnoc_node(
cpas_core, curr_node, curr_node_ptr,
&camnoc_idx);
rc = cam_cpas_parse_mnoc_node(cpas_core, soc_private, curr_node_ptr,
mnoc_node, &mnoc_idx);
if (rc) {
CAM_ERR(CAM_CPAS,
"Parse Camnoc port fail");
CAM_ERR(CAM_CPAS, "failed to parse mnoc node info rc=%d",
rc);
return rc;
}
}
rc = of_property_read_string(curr_node,
"client-name", &client_name);
if (!soc_private->control_camnoc_axi_clk) {
rc = cam_cpas_update_camnoc_node(cpas_core, curr_node,
curr_node_ptr, &camnoc_idx);
if (rc) {
CAM_ERR(CAM_CPAS, "failed to parse camnoc node info rc=%d",
rc);
return rc;
}
}
rc = of_property_read_string(curr_node, "client-name", &client_name);
if (!rc) {
rc = of_property_read_u32(curr_node,
"traffic-data", &curr_node_ptr->path_data_type);
rc = of_property_read_u32(curr_node, "traffic-data",
&curr_node_ptr->path_data_type);
if (rc) {
CAM_ERR(CAM_CPAS,
"Path Data type not found");
return rc;
}
rc = cam_cpas_util_path_type_to_idx(
&curr_node_ptr->path_data_type);
rc = cam_cpas_util_path_type_to_idx(&curr_node_ptr->path_data_type);
if (rc) {
CAM_ERR(CAM_CPAS, "Incorrect path type for client: %s",
client_name);
return rc;
}
rc = of_property_read_u32(curr_node,
"traffic-transaction-type",
rc = of_property_read_u32(curr_node, "traffic-transaction-type",
&curr_node_ptr->path_trans_type);
if (rc) {
CAM_ERR(CAM_CPAS,
"Path Transac type not found");
CAM_ERR(CAM_CPAS, "Path Transac type not found");
return rc;
}
if (curr_node_ptr->path_trans_type >=
CAM_CPAS_TRANSACTION_MAX) {
CAM_ERR(CAM_CPAS,
"Invalid transac type: %d",
if (curr_node_ptr->path_trans_type >= CAM_CPAS_TRANSACTION_MAX) {
CAM_ERR(CAM_CPAS, "Invalid transac type: %d",
curr_node_ptr->path_trans_type);
return -EINVAL;
}
count = of_property_count_u32_elems(curr_node,
"constituent-paths");
count = of_property_count_u32_elems(curr_node, "constituent-paths");
for (i = 0; i < count; i++) {
rc = of_property_read_u32_index(
curr_node, "constituent-paths",
i, &path_idx);
rc = of_property_read_u32_index(curr_node,
"constituent-paths", i, &path_idx);
if (rc) {
CAM_ERR(CAM_CPAS,
"No constituent path at %d", i);
CAM_ERR(CAM_CPAS, "No constituent path at %d", i);
return rc;
}
rc = cam_cpas_util_path_type_to_idx(
&path_idx);
rc = cam_cpas_util_path_type_to_idx(&path_idx);
if (rc)
return rc;
curr_node_ptr->constituent_paths
[path_idx] = true;
curr_node_ptr->constituent_paths[path_idx] = true;
}
rc = cam_common_util_get_string_index(
soc_private->client_name,
soc_private->num_clients,
client_name, &client_idx);
rc = cam_common_util_get_string_index(soc_private->client_name,
soc_private->num_clients, client_name, &client_idx);
if (rc) {
CAM_ERR(CAM_CPAS,
"client name not found in list: %s",
client_name);
CAM_ERR(CAM_CPAS, "client name not found in list: %s",
client_name);
return rc;
}
if (client_idx >= CAM_CPAS_MAX_CLIENTS)
return -EINVAL;
curr_client =
cpas_core->cpas_client[client_idx];
curr_client = cpas_core->cpas_client[client_idx];
curr_client->tree_node_valid = true;
curr_client->tree_node
[curr_node_ptr->path_data_type]
[curr_node_ptr->path_trans_type] =
curr_node_ptr;
CAM_DBG(CAM_CPAS,
"CLIENT NODE ADDED: %d %d %s",
curr_client->tree_node[curr_node_ptr->path_data_type]
[curr_node_ptr->path_trans_type] = curr_node_ptr;
if (soc_private->enable_cam_ddr_drv) {
rc = of_property_read_u32(curr_node, "drv-voting-index",
&curr_node_ptr->drv_voting_idx);
if (curr_node_ptr->drv_voting_idx == CAM_CPAS_PORT_DRV_DYN)
curr_client->is_drv_dyn = true;
if (curr_client->is_drv_dyn &&
(curr_node_ptr->drv_voting_idx !=
CAM_CPAS_PORT_DRV_DYN))
CAM_ERR(CAM_CPAS,
"Invalid config for drv dyn client: %s drv_idx: %d",
client_name, curr_node_ptr->drv_voting_idx);
}
CAM_DBG(CAM_CPAS, "Client Node Added: %d %d %s %d",
curr_node_ptr->path_data_type,
curr_node_ptr->path_trans_type,
client_name);
curr_node_ptr->path_trans_type, client_name,
curr_node_ptr->drv_voting_idx);
}
parent_node = of_parse_phandle(curr_node,
"parent-node", 0);
if (soc_private->enable_cam_ddr_drv)
for (j = CAM_CPAS_PORT_DRV_0; j < num_drv_ports; j++)
curr_node_ptr->bw_info[j].vote_type =
CAM_CPAS_VOTE_TYPE_DRV;
parent_node = of_parse_phandle(curr_node, "parent-node", 0);
if (parent_node) {
of_property_read_u32(parent_node, "cell-index",
&cell_idx);
curr_node_ptr->parent_node =
soc_private->tree_node[cell_idx];
of_property_read_u32(parent_node, "cell-index", &cell_idx);
curr_node_ptr->parent_node = soc_private->tree_node[cell_idx];
} else {
CAM_DBG(CAM_CPAS,
"no parent node at this level");
CAM_DBG(CAM_CPAS, "no parent node at this level");
}
}
}
mutex_init(&cpas_core->tree_lock);
cam_cpas_util_debug_parse_data(soc_private);
@@ -807,6 +871,7 @@ int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
struct device_node *of_node;
struct of_phandle_args src_args = {0}, dst_args = {0};
int count = 0, i = 0, rc = 0, num_bw_values = 0, num_levels = 0;
uint32_t cam_drv_en_mask_val = 0;
struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
if (!soc_private || !pdev) {
@@ -1120,6 +1185,10 @@ int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
soc_private->smart_qos_info = NULL;
}
rc = of_property_read_u32(of_node, "enable-cam-drv", &cam_drv_en_mask_val);
if (cam_drv_en_mask_val & CAM_DDR_DRV)
soc_private->enable_cam_ddr_drv = true;
rc = cam_cpas_parse_node_tree(cpas_core, of_node, soc_private);
if (rc) {
CAM_ERR(CAM_CPAS, "Node tree parsing failed rc: %d", rc);

View File

@@ -15,34 +15,21 @@
#define CAM_CPAS_MAX_TREE_NODES 61
#define CAM_CPAS_MAX_FUSE_FEATURE 10
/**
* struct cam_cpas_vdd_ahb_mapping : Voltage to ahb level mapping
*
* @vdd_corner : Voltage corner value
* @ahb_level : AHB vote level corresponds to this vdd_corner
*
*/
struct cam_cpas_vdd_ahb_mapping {
unsigned int vdd_corner;
enum cam_vote_level ahb_level;
};
/**
* struct cpas_tree_node: Generic cpas tree node for BW voting
*
* @cell_idx: Index to identify node from device tree and its parent
* @level_idx: Index to identify at what level the node is present
* @axi_port_idx: Index to identify which axi port to vote the consolidated bw
* @axi_port_idx_arr: Index to identify which axi port to vote the consolidated bw.
* It can point to multiple indexes in case of camera DRV
* @drv_voting_idx: Specifies the index to which the child node would finally vote.
* @camnoc_axi_port_idx: Index to find which axi port to vote consolidated bw
* @path_data_type: Traffic type info from device tree (ife-vid, ife-disp etc)
* @path_trans_type: Transaction type info from device tree (rd, wr)
* @merge_type: Traffic merge type (calculation info) from device tree
* @bus_width_factor: Factor for accounting bus width in CAMNOC bw calculation
* @camnoc_bw: CAMNOC bw value at current node
* @mnoc_ab_bw: MNOC AB bw value at current node
* @mnoc_ib_bw: MNOC IB bw value at current node
* @ddr_ab_bw: DDR AB bw value at current node
* @ddr_ib_bw: DDR IB bw value at current node
* @bw_info: AXI BW info for all drv ports
* @camnoc_max_needed: If node is needed for CAMNOC BW calculation then true
* @constituent_paths: Constituent paths presence info from device tree
* Ex: For CAM_CPAS_PATH_DATA_IFE_UBWC_STATS, index corresponding to
@@ -61,7 +48,8 @@ struct cam_cpas_vdd_ahb_mapping {
struct cam_cpas_tree_node {
uint32_t cell_idx;
int level_idx;
int axi_port_idx;
int *axi_port_idx_arr;
int drv_voting_idx;
int camnoc_axi_port_idx;
const char *node_name;
uint32_t path_data_type;
@@ -69,10 +57,7 @@ struct cam_cpas_tree_node {
uint32_t merge_type;
uint32_t bus_width_factor;
uint64_t camnoc_bw;
uint64_t mnoc_ab_bw;
uint64_t mnoc_ib_bw;
uint64_t ddr_ab_bw;
uint64_t ddr_ib_bw;
struct cam_cpas_axi_bw_info *bw_info;
bool camnoc_max_needed;
bool constituent_paths[CAM_CPAS_PATH_DATA_MAX];
struct device_node *tree_dev_node;
@@ -163,6 +148,7 @@ struct cam_cpas_smart_qos_info {
* @num_caches: Number of last level caches
* @llcc_info: Cache info
* @enable_smart_qos: Whether to enable Smart QoS mechanism on current chipset
* @enable_cam_ddr_drv: Whether to enable Camera DDR DRV on current chipset
* @smart_qos_info: Pointer to smart qos info
* @icp_clk_index: Index of optional icp clk
*/
@@ -188,6 +174,7 @@ struct cam_cpas_private_soc {
uint32_t num_caches;
struct cam_sys_cache_info *llcc_info;
bool enable_smart_qos;
bool enable_cam_ddr_drv;
struct cam_cpas_smart_qos_info *smart_qos_info;
int32_t icp_clk_index;
};

View File

@@ -498,6 +498,27 @@ struct cam_ahb_vote {
} vote;
};
/**
* struct cam_cpas_axi_per_path_bw_vote - Internal per path bandwidth vote information
*
* @usage_data: client usage data (left/right/rdi)
* @transac_type: Transaction type on the path (read/write)
* @path_data_type: Path for which vote is given (video, display, rdi)
* @vote_level: Vote level for this path
* @camnoc_bw: CAMNOC bw for this path
* @mnoc_ab_bw: MNOC AB bw for this path
* @mnoc_ib_bw: MNOC IB bw for this path
*/
struct cam_cpas_axi_per_path_bw_vote {
uint32_t usage_data;
uint32_t transac_type;
uint32_t path_data_type;
uint32_t vote_level;
uint64_t camnoc_bw;
uint64_t mnoc_ab_bw;
uint64_t mnoc_ib_bw;
};
/**
* struct cam_axi_vote : AXI vote
*
@@ -507,7 +528,7 @@ struct cam_ahb_vote {
*/
struct cam_axi_vote {
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_CPAS_MAX_PATHS_PER_CLIENT];
struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_CPAS_MAX_PATHS_PER_CLIENT];
};
/**
@@ -729,16 +750,31 @@ const char *cam_cpas_axi_util_path_type_to_string(
const char *cam_cpas_axi_util_trans_type_to_string(
uint32_t path_data_type);
/**
* cam_cpas_axi_util_drv_vote_lvl_to_string()
*
* @brief: API to get string for given DRV vote level
*
* @vote_lvl : DRV vote level
*
* @return string.
*
*/
const char *cam_cpas_axi_util_drv_vote_lvl_to_string(
uint32_t vote_lvl);
/**
* cam_cpas_log_votes()
*
* @brief: API to print the all bw votes of axi client. It also print the
* applied camnoc axi clock vote value and ahb vote value
*
* @ddr_only: Print only DDR info
*
* @return 0 on success.
*
*/
void cam_cpas_log_votes(void);
void cam_cpas_log_votes(bool ddr_only);
/**
* cam_cpas_select_qos_settings()
@@ -817,4 +853,40 @@ int cam_cpas_deactivate_llcc(enum cam_sys_cache_config_types type);
*/
int cam_cpas_dump_camnoc_buff_fill_info(uint32_t client_handle);
/**
* cam_cpas_csid_input_core_info_update()
*
* @brief: API to communicate csid input core info to cpas
*
* @csid_idx: csid hw index connected to particular sfe
* @sfe_idx: sfe idx to be connected to particular DRV path
* @set_port: Indicates whether to set or reset DRV port info in dynamic client
*
* @return 0 on success
*
*/
int cam_cpas_csid_input_core_info_update(int csid_idx, int sfe_idx, bool set_port);
/**
* cam_cpas_csid_process_resume()
*
* @brief: API to process csid resume in cpas
* @csid_idx: CSID idx to notify resume for
*
* @return 0 on success
*
*/
int cam_cpas_csid_process_resume(uint32_t csid_idx);
/**
* cam_cpas_query_drv_enable()
*
* @brief: API to indicate DRV enabled on hw or not
* @is_drv_enabled: Indication to be set by the API
*
* @return 0 on success
*
*/
int cam_cpas_query_drv_enable(bool *is_drv_enabled);
#endif /* _CAM_CPAS_API_H_ */

View File

@@ -362,7 +362,7 @@ static int cam_cre_update_cpas_vote(struct cam_cre_hw_mgr *hw_mgr,
memcpy(&bw_update.axi_vote.axi_path[0],
&clk_info->axi_path[0],
bw_update.axi_vote.num_paths *
sizeof(struct cam_axi_per_path_bw_vote));
sizeof(struct cam_cpas_axi_per_path_bw_vote));
bw_update.axi_vote_valid = true;
for (i = 0; i < cre_hw_mgr->num_cre; i++) {
@@ -484,7 +484,7 @@ static bool cam_cre_update_bw_v2(struct cam_cre_hw_mgr *hw_mgr,
memcpy(&ctx_data->clk_info.axi_path[0],
&clk_info->axi_path[0],
clk_info->num_paths * sizeof(struct cam_axi_per_path_bw_vote));
clk_info->num_paths * sizeof(struct cam_cpas_axi_per_path_bw_vote));
/*
* Add new vote of this context in hw mgr.
@@ -2045,7 +2045,7 @@ static int cam_cre_packet_generic_blob_handler(void *user_data,
struct cam_cre_ctx *ctx_data;
uint32_t index;
size_t clk_update_size = 0;
int rc = 0;
int rc = 0, i;
if (!blob_data || (blob_size == 0)) {
CAM_ERR(CAM_CRE, "Invalid blob info %pK %d", blob_data,
@@ -2099,10 +2099,23 @@ static int cam_cre_packet_generic_blob_handler(void *user_data,
clk_info = &ctx_data->req_list[index]->clk_info;
clk_info_v2 = &ctx_data->req_list[index]->clk_info_v2;
clk_info_v2.budget_ns = soc_req->budget_ns;
clk_info_v2.frame_cycles = soc_req->frame_cycles;
clk_info_v2.rt_flag = soc_req->rt_flag;
clk_info_v2.num_paths = soc_req->num_paths;
memcpy(clk_info_v2, soc_req, clk_update_size);
for (i = 0; i < soc_req->num_paths; i++) {
clk_info_v2.axi_path[i].usage_data = soc_req->axi_path[i].usage_data;
clk_info_v2.axi_path[i].transac_type = soc_req->axi_path[i].transac_type;
clk_info_v2.axi_path[i].path_data_type =
soc_req->axi_path[i].path_data_type;
clk_info_v2.axi_path[i].vote_level = 0;
clk_info_v2.axi_path[i].camnoc_bw = soc_req->axi_path[i].camnoc_bw;
clk_info_v2.axi_path[i].mnoc_ab_bw = soc_req->axi_path[i].mnoc_ab_bw;
clk_info_v2.axi_path[i].mnoc_ib_bw = soc_req->axi_path[i].mnoc_ib_bw;
}
/* Use v2 structure for clk fields */
/* Use v1 structure for clk fields */
clk_info->budget_ns = clk_info_v2->budget_ns;
clk_info->frame_cycles = clk_info_v2->frame_cycles;
clk_info->rt_flag = clk_info_v2->rt_flag;

View File

@@ -100,7 +100,7 @@ struct cam_cre_ctx_clk_info {
uint32_t reserved;
int32_t clk_rate[CAM_MAX_VOTE];
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_CRE_MAX_PER_PATH_VOTES];
struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_CRE_MAX_PER_PATH_VOTES];
};
/**
@@ -135,7 +135,7 @@ struct cam_cre_clk_info {
uint32_t threshold;
uint32_t over_clked;
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_CRE_MAX_PER_PATH_VOTES];
struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_CRE_MAX_PER_PATH_VOTES];
uint32_t hw_type;
struct cam_req_mgr_timer *watch_dog;
uint32_t watch_dog_reset_counter;
@@ -254,7 +254,7 @@ struct cam_cre_clk_bw_req_internal_v2 {
uint32_t rt_flag;
uint32_t reserved;
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_CRE_MAX_PER_PATH_VOTES];
struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_CRE_MAX_PER_PATH_VOTES];
};
/**

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/of.h>
@@ -81,10 +82,6 @@ int cam_bps_init_hw(void *device_priv,
CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote.axi_vote.axi_path[0].mnoc_ib_bw =
CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote.axi_vote.axi_path[0].ddr_ab_bw =
CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote.axi_vote.axi_path[0].ddr_ib_bw =
CAM_CPAS_DEFAULT_AXI_BW;
rc = cam_cpas_start(core_info->cpas_handle,
&cpas_vote.ahb_vote, &cpas_vote.axi_vote);

View File

@@ -547,8 +547,6 @@ static int cam_icp_remove_ctx_bw(struct cam_icp_hw_mgr *hw_mgr,
do_div(temp, device_share_ratio);
clk_update.axi_vote.axi_path[0].mnoc_ab_bw = temp;
clk_update.axi_vote.axi_path[0].mnoc_ib_bw = temp;
clk_update.axi_vote.axi_path[0].ddr_ab_bw = temp;
clk_update.axi_vote.axi_path[0].ddr_ib_bw = temp;
} else {
int path_index;
@@ -584,10 +582,6 @@ static int cam_icp_remove_ctx_bw(struct cam_icp_hw_mgr *hw_mgr,
ctx_data->clk_info.axi_path[i].mnoc_ab_bw;
clk_info->axi_path[path_index].mnoc_ib_bw -=
ctx_data->clk_info.axi_path[i].mnoc_ib_bw;
clk_info->axi_path[path_index].ddr_ab_bw -=
ctx_data->clk_info.axi_path[i].ddr_ab_bw;
clk_info->axi_path[path_index].ddr_ib_bw -=
ctx_data->clk_info.axi_path[i].ddr_ib_bw;
total_ab_bw +=
clk_info->axi_path[path_index].mnoc_ab_bw;
@@ -619,7 +613,7 @@ static int cam_icp_remove_ctx_bw(struct cam_icp_hw_mgr *hw_mgr,
memset(&ctx_data->clk_info.axi_path[0], 0,
CAM_ICP_MAX_PER_PATH_VOTES *
sizeof(struct cam_axi_per_path_bw_vote));
sizeof(struct cam_cpas_axi_per_path_bw_vote));
ctx_data->clk_info.curr_fc = 0;
ctx_data->clk_info.base_clk = 0;
@@ -627,7 +621,7 @@ static int cam_icp_remove_ctx_bw(struct cam_icp_hw_mgr *hw_mgr,
memcpy(&clk_update.axi_vote.axi_path[0],
&clk_info->axi_path[0],
clk_update.axi_vote.num_paths *
sizeof(struct cam_axi_per_path_bw_vote));
sizeof(struct cam_cpas_axi_per_path_bw_vote));
if (device_share_ratio > 1) {
for (i = 0; i < clk_update.axi_vote.num_paths; i++) {
@@ -640,12 +634,6 @@ static int cam_icp_remove_ctx_bw(struct cam_icp_hw_mgr *hw_mgr,
do_div(
clk_update.axi_vote.axi_path[i].mnoc_ib_bw,
device_share_ratio);
do_div(
clk_update.axi_vote.axi_path[i].ddr_ab_bw,
device_share_ratio);
do_div(
clk_update.axi_vote.axi_path[i].ddr_ib_bw,
device_share_ratio);
}
}
}
@@ -1224,17 +1212,13 @@ static bool cam_icp_update_bw_v2(struct cam_icp_hw_mgr *hw_mgr,
ctx_data->clk_info.axi_path[i].mnoc_ab_bw;
hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw -=
ctx_data->clk_info.axi_path[i].mnoc_ib_bw;
hw_mgr_clk_info->axi_path[path_index].ddr_ab_bw -=
ctx_data->clk_info.axi_path[i].ddr_ab_bw;
hw_mgr_clk_info->axi_path[path_index].ddr_ib_bw -=
ctx_data->clk_info.axi_path[i].ddr_ib_bw;
}
ctx_data->clk_info.num_paths = clk_info->num_paths;
memcpy(&ctx_data->clk_info.axi_path[0],
&clk_info->axi_path[0],
clk_info->num_paths * sizeof(struct cam_axi_per_path_bw_vote));
clk_info->num_paths * sizeof(struct cam_cpas_axi_per_path_bw_vote));
/*
* Add new vote of this context in hw mgr.
@@ -1267,11 +1251,6 @@ static bool cam_icp_update_bw_v2(struct cam_icp_hw_mgr *hw_mgr,
ctx_data->clk_info.axi_path[i].mnoc_ab_bw;
hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw +=
ctx_data->clk_info.axi_path[i].mnoc_ib_bw;
hw_mgr_clk_info->axi_path[path_index].ddr_ab_bw +=
ctx_data->clk_info.axi_path[i].ddr_ab_bw;
hw_mgr_clk_info->axi_path[path_index].ddr_ib_bw +=
ctx_data->clk_info.axi_path[i].ddr_ib_bw;
CAM_DBG(CAM_PERF,
"Consolidate Path Vote : Dev[%s] i[%d] path_idx[%d] : [%s %s] [%lld %lld]",
cam_icp_dev_type_to_name(
@@ -1617,14 +1596,12 @@ static int cam_icp_update_cpas_vote(struct cam_icp_hw_mgr *hw_mgr,
do_div(temp, device_share_ratio);
clk_update.axi_vote.axi_path[0].mnoc_ab_bw = temp;
clk_update.axi_vote.axi_path[0].mnoc_ib_bw = temp;
clk_update.axi_vote.axi_path[0].ddr_ab_bw = temp;
clk_update.axi_vote.axi_path[0].ddr_ib_bw = temp;
} else {
clk_update.axi_vote.num_paths = clk_info->num_paths;
memcpy(&clk_update.axi_vote.axi_path[0],
&clk_info->axi_path[0],
clk_update.axi_vote.num_paths *
sizeof(struct cam_axi_per_path_bw_vote));
sizeof(struct cam_cpas_axi_per_path_bw_vote));
if (device_share_ratio > 1) {
for (i = 0; i < clk_update.axi_vote.num_paths; i++) {
@@ -1637,12 +1614,6 @@ static int cam_icp_update_cpas_vote(struct cam_icp_hw_mgr *hw_mgr,
do_div(
clk_update.axi_vote.axi_path[i].mnoc_ib_bw,
device_share_ratio);
do_div(
clk_update.axi_vote.axi_path[i].ddr_ab_bw,
device_share_ratio);
do_div(
clk_update.axi_vote.axi_path[i].ddr_ib_bw,
device_share_ratio);
}
}
}
@@ -2285,6 +2256,47 @@ static inline void cam_icp_mgr_validate_inject_err(uint64_t current_req_id, uint
memset(&(ctx_data->err_inject_params), 0, sizeof(struct cam_hw_err_param));
}
static void cam_icp_mgr_dump_active_req_info(void)
{
struct cam_icp_hw_ctx_data *ctx_data = NULL;
char log_info[256];
size_t buf_size, len;
uint32_t total_active_streams = 0, total_active_requests = 0;
int i, j;
buf_size = sizeof(log_info);
mutex_lock(&icp_hw_mgr.hw_mgr_mutex);
for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
ctx_data = &icp_hw_mgr.ctx_data[i];
mutex_lock(&ctx_data->ctx_mutex);
if (ctx_data->state != CAM_ICP_CTX_STATE_ACQUIRED) {
mutex_unlock(&ctx_data->ctx_mutex);
continue;
}
memset(log_info, 0, buf_size);
len = 0;
for (j = 0; j < CAM_FRAME_CMD_MAX; j++) {
if (!ctx_data->hfi_frame_process.request_id[j])
continue;
len += scnprintf(log_info + len, (buf_size - len), " %llu",
ctx_data->hfi_frame_process.request_id[j]);
total_active_requests++;
}
total_active_streams++;
CAM_INFO(CAM_ICP, "Requests in ctx: %u type: %s :%s", ctx_data->ctx_id,
cam_icp_dev_type_to_name(ctx_data->icp_dev_acquire_info->dev_type),
len ? log_info : " None");
mutex_unlock(&ctx_data->ctx_mutex);
}
mutex_unlock(&icp_hw_mgr.hw_mgr_mutex);
CAM_INFO(CAM_ICP, "Total Active streams: %u, Total active requests: %u",
total_active_streams, total_active_requests);
}
static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
{
int i;
@@ -2296,8 +2308,7 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
struct cam_hw_done_event_data buf_data = {0};
struct cam_icp_hw_buf_done_evt_data icp_done_evt;
struct cam_icp_hw_error_evt_data icp_err_evt = {0};
uint32_t clk_type;
uint32_t event_id;
uint32_t clk_type, event_id;
struct cam_hangdump_mem_regions *mem_regions = NULL;
ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
@@ -2390,8 +2401,13 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
buf_data.request_id = hfi_frame_process->request_id[idx];
icp_done_evt.evt_id = event_id;
icp_done_evt.buf_done_data = &buf_data;
ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_BUF_DONE,
&icp_done_evt);
if (ctx_data->ctxt_event_cb)
ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_BUF_DONE,
&icp_done_evt);
else
CAM_ERR(CAM_ICP,
"Event callback invalid for ctx: %u [%s] failed to signal req: %llu",
ctx_data->ctx_id, ctx_data->ctx_id_string, buf_data.request_id);
hfi_frame_process->request_id[idx] = 0;
if (ctx_data->hfi_frame_process.in_resource[idx] > 0) {
@@ -2403,14 +2419,21 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
clear_bit(idx, ctx_data->hfi_frame_process.bitmap);
hfi_frame_process->fw_process_flag[idx] = false;
mutex_unlock(&ctx_data->ctx_mutex);
/* report recovery to userspace if FW encounters no memory */
if (ioconfig_ack->err_type == CAMERAICP_ENOMEMORY) {
cam_icp_mgr_dump_active_req_info();
icp_err_evt.err_type = CAM_ICP_HW_ERROR_NO_MEM;
icp_err_evt.req_id = request_id;
ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_ERROR,
&icp_err_evt);
mutex_lock(&ctx_data->ctx_mutex);
if (ctx_data->ctxt_event_cb)
ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_ERROR,
&icp_err_evt);
mutex_unlock(&ctx_data->ctx_mutex);
}
mutex_unlock(&ctx_data->ctx_mutex);
return 0;
}
@@ -5277,18 +5300,30 @@ static int cam_icp_packet_generic_blob_handler(void *user_data,
}
clk_update_size = sizeof(struct cam_icp_clk_bw_request_v2) +
((soc_req_v2->num_paths - 1) *
sizeof(struct cam_axi_per_path_bw_vote));
((soc_req_v2->num_paths - 1) * sizeof(struct cam_axi_per_path_bw_vote));
if (blob_size < clk_update_size) {
CAM_ERR(CAM_ICP, "Invalid blob size: %u",
blob_size);
CAM_ERR(CAM_ICP, "Invalid blob size: %u", blob_size);
return -EINVAL;
}
clk_info = &ctx_data->hfi_frame_process.clk_info[index];
clk_info_v2 = &ctx_data->hfi_frame_process.clk_info_v2[index];
clk_info_v2->budget_ns = soc_req_v2->budget_ns;
clk_info_v2->frame_cycles = soc_req_v2->frame_cycles;
clk_info_v2->rt_flag = soc_req_v2->rt_flag;
clk_info_v2->num_paths = soc_req_v2->num_paths;
memcpy(clk_info_v2, soc_req_v2, clk_update_size);
for (i = 0; i < soc_req_v2->num_paths; i++) {
clk_info_v2->axi_path[i].usage_data = soc_req_v2->axi_path[i].usage_data;
clk_info_v2->axi_path[i].transac_type =
soc_req_v2->axi_path[i].transac_type;
clk_info_v2->axi_path[i].path_data_type =
soc_req_v2->axi_path[i].path_data_type;
clk_info_v2->axi_path[i].vote_level = 0;
clk_info_v2->axi_path[i].camnoc_bw = soc_req_v2->axi_path[i].camnoc_bw;
clk_info_v2->axi_path[i].mnoc_ab_bw = soc_req_v2->axi_path[i].mnoc_ab_bw;
clk_info_v2->axi_path[i].mnoc_ib_bw = soc_req_v2->axi_path[i].mnoc_ib_bw;
}
/* Use v1 structure for clk fields */
clk_info->budget_ns = clk_info_v2->budget_ns;
@@ -5296,11 +5331,10 @@ static int cam_icp_packet_generic_blob_handler(void *user_data,
clk_info->rt_flag = clk_info_v2->rt_flag;
CAM_DBG(CAM_PERF,
"budget=%llu, frame_cycle=%llu, rt_flag=%d, num_paths=%d, clk_update_size=%d, index=%d, ctx_data=%pK",
"budget=%llu, frame_cycle=%llu, rt_flag=%d, num_paths=%d, index=%d, ctx_data=%pK",
clk_info_v2->budget_ns, clk_info_v2->frame_cycles,
clk_info_v2->rt_flag,
clk_info_v2->num_paths,
clk_update_size,
index,
ctx_data);
@@ -5944,8 +5978,6 @@ hw_dump:
*clk_addr++ = ctx_data->clk_info.axi_path[j].camnoc_bw;
*clk_addr++ = ctx_data->clk_info.axi_path[j].mnoc_ab_bw;
*clk_addr++ = ctx_data->clk_info.axi_path[j].mnoc_ib_bw;
*clk_addr++ = ctx_data->clk_info.axi_path[j].ddr_ab_bw;
*clk_addr++ = ctx_data->clk_info.axi_path[j].ddr_ib_bw;
}
hdr->size = hdr->word_size * (clk_addr - clk_start);
dump_args->offset += (hdr->size + sizeof(struct cam_icp_dump_header));

View File

@@ -170,7 +170,7 @@ struct cam_icp_clk_bw_req_internal_v2 {
uint32_t rt_flag;
uint32_t reserved;
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
};
#define HANG_DUMP_REGIONS_MAX 10
@@ -244,7 +244,7 @@ struct cam_ctx_clk_info {
uint64_t compressed_bw;
int32_t clk_rate[CAM_MAX_VOTE];
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
bool bw_included;
};
@@ -338,7 +338,7 @@ struct cam_icp_clk_info {
uint64_t uncompressed_bw;
uint64_t compressed_bw;
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
uint32_t hw_type;
struct cam_req_mgr_timer *watch_dog;
uint32_t watch_dog_reset_counter;

View File

@@ -230,10 +230,6 @@ int cam_icp_v1_init_hw(void *device_priv,
CAM_ICP_BW_BYTES_VOTE;
cpas_vote.axi_vote.axi_path[0].mnoc_ib_bw =
CAM_ICP_BW_BYTES_VOTE;
cpas_vote.axi_vote.axi_path[0].ddr_ab_bw =
CAM_ICP_BW_BYTES_VOTE;
cpas_vote.axi_vote.axi_path[0].ddr_ib_bw =
CAM_ICP_BW_BYTES_VOTE;
rc = cam_cpas_start(core_info->cpas_handle,
&cpas_vote.ahb_vote, &cpas_vote.axi_vote);

View File

@@ -160,8 +160,6 @@ static int cam_icp_v2_cpas_start(struct cam_icp_v2_core_info *core_info)
vote.axi_vote.axi_path[0].camnoc_bw = CAM_ICP_BW_BYTES_VOTE;
vote.axi_vote.axi_path[0].mnoc_ab_bw = CAM_ICP_BW_BYTES_VOTE;
vote.axi_vote.axi_path[0].mnoc_ib_bw = CAM_ICP_BW_BYTES_VOTE;
vote.axi_vote.axi_path[0].ddr_ab_bw = CAM_ICP_BW_BYTES_VOTE;
vote.axi_vote.axi_path[0].ddr_ib_bw = CAM_ICP_BW_BYTES_VOTE;
return __icp_v2_cpas_start(core_info, &vote);
}

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/of.h>
@@ -79,10 +80,6 @@ int cam_ipe_init_hw(void *device_priv,
CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote.axi_vote.axi_path[0].mnoc_ib_bw =
CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote.axi_vote.axi_path[0].ddr_ab_bw =
CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote.axi_vote.axi_path[0].ddr_ib_bw =
CAM_CPAS_DEFAULT_AXI_BW;
rc = cam_cpas_start(core_info->cpas_handle,
&cpas_vote.ahb_vote, &cpas_vote.axi_vote);

View File

@@ -4640,38 +4640,9 @@ static void *cam_isp_ctx_user_dump_stream_info(
void *dump_struct, uint8_t *addr_ptr)
{
struct cam_context *ctx = NULL;
struct cam_ife_hw_mgr_ctx *hw_mgr_ctx = NULL;
struct cam_isp_hw_mgr_res *hw_mgr_res = NULL;
struct cam_isp_resource_node *hw_res = NULL;
int hw_idx[CAM_ISP_HW_SPLIT_MAX] = { -1, -1 };
int sfe_hw_idx[CAM_ISP_HW_SPLIT_MAX] = { -1, -1 };
int32_t *addr;
int i;
ctx = (struct cam_context *)dump_struct;
hw_mgr_ctx = (struct cam_ife_hw_mgr_ctx *)ctx->ctxt_to_hw_map;
if (!list_empty(&hw_mgr_ctx->res_list_ife_src)) {
hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_ife_src,
struct cam_isp_hw_mgr_res, list);
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
hw_res = hw_mgr_res->hw_res[i];
if (hw_res && hw_res->hw_intf)
hw_idx[i] = hw_res->hw_intf->hw_idx;
}
}
if (!list_empty(&hw_mgr_ctx->res_list_sfe_src)) {
hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_sfe_src,
struct cam_isp_hw_mgr_res, list);
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
hw_res = hw_mgr_res->hw_res[i];
if (hw_res && hw_res->hw_intf)
sfe_hw_idx[i] = hw_res->hw_intf->hw_idx;
}
}
addr = (int32_t *)addr_ptr;
@@ -4679,20 +4650,6 @@ static void *cam_isp_ctx_user_dump_stream_info(
*addr++ = ctx->dev_hdl;
*addr++ = ctx->link_hdl;
*addr++ = hw_mgr_ctx->flags.is_dual;
*addr++ = hw_mgr_ctx->ctx_type;
*addr++ = hw_idx[CAM_ISP_HW_SPLIT_LEFT];
*addr++ = hw_idx[CAM_ISP_HW_SPLIT_RIGHT];
*addr++ = sfe_hw_idx[CAM_ISP_HW_SPLIT_LEFT];
*addr++ = sfe_hw_idx[CAM_ISP_HW_SPLIT_RIGHT];
*addr++ = hw_mgr_ctx->flags.is_sfe_shdr;
*addr++ = hw_mgr_ctx->flags.is_sfe_fs;
*addr++ = hw_mgr_ctx->flags.dsp_enabled;
*addr++ = hw_mgr_ctx->flags.is_offline;
return addr;
}
@@ -4714,6 +4671,8 @@ static int __cam_isp_ctx_dump_in_top_state(
struct cam_ctx_request *req_temp;
struct cam_hw_dump_args ife_dump_args;
struct cam_common_hw_dump_args dump_args;
struct cam_hw_cmd_args hw_cmd_args;
struct cam_isp_hw_cmd_args isp_hw_cmd_args;
spin_lock_bh(&ctx->lock);
list_for_each_entry_safe(req, req_temp,
@@ -4789,14 +4748,33 @@ hw_dump:
/* Dump stream info */
ctx->ctxt_to_hw_map = ctx_isp->hw_ctx;
rc = cam_common_user_dump_helper(&dump_args, cam_isp_ctx_user_dump_stream_info,
ctx, sizeof(int32_t), "ISP_STREAM_INFO:");
if (rc) {
CAM_ERR(CAM_ISP, "Stream info dump fail %lld, rc: %d",
req->request_id, rc);
goto end;
if (ctx->hw_mgr_intf->hw_dump) {
/* Dump first part of stream info from isp context */
rc = cam_common_user_dump_helper(&dump_args,
cam_isp_ctx_user_dump_stream_info, ctx,
sizeof(int32_t), "ISP_STREAM_INFO_FROM_CTX:");
if (rc) {
CAM_ERR(CAM_ISP, "ISP CTX stream info dump fail %lld, rc: %d",
req->request_id, rc);
goto end;
}
/* Dump second part of stream info from ife hw manager */
hw_cmd_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_DUMP_STREAM_INFO;
isp_hw_cmd_args.cmd_data = &dump_args;
hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv, &hw_cmd_args);
if (rc) {
CAM_ERR(CAM_ISP, "IFE HW MGR stream info dump fail %lld, rc: %d",
req->request_id, rc);
goto end;
}
dump_info->offset = dump_args.offset;
}
dump_info->offset = dump_args.offset;
/* Dump event record */
rc = __cam_isp_ctx_dump_event_record(ctx_isp, &dump_args);

View File

@@ -24,7 +24,6 @@
#include "cam_cdm_intf_api.h"
#include "cam_packet_util.h"
#include "cam_debug_util.h"
#include "cam_cpas_api.h"
#include "cam_mem_mgr.h"
#include "cam_mem_mgr_api.h"
#include "cam_common_util.h"
@@ -66,6 +65,9 @@ static struct cam_ife_hw_mgr g_ife_hw_mgr;
static uint32_t g_num_ife, g_num_ife_lite, g_num_sfe;
static uint32_t max_ife_out_res, max_sfe_out_res;
static int cam_ife_mgr_find_core_idx(int split_id, struct cam_ife_hw_mgr_ctx *ctx,
enum cam_isp_hw_type hw_type, uint32_t *core_idx);
static int cam_isp_blob_ife_clock_update(
struct cam_isp_clock_config *clock_config,
struct cam_ife_hw_mgr_ctx *ctx);
@@ -86,6 +88,88 @@ static int cam_ife_mgr_prog_default_settings(
static int cam_ife_mgr_cmd_get_sof_timestamp(struct cam_ife_hw_mgr_ctx *ife_ctx,
uint64_t *time_stamp, uint64_t *boot_time_stamp, uint64_t *prev_time_stamp);
static int cam_ife_mgr_update_core_info_to_cpas(struct cam_ife_hw_mgr_ctx *ctx,
bool set_port)
{
struct cam_isp_hw_mgr_res *hw_mgr_res;
int i, sfe_core_idx, csid_core_idx, rc = 0;
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
if (!hw_mgr_res->hw_res[i])
continue;
rc = cam_ife_mgr_find_core_idx(i, ctx, CAM_ISP_HW_TYPE_CSID,
&csid_core_idx);
if (rc)
return rc;
rc = cam_ife_mgr_find_core_idx(i, ctx, CAM_ISP_HW_TYPE_SFE, &sfe_core_idx);
if (rc)
return rc;
rc = cam_cpas_csid_input_core_info_update(csid_core_idx, sfe_core_idx,
set_port);
if (rc) {
CAM_ERR(CAM_PERF, "Failed in updating core info to cpas rc: %d",
rc);
return rc;
}
}
}
return rc;
}
static int cam_isp_blob_drv_config(struct cam_ife_hw_mgr_ctx *ctx,
uint64_t request_id, struct cam_isp_prepare_hw_update_data *prepare_hw_data)
{
struct cam_ife_hw_mgr *ife_hw_mgr;
struct cam_hw_intf *hw_intf;
struct cam_isp_drv_config *drv_config;
struct cam_ife_csid_drv_config_args drv_config_args = {0};
int i, rc = 0;
ife_hw_mgr = ctx->hw_mgr;
drv_config = &prepare_hw_data->isp_drv_config;
CAM_DBG(CAM_PERF,
"DRV config blob opcode:%u req_id:%llu disable_drv_override:%s ctx_idx:%u drv_en:%u path_idle_en:0x%x timeout_val:%u",
prepare_hw_data->packet_opcode_type, request_id,
CAM_BOOL_TO_YESNO(g_ife_hw_mgr.debug_cfg.disable_isp_drv),
ctx->ctx_index, drv_config->drv_en, drv_config->path_idle_en,
drv_config->timeout_val);
if (!g_ife_hw_mgr.cam_ddr_drv_support || g_ife_hw_mgr.debug_cfg.disable_isp_drv)
return rc;
if (prepare_hw_data->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV)
drv_config_args.is_init_config = true;
drv_config_args.drv_en = drv_config->drv_en;
drv_config_args.path_idle_en = drv_config->path_idle_en;
drv_config_args.timeout_val = drv_config->timeout_val;
for (i = 0; i < ctx->num_base; i++) {
if (ctx->base[i].hw_type != CAM_ISP_HW_TYPE_CSID)
continue;
hw_intf = ife_hw_mgr->csid_devices[ctx->base[i].idx];
if (hw_intf && hw_intf->hw_ops.process_cmd) {
rc = hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
CAM_ISP_HW_CMD_DRV_CONFIG, &drv_config_args,
sizeof(struct cam_ife_csid_drv_config_args));
if (rc) {
CAM_ERR(CAM_PERF,
"DRV config failed req_id:%d i:%d hw_idx=%d rc:%d",
request_id, i, ctx->base[i].idx, rc);
break;
}
}
}
return rc;
}
static bool cam_isp_is_ctx_primary_rdi(struct cam_ife_hw_mgr_ctx *ctx)
{
/* check for RDI only and RDI PD context*/
@@ -1808,6 +1892,7 @@ static int cam_ife_mgr_process_base_info(
res->hw_intf->hw_idx);
}
}
CAM_DBG(CAM_ISP, "ctx base num = %d", ctx->num_base);
return 0;
@@ -5191,6 +5276,12 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
goto free_res;
}
if (ife_ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) {
rc = cam_ife_mgr_update_core_info_to_cpas(ife_ctx, true);
if (rc)
goto free_res;
}
rc = cam_ife_mgr_allocate_cdm_cmd(
(ife_ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE ? true : false),
&ife_ctx->cdm_cmd);
@@ -5527,6 +5618,12 @@ static int cam_ife_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
goto free_res;
}
if (ife_ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) {
rc = cam_ife_mgr_update_core_info_to_cpas(ife_ctx, true);
if (rc)
goto free_res;
}
rc = cam_ife_mgr_allocate_cdm_cmd(false,
&ife_ctx->cdm_cmd);
if (rc)
@@ -5647,8 +5744,9 @@ static void cam_ife_mgr_print_blob_info(struct cam_ife_hw_mgr_ctx *ctx, uint64_t
struct cam_isp_prepare_hw_update_data *hw_update_data)
{
int i;
struct cam_isp_bw_config_v2 *bw_config =
(struct cam_isp_bw_config_v2 *) &hw_update_data->bw_clk_config.bw_config_v2;
struct cam_isp_bw_config_internal_v2 *bw_config =
(struct cam_isp_bw_config_internal_v2 *)
&hw_update_data->bw_clk_config.bw_config_v2;
struct cam_isp_clock_config *ife_clock_config =
(struct cam_isp_clock_config *) &hw_update_data->bw_clk_config.ife_clock_config;
struct cam_isp_clock_config *sfe_clock_config =
@@ -5698,13 +5796,13 @@ end:
}
static int cam_isp_classify_vote_info(
struct cam_isp_hw_mgr_res *hw_mgr_res,
struct cam_isp_bw_config_v2 *bw_config,
struct cam_axi_vote *isp_vote,
uint32_t hw_type,
uint32_t split_idx,
bool *nrdi_l_bw_updated,
bool *nrdi_r_bw_updated)
struct cam_isp_hw_mgr_res *hw_mgr_res,
struct cam_isp_bw_config_internal_v2 *bw_config,
struct cam_axi_vote *isp_vote,
uint32_t hw_type,
uint32_t split_idx,
bool *nrdi_l_bw_updated,
bool *nrdi_r_bw_updated)
{
int rc = 0, i, j = 0;
@@ -5723,7 +5821,7 @@ static int cam_isp_classify_vote_info(
memcpy(&isp_vote->axi_path[j],
&bw_config->axi_path[i],
sizeof(struct
cam_axi_per_path_bw_vote));
cam_cpas_axi_per_path_bw_vote));
j++;
}
}
@@ -5740,7 +5838,7 @@ static int cam_isp_classify_vote_info(
memcpy(&isp_vote->axi_path[j],
&bw_config->axi_path[i],
sizeof(struct
cam_axi_per_path_bw_vote));
cam_cpas_axi_per_path_bw_vote));
j++;
}
}
@@ -5761,7 +5859,7 @@ static int cam_isp_classify_vote_info(
memcpy(&isp_vote->axi_path[j],
&bw_config->axi_path[i],
sizeof(struct
cam_axi_per_path_bw_vote));
cam_cpas_axi_per_path_bw_vote));
j++;
}
}
@@ -5787,7 +5885,7 @@ static int cam_isp_classify_vote_info(
memcpy(&isp_vote->axi_path[j],
&bw_config->axi_path[i],
sizeof(struct
cam_axi_per_path_bw_vote));
cam_cpas_axi_per_path_bw_vote));
j++;
}
}
@@ -5804,7 +5902,7 @@ static int cam_isp_classify_vote_info(
memcpy(&isp_vote->axi_path[j],
&bw_config->axi_path[i],
sizeof(struct
cam_axi_per_path_bw_vote));
cam_cpas_axi_per_path_bw_vote));
j++;
}
}
@@ -5825,7 +5923,7 @@ static int cam_isp_classify_vote_info(
memcpy(&isp_vote->axi_path[j],
&bw_config->axi_path[i],
sizeof(struct
cam_axi_per_path_bw_vote));
cam_cpas_axi_per_path_bw_vote));
j++;
}
}
@@ -5843,13 +5941,15 @@ static int cam_isp_classify_vote_info(
for (i = 0; i < isp_vote->num_paths; i++) {
CAM_DBG(CAM_PERF,
"CLASSIFY_VOTE [%s] [%s] [%s] [%llu] [%llu] [%llu]",
"CLASSIFY_VOTE [%s] [%s] [%s] [%s] [%llu] [%llu] [%llu]",
cam_isp_util_usage_data_to_string(
isp_vote->axi_path[i].usage_data),
cam_cpas_axi_util_path_type_to_string(
isp_vote->axi_path[i].path_data_type),
cam_cpas_axi_util_trans_type_to_string(
isp_vote->axi_path[i].transac_type),
cam_cpas_axi_util_drv_vote_lvl_to_string(
isp_vote->axi_path[i].vote_level),
isp_vote->axi_path[i].camnoc_bw,
isp_vote->axi_path[i].mnoc_ab_bw,
isp_vote->axi_path[i].mnoc_ib_bw);
@@ -5859,8 +5959,8 @@ static int cam_isp_classify_vote_info(
}
static int cam_isp_blob_bw_update_v2(
struct cam_isp_bw_config_v2 *bw_config,
struct cam_ife_hw_mgr_ctx *ctx)
struct cam_isp_bw_config_internal_v2 *bw_config,
struct cam_ife_hw_mgr_ctx *ctx)
{
struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_hw_intf *hw_intf;
@@ -5873,7 +5973,7 @@ static int cam_isp_blob_bw_update_v2(
for (i = 0; i < bw_config->num_paths; i++) {
CAM_DBG(CAM_PERF,
"ISP_BLOB usage_type=%u [%s] [%s] [%s] [%llu] [%llu] [%llu]",
"ISP_BLOB usage_type=%u [%s] [%s] [%s] [%s] [%llu] [%llu] [%llu]",
bw_config->usage_type,
cam_isp_util_usage_data_to_string(
bw_config->axi_path[i].usage_data),
@@ -5881,6 +5981,8 @@ static int cam_isp_blob_bw_update_v2(
bw_config->axi_path[i].path_data_type),
cam_cpas_axi_util_trans_type_to_string(
bw_config->axi_path[i].transac_type),
cam_cpas_axi_util_drv_vote_lvl_to_string(
bw_config->axi_path[i].vote_level),
bw_config->axi_path[i].camnoc_bw,
bw_config->axi_path[i].mnoc_ab_bw,
bw_config->axi_path[i].mnoc_ib_bw);
@@ -6167,6 +6269,14 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
hw_update_data->bw_clk_config.ife_clock_config_valid,
hw_update_data->bw_clk_config.sfe_clock_config_valid);
if (hw_update_data->drv_config_valid) {
rc = cam_isp_blob_drv_config(ctx, cfg->request_id, hw_update_data);
if (rc) {
CAM_ERR(CAM_ISP, "DRV config failed for req: %llu rc:%d", cfg->request_id,
rc);
}
}
/*
* Update clock and bw values to top layer, the actual application of these
* votes to hw will happen for all relevant hw indices at once, in a separate
@@ -6199,9 +6309,10 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
CAM_ERR(CAM_PERF, "Bandwidth Update Failed rc: %d", rc);
return rc;
}
} else if (ctx->bw_config_version == CAM_ISP_BW_CONFIG_V2) {
rc = cam_isp_blob_bw_update_v2((struct cam_isp_bw_config_v2 *)
&hw_update_data->bw_clk_config.bw_config_v2, ctx);
} else if ((ctx->bw_config_version == CAM_ISP_BW_CONFIG_V2) ||
(ctx->bw_config_version == CAM_ISP_BW_CONFIG_V3)) {
rc = cam_isp_blob_bw_update_v2(&hw_update_data->bw_clk_config.bw_config_v2,
ctx);
if (rc) {
CAM_ERR(CAM_PERF, "Bandwidth Update Failed rc: %d", rc);
return rc;
@@ -6779,29 +6890,27 @@ err:
return rc;
}
/* To find SFE core idx for CSID wrapper config */
static int cam_ife_mgr_find_sfe_core_idx(
static int cam_ife_mgr_find_core_idx(
int split_id,
struct cam_ife_hw_mgr_ctx *ctx,
enum cam_isp_hw_type hw_type,
uint32_t *core_idx)
{
int i;
for (i = 0; i < ctx->num_base; i++) {
if (ctx->base[i].hw_type != CAM_ISP_HW_TYPE_SFE)
if (ctx->base[i].hw_type != hw_type)
continue;
if (ctx->base[i].split_id == split_id) {
CAM_DBG(CAM_ISP, "Found SFE core: %u for split_id: %d",
ctx->base[i].idx, split_id);
CAM_DBG(CAM_ISP, "Found core: %u for split_id: %d hw_type: %d",
ctx->base[i].idx, split_id, hw_type);
*core_idx = ctx->base[i].idx;
goto end;
}
}
CAM_ERR(CAM_ISP,
"Failed to find SFE core idx for split_id %d",
split_id);
CAM_ERR(CAM_ISP, "Failed to find core idx for hw_type: %d split_id %d", hw_type, split_id);
return -EINVAL;
end:
@@ -6961,8 +7070,8 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
if (ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) {
csid_top_args.input_core_type =
CAM_IFE_CSID_INPUT_CORE_SFE_IFE;
rc = cam_ife_mgr_find_sfe_core_idx(
i, ctx, &csid_top_args.core_idx);
rc = cam_ife_mgr_find_core_idx(i, ctx, CAM_ISP_HW_TYPE_SFE,
&csid_top_args.core_idx);
if (rc)
goto tasklet_stop;
} else {
@@ -7034,6 +7143,12 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
goto safe_disable;
}
rc = cam_cpas_query_drv_enable(&g_ife_hw_mgr.cam_ddr_drv_support);
if (rc) {
CAM_ERR(CAM_ISP, "Failed to query DRV enable rc: %d", rc);
goto cdm_streamoff;
}
start_only:
atomic_set(&ctx->overflow_pending, 0);
@@ -7269,6 +7384,12 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
/* we should called the stop hw before this already */
cam_ife_hw_mgr_release_hw_for_ctx(ctx);
if (ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) {
rc = cam_ife_mgr_update_core_info_to_cpas(ctx, false);
if (rc)
CAM_ERR(CAM_ISP, "Failed to update core info to cpas rc:%d", rc);
}
/* reset base info */
ctx->num_base = 0;
memset(ctx->base, 0, sizeof(ctx->base));
@@ -9494,7 +9615,7 @@ static int cam_isp_validate_scratch_buffer_blob(
static int cam_isp_packet_generic_blob_handler(void *user_data,
uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
{
int rc = 0;
int rc = 0, i;
struct cam_isp_generic_blob_info *blob_info = user_data;
struct cam_ife_hw_mgr_ctx *ife_mgr_ctx = NULL;
struct cam_hw_prepare_update_args *prepare = NULL;
@@ -9677,9 +9798,9 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
}
break;
case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2: {
size_t bw_config_size = 0;
struct cam_isp_bw_config_v2 *bw_config;
struct cam_isp_prepare_hw_update_data *prepare_hw_data;
struct cam_cpas_axi_per_path_bw_vote *path_vote;
if (blob_size < sizeof(struct cam_isp_bw_config_v2)) {
CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
@@ -9729,21 +9850,99 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
return -EINVAL;
}
prepare_hw_data = (struct cam_isp_prepare_hw_update_data *)
prepare->priv;
prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) prepare->priv;
memset(&prepare_hw_data->bw_clk_config.bw_config_v2, 0,
sizeof(prepare_hw_data->bw_clk_config.bw_config_v2));
bw_config_size = sizeof(struct cam_isp_bw_config_v2) +
((bw_config->num_paths - 1) *
sizeof(struct cam_axi_per_path_bw_vote));
memcpy(&prepare_hw_data->bw_clk_config.bw_config_v2, bw_config,
bw_config_size);
prepare_hw_data->bw_clk_config.bw_config_v2.usage_type = bw_config->usage_type;
prepare_hw_data->bw_clk_config.bw_config_v2.num_paths = bw_config->num_paths;
for (i = 0; i < bw_config->num_paths; i++) {
path_vote = &prepare_hw_data->bw_clk_config.bw_config_v2.axi_path[i];
path_vote->usage_data = bw_config->axi_path[i].usage_data;
path_vote->transac_type = bw_config->axi_path[i].transac_type;
path_vote->path_data_type = bw_config->axi_path[i].path_data_type;
path_vote->vote_level = 0;
path_vote->camnoc_bw = bw_config->axi_path[i].camnoc_bw;
path_vote->mnoc_ab_bw = bw_config->axi_path[i].mnoc_ab_bw;
path_vote->mnoc_ib_bw = bw_config->axi_path[i].mnoc_ib_bw;
}
ife_mgr_ctx->bw_config_version = CAM_ISP_BW_CONFIG_V2;
prepare_hw_data->bw_clk_config.bw_config_valid = true;
}
break;
case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V3: {
struct cam_isp_bw_config_v3 *bw_config;
struct cam_isp_prepare_hw_update_data *prepare_hw_data;
struct cam_cpas_axi_per_path_bw_vote *path_vote;
if (blob_size < sizeof(struct cam_isp_bw_config_v3)) {
CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
return -EINVAL;
}
bw_config = (struct cam_isp_bw_config_v3 *)blob_data;
if (bw_config->num_paths > CAM_ISP_MAX_PER_PATH_VOTES || !bw_config->num_paths) {
CAM_ERR(CAM_ISP, "Invalid num paths %d", bw_config->num_paths);
return -EINVAL;
}
/* Check for integer overflow */
if (bw_config->num_paths > 1) {
if (sizeof(struct cam_axi_per_path_bw_vote_v2) > ((UINT_MAX -
sizeof(struct cam_isp_bw_config_v3)) /
(bw_config->num_paths - 1))) {
CAM_ERR(CAM_ISP,
"Size exceeds limit paths:%u size per path:%lu",
bw_config->num_paths - 1,
sizeof(struct cam_axi_per_path_bw_vote_v2));
return -EINVAL;
}
}
if ((bw_config->num_paths != 0) && (blob_size <
(sizeof(struct cam_isp_bw_config_v3) +
(bw_config->num_paths - 1) *
sizeof(struct cam_axi_per_path_bw_vote_v2)))) {
CAM_ERR(CAM_ISP,
"Invalid blob size: %u, num_paths: %u, bw_config size: %lu, per_path_vote size: %lu",
blob_size, bw_config->num_paths,
sizeof(struct cam_isp_bw_config_v3),
sizeof(struct cam_axi_per_path_bw_vote_v2));
return -EINVAL;
}
if (!prepare || !prepare->priv ||
(bw_config->usage_type >= CAM_ISP_HW_USAGE_TYPE_MAX)) {
CAM_ERR(CAM_ISP, "Invalid inputs usage type %d",
bw_config->usage_type);
return -EINVAL;
}
prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) prepare->priv;
memset(&prepare_hw_data->bw_clk_config.bw_config_v2, 0,
sizeof(prepare_hw_data->bw_clk_config.bw_config_v2));
prepare_hw_data->bw_clk_config.bw_config_v2.usage_type = bw_config->usage_type;
prepare_hw_data->bw_clk_config.bw_config_v2.num_paths = bw_config->num_paths;
for (i = 0; i < bw_config->num_paths; i++) {
path_vote = &prepare_hw_data->bw_clk_config.bw_config_v2.axi_path[i];
path_vote->usage_data = bw_config->axi_path[i].usage_data;
path_vote->transac_type = bw_config->axi_path[i].transac_type;
path_vote->path_data_type = bw_config->axi_path[i].path_data_type;
path_vote->vote_level = bw_config->axi_path[i].vote_level;
path_vote->camnoc_bw = bw_config->axi_path[i].camnoc_bw;
path_vote->mnoc_ab_bw = bw_config->axi_path[i].mnoc_ab_bw;
path_vote->mnoc_ib_bw = bw_config->axi_path[i].mnoc_ib_bw;
}
ife_mgr_ctx->bw_config_version = CAM_ISP_BW_CONFIG_V3;
prepare_hw_data->bw_clk_config.bw_config_valid = true;
}
break;
case CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG: {
struct cam_ubwc_config *ubwc_config;
@@ -10130,6 +10329,28 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
}
break;
case CAM_ISP_GENERIC_BLOB_TYPE_DRV_CONFIG: {
struct cam_isp_drv_config *drv_config;
struct cam_isp_prepare_hw_update_data *prepare_hw_data;
if (blob_size < sizeof(struct cam_isp_drv_config)) {
CAM_ERR(CAM_ISP, "Invalid DRV blob size %u expected %u",
blob_size, sizeof(struct cam_isp_drv_config));
return -EINVAL;
}
prepare_hw_data = (struct cam_isp_prepare_hw_update_data *)
prepare->priv;
drv_config = (struct cam_isp_drv_config *)blob_data;
memcpy(&prepare_hw_data->isp_drv_config, drv_config,
sizeof(prepare_hw_data->isp_drv_config));
CAM_DBG(CAM_ISP, "DRV config blob en:%d timeout_val:%u path_idle_en: 0x%x",
drv_config->drv_en, drv_config->timeout_val, drv_config->path_idle_en);
prepare_hw_data->drv_config_valid = true;
}
break;
default:
CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type);
break;
@@ -11977,6 +12198,59 @@ end:
return rc;
}
static void *cam_ife_mgr_user_dump_stream_info(
void *dump_struct, uint8_t *addr_ptr)
{
struct cam_ife_hw_mgr_ctx *hw_mgr_ctx = NULL;
struct cam_isp_hw_mgr_res *hw_mgr_res = NULL;
struct cam_isp_resource_node *hw_res = NULL;
int32_t *addr;
int i;
int hw_idx[CAM_ISP_HW_SPLIT_MAX] = { -1, -1 };
int sfe_hw_idx[CAM_ISP_HW_SPLIT_MAX] = { -1, -1 };
hw_mgr_ctx = (struct cam_ife_hw_mgr_ctx *)dump_struct;
if (!list_empty(&hw_mgr_ctx->res_list_ife_src)) {
hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_ife_src,
struct cam_isp_hw_mgr_res, list);
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
hw_res = hw_mgr_res->hw_res[i];
if (hw_res && hw_res->hw_intf)
hw_idx[i] = hw_res->hw_intf->hw_idx;
}
}
if (!list_empty(&hw_mgr_ctx->res_list_sfe_src)) {
hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_sfe_src,
struct cam_isp_hw_mgr_res, list);
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
hw_res = hw_mgr_res->hw_res[i];
if (hw_res && hw_res->hw_intf)
sfe_hw_idx[i] = hw_res->hw_intf->hw_idx;
}
}
addr = (int32_t *)addr_ptr;
*addr++ = hw_mgr_ctx->flags.is_dual;
*addr++ = hw_mgr_ctx->ctx_type;
*addr++ = hw_idx[CAM_ISP_HW_SPLIT_LEFT];
*addr++ = hw_idx[CAM_ISP_HW_SPLIT_RIGHT];
*addr++ = sfe_hw_idx[CAM_ISP_HW_SPLIT_LEFT];
*addr++ = sfe_hw_idx[CAM_ISP_HW_SPLIT_RIGHT];
*addr++ = hw_mgr_ctx->flags.is_sfe_shdr;
*addr++ = hw_mgr_ctx->flags.is_sfe_fs;
*addr++ = hw_mgr_ctx->flags.dsp_enabled;
*addr++ = hw_mgr_ctx->flags.is_offline;
return addr;
}
static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
{
int rc = 0;
@@ -12056,6 +12330,12 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
&isp_hw_cmd_args->u.sof_ts.boot,
&isp_hw_cmd_args->u.sof_ts.prev);
break;
case CAM_ISP_HW_MGR_DUMP_STREAM_INFO:
rc = cam_common_user_dump_helper(
(void *)(isp_hw_cmd_args->cmd_data),
cam_ife_mgr_user_dump_stream_info, ctx,
sizeof(int32_t), "ISP_STREAM_INFO_FROM_IFE_HW_MGR:");
break;
default:
CAM_ERR(CAM_ISP, "Invalid HW mgr command:0x%x",
hw_cmd_args->cmd_type);
@@ -14050,6 +14330,8 @@ static int cam_ife_hw_mgr_debug_register(void)
g_ife_hw_mgr.debug_cfg.dentry, NULL, &cam_ife_hw_mgr_perfcnter_debug);
debugfs_create_file("ife_csid_testbus", 0644,
g_ife_hw_mgr.debug_cfg.dentry, NULL, &cam_ife_csid_testbus_debug);
debugfs_create_bool("disable_isp_drv", 0644, g_ife_hw_mgr.debug_cfg.dentry,
&g_ife_hw_mgr.debug_cfg.disable_isp_drv);
end:
g_ife_hw_mgr.debug_cfg.enable_csid_recovery = 1;
return rc;

View File

@@ -14,6 +14,7 @@
#include "cam_ife_csid_hw_intf.h"
#include "cam_tasklet_util.h"
#include "cam_cdm_intf_api.h"
#include "cam_cpas_api.h"
/*
* enum cam_ife_ctx_master_type - HW master type
@@ -57,6 +58,7 @@ enum cam_ife_ctx_master_type {
* @disable_ubwc_comp: Disable UBWC compression
* @disable_ife_mmu_prefetch: Disable MMU prefetch for IFE bus WR
* @rx_capture_debug_set: If rx capture debug is set by user
* @disable_isp_drv: Disable ISP DRV config
*
*/
struct cam_ife_hw_mgr_debug {
@@ -77,6 +79,7 @@ struct cam_ife_hw_mgr_debug {
bool disable_ubwc_comp;
bool disable_ife_mmu_prefetch;
bool rx_capture_debug_set;
bool disable_isp_drv;
};
/**
@@ -419,6 +422,7 @@ struct cam_isp_sfe_cache_info {
* @csid_rup_en Reg update at CSID side
* @csid_global_reset_en CSID global reset enable
* @csid_camif_irq_support CSID camif IRQ support
* @cam_ddr_drv_support DDR DRV support
* @isp_caps Capability of underlying SFE/IFE HW
* @path_port_map Mapping of outport to IFE mux
* @num_caches_found Number of caches supported
@@ -448,6 +452,7 @@ struct cam_ife_hw_mgr {
bool csid_rup_en;
bool csid_global_reset_en;
bool csid_camif_irq_support;
bool cam_ddr_drv_support;
struct cam_isp_ife_sfe_hw_caps isp_caps;
struct cam_isp_hw_path_port_map path_port_map;

View File

@@ -2462,7 +2462,7 @@ static int cam_tfe_classify_vote_info(
memcpy(&isp_vote->axi_path[j],
&bw_config->axi_path[i],
sizeof(struct
cam_axi_per_path_bw_vote));
cam_cpas_axi_per_path_bw_vote));
j++;
}
}
@@ -2479,7 +2479,7 @@ static int cam_tfe_classify_vote_info(
memcpy(&isp_vote->axi_path[j],
&bw_config->axi_path[i],
sizeof(struct
cam_axi_per_path_bw_vote));
cam_cpas_axi_per_path_bw_vote));
j++;
}
}
@@ -2500,7 +2500,7 @@ static int cam_tfe_classify_vote_info(
memcpy(&isp_vote->axi_path[j],
&bw_config->axi_path[i],
sizeof(struct
cam_axi_per_path_bw_vote));
cam_cpas_axi_per_path_bw_vote));
j++;
}
}
@@ -3866,7 +3866,7 @@ static int cam_isp_tfe_blob_clock_update(
static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
{
int rc = 0;
int rc = 0, i;
struct cam_isp_generic_blob_info *blob_info = user_data;
struct cam_hw_prepare_update_args *prepare = NULL;
struct cam_tfe_hw_mgr_ctx *tfe_mgr_ctx = NULL;
@@ -3984,6 +3984,7 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
struct cam_isp_tfe_bw_config_v2 *bw_config =
(struct cam_isp_tfe_bw_config_v2 *)blob_data;
struct cam_isp_prepare_hw_update_data *prepare_hw_data;
struct cam_cpas_axi_per_path_bw_vote *path_vote;
if (blob_size < sizeof(struct cam_isp_tfe_bw_config_v2)) {
CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
@@ -4030,15 +4031,22 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
return -EINVAL;
}
prepare_hw_data = (struct cam_isp_prepare_hw_update_data *)
prepare->priv;
prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) prepare->priv;
memset(&prepare_hw_data->bw_clk_config.bw_config_v2,
0, sizeof(prepare_hw_data->bw_clk_config.bw_config_v2));
bw_config_size = sizeof(struct cam_isp_tfe_bw_config_v2) +
((bw_config->num_paths - 1) *
sizeof(struct cam_axi_per_path_bw_vote));
memcpy(&prepare_hw_data->bw_clk_config.bw_config_v2, bw_config, bw_config_size);
prepare_hw_data->bw_clk_config.bw_config_v2.usage_type = bw_config->usage_type;
prepare_hw_data->bw_clk_config.bw_config_v2.num_paths = bw_config->num_paths;
for (i = 0; i < bw_config->num_paths; i++) {
path_vote = &prepare_hw_data->bw_clk_config.bw_config_v2.axi_path[i];
path_vote.usage_data = bw_config->axi_path[i].usage_data;
path_vote.transac_type = bw_config->axi_path[i].transac_type;
path_vote.path_data_type = bw_config->axi_path[i].path_data_type;
path_vote.vote_level = 0;
path_vote.camnoc_bw = bw_config->axi_path[i].camnoc_bw;
path_vote.mnoc_ab_bw = bw_config->axi_path[i].mnoc_ab_bw;
path_vote.mnoc_ib_bw = bw_config->axi_path[i].mnoc_ib_bw;
}
tfe_mgr_ctx->bw_config_version = CAM_ISP_BW_CONFIG_V2;
prepare_hw_data->bw_clk_config.bw_config_valid = true;

View File

@@ -13,6 +13,7 @@
#include <media/cam_isp.h>
#include "cam_hw_mgr_intf.h"
#include "cam_packet_util.h"
#include "cam_cpas_api.h"
/* MAX IFE instance */
#define CAM_IFE_HW_NUM_MAX 8
@@ -22,6 +23,7 @@
#define CAM_SFE_FE_RDI_NUM_MAX 3
#define CAM_ISP_BW_CONFIG_V1 1
#define CAM_ISP_BW_CONFIG_V2 2
#define CAM_ISP_BW_CONFIG_V3 2
#define CAM_TFE_HW_NUM_MAX 3
#define CAM_TFE_RDI_NUM_MAX 3
#define CAM_IFE_SCRATCH_NUM_MAX 2
@@ -181,9 +183,9 @@ struct cam_isp_clock_config_internal {
* @axi_path per path vote info
*/
struct cam_isp_bw_config_internal_v2 {
uint32_t usage_type;
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_ISP_MAX_PER_PATH_VOTES];
uint32_t usage_type;
uint32_t num_paths;
struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_ISP_MAX_PER_PATH_VOTES];
};
/**
@@ -238,6 +240,8 @@ struct cam_isp_bw_clk_config_info {
* @frame_header_iova: Frame header iova
* @frame_header_res_id: Out port res_id corresponding to frame header
* @bw_clk_config: BW and clock config info
* @isp_drv_config: DRV config info
* @bw_config_valid: Flag indicating if DRV config is valid for current request
* @reg_dump_buf_desc: cmd buffer descriptors for reg dump
* @num_reg_dump_buf: Count of descriptors in reg_dump_buf_desc
* @packet: CSL packet from user mode driver
@@ -253,6 +257,8 @@ struct cam_isp_prepare_hw_update_data {
uint64_t frame_header_iova;
uint32_t frame_header_res_id;
struct cam_isp_bw_clk_config_info bw_clk_config;
struct cam_isp_drv_config isp_drv_config;
bool drv_config_valid;
struct cam_cmd_buf_desc reg_dump_buf_desc[
CAM_REG_DUMP_MAX_BUF_ENTRIES];
uint32_t num_reg_dump_buf;
@@ -365,6 +371,7 @@ enum cam_isp_hw_mgr_command {
CAM_ISP_HW_MGR_GET_LAST_CDM_DONE,
CAM_ISP_HW_MGR_CMD_PROG_DEFAULT_CFG,
CAM_ISP_HW_MGR_GET_SOF_TS,
CAM_ISP_HW_MGR_DUMP_STREAM_INFO,
CAM_ISP_HW_MGR_CMD_MAX,
};

View File

@@ -256,11 +256,10 @@ static const struct cam_ife_csid_top_irq_desc cam_ife_csid_780_top_irq_desc[] =
.bitmask = BIT(1),
.err_type = CAM_ISP_HW_ERROR_CSID_SENSOR_SWITCH_ERROR,
.err_name = "FATAL_SENSOR_SWITCHING_IRQ",
.desc = "Fatal Error duirng dynamically switching between 2 sensors",
.desc = "Fatal Error during dynamically switching between 2 sensors",
},
{
.bitmask = BIT(18),
.err_type = CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW,
.err_name = "ERROR_NO_VOTE_DN",
.desc = "vote_up is asserted before IDLE is encountered in a frame",
},
@@ -269,6 +268,7 @@ static const struct cam_ife_csid_top_irq_desc cam_ife_csid_780_top_irq_desc[] =
.err_type = CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW,
.err_name = "ERROR_VOTE_UP_LATE",
.desc = "vote_up is asserted at the same time as an SOF",
.err_handler = cam_ife_csid_hw_ver2_drv_err_handler,
},
{
.bitmask = BIT(20),
@@ -1241,6 +1241,11 @@ static struct cam_ife_csid_ver2_common_reg_info
.buf_done_irq_set_addr = 0x98,
.test_bus_ctrl = 0x1E8,
.test_bus_debug = 0x1EC,
.drv_cfg0_addr = 0x13c,
.drv_cfg1_addr = 0x140,
.drv_cfg2_addr = 0x144,
.debug_drv_0_addr = 0x148,
.debug_drv_1_addr = 0x14C,
/*configurations */
.major_version = 6,
@@ -1273,6 +1278,8 @@ static struct cam_ife_csid_ver2_common_reg_info
.shdr_slave_rdi1_shift = 21,
.shdr_master_rdi0_shift = 5,
.shdr_master_slave_en_shift = 0,
.drv_en_shift = 0,
.drv_rup_en_shift = 0,
.early_eof_supported = 1,
.vfr_supported = 1,
.multi_vcdt_supported = 1,
@@ -1287,7 +1294,7 @@ static struct cam_ife_csid_ver2_common_reg_info
.ipp_irq_mask_all = 0x7FFF,
.rdi_irq_mask_all = 0x7FFF,
.ppp_irq_mask_all = 0xFFFF,
.top_err_irq_mask = 0x1C0002,
.top_err_irq_mask = 0x180002,
.rst_loc_path_only_val = 0x0,
.rst_loc_complete_csid_val = 0x1,
.rst_mode_frame_boundary_val = 0x0,
@@ -1312,6 +1319,28 @@ static struct cam_ife_csid_ver2_common_reg_info
.timestamp_enabled_in_cfg0 = true,
.camif_irq_support = true,
.sfe_ipp_input_rdi_res = BIT(CAM_IFE_PIX_PATH_RES_RDI_0),
.drv_rup_en_val_map = {
2, //RDI0
3, //RDI1
4, //RDI2
5, //RDI3
6, //RDI4
0, //IPP
1, //PPP
0, //UDI0
0, //UDI1
0, //UDI2
},
.drv_path_idle_en_val_map = {
BIT(4), //CAM_ISP_PXL_PATH
BIT(5), //CAM_ISP_PPP_PATH
0, // LCR not applicable
BIT(6), //CAM_ISP_RDI0_PATH
BIT(7), //CAM_ISP_RDI1_PATH
BIT(8), //CAM_ISP_RDI2_PATH
BIT(9), //CAM_ISP_RDI3_PATH
BIT(10), //CAM_ISP_RDI4_PATH
},
};
static struct cam_ife_csid_ver2_top_reg_info

View File

@@ -264,11 +264,10 @@ static const struct cam_ife_csid_top_irq_desc cam_ife_csid_880_top_irq_desc[] =
.bitmask = BIT(1),
.err_type = CAM_ISP_HW_ERROR_CSID_SENSOR_SWITCH_ERROR,
.err_name = "FATAL_SENSOR_SWITCHING_IRQ",
.desc = "Fatal Error duirng dynamically switching between 2 sensors",
.desc = "Fatal Error during dynamically switching between 2 sensors",
},
{
.bitmask = BIT(18),
.err_type = CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW,
.err_name = "ERROR_NO_VOTE_DN",
.desc = "vote_up is asserted before IDLE is encountered in a frame",
},
@@ -277,6 +276,7 @@ static const struct cam_ife_csid_top_irq_desc cam_ife_csid_880_top_irq_desc[] =
.err_type = CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW,
.err_name = "ERROR_VOTE_UP_LATE",
.desc = "vote_up is asserted at the same time as an SOF",
.err_handler = cam_ife_csid_hw_ver2_drv_err_handler,
},
{
.bitmask = BIT(20),
@@ -1280,6 +1280,11 @@ static struct cam_ife_csid_ver2_common_reg_info
.test_bus_debug = 0x11EC,
.path_domain_id_cfg0 = 0x0,
.path_domain_id_cfg1 = 0x4,
.drv_cfg0_addr = 0x13c,
.drv_cfg1_addr = 0x140,
.drv_cfg2_addr = 0x144,
.debug_drv_0_addr = 0x148,
.debug_drv_1_addr = 0x14C,
/*configurations */
.major_version = 6,
@@ -1312,6 +1317,8 @@ static struct cam_ife_csid_ver2_common_reg_info
.shdr_slave_rdi1_shift = 21,
.shdr_master_rdi0_shift = 5,
.shdr_master_slave_en_shift = 0,
.drv_en_shift = 0,
.drv_rup_en_shift = 0,
.early_eof_supported = 1,
.vfr_supported = 1,
.multi_vcdt_supported = 1,
@@ -1326,7 +1333,7 @@ static struct cam_ife_csid_ver2_common_reg_info
.ipp_irq_mask_all = 0x7FFF,
.rdi_irq_mask_all = 0x7FFF,
.ppp_irq_mask_all = 0xFFFF,
.top_err_irq_mask = 0x1C0002,
.top_err_irq_mask = 0x180002,
.rst_loc_path_only_val = 0x0,
.rst_loc_complete_csid_val = 0x1,
.rst_mode_frame_boundary_val = 0x0,
@@ -1351,6 +1358,28 @@ static struct cam_ife_csid_ver2_common_reg_info
.timestamp_enabled_in_cfg0 = true,
.sfe_ipp_input_rdi_res = BIT(CAM_IFE_PIX_PATH_RES_RDI_0),
.camif_irq_support = true,
.drv_rup_en_val_map = {
2, //RDI0
3, //RDI1
4, //RDI2
5, //RDI3
6, //RDI4
0, //IPP
1, //PPP
0, //UDI0
0, //UDI1
0, //UDI2
},
.drv_path_idle_en_val_map = {
BIT(4), //CAM_ISP_PXL_PATH
BIT(5), //CAM_ISP_PPP_PATH
0, // LCR not applicable
BIT(6), //CAM_ISP_RDI0_PATH
BIT(7), //CAM_ISP_RDI1_PATH
BIT(8), //CAM_ISP_RDI2_PATH
BIT(9), //CAM_ISP_RDI3_PATH
BIT(10), //CAM_ISP_RDI4_PATH
},
};
static struct cam_ife_csid_ver2_top_reg_info

View File

@@ -61,6 +61,9 @@
#define CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO BIT(7)
#define CAM_IFE_CSID_DEBUG_DISABLE_EARLY_EOF BIT(8)
#define CAM_IFE_DEBUG_ENABLE_UNMAPPED_VC_DT_IRQ BIT(9)
#define CAM_IFE_CSID_DEBUG_ENABLE_VOTE_UP_IRQ BIT(10)
#define CAM_IFE_CSID_DEBUG_ENABLE_VOTE_DN_IRQ BIT(11)
#define CAM_IFE_CSID_DEBUG_ENABLE_ERR_NO_VOTE_DN_IRQ BIT(12)
/* Binning supported masks. Binning support changes for specific paths
* and also for targets. With the mask, we handle the supported features
@@ -300,6 +303,7 @@ struct cam_ife_csid_hw_counters {
* @rx_capture_vc: rx packet vc capture
* @rx_capture_dt: rx packet dt capture
* @rst_capture_strobes: rx packet capture rst strobes
* @top_mask: Debug mask for top irq
* @rx_mask: Debug mask for rx irq
* @path_mask: Debug mask for path irq
* @test_bus_val: CSID test bus value
@@ -311,6 +315,7 @@ struct cam_ife_csid_debug_info {
uint32_t rx_capture_vc;
uint32_t rx_capture_dt;
uint32_t rst_capture_strobes;
uint32_t top_mask;
uint32_t rx_mask;
uint32_t path_mask;
uint32_t test_bus_val;

View File

@@ -3756,6 +3756,10 @@ static int cam_ife_csid_ver1_process_cmd(void *hw_priv,
/* Not supported for V1 */
rc = 0;
break;
case CAM_ISP_HW_CMD_DRV_CONFIG:
/* Not supported for V1 */
rc = 0;
break;
default:
CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
csid_hw->hw_intf->hw_idx, cmd_type);

View File

@@ -179,6 +179,18 @@ static int cam_ife_csid_ver2_set_debug(
csid_hw->debug_info.rx_mask |=
IFE_CSID_VER2_RX_UNMAPPED_VC_DT;
break;
case CAM_IFE_CSID_DEBUG_ENABLE_VOTE_UP_IRQ:
csid_hw->debug_info.top_mask |=
IFE_CSID_VER2_TOP_INFO_VOTE_UP;
break;
case CAM_IFE_CSID_DEBUG_ENABLE_VOTE_DN_IRQ:
csid_hw->debug_info.top_mask |=
IFE_CSID_VER2_TOP_INFO_VOTE_DN;
break;
case CAM_IFE_CSID_DEBUG_ENABLE_ERR_NO_VOTE_DN_IRQ:
csid_hw->debug_info.top_mask |=
IFE_CSID_VER2_TOP_ERR_NO_VOTE_DN;
break;
default:
break;
}
@@ -305,6 +317,36 @@ static int cam_ife_csid_ver2_put_evt_payload(
return 0;
}
static int cam_ife_csid_ver2_top_info_irq_top_half(
uint32_t evt_id,
struct cam_irq_th_payload *th_payload)
{
int rc = 0;
struct cam_ife_csid_ver2_hw *csid_hw = NULL;
struct cam_ife_csid_ver2_evt_payload *evt_payload;
csid_hw = th_payload->handler_priv;
rc = cam_ife_csid_ver2_get_evt_payload(csid_hw, &evt_payload,
&csid_hw->path_free_payload_list,
&csid_hw->path_payload_lock);
if (rc) {
CAM_WARN_RATE_LIMIT(CAM_ISP, "CSID:%d get payload failed, TOP info status: 0x%x",
csid_hw->hw_intf->hw_idx,
th_payload->evt_status_arr[0]);
return rc;
}
CAM_DBG(CAM_ISP, "CSID:%d TOP info status: 0x%x", csid_hw->hw_intf->hw_idx,
th_payload->evt_status_arr[0]);
evt_payload->irq_reg_val = th_payload->evt_status_arr[0];
ktime_get_boottime_ts64(&evt_payload->timestamp);
th_payload->evt_payload_priv = evt_payload;
return 0;
}
static int cam_ife_csid_ver2_top_err_irq_top_half(
uint32_t evt_id,
struct cam_irq_th_payload *th_payload)
@@ -312,11 +354,8 @@ static int cam_ife_csid_ver2_top_err_irq_top_half(
int rc = 0;
struct cam_ife_csid_ver2_hw *csid_hw = NULL;
struct cam_ife_csid_ver2_evt_payload *evt_payload;
struct cam_ife_csid_ver2_reg_info *csid_reg = NULL;
csid_hw = th_payload->handler_priv;
csid_reg = (struct cam_ife_csid_ver2_reg_info *)
csid_hw->core_info->csid_reg;
rc = cam_ife_csid_ver2_get_evt_payload(csid_hw, &evt_payload,
&csid_hw->path_free_payload_list,
@@ -332,6 +371,7 @@ static int cam_ife_csid_ver2_top_err_irq_top_half(
}
evt_payload->irq_reg_val = th_payload->evt_status_arr[0];
ktime_get_boottime_ts64(&evt_payload->timestamp);
th_payload->evt_payload_priv = evt_payload;
return 0;
@@ -484,7 +524,7 @@ static int cam_ife_csid_ver2_path_top_half(
}
evt_payload->irq_reg_val = th_payload->evt_status_arr[0];
ktime_get_boottime_ts64(&evt_payload->timestamp);
th_payload->evt_payload_priv = evt_payload;
return 0;
@@ -1292,6 +1332,27 @@ void cam_ife_csid_hw_ver2_rdi_line_buffer_conflict_handler(
}
void cam_ife_csid_hw_ver2_drv_err_handler(void *csid)
{
struct cam_ife_csid_ver2_hw *csid_hw = csid;
struct cam_ife_csid_ver2_reg_info *csid_reg = csid_hw->core_info->csid_reg;
struct cam_hw_soc_info *soc_info = &csid_hw->hw_info->soc_info;
void __iomem *base =
soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base;
uint32_t cfg0_val = 0, cfg1_val = 0, cfg2_val = 0, debug_drv_0_val = 0, debug_drv_1_val = 0;
cfg0_val = cam_io_r_mb(base + csid_reg->cmn_reg->drv_cfg0_addr);
cfg1_val = cam_io_r_mb(base + csid_reg->cmn_reg->drv_cfg1_addr);
cfg2_val = cam_io_r_mb(base + csid_reg->cmn_reg->drv_cfg2_addr);
debug_drv_0_val = cam_io_r_mb(base + csid_reg->cmn_reg->debug_drv_0_addr);
debug_drv_1_val = cam_io_r_mb(base + csid_reg->cmn_reg->debug_drv_1_addr);
CAM_INFO(CAM_ISP,
"CSID[%d] DRV cfg0:0x%x cfg1:0x%x cfg2:0x%x qtimer_val [start:end] [0x%x : 0x%x]",
csid_hw->hw_intf->hw_idx, cfg0_val, cfg1_val, cfg2_val, debug_drv_0_val,
debug_drv_1_val);
}
void cam_ife_csid_hw_ver2_mup_mismatch_handler(
void *csid, void *resource)
{
@@ -1456,7 +1517,8 @@ static int cam_ife_csid_ver2_parse_path_irq_status(
struct cam_isp_resource_node *res,
uint32_t index,
uint32_t err_mask,
uint32_t irq_status)
uint32_t irq_status,
struct cam_ife_csid_ver2_evt_payload *evt_payload)
{
const uint8_t **irq_reg_tag;
const struct cam_ife_csid_ver2_reg_info *csid_reg;
@@ -1497,9 +1559,11 @@ static int cam_ife_csid_ver2_parse_path_irq_status(
bit_pos = 0;
while (status) {
if (status & 0x1)
CAM_INFO(CAM_ISP, "CSID[%d] IRQ %s %s ",
CAM_INFO(CAM_ISP, "CSID[%d] IRQ %s %s timestamp:[%lld:%lld]",
csid_hw->hw_intf->hw_idx, irq_reg_tag[index],
csid_reg->path_irq_desc[bit_pos].desc);
csid_reg->path_irq_desc[bit_pos].desc,
evt_payload->timestamp.tv_sec,
evt_payload->timestamp.tv_nsec);
bit_pos++;
status >>= 1;
@@ -1520,6 +1584,57 @@ static int cam_ife_csid_ver2_parse_path_irq_status(
return err_type;
}
static int cam_ife_csid_ver2_top_info_irq_bottom_half(
void *handler_priv,
void *evt_payload_priv)
{
struct cam_ife_csid_ver2_evt_payload *payload;
struct cam_ife_csid_ver2_hw *csid_hw = NULL;
uint32_t irq_status;
if (!handler_priv || !evt_payload_priv) {
CAM_ERR(CAM_ISP, "Invalid params");
return -EINVAL;
}
payload = evt_payload_priv;
csid_hw = handler_priv;
irq_status = payload->irq_reg_val & csid_hw->debug_info.top_mask;
if (!irq_status) {
CAM_ERR(CAM_ISP, "Unexpected Scenario");
return 0;
}
if (irq_status & IFE_CSID_VER2_TOP_INFO_VOTE_UP) {
cam_cpas_log_votes(true);
CAM_INFO(CAM_ISP, "CSID:%d INFO_VOTE_UP timestamp:[%lld:%lld]",
csid_hw->hw_intf->hw_idx, payload->timestamp.tv_sec,
payload->timestamp.tv_nsec);
}
if (irq_status & IFE_CSID_VER2_TOP_INFO_VOTE_DN) {
cam_cpas_log_votes(true);
CAM_INFO(CAM_ISP, "CSID:%d INFO_VOTE_DN timestamp:[%lld:%lld]",
csid_hw->hw_intf->hw_idx, payload->timestamp.tv_sec,
payload->timestamp.tv_nsec);
}
if (irq_status & IFE_CSID_VER2_TOP_ERR_NO_VOTE_DN) {
CAM_INFO(CAM_ISP, "CSID:%d ERR_NO_VOTE_DN timestamp:[%lld:%lld]",
csid_hw->hw_intf->hw_idx, payload->timestamp.tv_sec,
payload->timestamp.tv_nsec);
cam_ife_csid_hw_ver2_drv_err_handler(csid_hw);
}
cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload,
&csid_hw->path_free_payload_list,
&csid_hw->path_payload_lock);
return 0;
}
static int cam_ife_csid_ver2_top_err_irq_bottom_half(
void *handler_priv,
void *evt_payload_priv)
@@ -1555,8 +1670,10 @@ static int cam_ife_csid_ver2_top_err_irq_bottom_half(
CAM_ERR(CAM_ISP, "%s %s",
csid_reg->top_irq_desc[i].err_name,
csid_reg->top_irq_desc[i].desc);
if (csid_reg->top_irq_desc[i].err_handler)
csid_reg->top_irq_desc[i].err_handler(csid_hw);
event_type |= csid_reg->top_irq_desc[i].err_type;
}
}
@@ -1697,7 +1814,7 @@ static int cam_ife_csid_ver2_ipp_bottom_half(
err_type = cam_ife_csid_ver2_parse_path_irq_status(
csid_hw, res,
CAM_IFE_CSID_IRQ_REG_IPP,
err_mask, irq_status_ipp);
err_mask, irq_status_ipp, payload);
if (err_type)
cam_ife_csid_ver2_handle_event_err(csid_hw,
@@ -1778,9 +1895,10 @@ static int cam_ife_csid_ver2_ppp_bottom_half(
csid_hw->hw_intf->hw_idx);
goto unlock;
}
err_type = cam_ife_csid_ver2_parse_path_irq_status(
csid_hw, res, CAM_IFE_CSID_IRQ_REG_PPP,
err_mask, irq_status_ppp);
err_mask, irq_status_ppp, payload);
if (err_type)
cam_ife_csid_ver2_handle_event_err(csid_hw,
@@ -1873,7 +1991,7 @@ static int cam_ife_csid_ver2_rdi_bottom_half(
err_type = cam_ife_csid_ver2_parse_path_irq_status(csid_hw, res,
path_cfg->irq_reg_idx,
err_mask, irq_status_rdi);
err_mask, irq_status_rdi, payload);
spin_unlock(&csid_hw->lock_state);
if (err_type) {
@@ -4086,6 +4204,7 @@ static int cam_ife_csid_ver2_enable_hw(
const struct cam_ife_csid_ver2_path_reg_info *path_reg = NULL;
uint32_t top_err_irq_mask = 0;
uint32_t buf_done_irq_mask = 0;
uint32_t top_info_irq_mask = 0;
if (csid_hw->flags.device_enabled) {
CAM_DBG(CAM_ISP, "CSID[%d] hw has already been enabled",
@@ -4172,6 +4291,27 @@ static int cam_ife_csid_ver2_enable_hw(
goto unsubscribe_top_err;
}
if (csid_hw->debug_info.top_mask) {
top_info_irq_mask = csid_hw->debug_info.top_mask;
csid_hw->top_info_irq_handle = cam_irq_controller_subscribe_irq(
csid_hw->top_irq_controller,
CAM_IRQ_PRIORITY_1,
&top_info_irq_mask,
csid_hw,
cam_ife_csid_ver2_top_info_irq_top_half,
cam_ife_csid_ver2_top_info_irq_bottom_half,
csid_hw->tasklet,
&tasklet_bh_api,
CAM_IRQ_EVT_GROUP_0);
if (csid_hw->top_info_irq_handle < 1) {
CAM_ERR(CAM_ISP, "CSID[%d] Subscribe Top Info Irq fail",
csid_hw->hw_intf->hw_idx);
return -EINVAL;
goto unsubscribe_top_err;
}
}
csid_hw->flags.device_enabled = true;
csid_hw->flags.fatal_err_detected = false;
CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
@@ -4415,6 +4555,15 @@ int cam_ife_csid_ver2_start(void *hw_priv, void *args,
csid_hw->flags.sof_irq_triggered = false;
csid_hw->counters.irq_debug_cnt = 0;
if (start_args->is_internal_start) {
rc = cam_cpas_csid_process_resume(csid_hw->hw_intf->hw_idx);
if (rc) {
CAM_ERR(CAM_ISP, "CSID:%u Failed to process resume rc: %d",
csid_hw->hw_intf->hw_idx, rc);
goto end;
}
}
rc = cam_ife_csid_ver2_enable_hw(csid_hw);
for (i = 0; i < start_args->num_res; i++) {
@@ -4572,6 +4721,12 @@ int cam_ife_csid_ver2_stop(void *hw_priv,
csid_hw->top_err_irq_handle = 0;
}
if (csid_hw->debug_info.top_mask) {
cam_irq_controller_unsubscribe_irq(csid_hw->top_irq_controller,
csid_hw->top_info_irq_handle);
csid_hw->top_info_irq_handle = 0;
}
cam_ife_csid_ver2_disable_csi2(csid_hw);
if (csid_hw->debug_info.test_bus_enabled)
cam_ife_csid_ver2_testbus_config(csid_hw, 0x0);
@@ -4690,7 +4845,6 @@ static int cam_ife_csid_ver2_top_cfg(
hw_idx, top_args->input_core_type, top_args->core_idx);
/*config dual sync params */
if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_NONE)
return rc;
else if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_MASTER)
@@ -5378,6 +5532,71 @@ static int cam_ife_csid_init_config_update(
return 0;
}
static int cam_ife_csid_ver2_drv_config(
struct cam_ife_csid_ver2_hw *csid_hw, void *cmd_args)
{
struct cam_hw_soc_info *soc_info;
struct cam_ife_csid_ver2_reg_info *csid_reg;
struct cam_ife_csid_drv_config_args *drv_config;
uint32_t cfg0_val = 0, cfg1_val = 0;
void __iomem *mem_base;
int i;
if (!csid_hw || !cmd_args) {
CAM_ERR(CAM_ISP, "Invalid params");
return -EINVAL;
}
drv_config = (struct cam_ife_csid_drv_config_args *) cmd_args;
soc_info = &csid_hw->hw_info->soc_info;
csid_reg = (struct cam_ife_csid_ver2_reg_info *) csid_hw->core_info->csid_reg;
mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base;
cfg0_val = drv_config->drv_en << csid_reg->cmn_reg->drv_en_shift;
/* Configure DRV RUP EN for init request, one time */
if (drv_config->is_init_config) {
if (csid_hw->path_res[CAM_IFE_PIX_PATH_RES_IPP].res_state >=
CAM_ISP_RESOURCE_STATE_RESERVED) {
cfg1_val = csid_reg->cmn_reg->drv_rup_en_val_map[CAM_IFE_PIX_PATH_RES_IPP];
} else if (csid_hw->path_res[CAM_IFE_PIX_PATH_RES_RDI_0].res_state >=
CAM_ISP_RESOURCE_STATE_RESERVED) {
cfg1_val =
csid_reg->cmn_reg->drv_rup_en_val_map[CAM_IFE_PIX_PATH_RES_RDI_0];
} else if (csid_hw->path_res[CAM_IFE_PIX_PATH_RES_PPP].res_state >=
CAM_ISP_RESOURCE_STATE_RESERVED) {
cfg1_val = csid_reg->cmn_reg->drv_rup_en_val_map[CAM_IFE_PIX_PATH_RES_PPP];
} else {
CAM_ERR(CAM_ISP, "Failed to configure rup_en for drv");
return -EINVAL;
}
cam_io_w_mb(cfg1_val, mem_base + csid_reg->cmn_reg->drv_cfg1_addr);
csid_hw->drv_init_done = true;
}
if (!csid_hw->drv_init_done) {
CAM_ERR(CAM_ISP, "Failed to update drv config, init config not done");
return -EINVAL;
}
for (i = 0; i < CAM_ISP_MAX_PATHS; i++)
cfg0_val |= ((drv_config->path_idle_en & BIT(i)) ?
csid_reg->cmn_reg->drv_path_idle_en_val_map[i] : 0);
cam_io_w_mb(cfg0_val, mem_base + csid_reg->cmn_reg->drv_cfg0_addr);
cam_io_w_mb(drv_config->timeout_val, mem_base + csid_reg->cmn_reg->drv_cfg2_addr);
CAM_DBG(CAM_ISP,
"CSID[%u] sfe_en:%s DRV config init_req:%s cfg0_val:0x%x cfg1_val:0x%x cfg2_val:0x%x",
csid_hw->hw_intf->hw_idx, CAM_BOOL_TO_YESNO(csid_hw->flags.sfe_en),
CAM_BOOL_TO_YESNO(drv_config->is_init_config), cfg0_val, cfg1_val,
drv_config->timeout_val);
return 0;
}
static int cam_ife_csid_ver2_process_cmd(void *hw_priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
@@ -5468,6 +5687,9 @@ static int cam_ife_csid_ver2_process_cmd(void *hw_priv,
case CAM_ISP_HW_CMD_INIT_CONFIG_UPDATE:
rc = cam_ife_csid_init_config_update(cmd_args, arg_size);
break;
case CAM_ISP_HW_CMD_DRV_CONFIG:
rc = cam_ife_csid_ver2_drv_config(csid_hw, cmd_args);
break;
default:
CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
csid_hw->hw_intf->hw_idx, cmd_type);

View File

@@ -12,6 +12,10 @@
#include "cam_ife_csid_soc.h"
#include "cam_ife_csid_common.h"
#define IFE_CSID_VER2_TOP_INFO_VOTE_UP BIT(16)
#define IFE_CSID_VER2_TOP_INFO_VOTE_DN BIT(17)
#define IFE_CSID_VER2_TOP_ERR_NO_VOTE_DN BIT(18)
#define IFE_CSID_VER2_RX_DL0_EOT_CAPTURED BIT(0)
#define IFE_CSID_VER2_RX_DL1_EOT_CAPTURED BIT(1)
#define IFE_CSID_VER2_RX_DL2_EOT_CAPTURED BIT(2)
@@ -114,6 +118,18 @@ struct cam_ife_csid_ver2_top_cfg {
struct cam_ife_csid_ver2_evt_payload {
struct list_head list;
uint32_t irq_reg_val;
struct timespec64 timestamp;
};
/*
* struct cam_ife_csid_ver2_camif_data: place holder for camif parameters
*
* @epoch0_cfg: Epoch 0 configuration value
* @epoch1_cfg: Epoch 1 configuration value
*/
struct cam_ife_csid_ver2_camif_data {
uint32_t epoch0;
uint32_t epoch1;
};
/*
@@ -379,6 +395,11 @@ struct cam_ife_csid_ver2_common_reg_info {
uint32_t test_bus_debug;
uint32_t path_domain_id_cfg0;
uint32_t path_domain_id_cfg1;
uint32_t drv_cfg0_addr;
uint32_t drv_cfg1_addr;
uint32_t drv_cfg2_addr;
uint32_t debug_drv_0_addr;
uint32_t debug_drv_1_addr;
/*Shift Bit Configurations*/
uint32_t rst_done_shift_val;
@@ -437,6 +458,8 @@ struct cam_ife_csid_ver2_common_reg_info {
uint32_t shdr_slave_rdi1_shift;
uint32_t shdr_master_rdi0_shift;
uint32_t shdr_master_slave_en_shift;
uint32_t drv_en_shift;
uint32_t drv_rup_en_shift;
/* config Values */
uint32_t major_version;
uint32_t minor_version;
@@ -466,6 +489,8 @@ struct cam_ife_csid_ver2_common_reg_info {
uint32_t sfe_ipp_input_rdi_res;
bool timestamp_enabled_in_cfg0;
bool camif_irq_support;
uint32_t drv_rup_en_val_map[CAM_IFE_PIX_PATH_RES_MAX];
uint32_t drv_path_idle_en_val_map[CAM_ISP_MAX_PATHS];
/* Masks */
uint32_t pxl_cnt_mask;
@@ -551,9 +576,12 @@ struct cam_ife_csid_ver2_reg_info {
* @tasklet: Tasklet for irq events
* @reset_irq_handle: Reset irq handle
* @buf_done_irq_handle: Buf done irq handle
* @top_err_irq_handle: Top Err IRQ handle
* @top_info_irq_handle: Top Info IRQ handle
* @sync_mode: Master/Slave modes
* @mup: MUP for incoming VC of next frame
* @discard_frame_per_path: Count of paths dropping initial frames
* @drv_init_done: Indicates if drv init config is done
*
*/
struct cam_ife_csid_ver2_hw {
@@ -593,9 +621,11 @@ struct cam_ife_csid_ver2_hw {
int reset_irq_handle;
int buf_done_irq_handle;
int top_err_irq_handle;
int top_info_irq_handle;
enum cam_isp_hw_sync_mode sync_mode;
uint32_t mup;
atomic_t discard_frame_per_path;
bool drv_init_done;
};
/*
@@ -638,5 +668,7 @@ void cam_ife_csid_ver2_print_illegal_programming_irq_status(void *csid_hw, void
void cam_ife_csid_ver2_print_format_measure_info(void *csid_hw, void *res);
void cam_ife_csid_hw_ver2_mup_mismatch_handler(void *csid_hw, void *res);
void cam_ife_csid_hw_ver2_rdi_line_buffer_conflict_handler(void *csid_hw);
void cam_ife_csid_hw_ver2_drv_err_handler(void *csid);
#endif

View File

@@ -14,6 +14,7 @@
#define CAM_IFE_CSID_HW_NUM_MAX 8
#define CAM_IFE_CSID_UDI_MAX 3
#define RT_BASE_IDX 2
#define CAM_ISP_MAX_PATHS 8
/**
* enum cam_ife_csid_input_core_type - Specify the csid input core
@@ -480,4 +481,19 @@ struct cam_ife_csid_debug_cfg_args {
bool rx_capture_debug_set;
};
/*
* struct cam_ife_csid_drv_config_args:
*
* @is_init_config: Indicator for init config
* @drv_en: Indicator for camera DRV enable
* @timeout_val: Timeout value from SOF to trigger up vote, given in number of GC cycles
* @path_idle_en: Mask for paths to be considered for consolidated IDLE
*/
struct cam_ife_csid_drv_config_args {
bool is_init_config;
bool drv_en;
uint32_t timeout_val;
uint32_t path_idle_en;
};
#endif /* _CAM_CSID_HW_INTF_H_ */

View File

@@ -216,6 +216,7 @@ enum cam_isp_hw_cmd_type {
CAM_ISP_HW_BUS_MINI_DUMP,
CAM_ISP_HW_USER_DUMP,
CAM_ISP_HW_CMD_RDI_LCR_CFG,
CAM_ISP_HW_CMD_DRV_CONFIG,
CAM_ISP_HW_CMD_MAX,
};

View File

@@ -114,6 +114,7 @@ static int cam_sfe_top_set_axi_bw_vote(
int rc = 0;
struct cam_hw_soc_info *soc_info = NULL;
struct cam_sfe_soc_private *soc_private = NULL;
int i, j;
soc_info = top_priv->common_data.soc_info;
soc_private = (struct cam_sfe_soc_private *)soc_info->soc_private;
@@ -131,6 +132,38 @@ static int cam_sfe_top_set_axi_bw_vote(
top_priv->total_bw_applied = total_bw_new_vote;
} else {
CAM_ERR(CAM_PERF, "BW request failed, rc=%d", rc);
for (i = 0; i < final_bw_vote->num_paths; i++) {
CAM_INFO(CAM_PERF,
"sfe[%d] : Applied BW Vote : [%s][%s][%s] [%llu %llu %llu]",
top_priv->common_data.hw_intf->hw_idx,
cam_cpas_axi_util_path_type_to_string(
final_bw_vote->axi_path[i].path_data_type),
cam_cpas_axi_util_trans_type_to_string(
final_bw_vote->axi_path[i].transac_type),
cam_cpas_axi_util_drv_vote_lvl_to_string(
final_bw_vote->axi_path[i].vote_level),
final_bw_vote->axi_path[i].camnoc_bw,
final_bw_vote->axi_path[i].mnoc_ab_bw,
final_bw_vote->axi_path[i].mnoc_ib_bw);
}
for (i = 0; i < CAM_DELAY_CLK_BW_REDUCTION_NUM_REQ; i++) {
for (j = 0; j < top_priv->last_bw_vote[i].num_paths; j++) {
CAM_INFO(CAM_PERF,
"sfe[%d] : History[%d] BW Vote : [%s][%s] [%s] [%llu %llu %llu]",
top_priv->common_data.hw_intf->hw_idx, i,
cam_cpas_axi_util_path_type_to_string(
top_priv->last_bw_vote[i].axi_path[j].path_data_type),
cam_cpas_axi_util_trans_type_to_string(
top_priv->last_bw_vote[i].axi_path[j].transac_type),
cam_cpas_axi_util_drv_vote_lvl_to_string(
top_priv->last_bw_vote[i].axi_path[j].vote_level),
top_priv->last_bw_vote[i].axi_path[j].camnoc_bw,
top_priv->last_bw_vote[i].axi_path[j].mnoc_ab_bw,
top_priv->last_bw_vote[i].axi_path[j].mnoc_ib_bw);
}
}
}
return rc;
@@ -390,7 +423,7 @@ int cam_sfe_top_calc_axi_bw_vote(struct cam_sfe_top_priv *top_priv,
&top_priv->req_axi_vote[i].axi_path[0],
top_priv->req_axi_vote[i].num_paths *
sizeof(
struct cam_axi_per_path_bw_vote));
struct cam_cpas_axi_per_path_bw_vote));
num_paths += top_priv->req_axi_vote[i].num_paths;
}
}
@@ -399,13 +432,15 @@ int cam_sfe_top_calc_axi_bw_vote(struct cam_sfe_top_priv *top_priv,
for (i = 0; i < top_priv->agg_incoming_vote.num_paths; i++) {
CAM_DBG(CAM_PERF,
"sfe[%d] : New BW Vote : counter[%d] [%s][%s] [%llu %llu %llu]",
"sfe[%d] : New BW Vote : counter[%d] [%s][%s][%s] [%llu %llu %llu]",
top_priv->common_data.hw_intf->hw_idx,
top_priv->last_bw_counter,
cam_cpas_axi_util_path_type_to_string(
top_priv->agg_incoming_vote.axi_path[i].path_data_type),
cam_cpas_axi_util_trans_type_to_string(
top_priv->agg_incoming_vote.axi_path[i].transac_type),
cam_cpas_axi_util_drv_vote_lvl_to_string(
top_priv->agg_incoming_vote.axi_path[i].vote_level),
top_priv->agg_incoming_vote.axi_path[i].camnoc_bw,
top_priv->agg_incoming_vote.axi_path[i].mnoc_ab_bw,
top_priv->agg_incoming_vote.axi_path[i].mnoc_ib_bw);
@@ -463,12 +498,14 @@ int cam_sfe_top_calc_axi_bw_vote(struct cam_sfe_top_priv *top_priv,
for (i = 0; i < final_bw_vote->num_paths; i++) {
CAM_DBG(CAM_PERF,
"sfe[%d] : Apply BW Vote : [%s][%s] [%llu %llu %llu]",
"sfe[%d] : Apply BW Vote : [%s][%s][%s] [%llu %llu %llu]",
top_priv->common_data.hw_intf->hw_idx,
cam_cpas_axi_util_path_type_to_string(
final_bw_vote->axi_path[i].path_data_type),
cam_cpas_axi_util_trans_type_to_string(
final_bw_vote->axi_path[i].transac_type),
cam_cpas_axi_util_drv_vote_lvl_to_string(
final_bw_vote->axi_path[i].vote_level),
final_bw_vote->axi_path[i].camnoc_bw,
final_bw_vote->axi_path[i].mnoc_ab_bw,
final_bw_vote->axi_path[i].mnoc_ib_bw);
@@ -846,7 +883,7 @@ static int cam_sfe_top_handle_overflow(
cam_sfe_top_print_debug_reg_info(top_priv);
if (bus_overflow_status) {
cam_cpas_log_votes();
cam_cpas_log_votes(false);
overflow_info->is_bus_overflow = true;
}
@@ -912,6 +949,8 @@ static int cam_sfe_top_apply_clk_bw_update(struct cam_sfe_top_priv *top_priv,
if ((!to_be_applied_axi_vote) && (top_priv->bw_state != CAM_CLK_BW_STATE_UNCHANGED)) {
CAM_ERR(CAM_PERF, "SFE:%d Invalid BW vote for state:%s", hw_intf->hw_idx,
cam_sfe_top_clk_bw_state_to_string(top_priv->bw_state));
rc = -EINVAL;
goto end;
}
CAM_DBG(CAM_PERF, "SFE:%d APPLY CLK/BW req_id:%ld clk_state:%s bw_state:%s ",

View File

@@ -1057,7 +1057,7 @@ static int cam_tfe_top_set_axi_bw_vote(
&top_priv->req_axi_vote[i].axi_path[0],
top_priv->req_axi_vote[i].num_paths *
sizeof(
struct cam_axi_per_path_bw_vote));
struct cam_cpas_axi_per_path_bw_vote));
num_paths += top_priv->req_axi_vote[i].num_paths;
}
}

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
@@ -186,6 +187,7 @@ int cam_vfe_init_soc_resources(struct cam_hw_soc_info *soc_info,
cpas_register_param.dev = soc_info->dev;
cpas_register_param.cam_cpas_client_cb = cam_vfe_cpas_cb;
cpas_register_param.userdata = soc_info;
rc = cam_cpas_register_client(&cpas_register_param);
if (rc) {
CAM_ERR(CAM_ISP, "CPAS registration failed rc=%d", rc);
@@ -252,18 +254,16 @@ int cam_vfe_enable_soc_resources(struct cam_hw_soc_info *soc_info)
rc = -EINVAL;
goto end;
}
soc_private = soc_info->soc_private;
soc_private = soc_info->soc_private;
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_LOWSVS_VOTE;
axi_vote.num_paths = 1;
if (strnstr(soc_info->compatible, "lite",
strlen(soc_info->compatible))) {
axi_vote.axi_path[0].path_data_type =
CAM_AXI_PATH_DATA_IFE_RDI1;
if (soc_private->is_ife_lite) {
axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_IFE_RDI1;
} else {
axi_vote.axi_path[0].path_data_type =
CAM_AXI_PATH_DATA_IFE_VID;
axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_IFE_VID;
axi_vote.axi_path[0].vote_level = CAM_CPAS_VOTE_LEVEL_LOW;
}
axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_WRITE;

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
@@ -183,6 +184,7 @@ static struct cam_vfe_camif_lite_ver3_reg_data vfe480_camif_rdi_reg_data[3] = {
.error_irq_mask2 = 0x20000,
.subscribe_irq_mask1 = 0x30,
.enable_diagnostic_hw = 0x1,
.top_debug_cfg_en = 1,
},
{
.extern_reg_update_shift = 0,
@@ -196,6 +198,7 @@ static struct cam_vfe_camif_lite_ver3_reg_data vfe480_camif_rdi_reg_data[3] = {
.error_irq_mask2 = 0x40000,
.subscribe_irq_mask1 = 0x300,
.enable_diagnostic_hw = 0x1,
.top_debug_cfg_en = 1,
},
{
.extern_reg_update_shift = 0,
@@ -209,6 +212,7 @@ static struct cam_vfe_camif_lite_ver3_reg_data vfe480_camif_rdi_reg_data[3] = {
.error_irq_mask2 = 0x80000,
.subscribe_irq_mask1 = 0x3000,
.enable_diagnostic_hw = 0x1,
.top_debug_cfg_en = 1,
},
};

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
@@ -571,7 +572,7 @@ static int cam_vfe_camif_lite_handle_irq_bottom_half(
ret = CAM_VFE_IRQ_STATUS_OVERFLOW;
cam_cpas_log_votes();
cam_cpas_log_votes(false);
}

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
@@ -325,9 +326,9 @@ skip_core_cfg:
memset(err_irq_mask, 0, sizeof(err_irq_mask));
memset(irq_mask, 0, sizeof(irq_mask));
/* config debug status registers */
cam_io_w_mb(rsrc_data->reg_data->top_debug_cfg_en, rsrc_data->mem_base +
rsrc_data->common_reg->top_debug_cfg);
val = cam_io_r(rsrc_data->mem_base + rsrc_data->common_reg->top_debug_cfg);
val |= rsrc_data->reg_data->top_debug_cfg_en;
cam_io_w_mb(val, rsrc_data->mem_base + rsrc_data->common_reg->top_debug_cfg);
if (!camif_lite_res->is_rdi_primary_res)
goto subscribe_err;
@@ -887,7 +888,7 @@ static void cam_vfe_camif_lite_print_status(uint32_t *status,
if (status_0 & 0x40000000) {
CAM_INFO(CAM_ISP, "PD PIPE OVERFLOW");
cam_cpas_log_votes();
cam_cpas_log_votes(false);
}
}
@@ -1019,7 +1020,7 @@ print_state:
if ((err_type == CAM_VFE_IRQ_STATUS_OVERFLOW) &&
bus_overflow_status)
cam_cpas_log_votes();
cam_cpas_log_votes(false);
}

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
@@ -903,7 +904,7 @@ static int cam_vfe_camif_handle_irq_bottom_half(void *handler_priv,
CAM_INFO(CAM_ISP, "ife_clk_src:%lld",
soc_private->ife_clk_src);
cam_cpas_log_votes();
cam_cpas_log_votes(false);
if (camif_priv->camif_debug & CAMIF_DEBUG_ENABLE_REG_DUMP)
cam_vfe_camif_reg_dump(camif_node->res_priv);
@@ -931,7 +932,7 @@ static int cam_vfe_camif_handle_irq_bottom_half(void *handler_priv,
CAM_INFO(CAM_ISP, "ife_clk_src:%lld",
soc_private->ife_clk_src);
cam_cpas_log_votes();
cam_cpas_log_votes(false);
if (camif_priv->camif_debug & CAMIF_DEBUG_ENABLE_REG_DUMP)
cam_vfe_camif_reg_dump(camif_node->res_priv);

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
@@ -400,8 +401,9 @@ static int cam_vfe_camif_ver3_resource_start(
}
/* config debug status registers */
cam_io_w_mb(rsrc_data->reg_data->top_debug_cfg_en, rsrc_data->mem_base +
rsrc_data->common_reg->top_debug_cfg);
val = cam_io_r(rsrc_data->mem_base + rsrc_data->common_reg->top_debug_cfg);
val |= rsrc_data->reg_data->top_debug_cfg_en;
cam_io_w_mb(val, rsrc_data->mem_base + rsrc_data->common_reg->top_debug_cfg);
val = cam_io_r_mb(rsrc_data->mem_base +
rsrc_data->common_reg->core_cfg_0);
@@ -1281,7 +1283,7 @@ print_state:
if ((err_type == CAM_VFE_IRQ_STATUS_OVERFLOW) &&
((camif_priv->cam_common_cfg.input_mux_sel_pp & 0x3) ||
(bus_overflow_status)))
cam_cpas_log_votes();
cam_cpas_log_votes(false);
}
static int cam_vfe_camif_ver3_handle_irq_top_half(uint32_t evt_id,

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
@@ -572,7 +573,7 @@ static int cam_vfe_rdi_handle_irq_bottom_half(void *handler_priv,
rdi_priv->event_cb(rdi_priv->priv,
CAM_ISP_HW_EVENT_ERROR,
(void *)&evt_info);
cam_cpas_log_votes();
cam_cpas_log_votes(false);
}
end:
cam_vfe_rdi_put_evt_payload(rdi_priv, &payload);

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "cam_vfe_top_common.h"
@@ -48,12 +49,14 @@ static int cam_vfe_top_set_axi_bw_vote(struct cam_vfe_top_priv_common *top_commo
final_bw_vote->num_paths, rc);
for (i = 0; i < final_bw_vote->num_paths; i++) {
CAM_INFO(CAM_PERF,
"ife[%d] : Applied BW Vote : [%s][%s] [%llu %llu %llu]",
"ife[%d] : Applied BW Vote : [%s][%s][%s] [%llu %llu %llu]",
top_common->hw_idx,
cam_cpas_axi_util_path_type_to_string(
final_bw_vote->axi_path[i].path_data_type),
cam_cpas_axi_util_trans_type_to_string(
final_bw_vote->axi_path[i].transac_type),
cam_cpas_axi_util_drv_vote_lvl_to_string(
final_bw_vote->axi_path[i].vote_level),
final_bw_vote->axi_path[i].camnoc_bw,
final_bw_vote->axi_path[i].mnoc_ab_bw,
final_bw_vote->axi_path[i].mnoc_ib_bw);
@@ -62,12 +65,14 @@ static int cam_vfe_top_set_axi_bw_vote(struct cam_vfe_top_priv_common *top_commo
for (i = 0; i < CAM_DELAY_CLK_BW_REDUCTION_NUM_REQ; i++) {
for (j = 0; j < top_common->last_bw_vote[i].num_paths; j++) {
CAM_INFO(CAM_PERF,
"ife[%d] : History[%d] BW Vote : [%s][%s] [%llu %llu %llu]",
"ife[%d] : History[%d] BW Vote : [%s][%s] [%s] [%llu %llu %llu]",
top_common->hw_idx, i,
cam_cpas_axi_util_path_type_to_string(
top_common->last_bw_vote[i].axi_path[j].path_data_type),
cam_cpas_axi_util_trans_type_to_string(
top_common->last_bw_vote[i].axi_path[j].transac_type),
cam_cpas_axi_util_drv_vote_lvl_to_string(
top_common->last_bw_vote[i].axi_path[j].vote_level),
top_common->last_bw_vote[i].axi_path[j].camnoc_bw,
top_common->last_bw_vote[i].axi_path[j].mnoc_ab_bw,
top_common->last_bw_vote[i].axi_path[j].mnoc_ib_bw);
@@ -284,7 +289,7 @@ static int cam_vfe_top_calc_axi_bw_vote(
&top_common->req_axi_vote[i].axi_path[0],
top_common->req_axi_vote[i].num_paths *
sizeof(
struct cam_axi_per_path_bw_vote));
struct cam_cpas_axi_per_path_bw_vote));
num_paths += top_common->req_axi_vote[i].num_paths;
}
}
@@ -293,13 +298,15 @@ static int cam_vfe_top_calc_axi_bw_vote(
for (i = 0; i < top_common->agg_incoming_vote.num_paths; i++) {
CAM_DBG(CAM_PERF,
"ife[%d] : New BW Vote : counter[%d] [%s][%s] [%llu %llu %llu]",
"ife[%d] : New BW Vote : counter[%d] [%s][%s][%s] [%llu %llu %llu]",
top_common->hw_idx,
top_common->last_bw_counter,
cam_cpas_axi_util_path_type_to_string(
top_common->agg_incoming_vote.axi_path[i].path_data_type),
cam_cpas_axi_util_trans_type_to_string(
top_common->agg_incoming_vote.axi_path[i].transac_type),
cam_cpas_axi_util_drv_vote_lvl_to_string(
top_common->agg_incoming_vote.axi_path[i].vote_level),
top_common->agg_incoming_vote.axi_path[i].camnoc_bw,
top_common->agg_incoming_vote.axi_path[i].mnoc_ab_bw,
top_common->agg_incoming_vote.axi_path[i].mnoc_ib_bw);
@@ -359,12 +366,14 @@ static int cam_vfe_top_calc_axi_bw_vote(
for (i = 0; i < final_bw_vote->num_paths; i++) {
CAM_DBG(CAM_PERF,
"ife[%d] : Apply BW Vote : [%s][%s] [%llu %llu %llu]",
"ife[%d] : Apply BW Vote : [%s][%s][%s] [%llu %llu %llu]",
top_common->hw_idx,
cam_cpas_axi_util_path_type_to_string(
final_bw_vote->axi_path[i].path_data_type),
cam_cpas_axi_util_trans_type_to_string(
final_bw_vote->axi_path[i].transac_type),
cam_cpas_axi_util_drv_vote_lvl_to_string(
final_bw_vote->axi_path[i].vote_level),
final_bw_vote->axi_path[i].camnoc_bw,
final_bw_vote->axi_path[i].mnoc_ab_bw,
final_bw_vote->axi_path[i].mnoc_ib_bw);
@@ -493,11 +502,6 @@ int cam_vfe_top_bw_update(struct cam_vfe_soc_private *soc_private,
bw_update->external_bw_bytes;
mux_axi_vote->axi_path[0].mnoc_ib_bw =
bw_update->external_bw_bytes;
/* Make ddr bw same as mnoc bw */
mux_axi_vote->axi_path[0].ddr_ab_bw =
bw_update->external_bw_bytes;
mux_axi_vote->axi_path[0].ddr_ib_bw =
bw_update->external_bw_bytes;
top_common->axi_vote_control[i] =
CAM_ISP_BW_CONTROL_INCLUDE;

View File

@@ -560,7 +560,7 @@ static int cam_vfe_top_ver4_print_overflow_debug_info(
cam_vfe_top_ver4_dump_timestamps(top_priv, res_id);
cam_cpas_dump_camnoc_buff_fill_info(soc_private->cpas_handle);
if (bus_overflow_status)
cam_cpas_log_votes();
cam_cpas_log_votes(false);
if (violation_status)
CAM_INFO(CAM_ISP, "VFE[%d] Bus violation status: 0x%x",

View File

@@ -778,7 +778,7 @@ static int32_t cam_ope_process_request_timer(void *priv, void *data)
memset(&ctx_data->clk_info.axi_path[0], 0,
CAM_OPE_MAX_PER_PATH_VOTES *
sizeof(struct cam_axi_per_path_bw_vote));
sizeof(struct cam_cpas_axi_per_path_bw_vote));
ctx_data->clk_info.curr_fc = 0;
ctx_data->clk_info.base_clk = 0;
@@ -786,7 +786,7 @@ static int32_t cam_ope_process_request_timer(void *priv, void *data)
memcpy(&clk_update.axi_vote.axi_path[0],
&clk_info->axi_path[0],
clk_update.axi_vote.num_paths *
sizeof(struct cam_axi_per_path_bw_vote));
sizeof(struct cam_cpas_axi_per_path_bw_vote));
if (device_share_ratio > 1) {
for (i = 0; i < clk_update.axi_vote.num_paths; i++) {
@@ -1463,7 +1463,7 @@ static bool cam_ope_update_bw_v2(struct cam_ope_hw_mgr *hw_mgr,
memcpy(&ctx_data->clk_info.axi_path[0],
&clk_info->axi_path[0],
clk_info->num_paths * sizeof(struct cam_axi_per_path_bw_vote));
clk_info->num_paths * sizeof(struct cam_cpas_axi_per_path_bw_vote));
/*
* Add new vote of this context in hw mgr.
@@ -1568,7 +1568,7 @@ static int cam_ope_update_cpas_vote(struct cam_ope_hw_mgr *hw_mgr,
memcpy(&bw_update.axi_vote.axi_path[0],
&clk_info->axi_path[0],
bw_update.axi_vote.num_paths *
sizeof(struct cam_axi_per_path_bw_vote));
sizeof(struct cam_cpas_axi_per_path_bw_vote));
bw_update.axi_vote_valid = true;
for (i = 0; i < ope_hw_mgr->num_ope; i++) {
@@ -3068,7 +3068,7 @@ static int cam_ope_packet_generic_blob_handler(void *user_data,
struct cam_ope_ctx *ctx_data;
uint32_t index;
size_t clk_update_size;
int rc = 0;
int rc = 0, i;
if (!blob_data || (blob_size == 0)) {
CAM_ERR(CAM_OPE, "Invalid blob info %pK %d", blob_data,
@@ -3122,8 +3122,22 @@ static int cam_ope_packet_generic_blob_handler(void *user_data,
clk_info = &ctx_data->req_list[index]->clk_info;
clk_info_v2 = &ctx_data->req_list[index]->clk_info_v2;
clk_info_v2->budget_ns = soc_req_v2->budget_ns;
clk_info_v2->frame_cycles = soc_req_v2->frame_cycles;
clk_info_v2->rt_flag = soc_req_v2->rt_flag;
clk_info_v2->num_paths = soc_req_v2->num_paths;
memcpy(clk_info_v2, soc_req_v2, clk_update_size);
for (i = 0; i < soc_req_v2->num_paths; i++) {
clk_info_v2->axi_path[i].usage_data = soc_req_v2->axi_path[i].usage_data;
clk_info_v2->axi_path[i].transac_type =
soc_req_v2->axi_path[i].transac_type;
clk_info_v2->axi_path[i].path_data_type =
soc_req_v2->axi_path[i].path_data_type;
clk_info_v2->axi_path[i].vote_level = 0;
clk_info_v2->axi_path[i].camnoc_bw = soc_req_v2->axi_path[i].camnoc_bw;
clk_info_v2->axi_path[i].mnoc_ab_bw = soc_req_v2->axi_path[i].mnoc_ab_bw;
clk_info_v2->axi_path[i].mnoc_ib_bw = soc_req_v2->axi_path[i].mnoc_ib_bw;
}
/* Use v1 structure for clk fields */
clk_info->budget_ns = clk_info_v2->budget_ns;

View File

@@ -79,7 +79,7 @@ struct cam_ope_clk_bw_req_internal_v2 {
uint32_t rt_flag;
uint32_t reserved;
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
};
/**
@@ -119,7 +119,7 @@ struct cam_ctx_clk_info {
uint64_t compressed_bw;
int32_t clk_rate[CAM_MAX_VOTE];
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
};
/**
@@ -156,7 +156,7 @@ struct cam_ope_clk_info {
uint64_t uncompressed_bw;
uint64_t compressed_bw;
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
uint32_t hw_type;
struct cam_req_mgr_timer *watch_dog;
uint32_t watch_dog_reset_counter;

View File

@@ -54,10 +54,10 @@ free_power_settings:
static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
{
int rc = 0;
struct cam_hw_soc_info *soc_info =
&a_ctrl->soc_info;
struct cam_actuator_soc_private *soc_private;
struct cam_sensor_power_ctrl_t *power_info;
struct cam_hw_soc_info *soc_info = &a_ctrl->soc_info;
struct cam_actuator_soc_private *soc_private;
struct cam_sensor_power_ctrl_t *power_info;
struct completion *i3c_probe_completion = NULL;
soc_private =
(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
@@ -99,7 +99,10 @@ static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
power_info->dev = soc_info->dev;
rc = cam_sensor_core_power_up(power_info, soc_info);
if (a_ctrl->io_master_info.master_type == I3C_MASTER)
i3c_probe_completion = cam_actuator_get_i3c_completion(a_ctrl->soc_info.index);
rc = cam_sensor_core_power_up(power_info, soc_info, i3c_probe_completion);
if (rc) {
CAM_ERR(CAM_ACTUATOR,
"failed in actuator power up rc %d", rc);

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_ACTUATOR_CORE_H_
@@ -63,4 +64,6 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, void *arg);
*/
void cam_actuator_shutdown(struct cam_actuator_ctrl_t *a_ctrl);
struct completion *cam_actuator_get_i3c_completion(uint32_t index);
#endif /* _CAM_ACTUATOR_CORE_H_ */

View File

@@ -10,6 +10,17 @@
#include "cam_actuator_core.h"
#include "cam_trace.h"
#include "camera_main.h"
#include "cam_compat.h"
static struct cam_i3c_actuator_data {
struct cam_actuator_ctrl_t *a_ctrl;
struct completion probe_complete;
} g_i3c_actuator_data[MAX_CAMERAS];
struct completion *cam_actuator_get_i3c_completion(uint32_t index)
{
return &g_i3c_actuator_data[index].probe_complete;
}
static int cam_actuator_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
@@ -411,6 +422,9 @@ static int cam_actuator_platform_component_bind(struct device *dev,
CAM_DBG(CAM_ACTUATOR, "Component bound successfully %d",
a_ctrl->soc_info.index);
g_i3c_actuator_data[a_ctrl->soc_info.index].a_ctrl = a_ctrl;
init_completion(&g_i3c_actuator_data[a_ctrl->soc_info.index].probe_complete);
return rc;
free_mem:
@@ -525,6 +539,120 @@ struct i2c_driver cam_actuator_i2c_driver = {
},
};
static struct i3c_device_id actuator_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
static int cam_actuator_i3c_driver_probe(struct i3c_device *client)
{
int32_t rc = 0;
struct cam_actuator_ctrl_t *a_ctrl = NULL;
uint32_t index;
struct device *dev;
if (!client) {
CAM_INFO(CAM_ACTUATOR, "Null Client pointer");
return -EINVAL;
}
dev = &client->dev;
CAM_DBG(CAM_ACTUATOR, "Probe for I3C Slave %s", dev_name(dev));
rc = of_property_read_u32(dev->of_node, "cell-index", &index);
if (rc) {
CAM_ERR(CAM_ACTUATOR, "device %s failed to read cell-index", dev_name(dev));
return rc;
}
if (index >= MAX_CAMERAS) {
CAM_ERR(CAM_ACTUATOR, "Invalid Cell-Index: %u for %s", index, dev_name(dev));
return -EINVAL;
}
a_ctrl = g_i3c_actuator_data[index].a_ctrl;
if (!a_ctrl) {
CAM_ERR(CAM_ACTUATOR,
"a_ctrl is null. I3C Probe before platfom driver probe for %s",
dev_name(dev));
return -EINVAL;
}
a_ctrl->io_master_info.i3c_client = client;
complete_all(&g_i3c_actuator_data[index].probe_complete);
CAM_DBG(CAM_ACTUATOR, "I3C Probe Finished for %s", dev_name(dev));
return rc;
}
static struct i3c_driver cam_actuator_i3c_driver = {
.id_table = actuator_i3c_id,
.probe = cam_actuator_i3c_driver_probe,
.remove = cam_i3c_driver_remove,
.driver = {
.owner = THIS_MODULE,
.name = ACTUATOR_DRIVER_I3C,
.of_match_table = cam_actuator_driver_dt_match,
.suppress_bind_attrs = true,
},
};
static int cam_actuator_fill_i3c_device_id(void)
{
struct device_node *dev;
int num_entries;
int i = 0;
uint8_t ent_num = 0;
uint32_t mid;
uint32_t pid;
int rc;
dev = of_find_node_by_path(I3C_SENSOR_DEV_ID_DT_PATH);
if (!dev) {
CAM_WARN(CAM_ACTUATOR, "Couldnt Find the i3c-id-table dev node");
return 0;
}
num_entries = of_property_count_u32_elems(dev, "i3c-actuator-id-table");
if (num_entries <= 0) {
CAM_WARN(CAM_ACTUATOR, "Failed while reading the property. num_entries:%d",
num_entries);
return 0;
}
while (i < num_entries) {
if (ent_num >= MAX_I3C_DEVICE_ID_ENTRIES) {
CAM_WARN(CAM_ACTUATOR,
"Num_entries are more than MAX_I3C_DEVICE_ID_ENTRIES");
return -ENOMEM;
}
rc = of_property_read_u32_index(dev, "i3c-actuator-id-table", i, &mid);
if (rc) {
CAM_ERR(CAM_ACTUATOR, "Failed in reading the MID. rc: %d", rc);
return rc;
}
i++;
rc = of_property_read_u32_index(dev, "i3c-actuator-id-table", i, &pid);
if (rc) {
CAM_ERR(CAM_ACTUATOR, "Failed in reading the PID. rc: %d", rc);
return rc;
}
i++;
CAM_DBG(CAM_ACTUATOR, "PID: 0x%x, MID: 0x%x", pid, mid);
actuator_i3c_id[ent_num].manuf_id = mid;
actuator_i3c_id[ent_num].match_flags = I3C_MATCH_MANUF_AND_PART;
actuator_i3c_id[ent_num].part_id = pid;
actuator_i3c_id[ent_num].data = 0;
ent_num++;
}
return 0;
}
int cam_actuator_driver_init(void)
{
int32_t rc = 0;
@@ -535,9 +663,30 @@ int cam_actuator_driver_init(void)
"platform_driver_register failed rc = %d", rc);
return rc;
}
rc = i2c_add_driver(&cam_actuator_i2c_driver);
if (rc)
if (rc) {
CAM_ERR(CAM_ACTUATOR, "i2c_add_driver failed rc = %d", rc);
goto i2c_register_err;
}
memset(actuator_i3c_id, 0, sizeof(struct i3c_device_id) * (MAX_I3C_DEVICE_ID_ENTRIES + 1));
rc = cam_actuator_fill_i3c_device_id();
if (rc)
goto i3c_register_err;
rc = i3c_driver_register_with_owner(&cam_actuator_i3c_driver, THIS_MODULE);
if (rc) {
CAM_ERR(CAM_ACTUATOR, "i3c_driver registration failed, rc: %d", rc);
goto i3c_register_err;
}
return 0;
i3c_register_err:
i2c_del_driver(&cam_actuator_i2c_driver);
i2c_register_err:
platform_driver_unregister(&cam_actuator_platform_driver);
return rc;
}
@@ -546,6 +695,7 @@ void cam_actuator_driver_exit(void)
{
platform_driver_unregister(&cam_actuator_platform_driver);
i2c_del_driver(&cam_actuator_i2c_driver);
i3c_driver_unregister(&cam_actuator_i3c_driver);
}
MODULE_DESCRIPTION("cam_actuator_driver");

View File

@@ -31,8 +31,10 @@
#define NUM_MASTERS 2
#define NUM_QUEUES 2
#define ACTUATOR_DRIVER_I2C "cam-i2c-actuator"
#define CAMX_ACTUATOR_DEV_NAME "cam-actuator-driver"
#define ACTUATOR_DRIVER_I2C "cam-i2c-actuator"
#define CAMX_ACTUATOR_DEV_NAME "cam-actuator-driver"
#define ACTUATOR_DRIVER_I3C "i3c_camera_actuator"
#define MSM_ACTUATOR_MAX_VREGS (10)
#define ACTUATOR_MAX_POLL_COUNT 10

View File

@@ -1027,8 +1027,8 @@ static inline void __cam_csiphy_compute_cdr_value(
*cdr_val -= csiphy_device->cdr_params.cdr_tolerance;
}
static int cam_csiphy_cphy_data_rate_config(
struct csiphy_device *csiphy_device, int32_t idx)
static int cam_csiphy_cphy_data_rate_config(struct csiphy_device *csiphy_device, int32_t idx,
uint8_t datarate_variant_idx)
{
int i;
unsigned int data_rate_idx;
@@ -1080,7 +1080,20 @@ static int cam_csiphy_cphy_data_rate_config(
CAM_DBG(CAM_CSIPHY, "table[%d] BW : %llu Selected",
data_rate_idx, supported_phy_bw);
config_params = drate_settings[data_rate_idx].data_rate_reg_array;
if (datarate_variant_idx >= CAM_CSIPHY_MAX_DATARATE_VARIANTS) {
CAM_ERR(CAM_CSIPHY, "Datarate variant Idx: %u can not exceed %u",
datarate_variant_idx, CAM_CSIPHY_MAX_DATARATE_VARIANTS-1);
return -EINVAL;
}
config_params =
drate_settings[data_rate_idx].data_rate_reg_array[datarate_variant_idx];
if (!config_params) {
CAM_ERR(CAM_CSIPHY, "Datarate settings are null. datarate variant idx: %u",
datarate_variant_idx);
return -EINVAL;
}
for (i = 0; i < num_reg_entries; i++) {
reg_addr = config_params[i].reg_addr;
@@ -1200,7 +1213,7 @@ static int __cam_csiphy_prgm_bist_reg(struct csiphy_device *csiphy_dev, bool is_
}
int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev,
int32_t dev_handle)
int32_t dev_handle, uint8_t datarate_variant_idx)
{
int32_t rc = 0;
uint32_t lane_enable = 0;
@@ -1302,7 +1315,7 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev,
if (csiphy_dev->csiphy_info[index].csiphy_3phase) {
rc = cam_csiphy_cphy_data_rate_config(csiphy_dev, index);
rc = cam_csiphy_cphy_data_rate_config(csiphy_dev, index, datarate_variant_idx);
if (rc) {
CAM_ERR(CAM_CSIPHY,
"Date rate specific configuration failed rc: %d",
@@ -2298,6 +2311,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
struct cam_start_stop_dev_cmd config;
int32_t offset;
int clk_vote_level = -1;
uint8_t data_rate_variant_idx = 0;
CAM_DBG(CAM_CSIPHY, "START_DEV Called");
rc = copy_from_user(&config, (void __user *)cmd->handle,
@@ -2363,7 +2377,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
if (csiphy_dev->csiphy_info[offset].csiphy_3phase) {
rc = cam_csiphy_cphy_data_rate_config(
csiphy_dev, offset);
csiphy_dev, offset, data_rate_variant_idx);
if (rc) {
CAM_ERR(CAM_CSIPHY,
"Data rate specific configuration failed rc: %d",
@@ -2446,7 +2460,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
CAM_CSIPHY_PRGM_INDVDL);
}
rc = cam_csiphy_config_dev(csiphy_dev, config.dev_handle);
rc = cam_csiphy_config_dev(csiphy_dev, config.dev_handle, data_rate_variant_idx);
if (rc < 0) {
CAM_ERR(CAM_CSIPHY, "cam_csiphy_config_dev failed");
cam_csiphy_disable_hw(csiphy_dev);

View File

@@ -56,9 +56,10 @@
#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_DPHY_LANES 4
#define CAM_CSIPHY_MAX_CPHY_LANES 3
#define CAM_CSIPHY_MAX_CPHY_DPHY_COMBO_LN 3
#define CAM_CSIPHY_MAX_DATARATE_VARIANTS 3
#define DPHY_LANE_0 BIT(0)
#define CPHY_LANE_0 BIT(1)
@@ -187,14 +188,14 @@ struct csiphy_device;
/*
* struct data_rate_reg_info_t
* @bandwidth : max bandwidth supported by this reg settings
* @data_rate_reg_array_size: number of reg value pairs in the array
* @csiphy_data_rate_regs : array of data rate specific reg value pairs
* @bandwidth : max bandwidth supported by this reg settings
* @data_rate_reg_array_size : data rate settings size
* @data_rate_reg_array : array of data rate specific reg value pairs
*/
struct data_rate_reg_info_t {
uint64_t bandwidth;
ssize_t data_rate_reg_array_size;
struct csiphy_reg_t *data_rate_reg_array;
struct csiphy_reg_t *data_rate_reg_array[CAM_CSIPHY_MAX_DATARATE_VARIANTS];
};
/**

View File

@@ -735,78 +735,78 @@ struct csiphy_reg_t datarate_210_5Gsps[] = {
{0x108C, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
};
struct data_rate_reg_info_t data_rate_settings_2_1_0[] = {
static struct data_rate_reg_info_t data_rate_settings_2_1_0[] = {
{
/* ((1.2 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 2736000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_1p2Gsps),
.data_rate_reg_array = datarate_210_1p2Gsps
.data_rate_reg_array[0] = datarate_210_1p2Gsps
},
{
/* ((1.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 3420000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_1p5Gsps),
.data_rate_reg_array = datarate_210_1p5Gsps,
.data_rate_reg_array[0] = datarate_210_1p5Gsps,
},
{
/* ((1.7 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 3876000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_1p7Gsps),
.data_rate_reg_array = datarate_210_1p7Gsps,
.data_rate_reg_array[0] = datarate_210_1p7Gsps,
},
{
/* ((2.1 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 4788000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_2p1Gsps),
.data_rate_reg_array = datarate_210_2p1Gsps,
.data_rate_reg_array[0] = datarate_210_2p1Gsps,
},
{
/* ((2.35 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5358000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_2p35Gsps),
.data_rate_reg_array = datarate_210_2p35Gsps,
.data_rate_reg_array[0] = datarate_210_2p35Gsps,
},
{
/* ((2.6 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5928000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_2p6Gsps),
.data_rate_reg_array = datarate_210_2p6Gsps,
.data_rate_reg_array[0] = datarate_210_2p6Gsps,
},
{
/* ((2.8 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 6384000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_2p8Gsps),
.data_rate_reg_array = datarate_210_2p8Gsps,
.data_rate_reg_array[0] = datarate_210_2p8Gsps,
},
{
/* ((3.3 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 7524000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_3p3Gsps),
.data_rate_reg_array = datarate_210_3p3Gsps,
.data_rate_reg_array[0] = datarate_210_3p3Gsps,
},
{
/* ((3.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 7980000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_3p5Gsps),
.data_rate_reg_array = datarate_210_3p5Gsps,
.data_rate_reg_array[0] = datarate_210_3p5Gsps,
},
{
/* ((4 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 9120000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_4Gsps),
.data_rate_reg_array = datarate_210_4Gsps,
.data_rate_reg_array[0] = datarate_210_4Gsps,
},
{
/* ((4.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 10260000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_4p5Gsps),
.data_rate_reg_array = datarate_210_4p5Gsps,
.data_rate_reg_array[0] = datarate_210_4p5Gsps,
},
{
/* ((5.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 11400000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_5Gsps),
.data_rate_reg_array = datarate_210_5Gsps,
.data_rate_reg_array[0] = datarate_210_5Gsps,
},
};

View File

@@ -724,78 +724,78 @@ struct csiphy_reg_t datarate_211_5Gsps[] = {
{0x108C, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
};
struct data_rate_reg_info_t data_rate_settings_2_1_1[] = {
static struct data_rate_reg_info_t data_rate_settings_2_1_1[] = {
{
/* ((1.2 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 2736000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_1p2Gsps),
.data_rate_reg_array = datarate_211_1p2Gsps,
.data_rate_reg_array[0] = datarate_211_1p2Gsps,
},
{
/* ((1.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 3420000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_1p5Gsps),
.data_rate_reg_array = datarate_211_1p5Gsps,
.data_rate_reg_array[0] = datarate_211_1p5Gsps,
},
{
/* ((1.7 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 3876000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_1p7Gsps),
.data_rate_reg_array = datarate_211_1p7Gsps,
.data_rate_reg_array[0] = datarate_211_1p7Gsps,
},
{
/* ((2.1 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 4788000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_2p1Gsps),
.data_rate_reg_array = datarate_211_2p1Gsps,
.data_rate_reg_array[0] = datarate_211_2p1Gsps,
},
{
/* ((2.35 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5358000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_2p35Gsps),
.data_rate_reg_array = datarate_211_2p35Gsps,
.data_rate_reg_array[0] = datarate_211_2p35Gsps,
},
{
/* ((2.6 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5928000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_2p6Gsps),
.data_rate_reg_array = datarate_211_2p6Gsps,
.data_rate_reg_array[0] = datarate_211_2p6Gsps,
},
{
/* ((2.8 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 6384000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_2p8Gsps),
.data_rate_reg_array = datarate_211_2p8Gsps,
.data_rate_reg_array[0] = datarate_211_2p8Gsps,
},
{
/* ((3.3 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 7524000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_3p3Gsps),
.data_rate_reg_array = datarate_211_3p3Gsps,
.data_rate_reg_array[0] = datarate_211_3p3Gsps,
},
{
/* ((3.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 7980000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_3p5Gsps),
.data_rate_reg_array = datarate_211_3p5Gsps,
.data_rate_reg_array[0] = datarate_211_3p5Gsps,
},
{
/* ((4 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 9120000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_4Gsps),
.data_rate_reg_array = datarate_211_4Gsps,
.data_rate_reg_array[0] = datarate_211_4Gsps,
},
{
/* ((4.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 10260000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_4p5Gsps),
.data_rate_reg_array = datarate_211_4p5Gsps,
.data_rate_reg_array[0] = datarate_211_4p5Gsps,
},
{
/* ((5.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 11400000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_5Gsps),
.data_rate_reg_array = datarate_211_5Gsps,
.data_rate_reg_array[0] = datarate_211_5Gsps,
},
};

View File

@@ -1330,174 +1330,174 @@ struct csiphy_reg_t datarate_212_6p0Gsps[] = {
{0x0A14, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
};
struct data_rate_reg_info_t data_rate_settings_2_1_2[] = {
static struct data_rate_reg_info_t data_rate_settings_2_1_2[] = {
{
/* ((100 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 228000000,
.data_rate_reg_array[0] = datarate_212_100Msps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_100Msps),
.data_rate_reg_array = datarate_212_100Msps
},
{
/* ((200 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 456000000,
.data_rate_reg_array[0] = datarate_212_200Msps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_200Msps),
.data_rate_reg_array = datarate_212_200Msps
},
{
/* ((300 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 684000000,
.data_rate_reg_array[0] = datarate_212_300Msps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_300Msps),
.data_rate_reg_array = datarate_212_300Msps
},
{
/* ((350 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 798000000,
.data_rate_reg_array[0] = datarate_212_350Msps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_350Msps),
.data_rate_reg_array = datarate_212_350Msps
},
{
/* ((400 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 912000000,
.data_rate_reg_array[0] = datarate_212_400Msps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_400Msps),
.data_rate_reg_array = datarate_212_400Msps
},
{
/* ((500 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 1140000000,
.data_rate_reg_array[0] = datarate_212_500Msps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_500Msps),
.data_rate_reg_array = datarate_212_500Msps
},
{
/* ((600 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 1368000000,
.data_rate_reg_array[0] = datarate_212_600Msps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_600Msps),
.data_rate_reg_array = datarate_212_600Msps
},
{
/* ((700 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 1596000000,
.data_rate_reg_array[0] = datarate_212_700Msps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_700Msps),
.data_rate_reg_array = datarate_212_700Msps
},
{
/* ((800 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 1824000000,
.data_rate_reg_array[0] = datarate_212_800Msps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_800Msps),
.data_rate_reg_array = datarate_212_800Msps
},
{
/* ((900 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 2052000000,
.data_rate_reg_array[0] = datarate_212_900Msps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_900Msps),
.data_rate_reg_array = datarate_212_900Msps
},
{
/* ((1000 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 2280000000,
.data_rate_reg_array[0] = datarate_212_1p0Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_1p0Gsps),
.data_rate_reg_array = datarate_212_1p0Gsps
},
{
/* ((1.2 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 2736000000,
.data_rate_reg_array[0] = datarate_212_1p2Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_1p2Gsps),
.data_rate_reg_array = datarate_212_1p2Gsps
},
{
/* ((1.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 3420000000,
.data_rate_reg_array[0] = datarate_212_1p5Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_1p5Gsps),
.data_rate_reg_array = datarate_212_1p5Gsps,
},
{
/* ((1.7 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 3876000000,
.data_rate_reg_array[0] = datarate_212_1p7Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_1p7Gsps),
.data_rate_reg_array = datarate_212_1p7Gsps,
},
{
/* ((2.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 4560000000,
.data_rate_reg_array[0] = datarate_212_2p0Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_2p0Gsps),
.data_rate_reg_array = datarate_212_2p0Gsps
},
{
/* ((2.1 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 4788000000,
.data_rate_reg_array[0] = datarate_212_2p1Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_2p1Gsps),
.data_rate_reg_array = datarate_212_2p1Gsps,
},
{
/* ((2.35 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5358000000,
.data_rate_reg_array[0] = datarate_212_2p35Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_2p35Gsps),
.data_rate_reg_array = datarate_212_2p35Gsps,
},
{
/* ((2.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5700000000,
.data_rate_reg_array[0] = datarate_212_2p5Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_2p5Gsps),
.data_rate_reg_array = datarate_212_2p5Gsps
},
{
/* ((2.6 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5928000000,
.data_rate_reg_array[0] = datarate_212_2p6Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_2p6Gsps),
.data_rate_reg_array = datarate_212_2p6Gsps,
},
{
/* ((2.8 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 6384000000,
.data_rate_reg_array[0] = datarate_212_2p8Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_2p8Gsps),
.data_rate_reg_array = datarate_212_2p8Gsps,
},
{
/* ((3.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 6840000000,
.data_rate_reg_array[0] = datarate_212_3p0Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_3p0Gsps),
.data_rate_reg_array = datarate_212_3p0Gsps
},
{
/* ((3.3 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 7524000000,
.data_rate_reg_array[0] = datarate_212_3p3Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_3p3Gsps),
.data_rate_reg_array = datarate_212_3p3Gsps,
},
{
/* ((3.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 7980000000,
.data_rate_reg_array[0] = datarate_212_3p5Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_3p5Gsps),
.data_rate_reg_array = datarate_212_3p5Gsps,
},
{
/* ((4 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 9120000000,
.data_rate_reg_array[0] = datarate_212_4p0Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_4p0Gsps),
.data_rate_reg_array = datarate_212_4p0Gsps,
},
{
/* ((4.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 10260000000,
.data_rate_reg_array[0] = datarate_212_4p5Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_4p5Gsps),
.data_rate_reg_array = datarate_212_4p5Gsps,
},
{
/* ((5.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 11400000000,
.data_rate_reg_array[0] = datarate_212_5p0Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_5p0Gsps),
.data_rate_reg_array = datarate_212_5p0Gsps,
},
{
/* ((5.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 12540000000,
.data_rate_reg_array[0] = datarate_212_5p5Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_5p5Gsps),
.data_rate_reg_array = datarate_212_5p5Gsps,
},
{
/* ((6.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 13680000000,
.data_rate_reg_array[0] = datarate_212_6p0Gsps,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_6p0Gsps),
.data_rate_reg_array = datarate_212_6p0Gsps,
},
};

View File

@@ -1106,156 +1106,156 @@ struct csiphy_reg_t datarate_213_5Gsps[] = {
{0x108C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
};
struct data_rate_reg_info_t data_rate_settings_2_1_3[] = {
static struct data_rate_reg_info_t data_rate_settings_2_1_3[] = {
{
/* ((100 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 228000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_100Msps),
.data_rate_reg_array = datarate_213_100Msps
.data_rate_reg_array[0] = datarate_213_100Msps
},
{
/* ((200 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 456000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_200Msps),
.data_rate_reg_array = datarate_213_200Msps
.data_rate_reg_array[0] = datarate_213_200Msps
},
{
/* ((300 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 684000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_300Msps),
.data_rate_reg_array = datarate_213_300Msps
.data_rate_reg_array[0] = datarate_213_300Msps
},
{
/* ((400 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 912000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_400Msps),
.data_rate_reg_array = datarate_213_400Msps
.data_rate_reg_array[0] = datarate_213_400Msps
},
{
/* ((500 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 1140000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_500Msps),
.data_rate_reg_array = datarate_213_500Msps
.data_rate_reg_array[0] = datarate_213_500Msps
},
{
/* ((600 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 1368000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_600Msps),
.data_rate_reg_array = datarate_213_600Msps
.data_rate_reg_array[0] = datarate_213_600Msps
},
{
/* ((700 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 1596000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_700Msps),
.data_rate_reg_array = datarate_213_700Msps
.data_rate_reg_array[0] = datarate_213_700Msps
},
{
/* ((800 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 1824000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_800Msps),
.data_rate_reg_array = datarate_213_800Msps
.data_rate_reg_array[0] = datarate_213_800Msps
},
{
/* ((900 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 2052000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_900Msps),
.data_rate_reg_array = datarate_213_900Msps
.data_rate_reg_array[0] = datarate_213_900Msps
},
{
/* ((1000 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 2280000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_1p0Gsps),
.data_rate_reg_array = datarate_213_1p0Gsps
.data_rate_reg_array[0] = datarate_213_1p0Gsps
},
{
/* ((1.2 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 2736000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_1p2Gsps),
.data_rate_reg_array = datarate_213_1p2Gsps
.data_rate_reg_array[0] = datarate_213_1p2Gsps
},
{
/* ((1.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 3420000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_1p5Gsps),
.data_rate_reg_array = datarate_213_1p5Gsps,
.data_rate_reg_array[0] = datarate_213_1p5Gsps,
},
{
/* ((1.7 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 3876000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_1p7Gsps),
.data_rate_reg_array = datarate_213_1p7Gsps,
.data_rate_reg_array[0] = datarate_213_1p7Gsps,
},
{
/* ((2.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 4560000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_2p0Gsps),
.data_rate_reg_array = datarate_213_2p0Gsps
.data_rate_reg_array[0] = datarate_213_2p0Gsps
},
{
/* ((2.1 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 4788000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_2p1Gsps),
.data_rate_reg_array = datarate_213_2p1Gsps,
.data_rate_reg_array[0] = datarate_213_2p1Gsps,
},
{
/* ((2.35 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5358000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_2p35Gsps),
.data_rate_reg_array = datarate_213_2p35Gsps,
.data_rate_reg_array[0] = datarate_213_2p35Gsps,
},
{
/* ((2.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5700000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_2p5Gsps),
.data_rate_reg_array = datarate_213_2p5Gsps
.data_rate_reg_array[0] = datarate_213_2p5Gsps
},
{
/* ((2.6 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5928000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_2p6Gsps),
.data_rate_reg_array = datarate_213_2p6Gsps,
.data_rate_reg_array[0] = datarate_213_2p6Gsps,
},
{
/* ((2.8 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 6384000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_2p8Gsps),
.data_rate_reg_array = datarate_213_2p8Gsps,
.data_rate_reg_array[0] = datarate_213_2p8Gsps,
},
{
/* ((3.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 6840000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_3p0Gsps),
.data_rate_reg_array = datarate_213_3p0Gsps
.data_rate_reg_array[0] = datarate_213_3p0Gsps
},
{
/* ((3.3 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 7524000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_3p3Gsps),
.data_rate_reg_array = datarate_213_3p3Gsps,
.data_rate_reg_array[0] = datarate_213_3p3Gsps,
},
{
/* ((3.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 7980000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_3p5Gsps),
.data_rate_reg_array = datarate_213_3p5Gsps,
.data_rate_reg_array[0] = datarate_213_3p5Gsps,
},
{
/* ((4 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 9120000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_4Gsps),
.data_rate_reg_array = datarate_213_4Gsps,
.data_rate_reg_array[0] = datarate_213_4Gsps,
},
{
/* ((4.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 10260000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_4p5Gsps),
.data_rate_reg_array = datarate_213_4p5Gsps,
.data_rate_reg_array[0] = datarate_213_4p5Gsps,
},
{
/* ((5.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 11400000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_5Gsps),
.data_rate_reg_array = datarate_213_5Gsps,
.data_rate_reg_array[0] = datarate_213_5Gsps,
},
};

View File

@@ -1574,186 +1574,186 @@ struct csiphy_reg_t datarate_220_8p0Gsps[] = {
{0x0A14, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
};
struct data_rate_reg_info_t data_rate_settings_2_2_0[] = {
static struct data_rate_reg_info_t data_rate_settings_2_2_0[] = {
{
/* ((100 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 228000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_100Msps),
.data_rate_reg_array = datarate_220_100Msps
.data_rate_reg_array[0] = datarate_220_100Msps
},
{
/* ((200 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 456000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_200Msps),
.data_rate_reg_array = datarate_220_200Msps
.data_rate_reg_array[0] = datarate_220_200Msps
},
{
/* ((300 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 684000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_300Msps),
.data_rate_reg_array = datarate_220_300Msps
.data_rate_reg_array[0] = datarate_220_300Msps
},
{
/* ((350 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 798000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_350Msps),
.data_rate_reg_array = datarate_220_350Msps
.data_rate_reg_array[0] = datarate_220_350Msps
},
{
/* ((400 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 912000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_400Msps),
.data_rate_reg_array = datarate_220_400Msps
.data_rate_reg_array[0] = datarate_220_400Msps
},
{
/* ((500 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 1140000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_500Msps),
.data_rate_reg_array = datarate_220_500Msps
.data_rate_reg_array[0] = datarate_220_500Msps
},
{
/* ((600 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 1368000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_600Msps),
.data_rate_reg_array = datarate_220_600Msps
.data_rate_reg_array[0] = datarate_220_600Msps
},
{
/* ((700 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 1596000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_700Msps),
.data_rate_reg_array = datarate_220_700Msps
.data_rate_reg_array[0] = datarate_220_700Msps
},
{
/* ((800 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 1824000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_800Msps),
.data_rate_reg_array = datarate_220_800Msps
.data_rate_reg_array[0] = datarate_220_800Msps
},
{
/* ((900 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 2052000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_900Msps),
.data_rate_reg_array = datarate_220_900Msps
.data_rate_reg_array[0] = datarate_220_900Msps
},
{
/* ((1000 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 2280000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_1p0Gsps),
.data_rate_reg_array = datarate_220_1p0Gsps
.data_rate_reg_array[0] = datarate_220_1p0Gsps
},
{
/* ((1.2 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 2736000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_1p2Gsps),
.data_rate_reg_array = datarate_220_1p2Gsps
.data_rate_reg_array[0] = datarate_220_1p2Gsps
},
{
/* ((1.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 3420000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_1p5Gsps),
.data_rate_reg_array = datarate_220_1p5Gsps,
.data_rate_reg_array[0] = datarate_220_1p5Gsps,
},
{
/* ((1.7 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 3876000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_1p7Gsps),
.data_rate_reg_array = datarate_220_1p7Gsps,
.data_rate_reg_array[0] = datarate_220_1p7Gsps,
},
{
/* ((2.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 4560000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_2p0Gsps),
.data_rate_reg_array = datarate_220_2p0Gsps
.data_rate_reg_array[0] = datarate_220_2p0Gsps
},
{
/* ((2.1 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 4788000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_2p1Gsps),
.data_rate_reg_array = datarate_220_2p1Gsps,
.data_rate_reg_array[0] = datarate_220_2p1Gsps,
},
{
/* ((2.35 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5358000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_2p35Gsps),
.data_rate_reg_array = datarate_220_2p35Gsps,
.data_rate_reg_array[0] = datarate_220_2p35Gsps,
},
{
/* ((2.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5700000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_2p5Gsps),
.data_rate_reg_array = datarate_220_2p5Gsps
.data_rate_reg_array[0] = datarate_220_2p5Gsps
},
{
/* ((2.6 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
.bandwidth = 5928000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_2p6Gsps),
.data_rate_reg_array = datarate_220_2p6Gsps,
.data_rate_reg_array[0] = datarate_220_2p6Gsps,
},
{
/* ((2.8 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 6384000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_2p8Gsps),
.data_rate_reg_array = datarate_220_2p8Gsps,
.data_rate_reg_array[0] = datarate_220_2p8Gsps,
},
{
/* ((3.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 6840000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_3p0Gsps),
.data_rate_reg_array = datarate_220_3p0Gsps
.data_rate_reg_array[0] = datarate_220_3p0Gsps
},
{
/* ((3.3 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 7524000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_3p3Gsps),
.data_rate_reg_array = datarate_220_3p3Gsps,
.data_rate_reg_array[0] = datarate_220_3p3Gsps,
},
{
/* ((3.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 7980000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_3p5Gsps),
.data_rate_reg_array = datarate_220_3p5Gsps,
.data_rate_reg_array[0] = datarate_220_3p5Gsps,
},
{
/* ((4 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 9120000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_4p0Gsps),
.data_rate_reg_array = datarate_220_4p0Gsps,
.data_rate_reg_array[0] = datarate_220_4p0Gsps,
},
{
/* ((4.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 10260000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_4p5Gsps),
.data_rate_reg_array = datarate_220_4p5Gsps,
.data_rate_reg_array[0] = datarate_220_4p5Gsps,
},
{
/* ((5.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 11400000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_5p0Gsps),
.data_rate_reg_array = datarate_220_5p0Gsps,
.data_rate_reg_array[0] = datarate_220_5p0Gsps,
},
{
/* ((5.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 12540000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_5p5Gsps),
.data_rate_reg_array = datarate_220_5p5Gsps,
.data_rate_reg_array[0] = datarate_220_5p5Gsps,
},
{
/* ((6.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 13680000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_6p0Gsps),
.data_rate_reg_array = datarate_220_6p0Gsps,
.data_rate_reg_array[0] = datarate_220_6p0Gsps,
},
{
/* ((7.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 15960000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_7p0Gsps),
.data_rate_reg_array = datarate_220_7p0Gsps,
.data_rate_reg_array[0] = datarate_220_7p0Gsps,
},
{
/* ((8.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
.bandwidth = 18240000000,
.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_8p0Gsps),
.data_rate_reg_array = datarate_220_8p0Gsps,
.data_rate_reg_array[0] = datarate_220_8p0Gsps,
},
};

View File

@@ -148,9 +148,9 @@ static int cam_eeprom_read_memory(struct cam_eeprom_ctrl_t *e_ctrl,
static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
struct cam_sensor_power_ctrl_t *power_info)
{
int32_t rc = 0;
struct cam_hw_soc_info *soc_info =
&e_ctrl->soc_info;
int32_t rc = 0;
struct cam_hw_soc_info *soc_info = &e_ctrl->soc_info;
struct completion *i3c_probe_completion = NULL;
/* Parse and fill vreg params for power up settings */
rc = msm_camera_fill_vreg_params(
@@ -176,7 +176,10 @@ static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
power_info->dev = soc_info->dev;
rc = cam_sensor_core_power_up(power_info, soc_info);
if (e_ctrl->io_master_info.master_type == I3C_MASTER)
i3c_probe_completion = cam_eeprom_get_i3c_completion(e_ctrl->soc_info.index);
rc = cam_sensor_core_power_up(power_info, soc_info, i3c_probe_completion);
if (rc) {
CAM_ERR(CAM_EEPROM, "failed in eeprom power up rc %d", rc);
return rc;
@@ -189,6 +192,7 @@ static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
goto cci_failure;
}
}
return rc;
cci_failure:
if (cam_sensor_util_power_down(power_info, soc_info))

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_EEPROM_CORE_H_
#define _CAM_EEPROM_CORE_H_
@@ -17,5 +18,7 @@ int32_t cam_eeprom_parse_read_memory_map(struct device_node *of_node,
*/
void cam_eeprom_shutdown(struct cam_eeprom_ctrl_t *e_ctrl);
struct completion *cam_eeprom_get_i3c_completion(uint32_t index);
#endif
/* _CAM_EEPROM_CORE_H_ */

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "cam_eeprom_dev.h"
@@ -9,6 +10,17 @@
#include "cam_eeprom_core.h"
#include "cam_debug_util.h"
#include "camera_main.h"
#include "cam_compat.h"
static struct cam_i3c_eeprom_data {
struct cam_eeprom_ctrl_t *e_ctrl;
struct completion probe_complete;
} g_i3c_eeprom_data[MAX_CAMERAS];
struct completion *cam_eeprom_get_i3c_completion(uint32_t index)
{
return &g_i3c_eeprom_data[index].probe_complete;
}
static int cam_eeprom_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
@@ -546,6 +558,9 @@ static int cam_eeprom_component_bind(struct device *dev,
e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;
CAM_DBG(CAM_EEPROM, "Component bound successfully");
g_i3c_eeprom_data[e_ctrl->soc_info.index].e_ctrl = e_ctrl;
init_completion(&g_i3c_eeprom_data[e_ctrl->soc_info.index].probe_complete);
return rc;
free_soc:
kfree(soc_private);
@@ -665,6 +680,119 @@ static struct spi_driver cam_eeprom_spi_driver = {
.probe = cam_eeprom_spi_driver_probe,
.remove = cam_eeprom_spi_driver_remove,
};
static struct i3c_device_id eeprom_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
static int cam_eeprom_i3c_driver_probe(struct i3c_device *client)
{
int32_t rc = 0;
struct cam_eeprom_ctrl_t *e_ctrl = NULL;
uint32_t index;
struct device *dev;
if (!client) {
CAM_INFO(CAM_EEPROM, "Null Client pointer");
return -EINVAL;
}
dev = &client->dev;
CAM_DBG(CAM_EEPROM, "Probe for I3C Slave %s", dev_name(dev));
rc = of_property_read_u32(dev->of_node, "cell-index", &index);
if (rc) {
CAM_ERR(CAM_EEPROM, "device %s failed to read cell-index", dev_name(dev));
return rc;
}
if (index >= MAX_CAMERAS) {
CAM_ERR(CAM_EEPROM, "Invalid Cell-Index: %u for %s", index, dev_name(dev));
return -EINVAL;
}
e_ctrl = g_i3c_eeprom_data[index].e_ctrl;
if (!e_ctrl) {
CAM_ERR(CAM_EEPROM, "e_ctrl is null. I3C Probe before platfom driver probe for %s",
dev_name(dev));
return -EINVAL;
}
e_ctrl->io_master_info.i3c_client = client;
complete_all(&g_i3c_eeprom_data[index].probe_complete);
CAM_DBG(CAM_EEPROM, "I3C Probe Finished for %s", dev_name(dev));
return rc;
}
static struct i3c_driver cam_eeprom_i3c_driver = {
.id_table = eeprom_i3c_id,
.probe = cam_eeprom_i3c_driver_probe,
.remove = cam_i3c_driver_remove,
.driver = {
.owner = THIS_MODULE,
.name = EEPROM_DRIVER_I3C,
.of_match_table = cam_eeprom_dt_match,
.suppress_bind_attrs = true,
},
};
static int cam_eeprom_fill_i3c_device_id(void)
{
struct device_node *dev;
int num_entries;
int i = 0;
uint8_t ent_num = 0;
uint32_t mid;
uint32_t pid;
int rc;
dev = of_find_node_by_path(I3C_SENSOR_DEV_ID_DT_PATH);
if (!dev) {
CAM_WARN(CAM_EEPROM, "Couldnt Find the i3c-id-table dev node");
return 0;
}
num_entries = of_property_count_u32_elems(dev, "i3c-eeprom-id-table");
if (num_entries <= 0) {
CAM_WARN(CAM_EEPROM, "Failed while reading the property. num_entries:%d",
num_entries);
return 0;
}
while (i < num_entries) {
if (ent_num >= MAX_I3C_DEVICE_ID_ENTRIES) {
CAM_WARN(CAM_EEPROM, "Num_entries are more than MAX_I3C_DEVICE_ID_ENTRIES");
return -ENOMEM;
}
rc = of_property_read_u32_index(dev, "i3c-eeprom-id-table", i, &mid);
if (rc) {
CAM_ERR(CAM_EEPROM, "Failed in reading the MID. rc: %d", rc);
return rc;
}
i++;
rc = of_property_read_u32_index(dev, "i3c-eeprom-id-table", i, &pid);
if (rc) {
CAM_ERR(CAM_EEPROM, "Failed in reading the PID. rc: %d", rc);
return rc;
}
i++;
CAM_DBG(CAM_EEPROM, "PID: 0x%x, MID: 0x%x", pid, mid);
eeprom_i3c_id[ent_num].manuf_id = mid;
eeprom_i3c_id[ent_num].match_flags = I3C_MATCH_MANUF_AND_PART;
eeprom_i3c_id[ent_num].part_id = pid;
eeprom_i3c_id[ent_num].data = 0;
ent_num++;
}
return 0;
}
int cam_eeprom_driver_init(void)
{
int rc = 0;
@@ -679,15 +807,35 @@ int cam_eeprom_driver_init(void)
rc = spi_register_driver(&cam_eeprom_spi_driver);
if (rc < 0) {
CAM_ERR(CAM_EEPROM, "spi_register_driver failed rc = %d", rc);
return rc;
goto spi_register_err;
}
rc = i2c_add_driver(&cam_eeprom_i2c_driver);
if (rc < 0) {
CAM_ERR(CAM_EEPROM, "i2c_add_driver failed rc = %d", rc);
return rc;
goto i2c_register_err;
}
memset(eeprom_i3c_id, 0, sizeof(struct i3c_device_id) * (MAX_I3C_DEVICE_ID_ENTRIES + 1));
rc = cam_eeprom_fill_i3c_device_id();
if (rc)
goto i3c_register_err;
rc = i3c_driver_register_with_owner(&cam_eeprom_i3c_driver, THIS_MODULE);
if (rc) {
CAM_ERR(CAM_EEPROM, "i3c_driver registration failed, rc: %d", rc);
goto i3c_register_err;
}
return 0;
i3c_register_err:
i2c_del_driver(&cam_sensor_i2c_driver);
i2c_register_err:
spi_unregister_driver(&cam_eeprom_spi_driver);
spi_register_err:
platform_driver_unregister(&cam_sensor_platform_driver);
return rc;
}
@@ -696,6 +844,7 @@ void cam_eeprom_driver_exit(void)
platform_driver_unregister(&cam_eeprom_platform_driver);
spi_unregister_driver(&cam_eeprom_spi_driver);
i2c_del_driver(&cam_eeprom_i2c_driver);
i3c_driver_unregister(&cam_eeprom_i3c_driver);
}
MODULE_DESCRIPTION("CAM EEPROM driver");

View File

@@ -34,7 +34,9 @@
#define MSM_EEPROM_MAX_MEM_MAP_CNT 100
#define MSM_EEPROM_MEM_MAP_PROPERTIES_CNT 8
#define EEPROM_DRIVER_I2C "cam-i2c-eeprom"
#define EEPROM_DRIVER_I2C "cam-i2c-eeprom"
#define EEPROM_DRIVER_I3C "i3c_camera_eeprom"
enum cam_eeprom_state {
CAM_EEPROM_INIT,

View File

@@ -169,7 +169,7 @@ int cam_flash_i2c_power_ops(struct cam_flash_ctrl *fctrl,
}
}
rc = cam_sensor_core_power_up(power_info, soc_info);
rc = cam_sensor_core_power_up(power_info, soc_info, NULL);
if (rc) {
CAM_ERR(CAM_FLASH, "power up the core is failed:%d",
rc);

View File

@@ -7,7 +7,7 @@
#include <linux/module.h>
#include <linux/firmware.h>
#include <cam_sensor_cmn_header.h>
#include "cam_sensor_cmn_header.h"
#include "cam_ois_core.h"
#include "cam_ois_soc.h"
#include "cam_sensor_util.h"
@@ -105,14 +105,13 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl,
static int cam_ois_power_up(struct cam_ois_ctrl_t *o_ctrl)
{
int rc = 0;
struct cam_hw_soc_info *soc_info =
&o_ctrl->soc_info;
struct cam_ois_soc_private *soc_private;
struct cam_sensor_power_ctrl_t *power_info;
int rc = 0;
struct cam_hw_soc_info *soc_info = &o_ctrl->soc_info;
struct cam_ois_soc_private *soc_private;
struct cam_sensor_power_ctrl_t *power_info;
struct completion *i3c_probe_completion = NULL;
soc_private =
(struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private;
soc_private = (struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private;
power_info = &soc_private->power_info;
if ((power_info->power_setting == NULL) &&
@@ -151,7 +150,10 @@ static int cam_ois_power_up(struct cam_ois_ctrl_t *o_ctrl)
power_info->dev = soc_info->dev;
rc = cam_sensor_core_power_up(power_info, soc_info);
if (o_ctrl->io_master_info.master_type == I3C_MASTER)
i3c_probe_completion = cam_ois_get_i3c_completion(o_ctrl->soc_info.index);
rc = cam_sensor_core_power_up(power_info, soc_info, i3c_probe_completion);
if (rc) {
CAM_ERR(CAM_OIS, "failed in ois power up rc %d", rc);
return rc;

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_OIS_CORE_H_
#define _CAM_OIS_CORE_H_
@@ -30,5 +31,7 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *e_ctrl, void *arg);
*/
void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl);
struct completion *cam_ois_get_i3c_completion(uint32_t index);
#endif
/* _CAM_OIS_CORE_H_ */

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "cam_ois_dev.h"
@@ -9,6 +10,17 @@
#include "cam_ois_core.h"
#include "cam_debug_util.h"
#include "camera_main.h"
#include "cam_compat.h"
static struct cam_i3c_ois_data {
struct cam_ois_ctrl_t *o_ctrl;
struct completion probe_complete;
} g_i3c_ois_data[MAX_CAMERAS];
struct completion *cam_ois_get_i3c_completion(uint32_t index)
{
return &g_i3c_ois_data[index].probe_complete;
}
static int cam_ois_subdev_close_internal(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
@@ -372,6 +384,10 @@ static int cam_ois_component_bind(struct device *dev,
platform_set_drvdata(pdev, o_ctrl);
o_ctrl->cam_ois_state = CAM_OIS_INIT;
g_i3c_ois_data[o_ctrl->soc_info.index].o_ctrl = o_ctrl;
init_completion(&g_i3c_ois_data[o_ctrl->soc_info.index].probe_complete);
CAM_DBG(CAM_OIS, "Component bound successfully");
return rc;
unreg_subdev:
@@ -485,8 +501,117 @@ struct i2c_driver cam_ois_i2c_driver = {
},
};
static struct cam_ois_registered_driver_t registered_driver = {
0, 0};
static struct i3c_device_id ois_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
static int cam_ois_i3c_driver_probe(struct i3c_device *client)
{
int32_t rc = 0;
struct cam_ois_ctrl_t *o_ctrl = NULL;
uint32_t index;
struct device *dev;
if (!client) {
CAM_INFO(CAM_OIS, "Null Client pointer");
return -EINVAL;
}
dev = &client->dev;
CAM_DBG(CAM_OIS, "Probe for I3C Slave %s", dev_name(dev));
rc = of_property_read_u32(dev->of_node, "cell-index", &index);
if (rc) {
CAM_ERR(CAM_OIS, "device %s failed to read cell-index", dev_name(dev));
return rc;
}
if (index >= MAX_CAMERAS) {
CAM_ERR(CAM_OIS, "Invalid Cell-Index: %u for %s", index, dev_name(dev));
return -EINVAL;
}
o_ctrl = g_i3c_ois_data[index].o_ctrl;
if (!o_ctrl) {
CAM_ERR(CAM_OIS, "o_ctrl is null. I3C Probe before platfom driver probe for %s",
dev_name(dev));
return -EINVAL;
}
o_ctrl->io_master_info.i3c_client = client;
complete_all(&g_i3c_ois_data[index].probe_complete);
CAM_DBG(CAM_OIS, "I3C Probe Finished for %s", dev_name(dev));
return rc;
}
static struct i3c_driver cam_ois_i3c_driver = {
.id_table = ois_i3c_id,
.probe = cam_ois_i3c_driver_probe,
.remove = cam_i3c_driver_remove,
.driver = {
.owner = THIS_MODULE,
.name = OIS_DRIVER_I3C,
.of_match_table = cam_ois_dt_match,
.suppress_bind_attrs = true,
},
};
static int cam_ois_fill_i3c_device_id(void)
{
struct device_node *dev;
int num_entries;
int i = 0;
uint8_t ent_num = 0;
uint32_t mid;
uint32_t pid;
int rc;
dev = of_find_node_by_path(I3C_SENSOR_DEV_ID_DT_PATH);
if (!dev) {
CAM_WARN(CAM_OIS, "Couldnt Find the i3c-id-table dev node");
return 0;
}
num_entries = of_property_count_u32_elems(dev, "i3c-ois-id-table");
if (num_entries <= 0) {
CAM_WARN(CAM_OIS, "Failed while reading the property. num_entries:%d",
num_entries);
return 0;
}
while (i < num_entries) {
if (ent_num >= MAX_I3C_DEVICE_ID_ENTRIES) {
CAM_WARN(CAM_OIS, "Num_entries are more than MAX_I3C_DEVICE_ID_ENTRIES");
return -ENOMEM;
}
rc = of_property_read_u32_index(dev, "i3c-ois-id-table", i, &mid);
if (rc) {
CAM_ERR(CAM_OIS, "Failed in reading the MID. rc: %d", rc);
return rc;
}
i++;
rc = of_property_read_u32_index(dev, "i3c-ois-id-table", i, &pid);
if (rc) {
CAM_ERR(CAM_OIS, "Failed in reading the PID. rc: %d", rc);
return rc;
}
i++;
CAM_DBG(CAM_OIS, "PID: 0x%x, MID: 0x%x", pid, mid);
ois_i3c_id[ent_num].manuf_id = mid;
ois_i3c_id[ent_num].match_flags = I3C_MATCH_MANUF_AND_PART;
ois_i3c_id[ent_num].part_id = pid;
ois_i3c_id[ent_num].data = 0;
ent_num++;
}
return 0;
}
int cam_ois_driver_init(void)
{
@@ -494,30 +619,42 @@ int cam_ois_driver_init(void)
rc = platform_driver_register(&cam_ois_platform_driver);
if (rc) {
CAM_ERR(CAM_OIS, "platform_driver_register failed rc = %d",
rc);
CAM_ERR(CAM_OIS, "platform_driver_register failed rc = %d", rc);
return rc;
}
registered_driver.platform_driver = 1;
rc = i2c_add_driver(&cam_ois_i2c_driver);
if (rc) {
CAM_ERR(CAM_OIS, "i2c_add_driver failed rc = %d", rc);
return rc;
goto i2c_register_err;
}
registered_driver.i2c_driver = 1;
memset(ois_i3c_id, 0, sizeof(struct i3c_device_id) * (MAX_I3C_DEVICE_ID_ENTRIES + 1));
rc = cam_ois_fill_i3c_device_id();
if (rc)
goto i3c_register_err;
rc = i3c_driver_register_with_owner(&cam_ois_i3c_driver, THIS_MODULE);
if (rc) {
CAM_ERR(CAM_OIS, "i3c_driver registration failed, rc: %d", rc);
goto i3c_register_err;
}
return 0;
i3c_register_err:
i2c_del_driver(&cam_ois_i2c_driver);
i2c_register_err:
platform_driver_unregister(&cam_ois_platform_driver);
return rc;
}
void cam_ois_driver_exit(void)
{
if (registered_driver.platform_driver)
platform_driver_unregister(&cam_ois_platform_driver);
if (registered_driver.i2c_driver)
i2c_del_driver(&cam_ois_i2c_driver);
platform_driver_unregister(&cam_ois_platform_driver);
i2c_del_driver(&cam_ois_i2c_driver);
i3c_driver_unregister(&cam_ois_i3c_driver);
}
MODULE_DESCRIPTION("CAM OIS driver");

View File

@@ -27,6 +27,7 @@
static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
#define OIS_DRIVER_I2C "cam-i2c-ois"
#define OIS_DRIVER_I3C "i3c_camera_ois"
enum cam_ois_state {
CAM_OIS_INIT,
@@ -35,17 +36,6 @@ enum cam_ois_state {
CAM_OIS_START,
};
/**
* struct cam_ois_registered_driver_t - registered driver info
* @platform_driver : flag indicates if platform driver is registered
* @i2c_driver : flag indicates if i2c driver is registered
*
*/
struct cam_ois_registered_driver_t {
bool platform_driver;
bool i2c_driver;
};
/**
* struct cam_ois_i2c_info_t - I2C info
* @slave_addr : slave address

View File

@@ -866,9 +866,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
struct cam_sensor_power_ctrl_t *power_info =
&s_ctrl->sensordata->power_info;
struct timespec64 ts;
struct completion *i3c_probe_completion;
uint64_t ms, sec, min, hrs;
long time_left;
if (!s_ctrl || !arg) {
CAM_ERR(CAM_SENSOR, "s_ctrl is NULL");
@@ -943,6 +941,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
);
goto free_power_settings;
}
if (s_ctrl->i2c_data.reg_bank_unlock_settings.is_settings_valid) {
rc = cam_sensor_apply_settings(s_ctrl, 0,
CAM_SENSOR_PACKET_OPCODE_SENSOR_REG_BANK_UNLOCK);
@@ -958,20 +957,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
}
}
if (s_ctrl->io_master_info.master_type == I3C_MASTER) {
i3c_probe_completion =
cam_sensor_get_i3c_completion(s_ctrl->soc_info.index);
time_left = cam_common_wait_for_completion_timeout(
i3c_probe_completion,
msecs_to_jiffies(CAM_SENSOR_I3C_PROBE_TIMEOUT_MS));
if (!time_left) {
CAM_ERR(CAM_SENSOR, "Wait for I3C probe timedout for %s",
s_ctrl->sensor_name);
return -ETIMEDOUT;
}
}
/* Match sensor ID */
rc = cam_sensor_match_id(s_ctrl);
if (rc < 0) {
@@ -1428,9 +1413,9 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
{
int rc;
struct cam_sensor_power_ctrl_t *power_info;
struct cam_camera_slave_info *slave_info;
struct cam_hw_soc_info *soc_info =
&s_ctrl->soc_info;
struct cam_camera_slave_info *slave_info;
struct cam_hw_soc_info *soc_info = &s_ctrl->soc_info;
struct completion *i3c_probe_completion = NULL;
if (!s_ctrl) {
CAM_ERR(CAM_SENSOR, "failed: %pK", s_ctrl);
@@ -1469,7 +1454,10 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
}
}
rc = cam_sensor_core_power_up(power_info, soc_info);
if (s_ctrl->io_master_info.master_type == I3C_MASTER)
i3c_probe_completion = cam_sensor_get_i3c_completion(s_ctrl->soc_info.index);
rc = cam_sensor_core_power_up(power_info, soc_info, i3c_probe_completion);
if (rc < 0) {
CAM_ERR(CAM_SENSOR, "core power up failed:%d", rc);
return rc;

View File

@@ -572,7 +572,7 @@ static struct i3c_device_id sensor_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
static struct i3c_driver cam_sensor_i3c_driver = {
.id_table = sensor_i3c_id,
.probe = cam_sensor_i3c_driver_probe,
.remove = cam_sensor_i3c_driver_remove,
.remove = cam_i3c_driver_remove,
.driver = {
.owner = THIS_MODULE,
.name = SENSOR_DRIVER_I3C,

View File

@@ -12,6 +12,7 @@ static int cam_qup_i3c_rxdata(struct i3c_device *dev_client, unsigned char *rxda
enum camera_sensor_i2c_type addr_type, int data_length)
{
int rc;
uint32_t us = 0;
struct i3c_priv_xfer read_buf[2] = {
{
.rnw = 0,
@@ -26,7 +27,18 @@ static int cam_qup_i3c_rxdata(struct i3c_device *dev_client, unsigned char *rxda
};
rc = i3c_device_do_priv_xfers(dev_client, read_buf, ARRAY_SIZE(read_buf));
if (rc)
if (rc == -ENOTCONN) {
while (us < CAM_I3C_DEV_PROBE_TIMEOUT_US) {
usleep_range(1000, 1005);
rc = i3c_device_do_priv_xfers(dev_client, read_buf, ARRAY_SIZE(read_buf));
if (rc != -ENOTCONN)
break;
us += 1000;
}
if (rc)
CAM_ERR(CAM_SENSOR, "Retry Failed i3c_read: rc = %d, us = %d", rc, us);
} else if (rc)
CAM_ERR(CAM_SENSOR, "Failed with i3c_read: rc = %d", rc);
return rc;
@@ -37,6 +49,7 @@ static int cam_qup_i3c_txdata(struct camera_io_master *dev_client, unsigned char
int length)
{
int rc;
uint32_t us = 0;
struct i3c_priv_xfer write_buf = {
.rnw = 0,
.len = length,
@@ -44,7 +57,18 @@ static int cam_qup_i3c_txdata(struct camera_io_master *dev_client, unsigned char
};
rc = i3c_device_do_priv_xfers(dev_client->i3c_client, &write_buf, 1);
if (rc)
if (rc == -ENOTCONN) {
while (us < CAM_I3C_DEV_PROBE_TIMEOUT_US) {
usleep_range(1000, 1005);
rc = i3c_device_do_priv_xfers(dev_client->i3c_client, &write_buf, 1);
if (rc != -ENOTCONN)
break;
us += 1000;
}
if (rc)
CAM_ERR(CAM_SENSOR, "Retry Failed i3c_write: rc = %d, us = %d", rc, us);
} else if (rc)
CAM_ERR(CAM_SENSOR, "Failed with i3c_write: rc = %d", rc);
return rc;

View File

@@ -23,7 +23,8 @@
#define MAX_POWER_CONFIG 12
#define MAX_PER_FRAME_ARRAY 32
#define BATCH_SIZE_MAX 16
#define CAM_SENSOR_I3C_PROBE_TIMEOUT_MS 10
#define CAM_I3C_DEV_PROBE_TIMEOUT_MS 10
#define CAM_I3C_DEV_PROBE_TIMEOUT_US (CAM_I3C_DEV_PROBE_TIMEOUT_MS * 1000)
#define I3C_SENSOR_DEV_ID_DT_PATH "/soc/qcom,cam-i3c-id-table"
#define MAX_I3C_DEVICE_ID_ENTRIES MAX_CAMERAS

View File

@@ -1977,12 +1977,13 @@ static int cam_config_mclk_reg(struct cam_sensor_power_ctrl_t *ctrl,
}
int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
struct cam_hw_soc_info *soc_info)
struct cam_hw_soc_info *soc_info, struct completion *i3c_probe_status)
{
int rc = 0, index = 0, no_gpio = 0, ret = 0, num_vreg, j = 0, i = 0;
int32_t vreg_idx = -1;
struct cam_sensor_power_setting *power_setting = NULL;
struct msm_camera_gpio_num_info *gpio_num_info = NULL;
long time_left;
CAM_DBG(CAM_SENSOR, "Enter");
if (!ctrl) {
@@ -2195,6 +2196,17 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
(power_setting->delay * 1000) + 1000);
}
if (i3c_probe_status) {
time_left = cam_common_wait_for_completion_timeout(
i3c_probe_status,
msecs_to_jiffies(CAM_I3C_DEV_PROBE_TIMEOUT_MS));
if (!time_left) {
CAM_ERR(CAM_SENSOR, "Wait for I3C probe timedout");
rc = -ETIMEDOUT;
goto power_up_failed;
}
}
return 0;
power_up_failed:
CAM_ERR(CAM_SENSOR, "failed. rc:%d", rc);

View File

@@ -66,7 +66,7 @@ int cam_sensor_util_init_gpio_pin_tbl(
struct cam_hw_soc_info *soc_info,
struct msm_camera_gpio_num_info **pgpio_num_info);
int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
struct cam_hw_soc_info *soc_info);
struct cam_hw_soc_info *soc_info, struct completion *i3c_probe_status);
int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
struct cam_hw_soc_info *soc_info);

View File

@@ -9,11 +9,107 @@
#include <linux/of_address.h>
#include <linux/slab.h>
#include <soc/qcom/rpmh.h>
#include "cam_compat.h"
#include "cam_debug_util.h"
#include "cam_cpas_api.h"
#include "camera_main.h"
#if IS_ENABLED(CONFIG_USE_RPMH_DRV_API)
#define CAM_RSC_DRV_IDENTIFIER "cam_rsc"
const struct device *cam_cpas_get_rsc_dev_for_drv(uint32_t index)
{
const struct device *rsc_dev;
rsc_dev = rpmh_get_device(CAM_RSC_DRV_IDENTIFIER, index);
if (!rsc_dev) {
CAM_ERR(CAM_CPAS, "Invalid dev for index: %u", index);
return NULL;
}
return rsc_dev;
}
int cam_cpas_start_drv_for_dev(const struct device *dev)
{
int rc = 0;
if (!dev) {
CAM_ERR(CAM_CPAS, "Invalid dev for DRV enable");
return -EINVAL;
}
rc = rpmh_drv_start(dev);
if (rc) {
CAM_ERR(CAM_CPAS, "[%s] Failed in DRV start", dev_name(dev));
return rc;
}
return rc;
}
int cam_cpas_stop_drv_for_dev(const struct device *dev)
{
int rc = 0;
if (!dev) {
CAM_ERR(CAM_CPAS, "Invalid dev for DRV disable");
return -EINVAL;
}
rc = rpmh_drv_stop(dev);
if (rc) {
CAM_ERR(CAM_CPAS, "[%s] Failed in DRV stop", dev_name(dev));
return rc;
}
return rc;
}
int cam_cpas_drv_channel_switch_for_dev(const struct device *dev)
{
int rc = 0;
if (!dev) {
CAM_ERR(CAM_CPAS, "Invalid dev for DRV channel switch");
return -EINVAL;
}
rc = rpmh_write_sleep_and_wake_no_child(dev);
if (rc) {
CAM_ERR(CAM_CPAS, "[%s] Failed in DRV channel switch", dev_name(dev));
return rc;
}
return rc;
}
#else
const struct device *cam_cpas_get_rsc_dev_for_drv(uint32_t index)
{
return NULL;
}
int cam_cpas_start_drv_for_dev(const struct device *dev)
{
return 0;
}
int cam_cpas_stop_drv_for_dev(const struct device *dev)
{
return 0;
}
int cam_cpas_drv_channel_switch_for_dev(const struct device *dev)
{
return 0;
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
int cam_reserve_icp_fw(struct cam_fw_alloc_info *icp_fw, size_t fw_length)
{
@@ -366,7 +462,7 @@ void cam_compat_util_put_dmabuf_va(struct dma_buf *dmabuf, void *vaddr)
dma_buf_vunmap(dmabuf, &mapping);
}
void cam_sensor_i3c_driver_remove(struct i3c_device *client)
void cam_i3c_driver_remove(struct i3c_device *client)
{
CAM_DBG(CAM_SENSOR, "I3C remove invoked for %s",
(client ? dev_name(&client->dev) : "none"));
@@ -411,7 +507,7 @@ void cam_compat_util_put_dmabuf_va(struct dma_buf *dmabuf, void *vaddr)
dma_buf_vunmap(dmabuf, vaddr);
}
int cam_sensor_i3c_driver_remove(struct i3c_device *client)
int cam_i3c_driver_remove(struct i3c_device *client)
{
CAM_DBG(CAM_SENSOR, "I3C remove invoked for %s",
(client ? dev_name(&client->dev) : "none"));

View File

@@ -55,14 +55,22 @@ void cam_compat_util_put_dmabuf_va(struct dma_buf *dmabuf, void *vaddr);
void cam_smmu_util_iommu_custom(struct device *dev,
dma_addr_t discard_start, size_t discard_length);
const struct device *cam_cpas_get_rsc_dev_for_drv(uint32_t index);
int cam_cpas_start_drv_for_dev(const struct device *dev);
int cam_cpas_stop_drv_for_dev(const struct device *dev);
int cam_cpas_drv_channel_switch_for_dev(const struct device *dev);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
int cam_req_mgr_ordered_list_cmp(void *priv,
const struct list_head *head_1, const struct list_head *head_2);
void cam_sensor_i3c_driver_remove(struct i3c_device *client);
void cam_i3c_driver_remove(struct i3c_device *client);
#else
int cam_req_mgr_ordered_list_cmp(void *priv,
struct list_head *head_1, struct list_head *head_2);
int cam_sensor_i3c_driver_remove(struct i3c_device *client);
int cam_i3c_driver_remove(struct i3c_device *client);
#endif
long cam_dma_buf_set_name(struct dma_buf *dmabuf, const char *name);

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/msm-bus.h>
@@ -65,7 +66,8 @@ end:
return rc;
}
int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib)
int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib,
enum cam_soc_bus_path_data bus_path_data)
{
int idx = 0;
struct msm_bus_paths *path;

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CAM_SOC_BUS_H_
@@ -10,9 +11,17 @@
#include <linux/slab.h>
#include <linux/platform_device.h>
#include "cam_debug_util.h"
#include "cam_cpas.h"
#define CAM_SOC_BUS_MAX_NUM_USECASES 8
enum cam_soc_bus_path_data {
CAM_SOC_BUS_PATH_DATA_HLOS,
CAM_SOC_BUS_PATH_DATA_DRV_HIGH,
CAM_SOC_BUS_PATH_DATA_DRV_LOW,
CAM_SOC_BUS_PATH_DATA_MAX,
};
/**
* struct cam_soc_bus_client_ab_ib : Bandwidth values for selected usecase
*
@@ -30,6 +39,7 @@ struct cam_soc_bus_client_ab_ib {
* @name: Name of bus client
* @src_id: Bus master/src id
* @dst_id: Bus slave/dst id
* @is_drv_port: If DRV bus client
* @num_usecases: Number of use cases for this client
* @bw_pair: Bandwidth values for applicable usecases
*/
@@ -37,6 +47,7 @@ struct cam_soc_bus_client_common_data {
const char *name;
uint32_t src_id;
uint32_t dst_id;
bool is_drv_port;
int num_usecases;
struct cam_soc_bus_client_ab_ib bw_pair[CAM_SOC_BUS_MAX_NUM_USECASES];
};
@@ -56,10 +67,12 @@ struct cam_soc_bus_client {
#if IS_REACHABLE(CONFIG_QCOM_BUS_SCALING) || \
IS_REACHABLE(CONFIG_INTERCONNECT_QCOM)
const char *cam_soc_bus_path_data_to_str(enum cam_soc_bus_path_data bus_path_data);
int cam_soc_bus_client_update_request(void *client, unsigned int idx);
int cam_soc_bus_client_update_bw(void *client, uint64_t ab,
uint64_t ib);
int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib,
enum cam_soc_bus_path_data bus_path_data);
int cam_soc_bus_client_register(struct platform_device *pdev,
struct device_node *dev_node, void **client,
@@ -68,14 +81,20 @@ int cam_soc_bus_client_register(struct platform_device *pdev,
void cam_soc_bus_client_unregister(void **client);
#else
static const char *cam_soc_bus_path_data_to_str(enum cam_soc_bus_path_data bus_path_data)
{
return NULL;
}
static inline int cam_soc_bus_client_update_request(void *client,
unsigned int idx)
{
return 0;
}
static inline int cam_soc_bus_client_update_bw(void *client,
uint64_t ab, uint64_t ib)
int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib,
enum cam_soc_bus_path_data bus_path_data)
{
return 0;
}

View File

@@ -1,9 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/interconnect.h>
#include <dt-bindings/interconnect/qcom,icc.h>
#include "cam_soc_bus.h"
/**
@@ -12,9 +14,22 @@
* @icc_data: Bus icc path information
*/
struct cam_soc_bus_client_data {
struct icc_path *icc_data;
struct icc_path *icc_data[CAM_SOC_BUS_PATH_DATA_MAX];
};
const char *cam_soc_bus_path_data_to_str(enum cam_soc_bus_path_data bus_path_data)
{
switch (bus_path_data) {
case CAM_SOC_BUS_PATH_DATA_HLOS:
return "BUS_PATH_HLOS";
case CAM_SOC_BUS_PATH_DATA_DRV_HIGH:
return "BUS_PATH_DRV_HIGH";
case CAM_SOC_BUS_PATH_DATA_DRV_LOW:
return "BUS_PATH_DRV_LOW";
default:
return "BUS_PATH_INVALID";
}
}
int cam_soc_bus_client_update_request(void *client, unsigned int idx)
{
int rc = 0;
@@ -37,7 +52,7 @@ int cam_soc_bus_client_update_request(void *client, unsigned int idx)
CAM_DBG(CAM_PERF, "Bus client=[%s] index[%d] ab[%llu] ib[%llu]",
bus_client->common_data->name, idx, ab, ib);
rc = icc_set_bw(bus_client_data->icc_data, Bps_to_icc(ab),
rc = icc_set_bw(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS], Bps_to_icc(ab),
Bps_to_icc(ib));
if (rc) {
CAM_ERR(CAM_UTIL,
@@ -50,26 +65,29 @@ end:
return rc;
}
int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib)
int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib,
enum cam_soc_bus_path_data bus_path_data)
{
struct cam_soc_bus_client *bus_client =
(struct cam_soc_bus_client *) client;
struct cam_soc_bus_client_data *bus_client_data =
(struct cam_soc_bus_client_data *) bus_client->client_data;
int rc = 0;
struct cam_soc_bus_client *bus_client =
(struct cam_soc_bus_client *) client;
struct cam_soc_bus_client_data *bus_client_data =
(struct cam_soc_bus_client_data *) bus_client->client_data;
int rc = 0;
CAM_DBG(CAM_PERF, "Bus client=[%s] :ab[%llu] ib[%llu]",
bus_client->common_data->name, ab, ib);
rc = icc_set_bw(bus_client_data->icc_data, Bps_to_icc(ab),
Bps_to_icc(ib));
if (rc) {
CAM_ERR(CAM_UTIL, "Update request failed, client[%s]",
bus_client->common_data->name);
goto end;
}
CAM_DBG(CAM_PERF, "Bus client=[%s] [%s] :ab[%llu] ib[%llu]",
bus_client->common_data->name, cam_soc_bus_path_data_to_str(bus_path_data),
ab, ib);
rc = icc_set_bw(bus_client_data->icc_data[bus_path_data], Bps_to_icc(ab),
Bps_to_icc(ib));
if (rc) {
CAM_ERR(CAM_UTIL, "Update request failed, client[%s]",
bus_client->common_data->name);
goto end;
}
end:
return rc;
}
int cam_soc_bus_client_register(struct platform_device *pdev,
@@ -89,8 +107,7 @@ int cam_soc_bus_client_register(struct platform_device *pdev,
*client = bus_client;
bus_client_data = kzalloc(sizeof(struct cam_soc_bus_client_data),
GFP_KERNEL);
bus_client_data = kzalloc(sizeof(struct cam_soc_bus_client_data), GFP_KERNEL);
if (!bus_client_data) {
kfree(bus_client);
*client = NULL;
@@ -100,30 +117,80 @@ int cam_soc_bus_client_register(struct platform_device *pdev,
bus_client->client_data = bus_client_data;
bus_client->common_data = common_data;
bus_client_data->icc_data = icc_get(&pdev->dev,
bus_client->common_data->src_id,
bus_client->common_data->dst_id);
if (IS_ERR_OR_NULL(bus_client_data->icc_data)) {
CAM_ERR(CAM_UTIL, "failed in register bus client");
rc = -EINVAL;
goto error;
if (bus_client->common_data->is_drv_port) {
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH] = icc_get(&pdev->dev,
bus_client->common_data->src_id, bus_client->common_data->dst_id);
if (IS_ERR_OR_NULL(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH])) {
CAM_ERR(CAM_UTIL,
"Failed to register DRV bus client Bus Client=[%s] : src=%d, dst=%d bus_path:%d",
bus_client->common_data->src_id, bus_client->common_data->dst_id,
CAM_SOC_BUS_PATH_DATA_DRV_HIGH);
rc = -EINVAL;
goto error;
}
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW] = icc_get(&pdev->dev,
bus_client->common_data->src_id, bus_client->common_data->dst_id);
if (IS_ERR_OR_NULL(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW])) {
CAM_ERR(CAM_UTIL,
"Failed to register DRV bus client Bus Client=[%s] : src=%d, dst=%d bus_path:%d",
bus_client->common_data->src_id, bus_client->common_data->dst_id,
CAM_SOC_BUS_PATH_DATA_DRV_LOW);
rc = -EINVAL;
goto error;
}
/* Set appropriate tags for HIGH and LOW vote paths */
icc_set_tag(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH],
QCOM_ICC_TAG_ACTIVE_ONLY);
icc_set_tag(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW],
QCOM_ICC_TAG_SLEEP);
rc = icc_set_bw(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH], 0, 0);
if (rc) {
CAM_ERR(CAM_UTIL, "Bus client[%s] update request failed, rc = %d",
bus_client->common_data->name, rc);
goto fail_unregister_client;
}
rc = icc_set_bw(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW], 0, 0);
if (rc) {
CAM_ERR(CAM_UTIL, "Bus client[%s] update request failed, rc = %d",
bus_client->common_data->name, rc);
goto fail_unregister_client;
}
} else {
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS] = icc_get(&pdev->dev,
bus_client->common_data->src_id, bus_client->common_data->dst_id);
if (IS_ERR_OR_NULL(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS])) {
CAM_ERR(CAM_UTIL, "failed to register HLOS bus client");
rc = -EINVAL;
goto error;
}
rc = icc_set_bw(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS], 0, 0);
if (rc) {
CAM_ERR(CAM_UTIL, "Bus client[%s] update request failed, rc = %d",
bus_client->common_data->name, rc);
goto fail_unregister_client;
}
}
rc = icc_set_bw(bus_client_data->icc_data, 0, 0);
if (rc) {
CAM_ERR(CAM_UTIL, "Bus client update request failed, rc = %d",
rc);
goto fail_unregister_client;
}
CAM_DBG(CAM_PERF, "Register Bus Client=[%s] : src=%d, dst=%d",
CAM_DBG(CAM_PERF, "Register Bus Client=[%s] : src=%d, dst=%d is_drv_port:%s",
bus_client->common_data->name, bus_client->common_data->src_id,
bus_client->common_data->dst_id);
bus_client->common_data->dst_id,
CAM_BOOL_TO_YESNO(bus_client->common_data->is_drv_port));
return 0;
fail_unregister_client:
icc_put(bus_client_data->icc_data);
if (bus_client->common_data->is_drv_port) {
icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH]);
icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW]);
} else {
icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS]);
}
error:
kfree(bus_client_data);
bus_client->client_data = NULL;
@@ -141,7 +208,13 @@ void cam_soc_bus_client_unregister(void **client)
struct cam_soc_bus_client_data *bus_client_data =
(struct cam_soc_bus_client_data *) bus_client->client_data;
icc_put(bus_client_data->icc_data);
if (bus_client->common_data->is_drv_port) {
icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH]);
icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW]);
} else {
icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS]);
}
kfree(bus_client_data);
bus_client->client_data = NULL;
kfree(bus_client);