mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 21:59:12 -04:00
Merge "msm: camera: jpeg: Add dma driver implementation" into camera-kernel.lnx.4.0
This commit is contained in:
commit
9d3a46d91e
8 changed files with 459 additions and 86 deletions
|
|
@ -38,6 +38,112 @@ static struct cam_jpeg_hw_mgr g_jpeg_hw_mgr;
|
|||
static int32_t cam_jpeg_hw_mgr_cb(uint32_t irq_status,
|
||||
int32_t result_size, void *data);
|
||||
static int cam_jpeg_mgr_process_cmd(void *priv, void *data);
|
||||
static int cam_jpeg_insert_cdm_change_base(
|
||||
struct cam_hw_config_args *config_args,
|
||||
struct cam_jpeg_hw_ctx_data *ctx_data,
|
||||
struct cam_jpeg_hw_mgr *hw_mgr);
|
||||
|
||||
static int cam_jpeg_process_next_hw_update(void *priv, void *data)
|
||||
{
|
||||
int rc;
|
||||
int i = 0;
|
||||
struct cam_jpeg_hw_mgr *hw_mgr = priv;
|
||||
struct cam_hw_update_entry *cmd;
|
||||
struct cam_cdm_bl_request *cdm_cmd;
|
||||
struct cam_hw_config_args *config_args = NULL;
|
||||
struct cam_jpeg_hw_ctx_data *ctx_data = NULL;
|
||||
uint32_t dev_type;
|
||||
struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL;
|
||||
uint32_t cdm_cfg_to_insert = 0;
|
||||
|
||||
if (!data || !priv) {
|
||||
CAM_ERR(CAM_JPEG, "Invalid data");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx_data = (struct cam_jpeg_hw_ctx_data *)data;
|
||||
dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
|
||||
p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];
|
||||
config_args = (struct cam_hw_config_args *)&p_cfg_req->hw_cfg_args;
|
||||
|
||||
if (!hw_mgr->devices[dev_type][0]->hw_ops.reset) {
|
||||
CAM_ERR(CAM_JPEG, "op reset null ");
|
||||
rc = -EFAULT;
|
||||
goto end_error;
|
||||
}
|
||||
rc = hw_mgr->devices[dev_type][0]->hw_ops.reset(
|
||||
hw_mgr->devices[dev_type][0]->hw_priv,
|
||||
NULL, 0);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_JPEG, "jpeg hw reset failed %d", rc);
|
||||
goto end_error;
|
||||
}
|
||||
|
||||
cdm_cmd = ctx_data->cdm_cmd;
|
||||
cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE;
|
||||
cdm_cmd->flag = false;
|
||||
cdm_cmd->userdata = NULL;
|
||||
cdm_cmd->cookie = 0;
|
||||
cdm_cmd->cmd_arrary_count = 0;
|
||||
|
||||
/* insert cdm chage base cmd */
|
||||
rc = cam_jpeg_insert_cdm_change_base(config_args,
|
||||
ctx_data, hw_mgr);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_JPEG, "insert change base failed %d", rc);
|
||||
goto end_error;
|
||||
}
|
||||
|
||||
/* insert next cdm payload at index */
|
||||
/* for enc or dma 1st pass at index 1 */
|
||||
/* for dma 2nd pass at index 2, for 3rd at 4 */
|
||||
if (p_cfg_req->num_hw_entry_processed == 0)
|
||||
cdm_cfg_to_insert = CAM_JPEG_CFG;
|
||||
else
|
||||
cdm_cfg_to_insert = p_cfg_req->num_hw_entry_processed + 2;
|
||||
|
||||
CAM_DBG(CAM_JPEG, "processed %d total %d using cfg entry %d for %pK",
|
||||
p_cfg_req->num_hw_entry_processed,
|
||||
config_args->num_hw_update_entries,
|
||||
cdm_cfg_to_insert,
|
||||
p_cfg_req);
|
||||
|
||||
cmd = (config_args->hw_update_entries + cdm_cfg_to_insert);
|
||||
cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].bl_addr.mem_handle =
|
||||
cmd->handle;
|
||||
cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].offset =
|
||||
cmd->offset;
|
||||
cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].len =
|
||||
cmd->len;
|
||||
CAM_DBG(CAM_JPEG, "i %d entry h %d o %d l %d",
|
||||
i, cmd->handle, cmd->offset, cmd->len);
|
||||
cdm_cmd->cmd_arrary_count++;
|
||||
|
||||
rc = cam_cdm_submit_bls(
|
||||
hw_mgr->cdm_info[dev_type][0].cdm_handle,
|
||||
cdm_cmd);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_JPEG, "Failed to apply the configs %d", rc);
|
||||
goto end_error;
|
||||
}
|
||||
|
||||
if (!hw_mgr->devices[dev_type][0]->hw_ops.start) {
|
||||
CAM_ERR(CAM_JPEG, "op start null ");
|
||||
rc = -EINVAL;
|
||||
goto end_error;
|
||||
}
|
||||
rc = hw_mgr->devices[dev_type][0]->hw_ops.start(
|
||||
hw_mgr->devices[dev_type][0]->hw_priv, NULL, 0);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_JPEG, "Failed to apply the configs %d",
|
||||
rc);
|
||||
goto end_error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
end_error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_jpeg_mgr_process_irq(void *priv, void *data)
|
||||
{
|
||||
|
|
@ -85,6 +191,21 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
p_cfg_req->num_hw_entry_processed++;
|
||||
CAM_DBG(CAM_JPEG, "hw entry processed %d",
|
||||
p_cfg_req->num_hw_entry_processed);
|
||||
|
||||
if ((task_data->result_size > 0) &&
|
||||
(p_cfg_req->num_hw_entry_processed <
|
||||
p_cfg_req->hw_cfg_args.num_hw_update_entries - 2)) {
|
||||
/* start processing next entry before marking device free */
|
||||
rc = cam_jpeg_process_next_hw_update(priv, ctx_data);
|
||||
if (!rc) {
|
||||
mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_cb;
|
||||
irq_cb.data = NULL;
|
||||
irq_cb.b_set_cb = false;
|
||||
|
|
@ -281,7 +402,9 @@ static int cam_jpeg_insert_cdm_change_base(
|
|||
|
||||
if (config_args->hw_update_entries[CAM_JPEG_CHBASE].offset >=
|
||||
ch_base_len) {
|
||||
CAM_ERR(CAM_JPEG, "Not enough buf");
|
||||
CAM_ERR(CAM_JPEG, "Not enough buf offset %d len %d",
|
||||
config_args->hw_update_entries[CAM_JPEG_CHBASE].offset,
|
||||
ch_base_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
CAM_DBG(CAM_JPEG, "iova %pK len %zu offset %d",
|
||||
|
|
@ -321,8 +444,6 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
|
|||
int rc;
|
||||
int i = 0;
|
||||
struct cam_jpeg_hw_mgr *hw_mgr = priv;
|
||||
struct cam_hw_update_entry *cmd;
|
||||
struct cam_cdm_bl_request *cdm_cmd;
|
||||
struct cam_hw_config_args *config_args = NULL;
|
||||
struct cam_jpeg_hw_ctx_data *ctx_data = NULL;
|
||||
uintptr_t request_id = 0;
|
||||
|
|
@ -424,71 +545,13 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
|
|||
goto end_callcb;
|
||||
}
|
||||
|
||||
if (!hw_mgr->devices[dev_type][0]->hw_ops.reset) {
|
||||
CAM_ERR(CAM_JPEG, "op reset null ");
|
||||
rc = -EFAULT;
|
||||
goto end_callcb;
|
||||
}
|
||||
rc = hw_mgr->devices[dev_type][0]->hw_ops.reset(
|
||||
hw_mgr->devices[dev_type][0]->hw_priv,
|
||||
NULL, 0);
|
||||
/* insert one of the cdm payloads */
|
||||
rc = cam_jpeg_process_next_hw_update(priv, ctx_data);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_JPEG, "jpeg hw reset failed %d", rc);
|
||||
CAM_ERR(CAM_JPEG, "next hw update failed %d", rc);
|
||||
goto end_callcb;
|
||||
}
|
||||
|
||||
cdm_cmd = ctx_data->cdm_cmd;
|
||||
cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE;
|
||||
cdm_cmd->flag = false;
|
||||
cdm_cmd->userdata = NULL;
|
||||
cdm_cmd->cookie = 0;
|
||||
cdm_cmd->cmd_arrary_count = 0;
|
||||
cdm_cmd->gen_irq_arb = false;
|
||||
|
||||
rc = cam_jpeg_insert_cdm_change_base(config_args,
|
||||
ctx_data, hw_mgr);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_JPEG, "insert change base failed %d", rc);
|
||||
goto end_callcb;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_JPEG, "num hw up %d", config_args->num_hw_update_entries);
|
||||
for (i = CAM_JPEG_CFG; i < (config_args->num_hw_update_entries - 1);
|
||||
i++) {
|
||||
cmd = (config_args->hw_update_entries + i);
|
||||
cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].bl_addr.mem_handle
|
||||
= cmd->handle;
|
||||
cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].offset =
|
||||
cmd->offset;
|
||||
cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].len =
|
||||
cmd->len;
|
||||
cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].arbitrate =
|
||||
false;
|
||||
CAM_DBG(CAM_JPEG, "i %d entry h %d o %d l %d",
|
||||
i, cmd->handle, cmd->offset, cmd->len);
|
||||
cdm_cmd->cmd_arrary_count++;
|
||||
}
|
||||
|
||||
rc = cam_cdm_submit_bls(
|
||||
hw_mgr->cdm_info[dev_type][0].cdm_handle, cdm_cmd);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_JPEG, "Failed to apply the configs %d", rc);
|
||||
goto end_callcb;
|
||||
}
|
||||
|
||||
if (!hw_mgr->devices[dev_type][0]->hw_ops.start) {
|
||||
CAM_ERR(CAM_JPEG, "op start null ");
|
||||
rc = -EINVAL;
|
||||
goto end_callcb;
|
||||
}
|
||||
rc = hw_mgr->devices[dev_type][0]->hw_ops.start(
|
||||
hw_mgr->devices[dev_type][0]->hw_priv,
|
||||
NULL, 0);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_JPEG, "Failed to start hw %d",
|
||||
rc);
|
||||
goto end_callcb;
|
||||
}
|
||||
p_cfg_req->submit_timestamp = ktime_get();
|
||||
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
|
|
@ -567,6 +630,7 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args)
|
|||
|
||||
request_id = (uintptr_t)config_args->priv;
|
||||
p_cfg_req->req_id = request_id;
|
||||
p_cfg_req->num_hw_entry_processed = 0;
|
||||
hw_update_entries = config_args->hw_update_entries;
|
||||
CAM_DBG(CAM_JPEG, "ctx_data = %pK req_id = %lld %zd",
|
||||
ctx_data, request_id, (uintptr_t)config_args->priv);
|
||||
|
|
@ -781,6 +845,7 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv,
|
|||
i, io_cfg_ptr[i].direction, io_cfg_ptr[i].fence);
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_JPEG, "received num cmd buf %d", packet->num_cmd_buf);
|
||||
|
||||
j = prepare_args->num_hw_update_entries;
|
||||
rc = cam_packet_util_get_kmd_buffer(packet, &kmd_buf);
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ struct cam_jpeg_hw_cdm_info_t {
|
|||
* @dev_type: Dev type for cfg request
|
||||
* @req_id: Request Id
|
||||
* @submit_timestamp: Timestamp of submitting request
|
||||
* @num_hw_entry_processed: Cdm payloads already processed
|
||||
*/
|
||||
struct cam_jpeg_hw_cfg_req {
|
||||
struct list_head list;
|
||||
|
|
@ -83,6 +84,7 @@ struct cam_jpeg_hw_cfg_req {
|
|||
uint32_t dev_type;
|
||||
uintptr_t req_id;
|
||||
ktime_t submit_timestamp;
|
||||
uint32_t num_hw_entry_processed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef CAM_JPEG_DMA_HW_INFO_VER_4_2_0_H
|
||||
#define CAM_JPEG_DMA_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_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_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,
|
||||
},
|
||||
.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,
|
||||
},
|
||||
.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,
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* CAM_JPEG_DMA_HW_INFO_VER_4_2_0_H */
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
|
|
@ -23,6 +23,15 @@
|
|||
#include "cam_cpas_api.h"
|
||||
#include "cam_debug_util.h"
|
||||
|
||||
#define CAM_JPEG_HW_IRQ_IS_FRAME_DONE(jpeg_irq_status, hi) \
|
||||
((jpeg_irq_status) & (hi)->int_status.framedone)
|
||||
#define CAM_JPEG_HW_IRQ_IS_RESET_ACK(jpeg_irq_status, hi) \
|
||||
((jpeg_irq_status) & (hi)->int_status.resetdone)
|
||||
#define CAM_JPEG_HW_IRQ_IS_STOP_DONE(jpeg_irq_status, hi) \
|
||||
((jpeg_irq_status) & (hi)->int_status.stopdone)
|
||||
|
||||
#define CAM_JPEG_DMA_RESET_TIMEOUT msecs_to_jiffies(500)
|
||||
|
||||
int cam_jpeg_dma_init_hw(void *device_priv,
|
||||
void *init_hw_args, uint32_t arg_size)
|
||||
{
|
||||
|
|
@ -132,7 +141,7 @@ int cam_jpeg_dma_deinit_hw(void *device_priv,
|
|||
|
||||
rc = cam_jpeg_dma_disable_soc_resources(soc_info);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_JPEG, "soc enable failed %d", rc);
|
||||
CAM_ERR(CAM_JPEG, "soc disable failed %d", rc);
|
||||
|
||||
rc = cam_cpas_stop(core_info->cpas_handle);
|
||||
if (rc)
|
||||
|
|
@ -143,6 +152,226 @@ int cam_jpeg_dma_deinit_hw(void *device_priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data)
|
||||
{
|
||||
struct cam_hw_info *jpeg_dma_dev = data;
|
||||
struct cam_jpeg_dma_device_core_info *core_info = NULL;
|
||||
uint32_t irq_status = 0;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
|
||||
void __iomem *mem_base;
|
||||
|
||||
if (!jpeg_dma_dev) {
|
||||
CAM_ERR(CAM_JPEG, "Invalid args");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
soc_info = &jpeg_dma_dev->soc_info;
|
||||
core_info = (struct cam_jpeg_dma_device_core_info *)
|
||||
jpeg_dma_dev->core_info;
|
||||
hw_info = core_info->jpeg_dma_hw_info;
|
||||
mem_base = soc_info->reg_map[0].mem_base;
|
||||
|
||||
irq_status = cam_io_r_mb(mem_base +
|
||||
core_info->jpeg_dma_hw_info->reg_offset.int_status);
|
||||
cam_io_w_mb(irq_status,
|
||||
soc_info->reg_map[0].mem_base +
|
||||
core_info->jpeg_dma_hw_info->reg_offset.int_clr);
|
||||
CAM_DBG(CAM_JPEG, "irq_num %d irq_status = %x , core_state %d",
|
||||
irq_num, irq_status, core_info->core_state);
|
||||
if (CAM_JPEG_HW_IRQ_IS_FRAME_DONE(irq_status, hw_info)) {
|
||||
spin_lock(&jpeg_dma_dev->hw_lock);
|
||||
if (core_info->core_state == CAM_JPEG_DMA_CORE_READY) {
|
||||
core_info->result_size = 1;
|
||||
CAM_DBG(CAM_JPEG, "result_size %d",
|
||||
core_info->result_size);
|
||||
core_info->core_state =
|
||||
CAM_JPEG_DMA_CORE_RESETTING_ON_DONE;
|
||||
cam_io_w_mb(hw_info->reg_val.reset_cmd,
|
||||
mem_base + hw_info->reg_offset.reset_cmd);
|
||||
} else {
|
||||
CAM_WARN(CAM_JPEG, "unexpected frame done ");
|
||||
core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
|
||||
}
|
||||
spin_unlock(&jpeg_dma_dev->hw_lock);
|
||||
}
|
||||
|
||||
if (CAM_JPEG_HW_IRQ_IS_RESET_ACK(irq_status, hw_info)) {
|
||||
spin_lock(&jpeg_dma_dev->hw_lock);
|
||||
if (core_info->core_state == CAM_JPEG_DMA_CORE_RESETTING) {
|
||||
core_info->core_state = CAM_JPEG_DMA_CORE_READY;
|
||||
core_info->result_size = -1;
|
||||
complete(&jpeg_dma_dev->hw_complete);
|
||||
} else if (core_info->core_state ==
|
||||
CAM_JPEG_DMA_CORE_RESETTING_ON_DONE) {
|
||||
if (core_info->irq_cb.jpeg_hw_mgr_cb) {
|
||||
core_info->irq_cb.jpeg_hw_mgr_cb(irq_status,
|
||||
core_info->result_size,
|
||||
core_info->irq_cb.data);
|
||||
} else {
|
||||
CAM_WARN(CAM_JPEG, "unexpected frame done");
|
||||
}
|
||||
core_info->result_size = -1;
|
||||
core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
|
||||
} else {
|
||||
CAM_ERR(CAM_JPEG, "unexpected reset irq");
|
||||
}
|
||||
spin_unlock(&jpeg_dma_dev->hw_lock);
|
||||
}
|
||||
if (CAM_JPEG_HW_IRQ_IS_STOP_DONE(irq_status, hw_info)) {
|
||||
spin_lock(&jpeg_dma_dev->hw_lock);
|
||||
if (core_info->core_state == CAM_JPEG_DMA_CORE_ABORTING) {
|
||||
core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
|
||||
complete(&jpeg_dma_dev->hw_complete);
|
||||
if (core_info->irq_cb.jpeg_hw_mgr_cb) {
|
||||
core_info->irq_cb.jpeg_hw_mgr_cb(irq_status,
|
||||
-1,
|
||||
core_info->irq_cb.data);
|
||||
}
|
||||
} else {
|
||||
CAM_ERR(CAM_JPEG, "unexpected abort irq");
|
||||
}
|
||||
spin_unlock(&jpeg_dma_dev->hw_lock);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int cam_jpeg_dma_reset_hw(void *data,
|
||||
void *start_args, uint32_t arg_size)
|
||||
{
|
||||
struct cam_hw_info *jpeg_dma_dev = data;
|
||||
struct cam_jpeg_dma_device_core_info *core_info = NULL;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
|
||||
void __iomem *mem_base;
|
||||
unsigned long rem_jiffies;
|
||||
|
||||
if (!jpeg_dma_dev) {
|
||||
CAM_ERR(CAM_JPEG, "Invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* maskdisable.clrirq.maskenable.resetcmd */
|
||||
soc_info = &jpeg_dma_dev->soc_info;
|
||||
core_info = (struct cam_jpeg_dma_device_core_info *)
|
||||
jpeg_dma_dev->core_info;
|
||||
hw_info = core_info->jpeg_dma_hw_info;
|
||||
mem_base = soc_info->reg_map[0].mem_base;
|
||||
|
||||
mutex_lock(&core_info->core_mutex);
|
||||
spin_lock(&jpeg_dma_dev->hw_lock);
|
||||
if (core_info->core_state == CAM_JPEG_DMA_CORE_RESETTING) {
|
||||
CAM_ERR(CAM_JPEG, "dma alrady resetting");
|
||||
spin_unlock(&jpeg_dma_dev->hw_lock);
|
||||
mutex_unlock(&core_info->core_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
reinit_completion(&jpeg_dma_dev->hw_complete);
|
||||
|
||||
core_info->core_state = CAM_JPEG_DMA_CORE_RESETTING;
|
||||
spin_unlock(&jpeg_dma_dev->hw_lock);
|
||||
|
||||
cam_io_w_mb(hw_info->reg_val.int_mask_disable_all,
|
||||
mem_base + hw_info->reg_offset.int_mask);
|
||||
cam_io_w_mb(hw_info->reg_val.int_clr_clearall,
|
||||
mem_base + hw_info->reg_offset.int_clr);
|
||||
cam_io_w_mb(hw_info->reg_val.int_mask_enable_all,
|
||||
mem_base + hw_info->reg_offset.int_mask);
|
||||
cam_io_w_mb(hw_info->reg_val.reset_cmd,
|
||||
mem_base + hw_info->reg_offset.reset_cmd);
|
||||
|
||||
rem_jiffies = wait_for_completion_timeout(&jpeg_dma_dev->hw_complete,
|
||||
CAM_JPEG_DMA_RESET_TIMEOUT);
|
||||
if (!rem_jiffies) {
|
||||
CAM_ERR(CAM_JPEG, "dma error Reset Timeout");
|
||||
core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
|
||||
}
|
||||
|
||||
mutex_unlock(&core_info->core_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cam_jpeg_dma_start_hw(void *data,
|
||||
void *start_args, uint32_t arg_size)
|
||||
{
|
||||
struct cam_hw_info *jpeg_dma_dev = data;
|
||||
struct cam_jpeg_dma_device_core_info *core_info = NULL;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
|
||||
void __iomem *mem_base;
|
||||
|
||||
if (!jpeg_dma_dev) {
|
||||
CAM_ERR(CAM_JPEG, "Invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
soc_info = &jpeg_dma_dev->soc_info;
|
||||
core_info = (struct cam_jpeg_dma_device_core_info *)
|
||||
jpeg_dma_dev->core_info;
|
||||
hw_info = core_info->jpeg_dma_hw_info;
|
||||
mem_base = soc_info->reg_map[0].mem_base;
|
||||
|
||||
if (core_info->core_state != CAM_JPEG_DMA_CORE_READY) {
|
||||
CAM_ERR(CAM_JPEG, "Error not ready");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_JPEG, "Starting DMA");
|
||||
cam_io_w_mb(0x00000601,
|
||||
mem_base + hw_info->reg_offset.int_mask);
|
||||
cam_io_w_mb(hw_info->reg_val.hw_cmd_start,
|
||||
mem_base + hw_info->reg_offset.hw_cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cam_jpeg_dma_stop_hw(void *data,
|
||||
void *stop_args, uint32_t arg_size)
|
||||
{
|
||||
struct cam_hw_info *jpeg_dma_dev = data;
|
||||
struct cam_jpeg_dma_device_core_info *core_info = NULL;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
|
||||
void __iomem *mem_base;
|
||||
unsigned long rem_jiffies;
|
||||
|
||||
if (!jpeg_dma_dev) {
|
||||
CAM_ERR(CAM_JPEG, "Invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
soc_info = &jpeg_dma_dev->soc_info;
|
||||
core_info = (struct cam_jpeg_dma_device_core_info *)
|
||||
jpeg_dma_dev->core_info;
|
||||
hw_info = core_info->jpeg_dma_hw_info;
|
||||
mem_base = soc_info->reg_map[0].mem_base;
|
||||
|
||||
mutex_lock(&core_info->core_mutex);
|
||||
spin_lock(&jpeg_dma_dev->hw_lock);
|
||||
if (core_info->core_state == CAM_JPEG_DMA_CORE_ABORTING) {
|
||||
CAM_ERR(CAM_JPEG, "alrady stopping");
|
||||
spin_unlock(&jpeg_dma_dev->hw_lock);
|
||||
mutex_unlock(&core_info->core_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
reinit_completion(&jpeg_dma_dev->hw_complete);
|
||||
core_info->core_state = CAM_JPEG_DMA_CORE_ABORTING;
|
||||
spin_unlock(&jpeg_dma_dev->hw_lock);
|
||||
|
||||
cam_io_w_mb(hw_info->reg_val.hw_cmd_stop,
|
||||
mem_base + hw_info->reg_offset.hw_cmd);
|
||||
|
||||
rem_jiffies = wait_for_completion_timeout(&jpeg_dma_dev->hw_complete,
|
||||
CAM_JPEG_DMA_RESET_TIMEOUT);
|
||||
if (!rem_jiffies) {
|
||||
CAM_ERR(CAM_JPEG, "error Reset Timeout");
|
||||
core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
|
||||
}
|
||||
|
||||
mutex_unlock(&core_info->core_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
|
||||
void *cmd_args, uint32_t arg_size)
|
||||
{
|
||||
|
|
@ -187,11 +416,7 @@ int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
|
|||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc)
|
||||
CAM_ERR(CAM_JPEG, "error cmdtype %d rc = %d", cmd_type, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data)
|
||||
{
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef CAM_JPEG_DMA_CORE_H
|
||||
|
|
@ -10,17 +10,48 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-buf.h>
|
||||
|
||||
#include "cam_jpeg_hw_intf.h"
|
||||
|
||||
struct cam_jpeg_dma_reg_offsets {
|
||||
uint32_t hw_version;
|
||||
uint32_t int_status;
|
||||
uint32_t int_clr;
|
||||
uint32_t int_mask;
|
||||
uint32_t hw_cmd;
|
||||
uint32_t reset_cmd;
|
||||
uint32_t encode_size;
|
||||
};
|
||||
|
||||
struct cam_jpeg_dma_regval {
|
||||
uint32_t int_clr_clearall;
|
||||
uint32_t int_mask_disable_all;
|
||||
uint32_t int_mask_enable_all;
|
||||
uint32_t hw_cmd_start;
|
||||
uint32_t reset_cmd;
|
||||
uint32_t hw_cmd_stop;
|
||||
};
|
||||
|
||||
struct cam_jpeg_dma_int_status {
|
||||
uint32_t framedone;
|
||||
uint32_t resetdone;
|
||||
uint32_t iserror;
|
||||
uint32_t stopdone;
|
||||
};
|
||||
|
||||
struct cam_jpeg_dma_device_hw_info {
|
||||
uint32_t reserved;
|
||||
struct cam_jpeg_dma_reg_offsets reg_offset;
|
||||
struct cam_jpeg_dma_regval reg_val;
|
||||
struct cam_jpeg_dma_int_status int_status;
|
||||
};
|
||||
|
||||
enum cam_jpeg_dma_core_state {
|
||||
CAM_JPEG_DMA_CORE_NOT_READY,
|
||||
CAM_JPEG_DMA_CORE_READY,
|
||||
CAM_JPEG_DMA_CORE_RESETTING,
|
||||
CAM_JPEG_DMA_CORE_ABORTING,
|
||||
CAM_JPEG_DMA_CORE_RESETTING_ON_DONE,
|
||||
CAM_JPEG_DMA_CORE_STATE_MAX,
|
||||
};
|
||||
|
||||
|
|
@ -31,12 +62,19 @@ struct cam_jpeg_dma_device_core_info {
|
|||
struct cam_jpeg_set_irq_cb irq_cb;
|
||||
int32_t ref_count;
|
||||
struct mutex core_mutex;
|
||||
int32_t result_size;
|
||||
};
|
||||
|
||||
int cam_jpeg_dma_init_hw(void *device_priv,
|
||||
void *init_hw_args, uint32_t arg_size);
|
||||
int cam_jpeg_dma_deinit_hw(void *device_priv,
|
||||
void *init_hw_args, uint32_t arg_size);
|
||||
int cam_jpeg_dma_start_hw(void *device_priv,
|
||||
void *start_hw_args, uint32_t arg_size);
|
||||
int cam_jpeg_dma_stop_hw(void *device_priv,
|
||||
void *stop_hw_args, uint32_t arg_size);
|
||||
int cam_jpeg_dma_reset_hw(void *device_priv,
|
||||
void *reset_hw_args, uint32_t arg_size);
|
||||
int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
|
||||
void *cmd_args, uint32_t arg_size);
|
||||
irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data);
|
||||
|
|
|
|||
|
|
@ -18,12 +18,9 @@
|
|||
#include "cam_jpeg_hw_mgr_intf.h"
|
||||
#include "cam_cpas_api.h"
|
||||
#include "cam_debug_util.h"
|
||||
#include "cam_jpeg_dma_hw_info_ver_4_2_0.h"
|
||||
#include "camera_main.h"
|
||||
|
||||
static struct cam_jpeg_dma_device_hw_info cam_jpeg_dma_hw_info = {
|
||||
.reserved = 0,
|
||||
};
|
||||
|
||||
static int cam_jpeg_dma_register_cpas(struct cam_hw_soc_info *soc_info,
|
||||
struct cam_jpeg_dma_device_core_info *core_info,
|
||||
uint32_t hw_idx)
|
||||
|
|
@ -90,6 +87,9 @@ static int cam_jpeg_dma_component_bind(struct device *dev,
|
|||
jpeg_dma_dev_intf->hw_priv = jpeg_dma_dev;
|
||||
jpeg_dma_dev_intf->hw_ops.init = cam_jpeg_dma_init_hw;
|
||||
jpeg_dma_dev_intf->hw_ops.deinit = cam_jpeg_dma_deinit_hw;
|
||||
jpeg_dma_dev_intf->hw_ops.start = cam_jpeg_dma_start_hw;
|
||||
jpeg_dma_dev_intf->hw_ops.stop = cam_jpeg_dma_stop_hw;
|
||||
jpeg_dma_dev_intf->hw_ops.reset = cam_jpeg_dma_reset_hw;
|
||||
jpeg_dma_dev_intf->hw_ops.process_cmd = cam_jpeg_dma_process_cmd;
|
||||
jpeg_dma_dev_intf->hw_type = CAM_JPEG_DEV_DMA;
|
||||
|
||||
|
|
@ -134,14 +134,11 @@ static int cam_jpeg_dma_component_bind(struct device *dev,
|
|||
mutex_init(&jpeg_dma_dev->hw_mutex);
|
||||
spin_lock_init(&jpeg_dma_dev->hw_lock);
|
||||
init_completion(&jpeg_dma_dev->hw_complete);
|
||||
|
||||
CAM_DBG(CAM_JPEG, "JPEG:%d component bound successfully",
|
||||
jpeg_dma_dev_intf->hw_idx);
|
||||
|
||||
CAM_DBG(CAM_JPEG, "JPEG-DMA component bound successfully");
|
||||
return rc;
|
||||
|
||||
error_reg_cpas:
|
||||
rc = cam_soc_util_release_platform_resource(&jpeg_dma_dev->soc_info);
|
||||
cam_soc_util_release_platform_resource(&jpeg_dma_dev->soc_info);
|
||||
error_init_soc:
|
||||
mutex_destroy(&core_info->core_mutex);
|
||||
error_match_dev:
|
||||
|
|
@ -150,6 +147,7 @@ error_alloc_core:
|
|||
kfree(jpeg_dma_dev);
|
||||
error_alloc_dev:
|
||||
kfree(jpeg_dma_dev_intf);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -198,8 +196,6 @@ deinit_soc:
|
|||
|
||||
free_jpeg_hw_intf:
|
||||
kfree(jpeg_dma_dev_intf);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
const static struct component_ops cam_jpeg_dma_component_ops = {
|
||||
|
|
|
|||
|
|
@ -356,6 +356,7 @@ int cam_jpeg_enc_start_hw(void *data,
|
|||
}
|
||||
spin_unlock_irqrestore(&jpeg_enc_dev->hw_lock, flags);
|
||||
|
||||
CAM_DBG(CAM_JPEG, "Starting JPEG ENC");
|
||||
cam_io_w_mb(hw_info->reg_val.hw_cmd_start,
|
||||
mem_base + hw_info->reg_offset.hw_cmd);
|
||||
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ static int cam_jpeg_enc_component_bind(struct device *dev,
|
|||
mutex_init(&jpeg_enc_dev->hw_mutex);
|
||||
spin_lock_init(&jpeg_enc_dev->hw_lock);
|
||||
init_completion(&jpeg_enc_dev->hw_complete);
|
||||
CAM_DBG(CAM_JPEG, "Encoder component bound successfully");
|
||||
CAM_DBG(CAM_JPEG, "JPEG-Encoder component bound successfully");
|
||||
|
||||
return rc;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue