File Index
Files and directories
Sign in
FILE

dcn32_hubp.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c C
  1/*
  2 * Copyright 2012-20 Advanced Micro Devices, Inc.
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a
  5 * copy of this software and associated documentation files (the "Software"),
  6 * to deal in the Software without restriction, including without limitation
  7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 * and/or sell copies of the Software, and to permit persons to whom the
  9 * Software is furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice shall be included in
 12 * all copies or substantial portions of the Software.
 13 *
 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 20 * OTHER DEALINGS IN THE SOFTWARE.
 21 *
 22 * Authors: AMD
 23 *
 24 */
 25
 26#include "dm_services.h"
 27#include "dce_calcs.h"
 28#include "reg_helper.h"
 29#include "basics/conversion.h"
 30#include "dcn32_hubp.h"
 31
 32#define REG(reg)\
 33	hubp2->hubp_regs->reg
 34
 35#define CTX \
 36	hubp2->base.ctx
 37
 38#undef FN
 39#define FN(reg_name, field_name) \
 40	hubp2->hubp_shift->field_name, hubp2->hubp_mask->field_name
 41
 42void hubp32_update_force_pstate_disallow(struct hubp *hubp, bool pstate_disallow)
 43{
 44	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 45	REG_UPDATE_2(UCLK_PSTATE_FORCE,
 46			DATA_UCLK_PSTATE_FORCE_EN, pstate_disallow,
 47			DATA_UCLK_PSTATE_FORCE_VALUE, 0);
 48}
 49
 50void hubp32_update_force_cursor_pstate_disallow(struct hubp *hubp, bool pstate_disallow)
 51{
 52	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 53
 54	REG_UPDATE_2(UCLK_PSTATE_FORCE,
 55			CURSOR_UCLK_PSTATE_FORCE_EN, pstate_disallow,
 56			CURSOR_UCLK_PSTATE_FORCE_VALUE, 0);
 57}
 58
 59void hubp32_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor)
 60{
 61	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 62
 63	// Also cache cursor in MALL if using MALL for SS
 64	REG_UPDATE_2(DCHUBP_MALL_CONFIG, USE_MALL_SEL, mall_sel,
 65			USE_MALL_FOR_CURSOR, c_cursor);
 66}
 67
 68void hubp32_prepare_subvp_buffering(struct hubp *hubp, bool enable)
 69{
 70	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 71	REG_UPDATE(DCHUBP_VMPG_CONFIG, FORCE_ONE_ROW_FOR_FRAME, enable);
 72
 73	/* Programming guide suggests CURSOR_REQ_MODE = 1 for SubVP:
 74	 * For Pstate change using the MALL with sub-viewport buffering,
 75	 * the cursor does not use the MALL (USE_MALL_FOR_CURSOR is ignored)
 76	 * and sub-viewport positioning by Display FW has to avoid the cursor
 77	 * requests to DRAM (set CURSOR_REQ_MODE = 1 to minimize this exclusion).
 78	 *
 79	 * CURSOR_REQ_MODE = 1 begins fetching cursor data at the beginning of display prefetch.
 80	 * Setting this should allow the sub-viewport position to always avoid the cursor because
 81	 * we do not allow the sub-viewport region to overlap with display prefetch (i.e. during blank).
 82	 */
 83	REG_UPDATE(CURSOR_CONTROL, CURSOR_REQ_MODE, enable);
 84}
 85
 86void hubp32_phantom_hubp_post_enable(struct hubp *hubp)
 87{
 88	uint32_t reg_val;
 89	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 90
 91	/* For phantom pipe enable, disable GSL */
 92	REG_UPDATE(DCSURF_FLIP_CONTROL2, SURFACE_GSL_ENABLE, 0);
 93	REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, 1);
 94	reg_val = REG_READ(DCHUBP_CNTL);
 95	if (reg_val) {
 96		/* init sequence workaround: in case HUBP is
 97		 * power gated, this wait would timeout.
 98		 *
 99		 * we just wrote reg_val to non-0, if it stay 0
100		 * it means HUBP is gated
101		 */
102		REG_WAIT(DCHUBP_CNTL,
103				HUBP_NO_OUTSTANDING_REQ, 1,
104				1, 200);
105	}
106}
107
108void hubp32_cursor_set_attributes(
109		struct hubp *hubp,
110		const struct dc_cursor_attributes *attr)
111{
112	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
113	enum cursor_pitch hw_pitch = hubp1_get_cursor_pitch(attr->pitch);
114	enum cursor_lines_per_chunk lpc = hubp2_get_lines_per_chunk(
115			attr->width, attr->color_format);
116
117	//Round cursor width up to next multiple of 64
118	uint32_t cursor_width = ((attr->width + 63) / 64) * 64;
119	uint32_t cursor_height = attr->height;
120	uint32_t cursor_size = cursor_width * cursor_height;
121	bool use_mall_for_cursor;
122
123	switch (attr->color_format) {
124	case CURSOR_MODE_MONO:
125		cursor_size /= 2;
126		break;
127	case CURSOR_MODE_COLOR_1BIT_AND:
128	case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
129	case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
130		cursor_size *= 4;
131		break;
132
133	case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
134	case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
135	default:
136		cursor_size *= 8;
137		break;
138	}
139	use_mall_for_cursor = cursor_size > 16384 ? 1 : 0;
140
141	hubp->curs_attr = *attr;
142
143	if (!hubp->cursor_offload) {
144		REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
145				CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
146		REG_UPDATE(CURSOR_SURFACE_ADDRESS,
147				CURSOR_SURFACE_ADDRESS, attr->address.low_part);
148
149		REG_UPDATE_2(CURSOR_SIZE,
150				CURSOR_WIDTH, attr->width,
151				CURSOR_HEIGHT, attr->height);
152
153		REG_UPDATE_4(CURSOR_CONTROL,
154				CURSOR_MODE, attr->color_format,
155				CURSOR_2X_MAGNIFY, attr->attribute_flags.bits.ENABLE_MAGNIFICATION,
156				CURSOR_PITCH, hw_pitch,
157				CURSOR_LINES_PER_CHUNK, lpc);
158
159		REG_SET_2(CURSOR_SETTINGS, 0,
160				/* no shift of the cursor HDL schedule */
161				CURSOR0_DST_Y_OFFSET, 0,
162				 /* used to shift the cursor chunk request deadline */
163				CURSOR0_CHUNK_HDL_ADJUST, 3);
164
165		REG_UPDATE(DCHUBP_MALL_CONFIG, USE_MALL_FOR_CURSOR, use_mall_for_cursor);
166	}
167	hubp->att.SURFACE_ADDR_HIGH  = attr->address.high_part;
168	hubp->att.SURFACE_ADDR       = attr->address.low_part;
169	hubp->att.size.bits.width    = attr->width;
170	hubp->att.size.bits.height   = attr->height;
171	hubp->att.cur_ctl.bits.mode  = attr->color_format;
172
173	hubp->cur_rect.w = attr->width;
174	hubp->cur_rect.h = attr->height;
175
176	hubp->att.cur_ctl.bits.pitch = hw_pitch;
177	hubp->att.cur_ctl.bits.line_per_chunk = lpc;
178	hubp->att.cur_ctl.bits.cur_2x_magnify = attr->attribute_flags.bits.ENABLE_MAGNIFICATION;
179	hubp->att.settings.bits.dst_y_offset  = 0;
180	hubp->att.settings.bits.chunk_hdl_adjust = 3;
181	hubp->use_mall_for_cursor = use_mall_for_cursor;
182}
183void hubp32_init(struct hubp *hubp)
184{
185	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
186	REG_WRITE(HUBPREQ_DEBUG_DB, 1 << 8);
187
188	REG_UPDATE(DCHUBP_CNTL, HUBP_TTU_DISABLE, 0);
189}
190static struct hubp_funcs dcn32_hubp_funcs = {
191	.hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
192	.hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled,
193	.hubp_program_surface_flip_and_addr = hubp3_program_surface_flip_and_addr,
194	.hubp_program_surface_config = hubp3_program_surface_config,
195	.hubp_is_flip_pending = hubp2_is_flip_pending,
196	.hubp_setup = hubp3_setup,
197	.hubp_setup_interdependent = hubp2_setup_interdependent,
198	.hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings,
199	.set_blank = hubp2_set_blank,
200	.set_blank_regs = hubp2_set_blank_regs,
201	.dcc_control = hubp3_dcc_control,
202	.hubp_reset = hubp_reset,
203	.mem_program_viewport = min_set_viewport,
204	.set_cursor_attributes	= hubp32_cursor_set_attributes,
205	.set_cursor_position	= hubp2_cursor_set_position,
206	.hubp_clk_cntl = hubp2_clk_cntl,
207	.hubp_vtg_sel = hubp2_vtg_sel,
208	.dmdata_set_attributes = hubp3_dmdata_set_attributes,
209	.dmdata_load = hubp2_dmdata_load,
210	.dmdata_status_done = hubp2_dmdata_status_done,
211	.hubp_read_state = hubp3_read_state,
212	.hubp_clear_underflow = hubp2_clear_underflow,
213	.hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl,
214	.hubp_init = hubp3_init,
215	.set_unbounded_requesting = hubp31_set_unbounded_requesting,
216	.hubp_soft_reset = hubp31_soft_reset,
217	.hubp_set_flip_int = hubp1_set_flip_int,
218	.hubp_in_blank = hubp1_in_blank,
219	.hubp_update_force_pstate_disallow = hubp32_update_force_pstate_disallow,
220	.hubp_update_force_cursor_pstate_disallow = hubp32_update_force_cursor_pstate_disallow,
221	.phantom_hubp_post_enable = hubp32_phantom_hubp_post_enable,
222	.hubp_update_mall_sel = hubp32_update_mall_sel,
223	.hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
224	.hubp_clear_tiling = hubp3_clear_tiling,
225	.hubp_read_reg_state = hubp3_read_reg_state
226};
227
228bool hubp32_construct(
229	struct dcn20_hubp *hubp2,
230	struct dc_context *ctx,
231	uint32_t inst,
232	const struct dcn_hubp2_registers *hubp_regs,
233	const struct dcn_hubp2_shift *hubp_shift,
234	const struct dcn_hubp2_mask *hubp_mask)
235{
236	hubp2->base.funcs = &dcn32_hubp_funcs;
237	hubp2->base.ctx = ctx;
238	hubp2->hubp_regs = hubp_regs;
239	hubp2->hubp_shift = hubp_shift;
240	hubp2->hubp_mask = hubp_mask;
241	hubp2->base.inst = inst;
242	hubp2->base.opp_id = OPP_ID_INVALID;
243	hubp2->base.mpcc_id = 0xf;
244
245	return true;
246}
~/ Read-only file preview.