Merge "msm: camera: isp: Add support for SFE sys cache config" into camera-kernel.lnx.5.0

This commit is contained in:
Savita Patted
2021-05-03 20:23:26 -07:00
zatwierdzone przez Gerrit - the friendly Code Review server
18 zmienionych plików z 1203 dodań i 40 usunięć

Wyświetl plik

@@ -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;

Wyświetl plik

@@ -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,
};

Wyświetl plik

@@ -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)
{

Wyświetl plik

@@ -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;

Wyświetl plik

@@ -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);

Wyświetl plik

@@ -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_ */

Wyświetl plik

@@ -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;
}

Wyświetl plik

@@ -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];
};
/**

Wyświetl plik

@@ -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,
};

Wyświetl plik

@@ -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:
*

Wyświetl plik

@@ -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,

Wyświetl plik

@@ -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);

Wyświetl plik

@@ -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;
}

Wyświetl plik

@@ -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:

Wyświetl plik

@@ -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;
};
/*

Wyświetl plik

@@ -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;

Wyświetl plik

@@ -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_ */

Wyświetl plik

@@ -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;
}