1
0

UPSTREAM: 11/22/19: Merge 'quic/camera-kernel.lnx.1.0' into 'quic/camera-kernel.lnx.4.0'

* quic/camera-kernel.lnx.1.0::
  msm: camera: sensor: Support for read operation
  msm: camera: req_mgr: Fix kmem_cache definition
  msm: camera: custom: Add support for acquire_hw_v1
  msm: camera: core: Prevent crash on kref_put
  msm: camera: isp: csid hw register reset with IRQ
  msm: camera: isp: Reset overflow pending flag in start hw
  msm: camera: icp: Increase MAX_PKT_SIZE_MSGQ for ICP
  msm: camera: icp: icp debug improvement
  msm: camera: reqmgr: Improve master slave sync
  msm: camera: isp: Notify CRM to pause SOF timer after flush
  msm: camera: csiphy: Fix csiphy v1.2 skew calibration settings
  msm: camera: csiphy: Update reset sequence for csiphy v1.2
  msm: camera: csiphy: Update registers for CSIPHY v1.2
  msm: camera: reqmgr: Change v4l2 notify error log type
  msm: camera: isp: Set device enable flag after enable csid hardware

Change-Id: I52c682b36583436425d157c8927e6fbcf5bf32eb
Signed-off-by: Abhijit Trivedi <abhijitt@codeaurora.org>
Este cometimento está contido em:
Abhijit Trivedi
2019-11-22 17:35:35 -08:00
ascendente 9b6110b579 50e83233ad
cometimento a15be98002
26 ficheiros modificados com 1154 adições e 345 eliminações

Ver ficheiro

@@ -597,7 +597,12 @@ int cam_context_deinit(struct cam_context *ctx)
void cam_context_putref(struct cam_context *ctx)
{
kref_put(&ctx->refcount, cam_node_put_ctxt_to_free_list);
if (kref_read(&ctx->refcount))
kref_put(&ctx->refcount, cam_node_put_ctxt_to_free_list);
else
WARN(1, "ctx %s %d state %d devhdl %X\n", ctx->dev_name,
ctx->ctx_id, ctx->state, ctx->dev_hdl);
CAM_DBG(CAM_CORE,
"ctx device hdl %ld, ref count %d, dev_name %s",
ctx->dev_hdl, refcount_read(&(ctx->refcount.refcount)),

Ver ficheiro

@@ -19,7 +19,7 @@
#include "cam_custom_context.h"
#include "cam_common_util.h"
static const char custom_dev_name[] = "custom hw";
static const char custom_dev_name[] = "cam-custom";
static int __cam_custom_ctx_handle_irq_in_activated(
void *context, uint32_t evt_id, void *evt_data);
@@ -275,6 +275,67 @@ static int __cam_custom_stop_dev_in_activated(struct cam_context *ctx,
return 0;
}
static int __cam_custom_ctx_release_hw_in_top_state(
struct cam_context *ctx, void *cmd)
{
int rc = 0;
struct cam_hw_release_args rel_arg;
struct cam_req_mgr_flush_request flush_req;
struct cam_custom_context *custom_ctx =
(struct cam_custom_context *) ctx->ctx_priv;
if (custom_ctx->hw_ctx) {
rel_arg.ctxt_to_hw_map = custom_ctx->hw_ctx;
rc = ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv,
&rel_arg);
custom_ctx->hw_ctx = NULL;
if (rc)
CAM_ERR(CAM_CUSTOM,
"Failed to release HW for ctx:%u", ctx->ctx_id);
} else {
CAM_ERR(CAM_CUSTOM, "No HW resources acquired for this ctx");
}
ctx->last_flush_req = 0;
custom_ctx->frame_id = 0;
custom_ctx->active_req_cnt = 0;
custom_ctx->hw_acquired = false;
custom_ctx->init_received = false;
/* check for active requests as well */
flush_req.type = CAM_REQ_MGR_FLUSH_TYPE_ALL;
flush_req.link_hdl = ctx->link_hdl;
flush_req.dev_hdl = ctx->dev_hdl;
CAM_DBG(CAM_CUSTOM, "try to flush pending list");
spin_lock_bh(&ctx->lock);
rc = __cam_custom_ctx_flush_req(ctx, &ctx->pending_req_list,
&flush_req);
spin_unlock_bh(&ctx->lock);
ctx->state = CAM_CTX_ACQUIRED;
CAM_DBG(CAM_CUSTOM, "Release HW success[%u] next state %d",
ctx->ctx_id, ctx->state);
return rc;
}
static int __cam_custom_ctx_release_hw_in_activated_state(
struct cam_context *ctx, void *cmd)
{
int rc = 0;
rc = __cam_custom_stop_dev_in_activated(ctx, NULL);
if (rc)
CAM_ERR(CAM_CUSTOM, "Stop device failed rc=%d", rc);
rc = __cam_custom_ctx_release_hw_in_top_state(ctx, cmd);
if (rc)
CAM_ERR(CAM_CUSTOM, "Release hw failed rc=%d", rc);
return rc;
}
static int __cam_custom_release_dev_in_acquired(struct cam_context *ctx,
struct cam_release_dev_cmd *cmd)
{
@@ -283,14 +344,16 @@ static int __cam_custom_release_dev_in_acquired(struct cam_context *ctx,
(struct cam_custom_context *) ctx->ctx_priv;
struct cam_req_mgr_flush_request flush_req;
rc = cam_context_release_dev_to_hw(ctx, cmd);
if (rc)
CAM_ERR(CAM_CUSTOM, "Unable to release device");
if (cmd && ctx_custom->hw_ctx) {
CAM_ERR(CAM_CUSTOM, "releasing hw");
__cam_custom_ctx_release_hw_in_top_state(ctx, NULL);
}
ctx->ctx_crm_intf = NULL;
ctx->last_flush_req = 0;
ctx_custom->frame_id = 0;
ctx_custom->active_req_cnt = 0;
ctx_custom->hw_acquired = false;
ctx_custom->init_received = false;
if (!list_empty(&ctx->active_req_list))
@@ -381,33 +444,128 @@ end:
return rc;
}
static int __cam_custom_ctx_acquire_dev_in_available(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd)
static int __cam_custom_ctx_acquire_hw_v1(
struct cam_context *ctx, void *args)
{
int rc;
struct cam_custom_context *custom_ctx;
int rc = 0;
struct cam_acquire_hw_cmd_v1 *cmd =
(struct cam_acquire_hw_cmd_v1 *)args;
struct cam_hw_acquire_args param;
struct cam_custom_context *ctx_custom =
(struct cam_custom_context *) ctx->ctx_priv;
struct cam_custom_acquire_hw_info *acquire_hw_info = NULL;
custom_ctx = (struct cam_custom_context *) ctx->ctx_priv;
if (cmd->num_resources > CAM_CUSTOM_DEV_CTX_RES_MAX) {
CAM_ERR(CAM_CUSTOM, "Too much resources in the acquire");
rc = -ENOMEM;
return rc;
if (!ctx->hw_mgr_intf) {
CAM_ERR(CAM_CUSTOM, "HW interface is not ready");
rc = -EFAULT;
goto end;
}
if (cmd->handle_type != 1) {
CAM_DBG(CAM_CUSTOM,
"session_hdl 0x%x, hdl type %d, res %lld",
cmd->session_handle, cmd->handle_type, cmd->resource_hdl);
if (cmd->handle_type != 1) {
CAM_ERR(CAM_CUSTOM, "Only user pointer is supported");
rc = -EINVAL;
goto end;
}
if (cmd->data_size < sizeof(*acquire_hw_info)) {
CAM_ERR(CAM_CUSTOM, "data_size is not a valid value");
goto end;
}
acquire_hw_info = kzalloc(cmd->data_size, GFP_KERNEL);
if (!acquire_hw_info) {
rc = -ENOMEM;
goto end;
}
CAM_DBG(CAM_CUSTOM, "start copy resources from user");
if (copy_from_user(acquire_hw_info, (void __user *)cmd->resource_hdl,
cmd->data_size)) {
rc = -EFAULT;
goto free_res;
}
memset(&param, 0, sizeof(param));
param.context_data = ctx;
param.event_cb = ctx->irq_cb_intf;
param.acquire_info_size = cmd->data_size;
param.acquire_info = (uint64_t) acquire_hw_info;
/* call HW manager to reserve the resource */
rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv,
&param);
if (rc != 0) {
CAM_ERR(CAM_CUSTOM, "Acquire HW failed");
goto free_res;
}
ctx_custom->hw_ctx = param.ctxt_to_hw_map;
ctx_custom->hw_acquired = true;
ctx->ctxt_to_hw_map = param.ctxt_to_hw_map;
CAM_DBG(CAM_CUSTOM,
"Acquire HW success on session_hdl 0x%xs for ctx_id %u",
ctx->session_hdl, ctx->ctx_id);
kfree(acquire_hw_info);
return rc;
free_res:
kfree(acquire_hw_info);
end:
return rc;
}
static int __cam_custom_ctx_acquire_dev_in_available(
struct cam_context *ctx, struct cam_acquire_dev_cmd *cmd)
{
int rc = 0;
struct cam_create_dev_hdl req_hdl_param;
if (!ctx->hw_mgr_intf) {
CAM_ERR(CAM_CUSTOM, "HW interface is not ready");
rc = -EFAULT;
return rc;
}
rc = cam_context_acquire_dev_to_hw(ctx, cmd);
if (!rc) {
ctx->state = CAM_CTX_ACQUIRED;
custom_ctx->hw_ctx = ctx->ctxt_to_hw_map;
CAM_DBG(CAM_CUSTOM,
"session_hdl 0x%x, num_resources %d, hdl type %d, res %lld",
cmd->session_handle, cmd->num_resources,
cmd->handle_type, cmd->resource_hdl);
if (cmd->num_resources != CAM_API_COMPAT_CONSTANT) {
CAM_ERR(CAM_CUSTOM, "Invalid num_resources 0x%x",
cmd->num_resources);
return -EINVAL;
}
CAM_DBG(CAM_CUSTOM, "Acquire done %d", ctx->ctx_id);
req_hdl_param.session_hdl = cmd->session_handle;
req_hdl_param.v4l2_sub_dev_flag = 0;
req_hdl_param.media_entity_flag = 0;
req_hdl_param.ops = ctx->crm_ctx_intf;
req_hdl_param.priv = ctx;
CAM_DBG(CAM_CUSTOM, "get device handle from bridge");
ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
if (ctx->dev_hdl <= 0) {
rc = -EFAULT;
CAM_ERR(CAM_CUSTOM, "Can not create device handle");
return rc;
}
cmd->dev_handle = ctx->dev_hdl;
ctx->session_hdl = cmd->session_handle;
ctx->state = CAM_CTX_ACQUIRED;
CAM_DBG(CAM_CUSTOM,
"Acquire dev success on session_hdl 0x%x for ctx %u",
cmd->session_handle, ctx->ctx_id);
return rc;
}
@@ -642,6 +800,13 @@ static int __cam_custom_ctx_config_dev_in_acquired(struct cam_context *ctx,
struct cam_config_dev_cmd *cmd)
{
int rc = 0;
struct cam_custom_context *ctx_custom =
(struct cam_custom_context *) ctx->ctx_priv;
if (!ctx_custom->hw_acquired) {
CAM_ERR(CAM_CUSTOM, "HW not acquired, reject config packet");
return -EAGAIN;
}
rc = __cam_custom_ctx_config_dev(ctx, cmd);
@@ -826,6 +991,27 @@ static int __cam_custom_ctx_handle_irq_in_activated(void *context,
return rc;
}
static int __cam_custom_ctx_acquire_hw_in_acquired(
struct cam_context *ctx, void *args)
{
int rc = -EINVAL;
uint32_t api_version;
if (!ctx || !args) {
CAM_ERR(CAM_CUSTOM, "Invalid input pointer");
return rc;
}
api_version = *((uint32_t *)args);
if (api_version == 1)
rc = __cam_custom_ctx_acquire_hw_v1(ctx, args);
else
CAM_ERR(CAM_CUSTOM, "Unsupported api version %d",
api_version);
return rc;
}
/* top state machine */
static struct cam_ctx_ops
cam_custom_dev_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
@@ -847,8 +1033,10 @@ static struct cam_ctx_ops
/* Acquired */
{
.ioctl_ops = {
.acquire_hw = __cam_custom_ctx_acquire_hw_in_acquired,
.release_dev = __cam_custom_release_dev_in_acquired,
.config_dev = __cam_custom_ctx_config_dev_in_acquired,
.release_hw = __cam_custom_ctx_release_hw_in_top_state,
},
.crm_ops = {
.link = __cam_custom_ctx_link_in_acquired,
@@ -866,6 +1054,7 @@ static struct cam_ctx_ops
.start_dev = __cam_custom_ctx_start_dev_in_ready,
.release_dev = __cam_custom_release_dev_in_acquired,
.config_dev = __cam_custom_ctx_config_dev,
.release_hw = __cam_custom_ctx_release_hw_in_top_state,
},
.crm_ops = {
.unlink = __cam_custom_ctx_unlink_in_ready,
@@ -883,6 +1072,8 @@ static struct cam_ctx_ops
.release_dev =
__cam_custom_ctx_release_dev_in_activated,
.config_dev = __cam_custom_ctx_config_dev,
.release_hw =
__cam_custom_ctx_release_hw_in_activated_state,
},
.crm_ops = {
.unlink = __cam_custom_ctx_unlink_in_activated,

Ver ficheiro

@@ -68,6 +68,7 @@ struct cam_custom_dev_ctx_req {
* custom HW will invoke CRM cb at those event.
* @active_req_cnt: Counter for the active request
* @frame_id: Frame id tracking for the custom context
* @hw_acquired: Flag to indicate if HW is acquired for this context
* @req_base: common request structure
* @req_custom: custom request structure
*
@@ -81,6 +82,7 @@ struct cam_custom_context {
uint32_t subscribe_event;
uint32_t active_req_cnt;
int64_t frame_id;
bool hw_acquired;
struct cam_ctx_request req_base[CAM_CTX_REQ_MAX];
struct cam_custom_dev_ctx_req req_custom[CAM_CTX_REQ_MAX];
};

Ver ficheiro

@@ -382,7 +382,7 @@ static int cam_custom_mgr_start_hw(void *hw_mgr_priv,
&ctx->res_list_custom_cid, list) {
rc = cam_custom_hw_mgr_init_hw_res(hw_mgr_res);
if (rc) {
CAM_ERR(CAM_ISP, "Can not INIT CID(id :%d)",
CAM_ERR(CAM_CUSTOM, "Can not INIT CID(id :%d)",
hw_mgr_res->res_id);
goto deinit_hw;
}
@@ -393,7 +393,7 @@ static int cam_custom_mgr_start_hw(void *hw_mgr_priv,
&ctx->res_list_custom_csid, list) {
rc = cam_custom_hw_mgr_init_hw_res(hw_mgr_res);
if (rc) {
CAM_ERR(CAM_ISP, "Can not INIT CSID(id :%d)",
CAM_ERR(CAM_CUSTOM, "Can not INIT CSID(id :%d)",
hw_mgr_res->res_id);
goto deinit_hw;
}
@@ -413,7 +413,7 @@ static int cam_custom_mgr_start_hw(void *hw_mgr_priv,
&ctx->res_list_custom_csid, list) {
rc = cam_custom_hw_mgr_start_hw_res(hw_mgr_res);
if (rc) {
CAM_ERR(CAM_ISP, "Can not START CSID(id :%d)",
CAM_ERR(CAM_CUSTOM, "Can not START CSID(id :%d)",
hw_mgr_res->res_id);
goto err;
}
@@ -424,7 +424,7 @@ static int cam_custom_mgr_start_hw(void *hw_mgr_priv,
&ctx->res_list_custom_cid, list) {
rc = cam_custom_hw_mgr_start_hw_res(hw_mgr_res);
if (rc) {
CAM_ERR(CAM_ISP, "Can not START CID(id :%d)",
CAM_ERR(CAM_CUSTOM, "Can not START CID(id :%d)",
hw_mgr_res->res_id);
goto err;
}
@@ -762,7 +762,7 @@ static int cam_custom_hw_mgr_release_hw_for_ctx(
&custom_ctx->res_list_custom_cid, list) {
rc = cam_custom_hw_mgr_free_hw_res(hw_mgr_res);
if (rc)
CAM_ERR(CAM_ISP, "Can not release CID(id :%d)",
CAM_ERR(CAM_CUSTOM, "Can not release CID(id :%d)",
hw_mgr_res->res_id);
cam_custom_hw_mgr_put_res(
&custom_ctx->free_res_list, &hw_mgr_res);
@@ -773,7 +773,7 @@ static int cam_custom_hw_mgr_release_hw_for_ctx(
&custom_ctx->res_list_custom_csid, list) {
rc = cam_custom_hw_mgr_free_hw_res(hw_mgr_res);
if (rc)
CAM_ERR(CAM_ISP, "Can not release CSID(id :%d)",
CAM_ERR(CAM_CUSTOM, "Can not release CSID(id :%d)",
hw_mgr_res->res_id);
cam_custom_hw_mgr_put_res(
&custom_ctx->free_res_list, &hw_mgr_res);
@@ -813,41 +813,82 @@ static int cam_custom_mgr_release_hw(void *hw_mgr_priv,
return rc;
}
static void cam_custom_hw_mgr_acquire_get_unified_dev_str(
struct cam_custom_in_port_info *in,
struct cam_isp_in_port_generic_info *gen_port_info)
static int cam_custom_hw_mgr_acquire_get_unified_dev_str(
struct cam_custom_acquire_hw_info *acquire_hw_info,
uint32_t *input_size,
struct cam_isp_in_port_generic_info **gen_port_info)
{
int i;
int32_t rc = 0, i;
uint32_t in_port_length = 0;
struct cam_custom_in_port_info *in = NULL;
struct cam_isp_in_port_generic_info *port_info = NULL;
gen_port_info->res_type = in->res_type +
in = (struct cam_custom_in_port_info *)
((uint8_t *)&acquire_hw_info->data +
acquire_hw_info->input_info_offset + *input_size);
in_port_length = sizeof(struct cam_custom_in_port_info) +
(in->num_out_res - 1) *
sizeof(struct cam_custom_out_port_info);
*input_size += in_port_length;
if ((*input_size) > acquire_hw_info->input_info_size) {
CAM_ERR(CAM_CUSTOM, "Input is not proper");
rc = -EINVAL;
return rc;
}
port_info = kzalloc(
sizeof(struct cam_isp_in_port_generic_info), GFP_KERNEL);
if (!port_info)
return -ENOMEM;
port_info->res_type = in->res_type +
CAM_ISP_IFE_IN_RES_BASE - CAM_CUSTOM_IN_RES_BASE;
gen_port_info->lane_type = in->lane_type;
gen_port_info->lane_num = in->lane_num;
gen_port_info->lane_cfg = in->lane_cfg;
gen_port_info->vc[0] = in->vc[0];
gen_port_info->dt[0] = in->dt[0];
gen_port_info->num_valid_vc_dt = in->num_valid_vc_dt;
gen_port_info->format = in->format;
gen_port_info->test_pattern = in->test_pattern;
gen_port_info->usage_type = in->usage_type;
gen_port_info->left_start = in->left_start;
gen_port_info->left_stop = in->left_stop;
gen_port_info->left_width = in->left_width;
gen_port_info->right_start = in->right_start;
gen_port_info->right_stop = in->right_stop;
gen_port_info->right_width = in->right_width;
gen_port_info->line_start = in->line_start;
gen_port_info->line_stop = in->line_stop;
gen_port_info->height = in->height;
gen_port_info->pixel_clk = in->pixel_clk;
gen_port_info->cust_node = 1;
gen_port_info->num_out_res = in->num_out_res;
gen_port_info->num_bytes_out = in->num_bytes_out;
port_info->lane_type = in->lane_type;
port_info->lane_num = in->lane_num;
port_info->lane_cfg = in->lane_cfg;
port_info->vc[0] = in->vc[0];
port_info->dt[0] = in->dt[0];
port_info->num_valid_vc_dt = in->num_valid_vc_dt;
port_info->format = in->format;
port_info->test_pattern = in->test_pattern;
port_info->usage_type = in->usage_type;
port_info->left_start = in->left_start;
port_info->left_stop = in->left_stop;
port_info->left_width = in->left_width;
port_info->right_start = in->right_start;
port_info->right_stop = in->right_stop;
port_info->right_width = in->right_width;
port_info->line_start = in->line_start;
port_info->line_stop = in->line_stop;
port_info->height = in->height;
port_info->pixel_clk = in->pixel_clk;
port_info->cust_node = 1;
port_info->num_out_res = in->num_out_res;
port_info->num_bytes_out = in->num_bytes_out;
port_info->data = kcalloc(in->num_out_res,
sizeof(struct cam_isp_out_port_generic_info),
GFP_KERNEL);
if (port_info->data == NULL) {
rc = -ENOMEM;
goto release_port_mem;
}
for (i = 0; i < in->num_out_res; i++) {
gen_port_info->data[i].res_type = in->data[i].res_type;
gen_port_info->data[i].format = in->data[i].format;
port_info->data[i].res_type = in->data[i].res_type;
port_info->data[i].format = in->data[i].format;
}
*gen_port_info = port_info;
return 0;
release_port_mem:
kfree(port_info);
return rc;
}
static int cam_custom_mgr_acquire_hw_for_ctx(
@@ -898,18 +939,16 @@ static int cam_custom_mgr_acquire_hw(
void *hw_mgr_priv,
void *acquire_hw_args)
{
int rc = -1;
int32_t i;
uint32_t in_port_length;
int rc = -1, i;
uint32_t input_size = 0;
struct cam_custom_hw_mgr_ctx *custom_ctx;
struct cam_custom_hw_mgr *custom_hw_mgr;
struct cam_hw_acquire_args *acquire_args =
(struct cam_hw_acquire_args *) acquire_hw_args;
struct cam_custom_in_port_info *in_port_info;
struct cam_custom_resource *custom_rsrc;
struct cam_custom_acquire_hw_info *acquire_hw_info = NULL;
struct cam_isp_in_port_generic_info *gen_port_info = NULL;
struct cam_hw_acquire_args *acquire_args =
(struct cam_hw_acquire_args *)acquire_hw_args;
if (!hw_mgr_priv || !acquire_args || (acquire_args->num_acq <= 0)) {
if (!hw_mgr_priv || !acquire_args) {
CAM_ERR(CAM_CUSTOM, "Invalid params");
return -EINVAL;
}
@@ -925,127 +964,47 @@ static int cam_custom_mgr_acquire_hw(
}
mutex_unlock(&g_custom_hw_mgr.ctx_mutex);
/* Handle Acquire Here */
custom_ctx->hw_mgr = custom_hw_mgr;
custom_ctx->cb_priv = acquire_args->context_data;
custom_ctx->event_cb = acquire_args->event_cb;
custom_rsrc = kcalloc(acquire_args->num_acq,
sizeof(*custom_rsrc), GFP_KERNEL);
if (!custom_rsrc) {
rc = -ENOMEM;
goto free_ctx;
}
acquire_hw_info =
(struct cam_custom_acquire_hw_info *)acquire_args->acquire_info;
CAM_DBG(CAM_CUSTOM, "start copy %d resources from user",
acquire_args->num_acq);
for (i = 0; i < acquire_hw_info->num_inputs; i++) {
rc = cam_custom_hw_mgr_acquire_get_unified_dev_str(
acquire_hw_info, &input_size, &gen_port_info);
if (copy_from_user(custom_rsrc,
(void __user *)acquire_args->acquire_info,
((sizeof(*custom_rsrc)) * acquire_args->num_acq))) {
rc = -EFAULT;
goto free_ctx;
}
for (i = 0; i < acquire_args->num_acq; i++) {
if (custom_rsrc[i].resource_id != CAM_CUSTOM_RES_ID_PORT)
continue;
CAM_DBG(CAM_CUSTOM, "acquire no = %d total = %d", i,
acquire_args->num_acq);
CAM_DBG(CAM_CUSTOM,
"start copy from user handle %lld with len = %d",
custom_rsrc[i].res_hdl,
custom_rsrc[i].length);
in_port_length = sizeof(struct cam_custom_in_port_info);
if (in_port_length > custom_rsrc[i].length) {
CAM_ERR(CAM_CUSTOM, "buffer size is not enough");
rc = -EINVAL;
if (rc < 0) {
CAM_ERR(CAM_CUSTOM, "Failed in parsing: %d", rc);
goto free_res;
}
in_port_info = memdup_user(
u64_to_user_ptr(custom_rsrc[i].res_hdl),
custom_rsrc[i].length);
if (!IS_ERR(in_port_info)) {
if (in_port_info->num_out_res >
CAM_CUSTOM_HW_OUT_RES_MAX) {
CAM_ERR(CAM_CUSTOM, "too many output res %d",
in_port_info->num_out_res);
rc = -EINVAL;
kfree(in_port_info);
goto free_res;
}
in_port_length =
sizeof(struct cam_custom_in_port_info) +
(in_port_info->num_out_res - 1) *
sizeof(struct cam_custom_out_port_info);
if (in_port_length > custom_rsrc[i].length) {
CAM_ERR(CAM_CUSTOM,
"buffer size is not enough");
rc = -EINVAL;
kfree(in_port_info);
goto free_res;
}
gen_port_info = kzalloc(
sizeof(struct cam_isp_in_port_generic_info),
GFP_KERNEL);
if (gen_port_info == NULL) {
rc = -ENOMEM;
goto free_res;
}
gen_port_info->data = kcalloc(
sizeof(struct cam_isp_out_port_generic_info),
in_port_info->num_out_res, GFP_KERNEL);
if (gen_port_info->data == NULL) {
kfree(gen_port_info);
gen_port_info = NULL;
rc = -ENOMEM;
goto free_res;
}
cam_custom_hw_mgr_acquire_get_unified_dev_str(
in_port_info, gen_port_info);
rc = cam_custom_mgr_acquire_hw_for_ctx(custom_ctx,
gen_port_info, &acquire_args->acquired_hw_id[i],
acquire_args->acquired_hw_path[i]);
kfree(in_port_info);
if (gen_port_info != NULL) {
kfree(gen_port_info->data);
kfree(gen_port_info);
gen_port_info = NULL;
}
if (rc) {
CAM_ERR(CAM_CUSTOM, "can not acquire resource");
goto free_res;
}
} else {
CAM_ERR(CAM_CUSTOM,
"Copy from user failed with in_port = %pK",
in_port_info);
rc = -EFAULT;
goto free_res;
CAM_DBG(CAM_CUSTOM, "in_res_type %x", gen_port_info->res_type);
rc = cam_custom_mgr_acquire_hw_for_ctx(custom_ctx,
gen_port_info, &acquire_args->acquired_hw_id[i],
acquire_args->acquired_hw_path[i]);
if (rc) {
CAM_ERR(CAM_CUSTOM, "can not acquire resource");
goto free_mem;
}
kfree(gen_port_info->data);
kfree(gen_port_info);
gen_port_info = NULL;
}
custom_ctx->ctx_in_use = 1;
acquire_args->ctxt_to_hw_map = custom_ctx;
cam_custom_hw_mgr_put_ctx(&custom_hw_mgr->used_ctx_list, &custom_ctx);
CAM_DBG(CAM_CUSTOM, "Exit...(success)");
return 0;
free_mem:
kfree(gen_port_info->data);
kfree(gen_port_info);
free_res:
cam_custom_hw_mgr_release_hw_for_ctx(custom_ctx);
free_ctx:
cam_custom_hw_mgr_put_ctx(&custom_hw_mgr->free_ctx_list, &custom_ctx);
err:
CAM_DBG(CAM_CUSTOM, "Exit...(rc=%d)", rc);

Ver ficheiro

@@ -74,7 +74,7 @@
#define ICP_SHARED_MEM_IN_BYTES (1024 * 1024)
#define ICP_UNCACHED_HEAP_SIZE_IN_BYTES (2 * 1024 * 1024)
#define ICP_HFI_MAX_PKT_SIZE_IN_WORDS 25600
#define ICP_HFI_MAX_PKT_SIZE_MSGQ_IN_WORDS 256
#define ICP_HFI_MAX_PKT_SIZE_MSGQ_IN_WORDS 1024
#define ICP_HFI_QTBL_HOSTID1 0x01000000
#define ICP_HFI_QTBL_STATUS_ENABLED 0x00000001

Ver ficheiro

@@ -2361,6 +2361,10 @@ static int cam_icp_mgr_process_fatal_error(
if (event_notify->event_id == HFI_EVENT_SYS_ERROR) {
CAM_INFO(CAM_ICP, "received HFI_EVENT_SYS_ERROR");
if (event_notify->event_data1 == HFI_ERR_SYS_FATAL) {
CAM_ERR(CAM_ICP, "received HFI_ERR_SYS_FATAL");
BUG();
}
rc = cam_icp_mgr_trigger_recovery(hw_mgr);
cam_icp_mgr_process_dbg_buf(icp_hw_mgr.a5_dbg_lvl);
}

Ver ficheiro

@@ -2165,6 +2165,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
struct cam_hw_stop_args stop_args;
struct cam_hw_reset_args reset_args;
struct cam_hw_cmd_args hw_cmd_args;
struct cam_req_mgr_timer_notify timer;
ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
@@ -2210,6 +2211,14 @@ static int __cam_isp_ctx_flush_req_in_top_state(
CAM_INFO(CAM_ISP, "Stop HW complete. Reset HW next.");
CAM_DBG(CAM_ISP, "Flush wait and active lists");
if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_timer) {
timer.link_hdl = ctx->link_hdl;
timer.dev_hdl = ctx->dev_hdl;
timer.state = false;
ctx->ctx_crm_intf->notify_timer(&timer);
}
spin_lock_bh(&ctx->lock);
if (!list_empty(&ctx->wait_req_list))
rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list,

Ver ficheiro

@@ -3360,9 +3360,10 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
struct cam_ife_hw_mgr_ctx *ctx;
struct cam_isp_prepare_hw_update_data *hw_update_data;
CAM_DBG(CAM_ISP, "Enter");
if (!hw_mgr_priv || !config_hw_args) {
CAM_ERR(CAM_ISP, "Invalid arguments");
CAM_ERR(CAM_ISP,
"Invalid arguments, hw_mgr_priv=%pK, config_hw_args=%pK",
hw_mgr_priv, config_hw_args);
return -EINVAL;
}
@@ -3370,21 +3371,28 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
ctx = (struct cam_ife_hw_mgr_ctx *)cfg->ctxt_to_hw_map;
if (!ctx) {
CAM_ERR(CAM_ISP, "Invalid context is used");
return -EPERM;
return -EINVAL;
}
if (!ctx->ctx_in_use || !ctx->cdm_cmd) {
CAM_ERR(CAM_ISP, "Invalid context parameters");
CAM_ERR(CAM_ISP,
"Invalid context parameters : ctx_in_use=%d, cdm_cmd=%pK",
ctx->ctx_in_use, ctx->cdm_cmd);
return -EPERM;
}
if (atomic_read(&ctx->overflow_pending)) {
CAM_DBG(CAM_ISP,
"Ctx[%pK][%d] Overflow pending, cannot apply req %llu",
ctx, ctx->ctx_index, cfg->request_id);
return -EPERM;
}
if (atomic_read(&ctx->overflow_pending))
return -EINVAL;
hw_update_data = (struct cam_isp_prepare_hw_update_data *) cfg->priv;
hw_update_data->ife_mgr_ctx = ctx;
CAM_DBG(CAM_ISP, "Ctx[%pK][%d] : Applying Req %lld",
ctx, ctx->ctx_index, cfg->request_id);
CAM_DBG(CAM_ISP, "Ctx[%pK][%d] : Applying Req %lld, init_packet=%d",
ctx, ctx->ctx_index, cfg->request_id, cfg->init_packet);
for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
if (hw_update_data->bw_config_valid[i] == true) {
@@ -3456,7 +3464,9 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
atomic_set(&ctx->cdm_done, 0);
rc = cam_cdm_submit_bls(ctx->cdm_handle, cdm_cmd);
if (rc) {
CAM_ERR(CAM_ISP, "Failed to apply the configs");
CAM_ERR(CAM_ISP,
"Failed to apply the configs for req %llu, rc %d",
cfg->request_id, rc);
return rc;
}
@@ -3956,11 +3966,16 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
}
start_only:
atomic_set(&ctx->overflow_pending, 0);
/* Apply initial configuration */
CAM_DBG(CAM_ISP, "Config HW");
rc = cam_ife_mgr_config_hw(hw_mgr_priv, &start_isp->hw_config);
if (rc) {
CAM_ERR(CAM_ISP, "Config HW failed");
CAM_ERR(CAM_ISP,
"Config HW failed, start_only=%d, rc=%d",
start_isp->start_only, rc);
goto cdm_streamoff;
}

Ver ficheiro

@@ -44,6 +44,8 @@
/* Max CSI Rx irq error count threshold value */
#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT 100
static int cam_ife_csid_reset_regs(
struct cam_ife_csid_hw *csid_hw, bool reset_hw);
static int cam_ife_csid_is_ipp_ppp_format_supported(
uint32_t in_format)
{
@@ -420,7 +422,7 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
const struct cam_ife_csid_reg_offset *csid_reg;
int rc = 0;
uint32_t val = 0, i;
uint32_t status;
unsigned long flags;
soc_info = &csid_hw->hw_info->soc_info;
csid_reg = csid_hw->csid_info->csid_reg;
@@ -435,6 +437,8 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
CAM_DBG(CAM_ISP, "CSID:%d Csid reset",
csid_hw->hw_intf->hw_idx);
spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags);
/* Mask all interrupts */
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
@@ -482,6 +486,8 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_irq_cmd_addr);
spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags);
cam_io_w_mb(0x80, soc_info->reg_map[0].mem_base +
csid_hw->csid_info->csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
@@ -498,37 +504,14 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
cam_io_w_mb(0x2, soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[i]->csid_rdi_cfg0_addr);
/* perform the top CSID HW registers reset */
cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_rst_strobes_addr);
/* reset HW regs first, then SW */
rc = cam_ife_csid_reset_regs(csid_hw, true);
if (rc < 0)
goto end;
rc = cam_ife_csid_reset_regs(csid_hw, false);
if (rc < 0)
goto end;
rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_status_addr,
status, (status & 0x1) == 0x1,
CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
if (rc < 0) {
CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
csid_hw->hw_intf->hw_idx, rc);
rc = -ETIMEDOUT;
}
/* perform the SW registers reset */
cam_io_w_mb(csid_reg->cmn_reg->csid_reg_rst_stb,
soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_rst_strobes_addr);
rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_status_addr,
status, (status & 0x1) == 0x1,
CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
if (rc < 0) {
CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
csid_hw->hw_intf->hw_idx, rc);
rc = -ETIMEDOUT;
}
usleep_range(3000, 3010);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
if (val != 0)
@@ -537,6 +520,7 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
csid_hw->error_irq_count = 0;
csid_hw->prev_boot_timestamp = 0;
end:
return rc;
}
@@ -656,7 +640,7 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
return -EINVAL;
}
init_completion(complete);
reinit_completion(complete);
reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;
/* Reset the corresponding ife csid path */
@@ -1196,6 +1180,7 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw)
struct cam_hw_soc_info *soc_info;
uint32_t i, val;
int clk_lvl;
unsigned long flags;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
@@ -1240,6 +1225,8 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw)
if (rc)
goto disable_soc;
spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags);
/* clear all interrupts */
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_clear_addr);
@@ -1271,11 +1258,17 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw)
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_irq_cmd_addr);
spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_hw_version_addr);
CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
csid_hw->hw_intf->hw_idx, val);
spin_lock_irqsave(&csid_hw->lock_state, flags);
csid_hw->device_enabled = 1;
spin_unlock_irqrestore(&csid_hw->lock_state, flags);
return 0;
disable_soc:
@@ -1560,7 +1553,7 @@ static int cam_ife_csid_enable_csi2(
}
}
/*Enable the CSI2 rx inerrupts */
/*Enable the CSI2 rx interrupts */
val = CSID_CSI2_RX_INFO_RST_DONE |
CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW |
CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW |
@@ -3089,6 +3082,7 @@ int cam_ife_csid_reset(void *hw_priv,
csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
reset = (struct cam_csid_reset_cfg_args *)reset_args;
mutex_lock(&csid_hw->hw_info->hw_mutex);
switch (reset->reset_type) {
case CAM_IFE_CSID_RESET_GLOBAL:
rc = cam_ife_csid_global_reset(csid_hw);
@@ -3102,6 +3096,7 @@ int cam_ife_csid_reset(void *hw_priv,
rc = -EINVAL;
break;
}
mutex_unlock(&csid_hw->hw_info->hw_mutex);
return rc;
}
@@ -3226,43 +3221,86 @@ end:
return rc;
}
static int cam_ife_csid_reset_retain_sw_reg(
struct cam_ife_csid_hw *csid_hw)
static int cam_ife_csid_reset_regs(
struct cam_ife_csid_hw *csid_hw, bool reset_hw)
{
int rc = 0;
uint32_t status;
const struct cam_ife_csid_reg_offset *csid_reg =
csid_hw->csid_info->csid_reg;
struct cam_hw_soc_info *soc_info;
uint32_t val = 0;
unsigned long flags;
soc_info = &csid_hw->hw_info->soc_info;
reinit_completion(&csid_hw->csid_top_complete);
spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags);
/* clear the top interrupt first */
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_clear_addr);
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_irq_cmd_addr);
cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
if (reset_hw) {
/* enable top reset complete IRQ */
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_mask_addr);
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_irq_cmd_addr);
}
/* perform the top CSID registers reset */
val = reset_hw ? csid_reg->cmn_reg->csid_rst_stb :
csid_reg->cmn_reg->csid_reg_rst_stb;
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_rst_strobes_addr);
rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_status_addr,
status, (status & 0x1) == 0x1,
CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
if (rc < 0) {
CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
csid_hw->hw_intf->hw_idx, rc);
/*
* for SW reset, we enable the IRQ after since the mask
* register has been reset
*/
if (!reset_hw) {
/* enable top reset complete IRQ */
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_mask_addr);
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_irq_cmd_addr);
}
spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags);
CAM_DBG(CAM_ISP, "CSID reset start");
rc = wait_for_completion_timeout(&csid_hw->csid_top_complete,
msecs_to_jiffies(IFE_CSID_TIMEOUT));
if (rc <= 0) {
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_status_addr);
if (val & 0x1) {
/* clear top reset IRQ */
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_clear_addr);
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_irq_cmd_addr);
CAM_DBG(CAM_ISP, "CSID:%d %s reset completed %d",
csid_hw->hw_intf->hw_idx,
reset_hw ? "hw" : "sw",
rc);
rc = 0;
goto end;
}
CAM_ERR(CAM_ISP, "CSID:%d csid_reset %s fail rc = %d",
csid_hw->hw_intf->hw_idx, reset_hw ? "hw" : "sw", rc);
rc = -ETIMEDOUT;
goto end;
} else {
CAM_DBG(CAM_ISP, "CSID:%d hw reset completed %d",
csid_hw->hw_intf->hw_idx, rc);
CAM_DBG(CAM_ISP, "CSID:%d %s reset completed %d",
csid_hw->hw_intf->hw_idx, reset_hw ? "hw" : "sw", rc);
rc = 0;
}
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_clear_addr);
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_irq_cmd_addr);
end:
return rc;
}
@@ -3274,7 +3312,6 @@ int cam_ife_csid_init_hw(void *hw_priv,
struct cam_hw_info *csid_hw_info;
struct cam_isp_resource_node *res;
const struct cam_ife_csid_reg_offset *csid_reg;
unsigned long flags;
if (!hw_priv || !init_args ||
(arg_size != sizeof(struct cam_isp_resource_node))) {
@@ -3348,16 +3385,13 @@ int cam_ife_csid_init_hw(void *hw_priv,
break;
}
rc = cam_ife_csid_reset_retain_sw_reg(csid_hw);
rc = cam_ife_csid_reset_regs(csid_hw, true);
if (rc < 0)
CAM_ERR(CAM_ISP, "CSID: Failed in SW reset");
CAM_ERR(CAM_ISP, "CSID: Failed in HW reset");
if (rc)
cam_ife_csid_disable_hw(csid_hw);
spin_lock_irqsave(&csid_hw->lock_state, flags);
csid_hw->device_enabled = 1;
spin_unlock_irqrestore(&csid_hw->lock_state, flags);
end:
mutex_unlock(&csid_hw->hw_info->hw_mutex);
return rc;
@@ -3830,7 +3864,11 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
}
}
spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags);
/* clear */
cam_io_w_mb(irq_status_top, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_top_irq_clear_addr);
cam_io_w_mb(irq_status_rx, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
if (csid_reg->cmn_reg->num_pix)
@@ -3860,6 +3898,8 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_irq_cmd_addr);
spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags);
CAM_DBG(CAM_ISP, "irq_status_top = 0x%x", irq_status_top);
CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx);
CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp);
@@ -3871,6 +3911,11 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
"irq_status_udi0= 0x%x irq_status_udi1= 0x%x irq_status_udi2= 0x%x",
irq_status_udi[0], irq_status_udi[1], irq_status_udi[2]);
if (irq_status_top & CSID_TOP_IRQ_DONE) {
CAM_DBG(CAM_ISP, "csid top reset complete");
complete(&csid_hw->csid_top_complete);
}
if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) {
CAM_DBG(CAM_ISP, "csi rx reset complete");
complete(&csid_hw->csid_csi2_complete);

Ver ficheiro

@@ -40,6 +40,7 @@
#define CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW BIT(26)
#define CSID_CSI2_RX_INFO_RST_DONE BIT(27)
#define CSID_TOP_IRQ_DONE BIT(0)
#define CSID_PATH_INFO_RST_DONE BIT(1)
#define CSID_PATH_ERROR_FIFO_OVERFLOW BIT(2)
#define CSID_PATH_INFO_SUBSAMPLED_EOF BIT(3)

Ver ficheiro

@@ -3,7 +3,7 @@
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_core
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_smmu/
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_utils
ccflags-y += -I$(src)
ccflags-y += -I$(srctree)/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_req_mgr_core.o\
cam_req_mgr_dev.o \

Ver ficheiro

@@ -1106,6 +1106,8 @@ static int __cam_req_mgr_check_sync_req_is_ready(
int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0;
int32_t sync_num_slots = 0;
uint64_t sync_frame_duration = 0;
uint64_t sof_timestamp_delta = 0;
uint64_t master_slave_diff = 0;
bool ready = true, sync_ready = true;
if (!link->sync_link) {
@@ -1139,6 +1141,11 @@ static int __cam_req_mgr_check_sync_req_is_ready(
else
sync_frame_duration = DEFAULT_FRAME_DURATION;
sof_timestamp_delta =
link->sof_timestamp >= sync_link->sof_timestamp
? link->sof_timestamp - sync_link->sof_timestamp
: sync_link->sof_timestamp - link->sof_timestamp;
CAM_DBG(CAM_CRM,
"sync link %x last frame_duration is %d ns",
sync_link->link_hdl, sync_frame_duration);
@@ -1260,11 +1267,10 @@ static int __cam_req_mgr_check_sync_req_is_ready(
* difference of two SOF timestamp less than
* (sync_frame_duration / 5).
*/
do_div(sync_frame_duration, 5);
if ((link->sof_timestamp > sync_link->sof_timestamp) &&
(sync_link->sof_timestamp > 0) &&
(link->sof_timestamp - sync_link->sof_timestamp <
sync_frame_duration) &&
master_slave_diff = sync_frame_duration;
do_div(master_slave_diff, 5);
if ((sync_link->sof_timestamp > 0) &&
(sof_timestamp_delta < master_slave_diff) &&
(sync_rd_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)) {
/*
@@ -1287,6 +1293,11 @@ static int __cam_req_mgr_check_sync_req_is_ready(
"sync link %x too quickly, skip next frame of sync link",
sync_link->link_hdl);
link->sync_link_sof_skip = true;
} else if (sync_link->req.in_q->slot[sync_slot_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED) {
CAM_DBG(CAM_CRM,
"link %x other not applied", link->link_hdl);
return -EAGAIN;
}
}
@@ -1744,6 +1755,10 @@ static void __cam_req_mgr_sof_freeze(struct timer_list *timer_data)
}
link = (struct cam_req_mgr_core_link *)timer->parent;
if (link->watchdog->pause_timer)
return;
task = cam_req_mgr_workq_get_task(link->workq);
if (!task) {
CAM_ERR(CAM_CRM, "No empty task");
@@ -2643,6 +2658,52 @@ end:
return rc;
}
/**
* cam_req_mgr_cb_notify_timer()
*
* @brief : Notify SOF timer to pause after flush
* @timer_data : contains information about frame_id, link etc.
*
* @return : 0 on success
*
*/
static int cam_req_mgr_cb_notify_timer(
struct cam_req_mgr_timer_notify *timer_data)
{
int rc = 0;
struct cam_req_mgr_core_link *link = NULL;
if (!timer_data) {
CAM_ERR(CAM_CRM, "timer data is NULL");
rc = -EINVAL;
goto end;
}
link = (struct cam_req_mgr_core_link *)
cam_get_device_priv(timer_data->link_hdl);
if (!link) {
CAM_DBG(CAM_CRM, "link ptr NULL %x", timer_data->link_hdl);
rc = -EINVAL;
goto end;
}
spin_lock_bh(&link->link_state_spin_lock);
if (link->state < CAM_CRM_LINK_STATE_READY) {
CAM_WARN(CAM_CRM, "invalid link state:%d", link->state);
spin_unlock_bh(&link->link_state_spin_lock);
rc = -EPERM;
goto end;
}
spin_unlock_bh(&link->link_state_spin_lock);
if (!timer_data->state)
link->watchdog->pause_timer = true;
end:
return rc;
}
/**
* cam_req_mgr_cb_notify_trigger()
*
@@ -2682,6 +2743,10 @@ static int cam_req_mgr_cb_notify_trigger(
rc = -EPERM;
goto end;
}
if (link->watchdog->pause_timer)
link->watchdog->pause_timer = false;
crm_timer_reset(link->watchdog);
spin_unlock_bh(&link->link_state_spin_lock);
@@ -2711,6 +2776,7 @@ static struct cam_req_mgr_crm_cb cam_req_mgr_ops = {
.notify_trigger = cam_req_mgr_cb_notify_trigger,
.notify_err = cam_req_mgr_cb_notify_err,
.add_req = cam_req_mgr_cb_add_req,
.notify_timer = cam_req_mgr_cb_notify_timer,
};
/**

Ver ficheiro

@@ -6,12 +6,17 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/highmem.h>
#include <mm/slab.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/cam_req_mgr.h>
#include <media/cam_defs.h>
#include "cam_req_mgr_dev.h"
#include "cam_req_mgr_util.h"
#include "cam_req_mgr_core.h"
@@ -19,7 +24,6 @@
#include "cam_mem_mgr.h"
#include "cam_debug_util.h"
#include "cam_common_util.h"
#include <linux/slub_def.h>
#define CAM_REQ_MGR_EVENT_MAX 30
@@ -204,31 +208,39 @@ static void cam_v4l2_event_queue_notify_error(const struct v4l2_event *old,
ev_header = CAM_REQ_MGR_GET_PAYLOAD_PTR((*old),
struct cam_req_mgr_message);
switch (old->id) {
case V4L_EVENT_CAM_REQ_MGR_SOF:
CAM_ERR(CAM_CRM, "Failed to notify SOF event");
CAM_ERR(CAM_CRM, "Sess %X FrameId %lld ReqId %lld link %X",
ev_header->session_hdl,
ev_header->u.frame_msg.frame_id,
ev_header->u.frame_msg.request_id,
ev_header->u.frame_msg.link_hdl);
case V4L_EVENT_CAM_REQ_MGR_SOF_BOOT_TS:
if (ev_header->u.frame_msg.request_id)
CAM_ERR(CAM_CRM,
"Failed to notify %s Sess %X FrameId %lld FrameMeta %d ReqId %lld link %X",
((old->id == V4L_EVENT_CAM_REQ_MGR_SOF) ?
"SOF_TS" : "BOOT_TS"),
ev_header->session_hdl,
ev_header->u.frame_msg.frame_id,
ev_header->u.frame_msg.frame_id_meta,
ev_header->u.frame_msg.request_id,
ev_header->u.frame_msg.link_hdl);
else
CAM_WARN_RATE_LIMIT_CUSTOM(CAM_CRM, 5, 1,
"Failed to notify %s Sess %X FrameId %lld FrameMeta %d ReqId %lld link %X",
((old->id == V4L_EVENT_CAM_REQ_MGR_SOF) ?
"SOF_TS" : "BOOT_TS"),
ev_header->session_hdl,
ev_header->u.frame_msg.frame_id,
ev_header->u.frame_msg.frame_id_meta,
ev_header->u.frame_msg.request_id,
ev_header->u.frame_msg.link_hdl);
break;
case V4L_EVENT_CAM_REQ_MGR_ERROR:
CAM_ERR(CAM_CRM, "Failed to notify ERROR");
CAM_ERR(CAM_CRM, "Sess %X ReqId %d Link %X Type %d",
ev_header->u.err_msg.error_type,
CAM_ERR(CAM_CRM,
"Failed to notify ERROR Sess %X ReqId %d Link %X Type %d",
ev_header->session_hdl,
ev_header->u.err_msg.request_id,
ev_header->u.err_msg.link_hdl,
ev_header->u.err_msg.error_type);
break;
case V4L_EVENT_CAM_REQ_MGR_SOF_BOOT_TS:
CAM_ERR(CAM_CRM, "Failed to notify BOOT_TS event");
CAM_ERR(CAM_CRM, "Sess %X FrameId %lld ReqId %lld link %X",
ev_header->session_hdl,
ev_header->u.frame_msg.frame_id,
ev_header->u.frame_msg.request_id,
ev_header->u.frame_msg.link_hdl);
break;
default:
CAM_ERR(CAM_CRM, "Failed to notify crm event id %d",
old->id);

Ver ficheiro

@@ -14,6 +14,7 @@
struct cam_req_mgr_trigger_notify;
struct cam_req_mgr_error_notify;
struct cam_req_mgr_add_request;
struct cam_req_mgr_timer_notify;
struct cam_req_mgr_device_info;
struct cam_req_mgr_core_dev_link_setup;
struct cam_req_mgr_apply_request;
@@ -35,6 +36,7 @@ typedef int (*cam_req_mgr_notify_trigger)(
struct cam_req_mgr_trigger_notify *);
typedef int (*cam_req_mgr_notify_err)(struct cam_req_mgr_error_notify *);
typedef int (*cam_req_mgr_add_req)(struct cam_req_mgr_add_request *);
typedef int (*cam_req_mgr_notify_timer)(struct cam_req_mgr_timer_notify *);
/**
* @brief: cam req mgr to camera device drivers
@@ -64,6 +66,7 @@ struct cam_req_mgr_crm_cb {
cam_req_mgr_notify_trigger notify_trigger;
cam_req_mgr_notify_err notify_err;
cam_req_mgr_add_req add_req;
cam_req_mgr_notify_timer notify_timer;
};
/**
@@ -206,6 +209,19 @@ struct cam_req_mgr_trigger_notify {
uint64_t sof_timestamp_val;
};
/**
* struct cam_req_mgr_timer_notify
* @link_hdl : link identifier
* @dev_hdl : device handle which has sent this req id
* @frame_id : frame id for internal tracking
* @state : timer state i.e ON or OFF
*/
struct cam_req_mgr_timer_notify {
int32_t link_hdl;
int32_t dev_hdl;
bool state;
};
/**
* struct cam_req_mgr_error_notify
* @link_hdl : link identifier

Ver ficheiro

@@ -1,11 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*/
#include "cam_req_mgr_timer.h"
#include "cam_debug_util.h"
extern struct kmem_cache *g_cam_req_mgr_timer_cachep;
void crm_timer_reset(struct cam_req_mgr_timer *crm_timer)
{
if (!crm_timer)

Ver ficheiro

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_REQ_MGR_TIMER_H_
@@ -12,16 +12,18 @@
#include "cam_req_mgr_core_defs.h"
/** struct cam_req_mgr_timer
* @expires : timeout value for timer
* @sys_timer : system timer variable
* @parent : priv data - link pointer
* @timer_cb : callback func which will be called when timeout expires
* @expires : timeout value for timer
* @sys_timer : system timer variable
* @parent : priv data - link pointer
* @timer_cb : callback func which will be called when timeout expires
* @pause_timer : flag to pause SOF timer
*/
struct cam_req_mgr_timer {
int32_t expires;
struct timer_list sys_timer;
void *parent;
void (*timer_cb)(struct timer_list *timer_data);
bool pause_timer;
};
/**
@@ -60,5 +62,4 @@ int crm_timer_init(struct cam_req_mgr_timer **timer,
*/
void crm_timer_exit(struct cam_req_mgr_timer **timer);
extern struct kmem_cache *g_cam_req_mgr_timer_cachep;
#endif

Ver ficheiro

@@ -554,7 +554,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
rc = cam_sensor_i2c_command_parser(
&a_ctrl->io_master_info,
i2c_reg_settings,
&cmd_desc[i], 1);
&cmd_desc[i], 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR,
"Failed:parse init settings: %d",
@@ -612,7 +612,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
rc = cam_sensor_i2c_command_parser(
&a_ctrl->io_master_info,
i2c_reg_settings,
cmd_desc, 1);
cmd_desc, 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR,
"Auto move lens parsing failed: %d", rc);
@@ -643,7 +643,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
rc = cam_sensor_i2c_command_parser(
&a_ctrl->io_master_info,
i2c_reg_settings,
cmd_desc, 1);
cmd_desc, 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR,
"Manual move lens parsing failed: %d", rc);
@@ -662,6 +662,68 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
}
cam_actuator_update_req_mgr(a_ctrl, csl_packet);
break;
case CAM_ACTUATOR_PACKET_OPCODE_READ: {
struct cam_buf_io_cfg *io_cfg;
struct i2c_settings_array i2c_read_settings;
if (a_ctrl->cam_act_state < CAM_ACTUATOR_CONFIG) {
rc = -EINVAL;
CAM_WARN(CAM_ACTUATOR,
"Not in right state to read actuator: %d",
a_ctrl->cam_act_state);
goto end;
}
CAM_DBG(CAM_ACTUATOR, "number of I/O configs: %d:",
csl_packet->num_io_configs);
if (csl_packet->num_io_configs == 0) {
CAM_ERR(CAM_ACTUATOR, "No I/O configs to process");
rc = -EINVAL;
goto end;
}
INIT_LIST_HEAD(&(i2c_read_settings.list_head));
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
&csl_packet->payload +
csl_packet->io_configs_offset);
if (io_cfg == NULL) {
CAM_ERR(CAM_ACTUATOR, "I/O config is invalid(NULL)");
rc = -EINVAL;
goto end;
}
offset = (uint32_t *)&csl_packet->payload;
offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
i2c_read_settings.is_settings_valid = 1;
i2c_read_settings.request_id = 0;
rc = cam_sensor_i2c_command_parser(&a_ctrl->io_master_info,
&i2c_read_settings,
cmd_desc, 1, io_cfg);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR,
"actuator read pkt parsing failed: %d", rc);
goto end;
}
rc = cam_sensor_i2c_read_data(
&i2c_read_settings,
&a_ctrl->io_master_info);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR, "cannot read data, rc:%d", rc);
delete_request(&i2c_read_settings);
goto end;
}
rc = delete_request(&i2c_read_settings);
if (rc < 0) {
CAM_ERR(CAM_ACTUATOR,
"Failed in deleting the read settings");
goto end;
}
break;
}
default:
CAM_ERR(CAM_ACTUATOR, "Wrong Opcode: %d",
csl_packet->header.op_code & 0xFFFFFF);

Ver ficheiro

@@ -12,9 +12,9 @@ struct csiphy_reg_parms_t csiphy_v1_2 = {
.mipi_csiphy_interrupt_status0_addr = 0x8B0,
.mipi_csiphy_interrupt_clear0_addr = 0x858,
.mipi_csiphy_glbl_irq_cmd_addr = 0x828,
.csiphy_common_array_size = 5,
.csiphy_reset_array_size = 4,
.csiphy_2ph_config_array_size = 19,
.csiphy_common_array_size = 6,
.csiphy_reset_array_size = 5,
.csiphy_2ph_config_array_size = 18,
.csiphy_3ph_config_array_size = 33,
.csiphy_2ph_clock_lane = 0x1,
.csiphy_2ph_combo_ck_ln = 0x10,
@@ -23,15 +23,17 @@ struct csiphy_reg_parms_t csiphy_v1_2 = {
struct csiphy_reg_t csiphy_common_reg_1_2[] = {
{0x0814, 0xd5, 0x00, CSIPHY_LANE_ENABLE},
{0x0818, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x081C, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x081C, 0x5A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0824, 0x72, 0x00, CSIPHY_2PH_REGS},
};
struct csiphy_reg_t csiphy_reset_reg_1_2[] = {
{0x0814, 0x00, 0x05, CSIPHY_LANE_ENABLE},
{0x0818, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x081C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0800, 0x01, 0x01, CSIPHY_DEFAULT_PARAMS},
{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
};
@@ -55,39 +57,37 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{0x0030, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0034, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0010, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x001C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0000, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0024, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x005C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0060, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0060, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0064, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
},
{
{0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0734, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0710, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x071C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x073C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0700, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0720, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0724, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0708, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x070c, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x070c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS},
@@ -97,106 +97,101 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0234, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0210, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x021C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0200, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0200, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0220, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0224, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0208, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x025C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0260, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0260, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0264, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
},
{
{0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0434, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0410, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x041C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0428, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0400, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0400, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0420, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0424, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0408, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x045C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0460, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0460, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0464, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
},
{
{0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0634, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0610, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x061C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0628, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0600, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0600, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0620, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0624, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0608, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x060c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x065C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0660, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0660, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0664, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
},
};
struct csiphy_reg_t
csiphy_2ph_v1_2_combo_mode_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
csiphy_2ph_v1_2_combo_mode_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{
{0x0030, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0034, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0010, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x001C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0000, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0024, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x000C, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x005C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0060, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0060, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0064, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
},
{
{0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0734, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0710, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x071C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x073C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0700, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0720, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0724, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0708, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x070C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x070C, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS},
@@ -206,60 +201,57 @@ struct csiphy_reg_t
{0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0234, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0210, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x021C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0200, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0200, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0220, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0224, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0208, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x020C, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x025C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0260, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0260, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0264, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
},
{
{0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0434, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0410, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x041C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0428, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0400, 0xD4, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0400, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0420, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0424, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0408, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x040C, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x045C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0460, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0460, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0464, 0x7F, 0x00, CSIPHY_DNP_PARAMS},
{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
},
{
{0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0634, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0610, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x061C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0628, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0600, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0600, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0620, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0624, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0608, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x060C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x060C, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0638, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS},
@@ -382,14 +374,11 @@ struct data_rate_settings_t data_rate_delta_table_1_2 = {
{
/* (2.5 * 10**3 * 2.28) rounded value*/
.bandwidth = 5700000000,
.data_rate_reg_array_size = 6,
.data_rate_reg_array_size = 3,
.csiphy_data_rate_regs = {
{0x144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x544, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
}
},
{
@@ -397,12 +386,12 @@ struct data_rate_settings_t data_rate_delta_table_1_2 = {
.bandwidth = 7980000000,
.data_rate_reg_array_size = 15,
.csiphy_data_rate_regs = {
{0x9B4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0xAB4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0xBB4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x144, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x344, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x544, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x16C, 0x2D, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x36C, 0x2D, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x56C, 0x2D, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0xA88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -419,21 +408,21 @@ struct data_rate_settings_t data_rate_delta_table_1_2 = {
.bandwidth = 10260000000,
.data_rate_reg_array_size = 15,
.csiphy_data_rate_regs = {
{0x9B4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0xAB4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0xBB4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x144, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x344, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x544, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0xA88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
{0xA80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0xB88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
{0xB80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x10C, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x30C, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x50C, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x10C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x30C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x50C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
},
}
}

Ver ficheiro

@@ -1070,7 +1070,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
rc = cam_sensor_i2c_command_parser(
&fctrl->io_master_info,
i2c_reg_settings,
&cmd_desc[i], 1);
&cmd_desc[i], 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_FLASH,
"pkt parsing failed: %d", rc);
@@ -1150,7 +1150,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
rc = cam_sensor_i2c_command_parser(
&fctrl->io_master_info,
i2c_reg_settings, cmd_desc, 1);
i2c_reg_settings, cmd_desc, 1, NULL);
if (rc) {
CAM_ERR(CAM_FLASH,
"Failed in parsing i2c packets");
@@ -1181,7 +1181,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
rc = cam_sensor_i2c_command_parser(
&fctrl->io_master_info,
i2c_reg_settings, cmd_desc, 1);
i2c_reg_settings, cmd_desc, 1, NULL);
if (rc) {
CAM_ERR(CAM_FLASH,
"Failed in parsing i2c NRT packets");

Ver ficheiro

@@ -540,7 +540,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
rc = cam_sensor_i2c_command_parser(
&o_ctrl->io_master_info,
i2c_reg_settings,
&cmd_desc[i], 1);
&cmd_desc[i], 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_OIS,
"init parsing failed: %d", rc);
@@ -557,7 +557,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
rc = cam_sensor_i2c_command_parser(
&o_ctrl->io_master_info,
i2c_reg_settings,
&cmd_desc[i], 1);
&cmd_desc[i], 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_OIS,
"Calib parsing failed: %d", rc);
@@ -629,7 +629,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
i2c_reg_settings->request_id = 0;
rc = cam_sensor_i2c_command_parser(&o_ctrl->io_master_info,
i2c_reg_settings,
cmd_desc, 1);
cmd_desc, 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_OIS, "OIS pkt parsing failed: %d", rc);
return rc;
@@ -648,6 +648,67 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
return rc;
}
break;
case CAM_OIS_PACKET_OPCODE_READ: {
struct cam_buf_io_cfg *io_cfg;
struct i2c_settings_array i2c_read_settings;
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
rc = -EINVAL;
CAM_WARN(CAM_OIS,
"Not in right state to read OIS: %d",
o_ctrl->cam_ois_state);
return rc;
}
CAM_DBG(CAM_OIS, "number of I/O configs: %d:",
csl_packet->num_io_configs);
if (csl_packet->num_io_configs == 0) {
CAM_ERR(CAM_OIS, "No I/O configs to process");
rc = -EINVAL;
return rc;
}
INIT_LIST_HEAD(&(i2c_read_settings.list_head));
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
&csl_packet->payload +
csl_packet->io_configs_offset);
if (io_cfg == NULL) {
CAM_ERR(CAM_OIS, "I/O config is invalid(NULL)");
rc = -EINVAL;
return rc;
}
offset = (uint32_t *)&csl_packet->payload;
offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
i2c_read_settings.is_settings_valid = 1;
i2c_read_settings.request_id = 0;
rc = cam_sensor_i2c_command_parser(&o_ctrl->io_master_info,
&i2c_read_settings,
cmd_desc, 1, io_cfg);
if (rc < 0) {
CAM_ERR(CAM_OIS, "OIS read pkt parsing failed: %d", rc);
return rc;
}
rc = cam_sensor_i2c_read_data(
&i2c_read_settings,
&o_ctrl->io_master_info);
if (rc < 0) {
CAM_ERR(CAM_OIS, "cannot read data rc: %d", rc);
delete_request(&i2c_read_settings);
return rc;
}
rc = delete_request(&i2c_read_settings);
if (rc < 0) {
CAM_ERR(CAM_OIS,
"Failed in deleting the read settings");
return rc;
}
break;
}
default:
CAM_ERR(CAM_OIS, "Invalid Opcode: %d",
(csl_packet->header.op_code & 0xFFFFFF));

Ver ficheiro

@@ -87,6 +87,7 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
struct cam_control *ioctl_ctrl = NULL;
struct cam_packet *csl_packet = NULL;
struct cam_cmd_buf_desc *cmd_desc = NULL;
struct cam_buf_io_cfg *io_cfg = NULL;
struct i2c_settings_array *i2c_reg_settings = NULL;
size_t len_of_buff = 0;
size_t remain_len = 0;
@@ -187,7 +188,28 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
i2c_reg_settings->is_settings_valid = 1;
break;
}
case CAM_SENSOR_PACKET_OPCODE_SENSOR_READ: {
i2c_reg_settings = &(i2c_data->read_settings);
i2c_reg_settings->request_id = 0;
i2c_reg_settings->is_settings_valid = 1;
CAM_DBG(CAM_SENSOR, "number of IO configs: %d:",
csl_packet->num_io_configs);
if (csl_packet->num_io_configs == 0) {
CAM_ERR(CAM_SENSOR, "No I/O configs to process");
goto end;
}
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
&csl_packet->payload +
csl_packet->io_configs_offset);
if (io_cfg == NULL) {
CAM_ERR(CAM_SENSOR, "I/O config is invalid(NULL)");
goto end;
}
break;
}
case CAM_SENSOR_PACKET_OPCODE_SENSOR_UPDATE: {
if ((s_ctrl->sensor_state == CAM_SENSOR_INIT) ||
(s_ctrl->sensor_state == CAM_SENSOR_ACQUIRE)) {
@@ -239,7 +261,7 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
rc = cam_sensor_i2c_command_parser(&s_ctrl->io_master_info,
i2c_reg_settings, cmd_desc, 1);
i2c_reg_settings, cmd_desc, 1, io_cfg);
if (rc < 0) {
CAM_ERR(CAM_SENSOR, "Fail parsing I2C Pkt: %d", rc);
goto end;
@@ -951,6 +973,24 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
}
s_ctrl->sensor_state = CAM_SENSOR_CONFIG;
}
if (s_ctrl->i2c_data.read_settings.is_settings_valid) {
rc = cam_sensor_i2c_read_data(
&s_ctrl->i2c_data.read_settings,
&s_ctrl->io_master_info);
if (rc < 0) {
CAM_ERR(CAM_SENSOR, "cannot read data: %d", rc);
delete_request(&s_ctrl->i2c_data.read_settings);
goto release_mutex;
}
rc = delete_request(
&s_ctrl->i2c_data.read_settings);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"Fail in deleting the read settings");
goto release_mutex;
}
}
}
break;
default:

Ver ficheiro

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
*/
#include "cam_sensor_dev.h"
@@ -179,6 +179,7 @@ static int32_t cam_sensor_driver_i2c_probe(struct i2c_client *client,
INIT_LIST_HEAD(&(s_ctrl->i2c_data.config_settings.list_head));
INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamon_settings.list_head));
INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamoff_settings.list_head));
INIT_LIST_HEAD(&(s_ctrl->i2c_data.read_settings.list_head));
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
INIT_LIST_HEAD(&(s_ctrl->i2c_data.per_frame[i].list_head));
@@ -314,6 +315,7 @@ static int32_t cam_sensor_driver_platform_probe(
INIT_LIST_HEAD(&(s_ctrl->i2c_data.config_settings.list_head));
INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamon_settings.list_head));
INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamoff_settings.list_head));
INIT_LIST_HEAD(&(s_ctrl->i2c_data.read_settings.list_head));
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
INIT_LIST_HEAD(&(s_ctrl->i2c_data.per_frame[i].list_head));

Ver ficheiro

@@ -152,13 +152,15 @@ enum cam_sensor_packet_opcodes {
CAM_SENSOR_PACKET_OPCODE_SENSOR_PROBE,
CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG,
CAM_SENSOR_PACKET_OPCODE_SENSOR_STREAMOFF,
CAM_SENSOR_PACKET_OPCODE_SENSOR_READ,
CAM_SENSOR_PACKET_OPCODE_SENSOR_NOP = 127
};
enum cam_actuator_packet_opcodes {
CAM_ACTUATOR_PACKET_OPCODE_INIT,
CAM_ACTUATOR_PACKET_AUTO_MOVE_LENS,
CAM_ACTUATOR_PACKET_MANUAL_MOVE_LENS
CAM_ACTUATOR_PACKET_MANUAL_MOVE_LENS,
CAM_ACTUATOR_PACKET_OPCODE_READ
};
enum cam_eeprom_packet_opcodes {
@@ -168,7 +170,8 @@ enum cam_eeprom_packet_opcodes {
enum cam_ois_packet_opcodes {
CAM_OIS_PACKET_OPCODE_INIT,
CAM_OIS_PACKET_OPCODE_OIS_CONTROL
CAM_OIS_PACKET_OPCODE_OIS_CONTROL,
CAM_OIS_PACKET_OPCODE_READ
};
enum msm_bus_perf_setting {
@@ -218,7 +221,8 @@ enum cam_sensor_i2c_cmd_type {
CAM_SENSOR_I2C_WRITE_RANDOM,
CAM_SENSOR_I2C_WRITE_BURST,
CAM_SENSOR_I2C_WRITE_SEQ,
CAM_SENSOR_I2C_READ,
CAM_SENSOR_I2C_READ_RANDOM,
CAM_SENSOR_I2C_READ_SEQ,
CAM_SENSOR_I2C_POLL
};
@@ -270,6 +274,8 @@ struct cam_sensor_i2c_reg_setting {
enum camera_sensor_i2c_type addr_type;
enum camera_sensor_i2c_type data_type;
unsigned short delay;
uint8_t *read_buff;
uint32_t read_buff_len;
};
struct cam_sensor_i2c_seq_reg {
@@ -297,6 +303,7 @@ struct i2c_data_settings {
struct i2c_settings_array config_settings;
struct i2c_settings_array streamon_settings;
struct i2c_settings_array streamoff_settings;
struct i2c_settings_array read_settings;
struct i2c_settings_array *per_frame;
};

Ver ficheiro

@@ -233,6 +233,134 @@ static int32_t cam_sensor_handle_continuous_write(
return rc;
}
static int32_t cam_sensor_get_io_buffer(
struct cam_buf_io_cfg *io_cfg,
struct cam_sensor_i2c_reg_setting *i2c_settings)
{
uintptr_t buf_addr = 0x0;
size_t buf_size = 0;
int32_t rc = 0;
if (io_cfg->direction == CAM_BUF_OUTPUT) {
rc = cam_mem_get_cpu_buf(io_cfg->mem_handle[0],
&buf_addr, &buf_size);
if ((rc < 0) || (!buf_addr)) {
CAM_ERR(CAM_SENSOR,
"invalid buffer, rc: %d, buf_addr: %pK",
rc, buf_addr);
return -EINVAL;
}
CAM_DBG(CAM_SENSOR,
"buf_addr: %pK, buf_size: %zu, offsetsize: %d",
(void *)buf_addr, buf_size, io_cfg->offsets[0]);
if (io_cfg->offsets[0] >= buf_size) {
CAM_ERR(CAM_SENSOR,
"invalid size:io_cfg->offsets[0]: %d, buf_size: %d",
io_cfg->offsets[0], buf_size);
return -EINVAL;
}
i2c_settings->read_buff =
(uint8_t *)buf_addr + io_cfg->offsets[0];
i2c_settings->read_buff_len =
buf_size - io_cfg->offsets[0];
} else {
CAM_ERR(CAM_SENSOR, "Invalid direction: %d",
io_cfg->direction);
rc = -EINVAL;
}
return rc;
}
static int32_t cam_sensor_handle_random_read(
struct cam_cmd_i2c_random_rd *cmd_i2c_random_rd,
struct i2c_settings_array *i2c_reg_settings,
uint16_t *cmd_length_in_bytes,
int32_t *offset,
struct list_head **list,
struct cam_buf_io_cfg *io_cfg)
{
struct i2c_settings_list *i2c_list;
int32_t rc = 0, cnt = 0;
i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings,
cmd_i2c_random_rd->header.count);
if ((i2c_list == NULL) ||
(i2c_list->i2c_settings.reg_setting == NULL)) {
CAM_ERR(CAM_SENSOR,
"Failed in allocating i2c_list: %pK",
i2c_list);
return -ENOMEM;
}
rc = cam_sensor_get_io_buffer(io_cfg, &(i2c_list->i2c_settings));
if (rc) {
CAM_ERR(CAM_SENSOR, "Failed to get read buffer: %d", rc);
} else {
*cmd_length_in_bytes = sizeof(struct i2c_rdwr_header) +
(sizeof(struct cam_cmd_read) *
(cmd_i2c_random_rd->header.count));
i2c_list->op_code = CAM_SENSOR_I2C_READ_RANDOM;
i2c_list->i2c_settings.addr_type =
cmd_i2c_random_rd->header.addr_type;
i2c_list->i2c_settings.data_type =
cmd_i2c_random_rd->header.data_type;
i2c_list->i2c_settings.size =
cmd_i2c_random_rd->header.count;
for (cnt = 0; cnt < (cmd_i2c_random_rd->header.count);
cnt++) {
i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
cmd_i2c_random_rd->data_read[cnt].reg_data;
}
*offset = cnt;
*list = &(i2c_list->list);
}
return rc;
}
static int32_t cam_sensor_handle_continuous_read(
struct cam_cmd_i2c_continuous_rd *cmd_i2c_continuous_rd,
struct i2c_settings_array *i2c_reg_settings,
uint16_t *cmd_length_in_bytes, int32_t *offset,
struct list_head **list,
struct cam_buf_io_cfg *io_cfg)
{
struct i2c_settings_list *i2c_list;
int32_t rc = 0, cnt = 0;
i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings, 1);
if ((i2c_list == NULL) ||
(i2c_list->i2c_settings.reg_setting == NULL)) {
CAM_ERR(CAM_SENSOR,
"Failed in allocating i2c_list: %pK",
i2c_list);
return -ENOMEM;
}
rc = cam_sensor_get_io_buffer(io_cfg, &(i2c_list->i2c_settings));
if (rc) {
CAM_ERR(CAM_SENSOR, "Failed to get read buffer: %d", rc);
} else {
*cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_continuous_rd);
i2c_list->op_code = CAM_SENSOR_I2C_READ_SEQ;
i2c_list->i2c_settings.addr_type =
cmd_i2c_continuous_rd->header.addr_type;
i2c_list->i2c_settings.data_type =
cmd_i2c_continuous_rd->header.data_type;
i2c_list->i2c_settings.size =
cmd_i2c_continuous_rd->header.count;
i2c_list->i2c_settings.reg_setting[0].reg_addr =
cmd_i2c_continuous_rd->reg_addr;
*offset = cnt;
*list = &(i2c_list->list);
}
return rc;
}
static int cam_sensor_handle_slave_info(
struct camera_io_master *io_master,
uint32_t *cmd_buf)
@@ -271,8 +399,11 @@ static int cam_sensor_handle_slave_info(
/**
* Name : cam_sensor_i2c_command_parser
* Description : Parse CSL CCI packet and apply register settings
* Parameters : s_ctrl input/output sub_device
* arg input cam_control
* Parameters : io_master input master information
* i2c_reg_settings output register settings to fill
* cmd_desc input command description
* num_cmd_buffers input number of command buffers to process
* io_cfg input buffer details for read operation only
* Description :
* Handle multiple I2C RD/WR and WAIT cmd formats in one command
* buffer, for example, a command buffer of m x RND_WR + 1 x HW_
@@ -283,11 +414,12 @@ int cam_sensor_i2c_command_parser(
struct camera_io_master *io_master,
struct i2c_settings_array *i2c_reg_settings,
struct cam_cmd_buf_desc *cmd_desc,
int32_t num_cmd_buffers)
int32_t num_cmd_buffers,
struct cam_buf_io_cfg *io_cfg)
{
int16_t rc = 0, i = 0;
size_t len_of_buff = 0;
uintptr_t generic_ptr;
uintptr_t generic_ptr;
uint16_t cmd_length_in_bytes = 0;
size_t remain_len = 0;
size_t tot_size = 0;
@@ -472,7 +604,7 @@ int cam_sensor_i2c_command_parser(
}
case CAMERA_SENSOR_CMD_TYPE_I2C_INFO: {
if (remain_len - byte_cnt <
sizeof(struct cam_cmd_i2c_info)) {
sizeof(struct cam_cmd_i2c_info)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer space");
rc = -EINVAL;
@@ -493,6 +625,88 @@ int cam_sensor_i2c_command_parser(
byte_cnt += cmd_length_in_bytes;
break;
}
case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_RD: {
uint16_t cmd_length_in_bytes = 0;
struct cam_cmd_i2c_random_rd *i2c_random_rd =
(struct cam_cmd_i2c_random_rd *)cmd_buf;
if (remain_len - byte_cnt <
sizeof(struct cam_cmd_i2c_random_rd)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer space");
rc = -EINVAL;
goto end;
}
tot_size = sizeof(struct i2c_rdwr_header) +
(sizeof(struct cam_cmd_read) *
i2c_random_rd->header.count);
if (tot_size > (remain_len - byte_cnt)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer provided %d, %d, %d",
tot_size, remain_len, byte_cnt);
rc = -EINVAL;
goto end;
}
rc = cam_sensor_handle_random_read(
i2c_random_rd,
i2c_reg_settings,
&cmd_length_in_bytes, &j, &list,
io_cfg);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"Failed in random read %d", rc);
goto end;
}
cmd_buf += cmd_length_in_bytes /
sizeof(uint32_t);
byte_cnt += cmd_length_in_bytes;
break;
}
case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD: {
uint16_t cmd_length_in_bytes = 0;
struct cam_cmd_i2c_continuous_rd
*i2c_continuous_rd =
(struct cam_cmd_i2c_continuous_rd *)cmd_buf;
if (remain_len - byte_cnt <
sizeof(struct cam_cmd_i2c_continuous_rd)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer space");
rc = -EINVAL;
goto end;
}
tot_size =
sizeof(struct cam_cmd_i2c_continuous_rd);
if (tot_size > (remain_len - byte_cnt)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer provided %d, %d, %d",
tot_size, remain_len, byte_cnt);
rc = -EINVAL;
goto end;
}
rc = cam_sensor_handle_continuous_read(
i2c_continuous_rd,
i2c_reg_settings,
&cmd_length_in_bytes, &j, &list,
io_cfg);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"Failed in continuous read %d", rc);
goto end;
}
cmd_buf += cmd_length_in_bytes /
sizeof(uint32_t);
byte_cnt += cmd_length_in_bytes;
break;
}
default:
CAM_ERR(CAM_SENSOR, "Invalid Command Type:%d",
cmm_hdr->cmd_type);
@@ -576,6 +790,90 @@ int cam_sensor_util_i2c_apply_setting(
return rc;
}
int32_t cam_sensor_i2c_read_data(
struct i2c_settings_array *i2c_settings,
struct camera_io_master *io_master_info)
{
int32_t rc = 0;
struct i2c_settings_list *i2c_list;
uint32_t cnt = 0;
uint8_t *read_buff = NULL;
uint32_t buff_length = 0;
uint32_t read_length = 0;
list_for_each_entry(i2c_list,
&(i2c_settings->list_head), list) {
read_buff = i2c_list->i2c_settings.read_buff;
buff_length = i2c_list->i2c_settings.read_buff_len;
if ((read_buff == NULL) || (buff_length == 0)) {
CAM_ERR(CAM_SENSOR,
"Invalid input buffer, buffer: %pK, length: %d",
read_buff, buff_length);
return -EINVAL;
}
if (i2c_list->op_code == CAM_SENSOR_I2C_READ_RANDOM) {
read_length = i2c_list->i2c_settings.data_type *
i2c_list->i2c_settings.size;
if ((read_length > buff_length) ||
(read_length < i2c_list->i2c_settings.size)) {
CAM_ERR(CAM_SENSOR,
"Invalid size, readLen:%d, bufLen:%d, size: %d",
read_length, buff_length,
i2c_list->i2c_settings.size);
return -EINVAL;
}
for (cnt = 0; cnt < (i2c_list->i2c_settings.size);
cnt++) {
struct cam_sensor_i2c_reg_array *reg_setting =
&(i2c_list->i2c_settings.reg_setting[cnt]);
rc = camera_io_dev_read(io_master_info,
reg_setting->reg_addr,
&reg_setting->reg_data,
i2c_list->i2c_settings.addr_type,
i2c_list->i2c_settings.data_type);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"Failed: random read I2C settings: %d",
rc);
return rc;
}
if (i2c_list->i2c_settings.data_type <
CAMERA_SENSOR_I2C_TYPE_MAX) {
memcpy(read_buff,
&reg_setting->reg_data,
i2c_list->i2c_settings.data_type);
read_buff +=
i2c_list->i2c_settings.data_type;
}
}
} else if (i2c_list->op_code == CAM_SENSOR_I2C_READ_SEQ) {
read_length = i2c_list->i2c_settings.size;
if (read_length > buff_length) {
CAM_ERR(CAM_SENSOR,
"Invalid buffer size, readLen: %d, bufLen: %d",
read_length, buff_length);
return -EINVAL;
}
rc = camera_io_dev_read_seq(
io_master_info,
i2c_list->i2c_settings.reg_setting[0].reg_addr,
read_buff,
i2c_list->i2c_settings.addr_type,
i2c_list->i2c_settings.data_type,
i2c_list->i2c_settings.size);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"failed: seq read I2C settings: %d",
rc);
return rc;
}
}
}
return rc;
}
int32_t msm_camera_fill_vreg_params(
struct cam_hw_soc_info *soc_info,
struct cam_sensor_power_setting *power_setting,

Ver ficheiro

@@ -30,11 +30,16 @@ int msm_camera_pinctrl_init
int cam_sensor_i2c_command_parser(struct camera_io_master *io_master,
struct i2c_settings_array *i2c_reg_settings,
struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers);
struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers,
struct cam_buf_io_cfg *io_cfg);
int cam_sensor_util_i2c_apply_setting(struct camera_io_master *io_master_info,
struct i2c_settings_list *i2c_list);
int32_t cam_sensor_i2c_read_data(
struct i2c_settings_array *i2c_settings,
struct camera_io_master *io_master_info);
int32_t delete_request(struct i2c_settings_array *i2c_array);
int cam_sensor_util_request_gpio_table(
struct cam_hw_soc_info *soc_info, int gpio_en);

Ver ficheiro

@@ -170,6 +170,23 @@ struct cam_custom_resource {
uint64_t res_hdl;
};
/**
* struct cam_custom_acquire_hw_info - Custom acquire HW params
*
* @num_inputs : Number of inputs
* @input_info_size : Size of input info struct used
* @input_info_offset : Offset of input info from start of data
* @reserved : reserved
* @data : Start of data region
*/
struct cam_custom_acquire_hw_info {
uint32_t num_inputs;
uint32_t input_info_size;
uint32_t input_info_offset;
uint32_t reserved;
uint64_t data;
};
/**
* struct cam_custom_cmd_buf_type_1 - cmd buf type 1
*