mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
Merge "msm: camera: isp: Change csid stop sequence during flush" into camera-kernel.lnx.4.0
This commit is contained in:
commit
4e289c6238
6 changed files with 227 additions and 65 deletions
|
|
@ -897,6 +897,52 @@ static void cam_ife_hw_mgr_dump_acq_data(
|
|||
}
|
||||
}
|
||||
|
||||
static int cam_ife_mgr_csid_change_halt_mode(struct cam_ife_hw_mgr_ctx *ctx,
|
||||
enum cam_ife_csid_halt_mode halt_mode)
|
||||
{
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_isp_resource_node *isp_res;
|
||||
struct cam_ife_csid_hw_halt_args halt;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
uint32_t i;
|
||||
int rc = 0;
|
||||
|
||||
if (!ctx->is_dual)
|
||||
return 0;
|
||||
|
||||
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
|
||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||
if (i == CAM_ISP_HW_SPLIT_LEFT)
|
||||
continue;
|
||||
|
||||
if (!hw_mgr_res->hw_res[i] ||
|
||||
(hw_mgr_res->hw_res[i]->res_state !=
|
||||
CAM_ISP_RESOURCE_STATE_STREAMING))
|
||||
continue;
|
||||
|
||||
isp_res = hw_mgr_res->hw_res[i];
|
||||
|
||||
if ((isp_res->res_type == CAM_ISP_RESOURCE_PIX_PATH) &&
|
||||
(isp_res->res_id == CAM_IFE_PIX_PATH_RES_IPP)) {
|
||||
hw_intf = isp_res->hw_intf;
|
||||
halt.node_res = isp_res;
|
||||
halt.halt_mode = halt_mode;
|
||||
rc = hw_intf->hw_ops.process_cmd(
|
||||
hw_intf->hw_priv,
|
||||
CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE,
|
||||
&halt,
|
||||
sizeof(
|
||||
struct cam_ife_csid_hw_halt_args));
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP, "Halt update failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_mgr_csid_stop_hw(
|
||||
struct cam_ife_hw_mgr_ctx *ctx, struct list_head *stop_list,
|
||||
uint32_t base_idx, uint32_t stop_cmd)
|
||||
|
|
@ -4074,6 +4120,13 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
|
|||
*/
|
||||
if (i == ctx->num_base)
|
||||
master_base_idx = ctx->base[0].idx;
|
||||
|
||||
/*Change slave mode*/
|
||||
if (csid_halt_type == CAM_CSID_HALT_IMMEDIATELY)
|
||||
cam_ife_mgr_csid_change_halt_mode(ctx,
|
||||
CAM_CSID_HALT_MODE_INTERNAL);
|
||||
|
||||
|
||||
CAM_DBG(CAM_ISP, "Stopping master CSID idx %d", master_base_idx);
|
||||
|
||||
/* Stop the master CSID path first */
|
||||
|
|
|
|||
|
|
@ -532,26 +532,30 @@ static int cam_tfe_hw_mgr_free_hw_res(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_tfe_mgr_csid_change_halt_mode(struct list_head *halt_list,
|
||||
uint32_t base_idx, enum cam_tfe_csid_halt_mode halt_mode)
|
||||
static int cam_tfe_mgr_csid_change_halt_mode(struct cam_tfe_hw_mgr_ctx *ctx,
|
||||
enum cam_tfe_csid_halt_mode halt_mode)
|
||||
{
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_isp_resource_node *isp_res;
|
||||
struct cam_csid_hw_halt_args halt;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_isp_resource_node *isp_res;
|
||||
struct cam_tfe_csid_hw_halt_args halt;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
uint32_t i;
|
||||
int rc = 0;
|
||||
|
||||
list_for_each_entry(hw_mgr_res, halt_list, list) {
|
||||
if (!ctx->is_dual)
|
||||
return 0;
|
||||
|
||||
list_for_each_entry(hw_mgr_res, &ctx->res_list_tfe_csid, list) {
|
||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||
if (i == CAM_ISP_HW_SPLIT_LEFT)
|
||||
continue;
|
||||
|
||||
if (!hw_mgr_res->hw_res[i] ||
|
||||
(hw_mgr_res->hw_res[i]->res_state !=
|
||||
CAM_ISP_RESOURCE_STATE_STREAMING))
|
||||
continue;
|
||||
|
||||
isp_res = hw_mgr_res->hw_res[i];
|
||||
if (isp_res->hw_intf->hw_idx != base_idx)
|
||||
continue;
|
||||
|
||||
if ((isp_res->res_type == CAM_ISP_RESOURCE_PIX_PATH) &&
|
||||
(isp_res->res_id ==
|
||||
|
|
@ -563,7 +567,8 @@ static int cam_tfe_mgr_csid_change_halt_mode(struct list_head *halt_list,
|
|||
hw_intf->hw_priv,
|
||||
CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE,
|
||||
&halt,
|
||||
sizeof(struct cam_csid_hw_halt_args));
|
||||
sizeof(
|
||||
struct cam_tfe_csid_hw_halt_args));
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP, "Halt update failed");
|
||||
break;
|
||||
|
|
@ -2798,16 +2803,9 @@ static int cam_tfe_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
|
|||
master_base_idx = ctx->base[0].idx;
|
||||
|
||||
/*Change slave mode*/
|
||||
if (csid_halt_type == CAM_CSID_HALT_IMMEDIATELY) {
|
||||
for (i = 0; i < ctx->num_base; i++) {
|
||||
if (ctx->base[i].idx == master_base_idx)
|
||||
continue;
|
||||
cam_tfe_mgr_csid_change_halt_mode(
|
||||
&ctx->res_list_tfe_csid,
|
||||
ctx->base[i].idx,
|
||||
CAM_TFE_CSID_HALT_MODE_INTERNAL);
|
||||
}
|
||||
}
|
||||
if (csid_halt_type == CAM_CSID_HALT_IMMEDIATELY)
|
||||
cam_tfe_mgr_csid_change_halt_mode(ctx,
|
||||
CAM_TFE_CSID_HALT_MODE_INTERNAL);
|
||||
|
||||
CAM_DBG(CAM_ISP, "Stopping master CSID idx %d", master_base_idx);
|
||||
|
||||
|
|
|
|||
|
|
@ -2344,6 +2344,52 @@ static int cam_ife_csid_enable_pxl_path(
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int cam_ife_csid_change_pxl_halt_mode(
|
||||
struct cam_ife_csid_hw *csid_hw,
|
||||
struct cam_ife_csid_hw_halt_args *csid_halt)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
const struct cam_ife_csid_reg_offset *csid_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
const struct cam_ife_csid_pxl_reg_offset *pxl_reg;
|
||||
struct cam_isp_resource_node *res;
|
||||
|
||||
res = csid_halt->node_res;
|
||||
|
||||
csid_reg = csid_hw->csid_info->csid_reg;
|
||||
soc_info = &csid_hw->hw_info->soc_info;
|
||||
|
||||
if (res->res_id != CAM_IFE_PIX_PATH_RES_IPP) {
|
||||
CAM_ERR(CAM_ISP, "CSID:%d Invalid res id %d",
|
||||
csid_hw->hw_intf->hw_idx, res->res_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
|
||||
CAM_ERR(CAM_ISP, "CSID:%d Res:%d in invalid state:%d",
|
||||
csid_hw->hw_intf->hw_idx, res->res_id, res->res_state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pxl_reg = csid_reg->ipp_reg;
|
||||
|
||||
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
|
||||
pxl_reg->csid_pxl_irq_mask_addr);
|
||||
|
||||
/* configure Halt for slave */
|
||||
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
pxl_reg->csid_pxl_ctrl_addr);
|
||||
val &= ~0xC;
|
||||
val |= (csid_halt->halt_mode << 2);
|
||||
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||
pxl_reg->csid_pxl_ctrl_addr);
|
||||
CAM_DBG(CAM_ISP, "CSID:%d IPP path Res halt mode:%d configured:%x",
|
||||
csid_hw->hw_intf->hw_idx, csid_halt->halt_mode, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_ife_csid_disable_pxl_path(
|
||||
struct cam_ife_csid_hw *csid_hw,
|
||||
struct cam_isp_resource_node *res,
|
||||
|
|
@ -3977,6 +4023,47 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int cam_ife_csid_halt(struct cam_ife_csid_hw *csid_hw,
|
||||
void *halt_args)
|
||||
{
|
||||
struct cam_isp_resource_node *res;
|
||||
struct cam_ife_csid_hw_halt_args *csid_halt;
|
||||
int rc = 0;
|
||||
|
||||
if (!csid_hw || !halt_args) {
|
||||
CAM_ERR(CAM_ISP, "CSID: Invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
csid_halt = (struct cam_ife_csid_hw_halt_args *)halt_args;
|
||||
|
||||
/* Change the halt mode */
|
||||
res = csid_halt->node_res;
|
||||
CAM_DBG(CAM_ISP, "CSID:%d res_type %d res_id %d",
|
||||
csid_hw->hw_intf->hw_idx,
|
||||
res->res_type, res->res_id);
|
||||
|
||||
if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) {
|
||||
CAM_ERR(CAM_ISP, "CSID:%d Invalid res type %d",
|
||||
csid_hw->hw_intf->hw_idx,
|
||||
res->res_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (res->res_id) {
|
||||
case CAM_IFE_PIX_PATH_RES_IPP:
|
||||
rc = cam_ife_csid_change_pxl_halt_mode(csid_hw, csid_halt);
|
||||
break;
|
||||
default:
|
||||
CAM_DBG(CAM_ISP, "CSID:%d res_id %d",
|
||||
csid_hw->hw_intf->hw_idx,
|
||||
res->res_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_ife_csid_stop(void *hw_priv,
|
||||
void *stop_args, uint32_t arg_size)
|
||||
{
|
||||
|
|
@ -4450,6 +4537,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv,
|
|||
case CAM_IFE_CSID_LOG_ACQUIRE_DATA:
|
||||
rc = cam_ife_csid_log_acquire_data(csid_hw, cmd_args);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE:
|
||||
rc = cam_ife_csid_halt(csid_hw, cmd_args);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
|
||||
csid_hw->hw_intf->hw_idx, cmd_type);
|
||||
|
|
|
|||
|
|
@ -156,6 +156,33 @@ enum cam_ife_csid_halt_cmd {
|
|||
CAM_CSID_HALT_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum cam_ife_csid_halt_mode - Specify the halt command type
|
||||
*/
|
||||
enum cam_ife_csid_halt_mode {
|
||||
CAM_CSID_HALT_MODE_INTERNAL,
|
||||
CAM_CSID_HALT_MODE_GLOBAL,
|
||||
CAM_CSID_HALT_MODE_MASTER,
|
||||
CAM_CSID_HALT_MODE_SLAVE,
|
||||
CAM_CSID_HALT_MODE_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_ife_csid_hw_halt_args
|
||||
* @halt_mode : Applicable only for PATH resources
|
||||
* 0 Internal : The CSID responds to the HALT_CMD
|
||||
* 1 Global : The CSID responds to the GLOBAL_HALT_CMD
|
||||
* 2 Master : The CSID responds to the HALT_CMD
|
||||
* 3 Slave : The CSID responds to the external halt command
|
||||
* and not the HALT_CMD register
|
||||
* @node_res : reource pointer array( ie cid or CSID)
|
||||
*
|
||||
*/
|
||||
struct cam_ife_csid_hw_halt_args {
|
||||
enum cam_ife_csid_halt_mode halt_mode;
|
||||
struct cam_isp_resource_node *node_res;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_csid_hw_stop- stop all resources
|
||||
* @stop_cmd : Applicable only for PATH resources
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ enum cam_tfe_csid_halt_cmd {
|
|||
};
|
||||
|
||||
/**
|
||||
* enum cam_tfe_csid_halt_mode_cmd - Specify the halt command type
|
||||
* enum cam_tfe_csid_halt_mode - Specify the halt command type
|
||||
*/
|
||||
enum cam_tfe_csid_halt_mode {
|
||||
CAM_TFE_CSID_HALT_MODE_INTERNAL,
|
||||
|
|
@ -107,7 +107,7 @@ enum cam_tfe_csid_halt_mode {
|
|||
};
|
||||
|
||||
/**
|
||||
* struct cam_csid_hw_halt_args
|
||||
* struct cam_tfe_csid_hw_halt_args
|
||||
* @halt_mode : Applicable only for PATH resources
|
||||
* 0 Internal : The CSID responds to the HALT_CMD
|
||||
* 1 Global : The CSID responds to the GLOBAL_HALT_CMD
|
||||
|
|
@ -117,9 +117,9 @@ enum cam_tfe_csid_halt_mode {
|
|||
* @node_res : reource pointer array( ie cid or CSID)
|
||||
*
|
||||
*/
|
||||
struct cam_csid_hw_halt_args {
|
||||
enum cam_tfe_csid_halt_mode halt_mode;
|
||||
struct cam_isp_resource_node *node_res;
|
||||
struct cam_tfe_csid_hw_halt_args {
|
||||
enum cam_tfe_csid_halt_mode halt_mode;
|
||||
struct cam_isp_resource_node *node_res;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1257,49 +1257,35 @@ static int cam_tfe_csid_enable_pxl_path(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void cam_tfe_csid_change_pxl_halt_mode(
|
||||
struct cam_tfe_csid_hw *csid_hw,
|
||||
struct cam_isp_resource_node *res,
|
||||
enum cam_tfe_csid_halt_mode halt_mode)
|
||||
static int cam_tfe_csid_change_pxl_halt_mode(
|
||||
struct cam_tfe_csid_hw *csid_hw,
|
||||
struct cam_tfe_csid_hw_halt_args *csid_halt)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
const struct cam_tfe_csid_reg_offset *csid_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
struct cam_tfe_csid_path_cfg *path_data;
|
||||
const struct cam_tfe_csid_pxl_reg_offset *pxl_reg;
|
||||
bool is_ipp;
|
||||
struct cam_isp_resource_node *res;
|
||||
|
||||
res = csid_halt->node_res;
|
||||
|
||||
path_data = (struct cam_tfe_csid_path_cfg *) res->res_priv;
|
||||
csid_reg = csid_hw->csid_info->csid_reg;
|
||||
soc_info = &csid_hw->hw_info->soc_info;
|
||||
|
||||
if (res->res_id >= CAM_TFE_CSID_PATH_RES_MAX) {
|
||||
CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d",
|
||||
if (res->res_id != CAM_TFE_CSID_PATH_RES_IPP) {
|
||||
CAM_ERR(CAM_ISP, "CSID:%d Invalid res id %d",
|
||||
csid_hw->hw_intf->hw_idx, res->res_id);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
|
||||
res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
|
||||
CAM_ERR(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
|
||||
csid_hw->hw_intf->hw_idx, res->res_id, res->res_state);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) {
|
||||
is_ipp = true;
|
||||
pxl_reg = csid_reg->ipp_reg;
|
||||
} else {
|
||||
goto end;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
|
||||
CAM_ERR(CAM_ISP, "CSID:%d %s path Res:%d Invalid state%d",
|
||||
csid_hw->hw_intf->hw_idx, "IPP",
|
||||
res->res_id, res->res_state);
|
||||
goto end;
|
||||
CAM_ERR(CAM_ISP, "CSID:%d Res:%d in invalid state:%d",
|
||||
csid_hw->hw_intf->hw_idx, res->res_id, res->res_state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pxl_reg = csid_reg->ipp_reg;
|
||||
|
||||
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
|
||||
pxl_reg->csid_pxl_irq_mask_addr);
|
||||
|
||||
|
|
@ -1307,11 +1293,13 @@ static void cam_tfe_csid_change_pxl_halt_mode(
|
|||
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
pxl_reg->csid_pxl_ctrl_addr);
|
||||
val &= ~0xC;
|
||||
val |= (halt_mode << 2);
|
||||
val |= (csid_halt->halt_mode << 2);
|
||||
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||
pxl_reg->csid_pxl_ctrl_addr);
|
||||
end:
|
||||
return;
|
||||
CAM_DBG(CAM_ISP, "CSID:%d IPP path Res halt mode:%d configured:%x",
|
||||
csid_hw->hw_intf->hw_idx, csid_halt->halt_mode, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_tfe_csid_disable_pxl_path(
|
||||
|
|
@ -2211,14 +2199,15 @@ int cam_tfe_csid_halt(struct cam_tfe_csid_hw *csid_hw,
|
|||
void *halt_args)
|
||||
{
|
||||
struct cam_isp_resource_node *res;
|
||||
struct cam_csid_hw_halt_args *csid_halt;
|
||||
struct cam_tfe_csid_hw_halt_args *csid_halt;
|
||||
int rc = 0;
|
||||
|
||||
if (!csid_hw || !halt_args) {
|
||||
CAM_ERR(CAM_ISP, "CSID: Invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
csid_halt = (struct cam_csid_hw_halt_args *)halt_args;
|
||||
csid_halt = (struct cam_tfe_csid_hw_halt_args *)halt_args;
|
||||
|
||||
/* Change the halt mode */
|
||||
res = csid_halt->node_res;
|
||||
|
|
@ -2226,20 +2215,25 @@ int cam_tfe_csid_halt(struct cam_tfe_csid_hw *csid_hw,
|
|||
csid_hw->hw_intf->hw_idx,
|
||||
res->res_type, res->res_id);
|
||||
|
||||
switch (res->res_type) {
|
||||
case CAM_ISP_RESOURCE_PIX_PATH:
|
||||
if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP)
|
||||
cam_tfe_csid_change_pxl_halt_mode(csid_hw, res,
|
||||
csid_halt->halt_mode);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
|
||||
if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) {
|
||||
CAM_ERR(CAM_ISP, "CSID:%d Invalid res type %d",
|
||||
csid_hw->hw_intf->hw_idx,
|
||||
res->res_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (res->res_id) {
|
||||
case CAM_TFE_CSID_PATH_RES_IPP:
|
||||
rc = cam_tfe_csid_change_pxl_halt_mode(csid_hw, csid_halt);
|
||||
break;
|
||||
default:
|
||||
CAM_DBG(CAM_ISP, "CSID:%d res_id %d",
|
||||
csid_hw->hw_intf->hw_idx,
|
||||
res->res_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_tfe_csid_stop(void *hw_priv,
|
||||
|
|
|
|||
Loading…
Reference in a new issue