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

Commit 06af1c70 authored by Guchun Chen's avatar Guchun Chen
Browse files

drm: msm: hw ctl needs to care reserved pipe



When kernel operates hw ctls, early RVC in bootloader
can also co-exist to update hardware registers. So it's
needed to care the reserved pipe by early RVC before
kernel starts to handle ctl setup.

CRs-Fixed: 2225630
Change-Id: I2df06350a44bd128dfb89cc0668c41d2edfb26a6
Signed-off-by: default avatarGuchun Chen <guchunc@codeaurora.org>
parent bf3bda0f
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -304,6 +304,8 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc)
	struct sde_crtc_mixer *mixer = sde_crtc->mixers;
	struct sde_hw_ctl *ctl;
	struct sde_hw_mixer *lm;
	struct sde_splash_info *sinfo;
	struct sde_kms *sde_kms = _sde_crtc_get_kms(crtc);

	int i;

@@ -314,6 +316,17 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc)
		return;
	}

	if (!sde_kms) {
		SDE_ERROR("invalid sde_kms\n");
		return;
	}

	sinfo = &sde_kms->splash_info;
	if (!sinfo) {
		SDE_ERROR("invalid splash info\n");
		return;
	}

	for (i = 0; i < sde_crtc->num_mixers; i++) {
		if (!mixer[i].hw_lm || !mixer[i].hw_ctl) {
			SDE_ERROR("invalid lm or ctl assigned to mixer\n");
@@ -323,7 +336,10 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc)
		mixer[i].flush_mask = 0;
		if (mixer[i].hw_ctl->ops.clear_all_blendstages)
			mixer[i].hw_ctl->ops.clear_all_blendstages(
					mixer[i].hw_ctl);
					mixer[i].hw_ctl,
					sinfo->handoff,
					sinfo->reserved_pipe_info,
					MAX_BLOCKS);
	}

	/* initialize stage cfg */
@@ -350,7 +366,8 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc)
			mixer[i].flush_mask);

		ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
			&sde_crtc->stage_cfg, i);
			&sde_crtc->stage_cfg, i,
			sinfo->handoff, sinfo->reserved_pipe_info, MAX_BLOCKS);
	}
}

+62 −4
Original line number Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-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
@@ -258,6 +258,35 @@ static inline int sde_hw_ctl_get_bitmask_cdm(struct sde_hw_ctl *ctx,
	return 0;
}

static inline int sde_hw_ctl_get_splash_mixercfg(const u32 *resv_pipes,
						u32 length)
{
	int i = 0;
	u32 mixercfg = 0;

	for (i = 0; i < length; i++) {
		/* LK's splash VIG layer always stays on top */
		switch (resv_pipes[i]) {
		case SSPP_VIG0:
			mixercfg |= 0x7 << 0;
			break;
		case SSPP_VIG1:
			mixercfg |= 0x7 << 3;
			break;
		case SSPP_VIG2:
			mixercfg |= 0x7 << 6;
			break;
		case SSPP_VIG3:
			mixercfg |= 0x7 << 26;
			break;
		default:
			break;
		}
	}

	return mixercfg;
}

static u32 sde_hw_ctl_poll_reset_status(struct sde_hw_ctl *ctx, u32 count)
{
	struct sde_hw_blk_reg_map *c = &ctx->hw;
@@ -312,15 +341,29 @@ static int sde_hw_ctl_wait_reset_status(struct sde_hw_ctl *ctx)
	return 0;
}

static void sde_hw_ctl_clear_all_blendstages(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)
{
	struct sde_hw_blk_reg_map *c = &ctx->hw;
	int i;

	for (i = 0; i < ctx->mixer_count; i++) {
		int mixer_id = ctx->mixer_hw_caps[i].id;
		u32 mixercfg = 0;

		SDE_REG_WRITE(c, CTL_LAYER(mixer_id), 0);
		/*
		 * if bootloaer still has early RVC running, mixer status
		 * can't be direcly cleared.
		 */
		if (handoff) {
			mixercfg =
				sde_hw_ctl_get_splash_mixercfg(resv_pipes,
						resv_pipes_length);

			mixercfg &= SDE_REG_READ(c, CTL_LAYER(mixer_id));
		}

		SDE_REG_WRITE(c, CTL_LAYER(mixer_id), mixercfg);
		SDE_REG_WRITE(c, CTL_LAYER_EXT(mixer_id), 0);
		SDE_REG_WRITE(c, CTL_LAYER_EXT2(mixer_id), 0);
		SDE_REG_WRITE(c, CTL_LAYER_EXT3(mixer_id), 0);
@@ -328,7 +371,8 @@ 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)
	enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg, u32 index,
	bool handoff, const u32 *resv_pipes, u32 resv_pipes_length)
{
	struct sde_hw_blk_reg_map *c = &ctx->hw;
	u32 mixercfg, mixercfg_ext, mix, ext, mixercfg_ext2;
@@ -353,6 +397,20 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
	mixercfg_ext = 0;
	mixercfg_ext2 = 0;

	/*
	 * if bootloader still have RVC running, its mixer stauts
	 * should be updated to kernel's mixer setup.
	 */
	if (handoff) {
		mixercfg =
			sde_hw_ctl_get_splash_mixercfg(resv_pipes,
						resv_pipes_length);

		mixercfg &= SDE_REG_READ(c, CTL_LAYER(lm));
		mixercfg |= BIT(24);
		stages--;
	}

	for (i = 0; i <= stages; i++) {
		/* overflow to ext register if 'i + 1 > 7' */
		mix = (i + 1) & 0x7;
+11 −3
Original line number Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-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
@@ -146,17 +146,25 @@ struct sde_hw_ctl_ops {
	/**
	 * Set all blend stages to disabled
	 * @ctx       : ctl path ctx pointer
	 * @handoff   : handoff flag
	 * @resv_pipes  : reserved pipes in DT
	 * @resv_pipes_length:    array size of array reserved_pipes
	 */
	void (*clear_all_blendstages)(struct sde_hw_ctl *ctx);
	void (*clear_all_blendstages)(struct sde_hw_ctl *ctx,
		bool handoff, const u32 *resv_pipes, u32 resv_pipes_length);

	/**
	 * Configure layer mixer to pipe configuration
	 * @ctx       : ctl path ctx pointer
	 * @lm        : layer mixer enumeration
	 * @cfg       : blend stage configuration
	 * @handoff   : handoff flag
	 * @resv_pipes  : reserved pipes in DT
	 * @resv_pipes_length:   array size of array reserved_pipes
	 */
	void (*setup_blendstage)(struct sde_hw_ctl *ctx,
		enum sde_lm lm, struct sde_hw_stage_cfg *cfg, u32 index);
		enum sde_lm lm, struct sde_hw_stage_cfg *cfg, u32 index,
		bool handoff, const u32 *resv_pipes, u32 resv_pipes_length);
};

/**