From c8a4cdc7613626bbfade0bb472ca2a265cd607e0 Mon Sep 17 00:00:00 2001 From: Amine Najahi Date: Thu, 12 Aug 2021 11:45:38 -0400 Subject: [PATCH] disp: msm: sde: add support for WB VBIF clock split Add support for localized CLK_CTRL access through WB hardware block. Change-Id: I408d1bbc798902d1abc7da5bcae9492baa3159c8 Signed-off-by: Amine Najahi --- msm/sde/sde_hw_catalog.c | 42 +++++++++++++++--------------- msm/sde/sde_hw_wb.c | 55 +++++++++++++++++++++++++++++++++++++++- msm/sde/sde_hw_wb.h | 5 +++- msm/sde/sde_rm.c | 15 ++++++++++- 4 files changed, 92 insertions(+), 25 deletions(-) diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index fadb496c39..9b2fb2dfeb 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -2588,31 +2588,29 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) } } - for (j = 0; j < sde_cfg->mdp_count; j++) { - sde_cfg->mdp[j].clk_ctrls[wb->clk_ctrl].reg_off = - PROP_BITVALUE_ACCESS(prop_value, - WB_CLK_CTRL, i, 0); - 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); + 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[wb->clk_ctrl].reg_off = + PROP_BITVALUE_ACCESS(prop_value, + WB_CLK_CTRL, i, 0); + 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); + } + + SDE_DEBUG("wb:%d xin:%d vbif:%d clk%d:%x/%d\n", wb->id - WB_0, + wb->xin_id, wb->vbif_idx, wb->clk_ctrl, + sde_cfg->mdp[0].clk_ctrls[wb->clk_ctrl].reg_off, + sde_cfg->mdp[0].clk_ctrls[wb->clk_ctrl].bit_off); } wb->format_list = sde_cfg->wb_formats; - - SDE_DEBUG( - "wb:%d xin:%d vbif:%d clk%d:%x/%d\n", - wb->id - WB_0, - wb->xin_id, - wb->vbif_idx, - wb->clk_ctrl, - sde_cfg->mdp[0].clk_ctrls[wb->clk_ctrl].reg_off, - sde_cfg->mdp[0].clk_ctrls[wb->clk_ctrl].bit_off); } end: diff --git a/msm/sde/sde_hw_wb.c b/msm/sde/sde_hw_wb.c index c980b71d95..fe45855baf 100644 --- a/msm/sde/sde_hw_wb.c +++ b/msm/sde/sde_hw_wb.c @@ -10,6 +10,7 @@ #include "sde_formats.h" #include "sde_dbg.h" #include "sde_kms.h" +#include "sde_vbif.h" #define WB_DST_FORMAT 0x000 #define WB_DST_OP_MODE 0x004 @@ -44,6 +45,8 @@ #define WB_MUX 0x150 #define WB_CROP_CTRL 0x154 #define WB_CROP_OFFSET 0x158 +#define WB_CLK_CTRL 0x178 +#define WB_CLK_STATUS 0x17C #define WB_CSC_BASE 0x260 #define WB_DST_ADDR_SW_STATUS 0x2B0 #define WB_CDP_CNTL 0x2B4 @@ -502,6 +505,44 @@ static void sde_hw_wb_program_cwb_dither_ctrl(struct sde_hw_wb *ctx, SDE_DEBUG("cwb dither enabled, dcwb_idx %u pp_id %u\n", dcwb_idx, pp_id); } +static bool sde_hw_wb_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_WB_VALID(clk_ctrl)) + return false; + + reg_val = SDE_REG_READ(hw, WB_CLK_CTRL); + + if (enable) + new_val = reg_val | BIT(0); + else + new_val = reg_val & ~BIT(0); + + SDE_REG_WRITE(hw, WB_CLK_CTRL, new_val); + wmb(); /* ensure write finished before progressing */ + + return !(reg_val & BIT(0)); +} + +static int sde_hw_wb_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_WB_VALID(clk_ctrl)) + return -EINVAL; + + *status = SDE_REG_READ(hw, WB_CLK_STATUS) & BIT(0); + + return 0; +} + static void _setup_wb_ops(struct sde_hw_wb_ops *ops, unsigned long features) { @@ -538,7 +579,8 @@ static void _setup_wb_ops(struct sde_hw_wb_ops *ops, struct sde_hw_blk_reg_map *sde_hw_wb_init(enum sde_wb idx, void __iomem *addr, struct sde_mdss_cfg *m, - struct sde_hw_mdp *hw_mdp) + struct sde_hw_mdp *hw_mdp, + struct sde_vbif_clk_client *clk_client) { struct sde_hw_wb *c; struct sde_wb_cfg *cfg; @@ -565,6 +607,17 @@ struct sde_hw_blk_reg_map *sde_hw_wb_init(enum sde_wb idx, _setup_wb_ops(&c->ops, c->caps->features); c->hw_mdp = hw_mdp; + if (test_bit(SDE_FEATURE_VBIF_CLK_SPLIT, m->features)) { + if (SDE_CLK_CTRL_WB_VALID(cfg->clk_ctrl)) { + clk_client->hw = &c->hw; + clk_client->clk_ctrl = cfg->clk_ctrl; + clk_client->ops.get_clk_ctrl_status = sde_hw_wb_get_clk_ctrl_status; + clk_client->ops.setup_clk_force_ctrl = sde_hw_wb_setup_clk_force_ctrl; + } else { + SDE_ERROR("invalid wb clk ctrl type %d\n", cfg->clk_ctrl); + } + } + sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name, c->hw.blk_off, c->hw.blk_off + c->hw.length, c->hw.xin_id); diff --git a/msm/sde/sde_hw_wb.h b/msm/sde/sde_hw_wb.h index 40bea8844a..379e1601c3 100644 --- a/msm/sde/sde_hw_wb.h +++ b/msm/sde/sde_hw_wb.h @@ -11,6 +11,7 @@ #include "sde_hw_top.h" #include "sde_hw_util.h" #include "sde_hw_pingpong.h" +#include "sde_hw_vbif.h" struct sde_hw_wb; @@ -211,11 +212,13 @@ static inline struct sde_hw_wb *to_sde_hw_wb(struct sde_hw_blk_reg_map *hw) * @addr: mapped register io address of MDP * @m : pointer to mdss catalog data * @hw_mdp: pointer to mdp top hw driver object + * @clk_client: pointer to vbif clk client info */ struct sde_hw_blk_reg_map *sde_hw_wb_init(enum sde_wb idx, void __iomem *addr, struct sde_mdss_cfg *m, - struct sde_hw_mdp *hw_mdp); + struct sde_hw_mdp *hw_mdp, + struct sde_vbif_clk_client *clk_client); /** * sde_hw_wb_destroy(): Destroy writeback hw driver object. diff --git a/msm/sde/sde_rm.c b/msm/sde/sde_rm.c index e783441ff5..46834cd6a6 100644 --- a/msm/sde/sde_rm.c +++ b/msm/sde/sde_rm.c @@ -19,6 +19,7 @@ #include "sde_hw_vdc.h" #include "sde_crtc.h" #include "sde_hw_qdss.h" +#include "sde_vbif.h" #define RESERVED_BY_OTHER(h, r) \ (((h)->rsvp && ((h)->rsvp->enc_id != (r)->enc_id)) ||\ @@ -597,9 +598,12 @@ static int _sde_rm_hw_blk_create( uint32_t id, void *hw_catalog_info) { + int rc; struct sde_rm_hw_blk *blk; struct sde_hw_mdp *hw_mdp; struct sde_hw_blk_reg_map *hw; + struct sde_kms *sde_kms = to_sde_kms(ddev_to_msm_kms(rm->dev)); + struct sde_vbif_clk_client clk_client; hw_mdp = rm->hw_mdp; @@ -626,7 +630,7 @@ static int _sde_rm_hw_blk_create( hw = sde_hw_intf_init(id, mmio, cat); break; case SDE_HW_BLK_WB: - hw = sde_hw_wb_init(id, mmio, cat, hw_mdp); + hw = sde_hw_wb_init(id, mmio, cat, hw_mdp, &clk_client); break; case SDE_HW_BLK_DSC: hw = sde_hw_dsc_init(id, mmio, cat); @@ -666,6 +670,15 @@ static int _sde_rm_hw_blk_create( _sde_rm_inc_resource_info(rm, &rm->avail_res, blk); + if (test_bit(SDE_FEATURE_VBIF_CLK_SPLIT, sde_kms->catalog->features) && + SDE_CLK_CTRL_VALID(clk_client.clk_ctrl)) { + rc = sde_vbif_clk_register(sde_kms, &clk_client); + if (rc) { + SDE_ERROR("failed to register vbif client %d\n", clk_client.clk_ctrl); + return -EFAULT; + } + } + return 0; }