Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c51f40bd authored by Ping Li's avatar Ping Li
Browse files

drm/msm/sde: Add support to bump up data bus when needed for PP



Some of the color-proc features require to program quite a lot registers
when they are enabled. And if reg_dma support for the feature is not
enabled, programing those registers may take too long and cause
potential frame drops.
This change adds the functionality to bump up the data bus when needed
to avoid the above issues.

Change-Id: I3022868092d777cc6be10aa70320ae4137239cf8
Signed-off-by: default avatarPing Li <pingli@codeaurora.org>
parent 316c5d63
Loading
Loading
Loading
Loading
+51 −1
Original line number Diff line number Diff line
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
@@ -25,6 +25,7 @@
#include "sde_hw_interrupts.h"
#include "sde_core_irq.h"
#include "dsi_panel.h"
#include "sde_hw_color_processing.h"

struct sde_cp_node {
	u32 property_id;
@@ -144,6 +145,24 @@ enum {
	SDE_CP_CRTC_MAX_FEATURES,
};

#define HIGH_BUS_VOTE_NEEDED(feature) ((feature == SDE_CP_CRTC_DSPP_IGC) |\
				 (feature == SDE_CP_CRTC_DSPP_GC) |\
				 (feature == SDE_CP_CRTC_DSPP_SIXZONE) |\
				 (feature == SDE_CP_CRTC_DSPP_GAMUT))

static u32 crtc_feature_map[SDE_CP_CRTC_MAX_FEATURES] = {
	[SDE_CP_CRTC_DSPP_IGC] = SDE_DSPP_IGC,
	[SDE_CP_CRTC_DSPP_PCC] = SDE_DSPP_PCC,
	[SDE_CP_CRTC_DSPP_GC] = SDE_DSPP_GC,
	[SDE_CP_CRTC_DSPP_MEMCOL_SKIN] = SDE_DSPP_MEMCOLOR,
	[SDE_CP_CRTC_DSPP_MEMCOL_SKY] = SDE_DSPP_MEMCOLOR,
	[SDE_CP_CRTC_DSPP_MEMCOL_FOLIAGE] = SDE_DSPP_MEMCOLOR,
	[SDE_CP_CRTC_DSPP_SIXZONE] = SDE_DSPP_SIXZONE,
	[SDE_CP_CRTC_DSPP_GAMUT] = SDE_DSPP_GAMUT,
	[SDE_CP_CRTC_DSPP_DITHER] = SDE_DSPP_DITHER,
	[SDE_CP_CRTC_DSPP_VLUT] = SDE_DSPP_VLUT,
};

#define INIT_PROP_ATTACH(p, crtc, prop, node, feature, val) \
	do { \
		(p)->crtc = crtc; \
@@ -837,6 +856,10 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc)
	struct sde_hw_ctl *ctl;
	uint32_t flush_mask = 0;
	u32 num_mixers = 0, i = 0;
	u32 sde_dspp_feature = SDE_DSPP_MAX;
	struct msm_drm_private *priv = NULL;
	struct sde_kms *sde_kms = NULL;
	bool mdss_bus_vote = false;

	if (!crtc || !crtc->dev) {
		DRM_ERROR("invalid crtc %pK dev %pK\n", crtc,
@@ -856,6 +879,17 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc)
		return;
	}

	priv = crtc->dev->dev_private;
	if (!priv || !priv->kms) {
		SDE_ERROR("invalid kms\n");
		return;
	}
	sde_kms = to_sde_kms(priv->kms);
	if (!sde_kms) {
		SDE_ERROR("invalid sde kms\n");
		return;
	}

	mutex_lock(&sde_crtc->crtc_cp_lock);

	/* Check if dirty lists are empty and ad features are disabled for
@@ -874,6 +908,16 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc)

	list_for_each_entry_safe(prop_node, n, &sde_crtc->dirty_list,
				dirty_list) {
		sde_dspp_feature = crtc_feature_map[prop_node->feature];
		if (!mdss_bus_vote && HIGH_BUS_VOTE_NEEDED(prop_node->feature)
			&& !reg_dmav1_dspp_feature_support(sde_dspp_feature)) {
			sde_power_scale_reg_bus(&priv->phandle,
				sde_kms->core_client,
				VOTE_INDEX_HIGH, false);
			pr_debug("Vote HIGH for data bus: feature %d\n",
					prop_node->feature);
			mdss_bus_vote = true;
		}
		sde_cp_crtc_setfeature(prop_node, sde_crtc);
		/* Set the flush flag to true */
		if (prop_node->is_dspp_feature)
@@ -881,6 +925,12 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc)
		else
			set_lm_flush = true;
	}
	if (mdss_bus_vote) {
		sde_power_scale_reg_bus(&priv->phandle, sde_kms->core_client,
			VOTE_INDEX_LOW, false);
		pr_debug("Vote LOW for data bus\n");
		mdss_bus_vote = false;
	}

	list_for_each_entry_safe(prop_node, n, &sde_crtc->ad_dirty,
				dirty_list) {
+27 −1
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -248,6 +248,32 @@ static int reg_dma_kick_off(enum sde_reg_dma_op op, enum sde_reg_dma_queue q,
	return rc;
}

bool reg_dmav1_dspp_feature_support(int feature)
{
	struct sde_hw_reg_dma_ops *dma_ops;
	bool is_supported = false;

	if (feature >= SDE_DSPP_MAX) {
		DRM_ERROR("invalid feature %x max %x\n",
			feature, SDE_DSPP_MAX);
		return is_supported;
	}

	if (feature_map[feature] >= REG_DMA_FEATURES_MAX) {
		DRM_ERROR("invalid feature map %d for feature %d\n",
			feature_map[feature], feature);
		return is_supported;
	}

	dma_ops = sde_reg_dma_get_ops();
	if (IS_ERR_OR_NULL(dma_ops))
		return is_supported;

	dma_ops->check_support(feature_map[feature], DSPP0, &is_supported);

	return is_supported;
}

int reg_dmav1_init_dspp_op_v4(int feature, enum sde_dspp idx)
{
	int rc = -ENOTSUPP;
+8 −1
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -24,6 +24,13 @@
 */
int reg_dmav1_init_dspp_op_v4(int feature, enum sde_dspp idx);

/**
 * reg_dmav1_dspp_feature_support() - check if dspp feature using REG_DMA
 *                                    or not.
 * @feature: dspp feature
 */
bool reg_dmav1_dspp_feature_support(int feature);

/**
 * reg_dma_init_sspp_op_v4() - initialize the sspp feature op for sde v4
 * @feature: sspp feature