mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 22:40:54 -04:00
Merge "msm: camera: tfe: Change csid stop sequence during flush" into camera-kernel.lnx.4.0
This commit is contained in:
commit
73452f0906
4 changed files with 179 additions and 1 deletions
|
|
@ -529,6 +529,48 @@ 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)
|
||||
{
|
||||
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;
|
||||
uint32_t i;
|
||||
int rc = 0;
|
||||
|
||||
list_for_each_entry(hw_mgr_res, halt_list, list) {
|
||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||
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 ==
|
||||
CAM_TFE_CSID_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_csid_hw_halt_args));
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP, "Halt update failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_tfe_mgr_csid_stop_hw(
|
||||
struct cam_tfe_hw_mgr_ctx *ctx, struct list_head *stop_list,
|
||||
uint32_t base_idx, uint32_t stop_cmd)
|
||||
|
|
@ -2650,6 +2692,19 @@ static int cam_tfe_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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP, "Stopping master CSID idx %d", master_base_idx);
|
||||
|
||||
/* Stop the master CSID path first */
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ enum cam_isp_hw_cmd_type {
|
|||
CAM_ISP_HW_CMD_BLANKING_UPDATE,
|
||||
CAM_ISP_HW_CMD_CSID_CLOCK_DUMP,
|
||||
CAM_ISP_HW_CMD_TPG_CORE_CFG_CMD,
|
||||
CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE,
|
||||
CAM_ISP_HW_CMD_MAX,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,33 @@ enum cam_tfe_csid_halt_cmd {
|
|||
CAM_TFE_CSID_HALT_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum cam_tfe_csid_halt_mode_cmd - Specify the halt command type
|
||||
*/
|
||||
enum cam_tfe_csid_halt_mode {
|
||||
CAM_TFE_CSID_HALT_MODE_INTERNAL,
|
||||
CAM_TFE_CSID_HALT_MODE_GLOBAL,
|
||||
CAM_TFE_CSID_HALT_MODE_MASTER,
|
||||
CAM_TFE_CSID_HALT_MODE_SLAVE,
|
||||
CAM_TFE_CSID_HALT_MODE_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_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_csid_hw_halt_args {
|
||||
enum cam_tfe_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
|
||||
|
|
|
|||
|
|
@ -1246,6 +1246,63 @@ 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)
|
||||
{
|
||||
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;
|
||||
|
||||
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",
|
||||
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;
|
||||
}
|
||||
|
||||
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_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 |= (halt_mode << 2);
|
||||
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||
pxl_reg->csid_pxl_ctrl_addr);
|
||||
end:
|
||||
return;
|
||||
}
|
||||
|
||||
static int cam_tfe_csid_disable_pxl_path(
|
||||
struct cam_tfe_csid_hw *csid_hw,
|
||||
struct cam_isp_resource_node *res,
|
||||
|
|
@ -2088,6 +2145,41 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!csid_hw || !halt_args) {
|
||||
CAM_ERR(CAM_ISP, "CSID: Invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
csid_halt = (struct cam_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);
|
||||
|
||||
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",
|
||||
csid_hw->hw_intf->hw_idx,
|
||||
res->res_type);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_tfe_csid_stop(void *hw_priv,
|
||||
void *stop_args, uint32_t arg_size)
|
||||
{
|
||||
|
|
@ -2095,7 +2187,7 @@ static int cam_tfe_csid_stop(void *hw_priv,
|
|||
struct cam_tfe_csid_hw *csid_hw;
|
||||
struct cam_hw_info *csid_hw_info;
|
||||
struct cam_isp_resource_node *res;
|
||||
struct cam_tfe_csid_hw_stop_args *csid_stop;
|
||||
struct cam_tfe_csid_hw_stop_args *csid_stop;
|
||||
uint32_t i;
|
||||
uint32_t res_mask = 0;
|
||||
|
||||
|
|
@ -2472,6 +2564,9 @@ static int cam_tfe_csid_process_cmd(void *hw_priv,
|
|||
case CAM_ISP_HW_CMD_DUMP_HW:
|
||||
rc = cam_tfe_csid_dump_hw(csid_hw, cmd_args);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE:
|
||||
rc = cam_tfe_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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue