Merge "msm: camera: jpeg: Add dma driver implementation" into camera-kernel.lnx.4.0

This commit is contained in:
Haritha Chintalapati 2020-07-27 13:37:45 -07:00 • committed by Gerrit - the friendly Code Review server
commit 9d3a46d91e
8 changed files with 459 additions and 86 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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