dcn10_mpc.c 4.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/*
 * Copyright 2012-15 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: AMD
 *
 */

#include "reg_helper.h"
#include "dcn10_mpc.h"

#define REG(reg)\
30
	mpcc10->mpcc_regs->reg
31 32

#define CTX \
33
	mpcc10->base.ctx
34 35 36

#undef FN
#define FN(reg_name, field_name) \
37
	mpcc10->mpcc_shift->field_name, mpcc10->mpcc_mask->field_name
38

39 40
#define MODE_TOP_ONLY 1
#define MODE_BLEND 3
41 42
#define BLND_PP_ALPHA 0
#define BLND_GLOBAL_ALPHA 2
43

44

45 46 47
void dcn10_mpcc_set_bg_color(
		struct mpcc *mpcc,
		struct tg_color *bg_color)
48
{
49
	struct dcn10_mpcc *mpcc10 = TO_DCN10_MPCC(mpcc);
50 51 52 53 54 55 56 57
	/* mpc color is 12 bit.  tg_color is 10 bit */
	/* todo: might want to use 16 bit to represent color and have each
	 * hw block translate to correct color depth.
	 */
	uint32_t bg_r_cr = bg_color->color_r_cr << 2;
	uint32_t bg_g_y = bg_color->color_g_y << 2;
	uint32_t bg_b_cb = bg_color->color_b_cb << 2;

58
	REG_SET(MPCC_BG_R_CR, 0,
59
			MPCC_BG_R_CR, bg_r_cr);
60
	REG_SET(MPCC_BG_G_Y, 0,
61
			MPCC_BG_G_Y, bg_g_y);
62
	REG_SET(MPCC_BG_B_CB, 0,
63 64 65
			MPCC_BG_B_CB, bg_b_cb);
}

66
static void set_output_mux(struct dcn10_mpcc *mpcc10, int opp_id, int mpcc_id)
67
{
68 69
	ASSERT(mpcc10->base.opp_id == 0xf || opp_id == mpcc10->base.opp_id);
	mpcc10->base.opp_id = opp_id;
70 71
	REG_UPDATE(OPP_PIPE_CONTROL[opp_id], OPP_PIPE_CLOCK_EN, 1);
	REG_SET(MUX[opp_id], 0, MPC_OUT_MUX, mpcc_id);
72 73
}

74
static void reset_output_mux(struct dcn10_mpcc *mpcc10)
75
{
76 77 78
	REG_SET(MUX[mpcc10->base.opp_id], 0, MPC_OUT_MUX, 0xf);
	REG_UPDATE(OPP_PIPE_CONTROL[mpcc10->base.opp_id], OPP_PIPE_CLOCK_EN, 0);
	mpcc10->base.opp_id = 0xf;
79 80
}

81
static void dcn10_mpcc_set(struct mpcc *mpcc, struct mpcc_cfg *cfg)
82
{
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
	struct dcn10_mpcc *mpcc10 = TO_DCN10_MPCC(mpcc);
	int alpha_blnd_mode = cfg->per_pixel_alpha ?
			BLND_PP_ALPHA : BLND_GLOBAL_ALPHA;
	int mpcc_mode = cfg->bot_mpcc_id != 0xf ?
				MODE_BLEND : MODE_TOP_ONLY;

	REG_SET(MPCC_OPP_ID, 0,
		MPCC_OPP_ID, cfg->opp_id);

	REG_SET(MPCC_TOP_SEL, 0,
		MPCC_TOP_SEL, cfg->top_dpp_id);

	REG_SET(MPCC_BOT_SEL, 0,
		MPCC_BOT_SEL, cfg->bot_mpcc_id);

	REG_SET_4(MPCC_CONTROL, 0xffffffff,
		MPCC_MODE, mpcc_mode,
		MPCC_ALPHA_BLND_MODE, alpha_blnd_mode,
101
		MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha,
102 103 104 105 106
		MPCC_BLND_ACTIVE_OVERLAP_ONLY, cfg->top_of_tree);

	if (cfg->top_of_tree) {
		if (cfg->opp_id != 0xf)
			set_output_mux(mpcc10, cfg->opp_id, mpcc->inst);
107
		else if (mpcc->opp_id != 0xf)
108
			reset_output_mux(mpcc10);
109
	}
110
	mpcc10->base.opp_id = cfg->opp_id;
111 112
}

113
static void dcn10_mpcc_wait_idle(struct mpcc *mpcc)
114
{
115
	struct dcn10_mpcc *mpcc10 = TO_DCN10_MPCC(mpcc);
116

117
	REG_WAIT(MPCC_STATUS, MPCC_BUSY, 0, 1000, 1000);
118
}
119 120


121 122 123 124 125
const struct mpcc_funcs dcn10_mpcc_funcs = {
		.set = dcn10_mpcc_set,
		.wait_for_idle = dcn10_mpcc_wait_idle,
		.set_bg_color = dcn10_mpcc_set_bg_color,
};
126

127 128 129 130 131 132 133 134
void dcn10_mpcc_construct(struct dcn10_mpcc *mpcc10,
	struct dc_context *ctx,
	const struct dcn_mpcc_registers *mpcc_regs,
	const struct dcn_mpcc_shift *mpcc_shift,
	const struct dcn_mpcc_mask *mpcc_mask,
	int inst)
{
	mpcc10->base.ctx = ctx;
135

136 137
	mpcc10->base.inst = inst;
	mpcc10->base.funcs = &dcn10_mpcc_funcs;
138

139 140 141
	mpcc10->mpcc_regs = mpcc_regs;
	mpcc10->mpcc_shift = mpcc_shift;
	mpcc10->mpcc_mask = mpcc_mask;
142

143
	mpcc10->base.opp_id = inst;
144
}