Merge 1510d5b82f on remote branch

Change-Id: I5c824f5427d765864701d3784d66657400801d14
This commit is contained in:
Linux Build Service Account 2021-09-17 03:04:13 -07:00
commit 702b632d40
34 changed files with 1274 additions and 57 deletions

View file

@ -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.
*/
#include <linux/delay.h>
@ -180,10 +180,12 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
(struct cam_cdm_bl_cb_request_entry *)data;
client_idx = CAM_CDM_GET_CLIENT_IDX(node->client_hdl);
mutex_lock(&cdm_hw->hw_mutex);
client = core->clients[client_idx];
if ((!client) || (client->handle != node->client_hdl)) {
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client,
node->client_hdl);
mutex_unlock(&cdm_hw->hw_mutex);
return;
}
cam_cdm_get_client_refcount(client);
@ -202,6 +204,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
}
mutex_unlock(&client->lock);
cam_cdm_put_client_refcount(client);
mutex_unlock(&cdm_hw->hw_mutex);
return;
} else if (status == CAM_CDM_CB_STATUS_HW_RESET_DONE ||
status == CAM_CDM_CB_STATUS_HW_FLUSH ||
@ -217,7 +220,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
if ((!client) || (client->handle != node->client_hdl)) {
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client,
node->client_hdl);
return;
return;
}
cam_cdm_get_client_refcount(client);
mutex_lock(&client->lock);
@ -239,6 +242,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
for (i = 0; i < CAM_PER_CDM_MAX_REGISTERED_CLIENTS; i++) {
if (core->clients[i] != NULL) {
mutex_lock(&cdm_hw->hw_mutex);
client = core->clients[i];
cam_cdm_get_client_refcount(client);
mutex_lock(&client->lock);
@ -261,6 +265,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
}
mutex_unlock(&client->lock);
cam_cdm_put_client_refcount(client);
mutex_unlock(&cdm_hw->hw_mutex);
}
}
}
@ -320,35 +325,34 @@ int cam_cdm_stream_ops_internal(void *hw_priv,
return -EINVAL;
core = (struct cam_cdm *)cdm_hw->core_info;
mutex_lock(&cdm_hw->hw_mutex);
client_idx = CAM_CDM_GET_CLIENT_IDX(*handle);
client = core->clients[client_idx];
if (!client) {
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client, *handle);
mutex_unlock(&cdm_hw->hw_mutex);
return -EINVAL;
}
cam_cdm_get_client_refcount(client);
if (*handle != client->handle) {
CAM_ERR(CAM_CDM, "client id given handle=%x invalid", *handle);
cam_cdm_put_client_refcount(client);
return -EINVAL;
rc = -EINVAL;
goto end;
}
if (operation == true) {
if (true == client->stream_on) {
CAM_ERR(CAM_CDM,
"Invalid CDM client is already streamed ON");
cam_cdm_put_client_refcount(client);
return rc;
goto end;
}
} else {
if (client->stream_on == false) {
CAM_ERR(CAM_CDM,
"Invalid CDM client is already streamed Off");
cam_cdm_put_client_refcount(client);
return rc;
goto end;
}
}
mutex_lock(&cdm_hw->hw_mutex);
if (operation == true) {
if (!cdm_hw->open_count) {
struct cam_ahb_vote ahb_vote;

View file

@ -6098,7 +6098,7 @@ static int cam_isp_context_dump_requests(void *data,
static int cam_isp_context_handle_message(void *context,
uint32_t msg_type, uint32_t *data)
{
int rc = 0;
int rc = -EINVAL;
struct cam_hw_cmd_args hw_cmd_args;
struct cam_isp_hw_cmd_args isp_hw_cmd_args;
struct cam_context *ctx = (struct cam_context *)context;

View file

@ -319,9 +319,10 @@ static int cam_tfe_hw_mgr_get_clock_rate(
continue;
hw_intf = isp_hw_res->hw_res[i]->hw_intf;
CAM_DBG(CAM_ISP, "hw type %d hw index:%d",
hw_intf->hw_type, hw_intf->hw_idx);
if (hw_intf && hw_intf->hw_ops.process_cmd) {
CAM_DBG(CAM_ISP, "hw type %d hw index:%d",
hw_intf->hw_type, hw_intf->hw_idx);
rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv,
CAM_ISP_HW_CMD_GET_CLOCK_RATE,
@ -343,7 +344,7 @@ static int cam_tfe_hw_mgr_update_clock_rate(
uint32_t *updated_clock_rate)
{
int i;
int rc = 0;
int rc = -EINVAL;
struct cam_hw_intf *hw_intf;
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
@ -351,29 +352,33 @@ static int cam_tfe_hw_mgr_update_clock_rate(
continue;
hw_intf = isp_hw_res->hw_res[i]->hw_intf;
CAM_DBG(CAM_ISP, "hw type %d hw index:%d",
hw_intf->hw_type, hw_intf->hw_idx);
if (hw_intf && hw_intf->hw_ops.process_cmd) {
CAM_DBG(CAM_ISP, "hw type %d hw index:%d",
hw_intf->hw_type, hw_intf->hw_idx);
rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv,
CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE,
set_clock_rate,
sizeof(uint32_t));
if (rc) {
CAM_ERR(CAM_ISP, "Failed to get Clock rate");
CAM_ERR(CAM_ISP, "Failed to set Clock rate");
return rc;
}
}
if (hw_intf && hw_intf->hw_ops.process_cmd) {
CAM_DBG(CAM_ISP, "hw type %d hw index:%d",
hw_intf->hw_type, hw_intf->hw_idx);
rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv,
CAM_ISP_HW_CMD_GET_CLOCK_RATE,
updated_clock_rate,
sizeof(uint32_t));
if (rc) {
CAM_ERR(CAM_ISP, "Failed to get Clock rate");
CAM_ERR(CAM_ISP, "Failed to get updated clock rate");
return rc;
}
}
@ -3247,6 +3252,17 @@ static int cam_tfe_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
if (ctx->init_done && start_isp->start_only)
goto start_only;
/* set tpg debug information for top tpg */
for (i = 0; i < CAM_TOP_TPG_HW_NUM_MAX; i++) {
if (g_tfe_hw_mgr.tpg_devices[i]) {
rc = g_tfe_hw_mgr.tpg_devices[i]->hw_ops.process_cmd(
g_tfe_hw_mgr.tpg_devices[i]->hw_priv,
CAM_ISP_HW_CMD_TPG_SET_PATTERN,
&g_tfe_hw_mgr.debug_cfg.set_tpg_pattern,
sizeof(g_tfe_hw_mgr.debug_cfg.set_tpg_pattern));
}
}
list_for_each_entry(hw_mgr_res, &ctx->res_list_tfe_csid, list) {
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
if (!hw_mgr_res->hw_res[i])
@ -5808,9 +5824,10 @@ static int cam_tfe_hw_mgr_debug_register(void)
int rc = 0;
struct dentry *dbgfileptr = NULL;
g_tfe_hw_mgr.debug_cfg.set_tpg_pattern = CAM_TOP_TPG_DEFAULT_PATTERN;
dbgfileptr = debugfs_create_dir("camera_tfe", NULL);
if (!dbgfileptr) {
CAM_ERR(CAM_ISP,"DebugFS could not create directory!");
CAM_ERR(CAM_ISP, "DebugFS could not create directory!");
rc = -ENOENT;
goto end;
}
@ -5828,6 +5845,9 @@ static int cam_tfe_hw_mgr_debug_register(void)
dbgfileptr = debugfs_create_u32("enable_csid_recovery", 0644,
g_tfe_hw_mgr.debug_cfg.dentry,
&g_tfe_hw_mgr.debug_cfg.enable_csid_recovery);
dbgfileptr = debugfs_create_u32("set_tpg_pattern", 0644,
g_tfe_hw_mgr.debug_cfg.dentry,
&g_tfe_hw_mgr.debug_cfg.set_tpg_pattern);
dbgfileptr = debugfs_create_file("tfe_camif_debug", 0644,
g_tfe_hw_mgr.debug_cfg.dentry, NULL, &cam_tfe_camif_debug);
dbgfileptr = debugfs_create_u32("per_req_reg_dump", 0644,

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_TFE_HW_MGR_H_
@ -30,6 +30,7 @@
* @enable_recovery: enable recovery
* @enable_csid_recovery: enable csid recovery
* @camif_debug: enable sensor diagnosis status
* @set_tpg_pattern: tpg pattern information
* @enable_reg_dump: enable reg dump on error;
* @per_req_reg_dump: Enable per request reg dump
*
@ -40,6 +41,7 @@ struct cam_tfe_hw_mgr_debug {
uint32_t enable_recovery;
uint32_t enable_csid_recovery;
uint32_t camif_debug;
uint32_t set_tpg_pattern;
uint32_t enable_reg_dump;
uint32_t per_req_reg_dump;
};

View file

@ -1589,12 +1589,13 @@ static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_mask_addr);
cam_tasklet_stop(csid_hw->tasklet);
rc = cam_ife_csid_disable_soc_resources(soc_info);
if (rc)
CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed",
csid_hw->hw_intf->hw_idx);
cam_tasklet_stop(csid_hw->tasklet);
spin_lock_irqsave(&csid_hw->lock_state, flags);
csid_hw->device_enabled = 0;
spin_unlock_irqrestore(&csid_hw->lock_state, flags);

View file

@ -138,6 +138,7 @@ enum cam_isp_hw_cmd_type {
CAM_ISP_HW_CMD_GET_CLOCK_RATE,
CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE,
CAM_ISP_HW_DUMP_HW_SRC_CLK_RATE,
CAM_ISP_HW_CMD_TPG_SET_PATTERN,
CAM_ISP_HW_CMD_MAX,
};

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_TOP_TPG_HW_INTF_H_
@ -14,7 +14,8 @@
#define CAM_TOP_TPG_HW_NUM_MAX 3
/* Max supported number of DT for TPG */
#define CAM_TOP_TPG_MAX_SUPPORTED_DT 4
/* TPG default pattern should be color bar */
#define CAM_TOP_TPG_DEFAULT_PATTERN 0x8
/**
* enum cam_top_tpg_id - top tpg hw instance id
*/

View file

@ -1165,12 +1165,13 @@ static int cam_tfe_csid_disable_hw(struct cam_tfe_csid_hw *csid_hw)
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_mask_addr);
cam_tasklet_stop(csid_hw->tasklet);
rc = cam_tfe_csid_disable_soc_resources(soc_info);
if (rc)
CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed",
csid_hw->hw_intf->hw_idx);
cam_tasklet_stop(csid_hw->tasklet);
spin_lock_irqsave(&csid_hw->spin_lock, flags);
csid_hw->device_enabled = 0;
spin_unlock_irqrestore(&csid_hw->spin_lock, flags);

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_TOP_TPG101_H_
@ -49,6 +49,7 @@ static struct cam_top_tpg_ver1_reg_offset cam_top_tpg101_reg = {
.tpg_payload_mode_color = 0x8,
.tpg_split_en_shift = 5,
.top_mux_reg_offset = 0x1C,
.top_unicolor_bar_shift = 2,
};
struct cam_top_tpg_hw_info cam_top_tpg101_hw_info = {

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/iopoll.h>
@ -282,6 +282,19 @@ irqreturn_t cam_top_tpg_irq(int irq_num, void *data)
return IRQ_HANDLED;
}
static int cam_top_tpg_set_top_tpg_pattern(struct cam_top_tpg_hw *tpg_hw,
void *cmd_args)
{
uint32_t *top_tpg_pattern;
top_tpg_pattern = (uint32_t *) cmd_args;
tpg_hw->tpg_pattern = *top_tpg_pattern;
CAM_DBG(CAM_ISP, "TPG:%d set tpg debug value:%d",
tpg_hw->hw_intf->hw_idx, tpg_hw->tpg_pattern);
return 0;
}
static int cam_top_tpg_process_cmd(void *hw_priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
@ -301,6 +314,9 @@ static int cam_top_tpg_process_cmd(void *hw_priv,
case CAM_ISP_HW_CMD_TPG_PHY_CLOCK_UPDATE:
rc = cam_top_tpg_set_phy_clock(tpg_hw, cmd_args);
break;
case CAM_ISP_HW_CMD_TPG_SET_PATTERN:
rc = cam_top_tpg_set_top_tpg_pattern(tpg_hw, cmd_args);
break;
default:
CAM_ERR(CAM_ISP, "TPG:%d unsupported cmd:%d",
tpg_hw->hw_intf->hw_idx, cmd_type);

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_TOP_TPG_CORE_H_
@ -106,7 +106,7 @@ struct cam_top_tpg_cfg {
* @hw_info: tpg hw device information
* @tpg_info: tpg hw specific information
* @tpg_res: tpg resource
* @tpg_cfg: tpg configuration
* @tpg_pattern: tpg pattern configuration
* @clk_rate clock rate
* @lock_state lock state
* @tpg_complete tpg completion
@ -117,6 +117,7 @@ struct cam_top_tpg_hw {
struct cam_hw_info *hw_info;
struct cam_top_tpg_hw_info *tpg_info;
struct cam_isp_resource_node tpg_res;
uint32_t tpg_pattern;
uint64_t clk_rate;
spinlock_t lock_state;
struct completion tpg_complete;

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#include <linux/iopoll.h>
@ -204,6 +204,7 @@ static int cam_top_tpg_ver1_start(
struct cam_top_tpg_ver1_reg_offset *tpg_reg;
struct cam_top_tpg_cfg *tpg_data;
uint32_t i, val;
uint32_t in_format = 0;
if (!hw_priv || !start_args ||
(arg_size != sizeof(struct cam_isp_resource_node))) {
@ -244,6 +245,7 @@ static int cam_top_tpg_ver1_start(
tpg_reg->tpg_dt_0_cfg_2 + 0x10 * i);
}
/* configure one DT, infinite frames */
val = (tpg_num_dt_map[tpg_data->num_active_dts-1] <<
tpg_reg->tpg_num_dts_shift_val) | tpg_data->vc_num[0];
cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc_cfg0);
@ -260,6 +262,57 @@ static int cam_top_tpg_ver1_start(
cam_io_w_mb(0x2581F4,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc_cfg1);
/* configure tpg pattern */
in_format = tpg_data->dt_cfg[0].encode_format & 0xF;
val = in_format << tpg_reg->tpg_dt_encode_format_shift;
switch (tpg_hw->tpg_pattern) {
case 0x0:
val = val | tpg_hw->tpg_pattern;
break;
case 0x1:
val = val | tpg_hw->tpg_pattern;
break;
case 0x2:
val = val | tpg_hw->tpg_pattern;
break;
case 0x3:
val = val | tpg_hw->tpg_pattern;
break;
case 0x4:
val = val | tpg_hw->tpg_pattern;
break;
case 0x5:
val = val | tpg_hw->tpg_pattern;
break;
case 0x6:
val = val | tpg_hw->tpg_pattern;
break;
case 0x7:
val = val | tpg_hw->tpg_pattern;
break;
case 0x8:
/* unicolor bar selection */
val = 0x1 | (1 << tpg_reg->top_unicolor_bar_shift);
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_color_bar_cfg);
val = (in_format << tpg_reg->tpg_dt_encode_format_shift) |
tpg_hw->tpg_pattern;
break;
default:
/* frame with split color bar */
val = 1 << tpg_reg->tpg_split_en_shift;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_color_bar_cfg);
val = (in_format << tpg_reg->tpg_dt_encode_format_shift) |
CAM_TOP_TPG_DEFAULT_PATTERN;
break;
}
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_dt_0_cfg_2);
/* config pix pattern */
val = (1 << tpg_reg->tpg_split_en_shift);
cam_io_w_mb(tpg_data->pix_pattern, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_common_gen_cfg);

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_TOP_TPG_VER1_H_
@ -48,6 +48,7 @@ struct cam_top_tpg_ver1_reg_offset {
uint32_t tpg_payload_mode_color;
uint32_t tpg_split_en_shift;
uint32_t top_mux_reg_offset;
uint32_t top_unicolor_bar_shift;
};
int cam_top_tpg_ver1_init(struct cam_top_tpg_hw *tpg_hw);

View file

@ -142,6 +142,13 @@ static int cam_jpeg_process_next_hw_update(void *priv, void *data,
CAM_TRACE(CAM_JPEG, "Start JPEG ENC Req %llu", config_args->request_id);
/* configure jpeg hw and camnoc misr */
rc = hw_mgr->devices[dev_type][0]->hw_ops.process_cmd(
hw_mgr->devices[dev_type][0]->hw_priv,
CAM_JPEG_CMD_CONFIG_HW_MISR,
&g_jpeg_hw_mgr.camnoc_misr_test,
sizeof(g_jpeg_hw_mgr.camnoc_misr_test));
rc = hw_mgr->devices[dev_type][0]->hw_ops.start(
hw_mgr->devices[dev_type][0]->hw_priv, NULL, 0);
if (rc) {
@ -174,6 +181,7 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL;
struct crm_workq_task *task;
struct cam_jpeg_process_frame_work_data_t *wq_task_data;
struct cam_jpeg_misr_dump_args misr_args;
if (!data || !priv) {
CAM_ERR(CAM_JPEG, "Invalid data");
@ -203,8 +211,19 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
}
p_cfg_req->num_hw_entry_processed++;
CAM_DBG(CAM_JPEG, "hw entry processed %d",
p_cfg_req->num_hw_entry_processed);
CAM_DBG(CAM_JPEG, "hw entry processed %d Encoded size :%d",
p_cfg_req->num_hw_entry_processed, task_data->result_size);
misr_args.req_id = p_cfg_req->req_id;
misr_args.enable_bug = g_jpeg_hw_mgr.bug_on_misr;
CAM_DBG(CAM_JPEG, "req %lld bug is enabled for MISR :%d",
misr_args.req_id, misr_args.enable_bug);
/* dump jpeg hw and camnoc misr */
rc = hw_mgr->devices[dev_type][0]->hw_ops.process_cmd(
hw_mgr->devices[dev_type][0]->hw_priv,
CAM_JPEG_CMD_DUMP_HW_MISR_VAL, &misr_args,
sizeof(struct cam_jpeg_misr_dump_args));
if ((task_data->result_size > 0) &&
(p_cfg_req->num_hw_entry_processed <
@ -298,7 +317,6 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
p_params = (struct cam_jpeg_config_inout_param_info *)cmd_buf_kaddr;
p_params->output_size = task_data->result_size;
CAM_DBG(CAM_JPEG, "Encoded Size %d", task_data->result_size);
buf_data.num_handles =
p_cfg_req->hw_cfg_args.num_out_map_entries;
@ -1791,6 +1809,64 @@ static int cam_jpeg_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
return rc;
}
static int cam_jpeg_set_camnoc_misr_test(void *data, u64 val)
{
g_jpeg_hw_mgr.camnoc_misr_test = val;
return 0;
}
static int cam_jpeg_get_camnoc_misr_test(void *data, u64 *val)
{
*val = g_jpeg_hw_mgr.camnoc_misr_test;
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(camnoc_misr_test, cam_jpeg_get_camnoc_misr_test,
cam_jpeg_set_camnoc_misr_test, "%08llu");
static int cam_jpeg_set_bug_on_misr(void *data, u64 val)
{
g_jpeg_hw_mgr.bug_on_misr = val;
return 0;
}
static int cam_jpeg_get_bug_on_misr(void *data, u64 *val)
{
*val = g_jpeg_hw_mgr.bug_on_misr;
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(bug_on_misr_mismatch, cam_jpeg_get_bug_on_misr,
cam_jpeg_set_bug_on_misr, "%08llu");
static int cam_jpeg_mgr_create_debugfs_entry(void)
{
int rc = 0;
struct dentry *dbgfileptr = NULL;
dbgfileptr = debugfs_create_dir("camera_jpeg", NULL);
if (!dbgfileptr) {
CAM_ERR(CAM_JPEG, "DebugFS could not create directory!");
rc = -ENOENT;
goto err;
}
/* Store parent inode for cleanup in caller */
g_jpeg_hw_mgr.dentry = dbgfileptr;
dbgfileptr = debugfs_create_file("camnoc_misr_test", 0644,
g_jpeg_hw_mgr.dentry, NULL, &camnoc_misr_test);
dbgfileptr = debugfs_create_file("bug_on_misr_mismatch", 0644,
g_jpeg_hw_mgr.dentry, NULL, &bug_on_misr_mismatch);
if (IS_ERR(dbgfileptr)) {
if (PTR_ERR(dbgfileptr) == -ENODEV)
CAM_WARN(CAM_JPEG, "DebugFS not enabled in kernel!");
else
rc = PTR_ERR(dbgfileptr);
}
err:
return rc;
}
int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
int *iommu_hdl)
{
@ -1877,7 +1953,9 @@ int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
if (iommu_hdl)
*iommu_hdl = g_jpeg_hw_mgr.iommu_hdl;
return rc;
rc = cam_jpeg_mgr_create_debugfs_entry();
if (!rc)
return rc;
cdm_iommu_failed:
cam_smmu_destroy_handle(g_jpeg_hw_mgr.iommu_hdl);

View file

@ -124,6 +124,9 @@ struct cam_jpeg_hw_ctx_data {
* @process_irq_cb_work_data: Work data pool for irq requests
* @cdm_iommu_hdl: Iommu handle received from cdm
* @cdm_iommu_hdl_secure: Secure iommu handle received from cdm
* @dentry: Debugfs entry
* @camnoc_misr_test : debugfs entry to select camnoc_misr for read or write path
* @bug_on_misr : enable/disable bug on when misr mismatch is seen
* @devices: Core hw Devices of JPEG hardware manager
* @cdm_info: Cdm info for each core device.
* @cdm_reg_map: Regmap of each device for cdm.
@ -147,6 +150,9 @@ struct cam_jpeg_hw_mgr {
struct cam_jpeg_process_irq_work_data_t *process_irq_cb_work_data;
int cdm_iommu_hdl;
int cdm_iommu_hdl_secure;
struct dentry *dentry;
u64 camnoc_misr_test;
u64 bug_on_misr;
struct cam_hw_intf **devices[CAM_JPEG_DEV_TYPE_MAX];
struct cam_jpeg_hw_cdm_info_t cdm_info[CAM_JPEG_DEV_TYPE_MAX]

View file

@ -18,6 +18,11 @@
#define CAM_JPEG_HW_DUMP_TAG_MAX_LEN 32
#define CAM_JPEG_HW_DUMP_NUM_WORDS 5
#define CAM_JPEG_HW_MAX_NUM_PID 2
#define CAM_JPEG_CAMNOC_MISR_VAL_ROW 2
#define CAM_JPEG_CAMNOC_MISR_VAL_COL 4
#define CAM_JPEG_ENC_MISR_VAL_NUM 3
#define CAM_JPEG_MISR_ID_LOW_RD 0
#define CAM_JPEG_MISR_ID_LOW_WR 1
enum cam_jpeg_hw_type {
CAM_JPEG_DEV_ENC,
@ -51,12 +56,25 @@ struct cam_jpeg_match_pid_args {
uint32_t match_res;
};
/**
* struct cam_jpeg_misr_dump_args
* @req_id: Request Id
* @enable_bug: This flag indicates whether BUG_ON(1) has to be called or not
* on MISR mismatch
*/
struct cam_jpeg_misr_dump_args {
uint32_t req_id;
bool enable_bug;
};
enum cam_jpeg_cmd_type {
CAM_JPEG_CMD_CDM_CFG,
CAM_JPEG_CMD_SET_IRQ_CB,
CAM_JPEG_CMD_HW_DUMP,
CAM_JPEG_CMD_GET_NUM_PID,
CAM_JPEG_CMD_MATCH_PID_MID,
CAM_JPEG_CMD_CONFIG_HW_MISR,
CAM_JPEG_CMD_DUMP_HW_MISR_VAL,
CAM_JPEG_CMD_MAX,
};

View file

@ -0,0 +1,75 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#ifndef CAM_JPEG_DMA_165_HW_INFO_VER_4_2_0_H
#define CAM_JPEG_DMA_165_HW_INFO_VER_4_2_0_H
#define CAM_JPEGDMA_HW_IRQ_STATUS_SESSION_DONE (1 << 0)
#define CAM_JPEGDMA_HW_IRQ_STATUS_RD_BUF_DONE (1 << 1)
#define CAM_JPEGDMA_HW_IRQ_STATUS_WR_BUF_DONE (1 << 5)
#define CAM_JPEGDMA_HW_IRQ_STATUS_AXI_HALT (1 << 9)
#define CAM_JPEGDMA_HW_IRQ_STATUS_RST_DONE (1 << 10)
#define CAM_JPEG_HW_MASK_SCALE_ENABLE 0x1
#define CAM_JPEGDMA_HW_MASK_COMP_FRAMEDONE \
CAM_JPEGDMA_HW_IRQ_STATUS_SESSION_DONE
#define CAM_JPEGDMA_HW_MASK_COMP_RESET_ACK \
CAM_JPEGDMA_HW_IRQ_STATUS_RST_DONE
static struct cam_jpeg_dma_device_hw_info cam_jpeg_dma_165_hw_info = {
.reg_offset = {
.hw_version = 0x0,
.int_clr = 0x14,
.int_status = 0x10,
.int_mask = 0x0C,
.hw_cmd = 0x1C,
.reset_cmd = 0x08,
.encode_size = 0x180,
.core_cfg = 0x18,
.misr_cfg0 = 0x160,
.misr_cfg1 = 0x164,
},
.reg_val = {
.int_clr_clearall = 0xFFFFFFFF,
.int_mask_disable_all = 0x00000000,
.int_mask_enable_all = 0xFFFFFFFF,
.hw_cmd_start = 0x00000001,
.reset_cmd = 0x32083,
.hw_cmd_stop = 0x00000004,
.misr_cfg0 = 0x506,
},
.int_status = {
.framedone = CAM_JPEGDMA_HW_MASK_COMP_FRAMEDONE,
.resetdone = CAM_JPEGDMA_HW_MASK_COMP_RESET_ACK,
.iserror = 0x0,
.stopdone = CAM_JPEGDMA_HW_IRQ_STATUS_AXI_HALT,
.scale_enable = CAM_JPEG_HW_MASK_SCALE_ENABLE,
.scale_enable_shift = 0x4,
},
.camnoc_misr_reg_offset = {
.main_ctl = 0x5908,
.id_mask_low = 0x5920,
.id_value_low = 0x5918,
.misc_ctl = 0x5910,
.sigdata0 = 0x5950,
},
.camnoc_misr_reg_val = {
.main_ctl = 0x7,
.id_mask_low = 0xFC0,
.id_value_low_rd = 0xD00,
.id_value_low_wr = 0xD42,
.misc_ctl_start = 0x1,
.misc_ctl_stop = 0x2,
},
.max_misr = 3,
.max_misr_rd = 4,
.max_misr_wr = 4,
.camnoc_misr_sigdata = 4,
.master_we_sel = 2,
.misr_rd_word_sel = 4,
};
#endif /* CAM_JPEG_DMA_165_HW_INFO_VER_4_2_0_H */

View file

@ -0,0 +1,75 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#ifndef CAM_JPEG_DMA_580_HW_INFO_VER_4_2_0_H
#define CAM_JPEG_DMA_580_HW_INFO_VER_4_2_0_H
#define CAM_JPEGDMA_HW_IRQ_STATUS_SESSION_DONE (1 << 0)
#define CAM_JPEGDMA_HW_IRQ_STATUS_RD_BUF_DONE (1 << 1)
#define CAM_JPEGDMA_HW_IRQ_STATUS_WR_BUF_DONE (1 << 5)
#define CAM_JPEGDMA_HW_IRQ_STATUS_AXI_HALT (1 << 9)
#define CAM_JPEGDMA_HW_IRQ_STATUS_RST_DONE (1 << 10)
#define CAM_JPEG_HW_MASK_SCALE_ENABLE 0x1
#define CAM_JPEGDMA_HW_MASK_COMP_FRAMEDONE \
CAM_JPEGDMA_HW_IRQ_STATUS_SESSION_DONE
#define CAM_JPEGDMA_HW_MASK_COMP_RESET_ACK \
CAM_JPEGDMA_HW_IRQ_STATUS_RST_DONE
static struct cam_jpeg_dma_device_hw_info cam_jpeg_dma_580_hw_info = {
.reg_offset = {
.hw_version = 0x0,
.int_clr = 0x14,
.int_status = 0x10,
.int_mask = 0x0C,
.hw_cmd = 0x1C,
.reset_cmd = 0x08,
.encode_size = 0x180,
.core_cfg = 0x18,
.misr_cfg0 = 0x160,
.misr_cfg1 = 0x164,
},
.reg_val = {
.int_clr_clearall = 0xFFFFFFFF,
.int_mask_disable_all = 0x00000000,
.int_mask_enable_all = 0xFFFFFFFF,
.hw_cmd_start = 0x00000001,
.reset_cmd = 0x32083,
.hw_cmd_stop = 0x00000004,
.misr_cfg0 = 0x506,
},
.int_status = {
.framedone = CAM_JPEGDMA_HW_MASK_COMP_FRAMEDONE,
.resetdone = CAM_JPEGDMA_HW_MASK_COMP_RESET_ACK,
.iserror = 0x0,
.stopdone = CAM_JPEGDMA_HW_IRQ_STATUS_AXI_HALT,
.scale_enable = CAM_JPEG_HW_MASK_SCALE_ENABLE,
.scale_enable_shift = 0x4,
},
.camnoc_misr_reg_offset = {
.main_ctl = 0x3608,
.id_mask_low = 0x3620,
.id_value_low = 0x3618,
.misc_ctl = 0x3610,
.sigdata0 = 0x3650,
},
.camnoc_misr_reg_val = {
.main_ctl = 0x7,
.id_mask_low = 0xFC0,
.id_value_low_rd = 0xD00,
.id_value_low_wr = 0xD42,
.misc_ctl_start = 0x1,
.misc_ctl_stop = 0x2,
},
.max_misr = 3,
.max_misr_rd = 4,
.max_misr_wr = 4,
.camnoc_misr_sigdata = 4,
.master_we_sel = 2,
.misr_rd_word_sel = 4,
};
#endif /* CAM_JPEG_DMA_580_HW_INFO_VER_4_2_0_H */

View file

@ -372,13 +372,236 @@ int cam_jpeg_dma_stop_hw(void *data,
return 0;
}
int cam_jpeg_dma_dump_camnoc_misr_val(struct cam_jpeg_dma_device_hw_info *hw_info,
struct cam_hw_soc_info *soc_info, void *cmd_args)
{
void __iomem *dma_mem_base = NULL;
void __iomem *camnoc_mem_base = NULL;
struct cam_jpeg_misr_dump_args *pmisr_args;
int32_t camnoc_misr_val[CAM_JPEG_CAMNOC_MISR_VAL_ROW][
CAM_JPEG_CAMNOC_MISR_VAL_COL] = {{0}};
int i, rc = 0;
int32_t val;
uint32_t index = 0;
bool mismatch = false;
dma_mem_base = soc_info->reg_map[0].mem_base;
camnoc_mem_base = soc_info->reg_map[1].mem_base;
pmisr_args = (struct cam_jpeg_misr_dump_args *)cmd_args;
if (!pmisr_args) {
CAM_ERR(CAM_JPEG, "Invalid command argument");
return -EINVAL;
}
val = cam_io_r_mb(dma_mem_base + hw_info->reg_offset.core_cfg);
index = (val >> hw_info->int_status.scale_enable_shift) &
hw_info->int_status.scale_enable;
CAM_DBG(CAM_JPEG, "index %d", index);
for (i = 0; i < hw_info->camnoc_misr_sigdata; i++) {
camnoc_misr_val[index][i] = cam_io_r_mb(camnoc_mem_base +
hw_info->camnoc_misr_reg_offset.sigdata0 + (i * 8));
if (hw_info->prev_camnoc_misr_val[index][i] !=
camnoc_misr_val[index][i])
mismatch = true;
}
if (mismatch && (pmisr_args->req_id != 1)) {
CAM_ERR(CAM_JPEG,
"CAMNOC DMA_MISR MISMATCH [req:%d][i:%d][index:%d]\n"
"curr:0x%x %x %x %x prev:0x%x %x %x %x isbug:%d",
pmisr_args->req_id, i, index,
camnoc_misr_val[index][3], camnoc_misr_val[index][2],
camnoc_misr_val[index][1], camnoc_misr_val[index][0],
hw_info->prev_camnoc_misr_val[index][3],
hw_info->prev_camnoc_misr_val[index][2],
hw_info->prev_camnoc_misr_val[index][1],
hw_info->prev_camnoc_misr_val[index][0],
pmisr_args->enable_bug);
if (pmisr_args->enable_bug)
BUG_ON(1);
}
CAM_DBG(CAM_JPEG,
"CAMNOC DMA_MISR req:%d SigData:0x %x %x %x %x",
pmisr_args->req_id,
camnoc_misr_val[index][3], camnoc_misr_val[index][2],
camnoc_misr_val[index][1], camnoc_misr_val[index][0]);
mismatch = false;
for (i = 0; i < hw_info->camnoc_misr_sigdata; i++)
hw_info->prev_camnoc_misr_val[index][i] =
camnoc_misr_val[index][i];
/* stop misr : cam_noc_cam_noc_0_req_link_misrprb_MiscCtl_Low */
cam_io_w_mb(hw_info->camnoc_misr_reg_val.misc_ctl_stop,
camnoc_mem_base + hw_info->camnoc_misr_reg_offset.misc_ctl);
return rc;
}
int cam_jpeg_dma_dump_hw_misr_val(struct cam_jpeg_dma_device_hw_info *hw_info,
struct cam_hw_soc_info *soc_info, void *cmd_args)
{
void __iomem *dma_mem_base = NULL;
void __iomem *camnoc_mem_base = NULL;
struct cam_jpeg_misr_dump_args *pmisr_args;
int32_t dma_wr_misr_val[CAM_JPEG_CAMNOC_MISR_VAL_ROW][
CAM_JPEG_CAMNOC_MISR_VAL_COL] = {{0}};
int32_t dma_rd_misr_val[CAM_JPEG_CAMNOC_MISR_VAL_ROW][
CAM_JPEG_CAMNOC_MISR_VAL_COL] = {{0}};
int offset, i, rc = 0;
int32_t val;
uint32_t index = 0;
bool mismatch = false;
dma_mem_base = soc_info->reg_map[0].mem_base;
camnoc_mem_base = soc_info->reg_map[1].mem_base;
pmisr_args = (struct cam_jpeg_misr_dump_args *)cmd_args;
if (!pmisr_args) {
CAM_ERR(CAM_JPEG, "Invalid command argument");
return -EINVAL;
}
val = cam_io_r_mb(dma_mem_base + hw_info->reg_offset.core_cfg);
index = (val >> hw_info->int_status.scale_enable_shift) &
hw_info->int_status.scale_enable;
CAM_DBG(CAM_JPEG, "index %d", index);
/* After the session is complete, read back the MISR values.
* fetch engine MISR values
*/
offset = hw_info->reg_offset.misr_cfg1;
for (i = 0; i < hw_info->max_misr_rd; i++) {
val = i << hw_info->misr_rd_word_sel;
cam_io_w_mb(val, dma_mem_base + offset);
dma_rd_misr_val[index][i] = cam_io_r_mb(dma_mem_base +
offset + 0x4);
if (hw_info->prev_dma_rd_misr_val[index][i] != dma_rd_misr_val[index][i])
mismatch = true;
}
if (mismatch && (pmisr_args->req_id != 1)) {
CAM_ERR(CAM_JPEG,
"CAMNOC DMA_RD_MISR MISMATCH [req:%d][index:%d][i:%d]\n"
"curr:0x%x %x %x %x prev:0x%x %x %x %x isbug:%d",
pmisr_args->req_id, index, i,
dma_rd_misr_val[index][3], dma_rd_misr_val[index][2],
dma_rd_misr_val[index][1], dma_rd_misr_val[index][0],
hw_info->prev_dma_rd_misr_val[index][3],
hw_info->prev_dma_rd_misr_val[index][2],
hw_info->prev_dma_rd_misr_val[index][1],
hw_info->prev_dma_rd_misr_val[index][0],
pmisr_args->enable_bug);
if (pmisr_args->enable_bug)
BUG_ON(1);
}
CAM_DBG(CAM_JPEG,
"CORE JPEG DMA RD MISR: 0x%x %x %x %x",
dma_rd_misr_val[index][3], dma_rd_misr_val[index][2],
dma_rd_misr_val[index][1], dma_rd_misr_val[index][0]);
mismatch = false;
for (i = 0; i < hw_info->max_misr_rd; i++) {
hw_info->prev_dma_rd_misr_val[index][i] =
dma_rd_misr_val[index][i];
}
/* write engine MISR values */
for (i = 0; i < hw_info->max_misr_wr; i++) {
val = hw_info->master_we_sel | (i << hw_info->misr_rd_word_sel);
cam_io_w_mb(val, dma_mem_base + offset);
dma_wr_misr_val[index][i] = cam_io_r_mb(dma_mem_base +
offset + 0x4);
if (hw_info->prev_dma_wr_misr_val[index][i] !=
dma_wr_misr_val[index][i])
mismatch = true;
}
if (mismatch && (pmisr_args->req_id != 1)) {
CAM_ERR(CAM_JPEG,
"CAMNOC DMA_WR_MISR MISMATCH [req:%d][index:%d][i:%d]\n"
"curr:0x%x %x %x %x prev:0x%x %x %x %x isbug:%d",
pmisr_args->req_id, index, i,
dma_wr_misr_val[index][3], dma_wr_misr_val[index][2],
dma_wr_misr_val[index][1], dma_wr_misr_val[index][0],
hw_info->prev_dma_wr_misr_val[index][3],
hw_info->prev_dma_wr_misr_val[index][2],
hw_info->prev_dma_wr_misr_val[index][1],
hw_info->prev_dma_wr_misr_val[index][0],
pmisr_args->enable_bug);
if (pmisr_args->enable_bug)
BUG_ON(1);
}
CAM_DBG(CAM_JPEG,
"CORE JPEG DMA WR MISR: 0x%x %x %x %x",
dma_wr_misr_val[index][3], dma_wr_misr_val[index][2],
dma_wr_misr_val[index][1], dma_wr_misr_val[index][0]);
mismatch = false;
for (i = 0; i < hw_info->max_misr_wr; i++) {
hw_info->prev_dma_wr_misr_val[index][i] =
dma_wr_misr_val[index][i];
}
return rc;
}
int cam_jpeg_dma_config_cmanoc_hw_misr(struct cam_jpeg_dma_device_hw_info *hw_info,
struct cam_hw_soc_info *soc_info, void *cmd_args)
{
void __iomem *dma_mem_base = NULL;
void __iomem *camnoc_mem_base = NULL;
uint32_t *camnoc_misr_test = NULL;
int val = 0;
dma_mem_base = soc_info->reg_map[0].mem_base;
camnoc_mem_base = soc_info->reg_map[1].mem_base;
if (!camnoc_mem_base) {
CAM_ERR(CAM_JPEG, "Invalid camnoc base address");
return -EINVAL;
}
camnoc_misr_test = (uint32_t *)cmd_args;
if (!camnoc_misr_test) {
CAM_ERR(CAM_JPEG, "Invalid command argument");
return -EINVAL;
}
/* enable FE and WE with sample data mode */
cam_io_w_mb(hw_info->reg_val.misr_cfg0, dma_mem_base +
hw_info->reg_offset.misr_cfg0);
/* cam_noc_cam_noc_0_req_link_misrprb_MainCtl_Low
* enable CRC generation on both RD, WR and transaction payload
*/
cam_io_w_mb(hw_info->camnoc_misr_reg_val.main_ctl, camnoc_mem_base +
hw_info->camnoc_misr_reg_offset.main_ctl);
/* cam_noc_cam_noc_0_req_link_misrprb_IdMask_Low */
cam_io_w_mb(hw_info->camnoc_misr_reg_val.main_ctl, camnoc_mem_base +
hw_info->camnoc_misr_reg_offset.id_mask_low);
/* cam_noc_cam_noc_0_req_link_misrprb_IdValue_Low */
switch (*camnoc_misr_test) {
case CAM_JPEG_MISR_ID_LOW_RD:
val = hw_info->camnoc_misr_reg_val.id_value_low_rd;
break;
case CAM_JPEG_MISR_ID_LOW_WR:
val = hw_info->camnoc_misr_reg_val.id_value_low_wr;
break;
default:
val = hw_info->camnoc_misr_reg_val.id_value_low_rd;
break;
}
cam_io_w_mb(val, camnoc_mem_base +
hw_info->camnoc_misr_reg_offset.id_value_low);
/* start/reset misr : cam_noc_cam_noc_0_req_link_misrprb_MiscCtl_Low */
cam_io_w_mb(hw_info->camnoc_misr_reg_val.misc_ctl_start,
camnoc_mem_base + hw_info->camnoc_misr_reg_offset.misc_ctl);
CAM_DBG(CAM_JPEG, "DMA CAMNOC and HW MISR configured");
return 0;
}
int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
void *cmd_args, uint32_t arg_size)
{
struct cam_hw_info *jpeg_dma_dev = device_priv;
struct cam_jpeg_dma_device_core_info *core_info = NULL;
struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
struct cam_jpeg_match_pid_args *match_pid_mid = NULL;
uint32_t *num_pid = NULL;
uint32_t *num_pid = NULL;
struct cam_hw_soc_info *soc_info = NULL;
int i, rc = 0;
if (!device_priv) {
@ -394,6 +617,10 @@ int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
core_info = (struct cam_jpeg_dma_device_core_info *)
jpeg_dma_dev->core_info;
hw_info = core_info->jpeg_dma_hw_info;
soc_info = &jpeg_dma_dev->soc_info;
switch (cmd_type) {
case CAM_JPEG_CMD_SET_IRQ_CB:
{
@ -455,6 +682,19 @@ int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
}
break;
case CAM_JPEG_CMD_CONFIG_HW_MISR:
{
rc = cam_jpeg_dma_config_cmanoc_hw_misr(hw_info, soc_info, cmd_args);
break;
}
case CAM_JPEG_CMD_DUMP_HW_MISR_VAL:
{
rc = cam_jpeg_dma_dump_hw_misr_val(hw_info, soc_info, cmd_args);
if (rc)
break;
rc = cam_jpeg_dma_dump_camnoc_misr_val(hw_info, soc_info, cmd_args);
break;
}
default:
rc = -EINVAL;
break;

View file

@ -22,6 +22,9 @@ struct cam_jpeg_dma_reg_offsets {
uint32_t hw_cmd;
uint32_t reset_cmd;
uint32_t encode_size;
uint32_t core_cfg;
uint32_t misr_cfg0;
uint32_t misr_cfg1;
};
struct cam_jpeg_dma_regval {
@ -31,6 +34,7 @@ struct cam_jpeg_dma_regval {
uint32_t hw_cmd_start;
uint32_t reset_cmd;
uint32_t hw_cmd_stop;
uint32_t misr_cfg0;
};
struct cam_jpeg_dma_int_status {
@ -38,12 +42,45 @@ struct cam_jpeg_dma_int_status {
uint32_t resetdone;
uint32_t iserror;
uint32_t stopdone;
uint32_t scale_enable;
uint32_t scale_enable_shift;
};
struct cam_jpeg_dma_camnoc_misr_reg_offset {
uint32_t main_ctl;
uint32_t id_mask_low;
uint32_t id_value_low;
uint32_t misc_ctl;
uint32_t sigdata0;
};
struct cam_jpeg_dma_camnoc_misr_reg_val {
uint32_t main_ctl;
uint32_t id_mask_low;
uint32_t id_value_low_rd;
uint32_t id_value_low_wr;
uint32_t misc_ctl_start;
uint32_t misc_ctl_stop;
};
struct cam_jpeg_dma_device_hw_info {
struct cam_jpeg_dma_reg_offsets reg_offset;
struct cam_jpeg_dma_regval reg_val;
struct cam_jpeg_dma_int_status int_status;
struct cam_jpeg_dma_camnoc_misr_reg_offset camnoc_misr_reg_offset;
struct cam_jpeg_dma_camnoc_misr_reg_val camnoc_misr_reg_val;
uint32_t max_misr;
uint32_t max_misr_rd;
uint32_t max_misr_wr;
uint32_t camnoc_misr_sigdata;
uint32_t master_we_sel;
uint32_t misr_rd_word_sel;
int32_t prev_dma_wr_misr_val[CAM_JPEG_CAMNOC_MISR_VAL_ROW][
CAM_JPEG_CAMNOC_MISR_VAL_COL];
int32_t prev_dma_rd_misr_val[CAM_JPEG_CAMNOC_MISR_VAL_ROW][
CAM_JPEG_CAMNOC_MISR_VAL_COL];
int32_t prev_camnoc_misr_val[CAM_JPEG_CAMNOC_MISR_VAL_ROW][
CAM_JPEG_CAMNOC_MISR_VAL_COL];
};
enum cam_jpeg_dma_core_state {

View file

@ -19,6 +19,8 @@
#include "cam_cpas_api.h"
#include "cam_debug_util.h"
#include "cam_jpeg_dma_hw_info_ver_4_2_0.h"
#include "cam_jpeg_dma_165_hw_info_ver_4_2_0.h"
#include "cam_jpeg_dma_580_hw_info_ver_4_2_0.h"
#include "camera_main.h"
static int cam_jpeg_dma_register_cpas(struct cam_hw_soc_info *soc_info,
@ -238,6 +240,14 @@ static const struct of_device_id cam_jpeg_dma_dt_match[] = {
.compatible = "qcom,cam_jpeg_dma",
.data = &cam_jpeg_dma_hw_info,
},
{
.compatible = "qcom,cam_jpeg_dma_165",
.data = &cam_jpeg_dma_165_hw_info,
},
{
.compatible = "qcom,cam_jpeg_dma_580",
.data = &cam_jpeg_dma_580_hw_info,
},
{}
};
MODULE_DEVICE_TABLE(of, cam_jpeg_dma_dt_match);

View file

@ -0,0 +1,102 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#ifndef CAM_JPEG_ENC_165_HW_INFO_TITAN170_H
#define CAM_JPEG_ENC_165_HW_INFO_TITAN170_H
#define CAM_JPEG_HW_IRQ_STATUS_FRAMEDONE_MASK 0x00000001
#define CAM_JPEG_HW_IRQ_STATUS_FRAMEDONE_SHIFT 0x00000000
#define CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK 0x10000000
#define CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a
#define CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_MASK 0x8000000
#define CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_SHIFT 0x0000001b
#define CAM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800
#define CAM_JPEG_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b
#define CAM_JPEG_HW_MASK_SCALE_ENABLE 0x1
#define CAM_JPEG_HW_IRQ_STATUS_DCD_UNESCAPED_FF (0x1<<19)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_HUFFMAN_ERROR (0x1<<20)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_COEFFICIENT_ERR (0x1<<21)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_MISSING_BIT_STUFF (0x1<<22)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_SCAN_UNDERFLOW (0x1<<23)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM (0x1<<24)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM_SEQ (0x1<<25)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_MISSING_RSM (0x1<<26)
#define CAM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK (0x1<<29)
#define CAM_JPEG_HW_MASK_COMP_FRAMEDONE \
CAM_JPEG_HW_IRQ_STATUS_FRAMEDONE_MASK
#define CAM_JPEG_HW_MASK_COMP_RESET_ACK \
CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK
#define CAM_JPEG_HW_MASK_COMP_ERR \
(CAM_JPEG_HW_IRQ_STATUS_DCD_UNESCAPED_FF | \
CAM_JPEG_HW_IRQ_STATUS_DCD_HUFFMAN_ERROR | \
CAM_JPEG_HW_IRQ_STATUS_DCD_COEFFICIENT_ERR | \
CAM_JPEG_HW_IRQ_STATUS_DCD_MISSING_BIT_STUFF | \
CAM_JPEG_HW_IRQ_STATUS_DCD_SCAN_UNDERFLOW | \
CAM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM | \
CAM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM_SEQ | \
CAM_JPEG_HW_IRQ_STATUS_DCD_MISSING_RSM | \
CAM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK)
static struct cam_jpeg_enc_device_hw_info cam_jpeg_enc_165_hw_info = {
.reg_offset = {
.hw_version = 0x0,
.int_clr = 0x1c,
.int_status = 0x20,
.int_mask = 0x18,
.hw_cmd = 0x10,
.reset_cmd = 0x8,
.encode_size = 0x180,
.core_cfg = 0xc,
.misr_cfg = 0x2B4,
.misr_rd0 = 0x2B8,
},
.reg_val = {
.int_clr_clearall = 0xFFFFFFFF,
.int_mask_disable_all = 0x00000000,
.int_mask_enable_all = 0xFFFFFFFF,
.hw_cmd_start = 0x00000001,
.reset_cmd = 0x200320D3,
.hw_cmd_stop = 0x00000002,
.misr_cfg = 0x7,
},
.int_status = {
.framedone = CAM_JPEG_HW_MASK_COMP_FRAMEDONE,
.resetdone = CAM_JPEG_HW_MASK_COMP_RESET_ACK,
.iserror = CAM_JPEG_HW_MASK_COMP_ERR,
.stopdone = CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_MASK,
.scale_enable = CAM_JPEG_HW_MASK_SCALE_ENABLE,
.scale_enable_shift = 0x7,
},
.reg_dump = {
.start_offset = 0x0,
.end_offset = 0x33C,
},
.camnoc_misr_reg_offset = {
.main_ctl = 0x5908,
.id_mask_low = 0x5920,
.id_value_low = 0x5918,
.misc_ctl = 0x5910,
.sigdata0 = 0x5950,
},
.camnoc_misr_reg_val = {
.main_ctl = 0x7,
.id_mask_low = 0xFC0,
.id_value_low_rd = 0xD80,
.id_value_low_wr = 0xDC2,
.misc_ctl_start = 0x1,
.misc_ctl_stop = 0x2,
},
.max_misr = 3,
.max_misr_rd = 4,
.camnoc_misr_sigdata = 4,
};
#endif /* CAM_JPEG_ENC_165_HW_INFO_TITAN170_H */

View file

@ -0,0 +1,102 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#ifndef CAM_JPEG_ENC_580_HW_INFO_TITAN170_H
#define CAM_JPEG_ENC_580_HW_INFO_TITAN170_H
#define CAM_JPEG_HW_IRQ_STATUS_FRAMEDONE_MASK 0x00000001
#define CAM_JPEG_HW_IRQ_STATUS_FRAMEDONE_SHIFT 0x00000000
#define CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK 0x10000000
#define CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a
#define CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_MASK 0x8000000
#define CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_SHIFT 0x0000001b
#define CAM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800
#define CAM_JPEG_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b
#define CAM_JPEG_HW_MASK_SCALE_ENABLE 0x1
#define CAM_JPEG_HW_IRQ_STATUS_DCD_UNESCAPED_FF (0x1<<19)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_HUFFMAN_ERROR (0x1<<20)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_COEFFICIENT_ERR (0x1<<21)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_MISSING_BIT_STUFF (0x1<<22)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_SCAN_UNDERFLOW (0x1<<23)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM (0x1<<24)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM_SEQ (0x1<<25)
#define CAM_JPEG_HW_IRQ_STATUS_DCD_MISSING_RSM (0x1<<26)
#define CAM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK (0x1<<29)
#define CAM_JPEG_HW_MASK_COMP_FRAMEDONE \
CAM_JPEG_HW_IRQ_STATUS_FRAMEDONE_MASK
#define CAM_JPEG_HW_MASK_COMP_RESET_ACK \
CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK
#define CAM_JPEG_HW_MASK_COMP_ERR \
(CAM_JPEG_HW_IRQ_STATUS_DCD_UNESCAPED_FF | \
CAM_JPEG_HW_IRQ_STATUS_DCD_HUFFMAN_ERROR | \
CAM_JPEG_HW_IRQ_STATUS_DCD_COEFFICIENT_ERR | \
CAM_JPEG_HW_IRQ_STATUS_DCD_MISSING_BIT_STUFF | \
CAM_JPEG_HW_IRQ_STATUS_DCD_SCAN_UNDERFLOW | \
CAM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM | \
CAM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM_SEQ | \
CAM_JPEG_HW_IRQ_STATUS_DCD_MISSING_RSM | \
CAM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK)
static struct cam_jpeg_enc_device_hw_info cam_jpeg_enc_580_hw_info = {
.reg_offset = {
.hw_version = 0x0,
.int_clr = 0x1c,
.int_status = 0x20,
.int_mask = 0x18,
.hw_cmd = 0x10,
.reset_cmd = 0x8,
.encode_size = 0x180,
.core_cfg = 0xc,
.misr_cfg = 0x2B4,
.misr_rd0 = 0x2B8,
},
.reg_val = {
.int_clr_clearall = 0xFFFFFFFF,
.int_mask_disable_all = 0x00000000,
.int_mask_enable_all = 0xFFFFFFFF,
.hw_cmd_start = 0x00000001,
.reset_cmd = 0x200320D3,
.hw_cmd_stop = 0x00000002,
.misr_cfg = 0x7,
},
.int_status = {
.framedone = CAM_JPEG_HW_MASK_COMP_FRAMEDONE,
.resetdone = CAM_JPEG_HW_MASK_COMP_RESET_ACK,
.iserror = CAM_JPEG_HW_MASK_COMP_ERR,
.stopdone = CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_MASK,
.scale_enable = CAM_JPEG_HW_MASK_SCALE_ENABLE,
.scale_enable_shift = 0x7,
},
.reg_dump = {
.start_offset = 0x0,
.end_offset = 0x33C,
},
.camnoc_misr_reg_offset = {
.main_ctl = 0x3608,
.id_mask_low = 0x3620,
.id_value_low = 0x3618,
.misc_ctl = 0x3610,
.sigdata0 = 0x3650,
},
.camnoc_misr_reg_val = {
.main_ctl = 0x7,
.id_mask_low = 0xFC0,
.id_value_low_rd = 0xD80,
.id_value_low_wr = 0xDC2,
.misc_ctl_start = 0x1,
.misc_ctl_stop = 0x2,
},
.max_misr = 3,
.max_misr_rd = 4,
.camnoc_misr_sigdata = 4,
};
#endif /* CAM_JPEG_ENC_580_HW_INFO_TITAN170_H */

View file

@ -493,13 +493,201 @@ int cam_jpeg_enc_hw_dump(
return 0;
}
int cam_jpeg_enc_dump_camnoc_misr_val(struct cam_jpeg_enc_device_hw_info *hw_info,
struct cam_hw_soc_info *soc_info, void *cmd_args)
{
void __iomem *enc_mem_base = NULL;
void __iomem *camnoc_mem_base = NULL;
struct cam_jpeg_misr_dump_args *pmisr_args;
int32_t val;
uint32_t index = 0;
int i;
bool mismatch = false;
int32_t camnoc_misr_val[CAM_JPEG_CAMNOC_MISR_VAL_ROW][
CAM_JPEG_CAMNOC_MISR_VAL_COL] = {{0}};
enc_mem_base = soc_info->reg_map[0].mem_base;
camnoc_mem_base = soc_info->reg_map[1].mem_base;
if (!camnoc_mem_base) {
CAM_ERR(CAM_JPEG, "Invalid camnoc base address");
return -EINVAL;
}
pmisr_args = (struct cam_jpeg_misr_dump_args *)cmd_args;
if (!pmisr_args) {
CAM_ERR(CAM_JPEG, "Invalid command argument");
return -EINVAL;
}
val = cam_io_r_mb(enc_mem_base + hw_info->reg_offset.core_cfg);
index = (val >> hw_info->int_status.scale_enable_shift) &
hw_info->int_status.scale_enable;
CAM_DBG(CAM_JPEG, "index %d", index);
for (i = 0; i < hw_info->camnoc_misr_sigdata; i++) {
camnoc_misr_val[index][i] = cam_io_r_mb(camnoc_mem_base +
hw_info->camnoc_misr_reg_offset.sigdata0 + (i * 8));
if (hw_info->prev_camnoc_misr_val[index][i] != camnoc_misr_val[index][i])
mismatch = true;
}
if (mismatch && (pmisr_args->req_id != 1)) {
CAM_ERR(CAM_JPEG,
"CAMNOC ENC_MISR MISMATCH [req:%d][i:%d][index:%d]\n"
"curr SigData:0x%x %x %x %x prev SigData:0x%x %x %x %x isbug:%d",
pmisr_args->req_id, i, index,
camnoc_misr_val[index][3], camnoc_misr_val[index][2],
camnoc_misr_val[index][1], camnoc_misr_val[index][0],
hw_info->prev_camnoc_misr_val[index][3],
hw_info->prev_camnoc_misr_val[index][2],
hw_info->prev_camnoc_misr_val[index][1],
hw_info->prev_camnoc_misr_val[index][0], pmisr_args->enable_bug);
if (pmisr_args->enable_bug)
BUG_ON(1);
}
CAM_DBG(CAM_JPEG,
"CAMNOC ENC MISR req:%d SigData:0x%x %x %x %x",
pmisr_args->req_id,
camnoc_misr_val[index][3], camnoc_misr_val[index][2],
camnoc_misr_val[index][1], camnoc_misr_val[index][0]);
mismatch = false;
for (i = 0; i < hw_info->camnoc_misr_sigdata; i++)
hw_info->prev_camnoc_misr_val[index][i] = camnoc_misr_val[index][i];
/* stop misr : cam_noc_cam_noc_0_req_link_misrprb_MiscCtl_Low */
cam_io_w_mb(hw_info->camnoc_misr_reg_val.misc_ctl_stop,
camnoc_mem_base + hw_info->camnoc_misr_reg_offset.misc_ctl);
return 0;
}
int cam_jpeg_enc_dump_hw_misr_val(struct cam_jpeg_enc_device_hw_info *hw_info,
struct cam_hw_soc_info *soc_info, void *cmd_args)
{
void __iomem *enc_mem_base = NULL;
void __iomem *camnoc_mem_base = NULL;
struct cam_jpeg_misr_dump_args *pmisr_args;
int32_t val;
uint32_t index = 0;
int offset, i, j;
bool mismatch = false;
int32_t enc_misr_val[CAM_JPEG_ENC_MISR_VAL_NUM][CAM_JPEG_CAMNOC_MISR_VAL_ROW][
CAM_JPEG_CAMNOC_MISR_VAL_COL] = {{{0}}};
enc_mem_base = soc_info->reg_map[0].mem_base;
camnoc_mem_base = soc_info->reg_map[1].mem_base;
if (!camnoc_mem_base) {
CAM_ERR(CAM_JPEG, "Invalid camnoc base address");
return -EINVAL;
}
pmisr_args = (struct cam_jpeg_misr_dump_args *)cmd_args;
if (!pmisr_args) {
CAM_ERR(CAM_JPEG, "Invalid command argument");
return -EINVAL;
}
val = cam_io_r_mb(enc_mem_base + hw_info->reg_offset.core_cfg);
index = (val >> hw_info->int_status.scale_enable_shift) &
hw_info->int_status.scale_enable;
CAM_DBG(CAM_JPEG, "index %d", index);
for (i = 0; i < hw_info->max_misr; i++) {
offset = hw_info->reg_offset.misr_rd0 + (i * 0x10);
for (j = 0; j < hw_info->max_misr_rd; j++) {
enc_misr_val[i][index][j] = cam_io_r_mb(enc_mem_base +
offset + (j * 4));
if (hw_info->prev_enc_misr_val[i][index][j] !=
enc_misr_val[i][index][j])
mismatch = true;
}
if (mismatch && (pmisr_args->req_id != 1)) {
CAM_ERR(CAM_JPEG,
"ENC_MISR RD MISMATCH [req:%d][i:%d][index:%d][j:%d]\n"
"curr:0x%x %x %x %x prev:0x%x %x %x %x isbug:%d",
pmisr_args->req_id, i, index, j, enc_misr_val[i][index][3],
enc_misr_val[i][index][2], enc_misr_val[i][index][1],
enc_misr_val[i][index][0], hw_info->prev_enc_misr_val[i][index][3],
hw_info->prev_enc_misr_val[i][index][2],
hw_info->prev_enc_misr_val[i][index][1],
hw_info->prev_enc_misr_val[i][index][0], pmisr_args->enable_bug);
if (pmisr_args->enable_bug)
BUG_ON(1);
}
CAM_DBG(CAM_JPEG, "ENC_MISR RD [req:%d][%d]: 0x%x %x %x %x",
pmisr_args->req_id, i,
enc_misr_val[i][index][3], enc_misr_val[i][index][2],
enc_misr_val[i][index][1], enc_misr_val[i][index][0]);
mismatch = false;
for (j = 0; j < hw_info->max_misr_rd; j++)
hw_info->prev_enc_misr_val[i][index][j] = enc_misr_val[i][index][j];
}
return 0;
}
int cam_jpeg_enc_config_cmanoc_hw_misr(struct cam_jpeg_enc_device_hw_info *hw_info,
struct cam_hw_soc_info *soc_info, void *cmd_args)
{
void __iomem *enc_mem_base = NULL;
void __iomem *camnoc_mem_base = NULL;
uint32_t *camnoc_misr_test = NULL;
int val = 0;
enc_mem_base = soc_info->reg_map[0].mem_base;
camnoc_mem_base = soc_info->reg_map[1].mem_base;
if (!camnoc_mem_base) {
CAM_ERR(CAM_JPEG, "Invalid camnoc base address");
return -EINVAL;
}
camnoc_misr_test = (uint32_t *)cmd_args;
if (!camnoc_misr_test) {
CAM_ERR(CAM_JPEG, "Invalid command argument");
return -EINVAL;
}
/* enable all MISRs */
cam_io_w_mb(hw_info->reg_val.misr_cfg, enc_mem_base +
hw_info->reg_offset.misr_cfg);
/* cam_noc_cam_noc_0_req_link_misrprb_MainCtl_Low
* enable CRC generation on both RD, WR and transaction payload
*/
cam_io_w_mb(hw_info->camnoc_misr_reg_val.main_ctl, camnoc_mem_base +
hw_info->camnoc_misr_reg_offset.main_ctl);
/* cam_noc_cam_noc_0_req_link_misrprb_IdMask_Low */
cam_io_w_mb(hw_info->camnoc_misr_reg_val.main_ctl, camnoc_mem_base +
hw_info->camnoc_misr_reg_offset.id_mask_low);
/* cam_noc_cam_noc_0_req_link_misrprb_IdValue_Low */
switch (*camnoc_misr_test) {
case CAM_JPEG_MISR_ID_LOW_RD:
val = hw_info->camnoc_misr_reg_val.id_value_low_rd;
break;
case CAM_JPEG_MISR_ID_LOW_WR:
val = hw_info->camnoc_misr_reg_val.id_value_low_wr;
break;
default:
val = hw_info->camnoc_misr_reg_val.id_value_low_rd;
break;
}
cam_io_w_mb(val, camnoc_mem_base +
hw_info->camnoc_misr_reg_offset.id_value_low);
/* start/reset misr : cam_noc_cam_noc_0_req_link_misrprb_MiscCtl_Low */
cam_io_w_mb(hw_info->camnoc_misr_reg_val.misc_ctl_start,
camnoc_mem_base + hw_info->camnoc_misr_reg_offset.misc_ctl);
CAM_DBG(CAM_JPEG, "ENC CAMNOC MISR configured");
return 0;
}
int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type,
void *cmd_args, uint32_t arg_size)
{
struct cam_hw_info *jpeg_enc_dev = device_priv;
struct cam_jpeg_enc_device_core_info *core_info = NULL;
struct cam_jpeg_enc_device_hw_info *hw_info = NULL;
struct cam_jpeg_match_pid_args *match_pid_mid = NULL;
uint32_t *num_pid = NULL;
struct cam_hw_soc_info *soc_info = NULL;
int i, rc = 0;
if (!device_priv) {
@ -515,6 +703,9 @@ int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type,
core_info = (struct cam_jpeg_enc_device_core_info *)
jpeg_enc_dev->core_info;
hw_info = core_info->jpeg_enc_hw_info;
soc_info = &jpeg_enc_dev->soc_info;
switch (cmd_type) {
case CAM_JPEG_CMD_SET_IRQ_CB:
{
@ -582,6 +773,19 @@ int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type,
}
break;
case CAM_JPEG_CMD_CONFIG_HW_MISR:
{
rc = cam_jpeg_enc_config_cmanoc_hw_misr(hw_info, soc_info, cmd_args);
break;
}
case CAM_JPEG_CMD_DUMP_HW_MISR_VAL:
{
rc = cam_jpeg_enc_dump_hw_misr_val(hw_info, soc_info, cmd_args);
if (rc)
break;
rc = cam_jpeg_enc_dump_camnoc_misr_val(hw_info, soc_info, cmd_args);
break;
}
default:
rc = -EINVAL;
break;

View file

@ -21,6 +21,9 @@ struct cam_jpeg_enc_reg_offsets {
uint32_t hw_cmd;
uint32_t reset_cmd;
uint32_t encode_size;
uint32_t core_cfg;
uint32_t misr_cfg;
uint32_t misr_rd0;
};
struct cam_jpeg_enc_regval {
@ -30,6 +33,7 @@ struct cam_jpeg_enc_regval {
uint32_t hw_cmd_start;
uint32_t reset_cmd;
uint32_t hw_cmd_stop;
uint32_t misr_cfg;
};
struct cam_jpeg_enc_int_status {
@ -37,6 +41,8 @@ struct cam_jpeg_enc_int_status {
uint32_t resetdone;
uint32_t iserror;
uint32_t stopdone;
uint32_t scale_enable;
uint32_t scale_enable_shift;
};
struct cam_jpeg_enc_reg_dump {
@ -44,11 +50,37 @@ struct cam_jpeg_enc_reg_dump {
uint32_t end_offset;
};
struct cam_jpeg_enc_camnoc_misr_reg_offset {
uint32_t main_ctl;
uint32_t id_mask_low;
uint32_t id_value_low;
uint32_t misc_ctl;
uint32_t sigdata0;
};
struct cam_jpeg_enc_camnoc_misr_reg_val {
uint32_t main_ctl;
uint32_t id_mask_low;
uint32_t id_value_low_rd;
uint32_t id_value_low_wr;
uint32_t misc_ctl_start;
uint32_t misc_ctl_stop;
};
struct cam_jpeg_enc_device_hw_info {
struct cam_jpeg_enc_reg_offsets reg_offset;
struct cam_jpeg_enc_regval reg_val;
struct cam_jpeg_enc_int_status int_status;
struct cam_jpeg_enc_reg_dump reg_dump;
struct cam_jpeg_enc_camnoc_misr_reg_offset camnoc_misr_reg_offset;
struct cam_jpeg_enc_camnoc_misr_reg_val camnoc_misr_reg_val;
uint32_t max_misr;
uint32_t max_misr_rd;
uint32_t camnoc_misr_sigdata;
int32_t prev_camnoc_misr_val[
CAM_JPEG_CAMNOC_MISR_VAL_ROW][CAM_JPEG_CAMNOC_MISR_VAL_COL];
int32_t prev_enc_misr_val[CAM_JPEG_ENC_MISR_VAL_NUM][
CAM_JPEG_CAMNOC_MISR_VAL_ROW][CAM_JPEG_CAMNOC_MISR_VAL_COL];
};
enum cam_jpeg_enc_core_state {

View file

@ -19,6 +19,8 @@
#include "cam_cpas_api.h"
#include "cam_debug_util.h"
#include "cam_jpeg_enc_hw_info_ver_4_2_0.h"
#include "cam_jpeg_enc_165_hw_info_ver_4_2_0.h"
#include "cam_jpeg_enc_580_hw_info_ver_4_2_0.h"
#include "camera_main.h"
static int cam_jpeg_enc_register_cpas(struct cam_hw_soc_info *soc_info,
@ -239,6 +241,14 @@ static const struct of_device_id cam_jpeg_enc_dt_match[] = {
.compatible = "qcom,cam_jpeg_enc",
.data = &cam_jpeg_enc_hw_info,
},
{
.compatible = "qcom,cam_jpeg_enc_165",
.data = &cam_jpeg_enc_165_hw_info,
},
{
.compatible = "qcom,cam_jpeg_enc_580",
.data = &cam_jpeg_enc_580_hw_info,
},
{}
};
MODULE_DEVICE_TABLE(of, cam_jpeg_enc_dt_match);

View file

@ -4112,14 +4112,14 @@ static void cam_ope_mgr_dump_pf_data(
packet = hw_cmd_args->u.pf_args.pf_data.packet;
ope_request = hw_cmd_args->u.pf_args.pf_data.req;
if (ctx_data->pf_mid_found)
goto stripedump;
ope_pid_mid_args.fault_mid = hw_cmd_args->u.pf_args.mid;
ope_pid_mid_args.fault_pid = hw_cmd_args->u.pf_args.pid;
ctx_found = hw_cmd_args->u.pf_args.ctx_found;
resource_type = hw_cmd_args->u.pf_args.resource_type;
if (ctx_data->pf_mid_found)
goto stripedump;
if (*ctx_found && *resource_type) {
hw_pid_support = false;
goto stripedump;
@ -4162,13 +4162,13 @@ static void cam_ope_mgr_dump_pf_data(
return;
}
io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload +
packet->io_configs_offset / 4);
*resource_type = ope_pid_mid_args.match_res;
CAM_INFO(CAM_OPE, "Fault port %d", *resource_type);
stripedump:
io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload +
packet->io_configs_offset / 4);
if (!ope_request)
goto iodump;
@ -4232,6 +4232,11 @@ iodump:
io_cfg[i].mem_handle[j]);
if (io_buf_found) {
if (j >= OPE_MAX_PLANES) {
CAM_ERR(CAM_OPE, "Invalid plane idx: %d", j);
break;
}
for (stripe_num = 0; stripe_num < io_buf->num_stripes[j];
stripe_num++) {
CAM_INFO(CAM_OPE,

View file

@ -42,10 +42,10 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link)
link->last_flush_id = 0;
link->initial_sync_req = -1;
link->dual_trigger = false;
link->trigger_cnt[0][0] = 0;
link->trigger_cnt[0][1] = 0;
link->trigger_cnt[1][0] = 0;
link->trigger_cnt[1][1] = 0;
link->trigger_cnt[0][CAM_TRIGGER_POINT_SOF] = 0;
link->trigger_cnt[0][CAM_TRIGGER_POINT_EOF] = 0;
link->trigger_cnt[1][CAM_TRIGGER_POINT_SOF] = 0;
link->trigger_cnt[1][CAM_TRIGGER_POINT_EOF] = 0;
link->in_msync_mode = false;
link->retry_cnt = 0;
link->is_shutdown = false;
@ -574,10 +574,10 @@ static void __cam_req_mgr_flush_req_slot(
atomic_set(&link->eof_event_cnt, 0);
in_q->wr_idx = 0;
in_q->rd_idx = 0;
link->trigger_cnt[0][0] = 0;
link->trigger_cnt[0][1] = 0;
link->trigger_cnt[1][0] = 0;
link->trigger_cnt[1][1] = 0;
link->trigger_cnt[0][CAM_TRIGGER_POINT_SOF] = 0;
link->trigger_cnt[0][CAM_TRIGGER_POINT_EOF] = 0;
link->trigger_cnt[1][CAM_TRIGGER_POINT_SOF] = 0;
link->trigger_cnt[1][CAM_TRIGGER_POINT_EOF] = 0;
}
/**
@ -2985,6 +2985,8 @@ static int cam_req_mgr_process_trigger(void *priv, void *data)
struct cam_req_mgr_core_link *link = NULL;
struct cam_req_mgr_req_queue *in_q = NULL;
struct crm_task_payload *task_data = NULL;
int reset_step = 0;
int i = 0;
if (!data || !priv) {
CAM_ERR(CAM_CRM, "input args NULL %pK %pK", data, priv);
@ -3013,6 +3015,22 @@ static int cam_req_mgr_process_trigger(void *priv, void *data)
in_q->last_applied_idx = -1;
if (idx == in_q->rd_idx)
__cam_req_mgr_dec_idx(&idx, 1, in_q->num_slots);
reset_step = link->max_delay;
for (i = 0; i < link->num_sync_links; i++) {
if (link->sync_link[i]) {
if ((link->in_msync_mode) &&
(link->sync_link[i]->max_delay >
reset_step))
reset_step =
link->sync_link[i]->max_delay;
}
}
__cam_req_mgr_dec_idx(
&idx, reset_step + 1,
in_q->num_slots);
__cam_req_mgr_reset_req_slot(link, idx);
}
}
@ -4084,10 +4102,10 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
goto setup_failed;
}
link->trigger_cnt[0][0] = 0;
link->trigger_cnt[0][1] = 0;
link->trigger_cnt[1][0] = 0;
link->trigger_cnt[1][1] = 0;
link->trigger_cnt[0][CAM_TRIGGER_POINT_SOF] = 0;
link->trigger_cnt[0][CAM_TRIGGER_POINT_EOF] = 0;
link->trigger_cnt[1][CAM_TRIGGER_POINT_SOF] = 0;
link->trigger_cnt[1][CAM_TRIGGER_POINT_EOF] = 0;
mutex_unlock(&link->lock);
mutex_unlock(&g_crm_core_dev->crm_lock);

View file

@ -415,7 +415,8 @@ struct cam_req_mgr_core_link {
uint64_t sof_timestamp;
uint64_t prev_sof_timestamp;
bool dual_trigger;
uint32_t trigger_cnt[CAM_REQ_MGR_MAX_TRIGGERS][CAM_TRIGGER_MAX_POINTS];
uint32_t trigger_cnt[CAM_REQ_MGR_MAX_TRIGGERS]
[CAM_TRIGGER_MAX_POINTS + 1];
atomic_t eof_event_cnt;
bool skip_init_frame;
uint64_t last_sof_trigger_jiffies;

View file

@ -459,6 +459,8 @@ static int cam_flash_ops(struct cam_flash_ctrl *flash_ctrl,
int cam_flash_off(struct cam_flash_ctrl *flash_ctrl)
{
int rc = 0;
if (!flash_ctrl) {
CAM_ERR(CAM_FLASH, "Flash control Null");
return -EINVAL;
@ -467,6 +469,16 @@ int cam_flash_off(struct cam_flash_ctrl *flash_ctrl)
if (flash_ctrl->switch_trigger)
cam_res_mgr_led_trigger_event(flash_ctrl->switch_trigger,
(enum led_brightness)LED_SWITCH_OFF);
if ((flash_ctrl->i2c_data.streamoff_settings.is_settings_valid) &&
(flash_ctrl->i2c_data.streamoff_settings.request_id == 0)) {
flash_ctrl->apply_streamoff = true;
rc = cam_flash_i2c_apply_setting(flash_ctrl, 0);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"cannot apply streamoff settings");
}
}
return 0;
}
@ -693,7 +705,22 @@ int cam_flash_i2c_apply_setting(struct cam_flash_ctrl *fctrl,
CAM_DBG(CAM_FLASH, "req_id=%llu", req_id);
if (req_id == 0) {
/* NonRealTime Init settings*/
if (fctrl->i2c_data.init_settings.is_settings_valid == true) {
if (fctrl->apply_streamoff == true) {
fctrl->apply_streamoff = false;
i2c_set = &fctrl->i2c_data.streamoff_settings;
list_for_each_entry(i2c_list,
&(i2c_set->list_head),
list) {
rc = cam_sensor_util_i2c_apply_setting
(&(fctrl->io_master_info), i2c_list);
if (rc) {
CAM_ERR(CAM_FLASH,
"Failed to apply stream on settings: %d", rc);
return rc;
}
break;
}
} else if (fctrl->i2c_data.init_settings.is_settings_valid == true) {
list_for_each_entry(i2c_list,
&(fctrl->i2c_data.init_settings.list_head),
list) {
@ -1217,6 +1244,16 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
"Failed in parsing i2c packets");
return rc;
}
if ((fctrl->flash_state == CAM_FLASH_STATE_ACQUIRE) ||
(fctrl->flash_state == CAM_FLASH_STATE_CONFIG)) {
fctrl->flash_state = CAM_FLASH_STATE_CONFIG;
rc = fctrl->func_tbl.apply_setting(fctrl, 1);
if (rc) {
CAM_ERR(CAM_FLASH, "cannot apply fire settings rc = %d", rc);
return rc;
}
return rc;
}
break;
}
case CAM_FLASH_PACKET_OPCODE_NON_REALTIME_SET_OPS: {
@ -1274,6 +1311,29 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
csl_packet->header.request_id);
goto update_req_mgr;
}
case CAM_FLASH_PACKET_OPCODE_STREAM_OFF: {
if (fctrl->streamoff_count > 0)
return rc;
CAM_DBG(CAM_FLASH, "Received Stream off Settings");
i2c_data = &(fctrl->i2c_data);
fctrl->streamoff_count = fctrl->streamoff_count + 1;
i2c_reg_settings = &i2c_data->streamoff_settings;
i2c_reg_settings->request_id = 0;
i2c_reg_settings->is_settings_valid = 1;
offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
csl_packet->cmd_buf_offset);
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
rc = cam_sensor_i2c_command_parser(&fctrl->io_master_info,
i2c_reg_settings,
cmd_desc, 1, NULL);
if (rc) {
CAM_ERR(CAM_FLASH,
"Failed in parsing i2c Stream off packets");
return rc;
}
break;
}
default:
CAM_ERR(CAM_FLASH, "Wrong Opcode : %d",
(csl_packet->header.op_code & 0xFFFFFF));
@ -1837,6 +1897,16 @@ int cam_flash_release_dev(struct cam_flash_ctrl *fctrl)
{
int rc = 0;
if (fctrl->i2c_data.streamoff_settings.is_settings_valid == true) {
fctrl->i2c_data.streamoff_settings.is_settings_valid = false;
rc = delete_request(&fctrl->i2c_data.streamoff_settings);
if (rc) {
CAM_WARN(CAM_FLASH,
"Failed to delete Stream off i2c_setting: %d",
rc);
}
}
if (fctrl->bridge_intf.device_hdl != 1) {
rc = cam_destroy_device_hdl(fctrl->bridge_intf.device_hdl);
if (rc)
@ -1847,6 +1917,7 @@ int cam_flash_release_dev(struct cam_flash_ctrl *fctrl)
fctrl->bridge_intf.link_hdl = -1;
fctrl->bridge_intf.session_hdl = -1;
fctrl->last_flush_req = 0;
fctrl->streamoff_count = 0;
}
return rc;

View file

@ -72,6 +72,7 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
flash_acq_dev.device_handle;
fctrl->bridge_intf.session_hdl =
flash_acq_dev.session_handle;
fctrl->apply_streamoff = false;
rc = copy_to_user(u64_to_user_ptr(cmd->handle),
&flash_acq_dev,
@ -126,6 +127,7 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
CAM_WARN(CAM_FLASH, "Power Down Failed");
}
fctrl->streamoff_count = 0;
fctrl->flash_state = CAM_FLASH_STATE_INIT;
break;
}
@ -165,6 +167,7 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
goto release_mutex;
}
fctrl->apply_streamoff = false;
fctrl->flash_state = CAM_FLASH_STATE_START;
break;
}
@ -493,6 +496,7 @@ static int cam_flash_component_bind(struct device *dev,
INIT_LIST_HEAD(&(fctrl->i2c_data.init_settings.list_head));
INIT_LIST_HEAD(&(fctrl->i2c_data.config_settings.list_head));
INIT_LIST_HEAD(&(fctrl->i2c_data.streamoff_settings.list_head));
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
INIT_LIST_HEAD(
&(fctrl->i2c_data.per_frame[i].list_head));
@ -641,6 +645,7 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client,
INIT_LIST_HEAD(&(fctrl->i2c_data.init_settings.list_head));
INIT_LIST_HEAD(&(fctrl->i2c_data.config_settings.list_head));
INIT_LIST_HEAD(&(fctrl->i2c_data.streamoff_settings.list_head));
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
INIT_LIST_HEAD(&(fctrl->i2c_data.per_frame[i].list_head));

View file

@ -46,6 +46,7 @@
#define CAM_FLASH_PACKET_OPCODE_INIT 0
#define CAM_FLASH_PACKET_OPCODE_SET_OPS 1
#define CAM_FLASH_PACKET_OPCODE_NON_REALTIME_SET_OPS 2
#define CAM_FLASH_PACKET_OPCODE_STREAM_OFF 3
struct cam_flash_ctrl;
@ -189,6 +190,8 @@ struct cam_flash_func_tbl {
* @io_master_info : Information about the communication master
* @i2c_data : I2C register settings
* @last_flush_req : last request to flush
* @streamoff_count : Count to hold the number of times stream off called
* @apply_streamoff : variable to store when to apply stream off
*/
struct cam_flash_ctrl {
char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH];
@ -217,6 +220,8 @@ struct cam_flash_ctrl {
struct camera_io_master io_master_info;
struct i2c_data_settings i2c_data;
uint32_t last_flush_req;
uint32_t streamoff_count;
int32_t apply_streamoff;
};
int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg);

View file

@ -212,6 +212,8 @@ struct cam_dma_buff_info {
struct cam_sec_buff_info {
struct dma_buf *buf;
struct dma_buf_attachment *attach;
struct sg_table *table;
enum dma_data_direction dir;
int ref_count;
dma_addr_t paddr;
@ -2876,6 +2878,8 @@ static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd,
mapping_info->dir = dma_dir;
mapping_info->ref_count = 1;
mapping_info->buf = dmabuf;
mapping_info->attach = attach;
mapping_info->table = table;
CAM_DBG(CAM_SMMU, "idx=%d, ion_fd=%d, dev=%pK, paddr=%pK, len=%u",
idx, ion_fd,
@ -2976,11 +2980,27 @@ static int cam_smmu_secure_unmap_buf_and_remove_from_list(
struct cam_sec_buff_info *mapping_info,
int idx)
{
if (!mapping_info) {
CAM_ERR(CAM_SMMU, "Error: List doesn't exist");
if ((!mapping_info->buf) || (!mapping_info->table) ||
(!mapping_info->attach)) {
CAM_ERR(CAM_SMMU, "Error: Invalid params dev = %pK, table = %pK",
(void *)iommu_cb_set.cb_info[idx].dev,
(void *)mapping_info->table);
CAM_ERR(CAM_SMMU, "Error:dma_buf = %pK, attach = %pK\n",
(void *)mapping_info->buf,
(void *)mapping_info->attach);
return -EINVAL;
}
/* skip cache operations */
mapping_info->attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
/* iommu buffer clean up */
dma_buf_unmap_attachment(mapping_info->attach,
mapping_info->table, mapping_info->dir);
dma_buf_detach(mapping_info->buf, mapping_info->attach);
dma_buf_put(mapping_info->buf);
mapping_info->buf = NULL;
list_del_init(&mapping_info->list);
CAM_DBG(CAM_SMMU, "unmap fd: %d, idx : %d", mapping_info->ion_fd, idx);

View file

@ -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.
*/
#include <linux/init.h>
@ -477,6 +477,7 @@ static int cam_sync_handle_create(struct cam_private_ioctl_arg *k_ioctl)
u64_to_user_ptr(k_ioctl->ioctl_ptr),
k_ioctl->size))
return -EFAULT;
sync_create.name[SYNC_DEBUG_NAME_LEN] = '\0';
result = cam_sync_create(&sync_create.sync_obj,
sync_create.name);