disp: msm: sde: add support for SSPP VBIF clock split
Add support for localized CLK_CTRL access through SSPP hardware block. Change-Id: I86345c94cb12c5584337aa45b562bceaab6cf8e6 Signed-off-by: Amine Najahi <anajahi@codeaurora.org>
Esse commit está contido em:
@@ -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,
|
sblk->src_blk.len = PROP_VALUE_ACCESS(props->values, SSPP_SIZE,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
for (j = 0; j < sde_cfg->mdp_count; j++) {
|
if (!test_bit(SDE_FEATURE_VBIF_CLK_SPLIT, sde_cfg->features)) {
|
||||||
sde_cfg->mdp[j].clk_ctrls[sspp->clk_ctrl].reg_off =
|
for (j = 0; j < sde_cfg->mdp_count; j++) {
|
||||||
PROP_BITVALUE_ACCESS(props->values,
|
sde_cfg->mdp[j].clk_ctrls[sspp->clk_ctrl].reg_off =
|
||||||
SSPP_CLK_CTRL, i, 0);
|
PROP_BITVALUE_ACCESS(props->values,
|
||||||
sde_cfg->mdp[j].clk_ctrls[sspp->clk_ctrl].bit_off =
|
SSPP_CLK_CTRL, i, 0);
|
||||||
PROP_BITVALUE_ACCESS(props->values,
|
sde_cfg->mdp[j].clk_ctrls[sspp->clk_ctrl].bit_off =
|
||||||
SSPP_CLK_CTRL, i, 1);
|
PROP_BITVALUE_ACCESS(props->values,
|
||||||
sde_cfg->mdp[j].clk_status[sspp->clk_ctrl].reg_off =
|
SSPP_CLK_CTRL, i, 1);
|
||||||
PROP_BITVALUE_ACCESS(props->values,
|
sde_cfg->mdp[j].clk_status[sspp->clk_ctrl].reg_off =
|
||||||
SSPP_CLK_STATUS, i, 0);
|
PROP_BITVALUE_ACCESS(props->values,
|
||||||
sde_cfg->mdp[j].clk_status[sspp->clk_ctrl].bit_off =
|
SSPP_CLK_STATUS, i, 0);
|
||||||
PROP_BITVALUE_ACCESS(props->values,
|
sde_cfg->mdp[j].clk_status[sspp->clk_ctrl].bit_off =
|
||||||
SSPP_CLK_STATUS, i, 1);
|
PROP_BITVALUE_ACCESS(props->values,
|
||||||
}
|
SSPP_CLK_STATUS, i, 1);
|
||||||
|
}
|
||||||
|
|
||||||
SDE_DEBUG("xin:%d ram:%d clk%d:%x/%d\n",
|
SDE_DEBUG("xin:%d ram:%d clk%d:%x/%d\n",
|
||||||
sspp->xin_id, sblk->pixel_ram_size, sspp->clk_ctrl,
|
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].reg_off,
|
||||||
sde_cfg->mdp[0].clk_ctrls[sspp->clk_ctrl].bit_off);
|
sde_cfg->mdp[0].clk_ctrls[sspp->clk_ctrl].bit_off);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include "sde_dbg.h"
|
#include "sde_dbg.h"
|
||||||
#include "sde_kms.h"
|
#include "sde_kms.h"
|
||||||
#include "sde_hw_reg_dma_v1_color_proc.h"
|
#include "sde_hw_reg_dma_v1_color_proc.h"
|
||||||
|
#include "sde_hw_vbif.h"
|
||||||
|
|
||||||
#define SDE_FETCH_CONFIG_RESET_VALUE 0x00000087
|
#define SDE_FETCH_CONFIG_RESET_VALUE 0x00000087
|
||||||
|
|
||||||
@@ -110,6 +111,8 @@
|
|||||||
#define SSPP_VIG_OP_MODE 0x0
|
#define SSPP_VIG_OP_MODE 0x0
|
||||||
#define SSPP_VIG_CSC_10_OP_MODE 0x0
|
#define SSPP_VIG_CSC_10_OP_MODE 0x0
|
||||||
#define SSPP_TRAFFIC_SHAPER_BPC_MAX 0xFF
|
#define SSPP_TRAFFIC_SHAPER_BPC_MAX 0xFF
|
||||||
|
#define SSPP_CLK_CTRL 0x330
|
||||||
|
#define SSPP_CLK_STATUS 0x334
|
||||||
|
|
||||||
/* SSPP_QOS_CTRL */
|
/* SSPP_QOS_CTRL */
|
||||||
#define SSPP_QOS_CTRL_VBLANK_EN BIT(16)
|
#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);
|
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,
|
static void _setup_layer_ops(struct sde_hw_pipe *c,
|
||||||
unsigned long features, unsigned long perf_features,
|
unsigned long features, unsigned long perf_features,
|
||||||
bool is_virtual_pipe)
|
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,
|
struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
|
||||||
void __iomem *addr, struct sde_mdss_cfg *catalog,
|
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_hw_pipe *hw_pipe;
|
||||||
struct sde_sspp_cfg *cfg;
|
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,
|
cfg->sblk->scaler_blk.len,
|
||||||
hw_pipe->hw.xin_id);
|
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;
|
return hw_pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
#include "sde_reg_dma.h"
|
#include "sde_reg_dma.h"
|
||||||
#include "sde_formats.h"
|
#include "sde_formats.h"
|
||||||
#include "sde_color_processing.h"
|
#include "sde_color_processing.h"
|
||||||
|
#include "sde_hw_vbif.h"
|
||||||
|
|
||||||
struct sde_hw_pipe;
|
struct sde_hw_pipe;
|
||||||
|
|
||||||
@@ -710,10 +711,11 @@ struct sde_hw_pipe {
|
|||||||
* @addr: Mapped register io address of MDP
|
* @addr: Mapped register io address of MDP
|
||||||
* @catalog : Pointer to mdss catalog data
|
* @catalog : Pointer to mdss catalog data
|
||||||
* @is_virtual_pipe: is this pipe virtual pipe
|
* @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,
|
struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
|
||||||
void __iomem *addr, struct sde_mdss_cfg *catalog,
|
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
|
* sde_hw_sspp_destroy(): Destroys SSPP driver context
|
||||||
|
@@ -4738,6 +4738,7 @@ struct drm_plane *sde_plane_init(struct drm_device *dev,
|
|||||||
struct msm_drm_private *priv;
|
struct msm_drm_private *priv;
|
||||||
struct sde_kms *kms;
|
struct sde_kms *kms;
|
||||||
enum drm_plane_type type;
|
enum drm_plane_type type;
|
||||||
|
struct sde_vbif_clk_client clk_client;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
@@ -4783,8 +4784,8 @@ struct drm_plane *sde_plane_init(struct drm_device *dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* initialize underlying h/w driver */
|
/* initialize underlying h/w driver */
|
||||||
psde->pipe_hw = sde_hw_sspp_init(pipe, kms->mmio, kms->catalog,
|
psde->pipe_hw = sde_hw_sspp_init(pipe, kms->mmio, kms->catalog, psde->is_virtual,
|
||||||
psde->is_virtual);
|
&clk_client);
|
||||||
if (IS_ERR(psde->pipe_hw)) {
|
if (IS_ERR(psde->pipe_hw)) {
|
||||||
SDE_ERROR("[%u]SSPP init failed\n", pipe);
|
SDE_ERROR("[%u]SSPP init failed\n", pipe);
|
||||||
ret = PTR_ERR(psde->pipe_hw);
|
ret = PTR_ERR(psde->pipe_hw);
|
||||||
@@ -4794,6 +4795,15 @@ struct drm_plane *sde_plane_init(struct drm_device *dev,
|
|||||||
goto clean_sspp;
|
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 */
|
/* cache features mask for later */
|
||||||
psde->features = psde->pipe_hw->cap->features_ext;
|
psde->features = psde->pipe_hw->cap->features_ext;
|
||||||
psde->perf_features = psde->pipe_hw->cap->perf_features;
|
psde->perf_features = psde->pipe_hw->cap->perf_features;
|
||||||
|
Referência em uma nova issue
Block a user