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
Esse commit está contido em:

commit de
Gerrit - the friendly Code Review server

commit
9272dea247
@@ -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
|
||||
|
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -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);
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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 {
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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_ */
|
||||
|
@@ -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;
|
||||
|
@@ -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];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -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);
|
||||
|
@@ -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));
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
};
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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_ */
|
||||
|
@@ -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,
|
||||
};
|
||||
|
||||
|
@@ -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 ",
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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",
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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_ */
|
||||
|
@@ -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");
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -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,
|
||||
},
|
||||
|
||||
};
|
||||
|
@@ -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))
|
||||
|
@@ -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_ */
|
||||
|
@@ -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");
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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_ */
|
||||
|
@@ -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");
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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"));
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
Referência em uma nova issue
Block a user