msm: camera: cre: Updated FE/WE configuration
Changed from static to dynamic allocation for hw_mgr_intf. Updated de-init handling during driver remove. Updated Idle irq handling to not clear request data at idle irq. Multiple request handling at buff done. Offset fix. CRs-Fixed: 2982472 Change-Id: I37fb690f9f4c1460ecf322a259e2e1001574339b Signed-off-by: Vikram Sharma <vikramsa@codeaurora.org>
Цей коміт міститься в:

зафіксовано
Gerrit - the friendly Code Review server

джерело
16710c7458
коміт
ffc9bf8758
@@ -238,36 +238,34 @@ static struct cam_ctx_ops
|
||||
};
|
||||
|
||||
int cam_cre_context_init(struct cam_cre_context *ctx,
|
||||
struct cam_context *ctx_base,
|
||||
struct cam_hw_mgr_intf *hw_intf,
|
||||
uint32_t ctx_id)
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
if (!ctx || !ctx_base) {
|
||||
if (!ctx || !ctx->base) {
|
||||
CAM_ERR(CAM_CRE, "Invalid Context");
|
||||
rc = -EFAULT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
ctx->base = ctx_base;
|
||||
|
||||
for (i = 0; i < CAM_CTX_REQ_MAX; i++)
|
||||
ctx->req_base[i].req_priv = ctx;
|
||||
|
||||
rc = cam_context_init(ctx_base, cre_dev_name, CAM_CRE, ctx_id,
|
||||
rc = cam_context_init(ctx->base, cre_dev_name, CAM_CRE, ctx_id,
|
||||
NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_CRE, "Camera Context Base init failed");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ctx_base->state_machine = cam_cre_ctx_state_machine;
|
||||
ctx_base->ctx_priv = ctx;
|
||||
ctx->base->state_machine = cam_cre_ctx_state_machine;
|
||||
ctx->base->ctx_priv = ctx;
|
||||
|
||||
ctx->base->max_hw_update_entries = CAM_CTX_CFG_MAX;
|
||||
ctx->base->max_in_map_entries = CAM_CTX_CFG_MAX;
|
||||
ctx->base->max_out_map_entries = CAM_CTX_CFG_MAX;
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
@@ -44,13 +44,11 @@ struct cam_cre_ctx_irq_ops {
|
||||
* @brief: Initialization function for the CRE context
|
||||
*
|
||||
* @ctx: CRE context obj to be initialized
|
||||
* @ctx_base: Context base from cam_context
|
||||
* @hw_intf: CRE hw manager interface
|
||||
* @ctx_id: ID for this context
|
||||
*
|
||||
*/
|
||||
int cam_cre_context_init(struct cam_cre_context *ctx,
|
||||
struct cam_context *ctx_base,
|
||||
struct cam_hw_mgr_intf *hw_intf,
|
||||
uint32_t ctx_id);
|
||||
|
||||
|
@@ -109,14 +109,14 @@ static const struct v4l2_subdev_internal_ops cam_cre_subdev_internal_ops = {
|
||||
static int cam_cre_subdev_component_bind(struct device *dev,
|
||||
struct device *master_dev, void *data)
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
struct cam_hw_mgr_intf hw_mgr_intf;
|
||||
int rc = 0;
|
||||
struct cam_hw_mgr_intf *hw_mgr_intf;
|
||||
struct cam_node *node;
|
||||
int iommu_hdl = -1;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
CAM_DBG(CAM_CRE, "CRE Subdev Component bind");
|
||||
g_cre_dev.sd.pdev = pdev;
|
||||
g_cre_dev.sd.internal_ops = &cam_cre_subdev_internal_ops;
|
||||
rc = cam_subdev_probe(&g_cre_dev.sd, pdev, CAM_CRE_DEV_NAME,
|
||||
CAM_CRE_DEVICE_TYPE);
|
||||
@@ -126,18 +126,25 @@ static int cam_cre_subdev_component_bind(struct device *dev,
|
||||
}
|
||||
node = (struct cam_node *)g_cre_dev.sd.token;
|
||||
|
||||
rc = cam_cre_hw_mgr_init(pdev->dev.of_node,
|
||||
(uint64_t *)&hw_mgr_intf, &iommu_hdl);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_CRE, "Can not initialize CRE HWmanager %d", rc);
|
||||
goto unregister;
|
||||
hw_mgr_intf = kzalloc(sizeof(*hw_mgr_intf), GFP_KERNEL);
|
||||
if (!hw_mgr_intf) {
|
||||
CAM_ERR(CAM_CRE, "Error allocating memory");
|
||||
rc = -ENOMEM;
|
||||
goto hw_alloc_fail;
|
||||
}
|
||||
|
||||
rc = cam_cre_hw_mgr_init(pdev->dev.of_node, hw_mgr_intf,
|
||||
&iommu_hdl);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_CRE, "Can not initialize CRE HWmanager %d", rc);
|
||||
goto hw_init_fail;
|
||||
}
|
||||
|
||||
memset(g_cre_dev.ctx_cre, 0, sizeof(g_cre_dev.ctx_cre));
|
||||
for (i = 0; i < CAM_CRE_CTX_MAX; i++) {
|
||||
g_cre_dev.ctx_cre[i].base = &g_cre_dev.ctx[i];
|
||||
rc = cam_cre_context_init(&g_cre_dev.ctx_cre[i],
|
||||
&g_cre_dev.ctx[i],
|
||||
&node->hw_mgr_intf,
|
||||
i);
|
||||
hw_mgr_intf, i);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_CRE, "CRE context init failed %d %d",
|
||||
i, rc);
|
||||
@@ -145,8 +152,8 @@ static int cam_cre_subdev_component_bind(struct device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
rc = cam_node_init(node, &hw_mgr_intf, g_cre_dev.ctx, CAM_CRE_CTX_MAX,
|
||||
CAM_CRE_DEV_NAME);
|
||||
rc = cam_node_init(node, hw_mgr_intf, g_cre_dev.ctx,
|
||||
CAM_CRE_CTX_MAX, CAM_CRE_DEV_NAME);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_CRE, "CRE node init failed %d", rc);
|
||||
goto ctx_init_fail;
|
||||
@@ -156,6 +163,7 @@ static int cam_cre_subdev_component_bind(struct device *dev,
|
||||
cam_smmu_set_client_page_fault_handler(iommu_hdl,
|
||||
cam_cre_dev_iommu_fault_handler, node);
|
||||
|
||||
g_cre_dev.open_cnt = 0;
|
||||
mutex_init(&g_cre_dev.cre_lock);
|
||||
|
||||
CAM_DBG(CAM_CRE, "Component bound successfully");
|
||||
@@ -166,7 +174,9 @@ ctx_init_fail:
|
||||
for (--i; i >= 0; i--)
|
||||
if (cam_cre_context_deinit(&g_cre_dev.ctx_cre[i]))
|
||||
CAM_ERR(CAM_CRE, "deinit fail %d %d", i, rc);
|
||||
unregister:
|
||||
hw_init_fail:
|
||||
kfree(hw_mgr_intf);
|
||||
hw_alloc_fail:
|
||||
if (cam_subdev_remove(&g_cre_dev.sd))
|
||||
CAM_ERR(CAM_CRE, "remove fail %d", rc);
|
||||
err:
|
||||
@@ -176,19 +186,14 @@ err:
|
||||
static void cam_cre_subdev_component_unbind(struct device *dev,
|
||||
struct device *master_dev, void *data)
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CAM_CTX_MAX; i++) {
|
||||
rc = cam_cre_context_deinit(&g_cre_dev.ctx_cre[i]);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_CRE, "CRE context %d deinit failed %d",
|
||||
i, rc);
|
||||
}
|
||||
for (i = 0; i < CRE_CTX_MAX; i++)
|
||||
cam_cre_context_deinit(&g_cre_dev.ctx_cre[i]);
|
||||
|
||||
rc = cam_subdev_remove(&g_cre_dev.sd);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_CRE, "Unregister failed %d", rc);
|
||||
cam_node_deinit(g_cre_dev.node);
|
||||
cam_subdev_remove(&g_cre_dev.sd);
|
||||
mutex_destroy(&g_cre_dev.cre_lock);
|
||||
}
|
||||
|
||||
const static struct component_ops cam_cre_subdev_component_ops = {
|
||||
|
@@ -2,12 +2,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/workqueue.h>
|
||||
@@ -37,9 +31,6 @@
|
||||
#include "cre_dev_intf.h"
|
||||
#include "cam_compat.h"
|
||||
|
||||
#define CAM_CRE_FE_IRQ 0x4
|
||||
#define CAM_CRE_WE_IRQ 0x2
|
||||
|
||||
static struct cam_cre_hw_mgr *cre_hw_mgr;
|
||||
|
||||
static struct cam_cre_io_buf_info *cam_cre_mgr_get_rsc(
|
||||
@@ -131,6 +122,7 @@ static int cam_cre_mgr_process_cmd_io_buf_req(struct cam_cre_hw_mgr *hw_mgr,
|
||||
|
||||
cre_request = ctx_data->req_list[req_idx];
|
||||
cre_request->num_batch = ctx_data->cre_acquire.batch_size;
|
||||
CAM_DBG(CAM_CRE, "num_io_configs %d", packet->num_io_configs);
|
||||
|
||||
for (i = 0; i < cre_request->num_batch; i++) {
|
||||
for (j = 0; j < packet->num_io_configs; j++) {
|
||||
@@ -154,9 +146,15 @@ static int cam_cre_mgr_process_cmd_io_buf_req(struct cam_cre_hw_mgr *hw_mgr,
|
||||
io_buf->num_planes = acq_io_buf->num_planes;
|
||||
io_buf->resource_type = acq_io_buf->res_id;
|
||||
io_buf->direction = acq_io_buf->direction;
|
||||
io_buf->fence = acq_io_buf->fence;
|
||||
io_buf->format = acq_io_buf->format;
|
||||
|
||||
alignment = acq_io_buf->alignment;
|
||||
io_buf->fence = io_cfg_ptr[j].fence;
|
||||
|
||||
CAM_DBG(CAM_CRE,
|
||||
"i %d j %d Number of planes %d res_type %d dir %d, fence %d format %d align %d",
|
||||
i, j, io_buf->num_planes, io_buf->resource_type,
|
||||
io_buf->direction, io_buf->fence, io_buf->format, alignment);
|
||||
|
||||
for (k = 0; k < io_buf->num_planes; k++) {
|
||||
is_secure = cam_mem_is_secure_buf(
|
||||
@@ -180,21 +178,27 @@ static int cam_cre_mgr_process_cmd_io_buf_req(struct cam_cre_hw_mgr *hw_mgr,
|
||||
iova_addr += io_cfg_ptr[j].offsets[k];
|
||||
plane_info = &io_buf->p_info[k];
|
||||
|
||||
plane_info->offset = io_cfg_ptr[j].offsets[k];
|
||||
plane_info->format = io_buf->format;
|
||||
/*
|
||||
* TODO: Confirm if the calculation for batch frame offset
|
||||
* is correct with some experiment in TFE.
|
||||
*/
|
||||
plane_info->offset = io_cfg_ptr[j].offsets[k];
|
||||
plane_info->format = acq_io_buf->format;
|
||||
plane_info->iova_addr = iova_addr +
|
||||
((io_cfg_ptr[j].planes[k].plane_stride *
|
||||
io_cfg_ptr[j].planes[k].slice_height) * i);
|
||||
plane_info->width =
|
||||
io_cfg_ptr[j].planes[k].width;
|
||||
plane_info->height =
|
||||
io_cfg_ptr[j].planes[k].height;
|
||||
io_cfg_ptr[j].planes[k].slice_height) * k);
|
||||
|
||||
plane_info->stride =
|
||||
io_cfg_ptr[j].planes[k].plane_stride;
|
||||
|
||||
/* Width for WE has to be updated in number of pixels */
|
||||
if (acq_io_buf->direction == CAM_BUF_OUTPUT) {
|
||||
/* PLAIN 128/8 = 16 Bytes per pixel */
|
||||
plane_info->width =
|
||||
io_cfg_ptr[j].planes[k].plane_stride/16;
|
||||
} else {
|
||||
/* FE width should be in bytes */
|
||||
plane_info->width =
|
||||
io_cfg_ptr[j].planes[k].plane_stride;
|
||||
}
|
||||
plane_info->height =
|
||||
io_cfg_ptr[j].planes[k].height;
|
||||
plane_info->len = len;
|
||||
plane_info->alignment = alignment;
|
||||
}
|
||||
@@ -233,47 +237,27 @@ static int cam_cre_mgr_reset_hw(void)
|
||||
}
|
||||
|
||||
|
||||
static void cam_cre_ctx_wait_for_idle_irq(struct cam_cre_ctx *ctx,
|
||||
struct cam_cre_request *cre_req, uint32_t cookie)
|
||||
static void cam_cre_ctx_wait_for_idle_irq(struct cam_cre_ctx *ctx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (ctx->ctx_state != CRE_CTX_STATE_ACQUIRED) {
|
||||
CAM_ERR(CAM_CRE, "ctx %u is in %d state",
|
||||
ctx->ctx_id, ctx->ctx_state);
|
||||
mutex_unlock(&ctx->ctx_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = wait_for_completion_timeout(
|
||||
&ctx->cre_top->idle_done, msecs_to_jiffies(30000));
|
||||
rc = cam_common_wait_for_completion_timeout(
|
||||
&ctx->cre_top->idle_done,
|
||||
msecs_to_jiffies(CAM_CRE_RESPONSE_TIME_THRESHOLD));
|
||||
if (!rc) {
|
||||
cam_cre_device_timer_reset(cre_hw_mgr);
|
||||
} else {
|
||||
CAM_INFO(CAM_CRE, "After reset of CRE, reapply req");
|
||||
rc = cam_cre_mgr_reset_hw();
|
||||
CAM_DBG(CAM_CRE, "IDLE done for req idx %d",
|
||||
ctx->last_req_idx);
|
||||
}
|
||||
|
||||
if (!test_bit(cookie, ctx->bitmap)) {
|
||||
CAM_ERR(CAM_CRE, "Req not present reqIdx = %d for ctx_id = %d",
|
||||
cookie, ctx->ctx_id);
|
||||
goto end;
|
||||
}
|
||||
CAM_DBG(CAM_REQ, "req_id= %llu ctx_id= %d lcb=%llu",
|
||||
cre_req->request_id, ctx->ctx_id);
|
||||
|
||||
ctx->req_cnt--;
|
||||
|
||||
cre_req->request_id = 0;
|
||||
cam_cre_free_io_config(ctx->req_list[cookie]);
|
||||
cam_free_clear((void *)ctx->req_list[cookie]);
|
||||
ctx->req_list[cookie] = NULL;
|
||||
clear_bit(cookie, ctx->bitmap);
|
||||
end:
|
||||
mutex_unlock(&ctx->ctx_mutex);
|
||||
}
|
||||
|
||||
|
||||
static int cam_cre_mgr_create_cre_reg_buf(struct cam_cre_hw_mgr *hw_mgr,
|
||||
struct cam_packet *packet,
|
||||
struct cam_hw_prepare_update_args *prepare_args,
|
||||
@@ -570,16 +554,16 @@ static int cam_cre_mgr_handle_config_err(
|
||||
struct cam_hw_config_args *config_args,
|
||||
struct cam_cre_ctx *ctx_data)
|
||||
{
|
||||
struct cam_hw_done_event_data buf_data;
|
||||
struct cam_hw_done_event_data err_data;
|
||||
struct cam_cre_request *cre_req;
|
||||
uint32_t req_idx;
|
||||
|
||||
cre_req = config_args->priv;
|
||||
|
||||
buf_data.request_id = cre_req->request_id;
|
||||
buf_data.evt_param = CAM_SYNC_CRE_EVENT_CONFIG_ERR;
|
||||
err_data.request_id = cre_req->request_id;
|
||||
err_data.evt_param = CAM_SYNC_CRE_EVENT_CONFIG_ERR;
|
||||
ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_CTX_EVT_ID_ERROR,
|
||||
&buf_data);
|
||||
&err_data);
|
||||
|
||||
req_idx = cre_req->req_idx;
|
||||
cre_req->request_id = 0;
|
||||
@@ -684,7 +668,7 @@ static int32_t cam_cre_deinit_idle_clk(void *priv, void *data)
|
||||
|
||||
CAM_DBG(CAM_CRE, "Disable %d", clk_info->hw_type);
|
||||
|
||||
dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id, NULL, 0);
|
||||
dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id, NULL, 0);
|
||||
|
||||
done:
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
@@ -719,19 +703,14 @@ static void cam_cre_device_timer_cb(struct timer_list *timer_data)
|
||||
static int cam_cre_device_timer_start(struct cam_cre_hw_mgr *hw_mgr)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CLK_HW_MAX; i++) {
|
||||
if (!hw_mgr->clk_info.watch_dog) {
|
||||
rc = crm_timer_init(&hw_mgr->clk_info.watch_dog,
|
||||
CRE_DEVICE_IDLE_TIMEOUT, &hw_mgr->clk_info,
|
||||
&cam_cre_device_timer_cb);
|
||||
|
||||
if (rc)
|
||||
CAM_ERR(CAM_CRE, "Failed to start timer %d", i);
|
||||
|
||||
hw_mgr->clk_info.watch_dog_reset_counter = 0;
|
||||
}
|
||||
if (!hw_mgr->clk_info.watch_dog) {
|
||||
rc = crm_timer_init(&hw_mgr->clk_info.watch_dog,
|
||||
CRE_DEVICE_IDLE_TIMEOUT, &hw_mgr->clk_info,
|
||||
&cam_cre_device_timer_cb);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_CRE, "Failed to start timer");
|
||||
hw_mgr->clk_info.watch_dog_reset_counter = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -753,7 +732,7 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
|
||||
struct cam_cre_ctx *ctx_data;
|
||||
struct cam_cre_request *cre_req;
|
||||
struct cam_cre_hw_mgr *hw_mgr = cre_hw_mgr;
|
||||
uint32_t active_req_idx;
|
||||
uint32_t num_batch;
|
||||
|
||||
if (!data || !priv) {
|
||||
CAM_ERR(CAM_CRE, "Invalid params%pK %pK", data, priv);
|
||||
@@ -772,12 +751,10 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
active_req_idx = task_data->req_idx;
|
||||
|
||||
if (active_req_idx >= CAM_CTX_REQ_MAX) {
|
||||
if (task_data->req_idx >= CAM_CTX_REQ_MAX) {
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
CAM_ERR(CAM_CRE, "Invalid reqIdx = %llu",
|
||||
active_req_idx);
|
||||
task_data->req_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -799,15 +776,34 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hw_mgr = task_data->data;
|
||||
ctx_data->active_req = cre_req;
|
||||
for (i = 0; i < cre_req->num_batch; i++) {
|
||||
cam_cre_mgr_update_reg_set(hw_mgr, cre_req);
|
||||
cam_cre_ctx_wait_for_idle_irq(ctx_data, cre_req,
|
||||
active_req_idx);
|
||||
}
|
||||
num_batch = cre_req->num_batch;
|
||||
|
||||
CAM_DBG(CAM_CRE,
|
||||
"Going to configure cre for req %d, req_idx %d num_batch %d",
|
||||
cre_req->request_id, cre_req->req_idx, num_batch);
|
||||
|
||||
for (i = 0; i < num_batch; i++) {
|
||||
if (i != 0) {
|
||||
rc = cam_common_wait_for_completion_timeout(
|
||||
&ctx_data->cre_top->bufdone,
|
||||
msecs_to_jiffies(100));
|
||||
if (!rc) {
|
||||
cam_cre_device_timer_reset(cre_hw_mgr);
|
||||
CAM_ERR(CAM_CRE,
|
||||
"Timedout waiting for bufdone on last frame");
|
||||
return -ETIMEDOUT;
|
||||
} else {
|
||||
reinit_completion(&ctx_data->cre_top->bufdone);
|
||||
CAM_INFO(CAM_CRE,
|
||||
"done for frame %d in batch of %d",
|
||||
i-1, num_batch);
|
||||
}
|
||||
}
|
||||
|
||||
cam_cre_mgr_update_reg_set(hw_mgr, cre_req, i);
|
||||
cam_cre_ctx_wait_for_idle_irq(ctx_data);
|
||||
}
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
|
||||
return rc;
|
||||
@@ -835,9 +831,11 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
|
||||
struct cam_hw_done_event_data buf_data;
|
||||
struct cam_cre_hw_mgr *hw_mgr;
|
||||
struct cam_cre_ctx *ctx;
|
||||
struct cam_cre_request *active_req;
|
||||
struct cam_cre_irq_data irq_data;
|
||||
int32_t ctx_id;
|
||||
uint32_t evt_id;
|
||||
uint32_t active_req_idx;
|
||||
int rc = 0;
|
||||
|
||||
if (!data || !priv) {
|
||||
@@ -864,31 +862,325 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
active_req_idx = find_next_bit(ctx->bitmap, ctx->bits, ctx->last_done_req_idx);
|
||||
CAM_DBG(CAM_CRE, "active_req_idx %d last_done_req_idx %d",
|
||||
active_req_idx, ctx->last_done_req_idx);
|
||||
|
||||
active_req = ctx->req_list[active_req_idx];
|
||||
if (!active_req)
|
||||
CAM_ERR(CAM_CRE, "Active req cannot be null");
|
||||
|
||||
if (irq_data.error) {
|
||||
evt_id = CAM_CTX_EVT_ID_ERROR;
|
||||
buf_data.evt_param = CAM_SYNC_CRE_EVENT_HW_ERR;
|
||||
buf_data.request_id = ctx->active_req->request_id;
|
||||
buf_data.request_id = active_req->request_id;
|
||||
ctx->ctxt_event_cb(ctx->context_priv, evt_id, &buf_data);
|
||||
rc = cam_cre_mgr_reset_hw();
|
||||
} else if ((irq_data.top_irq_status & CAM_CRE_WE_IRQ)
|
||||
&& (irq_data.wr_buf_done)) {
|
||||
clear_bit(active_req_idx, ctx->bitmap);
|
||||
cam_cre_free_io_config(active_req);
|
||||
cam_free_clear((void *)active_req);
|
||||
ctx->req_cnt--;
|
||||
ctx->req_list[active_req_idx] = NULL;
|
||||
} else if (irq_data.wr_buf_done) {
|
||||
/* Signal Buf done */
|
||||
ctx->active_req->frames_done++;
|
||||
if (ctx->active_req->frames_done == ctx->active_req->num_batch) {
|
||||
active_req->frames_done++;
|
||||
CAM_DBG(CAM_CRE, "Received frames_done %d num_batch %d req id %d",
|
||||
active_req->frames_done, active_req->num_batch,
|
||||
active_req->request_id);
|
||||
complete(&ctx->cre_top->bufdone);
|
||||
if (active_req->frames_done == active_req->num_batch) {
|
||||
ctx->last_done_req_idx = active_req_idx;
|
||||
CAM_DBG(CAM_CRE, "signaling buff done for req %d",
|
||||
active_req->request_id);
|
||||
evt_id = CAM_CTX_EVT_ID_SUCCESS;
|
||||
buf_data.evt_param = CAM_SYNC_COMMON_EVENT_SUCCESS;
|
||||
buf_data.request_id = ctx->active_req->request_id;
|
||||
buf_data.request_id = active_req->request_id;
|
||||
ctx->ctxt_event_cb(ctx->context_priv, evt_id, &buf_data);
|
||||
clear_bit(active_req_idx, ctx->bitmap);
|
||||
cam_cre_free_io_config(active_req);
|
||||
cam_free_clear((void *)active_req);
|
||||
ctx->req_cnt--;
|
||||
ctx->req_list[active_req_idx] = NULL;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ctx->ctx_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_cre_get_actual_clk_rate_idx(
|
||||
struct cam_cre_ctx *ctx_data, uint32_t base_clk)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CAM_MAX_VOTE; i++)
|
||||
if (ctx_data->clk_info.clk_rate[i] >= base_clk)
|
||||
return i;
|
||||
|
||||
/*
|
||||
* Caller has to ensure returned index is within array
|
||||
* size bounds while accessing that index.
|
||||
*/
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static bool cam_cre_is_over_clk(struct cam_cre_hw_mgr *hw_mgr,
|
||||
struct cam_cre_ctx *ctx_data,
|
||||
struct cam_cre_clk_info *hw_mgr_clk_info)
|
||||
{
|
||||
int base_clk_idx;
|
||||
int curr_clk_idx;
|
||||
|
||||
base_clk_idx = cam_cre_get_actual_clk_rate_idx(ctx_data,
|
||||
hw_mgr_clk_info->base_clk);
|
||||
|
||||
curr_clk_idx = cam_cre_get_actual_clk_rate_idx(ctx_data,
|
||||
hw_mgr_clk_info->curr_clk);
|
||||
|
||||
CAM_DBG(CAM_CRE, "bc_idx = %d cc_idx = %d %d %d",
|
||||
base_clk_idx, curr_clk_idx, hw_mgr_clk_info->base_clk,
|
||||
hw_mgr_clk_info->curr_clk);
|
||||
|
||||
if (curr_clk_idx > base_clk_idx)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int cam_cre_get_lower_clk_rate(struct cam_cre_hw_mgr *hw_mgr,
|
||||
struct cam_cre_ctx *ctx_data, uint32_t base_clk)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = cam_cre_get_actual_clk_rate_idx(ctx_data, base_clk);
|
||||
|
||||
while (i > 0) {
|
||||
if (ctx_data->clk_info.clk_rate[i - 1])
|
||||
return ctx_data->clk_info.clk_rate[i - 1];
|
||||
i--;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_CRE, "Already clk at lower level");
|
||||
|
||||
return base_clk;
|
||||
}
|
||||
|
||||
static int cam_cre_get_next_clk_rate(struct cam_cre_hw_mgr *hw_mgr,
|
||||
struct cam_cre_ctx *ctx_data, uint32_t base_clk)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = cam_cre_get_actual_clk_rate_idx(ctx_data, base_clk);
|
||||
|
||||
while (i < CAM_MAX_VOTE - 1) {
|
||||
if (ctx_data->clk_info.clk_rate[i + 1])
|
||||
return ctx_data->clk_info.clk_rate[i + 1];
|
||||
i++;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_CRE, "Already clk at higher level");
|
||||
return base_clk;
|
||||
}
|
||||
|
||||
static bool cam_cre_update_clk_overclk_free(struct cam_cre_hw_mgr *hw_mgr,
|
||||
struct cam_cre_ctx *ctx_data,
|
||||
struct cam_cre_clk_info *hw_mgr_clk_info,
|
||||
struct cam_cre_clk_bw_request *clk_info,
|
||||
uint32_t base_clk)
|
||||
{
|
||||
int rc = false;
|
||||
|
||||
/*
|
||||
* In caseof no pending packets case
|
||||
* 1. In caseof overclk cnt is less than threshold, increase
|
||||
* overclk count and no update in the clock rate
|
||||
* 2. In caseof overclk cnt is greater than or equal to threshold
|
||||
* then lower clock rate by one level and update hw_mgr current
|
||||
* clock value.
|
||||
* a. In case of new clock rate greater than sum of clock
|
||||
* rates, reset overclk count value to zero if it is
|
||||
* overclock
|
||||
* b. if it is less than sum of base clocks then go to next
|
||||
* level of clock and make overclk count to zero
|
||||
* c. if it is same as sum of base clock rates update overclock
|
||||
* cnt to 0
|
||||
*/
|
||||
if (hw_mgr_clk_info->over_clked < hw_mgr_clk_info->threshold) {
|
||||
hw_mgr_clk_info->over_clked++;
|
||||
rc = false;
|
||||
} else {
|
||||
hw_mgr_clk_info->curr_clk =
|
||||
cam_cre_get_lower_clk_rate(hw_mgr, ctx_data,
|
||||
hw_mgr_clk_info->curr_clk);
|
||||
if (hw_mgr_clk_info->curr_clk > hw_mgr_clk_info->base_clk) {
|
||||
if (cam_cre_is_over_clk(hw_mgr, ctx_data,
|
||||
hw_mgr_clk_info))
|
||||
hw_mgr_clk_info->over_clked = 0;
|
||||
} else if (hw_mgr_clk_info->curr_clk <
|
||||
hw_mgr_clk_info->base_clk) {
|
||||
hw_mgr_clk_info->curr_clk =
|
||||
cam_cre_get_next_clk_rate(hw_mgr, ctx_data,
|
||||
hw_mgr_clk_info->curr_clk);
|
||||
hw_mgr_clk_info->over_clked = 0;
|
||||
} else if (hw_mgr_clk_info->curr_clk ==
|
||||
hw_mgr_clk_info->base_clk) {
|
||||
hw_mgr_clk_info->over_clked = 0;
|
||||
}
|
||||
rc = true;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_cre_calc_total_clk(struct cam_cre_hw_mgr *hw_mgr,
|
||||
struct cam_cre_clk_info *hw_mgr_clk_info, uint32_t dev_type)
|
||||
{
|
||||
int i;
|
||||
struct cam_cre_ctx *ctx_data;
|
||||
|
||||
hw_mgr_clk_info->base_clk = 0;
|
||||
for (i = 0; i < CRE_CTX_MAX; i++) {
|
||||
ctx_data = &hw_mgr->ctx[i];
|
||||
if (ctx_data->ctx_state == CRE_CTX_STATE_ACQUIRED)
|
||||
hw_mgr_clk_info->base_clk +=
|
||||
ctx_data->clk_info.base_clk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_cre_get_actual_clk_rate(struct cam_cre_hw_mgr *hw_mgr,
|
||||
struct cam_cre_ctx *ctx_data, uint32_t base_clk)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CAM_MAX_VOTE; i++)
|
||||
if (ctx_data->clk_info.clk_rate[i] >= base_clk)
|
||||
return ctx_data->clk_info.clk_rate[i];
|
||||
|
||||
return base_clk;
|
||||
}
|
||||
|
||||
static bool cam_cre_update_clk_busy(struct cam_cre_hw_mgr *hw_mgr,
|
||||
struct cam_cre_ctx *ctx_data,
|
||||
struct cam_cre_clk_info *hw_mgr_clk_info,
|
||||
struct cam_cre_clk_bw_request *clk_info,
|
||||
uint32_t base_clk)
|
||||
{
|
||||
uint32_t next_clk_level;
|
||||
uint32_t actual_clk;
|
||||
bool rc = false;
|
||||
|
||||
/* 1. if current request frame cycles(fc) are more than previous
|
||||
* frame fc
|
||||
* Calculate the new base clock.
|
||||
* if sum of base clocks are more than next available clk level
|
||||
* Update clock rate, change curr_clk_rate to sum of base clock
|
||||
* rates and make over_clked to zero
|
||||
* else
|
||||
* Update clock rate to next level, update curr_clk_rate and make
|
||||
* overclked cnt to zero
|
||||
* 2. if current fc is less than or equal to previous frame fc
|
||||
* Still Bump up the clock to next available level
|
||||
* if it is available, then update clock, make overclk cnt to
|
||||
* zero. If the clock is already at highest clock rate then
|
||||
* no need to update the clock
|
||||
*/
|
||||
ctx_data->clk_info.base_clk = base_clk;
|
||||
hw_mgr_clk_info->over_clked = 0;
|
||||
if (clk_info->frame_cycles > ctx_data->clk_info.curr_fc) {
|
||||
cam_cre_calc_total_clk(hw_mgr, hw_mgr_clk_info,
|
||||
ctx_data->cre_acquire.dev_type);
|
||||
actual_clk = cam_cre_get_actual_clk_rate(hw_mgr,
|
||||
ctx_data, base_clk);
|
||||
if (hw_mgr_clk_info->base_clk > actual_clk) {
|
||||
hw_mgr_clk_info->curr_clk = hw_mgr_clk_info->base_clk;
|
||||
} else {
|
||||
next_clk_level = cam_cre_get_next_clk_rate(hw_mgr,
|
||||
ctx_data, hw_mgr_clk_info->curr_clk);
|
||||
hw_mgr_clk_info->curr_clk = next_clk_level;
|
||||
}
|
||||
rc = true;
|
||||
} else {
|
||||
next_clk_level =
|
||||
cam_cre_get_next_clk_rate(hw_mgr, ctx_data,
|
||||
hw_mgr_clk_info->curr_clk);
|
||||
if (hw_mgr_clk_info->curr_clk < next_clk_level) {
|
||||
hw_mgr_clk_info->curr_clk = next_clk_level;
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
ctx_data->clk_info.curr_fc = clk_info->frame_cycles;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool cam_cre_update_clk_free(struct cam_cre_hw_mgr *hw_mgr,
|
||||
struct cam_cre_ctx *ctx_data,
|
||||
struct cam_cre_clk_info *hw_mgr_clk_info,
|
||||
struct cam_cre_clk_bw_request *clk_info,
|
||||
uint32_t base_clk)
|
||||
{
|
||||
int rc = false;
|
||||
bool over_clocked = false;
|
||||
|
||||
ctx_data->clk_info.curr_fc = clk_info->frame_cycles;
|
||||
ctx_data->clk_info.base_clk = base_clk;
|
||||
cam_cre_calc_total_clk(hw_mgr, hw_mgr_clk_info,
|
||||
ctx_data->cre_acquire.dev_type);
|
||||
|
||||
/*
|
||||
* Current clock is not always sum of base clocks, due to
|
||||
* clock scales update to next higher or lower levels, it
|
||||
* equals to one of discrete clock values supported by hardware.
|
||||
* So even current clock is higher than sum of base clocks, we
|
||||
* can not consider it is over clocked. if it is greater than
|
||||
* discrete clock level then only it is considered as over clock.
|
||||
* 1. Handle over clock case
|
||||
* 2. If current clock is less than sum of base clocks
|
||||
* update current clock
|
||||
* 3. If current clock is same as sum of base clocks no action
|
||||
*/
|
||||
|
||||
over_clocked = cam_cre_is_over_clk(hw_mgr, ctx_data,
|
||||
hw_mgr_clk_info);
|
||||
|
||||
if (hw_mgr_clk_info->curr_clk > hw_mgr_clk_info->base_clk &&
|
||||
over_clocked) {
|
||||
rc = cam_cre_update_clk_overclk_free(hw_mgr, ctx_data,
|
||||
hw_mgr_clk_info, clk_info, base_clk);
|
||||
} else if (hw_mgr_clk_info->curr_clk > hw_mgr_clk_info->base_clk) {
|
||||
hw_mgr_clk_info->over_clked = 0;
|
||||
rc = false;
|
||||
} else if (hw_mgr_clk_info->curr_clk < hw_mgr_clk_info->base_clk) {
|
||||
hw_mgr_clk_info->curr_clk = cam_cre_get_actual_clk_rate(hw_mgr,
|
||||
ctx_data, hw_mgr_clk_info->base_clk);
|
||||
rc = true;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static uint32_t cam_cre_mgr_calc_base_clk(uint32_t frame_cycles,
|
||||
uint64_t budget)
|
||||
{
|
||||
uint64_t mul = 1000000000;
|
||||
uint64_t base_clk = frame_cycles * mul;
|
||||
|
||||
do_div(base_clk, budget);
|
||||
|
||||
CAM_DBG(CAM_CRE, "budget = %lld fc = %d ib = %lld base_clk = %lld",
|
||||
budget, frame_cycles,
|
||||
(long long)(frame_cycles * mul), base_clk);
|
||||
|
||||
return base_clk;
|
||||
}
|
||||
|
||||
static bool cam_cre_check_clk_update(struct cam_cre_hw_mgr *hw_mgr,
|
||||
struct cam_cre_ctx *ctx_data, int idx)
|
||||
{
|
||||
bool rc = false;
|
||||
bool busy = false, rc = false;
|
||||
uint64_t base_clk;
|
||||
struct cam_cre_clk_bw_request *clk_info;
|
||||
uint64_t req_id;
|
||||
struct cam_cre_clk_info *hw_mgr_clk_info;
|
||||
@@ -896,14 +1188,29 @@ static bool cam_cre_check_clk_update(struct cam_cre_hw_mgr *hw_mgr,
|
||||
cam_cre_device_timer_reset(hw_mgr);
|
||||
hw_mgr_clk_info = &hw_mgr->clk_info;
|
||||
req_id = ctx_data->req_list[idx]->request_id;
|
||||
if (ctx_data->req_cnt > 1)
|
||||
busy = true;
|
||||
|
||||
CAM_DBG(CAM_CRE, "req_id = %lld", req_id);
|
||||
CAM_DBG(CAM_CRE, "busy = %d req_id = %lld", busy, req_id);
|
||||
|
||||
clk_info = &ctx_data->req_list[idx]->clk_info;
|
||||
|
||||
/* Calculate base clk rate */
|
||||
base_clk = cam_cre_mgr_calc_base_clk(
|
||||
clk_info->frame_cycles, clk_info->budget_ns);
|
||||
ctx_data->clk_info.rt_flag = clk_info->rt_flag;
|
||||
|
||||
if (busy)
|
||||
rc = cam_cre_update_clk_busy(hw_mgr, ctx_data,
|
||||
hw_mgr_clk_info, clk_info, base_clk);
|
||||
else
|
||||
rc = cam_cre_update_clk_free(hw_mgr, ctx_data,
|
||||
hw_mgr_clk_info, clk_info, base_clk);
|
||||
|
||||
CAM_DBG(CAM_CRE, "bc = %d cc = %d busy = %d overclk = %d uc = %d",
|
||||
hw_mgr_clk_info->base_clk, hw_mgr_clk_info->curr_clk,
|
||||
busy, hw_mgr_clk_info->over_clked, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1020,7 +1327,8 @@ static int cam_cre_mgr_process_io_cfg(struct cam_cre_hw_mgr *hw_mgr,
|
||||
prep_arg->num_out_map_entries = 0;
|
||||
prep_arg->num_in_map_entries = 0;
|
||||
|
||||
CAM_DBG(CAM_CRE, "E: req_idx = %u %x", req_idx, packet);
|
||||
CAM_DBG(CAM_CRE, "E: req_idx = %u %x num batch%d",
|
||||
req_idx, packet, cre_request->num_batch);
|
||||
|
||||
for (i = 0; i < cre_request->num_batch; i++) {
|
||||
for (l = 0; l < cre_request->num_io_bufs[i]; l++) {
|
||||
@@ -1050,13 +1358,10 @@ static int cam_cre_mgr_process_io_cfg(struct cam_cre_hw_mgr *hw_mgr,
|
||||
prep_arg->num_out_map_entries++;
|
||||
}
|
||||
}
|
||||
CAM_DBG(CAM_REQ,
|
||||
CAM_DBG(CAM_CRE,
|
||||
"ctx_id: %u req_id: %llu dir[%d] %u, fence: %d",
|
||||
ctx_data->ctx_id, packet->header.request_id, i,
|
||||
io_buf->direction, io_buf->fence);
|
||||
CAM_DBG(CAM_REQ, "rsc_type = %u fmt = %d",
|
||||
io_buf->resource_type,
|
||||
io_buf->format);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1080,16 +1385,16 @@ static int cam_cre_mgr_process_io_cfg(struct cam_cre_hw_mgr *hw_mgr,
|
||||
|
||||
prep_arg->in_map_entries[0].sync_id = merged_sync_in_obj;
|
||||
prep_arg->num_in_map_entries = 1;
|
||||
CAM_DBG(CAM_REQ, "ctx_id: %u req_id: %llu Merged Sync obj: %d",
|
||||
CAM_DBG(CAM_CRE, "ctx_id: %u req_id: %llu Merged Sync obj: %d",
|
||||
ctx_data->ctx_id, packet->header.request_id,
|
||||
merged_sync_in_obj);
|
||||
} else if (prep_arg->num_in_map_entries == 1) {
|
||||
prep_arg->in_map_entries[0].sync_id = sync_in_obj[0];
|
||||
prep_arg->num_in_map_entries = 1;
|
||||
cre_request->in_resource = 0;
|
||||
CAM_DBG(CAM_CRE, "fence = %d", sync_in_obj[0]);
|
||||
} else {
|
||||
CAM_DBG(CAM_CRE, "Invalid count of input fences, count: %d",
|
||||
CAM_ERR(CAM_CRE,
|
||||
"Invalid count of input fences, count: %d",
|
||||
prep_arg->num_in_map_entries);
|
||||
prep_arg->num_in_map_entries = 0;
|
||||
cre_request->in_resource = 0;
|
||||
@@ -1203,48 +1508,42 @@ static int cam_cre_validate_acquire_res_info(
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cre_acquire->dev_type >= CRE_DEV_MAX) {
|
||||
if (cre_acquire->dev_type >= CAM_CRE_DEV_TYPE_MAX) {
|
||||
CAM_ERR(CAM_CRE, "Invalid device type: %d",
|
||||
cre_acquire->dev_type);
|
||||
return -EFAULT;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Confirm this with CRE HW folks
|
||||
* Reffering CRE HPG supported input formats are
|
||||
* CAM_FORMAT_MIPI_RAW_10
|
||||
* CAM_FORMAT_MIPI_RAW_12
|
||||
* CAM_FORMAT_MIPI_RAW_14
|
||||
* CAM_FORMAT_MIPI_RAW_16
|
||||
* CAM_FORMAT_MIPI_RAW_20
|
||||
*/
|
||||
for (i = 0; i < cre_acquire->num_in_res; i++) {
|
||||
if ((cre_acquire->in_res[i].format <
|
||||
CAM_FORMAT_MIPI_RAW_10) ||
|
||||
(cre_acquire->in_res[i].format >
|
||||
CAM_FORMAT_MIPI_RAW_20)) {
|
||||
CAM_ERR(CAM_CRE, "Invalid Input format");
|
||||
return -EINVAL;
|
||||
switch (cre_acquire->in_res[i].format) {
|
||||
case CAM_FORMAT_MIPI_RAW_10:
|
||||
case CAM_FORMAT_MIPI_RAW_12:
|
||||
case CAM_FORMAT_MIPI_RAW_14:
|
||||
case CAM_FORMAT_MIPI_RAW_20:
|
||||
case CAM_FORMAT_PLAIN1128:
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_CRE, "Invalid input format %d",
|
||||
cre_acquire->in_res[i].format);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Confirm this with CRE HW folks
|
||||
* Reffering CRE HPG supported output formats are
|
||||
* CAM_FORMAT_PLAIN16_8
|
||||
* CAM_FORMAT_PLAIN16_10
|
||||
* CAM_FORMAT_PLAIN16_12
|
||||
* CAM_FORMAT_PLAIN16_14
|
||||
* CAM_FORMAT_PLAIN16_16
|
||||
* CAM_FORMAT_PLAIN32_20
|
||||
*/
|
||||
for (i = 0; i < cre_acquire->num_out_res; i++) {
|
||||
if ((cre_acquire->out_res[i].format <
|
||||
CAM_FORMAT_PLAIN16_8) ||
|
||||
(cre_acquire->out_res[i].format >
|
||||
CAM_FORMAT_PLAIN32_20)) {
|
||||
CAM_ERR(CAM_CRE, "Invalid output format");
|
||||
return -EINVAL;
|
||||
switch (cre_acquire->out_res[i].format) {
|
||||
case CAM_FORMAT_PLAIN16_8:
|
||||
case CAM_FORMAT_PLAIN16_10:
|
||||
case CAM_FORMAT_PLAIN16_12:
|
||||
case CAM_FORMAT_PLAIN16_14:
|
||||
case CAM_FORMAT_PLAIN16_16:
|
||||
case CAM_FORMAT_PLAIN32_20:
|
||||
case CAM_FORMAT_PLAIN32:
|
||||
case CAM_FORMAT_PLAIN1128:
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_CRE, "Invalid output format %d",
|
||||
cre_acquire->out_res[i].format);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1270,9 +1569,6 @@ static int cam_cre_get_acquire_info(struct cam_cre_hw_mgr *hw_mgr,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (cam_cre_validate_acquire_res_info(&ctx->cre_acquire))
|
||||
return -EINVAL;
|
||||
|
||||
CAM_DBG(CAM_CRE, "top: %u %s %u %u %u",
|
||||
ctx->cre_acquire.dev_type,
|
||||
ctx->cre_acquire.dev_name,
|
||||
@@ -1295,6 +1591,9 @@ static int cam_cre_get_acquire_info(struct cam_cre_hw_mgr *hw_mgr,
|
||||
ctx->cre_acquire.out_res[i].format);
|
||||
}
|
||||
|
||||
if (cam_cre_validate_acquire_res_info(&ctx->cre_acquire))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1626,6 +1925,8 @@ static int cam_cre_mgr_release_ctx(struct cam_cre_hw_mgr *hw_mgr, int ctx_id)
|
||||
|
||||
hw_mgr->ctx[ctx_id].req_cnt = 0;
|
||||
hw_mgr->ctx[ctx_id].last_flush_req = 0;
|
||||
hw_mgr->ctx[ctx_id].last_req_idx = 0;
|
||||
hw_mgr->ctx[ctx_id].last_done_req_idx = 0;
|
||||
cam_cre_put_free_ctx(hw_mgr, ctx_id);
|
||||
|
||||
rc = cam_cre_mgr_cre_clk_remove(hw_mgr, ctx_id);
|
||||
@@ -1888,12 +2189,16 @@ static int cam_cre_mgr_prepare_hw_update(void *hw_priv,
|
||||
return rc;
|
||||
}
|
||||
|
||||
request_idx = find_first_zero_bit(ctx_data->bitmap, ctx_data->bits);
|
||||
request_idx = find_next_zero_bit(ctx_data->bitmap,
|
||||
ctx_data->bits, ctx_data->last_req_idx);
|
||||
if (request_idx >= CAM_CTX_REQ_MAX || request_idx < 0) {
|
||||
mutex_unlock(&ctx_data->ctx_mutex);
|
||||
CAM_ERR(CAM_CRE, "Invalid ctx req slot = %d", request_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
CAM_DBG(CAM_CRE, "req_idx %d last_req_idx %d bitmap size in bits %d",
|
||||
request_idx, ctx_data->last_req_idx, ctx_data->bits);
|
||||
ctx_data->last_req_idx = request_idx;
|
||||
|
||||
ctx_data->req_list[request_idx] =
|
||||
kzalloc(sizeof(struct cam_cre_request), GFP_KERNEL);
|
||||
@@ -1903,8 +2208,13 @@ static int cam_cre_mgr_prepare_hw_update(void *hw_priv,
|
||||
rc = -ENOMEM;
|
||||
goto req_mem_alloc_failed;
|
||||
}
|
||||
memset(ctx_data->req_list[request_idx], 0,
|
||||
sizeof(struct cam_cre_request));
|
||||
|
||||
cre_req = ctx_data->req_list[request_idx];
|
||||
cre_req->request_id = packet->header.request_id;
|
||||
cre_req->frames_done = 0;
|
||||
cre_req->req_idx = request_idx;
|
||||
|
||||
rc = cam_cre_mgr_process_io_cfg(hw_mgr, packet, ctx_data,
|
||||
request_idx, prepare_args);
|
||||
@@ -1987,8 +2297,13 @@ static int cam_cre_mgr_enqueue_config(struct cam_cre_hw_mgr *hw_mgr,
|
||||
task_data->req_idx = cre_req->req_idx;
|
||||
task_data->type = CRE_WORKQ_TASK_CMD_TYPE;
|
||||
task->process_cb = cam_cre_mgr_process_cmd;
|
||||
rc = cam_req_mgr_workq_enqueue_task(task, ctx_data,
|
||||
CRM_TASK_PRIORITY_0);
|
||||
|
||||
if (ctx_data->cre_acquire.dev_type == CAM_CRE_DEV_TYPE_RT)
|
||||
rc = cam_req_mgr_workq_enqueue_task(task, ctx_data,
|
||||
CRM_TASK_PRIORITY_0);
|
||||
else
|
||||
rc = cam_req_mgr_workq_enqueue_task(task, ctx_data,
|
||||
CRM_TASK_PRIORITY_1);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -2057,7 +2372,7 @@ static void cam_cre_mgr_print_io_bufs(struct cam_packet *packet,
|
||||
int32_t iommu_hdl, int32_t sec_mmu_hdl, uint32_t pf_buf_info,
|
||||
bool *mem_found)
|
||||
{
|
||||
dma_addr_t iova_addr;
|
||||
dma_addr_t iova_addr;
|
||||
size_t src_buf_size;
|
||||
int i;
|
||||
int j;
|
||||
@@ -2158,6 +2473,8 @@ static int cam_cre_mgr_flush_req(struct cam_cre_ctx *ctx_data,
|
||||
{
|
||||
int idx;
|
||||
int64_t request_id;
|
||||
uint32_t evt_id;
|
||||
struct cam_hw_done_event_data buf_data;
|
||||
|
||||
request_id = *(int64_t *)flush_args->flush_req_pending[0];
|
||||
for (idx = 0; idx < CAM_CTX_REQ_MAX; idx++) {
|
||||
@@ -2167,6 +2484,10 @@ static int cam_cre_mgr_flush_req(struct cam_cre_ctx *ctx_data,
|
||||
if (ctx_data->req_list[idx]->request_id != request_id)
|
||||
continue;
|
||||
|
||||
evt_id = CAM_CTX_EVT_ID_ERROR;
|
||||
buf_data.evt_param = CAM_SYNC_CRE_EVENT_HW_ERR;
|
||||
buf_data.request_id = ctx_data->req_list[idx]->request_id;
|
||||
ctx_data->ctxt_event_cb(ctx_data->context_priv, evt_id, &buf_data);
|
||||
ctx_data->req_list[idx]->request_id = 0;
|
||||
cam_cre_free_io_config(ctx_data->req_list[idx]);
|
||||
cam_free_clear(ctx_data->req_list[idx]);
|
||||
@@ -2181,6 +2502,8 @@ static int cam_cre_mgr_flush_all(struct cam_cre_ctx *ctx_data,
|
||||
struct cam_hw_flush_args *flush_args)
|
||||
{
|
||||
int i, rc;
|
||||
uint32_t evt_id;
|
||||
struct cam_hw_done_event_data buf_data;
|
||||
|
||||
mutex_lock(&ctx_data->ctx_mutex);
|
||||
rc = cam_cre_mgr_reset_hw();
|
||||
@@ -2189,6 +2512,10 @@ static int cam_cre_mgr_flush_all(struct cam_cre_ctx *ctx_data,
|
||||
if (!ctx_data->req_list[i])
|
||||
continue;
|
||||
|
||||
evt_id = CAM_CTX_EVT_ID_ERROR;
|
||||
buf_data.evt_param = CAM_SYNC_CRE_EVENT_HW_ERR;
|
||||
buf_data.request_id = ctx_data->req_list[i]->request_id;
|
||||
ctx_data->ctxt_event_cb(ctx_data->context_priv, evt_id, &buf_data);
|
||||
ctx_data->req_list[i]->request_id = 0;
|
||||
cam_cre_free_io_config(ctx_data->req_list[i]);
|
||||
cam_free_clear(ctx_data->req_list[i]);
|
||||
@@ -2533,15 +2860,6 @@ static int cam_cre_create_debug_fs(void)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!debugfs_create_bool("frame_dump_enable",
|
||||
0644,
|
||||
cre_hw_mgr->dentry,
|
||||
&cre_hw_mgr->frame_dump_enable)) {
|
||||
CAM_ERR(CAM_CRE,
|
||||
"failed to create dump_enable_debug");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!debugfs_create_bool("dump_req_data_enable",
|
||||
0644,
|
||||
cre_hw_mgr->dentry,
|
||||
@@ -2557,18 +2875,18 @@ err:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int cam_cre_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
|
||||
int cam_cre_hw_mgr_init(struct device_node *of_node, void *hw_mgr,
|
||||
int *iommu_hdl)
|
||||
{
|
||||
int i, rc = 0, j;
|
||||
struct cam_hw_mgr_intf *hw_mgr_intf;
|
||||
|
||||
if (!of_node || !hw_mgr_hdl) {
|
||||
if (!of_node || !hw_mgr) {
|
||||
CAM_ERR(CAM_CRE, "Invalid args of_node %pK hw_mgr %pK",
|
||||
of_node, hw_mgr_hdl);
|
||||
of_node, hw_mgr);
|
||||
return -EINVAL;
|
||||
}
|
||||
hw_mgr_intf = (struct cam_hw_mgr_intf *)hw_mgr_hdl;
|
||||
hw_mgr_intf = (struct cam_hw_mgr_intf *)hw_mgr;
|
||||
|
||||
cre_hw_mgr = kzalloc(sizeof(struct cam_cre_hw_mgr), GFP_KERNEL);
|
||||
if (!cre_hw_mgr) {
|
||||
|
@@ -19,20 +19,12 @@
|
||||
#include "cre_top.h"
|
||||
|
||||
#define CRE_CTX_MAX 32
|
||||
#define CAM_FRAME_CMD_MAX 20
|
||||
|
||||
#define CRE_WORKQ_NUM_TASK 100
|
||||
#define CRE_WORKQ_NUM_TASK 64
|
||||
#define CRE_WORKQ_TASK_CMD_TYPE 1
|
||||
#define CRE_WORKQ_TASK_MSG_TYPE 2
|
||||
|
||||
#define CRE_PACKET_SIZE 0
|
||||
#define CRE_PACKET_TYPE 1
|
||||
#define CRE_PACKET_OPCODE 2
|
||||
|
||||
#define CRE_PACKET_MAX_CMD_BUFS 4
|
||||
|
||||
#define CRE_FRAME_PROCESS_SUCCESS 0
|
||||
#define CRE_FRAME_PROCESS_FAILURE 1
|
||||
#define CRE_PACKET_MAX_CMD_BUFS 1
|
||||
|
||||
#define CRE_CTX_STATE_FREE 0
|
||||
#define CRE_CTX_STATE_IN_USE 1
|
||||
@@ -46,22 +38,18 @@
|
||||
#define CAM_CRE_BW_CONFIG_UNKNOWN 0
|
||||
#define CAM_CRE_BW_CONFIG_V2 2
|
||||
|
||||
#define CRE_DEV_MAX 1
|
||||
#define CLK_HW_CRE 0x0
|
||||
#define CLK_HW_MAX 0x1
|
||||
|
||||
#define CRE_DEVICE_IDLE_TIMEOUT 400
|
||||
#define CRE_REQUEST_TIMEOUT 200
|
||||
|
||||
#define CAM_CRE_HW_CFG_Q_MAX 50
|
||||
|
||||
#define CAM_CRE_MAX_PER_PATH_VOTES 6
|
||||
#define CAM_CRE_MAX_REG_SET 32
|
||||
|
||||
#define CAM_CRE_MAX_ACTIVE 8
|
||||
/*
|
||||
* Response time threshold in ms beyond which a request is not expected
|
||||
* to be with CRE hw
|
||||
*/
|
||||
#define CAM_CRE_RESPONSE_TIME_THRESHOLD 100000
|
||||
#define CAM_CRE_RESPONSE_TIME_THRESHOLD 300
|
||||
|
||||
/*
|
||||
* struct cam_cre_irq_data
|
||||
@@ -187,23 +175,6 @@ struct cre_clk_work_data {
|
||||
void *data;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cre_debug_buffer
|
||||
*
|
||||
* @cpu_addr: CPU address
|
||||
* @iova_addr: IOVA address
|
||||
* @len: Buffer length
|
||||
* @size: Buffer Size
|
||||
* @offset: buffer offset
|
||||
*/
|
||||
struct cre_debug_buffer {
|
||||
uintptr_t cpu_addr;
|
||||
dma_addr_t iova_addr;
|
||||
size_t len;
|
||||
uint32_t size;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct plane_info {
|
||||
uintptr_t cpu_addr;
|
||||
dma_addr_t iova_addr;
|
||||
@@ -213,7 +184,6 @@ struct plane_info {
|
||||
uint32_t format;
|
||||
uint32_t alignment;
|
||||
uint32_t offset;
|
||||
uint32_t x_init;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
@@ -222,9 +192,10 @@ struct plane_info {
|
||||
*
|
||||
* @direction: Direction of a buffer
|
||||
* @resource_type: Resource type of IO Buffer
|
||||
* @format: Format
|
||||
* @format: Format
|
||||
* @fence: Fence
|
||||
* @num_planes: Number of planes
|
||||
* p_info: per plane info
|
||||
*/
|
||||
struct cre_io_buf {
|
||||
uint32_t direction;
|
||||
@@ -310,7 +281,6 @@ struct cam_cre_request {
|
||||
uint32_t num_io_bufs[CRE_MAX_BATCH_SIZE];
|
||||
uint32_t in_resource;
|
||||
struct cre_reg_buffer cre_reg_buf[CRE_MAX_BATCH_SIZE];
|
||||
struct cre_debug_buffer cre_debug_buf;
|
||||
struct cre_io_buf *io_buf[CRE_MAX_BATCH_SIZE][CRE_MAX_IO_BUFS];
|
||||
struct cam_cre_clk_bw_request clk_info;
|
||||
struct cam_cre_clk_bw_req_internal_v2 clk_info_v2;
|
||||
@@ -321,54 +291,54 @@ struct cam_cre_request {
|
||||
/**
|
||||
* struct cam_cre_ctx
|
||||
*
|
||||
* @context_priv: Private data of context
|
||||
* @bitmap: Context bit map
|
||||
* @bitmap_size: Context bit map size
|
||||
* @bits: Context bit map bits
|
||||
* @ctx_id: Context ID
|
||||
* @ctx_state: State of a context
|
||||
* @req_cnt: Requests count
|
||||
* @ctx_mutex: Mutex for context
|
||||
* @acquire_dev_cmd: Cam acquire command
|
||||
* @cre_acquire: CRE acquire command
|
||||
* @ctxt_event_cb: Callback of a context
|
||||
* @req_list: Request List
|
||||
* @last_req_time: Timestamp of last request
|
||||
* @req_watch_dog: Watchdog for requests
|
||||
* @req_watch_dog_reset_counter: Request reset counter
|
||||
* @clk_info: CRE Ctx clock info
|
||||
* @clk_watch_dog: Clock watchdog
|
||||
* @clk_watch_dog_reset_counter: Reset counter
|
||||
* @last_flush_req: last flush req for this ctx
|
||||
* @ctx_id: Context ID
|
||||
* @ctx_state: State of a context
|
||||
* @req_cnt: Requests count
|
||||
* @last_flush_req: last flush req for this ctx
|
||||
* @last_req_time: Timestamp of last request
|
||||
* @last_req_idx: Last submitted req index
|
||||
* @last_done_req_idx: Last done req index
|
||||
* @bitmap: Context bit map
|
||||
* @bitmap_size: Context bit map size
|
||||
* @bits: Context bit map bits
|
||||
* @context_priv: Private data of context
|
||||
* @iommu_hdl: smmu handle
|
||||
* @ctx_mutex: Mutex for context
|
||||
* @acquire_dev_cmd: Cam acquire command
|
||||
* @cre_acquire: CRE acquire command
|
||||
* @clk_info: CRE Ctx clock info
|
||||
* @packet: Current packet to process
|
||||
* @cre_top: Pointer to CRE top data structure
|
||||
* @req_list: Request List
|
||||
* @ctxt_event_cb: Callback of a context
|
||||
*/
|
||||
struct cam_cre_ctx {
|
||||
void *context_priv;
|
||||
size_t bitmap_size;
|
||||
void *bitmap;
|
||||
size_t bits;
|
||||
uint32_t ctx_id;
|
||||
uint32_t ctx_state;
|
||||
uint32_t req_cnt;
|
||||
struct mutex ctx_mutex;
|
||||
struct cam_acquire_dev_cmd acquire_dev_cmd;
|
||||
struct cam_cre_acquire_dev_info cre_acquire;
|
||||
cam_hw_event_cb_func ctxt_event_cb;
|
||||
struct cam_cre_request *req_list[CAM_CTX_REQ_MAX];
|
||||
struct cam_cre_request *active_req;
|
||||
uint64_t last_req_time;
|
||||
struct cam_req_mgr_timer *req_watch_dog;
|
||||
uint32_t req_watch_dog_reset_counter;
|
||||
struct cam_cre_ctx_clk_info clk_info;
|
||||
struct cam_req_mgr_timer *clk_watch_dog;
|
||||
struct cre_top *cre_top;
|
||||
uint32_t clk_watch_dog_reset_counter;
|
||||
uint64_t last_flush_req;
|
||||
uint64_t last_req_time;
|
||||
uint64_t last_req_idx;
|
||||
uint64_t last_done_req_idx;
|
||||
void *bitmap;
|
||||
size_t bitmap_size;
|
||||
size_t bits;
|
||||
void *context_priv;
|
||||
int iommu_hdl;
|
||||
|
||||
struct mutex ctx_mutex;
|
||||
struct cam_acquire_dev_cmd acquire_dev_cmd;
|
||||
struct cam_cre_acquire_dev_info cre_acquire;
|
||||
struct cam_cre_ctx_clk_info clk_info;
|
||||
struct cre_top *cre_top;
|
||||
struct cam_packet *packet;
|
||||
struct cam_cre_request *req_list[CAM_CTX_REQ_MAX];
|
||||
cam_hw_event_cb_func ctxt_event_cb;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_cre_hw_mgr
|
||||
*
|
||||
* @cren_cnt: CRE device cren count
|
||||
* @cre_ctx_cnt: Open context count
|
||||
* @hw_mgr_mutex: Mutex for HW manager
|
||||
* @hw_mgr_lock: Spinlock for HW manager
|
||||
@@ -391,11 +361,9 @@ struct cam_cre_ctx {
|
||||
* @cre_dev_intf: CRE device interface
|
||||
* @clk_info: CRE clock Info for HW manager
|
||||
* @dentry: Pointer to CRE debugfs directory
|
||||
* @frame_dump_enable: CRE frame setting dump enablement
|
||||
* @dump_req_data_enable: CRE hang dump enablement
|
||||
*/
|
||||
struct cam_cre_hw_mgr {
|
||||
int32_t cren_cnt;
|
||||
uint32_t cre_ctx_cnt;
|
||||
struct mutex hw_mgr_mutex;
|
||||
spinlock_t hw_mgr_lock;
|
||||
@@ -420,7 +388,6 @@ struct cam_cre_hw_mgr {
|
||||
struct cam_soc_reg_map *reg_map[CRE_DEV_MAX][CRE_BASE_MAX];
|
||||
struct cam_cre_clk_info clk_info;
|
||||
struct dentry *dentry;
|
||||
bool frame_dump_enable;
|
||||
bool dump_req_data_enable;
|
||||
};
|
||||
|
||||
|
@@ -2,30 +2,17 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <media/cam_cre.h>
|
||||
#include "cam_io_util.h"
|
||||
#include "cam_hw.h"
|
||||
#include "cam_hw_intf.h"
|
||||
#include "cre_core.h"
|
||||
#include "cre_soc.h"
|
||||
#include "cam_soc_util.h"
|
||||
#include "cam_io_util.h"
|
||||
#include "cam_cpas_api.h"
|
||||
#include "cam_debug_util.h"
|
||||
#include "cam_common_util.h"
|
||||
#include "cre_core.h"
|
||||
#include "cre_hw.h"
|
||||
#include "cre_dev_intf.h"
|
||||
#include "cre_bus_rd.h"
|
||||
#include "cam_common_util.h"
|
||||
#include <media/cam_cre.h>
|
||||
|
||||
static struct cre_bus_rd *bus_rd;
|
||||
|
||||
@@ -36,6 +23,55 @@ static struct cre_bus_rd *bus_rd;
|
||||
cre_reg_buf->num_rd_reg_set++; \
|
||||
} while (0)
|
||||
|
||||
static int cam_cre_bus_rd_in_port_idx(uint32_t input_port_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CRE_MAX_IN_RES; i++)
|
||||
if (bus_rd->in_port_to_rm[i].input_port_id ==
|
||||
input_port_id)
|
||||
return i;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void cam_cre_update_read_reg_val(struct plane_info p_info,
|
||||
struct cam_cre_bus_rd_client_reg_val *rd_client_reg_val)
|
||||
{
|
||||
switch (p_info.format) {
|
||||
case CAM_FORMAT_MIPI_RAW_10:
|
||||
rd_client_reg_val->format = 0xd;
|
||||
break;
|
||||
case CAM_FORMAT_MIPI_RAW_12:
|
||||
rd_client_reg_val->format = 0xe;
|
||||
break;
|
||||
case CAM_FORMAT_MIPI_RAW_14:
|
||||
rd_client_reg_val->format = 0xf;
|
||||
break;
|
||||
case CAM_FORMAT_MIPI_RAW_20:
|
||||
rd_client_reg_val->format = 0x13;
|
||||
break;
|
||||
case CAM_FORMAT_PLAIN128:
|
||||
rd_client_reg_val->format = 0x0;
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_CRE, "Unsupported read format");
|
||||
return;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_CRE,
|
||||
"format %d width(in bytes) %d height %d stride(in byte) %d",
|
||||
p_info.format, p_info.width, p_info.height, p_info.stride);
|
||||
CAM_DBG(CAM_CRE, "alignment 0x%x",
|
||||
p_info.alignment);
|
||||
|
||||
/* Fetch engine width has to be updated in number of bytes */
|
||||
rd_client_reg_val->img_width = p_info.stride;
|
||||
rd_client_reg_val->stride = p_info.stride;
|
||||
rd_client_reg_val->img_height = p_info.height;
|
||||
rd_client_reg_val->alignment = p_info.alignment;
|
||||
}
|
||||
|
||||
static int cam_cre_bus_rd_release(struct cam_cre_hw *cam_cre_hw_info,
|
||||
int32_t ctx_id, void *data)
|
||||
{
|
||||
@@ -54,22 +90,17 @@ static int cam_cre_bus_rd_update(struct cam_cre_hw *cam_cre_hw_info,
|
||||
int32_t ctx_id, struct cre_reg_buffer *cre_reg_buf, int batch_idx,
|
||||
int io_idx, struct cam_cre_dev_prepare_req *prepare)
|
||||
{
|
||||
int k;
|
||||
uint32_t req_idx, temp;
|
||||
uint32_t rm_id;
|
||||
uint32_t rsc_type;
|
||||
int k, in_port_idx;
|
||||
uint32_t req_idx, val;
|
||||
uint32_t iova_base, iova_offset;
|
||||
struct cam_hw_prepare_update_args *prepare_args;
|
||||
struct cam_cre_ctx *ctx_data;
|
||||
struct cam_cre_request *cre_request;
|
||||
struct cre_io_buf *io_buf;
|
||||
struct cre_bus_rd_ctx *bus_rd_ctx;
|
||||
struct cam_cre_bus_rd_reg *rd_reg;
|
||||
struct cam_cre_bus_rd_client_reg *rd_reg_client;
|
||||
struct cam_cre_bus_rd_reg_val *rd_reg_val;
|
||||
struct cam_cre_bus_rd_client_reg_val *rd_res_val_client;
|
||||
struct cre_bus_in_port_to_rm *in_port_to_rm;
|
||||
struct cre_bus_rd_io_port_info *io_port_info;
|
||||
struct cam_cre_bus_rd_client_reg_val *rd_client_reg_val;
|
||||
|
||||
if (ctx_id < 0 || !prepare) {
|
||||
CAM_ERR(CAM_CRE, "Invalid data: %d %x", ctx_id, prepare);
|
||||
@@ -93,8 +124,6 @@ static int cam_cre_bus_rd_update(struct cam_cre_hw *cam_cre_hw_info,
|
||||
cre_request = ctx_data->req_list[req_idx];
|
||||
CAM_DBG(CAM_CRE, "req_idx = %d req_id = %lld",
|
||||
req_idx, cre_request->request_id);
|
||||
bus_rd_ctx = bus_rd->bus_rd_ctx[ctx_id];
|
||||
io_port_info = &bus_rd_ctx->io_port_info;
|
||||
rd_reg = cam_cre_hw_info->bus_rd_reg_offset;
|
||||
rd_reg_val = cam_cre_hw_info->bus_rd_reg_val;
|
||||
io_buf = cre_request->io_buf[batch_idx][io_idx];
|
||||
@@ -106,15 +135,13 @@ static int cam_cre_bus_rd_update(struct cam_cre_hw *cam_cre_hw_info,
|
||||
CAM_DBG(CAM_CRE, "batch:%d iobuf:%d direction:%d",
|
||||
batch_idx, io_idx, io_buf->direction);
|
||||
|
||||
in_port_to_rm =
|
||||
&bus_rd->in_port_to_rm[io_buf->resource_type - 1];
|
||||
in_port_idx =
|
||||
cam_cre_bus_rd_in_port_idx(io_buf->resource_type);
|
||||
|
||||
CAM_DBG(CAM_CRE, "in_port_idx %d", in_port_idx);
|
||||
for (k = 0; k < io_buf->num_planes; k++) {
|
||||
rsc_type = io_buf->resource_type - 1;
|
||||
/* frame level info */
|
||||
rm_id = in_port_to_rm->rm_port_id[k];
|
||||
rd_reg_client = &rd_reg->rd_clients[rm_id];
|
||||
rd_res_val_client = &rd_reg_val->rd_clients[rm_id];
|
||||
rd_reg_client = &rd_reg->rd_clients[in_port_idx];
|
||||
rd_client_reg_val = &rd_reg_val->rd_clients[in_port_idx];
|
||||
|
||||
/* security cfg */
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
@@ -127,11 +154,9 @@ static int cam_cre_bus_rd_update(struct cam_cre_hw *cam_cre_hw_info,
|
||||
1);
|
||||
|
||||
/* ccif meta data */
|
||||
temp = 0;
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
(rd_reg->offset + rd_reg_client->ccif_meta_data),
|
||||
temp);
|
||||
|
||||
0);
|
||||
/*
|
||||
* As CRE have 36 Bit addressing support Image Address
|
||||
* register will have 28 bit MSB of 36 bit iova.
|
||||
@@ -148,40 +173,39 @@ static int cam_cre_bus_rd_update(struct cam_cre_hw *cam_cre_hw_info,
|
||||
rd_reg->offset + rd_reg_client->addr_cfg,
|
||||
iova_offset);
|
||||
|
||||
cam_cre_update_read_reg_val(io_buf->p_info[k],
|
||||
rd_client_reg_val);
|
||||
|
||||
/* Buffer size */
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
rd_reg->offset + rd_reg_client->rd_width,
|
||||
io_buf->p_info[k].width);
|
||||
rd_client_reg_val->img_width);
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
rd_reg->offset + rd_reg_client->rd_height,
|
||||
io_buf->p_info[k].height);
|
||||
rd_client_reg_val->img_height);
|
||||
|
||||
/* stride */
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
rd_reg->offset + rd_reg_client->rd_stride,
|
||||
io_buf->p_info[k].stride);
|
||||
rd_client_reg_val->stride);
|
||||
|
||||
/* unpacker cfg : Mode and alignment */
|
||||
temp = 0;
|
||||
temp |= (io_buf->p_info[k].format &
|
||||
rd_res_val_client->mode_mask) <<
|
||||
rd_res_val_client->mode_shift;
|
||||
temp |= (io_buf->p_info[k].alignment &
|
||||
rd_res_val_client->alignment_mask) <<
|
||||
rd_res_val_client->alignment_shift;
|
||||
val = 0;
|
||||
val |= (rd_client_reg_val->format &
|
||||
rd_client_reg_val->format_mask) <<
|
||||
rd_client_reg_val->format_shift;
|
||||
val |= (rd_client_reg_val->alignment &
|
||||
rd_client_reg_val->alignment_mask) <<
|
||||
rd_client_reg_val->alignment_shift;
|
||||
/* unpacker cfg : format and alignment */
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
rd_reg->offset + rd_reg_client->unpacker_cfg,
|
||||
temp);
|
||||
rd_reg->offset + rd_reg_client->unpacker_cfg,
|
||||
val);
|
||||
|
||||
/* latency buffer allocation */
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
rd_reg->offset + rd_reg_client->latency_buf_allocation,
|
||||
io_port_info->latency_buf_size);
|
||||
/* Enable Debug cfg */
|
||||
temp = 0xFFFF;
|
||||
val = 0xFFFF;
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
rd_reg->offset + rd_reg_client->debug_status_cfg,
|
||||
temp);
|
||||
rd_reg->offset + rd_reg_client->debug_status_cfg,
|
||||
val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -197,12 +221,11 @@ static int cam_cre_bus_rd_prepare(struct cam_cre_hw *cam_cre_hw_info,
|
||||
struct cam_cre_ctx *ctx_data;
|
||||
struct cam_cre_request *cre_request;
|
||||
struct cre_io_buf *io_buf;
|
||||
struct cre_bus_rd_ctx *bus_rd_ctx;
|
||||
struct cam_cre_bus_rd_reg *rd_reg;
|
||||
struct cam_cre_bus_rd_reg_val *rd_reg_val;
|
||||
struct cre_reg_buffer *cre_reg_buf;
|
||||
|
||||
int temp;
|
||||
int val;
|
||||
|
||||
if (ctx_id < 0 || !data) {
|
||||
CAM_ERR(CAM_CRE, "Invalid data: %d %x", ctx_id, data);
|
||||
@@ -217,7 +240,6 @@ static int cam_cre_bus_rd_prepare(struct cam_cre_hw *cam_cre_hw_info,
|
||||
|
||||
CAM_DBG(CAM_CRE, "req_idx = %d req_id = %lld",
|
||||
req_idx, cre_request->request_id);
|
||||
bus_rd_ctx = bus_rd->bus_rd_ctx[ctx_id];
|
||||
rd_reg = cam_cre_hw_info->bus_rd_reg_offset;
|
||||
rd_reg_val = cam_cre_hw_info->bus_rd_reg_val;
|
||||
|
||||
@@ -238,29 +260,23 @@ static int cam_cre_bus_rd_prepare(struct cam_cre_hw *cam_cre_hw_info,
|
||||
}
|
||||
|
||||
/* Go command */
|
||||
temp = 0;
|
||||
temp |= rd_reg_val->go_cmd;
|
||||
temp |= rd_reg_val->static_prg & rd_reg_val->static_prg_mask;
|
||||
val = 0;
|
||||
val |= rd_reg_val->go_cmd;
|
||||
val |= rd_reg_val->static_prg & rd_reg_val->static_prg_mask;
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
rd_reg->offset + rd_reg->input_if_cmd,
|
||||
temp);
|
||||
val);
|
||||
}
|
||||
|
||||
for (i = 0; i < cre_reg_buf->num_rd_reg_set; i++) {
|
||||
CAM_DBG(CAM_CRE, "CRE value 0x%x offset 0x%x",
|
||||
cre_reg_buf->rd_reg_set[i].value,
|
||||
cre_reg_buf->rd_reg_set[i].offset);
|
||||
}
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_cre_bus_rd_in_port_idx(uint32_t input_port_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CRE_MAX_IN_RES; i++)
|
||||
if (bus_rd->in_port_to_rm[i].input_port_id ==
|
||||
input_port_id)
|
||||
return i;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int cam_cre_bus_rd_acquire(struct cam_cre_hw *cam_cre_hw_info,
|
||||
int32_t ctx_id, void *data)
|
||||
{
|
||||
@@ -271,7 +287,6 @@ static int cam_cre_bus_rd_acquire(struct cam_cre_hw *cam_cre_hw_info,
|
||||
struct cam_cre_bus_rd_reg_val *bus_rd_reg_val;
|
||||
int in_port_idx;
|
||||
|
||||
|
||||
if (ctx_id < 0 || !data || !cam_cre_hw_info || ctx_id >= CRE_CTX_MAX) {
|
||||
CAM_ERR(CAM_CRE, "Invalid data: %d %x %x",
|
||||
ctx_id, data, cam_cre_hw_info);
|
||||
@@ -295,12 +310,14 @@ static int cam_cre_bus_rd_acquire(struct cam_cre_hw *cam_cre_hw_info,
|
||||
if (!in_acquire->in_res[i].width)
|
||||
continue;
|
||||
|
||||
CAM_DBG(CAM_CRE, "i = %d format = %u width = %x height = %x",
|
||||
CAM_DBG(CAM_CRE, "i = %d format = %u width = 0x%x height = 0x%x res id %d",
|
||||
i, in_acquire->in_res[i].format,
|
||||
in_acquire->in_res[i].width,
|
||||
in_acquire->in_res[i].height);
|
||||
in_acquire->in_res[i].height,
|
||||
in_acquire->in_res[i].res_id);
|
||||
|
||||
in_port_idx = cam_cre_bus_rd_in_port_idx(i + 1);
|
||||
in_port_idx =
|
||||
cam_cre_bus_rd_in_port_idx(in_acquire->in_res[i].res_id);
|
||||
if (in_port_idx < 0) {
|
||||
CAM_ERR(CAM_CRE, "Invalid in_port_idx: %d", i + 1);
|
||||
rc = -EINVAL;
|
||||
@@ -308,21 +325,15 @@ static int cam_cre_bus_rd_acquire(struct cam_cre_hw *cam_cre_hw_info,
|
||||
}
|
||||
|
||||
in_port_to_rm = &bus_rd->in_port_to_rm[in_port_idx];
|
||||
|
||||
if (!in_port_to_rm->num_rm) {
|
||||
CAM_ERR(CAM_CRE, "Invalid format for Input port");
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
bus_rd_ctx->io_port_info.input_port_id[i] =
|
||||
in_acquire->in_res[i].res_id;
|
||||
bus_rd_ctx->io_port_info.input_format_type[i] =
|
||||
in_acquire->in_res[i].format;
|
||||
|
||||
CAM_DBG(CAM_CRE, "i:%d port_id = %u format %u",
|
||||
i, bus_rd_ctx->io_port_info.input_port_id[i],
|
||||
bus_rd_ctx->io_port_info.input_format_type[i]);
|
||||
i, in_acquire->in_res[i].res_id,
|
||||
in_acquire->in_res[i].format);
|
||||
}
|
||||
|
||||
end:
|
||||
@@ -342,6 +353,9 @@ static int cam_cre_bus_rd_reg_set_update(struct cam_cre_hw *cam_cre_hw_info,
|
||||
rd_reg_set = reg_set_upd_cmd->cre_reg_buf.rd_reg_set;
|
||||
|
||||
for (i = 0; i < num_reg_set; i++) {
|
||||
CAM_DBG(CAM_CRE, "base 0x%x CRE value 0x%x offset 0x%x",
|
||||
cam_cre_hw_info->bus_rd_reg_offset->base,
|
||||
rd_reg_set[i].value, rd_reg_set[i].offset);
|
||||
cam_io_w_mb(rd_reg_set[i].value,
|
||||
cam_cre_hw_info->bus_rd_reg_offset->base + rd_reg_set[i].offset);
|
||||
}
|
||||
@@ -397,7 +411,7 @@ static int cam_cre_bus_rd_probe(struct cam_cre_hw *cam_cre_hw_info,
|
||||
|
||||
for (i = 0; i < bus_rd_reg_val->num_clients; i++) {
|
||||
input_port_idx =
|
||||
bus_rd_reg_val->rd_clients[i].input_port_id - 1;
|
||||
bus_rd_reg_val->rd_clients[i].rm_port_id;
|
||||
in_port_to_rm = &bus_rd->in_port_to_rm[input_port_idx];
|
||||
|
||||
rm_idx = in_port_to_rm->num_rm;
|
||||
@@ -439,7 +453,6 @@ static int cam_cre_bus_rd_isr(struct cam_cre_hw *cam_cre_hw_info,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_CRE, "error 0x%x", irq_data->error);
|
||||
bus_rd_reg = cam_cre_hw_info->bus_rd_reg_offset;
|
||||
bus_rd_reg_val = cam_cre_hw_info->bus_rd_reg_val;
|
||||
|
||||
|
@@ -15,58 +15,17 @@
|
||||
#include "cam_soc_util.h"
|
||||
#include "cam_cre_hw_mgr.h"
|
||||
|
||||
/**
|
||||
* struct cre_bus_rd_io_port_info
|
||||
*
|
||||
* @pixel_pattern: Pixel pattern
|
||||
* @input_port_id: Port Id
|
||||
* @input_format_type: Format type
|
||||
* @latency_buf_size: Latency buffer size
|
||||
*/
|
||||
struct cre_bus_rd_io_port_info {
|
||||
uint32_t pixel_pattern[CRE_MAX_IN_RES];
|
||||
uint32_t input_port_id[CRE_MAX_IN_RES];
|
||||
uint32_t input_format_type[CRE_MAX_IN_RES];
|
||||
uint32_t latency_buf_size;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cre_bus_rd_io_port_batch
|
||||
*
|
||||
* num_batch: Number of batches
|
||||
* io_port: CDM IO Port Info
|
||||
*/
|
||||
struct cre_bus_rd_io_port_batch {
|
||||
uint32_t num_batch;
|
||||
struct cre_bus_rd_io_port_info io_port[CRE_MAX_BATCH_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cre_bus_rd_rm
|
||||
*
|
||||
* @rm_port_id: RM port ID
|
||||
* @format_type: Format type
|
||||
*/
|
||||
struct cre_bus_rd_rm {
|
||||
uint32_t rm_port_id;
|
||||
uint32_t format_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cre_bus_rd_ctx
|
||||
*
|
||||
* @cre_acquire: CRE acquire structure
|
||||
* @security_flag: security flag
|
||||
* @num_in_ports: Number of in ports
|
||||
* @io_port_info: IO port info
|
||||
* @io_port_batch: IO port info
|
||||
*/
|
||||
struct cre_bus_rd_ctx {
|
||||
struct cam_cre_acquire_dev_info *cre_acquire;
|
||||
bool security_flag;
|
||||
uint32_t num_in_ports;
|
||||
struct cre_bus_rd_io_port_info io_port_info;
|
||||
struct cre_bus_rd_io_port_batch io_port_batch;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -2,32 +2,19 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <media/cam_cre.h>
|
||||
#include "cam_io_util.h"
|
||||
#include "cam_hw.h"
|
||||
#include "cam_hw_intf.h"
|
||||
#include "cre_core.h"
|
||||
#include "cre_soc.h"
|
||||
#include "cam_soc_util.h"
|
||||
#include "cam_io_util.h"
|
||||
#include "cam_cpas_api.h"
|
||||
#include "cam_debug_util.h"
|
||||
#include "cam_common_util.h"
|
||||
#include "cre_core.h"
|
||||
#include "cre_hw.h"
|
||||
#include "cre_dev_intf.h"
|
||||
#include "cre_bus_wr.h"
|
||||
#include "cam_common_util.h"
|
||||
#include <media/cam_cre.h>
|
||||
|
||||
static struct cre_bus_wr *wr_info;
|
||||
|
||||
#define update_cre_reg_set(cre_reg_buf, off, val) \
|
||||
do { \
|
||||
cre_reg_buf->wr_reg_set[cre_reg_buf->num_wr_reg_set].offset = (off); \
|
||||
@@ -35,6 +22,30 @@ static struct cre_bus_wr *wr_info;
|
||||
cre_reg_buf->num_wr_reg_set++; \
|
||||
} while (0)
|
||||
|
||||
static int cam_cre_translate_write_format(struct plane_info p_info,
|
||||
struct cam_cre_bus_wr_client_reg_val *wr_client_reg_val)
|
||||
{
|
||||
CAM_DBG(CAM_CRE, "width 0x%x, height 0x%x stride 0x%x alignment 0x%x",
|
||||
p_info.width, p_info.height, p_info.stride, p_info.alignment);
|
||||
|
||||
/* Number of output pixels */
|
||||
wr_client_reg_val->width = p_info.width;
|
||||
/* Number of output bytes */
|
||||
wr_client_reg_val->stride = p_info.stride;
|
||||
/* Number of output lines */
|
||||
wr_client_reg_val->height = p_info.height;
|
||||
wr_client_reg_val->alignment = p_info.alignment;
|
||||
|
||||
/*
|
||||
* Update packer format to zero irrespective of output format
|
||||
* This is as per the recomendation from CRE HW team for CRE 1.0
|
||||
* This logic has to be updated for CRE 1.1
|
||||
*/
|
||||
wr_client_reg_val->format = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_cre_bus_wr_out_port_idx(uint32_t output_port_id)
|
||||
{
|
||||
int i;
|
||||
@@ -59,6 +70,9 @@ static int cam_cre_bus_wr_reg_set_update(struct cam_cre_hw *cam_cre_hw_info,
|
||||
wr_reg_set = reg_set_upd_cmd->cre_reg_buf.wr_reg_set;
|
||||
|
||||
for (i = 0; i < num_reg_set; i++) {
|
||||
CAM_DBG(CAM_CRE, "base 0x%x CRE value 0x%x offset 0x%x",
|
||||
cam_cre_hw_info->bus_wr_reg_offset->base,
|
||||
wr_reg_set[i].value, wr_reg_set[i].offset);
|
||||
cam_io_w_mb(wr_reg_set[i].value,
|
||||
cam_cre_hw_info->bus_wr_reg_offset->base + wr_reg_set[i].offset);
|
||||
}
|
||||
@@ -84,23 +98,18 @@ static int cam_cre_bus_wr_update(struct cam_cre_hw *cam_cre_hw_info,
|
||||
int batch_idx, int io_idx,
|
||||
struct cre_reg_buffer *cre_reg_buf)
|
||||
{
|
||||
int k, out_port_idx;
|
||||
uint32_t num_wm_ports;
|
||||
uint32_t comb_idx = 0;
|
||||
int rc, k, out_port_idx;
|
||||
uint32_t req_idx;
|
||||
uint32_t temp = 0;
|
||||
uint32_t wm_port_id;
|
||||
uint32_t val = 0;
|
||||
uint32_t iova_base, iova_offset;
|
||||
struct cam_hw_prepare_update_args *prepare_args;
|
||||
struct cam_cre_ctx *ctx_data;
|
||||
struct cam_cre_request *cre_request;
|
||||
struct cre_io_buf *io_buf;
|
||||
struct cre_bus_wr_ctx *bus_wr_ctx;
|
||||
struct cam_cre_bus_wr_reg *wr_reg;
|
||||
struct cam_cre_bus_wr_client_reg *wr_reg_client;
|
||||
struct cam_cre_bus_wr_reg_val *wr_reg_val;
|
||||
struct cam_cre_bus_wr_client_reg_val *wr_res_val_client;
|
||||
struct cre_bus_out_port_to_wm *out_port_to_wm;
|
||||
struct cam_cre_bus_wr_client_reg_val *wr_client_reg_val;
|
||||
|
||||
if (ctx_id < 0 || !prepare) {
|
||||
CAM_ERR(CAM_CRE, "Invalid data: %d %x", ctx_id, prepare);
|
||||
@@ -122,11 +131,10 @@ static int cam_cre_bus_wr_update(struct cam_cre_hw *cam_cre_hw_info,
|
||||
req_idx = prepare->req_idx;
|
||||
|
||||
cre_request = ctx_data->req_list[req_idx];
|
||||
bus_wr_ctx = wr_info->bus_wr_ctx[ctx_id];
|
||||
wr_reg = cam_cre_hw_info->bus_wr_reg_offset;
|
||||
wr_reg_val = cam_cre_hw_info->bus_wr_reg_val;
|
||||
|
||||
CAM_DBG(CAM_CRE, "req_idx = %d req_id = %lld offset = %d",
|
||||
CAM_DBG(CAM_CRE, "req_idx = %d req_id = %lld",
|
||||
req_idx, cre_request->request_id);
|
||||
|
||||
io_buf = cre_request->io_buf[batch_idx][io_idx];
|
||||
@@ -140,25 +148,26 @@ static int cam_cre_bus_wr_update(struct cam_cre_hw *cam_cre_hw_info,
|
||||
io_buf->resource_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
out_port_to_wm = &wr_info->out_port_to_wm[out_port_idx];
|
||||
num_wm_ports = out_port_to_wm->num_wm;
|
||||
|
||||
CAM_DBG(CAM_CRE, "out_port_idx = %d", out_port_idx);
|
||||
|
||||
for (k = 0; k < io_buf->num_planes; k++) {
|
||||
CAM_DBG(CAM_CRE, "comb_idx = %d p_idx = %d",
|
||||
comb_idx, k);
|
||||
/* frame level info */
|
||||
wm_port_id = out_port_to_wm->wm_port_id[k];
|
||||
wr_reg_client = &wr_reg->wr_clients[wm_port_id];
|
||||
wr_res_val_client = &wr_reg_val->wr_clients[wm_port_id];
|
||||
wr_reg_client = &wr_reg->wr_clients[out_port_idx];
|
||||
wr_client_reg_val = &wr_reg_val->wr_clients[out_port_idx];
|
||||
|
||||
CAM_DBG(CAM_CRE, "wr_reg_client %x wr_client_reg_val %x",
|
||||
wr_reg_client, wr_client_reg_val, wr_client_reg_val);
|
||||
|
||||
/* Core cfg: enable, Mode */
|
||||
temp = 0;
|
||||
temp |= ((wr_res_val_client->mode &
|
||||
wr_res_val_client->mode_mask) <<
|
||||
wr_res_val_client->mode_shift);
|
||||
val = 0;
|
||||
val |= ((wr_client_reg_val->mode &
|
||||
wr_client_reg_val->mode_mask) <<
|
||||
wr_client_reg_val->mode_shift);
|
||||
val |= wr_client_reg_val->client_en;
|
||||
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
wr_reg->offset + wr_reg_client->client_cfg,
|
||||
temp);
|
||||
val);
|
||||
|
||||
/*
|
||||
* As CRE have 36 Bit addressing support Image Address
|
||||
@@ -174,41 +183,43 @@ static int cam_cre_bus_wr_update(struct cam_cre_hw *cam_cre_hw_info,
|
||||
wr_reg->offset + wr_reg_client->addr_cfg,
|
||||
iova_offset);
|
||||
|
||||
rc = cam_cre_translate_write_format(io_buf->p_info[k],
|
||||
wr_client_reg_val);
|
||||
if (rc < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Buffer size */
|
||||
temp = 0;
|
||||
temp = io_buf->p_info[k].width;
|
||||
temp |= (io_buf->p_info[k].height &
|
||||
wr_res_val_client->height_mask) <<
|
||||
wr_res_val_client->height_shift;
|
||||
val = 0;
|
||||
val = wr_client_reg_val->width;
|
||||
val |= (wr_client_reg_val->height &
|
||||
wr_client_reg_val->height_mask) <<
|
||||
wr_client_reg_val->height_shift;
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
wr_reg->offset + wr_reg_client->img_cfg_0,
|
||||
temp);
|
||||
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
wr_reg->offset + wr_reg_client->img_cfg_1,
|
||||
io_buf->p_info[k].x_init);
|
||||
val);
|
||||
|
||||
/* stride */
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
wr_reg->offset + wr_reg_client->img_cfg_2,
|
||||
io_buf->p_info[k].stride);
|
||||
wr_client_reg_val->stride);
|
||||
|
||||
val = 0;
|
||||
val |= ((wr_client_reg_val->format &
|
||||
wr_client_reg_val->format_mask) <<
|
||||
wr_client_reg_val->format_shift);
|
||||
val |= ((wr_client_reg_val->alignment &
|
||||
wr_client_reg_val->alignment_mask) <<
|
||||
wr_client_reg_val->alignment_shift);
|
||||
/* pack cfg : Format and alignment */
|
||||
temp = 0;
|
||||
temp |= ((io_buf->p_info[k].format &
|
||||
wr_res_val_client->format_mask) <<
|
||||
wr_res_val_client->format_shift);
|
||||
temp |= ((io_buf->p_info[k].alignment &
|
||||
wr_res_val_client->alignment_mask) <<
|
||||
wr_res_val_client->alignment_shift);
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
wr_reg->offset + wr_reg_client->packer_cfg,
|
||||
temp);
|
||||
val);
|
||||
|
||||
/* Upadte debug status CFG*/
|
||||
temp = 0xFFFF;
|
||||
val = 0xFFFF;
|
||||
update_cre_reg_set(cre_reg_buf,
|
||||
wr_reg->offset + wr_reg_client->debug_status_cfg,
|
||||
temp);
|
||||
val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -224,7 +235,6 @@ static int cam_cre_bus_wr_prepare(struct cam_cre_hw *cam_cre_hw_info,
|
||||
struct cam_cre_ctx *ctx_data;
|
||||
struct cam_cre_request *cre_request;
|
||||
struct cre_io_buf *io_buf;
|
||||
struct cre_bus_wr_ctx *bus_wr_ctx;
|
||||
struct cre_reg_buffer *cre_reg_buf;
|
||||
|
||||
if (ctx_id < 0 || !data) {
|
||||
@@ -234,7 +244,6 @@ static int cam_cre_bus_wr_prepare(struct cam_cre_hw *cam_cre_hw_info,
|
||||
prepare = data;
|
||||
ctx_data = prepare->ctx_data;
|
||||
req_idx = prepare->req_idx;
|
||||
bus_wr_ctx = wr_info->bus_wr_ctx[ctx_id];
|
||||
|
||||
cre_request = ctx_data->req_list[req_idx];
|
||||
|
||||
@@ -245,8 +254,8 @@ static int cam_cre_bus_wr_prepare(struct cam_cre_hw *cam_cre_hw_info,
|
||||
cre_reg_buf = &cre_request->cre_reg_buf[i];
|
||||
for (j = 0; j < cre_request->num_io_bufs[i]; j++) {
|
||||
io_buf = cre_request->io_buf[i][j];
|
||||
CAM_DBG(CAM_CRE, "batch = %d io buf num = %d dir = %d",
|
||||
i, j, io_buf->direction);
|
||||
CAM_DBG(CAM_CRE, "batch = %d io buf num = %d",
|
||||
i, j);
|
||||
if (io_buf->direction != CAM_BUF_OUTPUT)
|
||||
continue;
|
||||
|
||||
@@ -292,10 +301,11 @@ static int cam_cre_bus_wr_acquire(struct cam_cre_hw *cam_cre_hw_info,
|
||||
if (!in_acquire->out_res[i].width)
|
||||
continue;
|
||||
|
||||
CAM_DBG(CAM_CRE, "i = %d format = %u width = %x height = %x",
|
||||
CAM_DBG(CAM_CRE, "i = %d format = %u width = 0x%x height = 0x%x res_id %d",
|
||||
i, in_acquire->out_res[i].format,
|
||||
in_acquire->out_res[i].width,
|
||||
in_acquire->out_res[i].height);
|
||||
in_acquire->out_res[i].height,
|
||||
in_acquire->in_res[i].res_id);
|
||||
|
||||
out_port_idx =
|
||||
cam_cre_bus_wr_out_port_idx(in_acquire->out_res[i].res_id);
|
||||
@@ -306,20 +316,12 @@ static int cam_cre_bus_wr_acquire(struct cam_cre_hw *cam_cre_hw_info,
|
||||
goto end;
|
||||
}
|
||||
CAM_DBG(CAM_CRE, "out_port_idx %d", out_port_idx);
|
||||
out_port_to_wr = &wr_info->out_port_to_wm[out_port_idx - 1];
|
||||
out_port_to_wr = &wr_info->out_port_to_wm[out_port_idx];
|
||||
if (!out_port_to_wr->num_wm) {
|
||||
CAM_DBG(CAM_CRE, "Invalid format for Input port");
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
bus_wr_ctx->io_port_info.output_port_id[i] =
|
||||
in_acquire->out_res[i].res_id;
|
||||
bus_wr_ctx->io_port_info.output_format_type[i] =
|
||||
in_acquire->out_res[i].format;
|
||||
|
||||
CAM_DBG(CAM_CRE, "i:%d port_id = %u",
|
||||
i, bus_wr_ctx->io_port_info.output_port_id[i]);
|
||||
}
|
||||
|
||||
end:
|
||||
@@ -343,12 +345,12 @@ static int cam_cre_bus_wr_init(struct cam_cre_hw *cam_cre_hw_info,
|
||||
bus_wr_reg = cam_cre_hw_info->bus_wr_reg_offset;
|
||||
bus_wr_reg->base = dev_init->core_info->cre_hw_info->cre_bus_wr_base;
|
||||
|
||||
CAM_DBG(CAM_CRE, "bus_wr_reg->base 0x%x", bus_wr_reg->base);
|
||||
|
||||
cam_io_w_mb(bus_wr_reg_val->irq_mask_0,
|
||||
cam_cre_hw_info->bus_wr_reg_offset->base +
|
||||
bus_wr_reg->irq_mask_0);
|
||||
bus_wr_reg->base + bus_wr_reg->irq_mask_0);
|
||||
cam_io_w_mb(bus_wr_reg_val->irq_mask_1,
|
||||
cam_cre_hw_info->bus_wr_reg_offset->base +
|
||||
bus_wr_reg->irq_mask_1);
|
||||
bus_wr_reg->base + bus_wr_reg->irq_mask_1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -377,7 +379,7 @@ static int cam_cre_bus_wr_probe(struct cam_cre_hw *cam_cre_hw_info,
|
||||
|
||||
for (i = 0; i < bus_wr_reg_val->num_clients; i++) {
|
||||
output_port_idx =
|
||||
bus_wr_reg_val->wr_clients[i].output_port_id - 1;
|
||||
bus_wr_reg_val->wr_clients[i].wm_port_id;
|
||||
out_port_to_wm = &wr_info->out_port_to_wm[output_port_idx];
|
||||
wm_idx = out_port_to_wm->num_wm;
|
||||
out_port_to_wm->output_port_id =
|
||||
@@ -391,12 +393,12 @@ static int cam_cre_bus_wr_probe(struct cam_cre_hw *cam_cre_hw_info,
|
||||
out_port_to_wm = &wr_info->out_port_to_wm[i];
|
||||
CAM_DBG(CAM_CRE, "output port id = %d",
|
||||
out_port_to_wm->output_port_id);
|
||||
CAM_DBG(CAM_CRE, "num_wms = %d",
|
||||
out_port_to_wm->num_wm);
|
||||
for (k = 0; k < out_port_to_wm->num_wm; k++) {
|
||||
CAM_DBG(CAM_CRE, "wm port id = %d",
|
||||
out_port_to_wm->wm_port_id[k]);
|
||||
}
|
||||
CAM_DBG(CAM_CRE, "num_wms = %d",
|
||||
out_port_to_wm->num_wm);
|
||||
for (k = 0; k < out_port_to_wm->num_wm; k++) {
|
||||
CAM_DBG(CAM_CRE, "wm port id = %d",
|
||||
out_port_to_wm->wm_port_id[k]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -413,6 +415,7 @@ static int cam_cre_bus_wr_isr(struct cam_cre_hw *cam_cre_hw_info,
|
||||
uint32_t debug_status_1;
|
||||
uint32_t img_violation_status;
|
||||
uint32_t violation_status;
|
||||
int i;
|
||||
|
||||
if (!cam_cre_hw_info || !irq_data) {
|
||||
CAM_ERR(CAM_CRE, "Invalid cam_cre_hw_info");
|
||||
@@ -425,6 +428,10 @@ static int cam_cre_bus_wr_isr(struct cam_cre_hw *cam_cre_hw_info,
|
||||
/* Read and Clear Top Interrupt status */
|
||||
irq_status_0 = cam_io_r_mb(bus_wr_reg->base + bus_wr_reg->irq_status_0);
|
||||
irq_status_1 = cam_io_r_mb(bus_wr_reg->base + bus_wr_reg->irq_status_1);
|
||||
|
||||
CAM_DBG(CAM_CRE, "BUS irq_status_0 0x%x irq_status_1 0x%x",
|
||||
irq_status_0, irq_status_1);
|
||||
|
||||
cam_io_w_mb(irq_status_0,
|
||||
bus_wr_reg->base + bus_wr_reg->irq_clear_0);
|
||||
cam_io_w_mb(irq_status_1,
|
||||
@@ -439,7 +446,8 @@ static int cam_cre_bus_wr_isr(struct cam_cre_hw *cam_cre_hw_info,
|
||||
}
|
||||
|
||||
if ((irq_status_0 & bus_wr_reg_val->violation) ||
|
||||
(irq_status_0 & bus_wr_reg_val->img_size_violation)) {
|
||||
(irq_status_0 & bus_wr_reg_val->img_size_violation) ||
|
||||
(irq_status_0 & bus_wr_reg_val->cons_violation)) {
|
||||
irq_data->error = 1;
|
||||
img_violation_status = cam_io_r_mb(bus_wr_reg->base +
|
||||
bus_wr_reg->image_size_violation_status);
|
||||
@@ -456,8 +464,14 @@ static int cam_cre_bus_wr_isr(struct cam_cre_hw *cam_cre_hw_info,
|
||||
debug_status_0, debug_status_1);
|
||||
}
|
||||
|
||||
if (irq_status_1 & bus_wr_reg_val->client_buf_done)
|
||||
CAM_INFO(CAM_CRE, "Cleint 0 Buff done");
|
||||
if (irq_status_0 & bus_wr_reg_val->comp_buf_done) {
|
||||
for (i = 0; i < bus_wr_reg_val->num_clients; i++) {
|
||||
if (irq_status_1 & bus_wr_reg_val->
|
||||
wr_clients[i].client_buf_done)
|
||||
CAM_INFO(CAM_CRE, "Cleint %d Buff done", i);
|
||||
irq_data->wr_buf_done = 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -15,43 +15,6 @@
|
||||
#include "cam_soc_util.h"
|
||||
#include "cam_cre_hw_mgr.h"
|
||||
|
||||
/**
|
||||
* struct cre_bus_wr_io_port_info
|
||||
*
|
||||
* @num_frames_cmds: Number of frame commands
|
||||
* @go_cmd_addr: GO command address
|
||||
* @go_cmd_len: GO command length
|
||||
*/
|
||||
struct cre_bus_wr_io_port_info {
|
||||
uint32_t num_frames_cmds;
|
||||
uint32_t *go_cmd_addr;
|
||||
uint32_t go_cmd_len;
|
||||
uint32_t output_port_id[CRE_MAX_OUT_RES];
|
||||
uint32_t output_format_type[CRE_MAX_OUT_RES];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cre_bus_wr_io_port_batch
|
||||
*
|
||||
* num_batch: Number of batches
|
||||
* io_port: CDM IO Port Info
|
||||
*/
|
||||
struct cre_bus_wr_io_port_batch {
|
||||
uint32_t num_batch;
|
||||
struct cre_bus_wr_io_port_info io_port[CRE_MAX_BATCH_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cre_bus_wr_wm
|
||||
*
|
||||
* @wm_port_id: WM port ID
|
||||
* @format_type: Format type
|
||||
*/
|
||||
struct cre_bus_wr_wm {
|
||||
uint32_t wm_port_id;
|
||||
uint32_t format_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cre_bus_out_port_to_wm
|
||||
*
|
||||
@@ -72,14 +35,11 @@ struct cre_bus_out_port_to_wm {
|
||||
* @cre_acquire: CRE acquire structure
|
||||
* @security_flag: security flag
|
||||
* @num_out_ports: Number of out ports
|
||||
* @io_port_info: IO port info
|
||||
*/
|
||||
struct cre_bus_wr_ctx {
|
||||
struct cam_cre_acquire_dev_info *cre_acquire;
|
||||
bool security_flag;
|
||||
uint32_t num_out_ports;
|
||||
struct cre_bus_wr_io_port_info io_port_info;
|
||||
struct cre_bus_wr_io_port_batch io_port_batch;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -94,5 +54,4 @@ struct cre_bus_wr {
|
||||
struct cre_bus_out_port_to_wm out_port_to_wm[CRE_MAX_OUT_RES];
|
||||
struct cre_bus_wr_ctx *bus_wr_ctx[CRE_CTX_MAX];
|
||||
};
|
||||
|
||||
#endif /* CRE_BUS_WR_H */
|
||||
|
@@ -4,9 +4,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/timer.h>
|
||||
@@ -29,9 +26,6 @@
|
||||
|
||||
#define CAM_CRE_RESET_TIMEOUT msecs_to_jiffies(500)
|
||||
|
||||
#define CAM_CRE_FE_IRQ 0x4
|
||||
#define CAM_CRE_WE_IRQ 0x2
|
||||
|
||||
struct cam_cre_irq_data irq_data;
|
||||
|
||||
static int cam_cre_caps_vote(struct cam_cre_device_core_info *core_info,
|
||||
@@ -558,6 +552,7 @@ irqreturn_t cam_cre_irq(int irq_num, void *data)
|
||||
cre_hw = core_info->cre_hw_info->cre_hw;
|
||||
|
||||
irq_data.error = 0;
|
||||
irq_data.wr_buf_done = 0;
|
||||
|
||||
cam_cre_top_process(cre_hw, 0, CRE_HW_ISR, &irq_data);
|
||||
|
||||
@@ -567,10 +562,10 @@ irqreturn_t cam_cre_irq(int irq_num, void *data)
|
||||
cam_cre_bus_rd_process(cre_hw, 0, CRE_HW_ISR, &irq_data);
|
||||
|
||||
spin_lock(&cre_dev->hw_lock);
|
||||
CAM_DBG(CAM_CRE, "core_info->irq_cb.cre_hw_mgr_cb %x core_info->irq_cb.data %x",
|
||||
core_info->irq_cb.cre_hw_mgr_cb, core_info->irq_cb.data);
|
||||
if (core_info->irq_cb.cre_hw_mgr_cb && core_info->irq_cb.data)
|
||||
if (irq_data.error ||
|
||||
((irq_data.top_irq_status & CAM_CRE_WE_IRQ) &&
|
||||
irq_data.wr_buf_done))
|
||||
if (irq_data.error || irq_data.wr_buf_done)
|
||||
core_info->irq_cb.cre_hw_mgr_cb(&irq_data,
|
||||
sizeof(struct cam_hw_info),
|
||||
core_info->irq_cb.data);
|
||||
|
@@ -16,6 +16,11 @@
|
||||
#include "cre_hw.h"
|
||||
#include "cam_cre_hw_intf.h"
|
||||
|
||||
#define CAM_CRE_IDLE_IRQ 0x8
|
||||
#define CAM_CRE_FE_IRQ 0x4
|
||||
#define CAM_CRE_WE_IRQ 0x2
|
||||
#define CAM_CRE_RESET_IRQ 0x1
|
||||
|
||||
/**
|
||||
* struct cam_cre_cpas_vote
|
||||
* @ahb_vote: AHB vote info
|
||||
|
@@ -3,8 +3,6 @@
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
|
@@ -14,11 +14,10 @@
|
||||
#define MAX_CRE_RD_CLIENTS 1
|
||||
#define MAX_CRE_WR_CLIENTS 1
|
||||
|
||||
#define CRE_TOP_BASE 0x1
|
||||
#define CRE_QOS_BASE 0x2
|
||||
#define CRE_BUS_RD 0x3
|
||||
#define CRE_BUS_WR 0x4
|
||||
#define CRE_BASE_MAX 0x5
|
||||
#define CRE_TOP_BASE 0x0
|
||||
#define CRE_BUS_RD 0x1
|
||||
#define CRE_BUS_WR 0x2
|
||||
#define CRE_BASE_MAX 0x3
|
||||
|
||||
#define CRE_WAIT_BUS_WR_RUP 0x1
|
||||
#define CRE_WAIT_BUS_WR_DONE 0x2
|
||||
@@ -133,9 +132,9 @@ struct cam_cre_bus_rd_client_reg_val {
|
||||
uint32_t alignment;
|
||||
uint32_t alignment_mask;
|
||||
uint32_t alignment_shift;
|
||||
uint32_t mode;
|
||||
uint32_t mode_mask;
|
||||
uint32_t mode_shift;
|
||||
uint32_t format;
|
||||
uint32_t format_mask;
|
||||
uint32_t format_shift;
|
||||
uint32_t latency_buf_size;
|
||||
uint32_t latency_buf_size_mask;
|
||||
uint32_t misr_cfg_en;
|
||||
@@ -258,6 +257,7 @@ struct cam_cre_bus_wr_client_reg_val {
|
||||
uint32_t x_init_mask;
|
||||
uint32_t stride;
|
||||
uint32_t stride_mask;
|
||||
uint32_t client_buf_done;
|
||||
uint32_t format;
|
||||
uint32_t format_mask;
|
||||
uint32_t format_shift;
|
||||
@@ -291,7 +291,6 @@ struct cam_cre_bus_wr_reg_val {
|
||||
uint32_t irq_status_1;
|
||||
uint32_t irq_cmd_set;
|
||||
uint32_t irq_cmd_clear;
|
||||
uint32_t client_buf_done;
|
||||
uint32_t frame_header_cfg_0;
|
||||
uint32_t local_frame_header_cfg_0;
|
||||
uint32_t iso_en;
|
||||
|
@@ -12,22 +12,22 @@
|
||||
#define CRE_BUS_WR_TYPE 0x2
|
||||
|
||||
static struct cam_cre_top_reg top_reg = {
|
||||
.hw_version = 0xFA000,
|
||||
.hw_cap = 0xFA004,
|
||||
.debug_0 = 0xFA080,
|
||||
.debug_1 = 0xFA084,
|
||||
.debug_cfg = 0xFA0DC,
|
||||
.testbus_ctrl = 0xFA1F4,
|
||||
.scratch_0 = 0xFA1F8,
|
||||
.irq_status = 0xFA00C,
|
||||
.irq_mask = 0xFA010,
|
||||
.irq_clear = 0xFA014,
|
||||
.irq_set = 0xFA018,
|
||||
.irq_cmd = 0xFA01C,
|
||||
.reset_cmd = 0xFA008,
|
||||
.core_clk_cfg_ctrl_0 = 0xFA020,
|
||||
.core_clk_cfg_ctrl_1 = 0xFA024,
|
||||
.top_spare = 0xFA1FC,
|
||||
.hw_version = 0x000,
|
||||
.hw_cap = 0x004,
|
||||
.debug_0 = 0x080,
|
||||
.debug_1 = 0x084,
|
||||
.debug_cfg = 0x0DC,
|
||||
.testbus_ctrl = 0x1F4,
|
||||
.scratch_0 = 0x1F8,
|
||||
.irq_status = 0x00C,
|
||||
.irq_mask = 0x010,
|
||||
.irq_clear = 0x014,
|
||||
.irq_set = 0x018,
|
||||
.irq_cmd = 0x01C,
|
||||
.reset_cmd = 0x008,
|
||||
.core_clk_cfg_ctrl_0 = 0x020,
|
||||
.core_clk_cfg_ctrl_1 = 0x024,
|
||||
.top_spare = 0x1FC,
|
||||
};
|
||||
|
||||
struct cam_cre_top_reg_val top_reg_value = {
|
||||
@@ -47,38 +47,38 @@ struct cam_cre_top_reg_val top_reg_value = {
|
||||
};
|
||||
|
||||
struct cam_cre_bus_rd_reg bus_rd_reg = {
|
||||
.hw_version = 0xFA400,
|
||||
.irq_mask = 0xFA404,
|
||||
.irq_clear = 0xFA408,
|
||||
.irq_cmd = 0xFA40C,
|
||||
.irq_status = 0xFA410,
|
||||
.input_if_cmd = 0xFA414,
|
||||
.irq_set = 0xFA418,
|
||||
.misr_reset = 0xFA41C,
|
||||
.security_cfg = 0xFA420,
|
||||
.iso_cfg = 0xFA424,
|
||||
.iso_seed = 0xFA428,
|
||||
.test_bus_ctrl = 0xFA42C,
|
||||
.hw_version = 0x00,
|
||||
.irq_mask = 0x04,
|
||||
.irq_clear = 0x08,
|
||||
.irq_cmd = 0x0C,
|
||||
.irq_status = 0x10,
|
||||
.input_if_cmd = 0x14,
|
||||
.irq_set = 0x18,
|
||||
.misr_reset = 0x1C,
|
||||
.security_cfg = 0x20,
|
||||
.iso_cfg = 0x24,
|
||||
.iso_seed = 0x28,
|
||||
.test_bus_ctrl = 0x2C,
|
||||
.num_clients = 1,
|
||||
.rd_clients[0] = {
|
||||
.core_cfg = 0xFA450,
|
||||
.ccif_meta_data = 0xFA454,
|
||||
.img_addr = 0xFA458,
|
||||
.rd_width = 0xFA45C,
|
||||
.rd_height = 0xFA460,
|
||||
.rd_stride = 0xFA464,
|
||||
.unpacker_cfg = 0xFA468,
|
||||
.latency_buf_allocation = 0xFA47C,
|
||||
.misr_cfg_0 = 0xFA484,
|
||||
.misr_cfg_1 = 0xFA488,
|
||||
.misr_rd_val = 0xFA48C,
|
||||
.debug_status_cfg = 0xFA490,
|
||||
.debug_status_0 = 0xFA494,
|
||||
.debug_status_1 = 0xFA498,
|
||||
.read_buff_cfg = 0xFA4A0,
|
||||
.addr_cfg = 0xFA4A4,
|
||||
.spare = 0xFA430,
|
||||
.cons_violation = 0xFA434,
|
||||
.core_cfg = 0x50,
|
||||
.ccif_meta_data = 0x54,
|
||||
.img_addr = 0x58,
|
||||
.rd_width = 0x5C,
|
||||
.rd_height = 0x60,
|
||||
.rd_stride = 0x64,
|
||||
.unpacker_cfg = 0x68,
|
||||
.latency_buf_allocation = 0x7C,
|
||||
.misr_cfg_0 = 0x84,
|
||||
.misr_cfg_1 = 0x88,
|
||||
.misr_rd_val = 0x8C,
|
||||
.debug_status_cfg = 0x90,
|
||||
.debug_status_0 = 0x94,
|
||||
.debug_status_1 = 0x98,
|
||||
.read_buff_cfg = 0xA0,
|
||||
.addr_cfg = 0xA4,
|
||||
.spare = 0x30,
|
||||
.cons_violation = 0x34,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -99,7 +99,6 @@ struct cam_cre_bus_wr_reg_val bus_wr_reg_value = {
|
||||
.irq_status_1 = 0x1,
|
||||
.irq_cmd_set = 0x10,
|
||||
.irq_cmd_clear = 0x1,
|
||||
.client_buf_done = 0x1,
|
||||
.iso_en = 0x1,
|
||||
.iso_en_mask = 0x1,
|
||||
.misr_0_en = 0x1,
|
||||
@@ -132,14 +131,15 @@ struct cam_cre_bus_wr_reg_val bus_wr_reg_value = {
|
||||
.bw_limit_en = 0x1,
|
||||
.bw_limit_en_mask = 0x1,
|
||||
.bw_limit_counter_mask = 0x1fe,
|
||||
.client_buf_done = 0x1,
|
||||
.output_port_id = CAM_CRE_OUTPUT_IMAGE,
|
||||
.wm_port_id = 1,
|
||||
.wm_port_id = 0,
|
||||
},
|
||||
};
|
||||
|
||||
struct cam_cre_bus_rd_reg_val bus_rd_reg_value = {
|
||||
.hw_version = 0x30000000,
|
||||
.irq_mask = 0x7,
|
||||
.irq_mask = 0x1, /* INFO_CONS_VIOLATION */
|
||||
.rd_buf_done = 0x4,
|
||||
.rup_done = 0x2,
|
||||
.cons_violation = 0x1,
|
||||
@@ -171,8 +171,8 @@ struct cam_cre_bus_rd_reg_val bus_rd_reg_value = {
|
||||
.stripe_location_shift = 0x0,
|
||||
.alignment_mask = 0x1,
|
||||
.alignment_shift = 0x5,
|
||||
.mode_mask = 0x1f,
|
||||
.mode_shift = 0x0,
|
||||
.format_mask = 0x1f,
|
||||
.format_shift = 0x0,
|
||||
.latency_buf_size_mask = 0xffff,
|
||||
.misr_cfg_en_mask = 0x4,
|
||||
.misr_cfg_samp_mode_mask = 0x3,
|
||||
@@ -184,48 +184,48 @@ struct cam_cre_bus_rd_reg_val bus_rd_reg_value = {
|
||||
};
|
||||
|
||||
struct cam_cre_bus_wr_reg bus_wr_reg = {
|
||||
.hw_version = 0xFA700,
|
||||
.cgc_override = 0xFA708,
|
||||
.irq_mask_0 = 0xFA718,
|
||||
.irq_mask_1 = 0xFA71C,
|
||||
.irq_clear_0 = 0xFA720,
|
||||
.irq_clear_1 = 0xFA724,
|
||||
.irq_status_0 = 0xFA728,
|
||||
.irq_status_1 = 0xFA72C,
|
||||
.irq_cmd = 0xFA730,
|
||||
.hw_version = 0x00,
|
||||
.cgc_override = 0x08,
|
||||
.irq_mask_0 = 0x18,
|
||||
.irq_mask_1 = 0x1C,
|
||||
.irq_clear_0 = 0x20,
|
||||
.irq_clear_1 = 0x24,
|
||||
.irq_status_0 = 0x28,
|
||||
.irq_status_1 = 0x2C,
|
||||
.irq_cmd = 0x30,
|
||||
.frame_header_cfg_0 = 0x0,
|
||||
.local_frame_header_cfg_0 = 0xFA74C,
|
||||
.irq_set_0 = 0xFA750,
|
||||
.irq_set_1 = 0xFA754,
|
||||
.iso_cfg = 0xFA75C,
|
||||
.violation_status = 0xFA764,
|
||||
.image_size_violation_status = 0xFA770,
|
||||
.perf_count_cfg_0 = 0xFA774,
|
||||
.perf_count_cfg_1 = 0xFA778,
|
||||
.perf_count_cfg_2 = 0xFA77C,
|
||||
.perf_count_cfg_3 = 0xFA780,
|
||||
.perf_count_val_0 = 0xFA794,
|
||||
.perf_count_val_1 = 0xFA798,
|
||||
.perf_count_val_2 = 0xFA79C,
|
||||
.perf_count_val_3 = 0xFA7A0,
|
||||
.perf_count_status = 0xFA7B4,
|
||||
.misr_cfg_0 = 0xFA7B8,
|
||||
.misr_cfg_1 = 0xFA7BC,
|
||||
.misr_rd_sel = 0xFA7C8,
|
||||
.misr_reset = 0xFA7CC,
|
||||
.misr_val = 0xFA7D0,
|
||||
.local_frame_header_cfg_0 = 0x4C,
|
||||
.irq_set_0 = 0x50,
|
||||
.irq_set_1 = 0x54,
|
||||
.iso_cfg = 0x5C,
|
||||
.violation_status = 0x64,
|
||||
.image_size_violation_status = 0x70,
|
||||
.perf_count_cfg_0 = 0x74,
|
||||
.perf_count_cfg_1 = 0x78,
|
||||
.perf_count_cfg_2 = 0x7C,
|
||||
.perf_count_cfg_3 = 0x80,
|
||||
.perf_count_val_0 = 0x94,
|
||||
.perf_count_val_1 = 0x98,
|
||||
.perf_count_val_2 = 0x9C,
|
||||
.perf_count_val_3 = 0xA0,
|
||||
.perf_count_status = 0xB4,
|
||||
.misr_cfg_0 = 0xB8,
|
||||
.misr_cfg_1 = 0xBC,
|
||||
.misr_rd_sel = 0xC8,
|
||||
.misr_reset = 0xCC,
|
||||
.misr_val = 0xD0,
|
||||
.wr_clients[0] = {
|
||||
.client_cfg = 0xFA900,
|
||||
.img_addr = 0xFA904,
|
||||
.img_cfg_0 = 0xFA90C,
|
||||
.img_cfg_1 = 0xFA910,
|
||||
.img_cfg_2 = 0xFA914,
|
||||
.bw_limit = 0xFA918,
|
||||
.packer_cfg = 0xFA91C,
|
||||
.addr_cfg = 0xFA970,
|
||||
.debug_status_cfg = 0xFA984,
|
||||
.debug_status_0 = 0xFA988,
|
||||
.debug_status_1 = 0xFA98C,
|
||||
.client_cfg = 0x200,
|
||||
.img_addr = 0x204,
|
||||
.img_cfg_0 = 0x20C,
|
||||
.img_cfg_1 = 0x210,
|
||||
.img_cfg_2 = 0x214,
|
||||
.packer_cfg = 0x218,
|
||||
.bw_limit = 0x21C,
|
||||
.addr_cfg = 0x270,
|
||||
.debug_status_cfg = 0x284,
|
||||
.debug_status_0 = 0x288,
|
||||
.debug_status_1 = 0x28C,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -13,6 +13,6 @@
|
||||
#define CAM_CRE_CTX_MAX 16
|
||||
|
||||
int cam_cre_hw_mgr_init(struct device_node *of_node,
|
||||
uint64_t *hw_mgr_hdl, int *iommu_hdl);
|
||||
void *hw_mgr, int *iommu_hdl);
|
||||
|
||||
#endif /* CAM_CRE_HW_MGR_INTF_H */
|
||||
|
@@ -2,16 +2,9 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/completion.h>
|
||||
#include <media/cam_cre.h>
|
||||
#include "cam_io_util.h"
|
||||
@@ -21,7 +14,6 @@
|
||||
#include "cre_soc.h"
|
||||
#include "cam_soc_util.h"
|
||||
#include "cam_io_util.h"
|
||||
#include "cam_cpas_api.h"
|
||||
#include "cam_debug_util.h"
|
||||
#include "cre_hw.h"
|
||||
#include "cre_dev_intf.h"
|
||||
@@ -155,6 +147,7 @@ static int cam_cre_top_init(struct cam_cre_hw *cre_hw_info,
|
||||
/* CRE SW RESET */
|
||||
init_completion(&cre_top_info.reset_complete);
|
||||
init_completion(&cre_top_info.idle_done);
|
||||
init_completion(&cre_top_info.bufdone);
|
||||
|
||||
/* enable interrupt mask */
|
||||
cam_io_w_mb(top_reg_val->irq_mask,
|
||||
|
@@ -40,6 +40,7 @@ struct cre_top {
|
||||
struct cre_top_ctx top_ctx[CAM_CRE_CTX_MAX];
|
||||
struct completion reset_complete;
|
||||
struct completion idle_done;
|
||||
struct completion bufdone;
|
||||
struct mutex cre_hw_mutex;
|
||||
spinlock_t hw_lock;
|
||||
};
|
||||
|
Посилання в новій задачі
Заблокувати користувача