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 <anajahi@codeaurora.org>
This commit is contained in:
Amine Najahi
2021-08-12 11:45:38 -04:00
parent c526f4aefa
commit c8a4cdc761
4 changed files with 92 additions and 25 deletions

View File

@@ -2588,6 +2588,7 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
} }
} }
if (!test_bit(SDE_FEATURE_VBIF_CLK_SPLIT, sde_cfg->features)) {
for (j = 0; j < sde_cfg->mdp_count; j++) { for (j = 0; j < sde_cfg->mdp_count; j++) {
sde_cfg->mdp[j].clk_ctrls[wb->clk_ctrl].reg_off = sde_cfg->mdp[j].clk_ctrls[wb->clk_ctrl].reg_off =
PROP_BITVALUE_ACCESS(prop_value, PROP_BITVALUE_ACCESS(prop_value,
@@ -2603,18 +2604,15 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
WB_CLK_STATUS, i, 1); WB_CLK_STATUS, i, 1);
} }
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_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].reg_off,
sde_cfg->mdp[0].clk_ctrls[wb->clk_ctrl].bit_off); sde_cfg->mdp[0].clk_ctrls[wb->clk_ctrl].bit_off);
} }
wb->format_list = sde_cfg->wb_formats;
}
end: end:
kfree(prop_value); kfree(prop_value);
return rc; return rc;

View File

@@ -10,6 +10,7 @@
#include "sde_formats.h" #include "sde_formats.h"
#include "sde_dbg.h" #include "sde_dbg.h"
#include "sde_kms.h" #include "sde_kms.h"
#include "sde_vbif.h"
#define WB_DST_FORMAT 0x000 #define WB_DST_FORMAT 0x000
#define WB_DST_OP_MODE 0x004 #define WB_DST_OP_MODE 0x004
@@ -44,6 +45,8 @@
#define WB_MUX 0x150 #define WB_MUX 0x150
#define WB_CROP_CTRL 0x154 #define WB_CROP_CTRL 0x154
#define WB_CROP_OFFSET 0x158 #define WB_CROP_OFFSET 0x158
#define WB_CLK_CTRL 0x178
#define WB_CLK_STATUS 0x17C
#define WB_CSC_BASE 0x260 #define WB_CSC_BASE 0x260
#define WB_DST_ADDR_SW_STATUS 0x2B0 #define WB_DST_ADDR_SW_STATUS 0x2B0
#define WB_CDP_CNTL 0x2B4 #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); 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, static void _setup_wb_ops(struct sde_hw_wb_ops *ops,
unsigned long features) 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, struct sde_hw_blk_reg_map *sde_hw_wb_init(enum sde_wb idx,
void __iomem *addr, void __iomem *addr,
struct sde_mdss_cfg *m, 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_hw_wb *c;
struct sde_wb_cfg *cfg; 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); _setup_wb_ops(&c->ops, c->caps->features);
c->hw_mdp = hw_mdp; 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, 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); c->hw.blk_off + c->hw.length, c->hw.xin_id);

View File

@@ -11,6 +11,7 @@
#include "sde_hw_top.h" #include "sde_hw_top.h"
#include "sde_hw_util.h" #include "sde_hw_util.h"
#include "sde_hw_pingpong.h" #include "sde_hw_pingpong.h"
#include "sde_hw_vbif.h"
struct sde_hw_wb; 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 * @addr: mapped register io address of MDP
* @m : pointer to mdss catalog data * @m : pointer to mdss catalog data
* @hw_mdp: pointer to mdp top hw driver object * @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, struct sde_hw_blk_reg_map *sde_hw_wb_init(enum sde_wb idx,
void __iomem *addr, void __iomem *addr,
struct sde_mdss_cfg *m, 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. * sde_hw_wb_destroy(): Destroy writeback hw driver object.

View File

@@ -19,6 +19,7 @@
#include "sde_hw_vdc.h" #include "sde_hw_vdc.h"
#include "sde_crtc.h" #include "sde_crtc.h"
#include "sde_hw_qdss.h" #include "sde_hw_qdss.h"
#include "sde_vbif.h"
#define RESERVED_BY_OTHER(h, r) \ #define RESERVED_BY_OTHER(h, r) \
(((h)->rsvp && ((h)->rsvp->enc_id != (r)->enc_id)) ||\ (((h)->rsvp && ((h)->rsvp->enc_id != (r)->enc_id)) ||\
@@ -597,9 +598,12 @@ static int _sde_rm_hw_blk_create(
uint32_t id, uint32_t id,
void *hw_catalog_info) void *hw_catalog_info)
{ {
int rc;
struct sde_rm_hw_blk *blk; struct sde_rm_hw_blk *blk;
struct sde_hw_mdp *hw_mdp; struct sde_hw_mdp *hw_mdp;
struct sde_hw_blk_reg_map *hw; 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; hw_mdp = rm->hw_mdp;
@@ -626,7 +630,7 @@ static int _sde_rm_hw_blk_create(
hw = sde_hw_intf_init(id, mmio, cat); hw = sde_hw_intf_init(id, mmio, cat);
break; break;
case SDE_HW_BLK_WB: 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; break;
case SDE_HW_BLK_DSC: case SDE_HW_BLK_DSC:
hw = sde_hw_dsc_init(id, mmio, cat); 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); _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; return 0;
} }