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

Commit 4a0416cb authored by Guchun Chen's avatar Guchun Chen
Browse files

drm: msm: sde: reduce black screen duration from null commit



User may send null commit without any plane attached to kernel.
In kernel, these null commits will clear mixer blendstage for
all pipes, and power on screen with black background color.
However, when bootloader splash is on, this operation will
override the splash, which brings long black screen duration
between splash and user UI. So this patch is to fix this.

Change-Id: I3a34ab2ad421f40bd315eb2874fea5dc33d3ccfb
Signed-off-by: default avatarGuchun Chen <guchunc@codeaurora.org>
parent ace476d5
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
Qualcomm Technologies, Inc. SDE early splash support

Optional properties:
- qcom,sde-plane-id: reserved plane id
- qcom,plane-name: reserved plane name
- qcom,pipe-early-release: dedicated for splash layer(not early RVC)

Example:

/ {
	qcom,sde-reserved-plane {
		qcom,sde-plane-id@0 {
			reg = <0x0>;
			qcom,plane-name = "vig0";
		};
		qcom,sde-plane-id@1 {
			reg = <0x1>;
			qcom,plane-name = "rgb0";
			qcom,pipe-early-release;
		};
		qcom,sde-plane-id@2 {
			reg = <0x2>;
			qcom,plane-name = "rgb1";
			qcom,pipe-early-release;
		};
		qcom,sde-plane-id@3 {
			reg = <0x3>;
			qcom,plane-name = "rgb2";
			qcom,pipe-early-release;
		};
	};
};
+5 −3
Original line number Diff line number Diff line
/*
 * Copyright (c) 2018 The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2019 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
@@ -311,7 +311,8 @@ end:
}

static void _sde_shd_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx,
	bool handoff, const u32 *resv_pipes, u32 resv_pipes_length)
	bool handoff, const struct splash_reserved_pipe_info *resv_pipes,
	u32 resv_pipes_length)
{
	struct sde_shd_hw_ctl *hw_ctl;
	int i;
@@ -345,7 +346,8 @@ static inline int _stage_offset(struct sde_hw_mixer *ctx, enum sde_stage stage)

static void _sde_shd_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
	enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg, u32 index,
	bool handoff, const u32 *resv_pipes, u32 resv_pipes_length)
	bool handoff, const struct splash_reserved_pipe_info *resv_pipes,
	u32 resv_pipes_length)
{
	struct sde_shd_hw_ctl *hw_ctl;
	u32 mixercfg = 0, mixercfg_ext = 0, mix, ext, full, mixercfg_ext2;
+19 −9
Original line number Diff line number Diff line
@@ -258,7 +258,8 @@ static inline int sde_hw_ctl_get_bitmask_cdm(struct sde_hw_ctl *ctx,
	return 0;
}

static inline void sde_hw_ctl_get_splash_mixer_mask(const u32 *resv_pipes,
static inline void sde_hw_ctl_get_splash_mixer_mask(
			const struct splash_reserved_pipe_info *resv_pipes,
			u32 length, u32 *mixercfg, u32 *mixercfg_ext)
{
	int i = 0;
@@ -268,7 +269,7 @@ static inline void sde_hw_ctl_get_splash_mixer_mask(const u32 *resv_pipes,
	for (i = 0; i < length; i++) {
		/* LK's splash VIG layer always stays on second top */
		/*  most layerearly HMI RGB layer stays at top most layer */
		switch (resv_pipes[i]) {
		switch (resv_pipes[i].pipe_id) {
		case SSPP_VIG0:
			mixer_mask |= 0x7 << 0;
			mixer_ext_mask |= BIT(0);
@@ -285,20 +286,25 @@ static inline void sde_hw_ctl_get_splash_mixer_mask(const u32 *resv_pipes,
			mixer_mask |= 0x7 << 26;
			mixer_ext_mask |= BIT(6);
			break;
		/*
		 * If going here, that means the call comes from one
		 * NULL commit, so stage RGB pipe as the same stage level
		 * as that in bootloader splash.
		 */
		case SSPP_RGB0:
			mixer_mask |= 0x7 << 9;
			mixer_mask |= 0x2 << 9;
			mixer_ext_mask |= BIT(8);
			break;
		case SSPP_RGB1:
			mixer_mask |= 0x7 << 12;
			mixer_mask |= 0x2 << 12;
			mixer_ext_mask |= BIT(10);
			break;
		case SSPP_RGB2:
			mixer_mask |= 0x7 << 15;
			mixer_mask |= 0x2 << 15;
			mixer_ext_mask |= BIT(12);
			break;
		case SSPP_RGB3:
			mixer_mask |= 0x7 << 29;
			mixer_mask |= 0x2 << 29;
			mixer_ext_mask |= BIT(14);
			break;
		default:
@@ -364,7 +370,9 @@ static int sde_hw_ctl_wait_reset_status(struct sde_hw_ctl *ctx)
}

static void sde_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx,
		bool handoff, const u32 *resv_pipes, u32 resv_pipes_length)
	bool handoff,
	const struct splash_reserved_pipe_info *resv_pipes,
	u32 resv_pipes_length)
{
	struct sde_hw_blk_reg_map *c = &ctx->hw;
	int i;
@@ -402,7 +410,9 @@ static void sde_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx,

static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
	enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg, u32 index,
	bool handoff, const u32 *resv_pipes, u32 resv_pipes_length)
	bool handoff,
	const struct splash_reserved_pipe_info *resv_pipes,
	u32 resv_pipes_length)
{
	struct sde_hw_blk_reg_map *c = &ctx->hw;
	u32 mixercfg, mixercfg_ext, mix, ext, mixercfg_ext2;
+9 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include "sde_hw_mdss.h"
#include "sde_hw_util.h"
#include "sde_hw_catalog.h"
#include "sde_splash.h"

/**
 * sde_ctl_mode_sel: Interface mode selection
@@ -151,7 +152,9 @@ struct sde_hw_ctl_ops {
	 * @resv_pipes_length: array size of array reserved_pipes
	 */
	void (*clear_all_blendstages)(struct sde_hw_ctl *ctx,
		bool handoff, const u32 *resv_pipes, u32 resv_pipes_length);
		bool handoff,
		const struct splash_reserved_pipe_info *resv_pipes,
		u32 resv_pipes_length);

	/**
	 * Configure layer mixer to pipe configuration
@@ -164,7 +167,9 @@ struct sde_hw_ctl_ops {
	 */
	void (*setup_blendstage)(struct sde_hw_ctl *ctx,
		enum sde_lm lm, struct sde_hw_stage_cfg *cfg, u32 index,
		bool handoff, const u32 *resv_pipes, u32 resv_pipes_length);
		bool handoff,
		const struct splash_reserved_pipe_info *resv_pipes,
		u32 resv_pipes_length);

	/**
	 * read CTL_TOP register value for splash case
+31 −6
Original line number Diff line number Diff line
@@ -306,9 +306,10 @@ static void _sde_splash_sent_pipe_update_uevent(struct sde_kms *sde_kms)
	}

	for (i = 0; i < MAX_BLOCKS; i++) {
		if (sde_kms->splash_info.reserved_pipe_info[i] != 0xFFFFFFFF)
		if (sde_kms->splash_info.reserved_pipe_info[i].pipe_id !=
								0xFFFFFFFF)
			snprintf(event_string, SZ_4K, "pipe%d avialable",
				sde_kms->splash_info.reserved_pipe_info[i]);
			sde_kms->splash_info.reserved_pipe_info[i].pipe_id);
	}

	DRM_INFO("generating pipe update event[%s]", event_string);
@@ -401,6 +402,21 @@ static void _sde_splash_update_property(struct sde_kms *sde_kms)
					catalog->max_mixer_blendstages);
}

static void
_sde_splash_release_early_splash_layer(struct sde_splash_info *splash_info)
{
	int i = 0;

	for (i = 0; i < MAX_BLOCKS; i++) {
		if (splash_info->reserved_pipe_info[i].early_release) {
			splash_info->reserved_pipe_info[i].pipe_id =
								0xFFFFFFFF;
			splash_info->reserved_pipe_info[i].early_release =
								false;
		}
	}
}

__ref int sde_splash_init(struct sde_power_handle *phandle, struct msm_kms *kms)
{
	struct sde_kms *sde_kms;
@@ -522,8 +538,10 @@ int sde_splash_parse_reserved_plane_dt(struct drm_device *dev,
	if (!parent)
		return -EINVAL;

	for (i = 0; i < MAX_BLOCKS; i++)
		splash_info->reserved_pipe_info[i] = 0xFFFFFFFF;
	for (i = 0; i < MAX_BLOCKS; i++) {
		splash_info->reserved_pipe_info[i].pipe_id = 0xFFFFFFFF;
		splash_info->reserved_pipe_info[i].early_release = false;
	}

	i = 0;
	for_each_child_of_node(parent, node) {
@@ -536,8 +554,11 @@ int sde_splash_parse_reserved_plane_dt(struct drm_device *dev,

		of_property_for_each_string(node, "qcom,plane-name",
					prop, cname)
		splash_info->reserved_pipe_info[i] =
			splash_info->reserved_pipe_info[i].pipe_id =
					_sde_splash_parse_sspp_id(cfg, cname);

		splash_info->reserved_pipe_info[i].early_release =
			of_property_read_bool(node, "qcom,pipe-early-release");
		i++;
	}

@@ -560,7 +581,8 @@ bool sde_splash_query_plane_is_reserved(struct sde_splash_info *sinfo,
		return false;

	for (i = 0; i < MAX_BLOCKS; i++) {
		if (sinfo->reserved_pipe_info[i] == pipe)
		if (!sinfo->reserved_pipe_info[i].early_release &&
			(sinfo->reserved_pipe_info[i].pipe_id == pipe))
			return true;
	}

@@ -948,6 +970,9 @@ int sde_splash_lk_stop_splash(struct msm_kms *kms,
	mutex_lock(&sde_splash_lock);
	if (_sde_splash_validate_commit(sde_kms, state) &&
			sinfo->display_splash_enabled) {
		/* release splash RGB layer */
		_sde_splash_release_early_splash_layer(sinfo);

		if (_sde_splash_lk_check()) {
			_sde_splash_notify_lk_stop_splash();
			error = _sde_splash_clear_mixer_blendstage(kms, state);
Loading