UPSTREAM commit 'b644f8d2d11a8d98f34a4c2716bd1aade9b2e068' 09/13

* commit 'b644f8d2d11a8d98f34a4c2716bd1aade9b2e068':
  msm: camera: csid: Disable CSI Rx upon fatal errors
  msm: camera: isp: Select epoch config based on Hardware
  msm: camera: csiphy: Correct delay when configure device
  msm: camera: flash: Add torch handling in early PCR
  msm: camera: core: Check context state prior to handle release
  ARM: dts: msm: Add camera actuator regulator load-current
  msm: camera: mem: Remove lock from get_cpu_buf unless mapping
  ARM: dts: msm: Add lowsvs clock support for IPE for sm8150 platform
  msm: camera: lrme: Fix the unpack config and add dump function
  msm: camera: eeprom: set platform driver data to null
  ARM: dts: msm: Set the bound as multiple of 1MB
  msm: camera: lrme: Add handler function to support early PCR
  msm: camera: delete i2c data in release dev
  msm: camera: cpas: Disable camnoc ubwc settings for sm6150
  msm: camera: isp: Handle bus error in bottom half
  ARM: dts: msm: Add support for irs1645 sensor
  msm: camera: Replace mutex lock with context spin lock
  msm: camera: isp: support composite fence id
  msm: camera: reqmgr: Remove mem_mgr init & deinit calls
  msm: camera: sync: Add warning logs

Change-Id: I907a68185192d164a2ac5e74bbe1ba42c74a6d41
Signed-off-by: Jigarkumar Zala <jzala@codeaurora.org>
This commit is contained in:
Jigarkumar Zala 2018-09-13 11:56:52 -07:00
commit 4c33b1ae41
35 changed files with 645 additions and 127 deletions

View File

@ -19,9 +19,9 @@
cell-index = <0>;
reg = <0x00 0x00>;
compatible = "qcom,camera-flash";
flash-source = <&pm6150l_flash0>;
torch-source = <&pm6150l_torch1>;
switch-source = <&pm6150l_switch0>;
flash-source = <&pm6150l_flash0 &pm6150l_flash1>;
torch-source = <&pm6150l_torch0 &pm6150l_torch1>;
switch-source = <&pm6150l_switch2 &pm6150l_switch2>;
status = "ok";
};
@ -29,9 +29,9 @@
cell-index = <1>;
reg = <0x01 0x00>;
compatible = "qcom,camera-flash";
flash-source = <&pm6150l_flash1>;
torch-source = <&pm6150l_torch1>;
switch-source = <&pm6150l_switch1>;
flash-source = <&pm6150l_flash0 &pm6150l_flash1>;
torch-source = <&pm6150l_torch0 &pm6150l_torch1>;
switch-source = <&pm6150l_switch2 &pm6150l_switch2>;
status = "ok";
};
@ -108,7 +108,7 @@
rgltr-cntrl-support;
rgltr-min-voltage = <2800000>;
rgltr-max-voltage = <2800000>;
rgltr-load-current = <0>;
rgltr-load-current = <100000>;
};
actuator_front: qcom,actuator@1 {
@ -121,7 +121,7 @@
rgltr-cntrl-support;
rgltr-min-voltage = <2800000>;
rgltr-max-voltage = <2800000>;
rgltr-load-current = <0>;
rgltr-load-current = <100000>;
};
eeprom_rear: qcom,eeprom@0 {
@ -138,7 +138,7 @@
rgltr-cntrl-support;
rgltr-min-voltage = <1800000 2850000 1200000 0 2800000>;
rgltr-max-voltage = <1800000 2850000 1200000 0 2800000>;
rgltr-load-current = <0 80000 105000 0 0>;
rgltr-load-current = <0 80000 105000 0 100000>;
gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk0_active
@ -175,7 +175,7 @@
rgltr-cntrl-support;
rgltr-min-voltage = <1800000 2850000 1200000 0 2800000>;
rgltr-max-voltage = <1800000 2850000 1200000 0 2800000>;
rgltr-load-current = <105000 0 80000 0 0>;
rgltr-load-current = <105000 0 80000 0 100000>;
gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk1_active
@ -212,7 +212,7 @@
rgltr-cntrl-support;
rgltr-min-voltage = <1800000 2850000 1200000 0 2800000>;
rgltr-max-voltage = <1800000 2850000 1200000 0 2800000>;
rgltr-load-current = <0 80000 105000 0 0>;
rgltr-load-current = <0 80000 105000 0 100000>;
gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk2_active
@ -296,7 +296,7 @@
rgltr-cntrl-support;
rgltr-min-voltage = <1800000 2850000 1200000 0>;
rgltr-max-voltage = <1800000 2850000 1200000 0>;
rgltr-load-current = <0 80000 105000 0>;
rgltr-load-current = <105000 0 80000 0>;
gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk1_active

View File

@ -389,15 +389,18 @@
pinctrl-0 = <&cam_sensor_mclk3_active
&cam_sensor_active_iris>;
pinctrl-1 = <&cam_sensor_mclk3_suspend
&cam_sensor_active_iris>;
&cam_sensor_suspend_iris>;
gpios = <&tlmm 16 0>,
<&tlmm 23 0>;
<&tlmm 23 0>,
<&tlmm 26 0>;
gpio-reset = <1>;
gpio-req-tbl-num = <0 1>;
gpio-req-tbl-flags = <1 0>;
gpio-req-tbl-num = <0 1 2>;
gpio-req-tbl-flags = <1 0 1>;
gpio-req-tbl-label = "CAMIF_MCLK3",
"CAM_RESET3";
"CAM_RESET3",
"IMG_START";
sensor-mode = <0>;
cci-device = <1>;
cci-master = <1>;
status = "ok";
clocks = <&clock_camcc CAM_CC_MCLK3_CLK>;

View File

@ -408,7 +408,7 @@
/* IO region is approximately 3 GB */
iova-region-name = "io";
iova-region-start = <0xda00000>;
iova-region-len = <0xacdfffff>;
iova-region-len = <0xace00000>;
iova-region-id = <0x3>;
status = "ok";
};
@ -1031,11 +1031,12 @@
<&clock_camcc CAM_CC_IPE_0_CLK>;
clock-rates =
<0 0 0 300000000 0>,
<0 0 0 475000000 0>,
<0 0 0 520000000 0>,
<0 0 0 600000000 0>,
<0 0 0 600000000 0>;
clock-cntl-level = "svs", "svs_l1",
clock-cntl-level = "lowsvs", "svs", "svs_l1",
"nominal", "turbo";
status = "ok";
};
@ -1064,11 +1065,12 @@
<&clock_camcc CAM_CC_IPE_1_CLK>;
clock-rates =
<0 0 0 300000000 0>,
<0 0 0 475000000 0>,
<0 0 0 520000000 0>,
<0 0 0 600000000 0>,
<0 0 0 600000000 0>;
clock-cntl-level = "svs", "svs_l1",
clock-cntl-level = "lowsvs", "svs", "svs_l1",
"nominal", "turbo";
status = "ok";
};
@ -1097,11 +1099,12 @@
<&clock_camcc CAM_CC_BPS_CLK>;
clock-rates =
<0 0 0 200000000 0>,
<0 0 0 400000000 0>,
<0 0 0 480000000 0>,
<0 0 0 600000000 0>,
<0 0 0 600000000 0>;
clock-cntl-level = "svs", "svs_l1",
clock-cntl-level = "lowsvs", "svs", "svs_l1",
"nominal", "turbo";
status = "ok";
};

View File

@ -3879,12 +3879,12 @@
cam_sensor_active_iris: cam_sensor_active_iris {
/* RESET IRIS */
mux {
pins = "gpio23";
pins = "gpio23", "gpio26";
function = "gpio";
};
config {
pins = "gpio23";
pins = "gpio23", "gpio26";
bias-disable; /* No PULL */
drive-strength = <2>; /* 2 MA */
};
@ -3893,12 +3893,12 @@
cam_sensor_suspend_iris: cam_sensor_suspend_iris {
/* RESET IRIS */
mux {
pins = "gpio23";
pins = "gpio23", "gpio26";
function = "gpio";
};
config {
pins = "gpio23";
pins = "gpio23", "gpio26";
bias-pull-down; /* PULL DOWN */
drive-strength = <2>; /* 2 MA */
output-low;

View File

@ -163,7 +163,6 @@ int cam_context_handle_crm_apply_req(struct cam_context *ctx,
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].crm_ops.apply_req) {
rc = ctx->state_machine[ctx->state].crm_ops.apply_req(ctx,
apply);
@ -172,7 +171,6 @@ int cam_context_handle_crm_apply_req(struct cam_context *ctx,
ctx->dev_hdl, ctx->state);
rc = -EPROTO;
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}

View File

@ -275,7 +275,7 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
uint64_t packet_addr;
struct cam_packet *packet;
size_t len = 0;
int32_t i = 0;
int32_t i = 0, j = 0;
if (!ctx || !cmd) {
CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd);
@ -355,6 +355,15 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
req->status = 1;
req->req_priv = cfg.priv;
for (i = 0; i < req->num_out_map_entries; i++) {
rc = cam_sync_get_obj_ref(req->out_map_entries[i].sync_id);
if (rc) {
CAM_ERR(CAM_CTXT, "Can't get ref for sync %d",
req->out_map_entries[i].sync_id);
goto put_ref;
}
}
if (req->num_in_map_entries > 0) {
spin_lock(&ctx->lock);
list_add_tail(&req->list, &ctx->pending_req_list);
@ -365,17 +374,17 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
"[%s][%d] : Moving req[%llu] from free_list to pending_list",
ctx->dev_name, ctx->ctx_id, req->request_id);
for (i = 0; i < req->num_in_map_entries; i++) {
for (j = 0; j < req->num_in_map_entries; j++) {
cam_context_getref(ctx);
rc = cam_sync_register_callback(
cam_context_sync_callback,
(void *)req,
req->in_map_entries[i].sync_id);
req->in_map_entries[j].sync_id);
if (rc) {
CAM_ERR(CAM_CTXT,
"[%s][%d] Failed register fence cb: %d ret = %d",
ctx->dev_name, ctx->ctx_id,
req->in_map_entries[i].sync_id, rc);
req->in_map_entries[j].sync_id, rc);
spin_lock(&ctx->lock);
list_del_init(&req->list);
spin_unlock(&ctx->lock);
@ -388,16 +397,23 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
cam_context_putref(ctx);
goto free_req;
goto put_ref;
}
CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d",
req->in_map_entries[i].sync_id, rc);
req->in_map_entries[j].sync_id, rc);
}
goto end;
}
return rc;
put_ref:
for (--i; i >= 0; i--) {
rc = cam_sync_put_obj_ref(req->out_map_entries[i].sync_id);
if (rc)
CAM_ERR(CAM_CTXT, "Failed to put ref of fence %d",
req->out_map_entries[i].sync_id);
}
free_req:
spin_lock(&ctx->lock);
list_add_tail(&req->list, &ctx->free_req_list);

View File

@ -286,20 +286,30 @@ static int __cam_node_handle_release_dev(struct cam_node *node,
return -EINVAL;
}
rc = cam_context_handle_release_dev(ctx, release);
if (rc)
CAM_ERR(CAM_CORE, "context release failed node %s", node->name);
if (ctx->state > CAM_CTX_UNINIT && ctx->state < CAM_CTX_STATE_MAX) {
rc = cam_context_handle_release_dev(ctx, release);
if (rc)
CAM_ERR(CAM_CORE, "context release failed for node %s",
node->name);
} else {
CAM_WARN(CAM_CORE,
"node %s context id %u state %d invalid to release hdl",
node->name, ctx->ctx_id, ctx->state);
goto destroy_dev_hdl;
}
cam_context_putref(ctx);
destroy_dev_hdl:
rc = cam_destroy_device_hdl(release->dev_handle);
if (rc)
CAM_ERR(CAM_CORE, "destroy device handle is failed node %s",
CAM_ERR(CAM_CORE, "destroy device hdl failed for node %s",
node->name);
CAM_DBG(CAM_CORE, "[%s] Release ctx_id=%d, refcount=%d",
node->name, ctx->ctx_id,
atomic_read(&(ctx->refcount.refcount.refs)));
cam_context_putref(ctx);
return rc;
}

View File

@ -381,7 +381,7 @@ static struct cam_camnoc_specific
.value = 0x0,
},
.ubwc_ctl = {
.enable = true,
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0xd08, /* SPECIFIC_IBL_RD_DECCTL_LOW */
@ -431,11 +431,11 @@ static struct cam_camnoc_specific
.value = 0x0,
},
.ubwc_ctl = {
.enable = true,
.enable = false,
.access_type = CAM_REG_TYPE_READ_WRITE,
.masked_value = 0,
.offset = 0x1188, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
.value = 1,
.value = 0x5,
},
},
{

View File

@ -50,6 +50,7 @@
#include "cam_soc_util.h"
#include "cam_trace.h"
#include "cam_cpas_api.h"
#include "cam_common_util.h"
#define ICP_WORKQ_TASK_CMD_TYPE 1
#define ICP_WORKQ_TASK_MSG_TYPE 2
@ -3394,6 +3395,11 @@ static int cam_icp_mgr_process_io_cfg(struct cam_icp_hw_mgr *hw_mgr,
io_cfg_ptr[i].resource_type);
}
if (prepare_args->num_in_map_entries > 1)
prepare_args->num_in_map_entries =
cam_common_util_remove_duplicate_arr(
sync_in_obj, prepare_args->num_in_map_entries);
if (prepare_args->num_in_map_entries > 1) {
rc = cam_sync_merge(&sync_in_obj[0],
prepare_args->num_in_map_entries, &merged_sync_in_obj);

View File

@ -1158,7 +1158,7 @@ static int __cam_isp_ctx_apply_req_in_activated_state(
{
int rc = 0;
struct cam_ctx_request *req;
struct cam_ctx_request *active_req;
struct cam_ctx_request *active_req = NULL;
struct cam_isp_ctx_req *req_isp;
struct cam_isp_ctx_req *active_req_isp;
struct cam_isp_context *ctx_isp = NULL;
@ -1178,8 +1178,10 @@ static int __cam_isp_ctx_apply_req_in_activated_state(
*
*/
ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
spin_lock_bh(&ctx->lock);
req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
list);
spin_unlock_bh(&ctx->lock);
/*
* Check whehter the request id is matching the tip, if not, this means
@ -1202,19 +1204,25 @@ static int __cam_isp_ctx_apply_req_in_activated_state(
"Reject apply request (id %lld) due to congestion(cnt = %d)",
req->request_id,
ctx_isp->active_req_cnt);
if (!list_empty(&ctx->active_req_list)) {
spin_lock_bh(&ctx->lock);
if (!list_empty(&ctx->active_req_list))
active_req = list_first_entry(&ctx->active_req_list,
struct cam_ctx_request, list);
active_req_isp =
(struct cam_isp_ctx_req *) active_req->req_priv;
__cam_isp_ctx_handle_buf_done_fail_log(active_req_isp);
} else {
else
CAM_ERR_RATE_LIMIT(CAM_ISP,
"WARNING: should not happen (cnt = %d) but active_list empty",
ctx_isp->active_req_cnt);
spin_unlock_bh(&ctx->lock);
if (active_req) {
active_req_isp =
(struct cam_isp_ctx_req *) active_req->req_priv;
__cam_isp_ctx_handle_buf_done_fail_log(active_req_isp);
}
rc = -EFAULT;
goto end;
rc = -EFAULT;
goto end;
}
req_isp->bubble_report = apply->report_if_bubble;
@ -1996,7 +2004,7 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
static int __cam_isp_ctx_config_dev_in_top_state(
struct cam_context *ctx, struct cam_config_dev_cmd *cmd)
{
int rc = 0;
int rc = 0, i;
struct cam_ctx_request *req = NULL;
struct cam_isp_ctx_req *req_isp;
uint64_t packet_addr;
@ -2072,6 +2080,15 @@ static int __cam_isp_ctx_config_dev_in_top_state(
req_isp->num_fence_map_in = cfg.num_in_map_entries;
req_isp->num_acked = 0;
for (i = 0; i < req_isp->num_fence_map_out; i++) {
rc = cam_sync_get_obj_ref(req_isp->fence_map_out[i].sync_id);
if (rc) {
CAM_ERR(CAM_ISP, "Can't get ref for fence %d",
req_isp->fence_map_out[i].sync_id);
goto put_ref;
}
}
CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d",
req_isp->num_cfg, req_isp->num_fence_map_out,
req_isp->num_fence_map_in);
@ -2113,7 +2130,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
}
}
if (rc)
goto free_req;
goto put_ref;
CAM_DBG(CAM_REQ,
"Preprocessing Config req_id %lld successful on ctx %u",
@ -2121,6 +2138,13 @@ static int __cam_isp_ctx_config_dev_in_top_state(
return rc;
put_ref:
for (--i; i >= 0; i--) {
rc = cam_sync_put_obj_ref(req_isp->fence_map_out[i].sync_id);
if (rc)
CAM_ERR(CAM_CTXT, "Failed to put ref of fence %d",
req_isp->fence_map_out[i].sync_id);
}
free_req:
spin_lock_bh(&ctx->lock);
list_add_tail(&req->list, &ctx->free_req_list);

View File

@ -43,7 +43,7 @@
#define CAM_IFE_CSID_QTIMER_DIV_FACTOR 192
/* Max number of sof irq's triggered in case of SOF freeze */
#define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 6
#define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 12
static int cam_ife_csid_is_ipp_ppp_format_supported(
uint32_t in_format)
@ -1413,15 +1413,43 @@ static int cam_ife_csid_disable_csi2(
if (csid_hw->csi2_cfg_cnt)
return 0;
/*Disable the CSI2 rx inerrupts */
/* Disable the CSI2 rx inerrupts */
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
/* Reset the Rx CFG registers */
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
return 0;
}
static void cam_ife_csid_halt_csi2(
struct cam_ife_csid_hw *csid_hw)
{
const struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
CAM_INFO(CAM_ISP, "CSID: %d cnt: %d Halt csi2 rx",
csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
/* Disable the CSI2 rx inerrupts */
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
/* Reset the Rx CFG registers */
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
}
static int cam_ife_csid_init_config_pxl_path(
struct cam_ife_csid_hw *csid_hw,
struct cam_isp_resource_node *res)
@ -2719,6 +2747,8 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0;
uint32_t irq_status_rdi[4] = {0, 0, 0, 0};
uint32_t val, irq_status_ppp = 0;
bool fatal_err_detected = false;
uint32_t sof_irq_debug_en = 0;
csid_hw = (struct cam_ife_csid_hw *)data;
@ -2787,22 +2817,27 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 0 over flow",
csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 1 over flow",
csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 2 over flow",
csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 3 over flow",
csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW",
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW",
csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_EOT_RECEPTION",
@ -2837,6 +2872,9 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
csid_hw->hw_intf->hw_idx);
}
if (fatal_err_detected)
cam_ife_csid_halt_csi2(csid_hw);
if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) {
if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED) {
CAM_INFO_RATE_LIMIT(CAM_ISP,
@ -2957,7 +2995,7 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
CAM_ERR_RATE_LIMIT(CAM_ISP,
"CSID:%d IPP fifo over flow",
csid_hw->hw_intf->hw_idx);
/*Stop IPP path immediately */
/* Stop IPP path immediately */
cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_pxl_ctrl_addr);
@ -2990,7 +3028,7 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
CAM_ERR_RATE_LIMIT(CAM_ISP,
"CSID:%d PPP fifo over flow",
csid_hw->hw_intf->hw_idx);
/*Stop PPP path immediately */
/* Stop PPP path immediately */
cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_ctrl_addr);
@ -3021,7 +3059,7 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
CAM_ERR_RATE_LIMIT(CAM_ISP,
"CSID:%d RDI fifo over flow",
csid_hw->hw_intf->hw_idx);
/*Stop RDI path immediately */
/* Stop RDI path immediately */
cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr);
@ -3029,7 +3067,7 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
}
if (csid_hw->irq_debug_cnt >= CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX) {
cam_ife_csid_sof_irq_debug(csid_hw, 0);
cam_ife_csid_sof_irq_debug(csid_hw, &sof_irq_debug_en);
csid_hw->irq_debug_cnt = 0;
}

View File

@ -238,6 +238,7 @@ struct cam_vfe_top_irq_evt_payload {
*
* @list: list_head node for the payload
* @core_index: Index of VFE HW that generated this IRQ event
* @debug_status_0: Value of debug status_0 register at time of IRQ
* @evt_id: IRQ event
* @irq_reg_val: IRQ and Error register values, read when IRQ was
* handled
@ -248,6 +249,7 @@ struct cam_vfe_top_irq_evt_payload {
struct cam_vfe_bus_irq_evt_payload {
struct list_head list;
uint32_t core_index;
uint32_t debug_status_0;
uint32_t evt_id;
uint32_t irq_reg_val[CAM_IFE_BUS_IRQ_REGISTERS_MAX];
uint32_t error_type;

View File

@ -239,6 +239,8 @@ static struct cam_vfe_bus_ver2_hw_info vfe170_bus_hw_info = {
.addr_sync_cfg = 0x0000207C,
.addr_sync_frame_hdr = 0x00002080,
.addr_sync_no_sync = 0x00002084,
.debug_status_cfg = 0x0000226C,
.debug_status_0 = 0x00002270,
},
.num_client = 20,
.bus_client_reg = {

View File

@ -36,6 +36,8 @@ static const char drv_name[] = "vfe_bus";
#define CAM_VFE_BUS_VER2_PAYLOAD_MAX 256
#define CAM_VFE_BUS_SET_DEBUG_REG 0x82
#define CAM_VFE_RDI_BUS_DEFAULT_WIDTH 0xFF01
#define CAM_VFE_RDI_BUS_DEFAULT_STRIDE 0xFF01
#define CAM_VFE_BUS_INTRA_CLIENT_MASK 0x3
@ -208,6 +210,7 @@ struct cam_vfe_bus_ver2_priv {
uint32_t irq_handle;
uint32_t error_irq_handle;
void *tasklet_info;
};
static int cam_vfe_bus_process_cmd(
@ -1348,6 +1351,99 @@ static int cam_vfe_bus_handle_wm_done_bottom_half(void *wm_node,
return rc;
}
static int cam_vfe_bus_err_bottom_half(void *ctx_priv,
void *evt_payload_priv)
{
struct cam_vfe_bus_irq_evt_payload *evt_payload;
struct cam_vfe_bus_ver2_common_data *common_data;
uint32_t val = 0;
if (!ctx_priv || !evt_payload_priv)
return -EINVAL;
evt_payload = evt_payload_priv;
common_data = evt_payload->ctx;
val = evt_payload->debug_status_0;
CAM_ERR(CAM_ISP, "Bus Violation: debug_status_0 = 0x%x", val);
if (val & 0x01)
CAM_INFO(CAM_ISP, "RDI 0 violation");
if (val & 0x02)
CAM_INFO(CAM_ISP, "RDI 1 violation");
if (val & 0x04)
CAM_INFO(CAM_ISP, "RDI 2 violation");
if (val & 0x08)
CAM_INFO(CAM_ISP, "VID Y 1:1 UBWC violation");
if (val & 0x010)
CAM_INFO(CAM_ISP, "VID C 1:1 UBWC violation");
if (val & 0x020)
CAM_INFO(CAM_ISP, "VID YC 4:1 violation");
if (val & 0x040)
CAM_INFO(CAM_ISP, "VID YC 16:1 violation");
if (val & 0x080)
CAM_INFO(CAM_ISP, "FD Y violation");
if (val & 0x0100)
CAM_INFO(CAM_ISP, "FD C violation");
if (val & 0x0200)
CAM_INFO(CAM_ISP, "RAW DUMP violation");
if (val & 0x0400)
CAM_INFO(CAM_ISP, "PDAF violation");
if (val & 0x0800)
CAM_INFO(CAM_ISP, "STATs HDR BE violation");
if (val & 0x01000)
CAM_INFO(CAM_ISP, "STATs HDR BHIST violation");
if (val & 0x02000)
CAM_INFO(CAM_ISP, "STATs TINTLESS BG violation");
if (val & 0x04000)
CAM_INFO(CAM_ISP, "STATs BF violation");
if (val & 0x08000)
CAM_INFO(CAM_ISP, "STATs AWB BG UBWC violation");
if (val & 0x010000)
CAM_INFO(CAM_ISP, "STATs BHIST violation");
if (val & 0x020000)
CAM_INFO(CAM_ISP, "STATs RS violation");
if (val & 0x040000)
CAM_INFO(CAM_ISP, "STATs CS violation");
if (val & 0x080000)
CAM_INFO(CAM_ISP, "STATs IHIST violation");
if (val & 0x0100000)
CAM_INFO(CAM_ISP, "DISP Y 1:1 UBWC violation");
if (val & 0x0200000)
CAM_INFO(CAM_ISP, "DISP C 1:1 UBWC violation");
if (val & 0x0400000)
CAM_INFO(CAM_ISP, "DISP YC 4:1 violation");
if (val & 0x0800000)
CAM_INFO(CAM_ISP, "DISP YC 16:1 violation");
cam_vfe_bus_put_evt_payload(common_data, &evt_payload);
return 0;
}
static int cam_vfe_bus_init_wm_resource(uint32_t index,
struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
@ -2048,6 +2144,7 @@ static int cam_vfe_bus_acquire_vfe_out(void *bus_priv, void *acquire_args,
}
mutex_unlock(&rsrc_data->common_data->bus_mutex);
ver2_bus_priv->tasklet_info = acq_args->tasklet;
rsrc_data->num_wm = num_wm;
rsrc_node->res_id = out_acquire_args->out_port_info->res_type;
rsrc_node->tasklet_info = acq_args->tasklet;
@ -2389,9 +2486,10 @@ static int cam_vfe_bus_ver2_handle_irq(uint32_t evt_id,
static int cam_vfe_bus_error_irq_top_half(uint32_t evt_id,
struct cam_irq_th_payload *th_payload)
{
int i = 0;
int i = 0, rc = 0;
struct cam_vfe_bus_ver2_priv *bus_priv =
th_payload->handler_priv;
struct cam_vfe_bus_irq_evt_payload *evt_payload;
CAM_ERR_RATE_LIMIT(CAM_ISP, "Bus Err IRQ");
for (i = 0; i < th_payload->num_registers; i++) {
@ -2402,8 +2500,25 @@ static int cam_vfe_bus_error_irq_top_half(uint32_t evt_id,
cam_irq_controller_disable_irq(bus_priv->common_data.bus_irq_controller,
bus_priv->error_irq_handle);
/* Returning error stops from enqueuing bottom half */
return -EFAULT;
rc = cam_vfe_bus_get_evt_payload(&bus_priv->common_data, &evt_payload);
if (rc) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "Cannot get payload");
return rc;
}
for (i = 0; i < th_payload->num_registers; i++)
evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
evt_payload->core_index = bus_priv->common_data.core_index;
evt_payload->evt_id = evt_id;
evt_payload->ctx = &bus_priv->common_data;
evt_payload->debug_status_0 = cam_io_r_mb(
bus_priv->common_data.mem_base +
bus_priv->common_data.common_reg->debug_status_0);
th_payload->evt_payload_priv = evt_payload;
return rc;
}
static void cam_vfe_bus_update_ubwc_meta_addr(
@ -3161,15 +3276,19 @@ static int cam_vfe_bus_init_hw(void *hw_priv,
bus_error_irq_mask,
bus_priv,
cam_vfe_bus_error_irq_top_half,
NULL,
NULL,
NULL);
cam_vfe_bus_err_bottom_half,
bus_priv->tasklet_info,
&tasklet_bh_api);
if (bus_priv->irq_handle <= 0) {
CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ");
return -EFAULT;
}
/*Set Debug Registers*/
cam_io_w_mb(CAM_VFE_BUS_SET_DEBUG_REG, bus_priv->common_data.mem_base +
bus_priv->common_data.common_reg->debug_status_cfg);
/* BUS_WR_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
cam_io_w_mb(0x0, bus_priv->common_data.mem_base +
bus_priv->common_data.common_reg->addr_sync_frame_hdr);

View File

@ -87,6 +87,8 @@ struct cam_vfe_bus_ver2_reg_offset_common {
uint32_t addr_sync_cfg;
uint32_t addr_sync_frame_hdr;
uint32_t addr_sync_no_sync;
uint32_t debug_status_cfg;
uint32_t debug_status_0;
};
/*

View File

@ -211,6 +211,8 @@ static int cam_vfe_camif_resource_start(
uint32_t epoch0_irq_mask;
uint32_t epoch1_irq_mask;
uint32_t computed_epoch_line_cfg;
uint32_t camera_hw_version = 0;
int rc = 0;
if (!camif_res) {
CAM_ERR(CAM_ISP, "Error! Invalid input arguments");
@ -250,16 +252,50 @@ static int cam_vfe_camif_resource_start(
rsrc_data->common_reg->module_ctrl[
CAM_VFE_TOP_VER2_MODULE_STATS]->cgc_ovd);
/* get the HW version */
rc = cam_cpas_get_cpas_hw_version(&camera_hw_version);
if (rc) {
CAM_ERR(CAM_ISP, "Couldn't find HW version. rc: %d", rc);
return rc;
}
/* epoch config */
epoch0_irq_mask = ((rsrc_data->last_line - rsrc_data->first_line) / 2) +
rsrc_data->first_line;
epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg & 0xFFFF;
computed_epoch_line_cfg = (epoch0_irq_mask << 16) | epoch1_irq_mask;
cam_io_w_mb(computed_epoch_line_cfg,
rsrc_data->mem_base + rsrc_data->camif_reg->epoch_irq);
CAM_DBG(CAM_ISP, "first_line:%u last_line:%u epoch_line_cfg: 0x%x",
rsrc_data->first_line, rsrc_data->last_line,
computed_epoch_line_cfg);
switch (camera_hw_version) {
case CAM_CPAS_TITAN_175_V101:
case CAM_CPAS_TITAN_175_V100:
epoch0_irq_mask = ((rsrc_data->last_line -
rsrc_data->first_line) / 2) +
rsrc_data->first_line;
epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg &
0xFFFF;
computed_epoch_line_cfg = (epoch0_irq_mask << 16) |
epoch1_irq_mask;
cam_io_w_mb(computed_epoch_line_cfg,
rsrc_data->mem_base +
rsrc_data->camif_reg->epoch_irq);
CAM_DBG(CAM_ISP, "first_line: %u\n"
"last_line: %u\n"
"epoch_line_cfg: 0x%x",
rsrc_data->first_line,
rsrc_data->last_line,
computed_epoch_line_cfg);
break;
case CAM_CPAS_TITAN_170_V100:
case CAM_CPAS_TITAN_170_V110:
case CAM_CPAS_TITAN_170_V120:
cam_io_w_mb(rsrc_data->reg_data->epoch_line_cfg,
rsrc_data->mem_base +
rsrc_data->camif_reg->epoch_irq);
break;
default:
cam_io_w_mb(rsrc_data->reg_data->epoch_line_cfg,
rsrc_data->mem_base +
rsrc_data->camif_reg->epoch_irq);
CAM_WARN(CAM_ISP, "Hardware version not proper: 0x%x",
camera_hw_version);
break;
}
camif_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;

View File

@ -25,7 +25,7 @@ static int __cam_lrme_ctx_acquire_dev_in_available(struct cam_context *ctx,
uint64_t ctxt_to_hw_map = (uint64_t)ctx->ctxt_to_hw_map;
struct cam_lrme_context *lrme_ctx = ctx->ctx_priv;
CAM_DBG(CAM_LRME, "Enter");
CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = cam_context_acquire_dev_to_hw(ctx, cmd);
if (rc) {
@ -46,7 +46,7 @@ static int __cam_lrme_ctx_release_dev_in_acquired(struct cam_context *ctx,
{
int rc = 0;
CAM_DBG(CAM_LRME, "Enter");
CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = cam_context_release_dev_to_hw(ctx, cmd);
if (rc) {
@ -64,7 +64,7 @@ static int __cam_lrme_ctx_start_dev_in_acquired(struct cam_context *ctx,
{
int rc = 0;
CAM_DBG(CAM_LRME, "Enter");
CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = cam_context_start_dev_to_hw(ctx, cmd);
if (rc) {
@ -82,7 +82,7 @@ static int __cam_lrme_ctx_config_dev_in_activated(struct cam_context *ctx,
{
int rc;
CAM_DBG(CAM_LRME, "Enter");
CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = cam_context_prepare_dev_to_hw(ctx, cmd);
if (rc) {
@ -98,6 +98,8 @@ static int __cam_lrme_ctx_flush_dev_in_activated(struct cam_context *ctx,
{
int rc;
CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = cam_context_flush_dev_to_hw(ctx, cmd);
if (rc)
CAM_ERR(CAM_LRME, "Failed to flush device");
@ -109,7 +111,7 @@ static int __cam_lrme_ctx_stop_dev_in_activated(struct cam_context *ctx,
{
int rc = 0;
CAM_DBG(CAM_LRME, "Enter");
CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = cam_context_stop_dev_to_hw(ctx);
if (rc) {
@ -127,7 +129,7 @@ static int __cam_lrme_ctx_release_dev_in_activated(struct cam_context *ctx,
{
int rc = 0;
CAM_DBG(CAM_LRME, "Enter");
CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = __cam_lrme_ctx_stop_dev_in_activated(ctx, NULL);
if (rc) {
@ -182,6 +184,7 @@ static struct cam_ctx_ops
/* Acquired */
{
.ioctl_ops = {
.config_dev = __cam_lrme_ctx_config_dev_in_activated,
.release_dev = __cam_lrme_ctx_release_dev_in_acquired,
.start_dev = __cam_lrme_ctx_start_dev_in_acquired,
},

View File

@ -765,6 +765,12 @@ static int cam_lrme_mgr_hw_start(void *hw_mgr_priv, void *hw_start_args)
return -EINVAL;
}
rc = hw_device->hw_intf.hw_ops.process_cmd(
hw_device->hw_intf.hw_priv,
CAM_LRME_HW_CMD_DUMP_REGISTER,
&g_lrme_hw_mgr.debugfs_entry.dump_register,
sizeof(bool));
return rc;
}
@ -963,6 +969,35 @@ static int cam_lrme_mgr_hw_config(void *hw_mgr_priv,
return rc;
}
static int cam_lrme_mgr_create_debugfs_entry(void)
{
int rc = 0;
g_lrme_hw_mgr.debugfs_entry.dentry =
debugfs_create_dir("camera_lrme", NULL);
if (!g_lrme_hw_mgr.debugfs_entry.dentry) {
CAM_ERR(CAM_LRME, "failed to create dentry");
return -ENOMEM;
}
if (!debugfs_create_bool("dump_register",
0644,
g_lrme_hw_mgr.debugfs_entry.dentry,
&g_lrme_hw_mgr.debugfs_entry.dump_register)) {
CAM_ERR(CAM_LRME, "failed to create dump register entry");
rc = -ENOMEM;
goto err;
}
return rc;
err:
debugfs_remove_recursive(g_lrme_hw_mgr.debugfs_entry.dentry);
g_lrme_hw_mgr.debugfs_entry.dentry = NULL;
return rc;
}
int cam_lrme_mgr_register_device(
struct cam_hw_intf *lrme_hw_intf,
struct cam_iommu_handle *device_iommu,
@ -1113,6 +1148,8 @@ int cam_lrme_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf,
g_lrme_hw_mgr.event_cb = cam_lrme_dev_buf_done_cb;
cam_lrme_mgr_create_debugfs_entry();
CAM_DBG(CAM_LRME, "Hw mgr init done");
return rc;
}

View File

@ -52,12 +52,23 @@ enum cam_lrme_hw_mgr_ctx_priority {
/**
* struct cam_lrme_mgr_work_data : HW Mgr work data
*
* hw_device : Pointer to the hw device
* @hw_device : Pointer to the hw device
*/
struct cam_lrme_mgr_work_data {
struct cam_lrme_device *hw_device;
};
/**
* struct cam_lrme_debugfs_entry : debugfs entry struct
*
* @dentry : entry of debugfs
* @dump_register : flag to dump registers
*/
struct cam_lrme_debugfs_entry {
struct dentry *dentry;
bool dump_register;
};
/**
* struct cam_lrme_device : LRME HW device
*
@ -98,6 +109,7 @@ struct cam_lrme_device {
* @frame_req : List of frame request to use
* @lrme_caps : LRME capabilities
* @event_cb : IRQ callback function
* @debugfs_entry : debugfs entry to set debug prop
*/
struct cam_lrme_hw_mgr {
uint32_t device_count;
@ -110,6 +122,7 @@ struct cam_lrme_hw_mgr {
struct cam_lrme_frame_request frame_req[CAM_CTX_REQ_MAX * CAM_CTX_MAX];
struct cam_lrme_query_cap_cmd lrme_caps;
cam_hw_event_cb_func event_cb;
struct cam_lrme_debugfs_entry debugfs_entry;
};
int cam_lrme_mgr_register_device(struct cam_hw_intf *lrme_hw_intf,

View File

@ -14,6 +14,20 @@
#include "cam_lrme_hw_soc.h"
#include "cam_smmu_api.h"
static void cam_lrme_dump_registers(void __iomem *base)
{
/* dump the clc registers */
cam_io_dump(base, 0x60, (0xc0 - 0x60) / 0x4);
/* dump the fe and we registers */
cam_io_dump(base, 0x200, (0x29c - 0x200) / 0x4);
cam_io_dump(base, 0x2f0, (0x330 - 0x2f0) / 0x4);
cam_io_dump(base, 0x500, (0x5b4 - 0x500) / 0x4);
cam_io_dump(base, 0x700, (0x778 - 0x700) / 0x4);
cam_io_dump(base, 0x800, (0x878 - 0x800) / 0x4);
/* dump lrme sw registers, interrupts */
cam_io_dump(base, 0x900, (0x928 - 0x900) / 0x4);
}
static void cam_lrme_cdm_write_reg_val_pair(uint32_t *buffer,
uint32_t *index, uint32_t reg_offset, uint32_t reg_value)
{
@ -64,7 +78,8 @@ static void cam_lrme_hw_util_fill_fe_reg(struct cam_lrme_hw_io_buffer *io_buf,
cam_lrme_cdm_write_reg_val_pair(reg_val_pair, num_cmd,
hw_info->bus_rd_reg.bus_client_reg[index].unpack_cfg_0,
0x0);
else if (io_buf->io_cfg->format == CAM_FORMAT_Y_ONLY)
else if (io_buf->io_cfg->format == CAM_FORMAT_Y_ONLY ||
io_buf->io_cfg->format == CAM_FORMAT_PLAIN8)
cam_lrme_cdm_write_reg_val_pair(reg_val_pair, num_cmd,
hw_info->bus_rd_reg.bus_client_reg[index].unpack_cfg_0,
0x1);
@ -567,6 +582,8 @@ static int cam_lrme_hw_util_process_err(struct cam_hw_info *lrme_hw)
lrme_core->state);
}
cam_lrme_dump_registers(lrme_hw->soc_info.reg_map[0].mem_base);
CAM_ERR_RATE_LIMIT(CAM_LRME, "Start recovery");
lrme_core->state = CAM_LRME_CORE_STATE_RECOVERY;
rc = cam_lrme_hw_util_reset(lrme_hw, CAM_LRME_HW_RESET_TYPE_HW_RESET);
@ -610,6 +627,9 @@ static int cam_lrme_hw_util_process_reg_update(
lrme_core->req_proc = lrme_core->req_submit;
lrme_core->req_submit = NULL;
if (lrme_core->dump_flag)
cam_lrme_dump_registers(lrme_hw->soc_info.reg_map[0].mem_base);
return 0;
}
@ -654,13 +674,13 @@ void cam_lrme_set_irq(struct cam_hw_info *lrme_hw,
cam_io_w_mb(0xFFFF,
soc_info->reg_map[0].mem_base +
hw_info->titan_reg.top_irq_mask);
cam_io_w_mb(0xFFFF,
cam_io_w_mb(0xFFFFF,
soc_info->reg_map[0].mem_base +
hw_info->bus_wr_reg.common_reg.irq_mask_0);
cam_io_w_mb(0xFFFF,
cam_io_w_mb(0xFFFFF,
soc_info->reg_map[0].mem_base +
hw_info->bus_wr_reg.common_reg.irq_mask_1);
cam_io_w_mb(0xFFFF,
cam_io_w_mb(0xFFFFF,
soc_info->reg_map[0].mem_base +
hw_info->bus_rd_reg.common_reg.irq_mask);
break;
@ -952,6 +972,7 @@ int cam_lrme_hw_submit_req(void *hw_priv, void *hw_submit_args,
}
lrme_core->req_submit = frame_req;
mutex_unlock(&lrme_hw->hw_mutex);
CAM_DBG(CAM_LRME, "Release lock, submit done for req %llu",
frame_req->req_id);
@ -1235,6 +1256,14 @@ int cam_lrme_hw_process_cmd(void *hw_priv, uint32_t cmd_type,
break;
}
case CAM_LRME_HW_CMD_DUMP_REGISTER: {
struct cam_lrme_core *lrme_core =
(struct cam_lrme_core *)lrme_hw->core_info;
lrme_core->dump_flag = *(bool *)cmd_args;
CAM_DBG(CAM_LRME, "dump_flag %d", lrme_core->dump_flag);
break;
}
default:
break;
}

View File

@ -137,6 +137,7 @@ struct cam_lrme_core {
struct cam_lrme_frame_request *req_submit;
struct cam_lrme_cdm_info *hw_cdm_info;
uint32_t hw_idx;
bool dump_flag;
};
/**

View File

@ -65,11 +65,13 @@ enum cam_lrme_cb_type {
* @CAM_LRME_HW_CMD_prepare_hw_update : Prepare HW update
* @CAM_LRME_HW_CMD_REGISTER_CB : register HW manager callback
* @CAM_LRME_HW_CMD_SUBMIT : Submit frame to HW
* @CAM_LRME_HW_CMD_DUMP_REGISTER : dump register values
*/
enum cam_lrme_hw_cmd_type {
CAM_LRME_HW_CMD_PREPARE_HW_UPDATE,
CAM_LRME_HW_CMD_REGISTER_CB,
CAM_LRME_HW_CMD_SUBMIT,
CAM_LRME_HW_CMD_DUMP_REGISTER,
};
/**

View File

@ -244,37 +244,42 @@ int cam_mem_get_cpu_buf(int32_t buf_handle, uint64_t *vaddr_ptr, size_t *len)
if (!tbl.bufq[idx].active)
return -EPERM;
mutex_lock(&tbl.bufq[idx].q_lock);
if (buf_handle != tbl.bufq[idx].buf_handle) {
rc = -EINVAL;
goto exit_func;
}
dmabuf = tbl.bufq[idx].dma_buf;
if (!dmabuf) {
CAM_ERR(CAM_MEM, "Invalid DMA buffer pointer");
if (!(tbl.bufq[idx].flags & CAM_MEM_FLAG_KMD_ACCESS)) {
rc = -EINVAL;
goto exit_func;
}
if (tbl.bufq[idx].flags & CAM_MEM_FLAG_KMD_ACCESS) {
if (!tbl.bufq[idx].kmdvaddr) {
rc = cam_mem_util_map_cpu_va(dmabuf,
&kvaddr, &klen);
if (rc)
goto exit_func;
tbl.bufq[idx].kmdvaddr = kvaddr;
if (!tbl.bufq[idx].kmdvaddr) {
mutex_lock(&tbl.bufq[idx].q_lock);
dmabuf = tbl.bufq[idx].dma_buf;
if (!dmabuf) {
CAM_ERR(CAM_MEM, "Invalid DMA buffer pointer");
rc = -EINVAL;
goto release_mutex;
}
} else {
rc = -EINVAL;
goto exit_func;
rc = cam_mem_util_map_cpu_va(dmabuf,
&kvaddr, &klen);
if (rc)
goto release_mutex;
tbl.bufq[idx].kmdvaddr = kvaddr;
mutex_unlock(&tbl.bufq[idx].q_lock);
}
*vaddr_ptr = tbl.bufq[idx].kmdvaddr;
*len = tbl.bufq[idx].len;
exit_func:
return rc;
release_mutex:
mutex_unlock(&tbl.bufq[idx].q_lock);
exit_func:
return rc;
}
EXPORT_SYMBOL(cam_mem_get_cpu_buf);

View File

@ -584,7 +584,6 @@ EXPORT_SYMBOL(cam_unregister_subdev);
static int cam_req_mgr_remove(struct platform_device *pdev)
{
cam_req_mgr_core_device_deinit();
cam_mem_mgr_deinit();
cam_req_mgr_util_deinit();
cam_media_device_cleanup();
cam_video_device_cleanup();
@ -624,12 +623,6 @@ static int cam_req_mgr_probe(struct platform_device *pdev)
goto req_mgr_util_fail;
}
rc = cam_mem_mgr_init();
if (rc) {
CAM_ERR(CAM_CRM, "mem mgr init failed");
goto mem_mgr_init_fail;
}
rc = cam_req_mgr_core_device_init();
if (rc) {
CAM_ERR(CAM_CRM, "core device setup failed");
@ -654,8 +647,6 @@ static int cam_req_mgr_probe(struct platform_device *pdev)
return rc;
req_mgr_core_fail:
cam_mem_mgr_deinit();
mem_mgr_init_fail:
cam_req_mgr_util_deinit();
req_mgr_util_fail:
mutex_destroy(&g_dev.dev_lock);

View File

@ -352,8 +352,10 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev)
CAM_DBG(CAM_CSIPHY, "Do Nothing");
break;
}
usleep_range(reg_array[lane_pos][i].delay*1000,
reg_array[lane_pos][i].delay*1000 + 1000);
if (reg_array[lane_pos][i].delay > 0) {
usleep_range(reg_array[lane_pos][i].delay*1000,
reg_array[lane_pos][i].delay*1000 + 10);
}
}
lane_mask >>= 1;
lane_pos++;

View File

@ -261,7 +261,10 @@ static int cam_eeprom_i2c_driver_remove(struct i2c_client *client)
for (i = 0; i < soc_info->num_clk; i++)
devm_clk_put(soc_info->dev, soc_info->clk[i]);
mutex_destroy(&(e_ctrl->eeprom_mutex));
kfree(soc_private);
kfree(e_ctrl->io_master_info.cci_client);
v4l2_set_subdevdata(&e_ctrl->v4l2_dev_str.sd, NULL);
kfree(e_ctrl);
return 0;
@ -392,6 +395,8 @@ static int cam_eeprom_spi_driver_remove(struct spi_device *sdev)
kfree(soc_private->power_info.gpio_num_info);
kfree(soc_private);
}
mutex_destroy(&(e_ctrl->eeprom_mutex));
v4l2_set_subdevdata(&e_ctrl->v4l2_dev_str.sd, NULL);
kfree(e_ctrl);
return 0;
@ -487,8 +492,11 @@ static int cam_eeprom_platform_driver_remove(struct platform_device *pdev)
for (i = 0; i < soc_info->num_clk; i++)
devm_clk_put(soc_info->dev, soc_info->clk[i]);
mutex_destroy(&(e_ctrl->eeprom_mutex));
kfree(soc_info->soc_private);
kfree(e_ctrl->io_master_info.cci_client);
platform_set_drvdata(pdev, NULL);
v4l2_set_subdevdata(&e_ctrl->v4l2_dev_str.sd, NULL);
kfree(e_ctrl);
return 0;
}

View File

@ -371,12 +371,12 @@ int cam_flash_apply_setting(struct cam_flash_ctrl *fctrl,
if (flash_data->opcode ==
CAMERA_SENSOR_FLASH_OP_FIREHIGH) {
if (fctrl->flash_state !=
CAM_FLASH_STATE_CONFIG) {
if (fctrl->flash_state ==
CAM_FLASH_STATE_START) {
CAM_WARN(CAM_FLASH,
"Cannot apply Start Dev:Prev state: %d",
"Wrong state :Prev state: %d",
fctrl->flash_state);
return rc;
return -EINVAL;
}
rc = cam_flash_prepare(fctrl, true);
if (rc) {
@ -387,8 +387,27 @@ int cam_flash_apply_setting(struct cam_flash_ctrl *fctrl,
rc = cam_flash_high(fctrl, flash_data);
if (rc)
CAM_ERR(CAM_FLASH,
"FLASH ON failed : %d",
rc);
"FLASH ON failed : %d", rc);
}
if (flash_data->opcode ==
CAMERA_SENSOR_FLASH_OP_FIRELOW) {
if (fctrl->flash_state ==
CAM_FLASH_STATE_START) {
CAM_WARN(CAM_FLASH,
"Wrong state :Prev state: %d",
fctrl->flash_state);
return -EINVAL;
}
rc = cam_flash_prepare(fctrl, true);
if (rc) {
CAM_ERR(CAM_FLASH,
"Enable Regulator Failed rc = %d", rc);
return rc;
}
rc = cam_flash_low(fctrl, flash_data);
if (rc)
CAM_ERR(CAM_FLASH,
"TORCH ON failed : %d", rc);
}
if (flash_data->opcode ==
CAMERA_SENSOR_FLASH_OP_OFF) {
@ -617,7 +636,7 @@ int cam_flash_parser(struct cam_flash_ctrl *fctrl, void *arg)
CAM_FLASH_STATE_CONFIG;
break;
case CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_FIRE:
CAM_DBG(CAM_FLASH, "Widget Flash Operation");
CAM_DBG(CAM_FLASH, "INIT Fire Operation");
flash_operation_info =
(struct cam_flash_set_on_off *) cmd_buf;
fctrl->nrt_info.cmn_attr.count =

View File

@ -149,17 +149,15 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
goto release_mutex;
}
rc = cam_flash_prepare(fctrl, true);
if (rc) {
CAM_ERR(CAM_FLASH,
"Enable Regulator Failed rc = %d", rc);
goto release_mutex;
}
rc = cam_flash_apply_setting(fctrl, 0);
if (rc) {
CAM_ERR(CAM_FLASH, "cannot apply settings rc = %d", rc);
goto release_mutex;
if (fctrl->is_regulator_enabled == false) {
rc = cam_flash_prepare(fctrl, true);
if (rc) {
CAM_ERR(CAM_FLASH,
"Enable Regulator Failed rc = %d", rc);
goto release_mutex;
}
}
fctrl->flash_state = CAM_FLASH_STATE_START;
break;
}

View File

@ -662,6 +662,15 @@ void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl)
o_ctrl->bridge_intf.session_hdl = -1;
}
if (o_ctrl->i2c_mode_data.is_settings_valid == 1)
delete_request(&o_ctrl->i2c_mode_data);
if (o_ctrl->i2c_calib_data.is_settings_valid == 1)
delete_request(&o_ctrl->i2c_calib_data);
if (o_ctrl->i2c_init_data.is_settings_valid == 1)
delete_request(&o_ctrl->i2c_init_data);
kfree(power_info->power_setting);
kfree(power_info->power_down_setting);
power_info->power_setting = NULL;
@ -779,6 +788,16 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg)
power_info->power_down_setting = NULL;
power_info->power_down_setting_size = 0;
power_info->power_setting_size = 0;
if (o_ctrl->i2c_mode_data.is_settings_valid == 1)
delete_request(&o_ctrl->i2c_mode_data);
if (o_ctrl->i2c_calib_data.is_settings_valid == 1)
delete_request(&o_ctrl->i2c_calib_data);
if (o_ctrl->i2c_init_data.is_settings_valid == 1)
delete_request(&o_ctrl->i2c_init_data);
break;
case CAM_STOP_DEV:
if (o_ctrl->cam_ois_state != CAM_OIS_START) {

View File

@ -18,6 +18,7 @@
#include <linux/debugfs.h>
#include "cam_sync_util.h"
#include "cam_debug_util.h"
#include "cam_common_util.h"
struct sync_device *sync_dev;
@ -221,6 +222,11 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status)
return -EINVAL;
}
if (!atomic_dec_and_test(&row->ref_cnt)) {
spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
return 0;
}
row->state = status;
cam_sync_util_dispatch_signaled_cb(sync_obj, status);
@ -284,6 +290,12 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj)
return -EINVAL;
}
if (cam_common_util_remove_duplicate_arr(sync_obj, num_objs)
!= num_objs) {
CAM_ERR(CAM_SYNC, "The obj list has duplicate fence");
return -EINVAL;
}
do {
idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS);
if (idx >= CAM_SYNC_MAX_OBJS)
@ -309,6 +321,46 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj)
return 0;
}
int cam_sync_get_obj_ref(int32_t sync_obj)
{
struct sync_table_row *row = NULL;
if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0)
return -EINVAL;
row = sync_dev->sync_table + sync_obj;
spin_lock(&sync_dev->row_spinlocks[sync_obj]);
if (row->state != CAM_SYNC_STATE_ACTIVE) {
spin_unlock(&sync_dev->row_spinlocks[sync_obj]);
CAM_ERR(CAM_SYNC,
"Error: accessing an uninitialized sync obj = %d",
sync_obj);
return -EINVAL;
}
atomic_inc(&row->ref_cnt);
spin_unlock(&sync_dev->row_spinlocks[sync_obj]);
CAM_DBG(CAM_SYNC, "get ref for obj %d", sync_obj);
return 0;
}
int cam_sync_put_obj_ref(int32_t sync_obj)
{
struct sync_table_row *row = NULL;
if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0)
return -EINVAL;
row = sync_dev->sync_table + sync_obj;
atomic_dec(&row->ref_cnt);
CAM_DBG(CAM_SYNC, "put ref for obj %d", sync_obj);
return 0;
}
int cam_sync_destroy(int32_t sync_obj)
{
CAM_DBG(CAM_SYNC, "sync_obj: %i", sync_obj);
@ -405,6 +457,8 @@ static int cam_sync_handle_signal(struct cam_private_ioctl_arg *k_ioctl)
k_ioctl->size))
return -EFAULT;
/* need to get ref for UMD signaled fences */
cam_sync_get_obj_ref(sync_signal.sync_obj);
return cam_sync_signal(sync_signal.sync_obj,
sync_signal.sync_state);
}

View File

@ -100,6 +100,29 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status);
*/
int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj);
/**
* @brief: get ref count of sync obj
*
* This function will increment ref count for the sync object, and the ref
* count will be decremented when this sync object is signaled.
*
* @param sync_obj: sync object
*
* @return Status of operation. Negative in case of error. Zero otherwise.
*/
int cam_sync_get_obj_ref(int32_t sync_obj);
/**
* @brief: put ref count of sync obj
*
* This function will decrement ref count for the sync object.
*
* @param sync_obj: sync object
*
* @return Status of operation. Negative in case of error. Zero otherwise.
*/
int cam_sync_put_obj_ref(int32_t sync_obj);
/**
* @brief: Destroys a sync object
*

View File

@ -139,6 +139,7 @@ struct sync_user_payload {
* @signaled : Completion variable on which block calls will wait
* @callback_list : Linked list of kernel callbacks registered
* @user_payload_list : LInked list of user space payloads registered
* @ref_cnt : ref count of the number of usage of the fence.
*/
struct sync_table_row {
char name[CAM_SYNC_OBJ_NAME_LEN];
@ -153,6 +154,7 @@ struct sync_table_row {
struct completion signaled;
struct list_head callback_list;
struct list_head user_payload_list;
atomic_t ref_cnt;
};
/**

View File

@ -49,6 +49,7 @@ int cam_sync_init_row(struct sync_table_row *table,
row->sync_id = idx;
row->state = CAM_SYNC_STATE_ACTIVE;
row->remaining = 0;
atomic_set(&row->ref_cnt, 0);
init_completion(&row->signaled);
INIT_LIST_HEAD(&row->callback_list);
INIT_LIST_HEAD(&row->user_payload_list);
@ -175,6 +176,12 @@ int cam_sync_deinit_object(struct sync_table_row *table, uint32_t idx)
idx);
return -EINVAL;
}
if (row->state == CAM_SYNC_STATE_ACTIVE)
CAM_WARN(CAM_SYNC,
"Destroying an active sync object name:%s id:%i",
row->name, row->sync_id);
row->state = CAM_SYNC_STATE_INVALID;
/* Object's child and parent objects will be added into this list */
@ -217,6 +224,11 @@ int cam_sync_deinit_object(struct sync_table_row *table, uint32_t idx)
continue;
}
if (child_row->state == CAM_SYNC_STATE_ACTIVE)
CAM_WARN(CAM_SYNC,
"Warning: destroying active child sync obj = %d",
child_info->sync_id);
cam_sync_util_cleanup_parents_list(child_row,
SYNC_LIST_CLEAN_ONE, idx);
@ -241,6 +253,11 @@ int cam_sync_deinit_object(struct sync_table_row *table, uint32_t idx)
continue;
}
if (parent_row->state == CAM_SYNC_STATE_ACTIVE)
CAM_WARN(CAM_SYNC,
"Warning: destroying active parent sync obj = %d",
parent_info->sync_id);
cam_sync_util_cleanup_children_list(parent_row,
SYNC_LIST_CLEAN_ONE, idx);

View File

@ -33,3 +33,25 @@ int cam_common_util_get_string_index(const char **strings,
return -EINVAL;
}
uint32_t cam_common_util_remove_duplicate_arr(int32_t *arr, uint32_t num)
{
int i, j;
uint32_t wr_idx = 1;
if (!arr) {
CAM_ERR(CAM_UTIL, "Null input array");
return 0;
}
for (i = 1; i < num; i++) {
for (j = 0; j < wr_idx ; j++) {
if (arr[i] == arr[j])
break;
}
if (j == wr_idx)
arr[wr_idx++] = arr[i];
}
return wr_idx;
}

View File

@ -32,4 +32,18 @@
int cam_common_util_get_string_index(const char **strings,
uint32_t num_strings, char *matching_string, uint32_t *index);
/**
* cam_common_util_remove_duplicate_arr()
*
* @brief Move all the unique integers to the start of
* the array and return the number of unique integers
*
* @array: Pointer to the first integer of array
* @num: Number of elements in array
*
* @return: Number of unique integers in array
*/
uint32_t cam_common_util_remove_duplicate_arr(int32_t *array,
uint32_t num);
#endif /* _CAM_COMMON_UTIL_H_ */