diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 18eaa0bf07..fadb496c39 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -2030,25 +2030,27 @@ static int _sde_sspp_setup_cmn(struct device_node *np, sblk->src_blk.len = PROP_VALUE_ACCESS(props->values, SSPP_SIZE, 0); - for (j = 0; j < sde_cfg->mdp_count; j++) { - sde_cfg->mdp[j].clk_ctrls[sspp->clk_ctrl].reg_off = - PROP_BITVALUE_ACCESS(props->values, - SSPP_CLK_CTRL, i, 0); - 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); - } + if (!test_bit(SDE_FEATURE_VBIF_CLK_SPLIT, sde_cfg->features)) { + for (j = 0; j < sde_cfg->mdp_count; j++) { + sde_cfg->mdp[j].clk_ctrls[sspp->clk_ctrl].reg_off = + PROP_BITVALUE_ACCESS(props->values, + SSPP_CLK_CTRL, i, 0); + 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", - sspp->xin_id, sblk->pixel_ram_size, sspp->clk_ctrl, - sde_cfg->mdp[0].clk_ctrls[sspp->clk_ctrl].reg_off, - sde_cfg->mdp[0].clk_ctrls[sspp->clk_ctrl].bit_off); + SDE_DEBUG("xin:%d ram:%d clk%d:%x/%d\n", + sspp->xin_id, sblk->pixel_ram_size, sspp->clk_ctrl, + sde_cfg->mdp[0].clk_ctrls[sspp->clk_ctrl].reg_off, + sde_cfg->mdp[0].clk_ctrls[sspp->clk_ctrl].bit_off); + } } end: diff --git a/msm/sde/sde_hw_sspp.c b/msm/sde/sde_hw_sspp.c index 886dab5be2..5167d5d190 100644 --- a/msm/sde/sde_hw_sspp.c +++ b/msm/sde/sde_hw_sspp.c @@ -11,6 +11,7 @@ #include "sde_dbg.h" #include "sde_kms.h" #include "sde_hw_reg_dma_v1_color_proc.h" +#include "sde_hw_vbif.h" #define SDE_FETCH_CONFIG_RESET_VALUE 0x00000087 @@ -110,6 +111,8 @@ #define SSPP_VIG_OP_MODE 0x0 #define SSPP_VIG_CSC_10_OP_MODE 0x0 #define SSPP_TRAFFIC_SHAPER_BPC_MAX 0xFF +#define SSPP_CLK_CTRL 0x330 +#define SSPP_CLK_STATUS 0x334 /* SSPP_QOS_CTRL */ #define SSPP_QOS_CTRL_VBLANK_EN BIT(16) @@ -1382,6 +1385,44 @@ static void sde_hw_sspp_setup_dgm_csc(struct sde_hw_pipe *ctx, SDE_REG_WRITE(&ctx->hw, offset, op_mode); } +static bool sde_hw_sspp_setup_clk_force_ctrl(struct sde_hw_blk_reg_map *hw, + enum sde_clk_ctrl_type clk_ctrl, bool enable) +{ + u32 reg_val, new_val; + + if (!hw) + return false; + + if (!SDE_CLK_CTRL_SSPP_VALID(clk_ctrl)) + return false; + + reg_val = SDE_REG_READ(hw, SSPP_CLK_CTRL); + + if (enable) + new_val = reg_val | BIT(0); + else + new_val = reg_val & ~BIT(0); + + SDE_REG_WRITE(hw, SSPP_CLK_CTRL, new_val); + wmb(); /* ensure write finished before progressing */ + + return !(reg_val & BIT(0)); +} + +static int sde_hw_sspp_get_clk_ctrl_status(struct sde_hw_blk_reg_map *hw, + enum sde_clk_ctrl_type clk_ctrl, bool *status) +{ + if (!hw) + return -EINVAL; + + if (!SDE_CLK_CTRL_SSPP_VALID(clk_ctrl)) + return -EINVAL; + + *status = SDE_REG_READ(hw, SSPP_CLK_STATUS) & BIT(0); + + return 0; +} + static void _setup_layer_ops(struct sde_hw_pipe *c, unsigned long features, unsigned long perf_features, bool is_virtual_pipe) @@ -1508,7 +1549,7 @@ static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp, struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx, void __iomem *addr, struct sde_mdss_cfg *catalog, - bool is_virtual_pipe) + bool is_virtual_pipe, struct sde_vbif_clk_client *clk_client) { struct sde_hw_pipe *hw_pipe; struct sde_sspp_cfg *cfg; @@ -1582,6 +1623,17 @@ struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx, cfg->sblk->scaler_blk.len, hw_pipe->hw.xin_id); + if (test_bit(SDE_FEATURE_VBIF_CLK_SPLIT, catalog->features)) { + if (SDE_CLK_CTRL_SSPP_VALID(cfg->clk_ctrl)) { + clk_client->hw = &hw_pipe->hw; + clk_client->clk_ctrl = cfg->clk_ctrl; + clk_client->ops.get_clk_ctrl_status = sde_hw_sspp_get_clk_ctrl_status; + clk_client->ops.setup_clk_force_ctrl = sde_hw_sspp_setup_clk_force_ctrl; + } else { + SDE_ERROR("invalid sspp clk ctrl type %d\n", cfg->clk_ctrl); + } + } + return hw_pipe; } diff --git a/msm/sde/sde_hw_sspp.h b/msm/sde/sde_hw_sspp.h index 750acbd9ce..fd40cab75d 100644 --- a/msm/sde/sde_hw_sspp.h +++ b/msm/sde/sde_hw_sspp.h @@ -12,6 +12,7 @@ #include "sde_reg_dma.h" #include "sde_formats.h" #include "sde_color_processing.h" +#include "sde_hw_vbif.h" struct sde_hw_pipe; @@ -710,10 +711,11 @@ struct sde_hw_pipe { * @addr: Mapped register io address of MDP * @catalog : Pointer to mdss catalog data * @is_virtual_pipe: is this pipe virtual pipe + * @client: Pointer to VBIF clock client info */ struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx, void __iomem *addr, struct sde_mdss_cfg *catalog, - bool is_virtual_pipe); + bool is_virtual_pipe, struct sde_vbif_clk_client *client); /** * sde_hw_sspp_destroy(): Destroys SSPP driver context diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 26723b8f41..89bde61b13 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -4738,6 +4738,7 @@ struct drm_plane *sde_plane_init(struct drm_device *dev, struct msm_drm_private *priv; struct sde_kms *kms; enum drm_plane_type type; + struct sde_vbif_clk_client clk_client; int ret = -EINVAL; if (!dev) { @@ -4783,8 +4784,8 @@ struct drm_plane *sde_plane_init(struct drm_device *dev, } /* initialize underlying h/w driver */ - psde->pipe_hw = sde_hw_sspp_init(pipe, kms->mmio, kms->catalog, - psde->is_virtual); + psde->pipe_hw = sde_hw_sspp_init(pipe, kms->mmio, kms->catalog, psde->is_virtual, + &clk_client); if (IS_ERR(psde->pipe_hw)) { SDE_ERROR("[%u]SSPP init failed\n", pipe); ret = PTR_ERR(psde->pipe_hw); @@ -4794,6 +4795,15 @@ struct drm_plane *sde_plane_init(struct drm_device *dev, goto clean_sspp; } + if (test_bit(SDE_FEATURE_VBIF_CLK_SPLIT, kms->catalog->features)) { + ret = sde_vbif_clk_register(kms, &clk_client); + if (ret) { + SDE_ERROR("failed to register vbif client %d\n", + clk_client.clk_ctrl); + goto clean_sspp; + } + } + /* cache features mask for later */ psde->features = psde->pipe_hw->cap->features_ext; psde->perf_features = psde->pipe_hw->cap->perf_features;