From 6fb7609c0b8232ca018bc00f20c87fbb042ce6e3 Mon Sep 17 00:00:00 2001 From: Shadul Shaikh Date: Fri, 13 Aug 2021 16:27:04 +0530 Subject: [PATCH 1/6] msm: camera: smmu: Unmap secure buffers in secure camera use case Dettach and unmap DMA buffers obtained previously from DMA attach and mappings respectively. CRs-Fixed: 3014632 Change-Id: If8f8ebe9fc270f2ba39a9a42ab7c7bfb0f79c4eb Signed-off-by: Shadul Shaikh --- drivers/cam_smmu/cam_smmu_api.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/cam_smmu/cam_smmu_api.c b/drivers/cam_smmu/cam_smmu_api.c index 05b3700bddfb..0083d8674d65 100644 --- a/drivers/cam_smmu/cam_smmu_api.c +++ b/drivers/cam_smmu/cam_smmu_api.c @@ -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); From 9d68bffd2aaf45bc8c938cb847c64709c3960f1b Mon Sep 17 00:00:00 2001 From: Shravya Samala Date: Wed, 11 Aug 2021 11:06:27 +0530 Subject: [PATCH 2/6] msm: camera: cdm: Acquire mutex lock before accessing client data There is a chance of use after release of client data in cdm internal operation calls. Hence acquire mutex lock whenever accessing client data to avoid use after release scenario. CRs-Fixed: 3010261 Change-Id: Iaf7f41d56301299a6f63a5dc1090334063019881 Signed-off-by: Shravya Samala --- drivers/cam_cdm/cam_cdm_core_common.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/cam_cdm/cam_cdm_core_common.c b/drivers/cam_cdm/cam_cdm_core_common.c index d7ddcee6d9b7..fd84b8d6866b 100644 --- a/drivers/cam_cdm/cam_cdm_core_common.c +++ b/drivers/cam_cdm/cam_cdm_core_common.c @@ -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 @@ -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; From 1c390133114972aee7dc4b68a17a6a1a76c722dc Mon Sep 17 00:00:00 2001 From: chengxue Date: Mon, 16 Aug 2021 20:31:32 +0800 Subject: [PATCH 3/6] msm: camera: reqmgr: Delay to do slot reset for finished req For boken mode with hw sync enable, a link and its synclink streaming with sync. if a bubble condition happens on a link, and can not wait all buf done to clear the isp ctx process_bubble flag in time, there may apply fails on isp during the bubble recovery flow. current crm reset in_q slot after req's report has finished. this may lead to a synclink slot not found while do ready check. So delay to do slot reset by referring the link delay. CRs-Fixed: 2996710 Change-Id: Ice8c340a9f478a69d97e3a7c77e0d0a263be66fa Signed-off-by: chengxue --- drivers/cam_req_mgr/cam_req_mgr_core.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.c b/drivers/cam_req_mgr/cam_req_mgr_core.c index bb8f203489db..8fdc5ce4a72e 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/cam_req_mgr/cam_req_mgr_core.c @@ -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); } } From 6e6855210594d192580884e757d5205e788e4a80 Mon Sep 17 00:00:00 2001 From: Dharmender Sharma Date: Fri, 30 Jul 2021 20:19:00 +0530 Subject: [PATCH 4/6] msm: camera: isp: Support all patterns for TOP TPG It provide support for differeent TPG patterns like color bar, incrementing and user defined. CRs-Fixed: 3026095 Change-Id: If18c99fb759f9cdb5bf8950c54f719d188a5e4ae Signed-off-by: Dharmender Sharma --- drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c | 17 +++++- drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h | 4 +- .../isp_hw_mgr/isp_hw/include/cam_isp_hw.h | 1 + .../isp_hw/include/cam_top_tpg_hw_intf.h | 5 +- .../isp_hw/top_tpg/cam_top_tpg101.h | 3 +- .../isp_hw/top_tpg/cam_top_tpg_core.c | 18 +++++- .../isp_hw/top_tpg/cam_top_tpg_core.h | 5 +- .../isp_hw/top_tpg/cam_top_tpg_ver1.c | 55 ++++++++++++++++++- .../isp_hw/top_tpg/cam_top_tpg_ver1.h | 3 +- 9 files changed, 101 insertions(+), 10 deletions(-) diff --git a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c index d3e2b3d24cf9..0f9c8834c828 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c @@ -3228,6 +3228,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]) @@ -5789,9 +5800,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; } @@ -5809,6 +5821,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, diff --git a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h index b4b75d91103b..ea12717945e2 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h +++ b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h @@ -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; }; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h index 6638b9269a58..80ca8847b069 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h @@ -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, }; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_top_tpg_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_top_tpg_hw_intf.h index 1aa9d26e11c1..50191f075307 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_top_tpg_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_top_tpg_hw_intf.h @@ -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 */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg101.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg101.h index 0b99a3f6d1ba..937bc9886451 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg101.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg101.h @@ -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 = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.c index 23b62f6fdb85..1d1673b9685b 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.c @@ -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 @@ -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); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h index d904eb949817..10a8a5bc1779 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h @@ -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; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.c index 2f7d461383a9..821f6040a072 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.c @@ -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 @@ -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); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.h index b0c5d68f04f1..9ceba49e3448 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.h @@ -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); From 1510d5b82f938509a6bccecfe8f353e988b4bf07 Mon Sep 17 00:00:00 2001 From: Dharmender Sharma Date: Thu, 5 Aug 2021 15:05:38 +0530 Subject: [PATCH 5/6] msm: camera: jpeg: JPEG HW and Camnoc MISR Support for Camnoc MISR for JPEG DMA and Encoder. Also added support for seprate target files. CRs-Fixed: 3012752 Change-Id: I5e066d5d871f58073f669c01270d5b64ce16088e Signed-off-by: Dharmender Sharma Signed-off-by: Shravya Samala --- drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c | 86 ++++++- drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h | 6 + .../jpeg_hw/include/cam_jpeg_hw_intf.h | 18 ++ .../cam_jpeg_dma_165_hw_info_ver_4_2_0.h | 75 ++++++ .../cam_jpeg_dma_580_hw_info_ver_4_2_0.h | 75 ++++++ .../jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c | 242 +++++++++++++++++- .../jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h | 37 +++ .../jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c | 10 + .../cam_jpeg_enc_165_hw_info_ver_4_2_0.h | 102 ++++++++ .../cam_jpeg_enc_580_hw_info_ver_4_2_0.h | 102 ++++++++ .../jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c | 204 +++++++++++++++ .../jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h | 32 +++ .../jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c | 10 + 13 files changed, 994 insertions(+), 5 deletions(-) create mode 100644 drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/cam_jpeg_dma_165_hw_info_ver_4_2_0.h create mode 100644 drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/cam_jpeg_dma_580_hw_info_ver_4_2_0.h create mode 100644 drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_165_hw_info_ver_4_2_0.h create mode 100644 drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_580_hw_info_ver_4_2_0.h diff --git a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 8078ee59dc20..532f6a5a0c1e 100644 --- a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -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); diff --git a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h index c4cd35307701..34d98172b8b6 100644 --- a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h +++ b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h @@ -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] diff --git a/drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h b/drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h index 1856e6e3cc13..9bb20da715ab 100644 --- a/drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h +++ b/drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h @@ -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, }; diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/cam_jpeg_dma_165_hw_info_ver_4_2_0.h b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/cam_jpeg_dma_165_hw_info_ver_4_2_0.h new file mode 100644 index 000000000000..81e146938265 --- /dev/null +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/cam_jpeg_dma_165_hw_info_ver_4_2_0.h @@ -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 */ diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/cam_jpeg_dma_580_hw_info_ver_4_2_0.h b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/cam_jpeg_dma_580_hw_info_ver_4_2_0.h new file mode 100644 index 000000000000..b4f4ce10325d --- /dev/null +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/cam_jpeg_dma_580_hw_info_ver_4_2_0.h @@ -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 */ diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c index bae4f3d9982d..081a52dca755 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c @@ -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; diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h index 8f08033b04f6..c8c398072306 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h @@ -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 { diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c index c5c4b78cc1f4..512fc3225c20 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c @@ -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); diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_165_hw_info_ver_4_2_0.h b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_165_hw_info_ver_4_2_0.h new file mode 100644 index 000000000000..af434b2928bd --- /dev/null +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_165_hw_info_ver_4_2_0.h @@ -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 */ diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_580_hw_info_ver_4_2_0.h b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_580_hw_info_ver_4_2_0.h new file mode 100644 index 000000000000..647bdb514957 --- /dev/null +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_580_hw_info_ver_4_2_0.h @@ -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 */ diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c index 5f79260e1391..a767bb2bc75b 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c @@ -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; diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h index 8dfc443ccd70..af52512ac43c 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h @@ -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 { diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c index 5b6c307778a8..467d39958fe4 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c @@ -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); From ed7d45ddc51e148bda5e67879a9df75d1fc94f83 Mon Sep 17 00:00:00 2001 From: Shravya Samala Date: Mon, 6 Sep 2021 21:12:00 +0530 Subject: [PATCH 6/6] msm: camera: jpeg: Ensure in/out map entries are within allowed range Added checks to make sure in_map /out_map entries of packet io configs are within expected maximum value. CRs-Fixed: 3007258 Change-Id: I7e5a652cd8f9ae104a10a2af551fe49930849b2d Signed-off-by: Shravya Samala --- drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 8078ee59dc20..fa86ad313541 100644 --- a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -743,10 +743,11 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv, } if ((packet->num_cmd_buf > 5) || !packet->num_patches || - !packet->num_io_configs) { - CAM_ERR(CAM_JPEG, "wrong number of cmd/patch info: %u %u", - packet->num_cmd_buf, - packet->num_patches); + !packet->num_io_configs || + (packet->num_io_configs > CAM_JPEG_IMAGE_MAX)) { + CAM_ERR(CAM_JPEG, + "wrong number of cmd/patch/io_configs info: %u %u %u", + packet->num_cmd_buf, packet->num_patches, packet->num_io_configs); return -EINVAL; }