Merge "disp: msm: sde: add xin client clock status for wb2" into display-kernel.lnx.5.4
This commit is contained in:

کامیت شده توسط
Gerrit - the friendly Code Review server

کامیت
8fb0e26527
@@ -1200,6 +1200,25 @@ static int sde_encoder_phys_wb_frame_timeout(struct sde_encoder_phys *phys_enc)
|
||||
return event;
|
||||
}
|
||||
|
||||
static bool _sde_encoder_phys_wb_is_idle(
|
||||
struct sde_encoder_phys *phys_enc)
|
||||
{
|
||||
bool ret = false;
|
||||
struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc);
|
||||
struct sde_hw_wb *hw_wb = wb_enc->hw_wb;
|
||||
struct sde_vbif_get_xin_status_params xin_status = {0};
|
||||
|
||||
xin_status.vbif_idx = hw_wb->caps->vbif_idx;
|
||||
xin_status.xin_id = hw_wb->caps->xin_id;
|
||||
xin_status.clk_ctrl = hw_wb->caps->clk_ctrl;
|
||||
if (sde_vbif_get_xin_status(phys_enc->sde_kms, &xin_status)) {
|
||||
_sde_encoder_phys_wb_frame_done_helper(wb_enc, false);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _sde_encoder_phys_wb_wait_for_commit_done(
|
||||
struct sde_encoder_phys *phys_enc, bool is_disable)
|
||||
{
|
||||
@@ -1235,7 +1254,9 @@ static int _sde_encoder_phys_wb_wait_for_commit_done(
|
||||
KICKOFF_TIMEOUT_MS);
|
||||
rc = sde_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_WB_DONE,
|
||||
&wait_info);
|
||||
if (rc == -ETIMEDOUT) {
|
||||
if (rc == -ETIMEDOUT && _sde_encoder_phys_wb_is_idle(phys_enc)) {
|
||||
rc = 0;
|
||||
} else if (rc == -ETIMEDOUT) {
|
||||
SDE_EVT32(DRMID(phys_enc->parent), WBID(wb_enc),
|
||||
wb_enc->frame_count, SDE_EVTLOG_ERROR);
|
||||
SDE_ERROR("wb:%d kickoff timed out\n", WBID(wb_enc));
|
||||
|
@@ -441,6 +441,7 @@ enum {
|
||||
WB_ID,
|
||||
WB_XIN_ID,
|
||||
WB_CLK_CTRL,
|
||||
WB_CLK_STATUS,
|
||||
WB_PROP_MAX,
|
||||
};
|
||||
|
||||
@@ -832,6 +833,8 @@ static struct sde_prop_type wb_prop[] = {
|
||||
{WB_XIN_ID, "qcom,sde-wb-xin-id", false, PROP_TYPE_U32_ARRAY},
|
||||
{WB_CLK_CTRL, "qcom,sde-wb-clk-ctrl", false,
|
||||
PROP_TYPE_BIT_OFFSET_ARRAY},
|
||||
{WB_CLK_STATUS, "qcom,sde-wb-clk-status", false,
|
||||
PROP_TYPE_BIT_OFFSET_ARRAY},
|
||||
};
|
||||
|
||||
static struct sde_prop_type vbif_prop[] = {
|
||||
@@ -881,7 +884,7 @@ static struct sde_prop_type reg_dma_prop[REG_DMA_PROP_MAX] = {
|
||||
"qcom,sde-reg-dma-broadcast-disabled", false, PROP_TYPE_BOOL},
|
||||
[REG_DMA_XIN_ID] = {REG_DMA_XIN_ID,
|
||||
"qcom,sde-reg-dma-xin-id", false, PROP_TYPE_U32},
|
||||
[REG_DMA_CLK_CTRL] = {REG_DMA_XIN_ID,
|
||||
[REG_DMA_CLK_CTRL] = {REG_DMA_CLK_CTRL,
|
||||
"qcom,sde-reg-dma-clk-ctrl", false, PROP_TYPE_BIT_OFFSET_ARRAY},
|
||||
};
|
||||
|
||||
@@ -1842,6 +1845,12 @@ static int _sde_sspp_setup_cmn(struct device_node *np,
|
||||
sde_cfg->mdp[j].clk_ctrls[sspp->clk_ctrl].bit_off =
|
||||
PROP_BITVALUE_ACCESS(props->values,
|
||||
SSPP_CLK_CTRL, i, 1);
|
||||
sde_cfg->mdp[j].clk_status[sspp->clk_ctrl].reg_off =
|
||||
PROP_BITVALUE_ACCESS(props->values,
|
||||
SSPP_CLK_STATUS, i, 0);
|
||||
sde_cfg->mdp[j].clk_status[sspp->clk_ctrl].bit_off =
|
||||
PROP_BITVALUE_ACCESS(props->values,
|
||||
SSPP_CLK_STATUS, i, 1);
|
||||
}
|
||||
|
||||
SDE_DEBUG("xin:%d ram:%d clk%d:%x/%d\n",
|
||||
@@ -2354,6 +2363,12 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
|
||||
sde_cfg->mdp[j].clk_ctrls[wb->clk_ctrl].bit_off =
|
||||
PROP_BITVALUE_ACCESS(prop_value,
|
||||
WB_CLK_CTRL, i, 1);
|
||||
sde_cfg->mdp[j].clk_status[wb->clk_ctrl].reg_off =
|
||||
PROP_BITVALUE_ACCESS(prop_value,
|
||||
WB_CLK_STATUS, i, 0);
|
||||
sde_cfg->mdp[j].clk_status[wb->clk_ctrl].bit_off =
|
||||
PROP_BITVALUE_ACCESS(prop_value,
|
||||
WB_CLK_STATUS, i, 1);
|
||||
}
|
||||
|
||||
wb->format_list = sde_cfg->wb_formats;
|
||||
|
@@ -868,6 +868,7 @@ struct sde_clk_ctrl_reg {
|
||||
* @has_dest_scaler: indicates support of destination scaler
|
||||
* @smart_panel_align_mode: split display smart panel align modes
|
||||
* @clk_ctrls clock control register definition
|
||||
* @clk_status clock status register definition
|
||||
*/
|
||||
struct sde_mdp_cfg {
|
||||
SDE_HW_BLK_INFO;
|
||||
@@ -877,6 +878,7 @@ struct sde_mdp_cfg {
|
||||
bool has_dest_scaler;
|
||||
u32 smart_panel_align_mode;
|
||||
struct sde_clk_ctrl_reg clk_ctrls[SDE_CLK_CTRL_MAX];
|
||||
struct sde_clk_ctrl_reg clk_status[SDE_CLK_CTRL_MAX];
|
||||
};
|
||||
|
||||
/* struct sde_uidle_cfg : MDP TOP-BLK instance info
|
||||
|
@@ -219,6 +219,27 @@ static bool sde_hw_setup_clk_force_ctrl(struct sde_hw_mdp *mdp,
|
||||
return clk_forced_on;
|
||||
}
|
||||
|
||||
static int sde_hw_get_clk_ctrl_status(struct sde_hw_mdp *mdp,
|
||||
enum sde_clk_ctrl_type clk_ctrl, bool *status)
|
||||
{
|
||||
struct sde_hw_blk_reg_map *c;
|
||||
u32 reg_off, bit_off;
|
||||
|
||||
if (!mdp)
|
||||
return -EINVAL;
|
||||
|
||||
c = &mdp->hw;
|
||||
|
||||
if (clk_ctrl <= SDE_CLK_CTRL_NONE || clk_ctrl >= SDE_CLK_CTRL_MAX ||
|
||||
!mdp->caps->clk_status[clk_ctrl].reg_off)
|
||||
return -EINVAL;
|
||||
|
||||
reg_off = mdp->caps->clk_status[clk_ctrl].reg_off;
|
||||
bit_off = mdp->caps->clk_status[clk_ctrl].bit_off;
|
||||
|
||||
*status = SDE_REG_READ(c, reg_off) & BIT(bit_off);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sde_hw_get_danger_status(struct sde_hw_mdp *mdp,
|
||||
struct sde_danger_safe_status *status)
|
||||
@@ -600,6 +621,7 @@ static void _setup_mdp_ops(struct sde_hw_mdp_ops *ops,
|
||||
ops->setup_pp_split = sde_hw_setup_pp_split;
|
||||
ops->setup_cdm_output = sde_hw_setup_cdm_output;
|
||||
ops->setup_clk_force_ctrl = sde_hw_setup_clk_force_ctrl;
|
||||
ops->get_clk_ctrl_status = sde_hw_get_clk_ctrl_status;
|
||||
ops->get_danger_status = sde_hw_get_danger_status;
|
||||
ops->setup_vsync_source = sde_hw_setup_vsync_source;
|
||||
ops->set_cwb_ppb_cntl = sde_hw_program_cwb_ppb_ctrl;
|
||||
|
@@ -140,6 +140,16 @@ struct sde_hw_mdp_ops {
|
||||
bool (*setup_clk_force_ctrl)(struct sde_hw_mdp *mdp,
|
||||
enum sde_clk_ctrl_type clk_ctrl, bool enable);
|
||||
|
||||
/**
|
||||
* get_clk_ctrl_status - get clock control status
|
||||
* @mdp: mdp top context driver
|
||||
* @clk_ctrl: clock to be controlled
|
||||
* @status: returns true if clock is on
|
||||
* @return: 0 if success, otherwise return code
|
||||
*/
|
||||
int (*get_clk_ctrl_status)(struct sde_hw_mdp *mdp,
|
||||
enum sde_clk_ctrl_type clk_ctrl, bool *status);
|
||||
|
||||
/**
|
||||
* setup_dce - set DCE mux for DSC ctrl path
|
||||
* @mdp: mdp top context driver
|
||||
|
@@ -406,6 +406,58 @@ bool sde_vbif_set_xin_halt(struct sde_kms *sde_kms,
|
||||
return forced_on;
|
||||
}
|
||||
|
||||
bool sde_vbif_get_xin_status(struct sde_kms *sde_kms,
|
||||
struct sde_vbif_get_xin_status_params *params)
|
||||
{
|
||||
struct sde_hw_vbif *vbif = NULL;
|
||||
struct sde_hw_mdp *mdp;
|
||||
int i, rc;
|
||||
bool status;
|
||||
|
||||
if (!sde_kms || !params) {
|
||||
SDE_ERROR("invalid arguments\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sde_kms_is_vbif_operation_allowed(sde_kms)) {
|
||||
SDE_DEBUG("vbif operations not permitted\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
mdp = sde_kms->hw_mdp;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) {
|
||||
if (sde_kms->hw_vbif[i] &&
|
||||
sde_kms->hw_vbif[i]->idx == params->vbif_idx) {
|
||||
vbif = sde_kms->hw_vbif[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vbif || !mdp) {
|
||||
SDE_DEBUG("invalid arguments vbif:%d mdp:%d vbif idx:%d\n",
|
||||
vbif != NULL, mdp != NULL, params->vbif_idx);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mdp->ops.get_clk_ctrl_status ||
|
||||
!vbif->ops.get_xin_halt_status)
|
||||
return false;
|
||||
|
||||
mutex_lock(&vbif->mutex);
|
||||
SDE_EVT32_VERBOSE(vbif->idx, params->xin_id);
|
||||
status = vbif->ops.get_xin_halt_status(vbif, params->xin_id);
|
||||
if (status) {
|
||||
rc = !mdp->ops.get_clk_ctrl_status(mdp, params->clk_ctrl,
|
||||
&status);
|
||||
if (rc)
|
||||
status = false;
|
||||
}
|
||||
mutex_unlock(&vbif->mutex);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void sde_vbif_set_qos_remap(struct sde_kms *sde_kms,
|
||||
struct sde_vbif_set_qos_params *params)
|
||||
{
|
||||
|
@@ -44,6 +44,18 @@ struct sde_vbif_set_xin_halt_params {
|
||||
bool enable;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sde_vbif_get_xin_status_params - xin halt parameters
|
||||
* @vbif_idx: vbif identifier
|
||||
* @xin_id: client interface identifier
|
||||
* @clk_ctrl: clock control identifier of the xin
|
||||
*/
|
||||
struct sde_vbif_get_xin_status_params {
|
||||
u32 vbif_idx;
|
||||
u32 xin_id;
|
||||
u32 clk_ctrl;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sde_vbif_set_qos_params - QoS remapper parameter
|
||||
* @vbif_idx: vbif identifier
|
||||
@@ -78,6 +90,16 @@ void sde_vbif_set_ot_limit(struct sde_kms *sde_kms,
|
||||
bool sde_vbif_set_xin_halt(struct sde_kms *sde_kms,
|
||||
struct sde_vbif_set_xin_halt_params *params);
|
||||
|
||||
/**
|
||||
* sde_vbif_get_xin_status - halt one of the xin ports
|
||||
* This function isn't thread safe.
|
||||
* @sde_kms: SDE handler
|
||||
* @params: Pointer to xin status parameters
|
||||
* Returns: true if xin client is idle, false otherwise
|
||||
*/
|
||||
bool sde_vbif_get_xin_status(struct sde_kms *sde_kms,
|
||||
struct sde_vbif_get_xin_status_params *params);
|
||||
|
||||
/**
|
||||
* sde_vbif_set_qos_remap - set QoS priority level remap
|
||||
* @sde_kms: SDE handler
|
||||
|
مرجع در شماره جدید
Block a user