Merge "msm: camera: isp: Add support for SFE sys cache config" into camera-kernel.lnx.5.0
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
c2889122d0
@@ -2191,6 +2191,149 @@ done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_cpas_activate_cache(
|
||||
struct cam_hw_info *cpas_hw,
|
||||
struct cam_sys_cache_info *cache_info)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&cpas_hw->hw_mutex);
|
||||
cache_info->ref_cnt++;
|
||||
if (cache_info->ref_cnt > 1) {
|
||||
mutex_unlock(&cpas_hw->hw_mutex);
|
||||
CAM_DBG(CAM_CPAS, "Cache: %s has already been activated cnt: %d",
|
||||
cache_info->name, cache_info->ref_cnt);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = llcc_slice_activate(cache_info->slic_desc);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_CPAS, "Failed to activate cache:%s",
|
||||
cache_info->name);
|
||||
goto end;
|
||||
}
|
||||
|
||||
mutex_unlock(&cpas_hw->hw_mutex);
|
||||
CAM_DBG(CAM_CPAS, "Activated cache:%s", cache_info->name);
|
||||
return rc;
|
||||
|
||||
end:
|
||||
cache_info->ref_cnt--;
|
||||
mutex_unlock(&cpas_hw->hw_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_cpas_deactivate_cache(
|
||||
struct cam_hw_info *cpas_hw,
|
||||
struct cam_sys_cache_info *cache_info)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&cpas_hw->hw_mutex);
|
||||
if (!cache_info->ref_cnt) {
|
||||
mutex_unlock(&cpas_hw->hw_mutex);
|
||||
CAM_ERR(CAM_CPAS, "Unbalanced deactivate");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
cache_info->ref_cnt--;
|
||||
if (cache_info->ref_cnt) {
|
||||
mutex_unlock(&cpas_hw->hw_mutex);
|
||||
CAM_DBG(CAM_CPAS, "activate cnt for: %s non-zero: %d",
|
||||
cache_info->name, cache_info->ref_cnt);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = llcc_slice_deactivate(cache_info->slic_desc);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_CPAS, "Failed to deactivate cache:%s",
|
||||
cache_info->name);
|
||||
|
||||
mutex_unlock(&cpas_hw->hw_mutex);
|
||||
CAM_DBG(CAM_CPAS, "De-activated cache:%s", cache_info->name);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline int cam_cpas_validate_cache_type(
|
||||
uint32_t num_caches, enum cam_sys_cache_config_types type)
|
||||
{
|
||||
if ((!num_caches) || (type < 0) || (type >= num_caches))
|
||||
return -EINVAL;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_cpas_get_slice_id(
|
||||
struct cam_hw_info *cpas_hw,
|
||||
enum cam_sys_cache_config_types type)
|
||||
{
|
||||
struct cam_cpas_private_soc *soc_private =
|
||||
(struct cam_cpas_private_soc *)cpas_hw->soc_info.soc_private;
|
||||
uint32_t num_caches = soc_private->num_caches;
|
||||
int scid = -1, i;
|
||||
|
||||
if (cam_cpas_validate_cache_type(num_caches, type))
|
||||
goto end;
|
||||
|
||||
for (i = 0; i < num_caches; i++) {
|
||||
if (type == soc_private->llcc_info[i].type) {
|
||||
scid = soc_private->llcc_info[i].scid;
|
||||
CAM_DBG(CAM_CPAS, "Cache:%s type:%d scid:%d",
|
||||
soc_private->llcc_info[i].name, type, scid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return scid;
|
||||
}
|
||||
|
||||
static int cam_cpas_activate_cache_slice(
|
||||
struct cam_hw_info *cpas_hw,
|
||||
enum cam_sys_cache_config_types type)
|
||||
{
|
||||
struct cam_cpas_private_soc *soc_private =
|
||||
(struct cam_cpas_private_soc *)cpas_hw->soc_info.soc_private;
|
||||
uint32_t num_caches = soc_private->num_caches;
|
||||
int rc = 0, i;
|
||||
|
||||
CAM_DBG(CAM_CPAS, "Activate type: %d", type);
|
||||
if (cam_cpas_validate_cache_type(num_caches, type))
|
||||
goto end;
|
||||
|
||||
for (i = 0; i < num_caches; i++) {
|
||||
if (type == soc_private->llcc_info[i].type)
|
||||
rc = cam_cpas_activate_cache(cpas_hw,
|
||||
&soc_private->llcc_info[i]);
|
||||
}
|
||||
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_cpas_deactivate_cache_slice(
|
||||
struct cam_hw_info *cpas_hw,
|
||||
enum cam_sys_cache_config_types type)
|
||||
{
|
||||
struct cam_cpas_private_soc *soc_private =
|
||||
(struct cam_cpas_private_soc *)cpas_hw->soc_info.soc_private;
|
||||
uint32_t num_caches = soc_private->num_caches;
|
||||
int rc = 0, i;
|
||||
|
||||
CAM_DBG(CAM_CPAS, "De-activate type: %d", type);
|
||||
if (cam_cpas_validate_cache_type(num_caches, type))
|
||||
goto end;
|
||||
|
||||
for (i = 0; i < num_caches; i++) {
|
||||
if (type == soc_private->llcc_info[i].type)
|
||||
rc = cam_cpas_deactivate_cache(cpas_hw,
|
||||
&soc_private->llcc_info[i]);
|
||||
}
|
||||
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_cpas_hw_process_cmd(void *hw_priv,
|
||||
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
|
||||
{
|
||||
@@ -2327,6 +2470,42 @@ static int cam_cpas_hw_process_cmd(void *hw_priv,
|
||||
rc = cam_cpas_select_qos(hw_priv, *selection_mask);
|
||||
break;
|
||||
}
|
||||
case CAM_CPAS_HW_CMD_GET_SCID: {
|
||||
enum cam_sys_cache_config_types type;
|
||||
|
||||
if (sizeof(enum cam_sys_cache_config_types) != arg_size) {
|
||||
CAM_ERR(CAM_CPAS, "cmd_type %d, size mismatch %d",
|
||||
cmd_type, arg_size);
|
||||
break;
|
||||
}
|
||||
type = *((enum cam_sys_cache_config_types *) cmd_args);
|
||||
rc = cam_cpas_get_slice_id(hw_priv, type);
|
||||
}
|
||||
break;
|
||||
case CAM_CPAS_HW_CMD_ACTIVATE_LLC: {
|
||||
enum cam_sys_cache_config_types type;
|
||||
|
||||
if (sizeof(enum cam_sys_cache_config_types) != arg_size) {
|
||||
CAM_ERR(CAM_CPAS, "cmd_type %d, size mismatch %d",
|
||||
cmd_type, arg_size);
|
||||
break;
|
||||
}
|
||||
type = *((enum cam_sys_cache_config_types *) cmd_args);
|
||||
rc = cam_cpas_activate_cache_slice(hw_priv, type);
|
||||
}
|
||||
break;
|
||||
case CAM_CPAS_HW_CMD_DEACTIVATE_LLC: {
|
||||
enum cam_sys_cache_config_types type;
|
||||
|
||||
if (sizeof(enum cam_sys_cache_config_types) != arg_size) {
|
||||
CAM_ERR(CAM_CPAS, "cmd_type %d, size mismatch %d",
|
||||
cmd_type, arg_size);
|
||||
break;
|
||||
}
|
||||
type = *((enum cam_sys_cache_config_types *) cmd_args);
|
||||
rc = cam_cpas_deactivate_cache_slice(hw_priv, type);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_CPAS, "CPAS HW command not valid =%d", cmd_type);
|
||||
break;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CPAS_HW_INTF_H_
|
||||
@@ -43,6 +43,9 @@ enum cam_cpas_hw_cmd_process {
|
||||
CAM_CPAS_HW_CMD_LOG_VOTE,
|
||||
CAM_CPAS_HW_CMD_SELECT_QOS,
|
||||
CAM_CPAS_HW_CMD_LOG_EVENT,
|
||||
CAM_CPAS_HW_CMD_GET_SCID,
|
||||
CAM_CPAS_HW_CMD_ACTIVATE_LLC,
|
||||
CAM_CPAS_HW_CMD_DEACTIVATE_LLC,
|
||||
CAM_CPAS_HW_CMD_INVALID,
|
||||
};
|
||||
|
||||
|
@@ -589,6 +589,82 @@ int cam_cpas_register_client(
|
||||
}
|
||||
EXPORT_SYMBOL(cam_cpas_register_client);
|
||||
|
||||
int cam_cpas_get_scid(
|
||||
enum cam_sys_cache_config_types type)
|
||||
{
|
||||
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_GET_SCID, &type,
|
||||
sizeof(type));
|
||||
} else {
|
||||
CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(cam_cpas_get_scid);
|
||||
|
||||
int cam_cpas_activate_llcc(
|
||||
enum cam_sys_cache_config_types type)
|
||||
{
|
||||
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_ACTIVATE_LLC, &type,
|
||||
sizeof(type));
|
||||
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_activate_llcc);
|
||||
|
||||
int cam_cpas_deactivate_llcc(
|
||||
enum cam_sys_cache_config_types type)
|
||||
{
|
||||
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_DEACTIVATE_LLC, &type,
|
||||
sizeof(type));
|
||||
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_deactivate_llcc);
|
||||
|
||||
int cam_cpas_subdev_cmd(struct cam_cpas_intf *cpas_intf,
|
||||
struct cam_control *cmd)
|
||||
{
|
||||
|
@@ -637,6 +637,105 @@ end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline enum cam_sys_cache_config_types cam_cpas_find_type_from_string(
|
||||
const char *cache_name)
|
||||
{
|
||||
if (strcmp(cache_name, "small-1") == 0)
|
||||
return CAM_LLCC_SMALL_1;
|
||||
else if (strcmp(cache_name, "small-2") == 0)
|
||||
return CAM_LLCC_SMALL_2;
|
||||
else
|
||||
return CAM_LLCC_MAX;
|
||||
}
|
||||
|
||||
static int cam_cpas_parse_sys_cache_uids(
|
||||
struct device_node *of_node,
|
||||
struct cam_cpas_private_soc *soc_private)
|
||||
{
|
||||
enum cam_sys_cache_config_types type = CAM_LLCC_MAX;
|
||||
int num_caches, i, rc;
|
||||
uint32_t scid;
|
||||
|
||||
soc_private->llcc_info = NULL;
|
||||
soc_private->num_caches = 0;
|
||||
|
||||
num_caches = of_property_count_strings(of_node, "sys-cache-names");
|
||||
if (num_caches <= 0) {
|
||||
CAM_DBG(CAM_CPAS, "no cache-names found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (num_caches > CAM_LLCC_MAX) {
|
||||
CAM_ERR(CAM_CPAS,
|
||||
"invalid number of cache-names found: 0x%x",
|
||||
num_caches);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
soc_private->llcc_info = kcalloc(num_caches,
|
||||
sizeof(struct cam_sys_cache_info), GFP_KERNEL);
|
||||
if (!soc_private->llcc_info)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < num_caches; i++) {
|
||||
rc = of_property_read_string_index(of_node, "sys-cache-names", i,
|
||||
&soc_private->llcc_info[i].name);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_CPAS, "failed to read cache-names at %d", i);
|
||||
goto end;
|
||||
}
|
||||
|
||||
type = cam_cpas_find_type_from_string(
|
||||
soc_private->llcc_info[i].name);
|
||||
if (type == CAM_LLCC_MAX) {
|
||||
CAM_ERR(CAM_CPAS, "Unsupported cache found: %s",
|
||||
soc_private->llcc_info[i].name);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
soc_private->llcc_info[i].type = type;
|
||||
rc = of_property_read_u32_index(of_node,
|
||||
"sys-cache-uids", i,
|
||||
&soc_private->llcc_info[i].uid);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_CPAS,
|
||||
"unable to read sys cache uid at index %d", i);
|
||||
goto end;
|
||||
}
|
||||
|
||||
soc_private->llcc_info[i].slic_desc =
|
||||
llcc_slice_getd(soc_private->llcc_info[i].uid);
|
||||
|
||||
if (IS_ERR_OR_NULL(soc_private->llcc_info[i].slic_desc)) {
|
||||
CAM_ERR(CAM_CPAS,
|
||||
"Failed to get slice desc for uid %u",
|
||||
soc_private->llcc_info[i].uid);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
scid = llcc_get_slice_id(soc_private->llcc_info[i].slic_desc);
|
||||
soc_private->llcc_info[i].scid = scid;
|
||||
soc_private->llcc_info[i].size =
|
||||
llcc_get_slice_size(soc_private->llcc_info[i].slic_desc);
|
||||
soc_private->num_caches++;
|
||||
|
||||
CAM_DBG(CAM_CPAS,
|
||||
"Cache: %s uid: %u scid: %d size: %zukb",
|
||||
soc_private->llcc_info[i].name,
|
||||
soc_private->llcc_info[i].uid, scid,
|
||||
soc_private->llcc_info[i].size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
end:
|
||||
kfree(soc_private->llcc_info);
|
||||
soc_private->llcc_info = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
|
||||
struct platform_device *pdev, struct cam_cpas_private_soc *soc_private)
|
||||
{
|
||||
@@ -952,8 +1051,16 @@ int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
|
||||
CAM_DBG(CAM_CPAS, "RPMH BCM info not available in DT, count=%d",
|
||||
count);
|
||||
}
|
||||
|
||||
/* check cache info */
|
||||
rc = cam_cpas_parse_sys_cache_uids(of_node, soc_private);
|
||||
if (rc)
|
||||
goto cache_parse_fail;
|
||||
|
||||
return 0;
|
||||
|
||||
cache_parse_fail:
|
||||
soc_private->rpmh_info[CAM_RPMH_NUMBER_OF_BCMS] = 0;
|
||||
cleanup_tree:
|
||||
cam_cpas_node_tree_cleanup(cpas_core, soc_private);
|
||||
cleanup_clients:
|
||||
@@ -1011,11 +1118,13 @@ release_res:
|
||||
int cam_cpas_soc_deinit_resources(struct cam_hw_soc_info *soc_info)
|
||||
{
|
||||
int rc;
|
||||
struct cam_cpas_private_soc *soc_private = soc_info->soc_private;
|
||||
|
||||
rc = cam_soc_util_release_platform_resource(soc_info);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_CPAS, "release platform failed, rc=%d", rc);
|
||||
|
||||
kfree(soc_private->llcc_info);
|
||||
kfree(soc_info->soc_private);
|
||||
soc_info->soc_private = NULL;
|
||||
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#ifndef _CAM_CPAS_SOC_H_
|
||||
#define _CAM_CPAS_SOC_H_
|
||||
|
||||
#include <linux/soc/qcom/llcc-qcom.h>
|
||||
#include "cam_soc_util.h"
|
||||
#include "cam_cpas_hw.h"
|
||||
|
||||
@@ -89,6 +90,26 @@ struct cam_cpas_feature_info {
|
||||
uint32_t hw_map;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_sys_cache_info : Last level camera cache info
|
||||
*
|
||||
* @ref_cnt: Ref cnt activate/deactivate cache
|
||||
* @type: cache type small/large etc.
|
||||
* @uid: Client user ID
|
||||
* @size: Cache size
|
||||
* @scid: Slice ID
|
||||
* @slic_desc: Slice descriptor
|
||||
*/
|
||||
struct cam_sys_cache_info {
|
||||
uint32_t ref_cnt;
|
||||
enum cam_sys_cache_config_types type;
|
||||
uint32_t uid;
|
||||
size_t size;
|
||||
int32_t scid;
|
||||
const char *name;
|
||||
struct llcc_slice_desc *slic_desc;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_cpas_private_soc : CPAS private DT info
|
||||
*
|
||||
@@ -112,6 +133,8 @@ struct cam_cpas_feature_info {
|
||||
* @rpmh_info: RPMH BCM info
|
||||
* @num_feature_info: number of feature_info entries
|
||||
* @feature_info: Structure for storing feature information
|
||||
* @num_caches: Number of last level caches
|
||||
* @llcc_info: Cache info
|
||||
*/
|
||||
struct cam_cpas_private_soc {
|
||||
const char *arch_compat;
|
||||
@@ -132,6 +155,8 @@ struct cam_cpas_private_soc {
|
||||
uint32_t rpmh_info[CAM_RPMH_BCM_INFO_MAX];
|
||||
uint32_t num_feature_info;
|
||||
struct cam_cpas_feature_info feature_info[CAM_CPAS_MAX_FUSE_FEATURE];
|
||||
uint32_t num_caches;
|
||||
struct cam_sys_cache_info *llcc_info;
|
||||
};
|
||||
|
||||
void cam_cpas_util_debug_parse_data(struct cam_cpas_private_soc *soc_private);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CPAS_API_H_
|
||||
@@ -210,6 +210,16 @@ enum cam_camnoc_irq_type {
|
||||
CAM_CAMNOC_IRQ_AHB_TIMEOUT,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* enum cam_sys_cache_config_types - Enum for camera llc's
|
||||
*/
|
||||
enum cam_sys_cache_config_types {
|
||||
CAM_LLCC_SMALL_1 = 0,
|
||||
CAM_LLCC_SMALL_2 = 1,
|
||||
CAM_LLCC_MAX = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_camnoc_irq_slave_err_data : Data for Slave error.
|
||||
*
|
||||
@@ -721,4 +731,40 @@ int cam_cpas_select_qos_settings(uint32_t selection_mask);
|
||||
int cam_cpas_notify_event(const char *identifier_string,
|
||||
int32_t identifier_value);
|
||||
|
||||
/**
|
||||
* cam_cpas_get_scid()
|
||||
*
|
||||
* @brief: API to obtain slice id for the given type
|
||||
*
|
||||
* @type: Cache type
|
||||
*
|
||||
* @return slice id, -1 for invalid id.
|
||||
*
|
||||
*/
|
||||
int cam_cpas_get_scid(enum cam_sys_cache_config_types type);
|
||||
|
||||
/**
|
||||
* cam_cpas_activate_llcc()
|
||||
*
|
||||
* @brief: API to activate system cache
|
||||
*
|
||||
* @type: Cache type
|
||||
*
|
||||
* @return 0 for success.
|
||||
*
|
||||
*/
|
||||
int cam_cpas_activate_llcc(enum cam_sys_cache_config_types type);
|
||||
|
||||
/**
|
||||
* cam_cpas_deactivate_llcc()
|
||||
*
|
||||
* @brief: API to de-activate system cache
|
||||
*
|
||||
* @type: Cache type
|
||||
*
|
||||
* @return 0 for success.
|
||||
*
|
||||
*/
|
||||
int cam_cpas_deactivate_llcc(enum cam_sys_cache_config_types type);
|
||||
|
||||
#endif /* _CAM_CPAS_API_H_ */
|
||||
|
@@ -781,6 +781,12 @@ static void cam_ife_hw_mgr_deinit_hw(
|
||||
for (i = 0; i < max_ife_out_res; i++)
|
||||
cam_ife_hw_mgr_deinit_hw_res(&ctx->res_list_ife_out[i]);
|
||||
|
||||
/* Check if any cache needs to be de-activated */
|
||||
for (i = CAM_LLCC_SMALL_1; i < CAM_LLCC_MAX; i++) {
|
||||
if (ctx->flags.sys_cache_usage[i])
|
||||
cam_cpas_deactivate_llcc(i);
|
||||
ctx->flags.sys_cache_usage[i] = false;
|
||||
}
|
||||
ctx->flags.init_done = false;
|
||||
}
|
||||
|
||||
@@ -890,6 +896,18 @@ static int cam_ife_hw_mgr_init_hw(
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if any cache needs to be activated */
|
||||
for (i = CAM_LLCC_SMALL_1; i < CAM_LLCC_MAX; i++) {
|
||||
if (ctx->flags.sys_cache_usage[i]) {
|
||||
rc = cam_cpas_activate_llcc(i);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Failed to activate cache: %d", i);
|
||||
goto deinit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
deinit:
|
||||
ctx->flags.init_done = true;
|
||||
@@ -6219,8 +6237,9 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
|
||||
for (i = 0; i < CAM_SFE_HW_NUM_MAX; i++) {
|
||||
struct cam_sfe_debug_cfg_params debug_cfg;
|
||||
|
||||
debug_cfg.sfe_debug_cfg = g_ife_hw_mgr.debug_cfg.sfe_debug;
|
||||
debug_cfg.sfe_sensor_sel = g_ife_hw_mgr.debug_cfg.sfe_sensor_diag_cfg;
|
||||
debug_cfg.cache_config = false;
|
||||
debug_cfg.u.dbg_cfg.sfe_debug_cfg = g_ife_hw_mgr.debug_cfg.sfe_debug;
|
||||
debug_cfg.u.dbg_cfg.sfe_sensor_sel = g_ife_hw_mgr.debug_cfg.sfe_sensor_diag_cfg;
|
||||
if (g_ife_hw_mgr.sfe_devices[i]) {
|
||||
rc = g_ife_hw_mgr.sfe_devices[i]->hw_ops.process_cmd(
|
||||
g_ife_hw_mgr.sfe_devices[i]->hw_priv,
|
||||
@@ -6970,8 +6989,6 @@ end:
|
||||
}
|
||||
|
||||
static int cam_isp_blob_sfe_scratch_buf_update(
|
||||
uint32_t blob_type,
|
||||
struct cam_isp_generic_blob_info *blob_info,
|
||||
struct cam_isp_sfe_init_scratch_buf_config *scratch_config,
|
||||
struct cam_hw_prepare_update_args *prepare)
|
||||
{
|
||||
@@ -7056,6 +7073,148 @@ static int cam_isp_blob_sfe_scratch_buf_update(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int __cam_isp_sfe_send_cache_config(
|
||||
int32_t cmd_type,
|
||||
struct cam_isp_sfe_bus_sys_cache_config *wm_rm_cache_cfg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_isp_resource_node *hw_res = wm_rm_cache_cfg->res;
|
||||
|
||||
rc = hw_res->hw_intf->hw_ops.process_cmd(
|
||||
hw_res->hw_intf->hw_priv,
|
||||
cmd_type, wm_rm_cache_cfg,
|
||||
sizeof(struct cam_isp_sfe_bus_sys_cache_config));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Failed in sending cache config for:%d",
|
||||
hw_res->res_id);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_isp_blob_sfe_exp_order_update(
|
||||
uint32_t base_idx,
|
||||
struct cam_isp_sfe_exp_config *exp_config,
|
||||
struct cam_hw_prepare_update_args *prepare)
|
||||
{
|
||||
int rc = 0, i, j;
|
||||
uint32_t exp_order_max = 0;
|
||||
uint32_t res_id_out, res_id_in;
|
||||
struct cam_ife_hw_mgr_ctx *ctx;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_isp_hw_mgr_res *tmp;
|
||||
struct cam_isp_sfe_wm_exp_order_config *order_cfg;
|
||||
struct cam_ife_hw_mgr *hw_mgr;
|
||||
struct cam_isp_sfe_bus_sys_cache_config wm_rm_cache_cfg;
|
||||
|
||||
ctx = prepare->ctxt_to_hw_map;
|
||||
hw_mgr = ctx->hw_mgr;
|
||||
memset(ctx->flags.sys_cache_usage, false, sizeof(ctx->flags.sys_cache_usage));
|
||||
|
||||
if (!hw_mgr->num_caches_found) {
|
||||
CAM_DBG(CAM_ISP, "No caches found during probe");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The last resource in the array will be considered as
|
||||
* last exposure
|
||||
*/
|
||||
exp_order_max = exp_config->num_ports - 1;
|
||||
for (i = 0; i < exp_config->num_ports; i++) {
|
||||
order_cfg = &exp_config->wm_config[i];
|
||||
|
||||
rc = cam_ife_hw_mgr_is_sfe_rdi_for_fetch(
|
||||
order_cfg->res_type);
|
||||
if (!rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Not a SFE fetch RDI: 0x%x",
|
||||
order_cfg->res_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Add more params if needed */
|
||||
wm_rm_cache_cfg.use_cache =
|
||||
(exp_order_max == i) ? true : false;
|
||||
wm_rm_cache_cfg.scid = 0;
|
||||
|
||||
/* Currently using cache for short only */
|
||||
if (wm_rm_cache_cfg.use_cache) {
|
||||
if (base_idx == CAM_SFE_CORE_0) {
|
||||
wm_rm_cache_cfg.scid =
|
||||
hw_mgr->sys_cache_info[CAM_LLCC_SMALL_1].scid;
|
||||
if (wm_rm_cache_cfg.scid <= 0)
|
||||
goto end;
|
||||
|
||||
ctx->flags.sys_cache_usage[CAM_LLCC_SMALL_1] = true;
|
||||
} else if (base_idx == CAM_SFE_CORE_1) {
|
||||
wm_rm_cache_cfg.scid =
|
||||
hw_mgr->sys_cache_info[CAM_LLCC_SMALL_2].scid;
|
||||
if (wm_rm_cache_cfg.scid <= 0)
|
||||
goto end;
|
||||
|
||||
ctx->flags.sys_cache_usage[CAM_LLCC_SMALL_2] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure cache config for WM */
|
||||
res_id_out = order_cfg->res_type & 0xFF;
|
||||
hw_mgr_res = &ctx->res_list_sfe_out[res_id_out];
|
||||
for (j = 0; j < CAM_ISP_HW_SPLIT_MAX; j++) {
|
||||
if (!hw_mgr_res->hw_res[j])
|
||||
continue;
|
||||
|
||||
if (hw_mgr_res->hw_res[j]->hw_intf->hw_idx != base_idx)
|
||||
continue;
|
||||
|
||||
wm_rm_cache_cfg.res = hw_mgr_res->hw_res[j];
|
||||
rc = __cam_isp_sfe_send_cache_config(
|
||||
CAM_ISP_HW_SFE_SYS_CACHE_WM_CONFIG,
|
||||
&wm_rm_cache_cfg);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* RDI WMs have been validated find corresponding RM */
|
||||
if (order_cfg->res_type == CAM_ISP_SFE_OUT_RES_RDI_0)
|
||||
res_id_in = CAM_ISP_HW_SFE_IN_RD0;
|
||||
else if (order_cfg->res_type == CAM_ISP_SFE_OUT_RES_RDI_1)
|
||||
res_id_in = CAM_ISP_HW_SFE_IN_RD1;
|
||||
else
|
||||
res_id_in = CAM_ISP_HW_SFE_IN_RD2;
|
||||
|
||||
/* Configure cache config for RM */
|
||||
list_for_each_entry_safe(hw_mgr_res, tmp, &ctx->res_list_ife_in_rd, list) {
|
||||
for (j = 0; j < CAM_ISP_HW_SPLIT_MAX; j++) {
|
||||
if (!hw_mgr_res->hw_res[j])
|
||||
continue;
|
||||
|
||||
if (hw_mgr_res->hw_res[j]->res_id != res_id_in)
|
||||
continue;
|
||||
|
||||
if (hw_mgr_res->hw_res[j]->hw_intf->hw_idx != base_idx)
|
||||
continue;
|
||||
|
||||
wm_rm_cache_cfg.res = hw_mgr_res->hw_res[j];
|
||||
rc = __cam_isp_sfe_send_cache_config(
|
||||
CAM_ISP_HW_SFE_SYS_CACHE_RM_CONFIG,
|
||||
&wm_rm_cache_cfg);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
CAM_DBG(CAM_ISP,
|
||||
"cache config based on exp order: %u [max: %u] for out: 0x%x",
|
||||
i, exp_order_max, order_cfg->res_type);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_isp_blob_hfr_update(
|
||||
uint32_t blob_type,
|
||||
struct cam_isp_generic_blob_info *blob_info,
|
||||
@@ -8288,6 +8447,7 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_HFR_CONFIG:
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_FE_CONFIG:
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_SCRATCH_BUF_CFG:
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_EXP_ORDER_CFG:
|
||||
break;
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH: {
|
||||
struct cam_isp_mode_switch_info *mup_config;
|
||||
@@ -8604,7 +8764,7 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = cam_isp_blob_sfe_scratch_buf_update(blob_type, blob_info,
|
||||
rc = cam_isp_blob_sfe_scratch_buf_update(
|
||||
scratch_config, prepare);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP, "SFE scratch buffer update failed");
|
||||
@@ -8642,6 +8802,69 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data,
|
||||
mup_config->num_expoures;
|
||||
}
|
||||
break;
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_EXP_ORDER_CFG: {
|
||||
struct cam_isp_sfe_exp_config *exp_config;
|
||||
|
||||
if (!ife_mgr_ctx->flags.is_sfe_shdr) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Blob %u supported only for sHDR streams",
|
||||
blob_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (blob_size <
|
||||
sizeof(struct cam_isp_sfe_exp_config)) {
|
||||
CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
exp_config =
|
||||
(struct cam_isp_sfe_exp_config *)blob_data;
|
||||
|
||||
if ((exp_config->num_ports > CAM_SFE_FE_RDI_NUM_MAX) ||
|
||||
(exp_config->num_ports == 0)) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Invalid num_ports %u in exp order config",
|
||||
exp_config->num_ports);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check for integer overflow */
|
||||
if (exp_config->num_ports != 1) {
|
||||
if (sizeof(struct cam_isp_sfe_wm_exp_order_config) >
|
||||
((UINT_MAX -
|
||||
sizeof(
|
||||
struct cam_isp_sfe_exp_config)) /
|
||||
(exp_config->num_ports - 1))) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Max size exceeded in exp order config num_ports: %u size per port: %lu",
|
||||
exp_config->num_ports,
|
||||
sizeof(
|
||||
struct cam_isp_sfe_wm_exp_order_config));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (blob_size <
|
||||
(sizeof(struct cam_isp_sfe_exp_config) +
|
||||
(exp_config->num_ports - 1) *
|
||||
sizeof(struct cam_isp_sfe_wm_exp_order_config))) {
|
||||
CAM_ERR(CAM_ISP, "Invalid blob size: %u expected: %lu",
|
||||
blob_size,
|
||||
sizeof(
|
||||
struct cam_isp_sfe_exp_config) +
|
||||
(exp_config->num_ports - 1) *
|
||||
sizeof(
|
||||
struct cam_isp_sfe_wm_exp_order_config));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = cam_isp_blob_sfe_exp_order_update(
|
||||
blob_info->base_info->idx, exp_config, prepare);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP, "SFE exp order update failed");
|
||||
}
|
||||
break;
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG:
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG:
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG:
|
||||
@@ -11086,6 +11309,49 @@ static int cam_ife_hw_mgr_sort_dev_with_caps(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_ife_set_sfe_cache_debug(void *data, u64 val)
|
||||
{
|
||||
int i, rc = -EINVAL;
|
||||
uint32_t hw_idx = 0;
|
||||
struct cam_sfe_debug_cfg_params debug_cfg;
|
||||
struct cam_hw_intf *hw_intf = NULL;
|
||||
|
||||
debug_cfg.cache_config = true;
|
||||
|
||||
/* BITS [0:3] is for hw_idx */
|
||||
hw_idx = val & 0xF;
|
||||
for (i = 0; i < CAM_SFE_HW_NUM_MAX; i++) {
|
||||
if ((g_ife_hw_mgr.sfe_devices[i]) && (i == hw_idx)) {
|
||||
hw_intf = g_ife_hw_mgr.sfe_devices[i];
|
||||
|
||||
debug_cfg.u.cache_cfg.sfe_cache_dbg = (val >> 4);
|
||||
g_ife_hw_mgr.debug_cfg.sfe_cache_debug[i] =
|
||||
debug_cfg.u.cache_cfg.sfe_cache_dbg;
|
||||
rc = hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
|
||||
CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG,
|
||||
&debug_cfg,
|
||||
sizeof(struct cam_sfe_debug_cfg_params));
|
||||
}
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP, "Set SFE cache debug value: 0x%llx", val);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_get_sfe_cache_debug(void *data, u64 *val)
|
||||
{
|
||||
*val = g_ife_hw_mgr.debug_cfg.sfe_cache_debug[CAM_SFE_CORE_1];
|
||||
*val = *val << 32;
|
||||
*val |= g_ife_hw_mgr.debug_cfg.sfe_cache_debug[CAM_SFE_CORE_0];
|
||||
CAM_DBG(CAM_ISP, "Get SFE cace debug value: 0x%llx", *val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(cam_ife_sfe_cache_debug,
|
||||
cam_ife_get_sfe_cache_debug,
|
||||
cam_ife_set_sfe_cache_debug, "%16llu");
|
||||
|
||||
static int cam_ife_set_csid_debug(void *data, u64 val)
|
||||
{
|
||||
g_ife_hw_mgr.debug_cfg.csid_debug = val;
|
||||
@@ -11208,6 +11474,8 @@ static int cam_ife_hw_mgr_debug_register(void)
|
||||
dbgfileptr = debugfs_create_bool("disable_ife_mmu_prefetch", 0644,
|
||||
g_ife_hw_mgr.debug_cfg.dentry,
|
||||
&g_ife_hw_mgr.debug_cfg.disable_ife_mmu_prefetch);
|
||||
dbgfileptr = debugfs_create_file("sfe_cache_debug", 0644,
|
||||
g_ife_hw_mgr.debug_cfg.dentry, NULL, &cam_ife_sfe_cache_debug);
|
||||
|
||||
if (IS_ERR(dbgfileptr)) {
|
||||
if (PTR_ERR(dbgfileptr) == -ENODEV)
|
||||
@@ -11464,6 +11732,18 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Populate sys cache info */
|
||||
g_ife_hw_mgr.num_caches_found = 0;
|
||||
for (i = CAM_LLCC_SMALL_1; i < CAM_LLCC_MAX; i++) {
|
||||
g_ife_hw_mgr.sys_cache_info[i].scid =
|
||||
cam_cpas_get_scid(i);
|
||||
g_ife_hw_mgr.sys_cache_info[i].type = i;
|
||||
CAM_DBG(CAM_ISP, "Cache_%d scid: %d",
|
||||
i, g_ife_hw_mgr.sys_cache_info[i].scid);
|
||||
if (g_ife_hw_mgr.sys_cache_info[i].scid > 0)
|
||||
g_ife_hw_mgr.num_caches_found++;
|
||||
}
|
||||
|
||||
/* fill return structure */
|
||||
hw_mgr_intf->hw_mgr_priv = &g_ife_hw_mgr;
|
||||
hw_mgr_intf->hw_get_caps = cam_ife_mgr_get_hw_caps;
|
||||
@@ -11531,4 +11811,5 @@ void cam_ife_hw_mgr_deinit(void)
|
||||
|
||||
cam_smmu_destroy_handle(g_ife_hw_mgr.mgr_common.img_iommu_hdl);
|
||||
g_ife_hw_mgr.mgr_common.img_iommu_hdl = -1;
|
||||
g_ife_hw_mgr.num_caches_found = 0;
|
||||
}
|
||||
|
@@ -44,9 +44,11 @@ enum cam_ife_ctx_master_type {
|
||||
* @dentry: Debugfs entry
|
||||
* @csid_debug: csid debug information
|
||||
* @enable_recovery: enable recovery
|
||||
* @camif_debug: camif debug info
|
||||
* @enable_csid_recovery: enable csid recovery
|
||||
* @sfe_debug: sfe debug config
|
||||
* @sfe_sensor_diag_cfg: sfe sensor diag config
|
||||
* @sfe_cache_debug: sfe cache debug info
|
||||
* @enable_req_dump: Enable request dump on HW errors
|
||||
* @per_req_reg_dump: Enable per request reg dump
|
||||
* @disable_ubwc_comp: Disable UBWC compression
|
||||
@@ -61,6 +63,7 @@ struct cam_ife_hw_mgr_debug {
|
||||
uint32_t enable_csid_recovery;
|
||||
uint32_t sfe_debug;
|
||||
uint32_t sfe_sensor_diag_cfg;
|
||||
uint32_t sfe_cache_debug[CAM_SFE_HW_NUM_MAX];
|
||||
bool enable_req_dump;
|
||||
bool per_req_reg_dump;
|
||||
bool disable_ubwc_comp;
|
||||
@@ -123,8 +126,11 @@ struct cam_sfe_scratch_buf_cfg {
|
||||
* resources
|
||||
* @is_sfe_shdr: indicate if stream is for SFE sHDR
|
||||
* @is_sfe_fs: indicate if stream is for inline SFE FS
|
||||
* @dump_on_flush Set if reg dump triggered on flush
|
||||
* @dump_on_error Set if reg dump triggered on error
|
||||
* @dump_on_flush: Set if reg dump triggered on flush
|
||||
* @dump_on_error: Set if reg dump triggered on error
|
||||
* @sys_cache_usage: Per context sys cache usage
|
||||
* The corresponding index will be set
|
||||
* for the cache type
|
||||
*
|
||||
*/
|
||||
struct cam_ife_hw_mgr_ctx_flags {
|
||||
@@ -144,6 +150,7 @@ struct cam_ife_hw_mgr_ctx_flags {
|
||||
bool is_sfe_fs;
|
||||
bool dump_on_flush;
|
||||
bool dump_on_error;
|
||||
bool sys_cache_usage[CAM_LLCC_MAX];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -260,6 +267,19 @@ struct cam_isp_bus_hw_caps {
|
||||
bool support_consumed_addr;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_isp_sys_cache_info:
|
||||
*
|
||||
* @Brief: ISP Bus sys cache info
|
||||
*
|
||||
* @type: Cache type
|
||||
* @scid: Cache slice ID
|
||||
*/
|
||||
struct cam_isp_sys_cache_info {
|
||||
enum cam_sys_cache_config_types type;
|
||||
int32_t scid;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_ife_hw_mgr - IFE HW Manager
|
||||
*
|
||||
@@ -292,23 +312,26 @@ struct cam_ife_hw_mgr {
|
||||
struct cam_hw_intf *sfe_devices[CAM_SFE_HW_NUM_MAX];
|
||||
struct cam_soc_reg_map *cdm_reg_map[CAM_IFE_HW_NUM_MAX];
|
||||
|
||||
struct mutex ctx_mutex;
|
||||
atomic_t active_ctx_cnt;
|
||||
struct list_head free_ctx_list;
|
||||
struct list_head used_ctx_list;
|
||||
struct cam_ife_hw_mgr_ctx ctx_pool[CAM_IFE_CTX_MAX];
|
||||
struct mutex ctx_mutex;
|
||||
atomic_t active_ctx_cnt;
|
||||
struct list_head free_ctx_list;
|
||||
struct list_head used_ctx_list;
|
||||
struct cam_ife_hw_mgr_ctx ctx_pool[CAM_IFE_CTX_MAX];
|
||||
|
||||
struct cam_ife_csid_hw_caps csid_hw_caps[
|
||||
struct cam_ife_csid_hw_caps csid_hw_caps[
|
||||
CAM_IFE_CSID_HW_NUM_MAX];
|
||||
struct cam_vfe_hw_get_hw_cap ife_dev_caps[CAM_IFE_HW_NUM_MAX];
|
||||
struct cam_req_mgr_core_workq *workq;
|
||||
struct cam_ife_hw_mgr_debug debug_cfg;
|
||||
spinlock_t ctx_lock;
|
||||
bool hw_pid_support;
|
||||
bool csid_rup_en;
|
||||
bool csid_global_reset_en;
|
||||
struct cam_isp_bus_hw_caps isp_bus_caps;
|
||||
struct cam_isp_hw_path_port_map path_port_map;
|
||||
struct cam_vfe_hw_get_hw_cap ife_dev_caps[CAM_IFE_HW_NUM_MAX];
|
||||
struct cam_req_mgr_core_workq *workq;
|
||||
struct cam_ife_hw_mgr_debug debug_cfg;
|
||||
spinlock_t ctx_lock;
|
||||
bool hw_pid_support;
|
||||
bool csid_rup_en;
|
||||
bool csid_global_reset_en;
|
||||
struct cam_isp_bus_hw_caps isp_bus_caps;
|
||||
struct cam_isp_hw_path_port_map path_port_map;
|
||||
|
||||
uint32_t num_caches_found;
|
||||
struct cam_isp_sys_cache_info sys_cache_info[CAM_LLCC_MAX];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -157,6 +157,8 @@ enum cam_isp_hw_cmd_type {
|
||||
CAM_ISP_HW_CMD_IS_PDAF_RDI2_MUX_EN,
|
||||
CAM_ISP_HW_CMD_GET_PATH_PORT_MAP,
|
||||
CAM_ISP_HW_CMD_IFE_BUS_DEBUG_CFG,
|
||||
CAM_ISP_HW_SFE_SYS_CACHE_WM_CONFIG,
|
||||
CAM_ISP_HW_SFE_SYS_CACHE_RM_CONFIG,
|
||||
CAM_ISP_HW_CMD_MAX,
|
||||
};
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_SFE_HW_INTF_H_
|
||||
@@ -14,6 +14,12 @@
|
||||
#define SFE_RT_CDM_BASE_IDX 1
|
||||
#define CAM_SFE_HW_NUM_MAX 2
|
||||
|
||||
enum cam_sfe_core_id {
|
||||
CAM_SFE_CORE_0,
|
||||
CAM_SFE_CORE_1,
|
||||
CAM_SFE_CORE_MAX,
|
||||
};
|
||||
|
||||
enum cam_isp_hw_sfe_in {
|
||||
CAM_ISP_HW_SFE_IN_PIX,
|
||||
CAM_ISP_HW_SFE_IN_RD0,
|
||||
@@ -56,16 +62,40 @@ enum cam_sfe_bus_rd_irq_regs {
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_debug_cfg_params:
|
||||
* struct cam_sfe_generic_debug_config:
|
||||
*
|
||||
* @sfe_debug_cfg : SFE debug cfg value
|
||||
* @sfe_sensor_sel: SFE sensor sel for diag data
|
||||
*/
|
||||
struct cam_sfe_debug_cfg_params {
|
||||
struct cam_sfe_generic_debug_config {
|
||||
uint32_t sfe_debug_cfg;
|
||||
uint32_t sfe_sensor_sel;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_sys_cache_debug_config:
|
||||
*
|
||||
* @sfe_cache_dbg: SFE cache debug cfg
|
||||
*/
|
||||
|
||||
struct cam_sfe_sys_cache_debug_config {
|
||||
uint32_t sfe_cache_dbg;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* struct cam_sfe_debug_cfg_params:
|
||||
*
|
||||
* @cache_config: If the config is for cache
|
||||
*/
|
||||
struct cam_sfe_debug_cfg_params {
|
||||
bool cache_config;
|
||||
union {
|
||||
struct cam_sfe_generic_debug_config dbg_cfg;
|
||||
struct cam_sfe_sys_cache_debug_config cache_cfg;
|
||||
} u;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_bw_control_args:
|
||||
*
|
||||
@@ -122,6 +152,23 @@ struct cam_sfe_core_config_args {
|
||||
struct cam_isp_sfe_core_config core_config;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_isp_sfe_bus_sys_cache_config:
|
||||
*
|
||||
* @Brief: Based on exp order rxved from userland
|
||||
* configure sys cache for SFE WMs & RMs
|
||||
*
|
||||
* @res: SFE WM/RM Resource node
|
||||
* @use_cache: If set cache configured
|
||||
* @type: Dictates which slice ID to be used
|
||||
*
|
||||
*/
|
||||
struct cam_isp_sfe_bus_sys_cache_config {
|
||||
struct cam_isp_resource_node *res;
|
||||
bool use_cache;
|
||||
int scid;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_top_irq_evt_payload:
|
||||
*
|
||||
|
@@ -311,6 +311,7 @@ static struct cam_sfe_bus_rd_hw_info sfe680_bus_rd_hw_info = {
|
||||
.stride = 0x00000464,
|
||||
.unpacker_cfg = 0x00000468,
|
||||
.latency_buf_allocation = 0x0000047C,
|
||||
.system_cache_cfg = 0x0000049C,
|
||||
},
|
||||
/* BUS Client 1 */
|
||||
{
|
||||
@@ -321,6 +322,7 @@ static struct cam_sfe_bus_rd_hw_info sfe680_bus_rd_hw_info = {
|
||||
.stride = 0x00000504,
|
||||
.unpacker_cfg = 0x00000508,
|
||||
.latency_buf_allocation = 0x0000051C,
|
||||
.system_cache_cfg = 0x0000053C,
|
||||
},
|
||||
/* BUS Client 2 */
|
||||
{
|
||||
@@ -331,6 +333,7 @@ static struct cam_sfe_bus_rd_hw_info sfe680_bus_rd_hw_info = {
|
||||
.stride = 0x000005A4,
|
||||
.unpacker_cfg = 0x000005A8,
|
||||
.latency_buf_allocation = 0x000005BC,
|
||||
.system_cache_cfg = 0x000005DC,
|
||||
},
|
||||
},
|
||||
.num_bus_rd_resc = 3,
|
||||
|
@@ -334,6 +334,7 @@ int cam_sfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
||||
case CAM_ISP_HW_CMD_WM_CONFIG_UPDATE:
|
||||
case CAM_ISP_HW_CMD_GET_SECURE_MODE:
|
||||
case CAM_ISP_HW_CMD_QUERY_BUS_CAP:
|
||||
case CAM_ISP_HW_SFE_SYS_CACHE_WM_CONFIG:
|
||||
rc = core_info->sfe_bus_wr->hw_ops.process_cmd(
|
||||
core_info->sfe_bus_wr->bus_priv, cmd_type,
|
||||
cmd_args, arg_size);
|
||||
@@ -342,6 +343,7 @@ int cam_sfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
||||
case CAM_ISP_HW_CMD_GET_BUF_UPDATE_RM:
|
||||
case CAM_ISP_HW_CMD_BUF_UPDATE_RM:
|
||||
case CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD:
|
||||
case CAM_ISP_HW_SFE_SYS_CACHE_RM_CONFIG:
|
||||
rc = core_info->sfe_bus_rd->hw_ops.process_cmd(
|
||||
core_info->sfe_bus_rd->bus_priv, cmd_type,
|
||||
cmd_args, arg_size);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "cam_sfe_bus.h"
|
||||
@@ -90,3 +90,77 @@ int cam_sfe_bus_deinit(
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline int __cam_sfe_bus_validate_alloc_type(
|
||||
uint32_t alloc_type) {
|
||||
|
||||
if ((alloc_type >= CACHE_ALLOC_NONE) &&
|
||||
(alloc_type <= CACHE_ALLOC_TBH_ALLOC))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cam_sfe_bus_parse_cache_cfg(
|
||||
bool is_read,
|
||||
uint32_t debug_val,
|
||||
struct cam_sfe_bus_cache_dbg_cfg *dbg_cfg)
|
||||
{
|
||||
uint32_t scratch_alloc_shift = 0, buf_alloc_shift = 0;
|
||||
uint32_t scratch_cfg, buf_cfg, alloc_type;
|
||||
|
||||
if (debug_val >= DISABLE_CACHING_FOR_ALL) {
|
||||
dbg_cfg->disable_all = true;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (is_read) {
|
||||
scratch_alloc_shift = CACHE_SCRATCH_RD_ALLOC_SHIFT;
|
||||
buf_alloc_shift = CACHE_BUF_RD_ALLOC_SHIFT;
|
||||
} else {
|
||||
scratch_alloc_shift = CACHE_SCRATCH_WR_ALLOC_SHIFT;
|
||||
buf_alloc_shift = CACHE_BUF_WR_ALLOC_SHIFT;
|
||||
}
|
||||
|
||||
scratch_cfg = (debug_val >> CACHE_SCRATCH_DEBUG_SHIFT) & 0xF;
|
||||
buf_cfg = (debug_val >> CACHE_BUF_DEBUG_SHIFT) & 0xF;
|
||||
|
||||
/* Check for scratch cfg */
|
||||
if (scratch_cfg == 0xF) {
|
||||
dbg_cfg->disable_for_scratch = true;
|
||||
} else if (scratch_cfg == 1) {
|
||||
alloc_type =
|
||||
(debug_val >> scratch_alloc_shift) & 0xF;
|
||||
if (__cam_sfe_bus_validate_alloc_type(alloc_type)) {
|
||||
dbg_cfg->scratch_alloc = alloc_type;
|
||||
dbg_cfg->scratch_dbg_cfg = true;
|
||||
}
|
||||
dbg_cfg->disable_for_scratch = false;
|
||||
} else {
|
||||
/* Reset to default */
|
||||
dbg_cfg->disable_for_scratch = false;
|
||||
dbg_cfg->scratch_dbg_cfg = false;
|
||||
}
|
||||
|
||||
/* Check for buf cfg */
|
||||
if (buf_cfg == 0xF) {
|
||||
dbg_cfg->disable_for_buf = true;
|
||||
} else if (buf_cfg == 1) {
|
||||
alloc_type =
|
||||
(debug_val >> buf_alloc_shift) & 0xF;
|
||||
if (__cam_sfe_bus_validate_alloc_type(alloc_type)) {
|
||||
dbg_cfg->buf_alloc = alloc_type;
|
||||
dbg_cfg->buf_dbg_cfg = true;
|
||||
}
|
||||
dbg_cfg->disable_for_buf = false;
|
||||
} else {
|
||||
/* Reset to default */
|
||||
dbg_cfg->disable_for_buf = false;
|
||||
dbg_cfg->buf_dbg_cfg = false;
|
||||
}
|
||||
|
||||
/* Reset to default */
|
||||
dbg_cfg->disable_all = false;
|
||||
|
||||
end:
|
||||
return;
|
||||
}
|
||||
|
@@ -74,6 +74,8 @@ struct cam_sfe_bus_rd_common_data {
|
||||
cam_hw_mgr_event_cb_func event_cb;
|
||||
bool err_irq_subscribe;
|
||||
uint32_t sfe_debug_cfg;
|
||||
|
||||
struct cam_sfe_bus_cache_dbg_cfg cache_dbg_cfg;
|
||||
};
|
||||
|
||||
struct cam_sfe_bus_rd_rm_resource_data {
|
||||
@@ -94,6 +96,9 @@ struct cam_sfe_bus_rd_rm_resource_data {
|
||||
uint32_t en_cfg;
|
||||
uint32_t img_addr;
|
||||
uint32_t input_if_cmd;
|
||||
bool enable_caching;
|
||||
uint32_t cache_cfg;
|
||||
uint32_t current_scid;
|
||||
};
|
||||
|
||||
struct cam_sfe_bus_rd_data {
|
||||
@@ -398,6 +403,9 @@ static int cam_sfe_bus_acquire_rm(
|
||||
cam_sfe_bus_get_unpacker_fmt(unpacker_fmt);
|
||||
rsrc_data->latency_buf_allocation =
|
||||
BUS_RD_DEFAULT_LATENCY_BUF_ALLOC;
|
||||
rsrc_data->enable_caching = false;
|
||||
/* Default register value */
|
||||
rsrc_data->cache_cfg = 0x20;
|
||||
|
||||
*rm_res = rm_res_local;
|
||||
|
||||
@@ -472,6 +480,7 @@ static int cam_sfe_bus_stop_rm(struct cam_isp_resource_node *rm_res)
|
||||
cam_io_w_mb(0x0, common_data->mem_base + rsrc_data->hw_regs->cfg);
|
||||
|
||||
rm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
|
||||
rsrc_data->enable_caching = false;
|
||||
|
||||
CAM_DBG(CAM_SFE, "SFE:%d RM:%d stopped",
|
||||
rsrc_data->common_data->core_index, rsrc_data->index);
|
||||
@@ -1133,11 +1142,13 @@ static int cam_sfe_bus_rd_config_rm(void *priv, void *cmd_args,
|
||||
struct cam_isp_hw_get_cmd_update *update_buf;
|
||||
struct cam_sfe_bus_rd_data *sfe_bus_rd_data = NULL;
|
||||
struct cam_sfe_bus_rd_rm_resource_data *rm_data = NULL;
|
||||
struct cam_sfe_bus_cache_dbg_cfg *cache_dbg_cfg = NULL;
|
||||
uint32_t width = 0, height = 0, stride = 0;
|
||||
uint32_t i;
|
||||
|
||||
bus_priv = (struct cam_sfe_bus_rd_priv *) priv;
|
||||
update_buf = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||
cache_dbg_cfg = &bus_priv->common_data.cache_dbg_cfg;
|
||||
|
||||
sfe_bus_rd_data = (struct cam_sfe_bus_rd_data *)
|
||||
update_buf->res->res_priv;
|
||||
@@ -1170,6 +1181,25 @@ static int cam_sfe_bus_rd_config_rm(void *priv, void *cmd_args,
|
||||
rm_data->unpacker_cfg, &rm_data->width);
|
||||
rm_data->height = height;
|
||||
|
||||
rm_data->cache_cfg = 0x20;
|
||||
if ((!cache_dbg_cfg->disable_for_scratch) &&
|
||||
(rm_data->enable_caching)) {
|
||||
rm_data->cache_cfg =
|
||||
rm_data->current_scid << 8;
|
||||
rm_data->cache_cfg |= (3 << 4);
|
||||
if (cache_dbg_cfg->scratch_dbg_cfg)
|
||||
rm_data->cache_cfg |= cache_dbg_cfg->scratch_alloc;
|
||||
else
|
||||
rm_data->cache_cfg |= CACHE_ALLOC_FORGET;
|
||||
}
|
||||
|
||||
cam_io_w_mb(rm_data->cache_cfg,
|
||||
rm_data->common_data->mem_base +
|
||||
rm_data->hw_regs->system_cache_cfg);
|
||||
CAM_DBG(CAM_SFE, "SFE:%d RM:%d cache_cfg:0x%x",
|
||||
rm_data->common_data->core_index,
|
||||
rm_data->index, rm_data->cache_cfg);
|
||||
|
||||
cam_io_w_mb(rm_data->width,
|
||||
rm_data->common_data->mem_base +
|
||||
rm_data->hw_regs->buf_width);
|
||||
@@ -1213,6 +1243,7 @@ static int cam_sfe_bus_rd_update_rm(void *priv, void *cmd_args,
|
||||
struct cam_sfe_bus_rd_data *sfe_bus_rd_data = NULL;
|
||||
struct cam_sfe_bus_rd_rm_resource_data *rm_data = NULL;
|
||||
struct cam_cdm_utils_ops *cdm_util_ops;
|
||||
struct cam_sfe_bus_cache_dbg_cfg *cache_dbg_cfg = NULL;
|
||||
uint32_t *reg_val_pair;
|
||||
uint32_t num_regval_pairs = 0;
|
||||
uint32_t width = 0, height = 0, stride = 0;
|
||||
@@ -1220,6 +1251,7 @@ static int cam_sfe_bus_rd_update_rm(void *priv, void *cmd_args,
|
||||
|
||||
bus_priv = (struct cam_sfe_bus_rd_priv *) priv;
|
||||
update_buf = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||
cache_dbg_cfg = &bus_priv->common_data.cache_dbg_cfg;
|
||||
|
||||
sfe_bus_rd_data = (struct cam_sfe_bus_rd_data *)
|
||||
update_buf->res->res_priv;
|
||||
@@ -1270,6 +1302,42 @@ static int cam_sfe_bus_rd_update_rm(void *priv, void *cmd_args,
|
||||
rm_data->unpacker_cfg, &rm_data->width);
|
||||
rm_data->height = height;
|
||||
|
||||
rm_data->cache_cfg = 0x20;
|
||||
if (rm_data->enable_caching) {
|
||||
if ((cache_dbg_cfg->disable_for_scratch) &&
|
||||
(update_buf->use_scratch_cfg))
|
||||
goto skip_cache_cfg;
|
||||
|
||||
if ((cache_dbg_cfg->disable_for_buf) &&
|
||||
(!update_buf->use_scratch_cfg))
|
||||
goto skip_cache_cfg;
|
||||
|
||||
rm_data->cache_cfg =
|
||||
rm_data->current_scid << 8;
|
||||
rm_data->cache_cfg |= (3 << 4);
|
||||
if ((update_buf->use_scratch_cfg) &&
|
||||
(cache_dbg_cfg->scratch_dbg_cfg)) {
|
||||
rm_data->cache_cfg |= cache_dbg_cfg->scratch_alloc;
|
||||
} else if ((!update_buf->use_scratch_cfg) &&
|
||||
(cache_dbg_cfg->buf_dbg_cfg)) {
|
||||
rm_data->cache_cfg |= cache_dbg_cfg->buf_alloc;
|
||||
} else {
|
||||
if (update_buf->use_scratch_cfg)
|
||||
rm_data->cache_cfg |= CACHE_ALLOC_FORGET;
|
||||
else
|
||||
rm_data->cache_cfg |= CACHE_ALLOC_DEALLOC;
|
||||
}
|
||||
}
|
||||
|
||||
skip_cache_cfg:
|
||||
|
||||
CAM_SFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
rm_data->hw_regs->system_cache_cfg,
|
||||
rm_data->cache_cfg);
|
||||
CAM_DBG(CAM_SFE, "SFE:%d RM:%d cache_cfg:0x%x",
|
||||
rm_data->common_data->core_index,
|
||||
rm_data->index, reg_val_pair[j-1]);
|
||||
|
||||
CAM_SFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
rm_data->hw_regs->buf_width, rm_data->width);
|
||||
CAM_SFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
@@ -1336,6 +1404,45 @@ static int cam_sfe_bus_deinit_hw(void *hw_priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_sfe_bus_rd_cache_config(void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
int i;
|
||||
struct cam_sfe_bus_rd_priv *bus_priv;
|
||||
struct cam_isp_sfe_bus_sys_cache_config *cache_cfg;
|
||||
struct cam_sfe_bus_rd_data *sfe_bus_rd_data = NULL;
|
||||
struct cam_sfe_bus_rd_rm_resource_data *rm_data = NULL;
|
||||
|
||||
bus_priv = (struct cam_sfe_bus_rd_priv *)priv;
|
||||
cache_cfg = (struct cam_isp_sfe_bus_sys_cache_config *)cmd_args;
|
||||
|
||||
sfe_bus_rd_data = (struct cam_sfe_bus_rd_data *)
|
||||
cache_cfg->res->res_priv;
|
||||
|
||||
if (!sfe_bus_rd_data) {
|
||||
CAM_ERR(CAM_SFE, "Invalid data");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bus_priv->common_data.cache_dbg_cfg.disable_all)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < sfe_bus_rd_data->num_rm; i++) {
|
||||
rm_data = (struct cam_sfe_bus_rd_rm_resource_data *)
|
||||
sfe_bus_rd_data->rm_res[i]->res_priv;
|
||||
rm_data->enable_caching = cache_cfg->use_cache;
|
||||
rm_data->current_scid = cache_cfg->scid;
|
||||
|
||||
CAM_DBG(CAM_SFE, "SFE:%d RM:%d cache_enable:%s scid:%u",
|
||||
rm_data->common_data->core_index,
|
||||
rm_data->index,
|
||||
(rm_data->enable_caching ? "true" : "false"),
|
||||
rm_data->current_scid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_sfe_bus_rd_set_debug_cfg(
|
||||
void *priv, void *cmd_args)
|
||||
{
|
||||
@@ -1345,11 +1452,17 @@ static int cam_sfe_bus_rd_set_debug_cfg(
|
||||
|
||||
debug_cfg = (struct cam_sfe_debug_cfg_params *)cmd_args;
|
||||
|
||||
bus_priv->common_data.sfe_debug_cfg = debug_cfg->sfe_debug_cfg;
|
||||
if (debug_cfg->cache_config)
|
||||
cam_sfe_bus_parse_cache_cfg(true,
|
||||
debug_cfg->u.cache_cfg.sfe_cache_dbg,
|
||||
&bus_priv->common_data.cache_dbg_cfg);
|
||||
else
|
||||
bus_priv->common_data.sfe_debug_cfg =
|
||||
debug_cfg->u.dbg_cfg.sfe_debug_cfg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int cam_sfe_bus_rd_process_cmd(
|
||||
void *priv, uint32_t cmd_type,
|
||||
void *cmd_args, uint32_t arg_size)
|
||||
@@ -1379,6 +1492,9 @@ static int cam_sfe_bus_rd_process_cmd(
|
||||
case CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG:
|
||||
rc = cam_sfe_bus_rd_set_debug_cfg(priv, cmd_args);
|
||||
break;
|
||||
case CAM_ISP_HW_SFE_SYS_CACHE_RM_CONFIG:
|
||||
rc = cam_sfe_bus_rd_cache_config(priv, cmd_args, arg_size);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR_RATE_LIMIT(CAM_SFE,
|
||||
"Invalid SFE BUS RD command type: %d",
|
||||
@@ -1397,6 +1513,7 @@ int cam_sfe_bus_rd_init(
|
||||
struct cam_sfe_bus **sfe_bus)
|
||||
{
|
||||
int i, rc = 0;
|
||||
struct cam_sfe_soc_private *soc_private;
|
||||
struct cam_sfe_bus_rd_priv *bus_priv = NULL;
|
||||
struct cam_sfe_bus *sfe_bus_local;
|
||||
struct cam_sfe_bus_rd_hw_info *bus_rd_hw_info = bus_hw_info;
|
||||
@@ -1409,6 +1526,7 @@ int cam_sfe_bus_rd_init(
|
||||
goto end;
|
||||
}
|
||||
|
||||
soc_private = soc_info->soc_private;
|
||||
sfe_bus_local = kzalloc(sizeof(struct cam_sfe_bus), GFP_KERNEL);
|
||||
if (!sfe_bus_local) {
|
||||
CAM_DBG(CAM_SFE, "Failed to alloc for sfe_bus");
|
||||
@@ -1484,6 +1602,9 @@ int cam_sfe_bus_rd_init(
|
||||
*sfe_bus = sfe_bus_local;
|
||||
bus_priv->common_data.sfe_debug_cfg = 0;
|
||||
|
||||
/* Remove after sys cache verification */
|
||||
bus_priv->common_data.cache_dbg_cfg.disable_all = true;
|
||||
|
||||
return rc;
|
||||
|
||||
deinit_sfe_bus_rd:
|
||||
|
@@ -46,6 +46,7 @@ struct cam_sfe_bus_rd_reg_offset_bus_client {
|
||||
uint32_t stride;
|
||||
uint32_t unpacker_cfg;
|
||||
uint32_t latency_buf_allocation;
|
||||
uint32_t system_cache_cfg;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -93,6 +93,7 @@ struct cam_sfe_bus_wr_common_data {
|
||||
cam_hw_mgr_event_cb_func event_cb;
|
||||
|
||||
uint32_t sfe_debug_cfg;
|
||||
struct cam_sfe_bus_cache_dbg_cfg cache_dbg_cfg;
|
||||
};
|
||||
|
||||
struct cam_sfe_wr_scratch_buf_info {
|
||||
@@ -132,6 +133,10 @@ struct cam_sfe_bus_wr_wm_resource_data {
|
||||
|
||||
uint32_t acquired_width;
|
||||
uint32_t acquired_height;
|
||||
|
||||
bool enable_caching;
|
||||
uint32_t cache_cfg;
|
||||
int32_t current_scid;
|
||||
};
|
||||
|
||||
struct cam_sfe_bus_wr_comp_grp_data {
|
||||
@@ -591,6 +596,7 @@ static int cam_sfe_bus_acquire_wm(
|
||||
rsrc_data->acquired_width = out_port_info->width;
|
||||
rsrc_data->acquired_height = out_port_info->height;
|
||||
rsrc_data->is_dual = is_dual;
|
||||
rsrc_data->enable_caching = false;
|
||||
|
||||
/* RDI0-2 line based mode by default */
|
||||
if (sfe_out_res_id == CAM_SFE_BUS_SFE_OUT_RDI0 ||
|
||||
@@ -783,6 +789,7 @@ static int cam_sfe_bus_stop_wm(struct cam_isp_resource_node *wm_res)
|
||||
wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
|
||||
rsrc_data->init_cfg_done = false;
|
||||
rsrc_data->hfr_cfg_done = false;
|
||||
rsrc_data->enable_caching = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1007,7 +1014,7 @@ static int cam_sfe_bus_release_comp_grp(
|
||||
if (in_rsrc_data->acquire_dev_cnt == 0) {
|
||||
list_del(&comp_grp->list);
|
||||
|
||||
in_rsrc_data->dual_slave_core = CAM_SFE_BUS_SFE_CORE_MAX;
|
||||
in_rsrc_data->dual_slave_core = CAM_SFE_CORE_MAX;
|
||||
in_rsrc_data->addr_sync_mode = 0;
|
||||
in_rsrc_data->composite_mask = 0;
|
||||
|
||||
@@ -1083,7 +1090,7 @@ static int cam_sfe_bus_wr_init_comp_grp(uint32_t index,
|
||||
|
||||
rsrc_data->comp_grp_type = index;
|
||||
rsrc_data->common_data = &bus_priv->common_data;
|
||||
rsrc_data->dual_slave_core = CAM_SFE_BUS_SFE_CORE_MAX;
|
||||
rsrc_data->dual_slave_core = CAM_SFE_CORE_MAX;
|
||||
|
||||
list_add_tail(&comp_grp->list, &bus_priv->free_comp_grp);
|
||||
|
||||
@@ -2072,6 +2079,7 @@ static int cam_sfe_bus_wr_update_wm(void *priv, void *cmd_args,
|
||||
struct cam_sfe_bus_wr_out_data *sfe_out_data = NULL;
|
||||
struct cam_cdm_utils_ops *cdm_util_ops;
|
||||
struct cam_sfe_bus_wr_wm_resource_data *wm_data = NULL;
|
||||
struct cam_sfe_bus_cache_dbg_cfg *cache_dbg_cfg = NULL;
|
||||
uint32_t *reg_val_pair;
|
||||
uint32_t num_regval_pairs = 0;
|
||||
uint32_t i, j, k, size = 0;
|
||||
@@ -2080,6 +2088,7 @@ static int cam_sfe_bus_wr_update_wm(void *priv, void *cmd_args,
|
||||
|
||||
bus_priv = (struct cam_sfe_bus_wr_priv *) priv;
|
||||
update_buf = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||
cache_dbg_cfg = &bus_priv->common_data.cache_dbg_cfg;
|
||||
|
||||
sfe_out_data = (struct cam_sfe_bus_wr_out_data *)
|
||||
update_buf->res->res_priv;
|
||||
@@ -2121,6 +2130,37 @@ static int cam_sfe_bus_wr_update_wm(void *priv, void *cmd_args,
|
||||
wm_data->index, sfe_out_data->wm_res[i].res_name,
|
||||
reg_val_pair[j-1]);
|
||||
|
||||
wm_data->cache_cfg = 0;
|
||||
if (wm_data->enable_caching) {
|
||||
if ((cache_dbg_cfg->disable_for_scratch) &&
|
||||
(update_buf->use_scratch_cfg))
|
||||
goto skip_cache_cfg;
|
||||
|
||||
if ((cache_dbg_cfg->disable_for_buf) &&
|
||||
(!update_buf->use_scratch_cfg))
|
||||
goto skip_cache_cfg;
|
||||
|
||||
wm_data->cache_cfg =
|
||||
wm_data->current_scid << 8;
|
||||
wm_data->cache_cfg |= 3 << 4;
|
||||
if ((update_buf->use_scratch_cfg) &&
|
||||
(cache_dbg_cfg->scratch_dbg_cfg))
|
||||
wm_data->cache_cfg |= cache_dbg_cfg->scratch_alloc;
|
||||
else if ((!update_buf->use_scratch_cfg) &&
|
||||
(cache_dbg_cfg->buf_dbg_cfg))
|
||||
wm_data->cache_cfg |= cache_dbg_cfg->buf_alloc;
|
||||
else
|
||||
wm_data->cache_cfg |= CACHE_ALLOC_ALLOC;
|
||||
}
|
||||
|
||||
skip_cache_cfg:
|
||||
|
||||
CAM_SFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
wm_data->hw_regs->system_cache_cfg,
|
||||
wm_data->cache_cfg);
|
||||
CAM_DBG(CAM_SFE, "WM:%d cache_cfg:0x%x",
|
||||
wm_data->index, reg_val_pair[j-1]);
|
||||
|
||||
val = (wm_data->height << 16) | wm_data->width;
|
||||
CAM_SFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
wm_data->hw_regs->image_cfg_0, val);
|
||||
@@ -2239,12 +2279,14 @@ static int cam_sfe_bus_wr_config_wm(void *priv, void *cmd_args,
|
||||
struct cam_isp_hw_get_cmd_update *update_buf;
|
||||
struct cam_sfe_bus_wr_out_data *sfe_out_data = NULL;
|
||||
struct cam_sfe_bus_wr_wm_resource_data *wm_data = NULL;
|
||||
struct cam_sfe_bus_cache_dbg_cfg *cache_dbg_cfg = NULL;
|
||||
uint32_t i, k;
|
||||
uint32_t frame_inc = 0, val;
|
||||
uint32_t loop_size = 0, stride = 0, slice_h = 0;
|
||||
|
||||
bus_priv = (struct cam_sfe_bus_wr_priv *) priv;
|
||||
update_buf = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||
cache_dbg_cfg = &bus_priv->common_data.cache_dbg_cfg;
|
||||
|
||||
sfe_out_data = (struct cam_sfe_bus_wr_out_data *)
|
||||
update_buf->res->res_priv;
|
||||
@@ -2328,6 +2370,24 @@ static int cam_sfe_bus_wr_config_wm(void *priv, void *cmd_args,
|
||||
CAM_DBG(CAM_SFE, "WM:%d frame_inc %d",
|
||||
wm_data->index, frame_inc);
|
||||
|
||||
wm_data->cache_cfg = 0;
|
||||
if ((!cache_dbg_cfg->disable_for_scratch) &&
|
||||
(wm_data->enable_caching)) {
|
||||
wm_data->cache_cfg =
|
||||
wm_data->current_scid << 8;
|
||||
wm_data->cache_cfg |= 3 << 4;
|
||||
if (cache_dbg_cfg->scratch_dbg_cfg)
|
||||
wm_data->cache_cfg |= cache_dbg_cfg->scratch_alloc;
|
||||
else
|
||||
wm_data->cache_cfg |= CACHE_ALLOC_ALLOC;
|
||||
}
|
||||
|
||||
cam_io_w_mb(wm_data->cache_cfg,
|
||||
wm_data->common_data->mem_base +
|
||||
wm_data->hw_regs->system_cache_cfg);
|
||||
CAM_DBG(CAM_SFE, "WM:%d cache_cfg:0x%x",
|
||||
wm_data->index, wm_data->cache_cfg);
|
||||
|
||||
/* enable the WM */
|
||||
cam_io_w_mb(wm_data->en_cfg,
|
||||
wm_data->common_data->mem_base +
|
||||
@@ -2596,6 +2656,47 @@ static int __cam_sfe_bus_wr_process_cmd(
|
||||
cmd_args, arg_size);
|
||||
}
|
||||
|
||||
static int cam_sfe_bus_wr_cache_config(
|
||||
void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
int i;
|
||||
struct cam_sfe_bus_wr_priv *bus_priv;
|
||||
struct cam_isp_sfe_bus_sys_cache_config *cache_cfg;
|
||||
struct cam_sfe_bus_wr_out_data *sfe_out_data = NULL;
|
||||
struct cam_sfe_bus_wr_wm_resource_data *wm_data = NULL;
|
||||
|
||||
|
||||
bus_priv = (struct cam_sfe_bus_wr_priv *)priv;
|
||||
cache_cfg = (struct cam_isp_sfe_bus_sys_cache_config *)cmd_args;
|
||||
|
||||
sfe_out_data = (struct cam_sfe_bus_wr_out_data *)
|
||||
cache_cfg->res->res_priv;
|
||||
|
||||
if (!sfe_out_data) {
|
||||
CAM_ERR(CAM_SFE, "Invalid data");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bus_priv->common_data.cache_dbg_cfg.disable_all)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < sfe_out_data->num_wm; i++) {
|
||||
wm_data = (struct cam_sfe_bus_wr_wm_resource_data *)
|
||||
sfe_out_data->wm_res[i].res_priv;
|
||||
wm_data->enable_caching = cache_cfg->use_cache;
|
||||
wm_data->current_scid = cache_cfg->scid;
|
||||
|
||||
CAM_DBG(CAM_SFE, "SFE:%d WM:%d cache_enable:%s scid:%u",
|
||||
wm_data->common_data->core_index,
|
||||
wm_data->index,
|
||||
(wm_data->enable_caching ? "true" : "false"),
|
||||
wm_data->current_scid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_sfe_bus_wr_set_debug_cfg(
|
||||
void *priv, void *cmd_args)
|
||||
{
|
||||
@@ -2605,7 +2706,14 @@ static int cam_sfe_bus_wr_set_debug_cfg(
|
||||
|
||||
debug_cfg = (struct cam_sfe_debug_cfg_params *)cmd_args;
|
||||
|
||||
bus_priv->common_data.sfe_debug_cfg = debug_cfg->sfe_debug_cfg;
|
||||
if (debug_cfg->cache_config)
|
||||
cam_sfe_bus_parse_cache_cfg(false,
|
||||
debug_cfg->u.cache_cfg.sfe_cache_dbg,
|
||||
&bus_priv->common_data.cache_dbg_cfg);
|
||||
else
|
||||
bus_priv->common_data.sfe_debug_cfg =
|
||||
debug_cfg->u.dbg_cfg.sfe_debug_cfg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2667,6 +2775,9 @@ static int cam_sfe_bus_wr_process_cmd(
|
||||
rc = 0;
|
||||
}
|
||||
break;
|
||||
case CAM_ISP_HW_SFE_SYS_CACHE_WM_CONFIG:
|
||||
rc = cam_sfe_bus_wr_cache_config(priv, cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG:
|
||||
rc = cam_sfe_bus_wr_set_debug_cfg(priv, cmd_args);
|
||||
break;
|
||||
@@ -2687,6 +2798,7 @@ int cam_sfe_bus_wr_init(
|
||||
struct cam_sfe_bus **sfe_bus)
|
||||
{
|
||||
int i, rc = 0;
|
||||
struct cam_sfe_soc_private *soc_private;
|
||||
struct cam_sfe_bus_wr_priv *bus_priv = NULL;
|
||||
struct cam_sfe_bus *sfe_bus_local;
|
||||
struct cam_sfe_bus_wr_hw_info *hw_info = bus_hw_info;
|
||||
@@ -2701,6 +2813,7 @@ int cam_sfe_bus_wr_init(
|
||||
goto end;
|
||||
}
|
||||
|
||||
soc_private = soc_info->soc_private;
|
||||
sfe_bus_local = kzalloc(sizeof(struct cam_sfe_bus), GFP_KERNEL);
|
||||
if (!sfe_bus_local) {
|
||||
CAM_DBG(CAM_SFE, "Failed to alloc for sfe_bus");
|
||||
@@ -2810,8 +2923,12 @@ int cam_sfe_bus_wr_init(
|
||||
sfe_bus_local->bottom_half_handler = NULL;
|
||||
sfe_bus_local->hw_ops.process_cmd = __cam_sfe_bus_wr_process_cmd;
|
||||
bus_priv->bus_irq_handle = 0;
|
||||
bus_priv->common_data.sfe_debug_cfg = 0;
|
||||
*sfe_bus = sfe_bus_local;
|
||||
|
||||
/* Remove after sys cache verification */
|
||||
bus_priv->common_data.cache_dbg_cfg.disable_all = true;
|
||||
|
||||
CAM_DBG(CAM_SFE, "Exit");
|
||||
return rc;
|
||||
|
||||
|
@@ -21,11 +21,22 @@
|
||||
#define ALIGNUP(value, alignment) \
|
||||
((value + alignment - 1) / alignment * alignment)
|
||||
|
||||
enum cam_sfe_bus_sfe_core_id {
|
||||
CAM_SFE_BUS_SFE_CORE_0,
|
||||
CAM_SFE_BUS_SFE_CORE_1,
|
||||
CAM_SFE_BUS_SFE_CORE_MAX,
|
||||
};
|
||||
#define CACHE_ALLOC_NONE 0
|
||||
#define CACHE_ALLOC_ALLOC 1
|
||||
#define CACHE_ALLOC_ALLOC_CLEAN 2
|
||||
#define CACHE_ALLOC_ALLOC_TRANS 3
|
||||
#define CACHE_ALLOC_CLEAN 5
|
||||
#define CACHE_ALLOC_DEALLOC 6
|
||||
#define CACHE_ALLOC_FORGET 7
|
||||
#define CACHE_ALLOC_TBH_ALLOC 8
|
||||
|
||||
#define DISABLE_CACHING_FOR_ALL 0xFFFFFF
|
||||
#define CACHE_SCRATCH_RD_ALLOC_SHIFT 0
|
||||
#define CACHE_SCRATCH_WR_ALLOC_SHIFT 4
|
||||
#define CACHE_SCRATCH_DEBUG_SHIFT 8
|
||||
#define CACHE_BUF_RD_ALLOC_SHIFT 12
|
||||
#define CACHE_BUF_WR_ALLOC_SHIFT 16
|
||||
#define CACHE_BUF_DEBUG_SHIFT 20
|
||||
|
||||
enum cam_sfe_bus_plane_type {
|
||||
PLANE_Y,
|
||||
@@ -39,6 +50,31 @@ enum cam_sfe_bus_type {
|
||||
BUS_TYPE_SFE_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_bus_cache_dbg_cfg:
|
||||
*
|
||||
* @Brief: Bus cache debug cfg
|
||||
*
|
||||
* @disable_all: Disable caching for all [scratch/snapshot]
|
||||
* @disable_for_scratch: Disable caching for scratch
|
||||
* @scratch_dbg_cfg: Scratch alloc configured
|
||||
* @scratch_alloc: Alloc type for scratch
|
||||
* @disable_for_buf: Disable caching for buffer
|
||||
* @buf_dbg_cfg: Buf alloc configured
|
||||
* @buf_alloc: Alloc type for actual buffer
|
||||
*/
|
||||
struct cam_sfe_bus_cache_dbg_cfg {
|
||||
bool disable_all;
|
||||
|
||||
bool disable_for_scratch;
|
||||
bool scratch_dbg_cfg;
|
||||
uint32_t scratch_alloc;
|
||||
|
||||
bool disable_for_buf;
|
||||
bool buf_dbg_cfg;
|
||||
uint32_t buf_alloc;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_sfe_bus:
|
||||
*
|
||||
@@ -98,4 +134,20 @@ int cam_sfe_bus_deinit(
|
||||
int bus_type,
|
||||
struct cam_sfe_bus **sfe_bus);
|
||||
|
||||
|
||||
/*
|
||||
* cam_sfe_bus_parse_cache_cfg()
|
||||
*
|
||||
* @Brief: Parse SFE debug config
|
||||
*
|
||||
* @is_read: If set it's RM
|
||||
* @debug_val: Debug val to be parsed
|
||||
* @dbg_cfg: Debug cfg of RM/WM
|
||||
*
|
||||
*/
|
||||
void cam_sfe_bus_parse_cache_cfg(
|
||||
bool is_read,
|
||||
uint32_t debug_val,
|
||||
struct cam_sfe_bus_cache_dbg_cfg *dbg_cfg);
|
||||
|
||||
#endif /* _CAM_SFE_BUS_ */
|
||||
|
@@ -926,8 +926,10 @@ static int cam_sfe_set_top_debug(
|
||||
struct cam_sfe_debug_cfg_params *debug_cfg;
|
||||
|
||||
debug_cfg = (struct cam_sfe_debug_cfg_params *)cmd_args;
|
||||
top_priv->sfe_debug_cfg = debug_cfg->sfe_debug_cfg;
|
||||
top_priv->sensor_sel_diag_cfg = debug_cfg->sfe_sensor_sel;
|
||||
if (!debug_cfg->cache_config) {
|
||||
top_priv->sfe_debug_cfg = debug_cfg->u.dbg_cfg.sfe_debug_cfg;
|
||||
top_priv->sensor_sel_diag_cfg = debug_cfg->u.dbg_cfg.sfe_sensor_sel;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user