Prechádzať zdrojové kódy

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 <[email protected]>
Amine Najahi 3 rokov pred
rodič
commit
c526f4aefa
4 zmenil súbory, kde vykonal 88 pridanie a 22 odobranie
  1. 20 18
      msm/sde/sde_hw_catalog.c
  2. 53 1
      msm/sde/sde_hw_sspp.c
  3. 3 1
      msm/sde/sde_hw_sspp.h
  4. 12 2
      msm/sde/sde_plane.c

+ 20 - 18
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:

+ 53 - 1
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;
 }
 

+ 3 - 1
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

+ 12 - 2
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;