xref: /linux/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2026 Advanced Micro Devices, Inc.
4 
5 #include "dcn401/dcn401_hubp.h"
6 #include "dcn42_hubp.h"
7 #include "reg_helper.h"
8 
9 #define REG(reg) \
10 	hubp2->hubp_regs->reg
11 
12 #define CTX \
13 	hubp2->base.ctx
14 
15 #undef FN
16 #define FN(reg_name, field_name) \
17 	hubp2->hubp_shift->field_name, hubp2->hubp_mask->field_name
18 
19 static void hubp42_set_fgcg(struct hubp *hubp, bool enable)
20 {
21 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
22 
23 	/* Temporary workaround for IOMMU mismatch issue.
24 	 * Fine grain control via bit1 of debug flag.
25 	 */
26 	if (hubp->ctx->dc->debug.iommu_mismatch_temp_wka & 0x2)
27 		enable = false;
28 
29 	REG_UPDATE(HUBP_CLK_CNTL, HUBP_FGCG_REP_DIS, !enable);
30 }
31 
32 static void hubp42_init(struct hubp *hubp)
33 {
34 	hubp3_init(hubp);
35 
36 	hubp42_set_fgcg(hubp, hubp->ctx->dc->debug.enable_fine_grain_clock_gating.bits.dchub);
37 
38 	/*do nothing for now for dcn3.5 or later*/
39 }
40 
41 static void hubp42_program_pixel_format(
42 	struct hubp *hubp,
43 	enum surface_pixel_format format)
44 {
45 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
46 	uint32_t green_bar = 1;
47 	uint32_t red_bar = 3;
48 	uint32_t blue_bar = 2;
49 
50 	/* swap for ABGR format */
51 	if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
52 			|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
53 			|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
54 			|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616
55 			|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
56 		red_bar = 2;
57 		blue_bar = 3;
58 	}
59 
60 	REG_UPDATE_3(HUBPRET_CONTROL,
61 			CROSSBAR_SRC_Y_G, green_bar,
62 			CROSSBAR_SRC_CB_B, blue_bar,
63 			CROSSBAR_SRC_CR_R, red_bar);
64 
65 	/* Mapping is same as ipp programming (cnvc) */
66 
67 	switch (format)	{
68 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
69 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
70 				SURFACE_PIXEL_FORMAT, 1);
71 		break;
72 	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
73 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
74 				SURFACE_PIXEL_FORMAT, 3);
75 		break;
76 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
77 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
78 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
79 				SURFACE_PIXEL_FORMAT, 8);
80 		break;
81 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
82 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
83 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
84 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
85 				SURFACE_PIXEL_FORMAT, 10);
86 		break;
87 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
88 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: /* we use crossbar already */
89 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
90 				SURFACE_PIXEL_FORMAT, 26); /* ARGB16161616_UNORM */
91 		break;
92 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
93 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:/*we use crossbar already*/
94 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
95 				SURFACE_PIXEL_FORMAT, 24);
96 		break;
97 
98 	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
99 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
100 				SURFACE_PIXEL_FORMAT, 65);
101 		break;
102 	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
103 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
104 				SURFACE_PIXEL_FORMAT, 64);
105 		break;
106 	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
107 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
108 				SURFACE_PIXEL_FORMAT, 67);
109 		break;
110 	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
111 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
112 				SURFACE_PIXEL_FORMAT, 66);
113 		break;
114 	case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
115 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
116 				SURFACE_PIXEL_FORMAT, 12);
117 		break;
118 	case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
119 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
120 				SURFACE_PIXEL_FORMAT, 112);
121 		break;
122 	case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
123 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
124 				SURFACE_PIXEL_FORMAT, 113);
125 		break;
126 	case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
127 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
128 				SURFACE_PIXEL_FORMAT, 114);
129 		break;
130 	case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
131 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
132 				SURFACE_PIXEL_FORMAT, 118);
133 		break;
134 	case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
135 		REG_UPDATE(DCSURF_SURFACE_CONFIG,
136 				SURFACE_PIXEL_FORMAT, 119);
137 		break;
138 	case SURFACE_PIXEL_FORMAT_GRPH_RGBE:
139 		REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
140 				SURFACE_PIXEL_FORMAT, 116,
141 				ALPHA_PLANE_EN, 0);
142 		break;
143 	case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
144 		REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
145 				SURFACE_PIXEL_FORMAT, 116,
146 				ALPHA_PLANE_EN, 1);
147 		break;
148 	default:
149 		BREAK_TO_DEBUGGER();
150 		break;
151 	}
152 
153 	/* don't see the need of program the xbar in DCN 1.0 */
154 }
155 
156 static void hubp42_program_deadline(
157 		struct hubp *hubp,
158 		struct dml2_display_dlg_regs *dlg_attr,
159 		struct dml2_display_ttu_regs *ttu_attr)
160 {
161 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
162 
163 	/* put DLG in mission mode */
164 	REG_WRITE(HUBPREQ_DEBUG_DB, 0);
165 
166 	/* DLG - Per hubp */
167 	REG_SET_2(BLANK_OFFSET_0, 0,
168 		REFCYC_H_BLANK_END, dlg_attr->refcyc_h_blank_end,
169 		DLG_V_BLANK_END, dlg_attr->dlg_vblank_end);
170 
171 	REG_SET(BLANK_OFFSET_1, 0,
172 		MIN_DST_Y_NEXT_START, dlg_attr->min_dst_y_next_start);
173 
174 	REG_SET(DST_DIMENSIONS, 0,
175 		REFCYC_PER_HTOTAL, dlg_attr->refcyc_per_htotal);
176 
177 	REG_SET_2(DST_AFTER_SCALER, 0,
178 		REFCYC_X_AFTER_SCALER, dlg_attr->refcyc_x_after_scaler,
179 		DST_Y_AFTER_SCALER, dlg_attr->dst_y_after_scaler);
180 
181 	REG_SET(REF_FREQ_TO_PIX_FREQ, 0,
182 		REF_FREQ_TO_PIX_FREQ, dlg_attr->ref_freq_to_pix_freq);
183 
184 	/* DLG - Per luma/chroma */
185 	REG_SET(VBLANK_PARAMETERS_1, 0,
186 		REFCYC_PER_PTE_GROUP_VBLANK_L, dlg_attr->refcyc_per_pte_group_vblank_l);
187 
188 	if (REG(NOM_PARAMETERS_0))
189 		REG_SET(NOM_PARAMETERS_0, 0,
190 			DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l);
191 
192 	if (REG(NOM_PARAMETERS_1))
193 		REG_SET(NOM_PARAMETERS_1, 0,
194 			REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l);
195 
196 	REG_SET(NOM_PARAMETERS_4, 0,
197 		DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l);
198 
199 	REG_SET(NOM_PARAMETERS_5, 0,
200 		REFCYC_PER_META_CHUNK_NOM_L, dlg_attr->refcyc_per_meta_chunk_nom_l);
201 
202 	REG_SET_2(PER_LINE_DELIVERY, 0,
203 		REFCYC_PER_LINE_DELIVERY_L, dlg_attr->refcyc_per_line_delivery_l,
204 		REFCYC_PER_LINE_DELIVERY_C, dlg_attr->refcyc_per_line_delivery_c);
205 
206 	REG_SET(VBLANK_PARAMETERS_2, 0,
207 		REFCYC_PER_PTE_GROUP_VBLANK_C, dlg_attr->refcyc_per_pte_group_vblank_c);
208 
209 	if (REG(NOM_PARAMETERS_2))
210 		REG_SET(NOM_PARAMETERS_2, 0,
211 			DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c);
212 
213 	if (REG(NOM_PARAMETERS_3))
214 		REG_SET(NOM_PARAMETERS_3, 0,
215 			REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c);
216 
217 	REG_SET(NOM_PARAMETERS_6, 0,
218 		DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c);
219 
220 	REG_SET(NOM_PARAMETERS_7, 0,
221 		REFCYC_PER_META_CHUNK_NOM_C, dlg_attr->refcyc_per_meta_chunk_nom_c);
222 
223 	/* TTU - per hubp */
224 	REG_SET_2(DCN_TTU_QOS_WM, 0,
225 		QoS_LEVEL_LOW_WM, ttu_attr->qos_level_low_wm,
226 		QoS_LEVEL_HIGH_WM, ttu_attr->qos_level_high_wm);
227 
228 	/* TTU - per luma/chroma */
229 	/* Assumed surf0 is luma and 1 is chroma */
230 
231 	REG_SET_3(DCN_SURF0_TTU_CNTL0, 0,
232 		REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_l,
233 		QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_l,
234 		QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_l);
235 
236 	REG_SET_3(DCN_SURF1_TTU_CNTL0, 0,
237 		REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_c,
238 		QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_c,
239 		QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_c);
240 
241 	REG_SET_3(DCN_CUR0_TTU_CNTL0, 0,
242 		REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_cur0,
243 		QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_cur0,
244 		QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_cur0);
245 
246 	REG_SET(FLIP_PARAMETERS_1, 0,
247 		REFCYC_PER_PTE_GROUP_FLIP_L, dlg_attr->refcyc_per_pte_group_flip_l);
248 	REG_SET(HUBP_3DLUT_DLG_PARAM, 0, REFCYC_PER_3DLUT_GROUP, dlg_attr->refcyc_per_tdlut_group);
249 
250 	REG_UPDATE(DCN_DMDATA_VM_CNTL,
251 			REFCYC_PER_VM_DMDATA, dlg_attr->refcyc_per_vm_dmdata);
252 }
253 
254 void hubp42_program_requestor(
255 		struct hubp *hubp,
256 		struct dml2_display_rq_regs *rq_regs)
257 {
258 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
259 
260 	REG_UPDATE(HUBPRET_CONTROL,
261 			DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address);
262 	REG_SET_4(DCN_EXPANSION_MODE, 0,
263 			DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode,
264 			PRQ_EXPANSION_MODE, rq_regs->prq_expansion_mode,
265 			MRQ_EXPANSION_MODE, rq_regs->mrq_expansion_mode,
266 			CRQ_EXPANSION_MODE, rq_regs->crq_expansion_mode);
267 	REG_SET_8(DCHUBP_REQ_SIZE_CONFIG, 0,
268 		CHUNK_SIZE, rq_regs->rq_regs_l.chunk_size,
269 		MIN_CHUNK_SIZE, rq_regs->rq_regs_l.min_chunk_size,
270 		META_CHUNK_SIZE, rq_regs->rq_regs_l.meta_chunk_size,
271 		MIN_META_CHUNK_SIZE, rq_regs->rq_regs_l.min_meta_chunk_size,
272 		DPTE_GROUP_SIZE, rq_regs->rq_regs_l.dpte_group_size,
273 		VM_GROUP_SIZE, rq_regs->rq_regs_l.mpte_group_size,
274 		SWATH_HEIGHT, rq_regs->rq_regs_l.swath_height,
275 		PTE_ROW_HEIGHT_LINEAR, rq_regs->rq_regs_l.pte_row_height_linear);
276 	REG_SET_7(DCHUBP_REQ_SIZE_CONFIG_C, 0,
277 		CHUNK_SIZE_C, rq_regs->rq_regs_c.chunk_size,
278 		MIN_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_chunk_size,
279 		META_CHUNK_SIZE_C, rq_regs->rq_regs_c.meta_chunk_size,
280 		MIN_META_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_meta_chunk_size,
281 		DPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.dpte_group_size,
282 		SWATH_HEIGHT_C, rq_regs->rq_regs_c.swath_height,
283 		PTE_ROW_HEIGHT_LINEAR_C, rq_regs->rq_regs_c.pte_row_height_linear);
284 }
285 
286 
287 void hubp42_setup(
288 		struct hubp *hubp,
289 	    struct dml2_dchub_per_pipe_register_set *pipe_regs,
290 		union dml2_global_sync_programming *pipe_global_sync,
291 		struct dc_crtc_timing *timing)
292 {
293 	/* otg is locked when this func is called. Register are double buffered.
294 	 * disable the requestors is not needed
295 	 */
296 	hubp401_vready_at_or_After_vsync(hubp, pipe_global_sync, timing);
297 	hubp42_program_requestor(hubp, &pipe_regs->rq_regs);
298 	hubp42_program_deadline(hubp, &pipe_regs->dlg_regs, &pipe_regs->ttu_regs);
299 }
300 static void hubp42_program_surface_config(
301 	struct hubp *hubp,
302 	enum surface_pixel_format format,
303 	struct dc_tiling_info *tiling_info,
304 	struct plane_size *plane_size,
305 	enum dc_rotation_angle rotation,
306 	struct dc_plane_dcc_param *dcc,
307 	bool horizontal_mirror,
308 	unsigned int compat_level)
309 {
310 	(void)compat_level;
311 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
312 
313 	hubp3_dcc_control_sienna_cichlid(hubp, dcc);
314 	hubp3_program_tiling(hubp2, tiling_info, format);
315 	hubp2_program_size(hubp, format, plane_size, dcc);
316 	hubp2_program_rotation(hubp, rotation, horizontal_mirror);
317 	hubp42_program_pixel_format(hubp, format);
318 }
319 
320 static void hubp42_get_3dlut_fl_xbar_map(
321 		const enum dc_cm_lut_pixel_format format,
322 		enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_y_g,
323 		enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cb_b,
324 		enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cr_r)
325 {
326 	switch (format) {
327 	case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB:
328 	case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB:
329 	case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10:
330 		/* BGRA */
331 		*bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
332 		*bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
333 		*bit_slice_cb_b =  hubp_3dlut_fl_crossbar_bit_slice_0_15;
334 		break;
335 	case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
336 	case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
337 	case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
338 	default:
339 		/* RGBA */
340 		*bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
341 		*bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
342 		*bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
343 		break;
344 	}
345 }
346 
347 void hubp42_program_3dlut_fl_crossbar(struct hubp *hubp,
348 		const enum dc_cm_lut_pixel_format format)
349 {
350 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
351 
352 	enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g = 0;
353 	enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b = 0;
354 	enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r = 0;
355 
356 	hubp42_get_3dlut_fl_xbar_map(format,
357 			&bit_slice_g,
358 			&bit_slice_b,
359 			&bit_slice_r);
360 
361 	REG_UPDATE_3(HUBP_3DLUT_CONTROL,
362 		HUBP_3DLUT_CROSSBAR_SEL_R, bit_slice_r,
363 		HUBP_3DLUT_CROSSBAR_SEL_G, bit_slice_g,
364 		HUBP_3DLUT_CROSSBAR_SEL_B, bit_slice_b);
365 }
366 
367 static uint32_t hubp42_get_3dlut_fl_mpc_width(
368 		const enum dc_cm_lut_size size)
369 {
370 	uint32_t width = 0;
371 
372 	switch (size) {
373 	case CM_LUT_SIZE_333333:
374 		width = 1;
375 		break;
376 	case CM_LUT_SIZE_171717:
377 	default:
378 		width = 0;
379 		break;
380 	}
381 
382 	return width;
383 }
384 
385 void hubp42_program_3dlut_fl_config(struct hubp *hubp,
386 		const struct dc_3dlut_dma *config)
387 {
388 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
389 
390 	uint32_t mpc_width = hubp42_get_3dlut_fl_mpc_width(config->size);
391 
392 	REG_UPDATE(HUBP_3DLUT_CONTROL,
393 			HUBP_3DLUT_MPC_WIDTH, mpc_width);
394 
395 	hubp401_program_3dlut_fl_config(hubp, config);
396 }
397 
398 static bool hubp42_program_surface_flip_and_addr(
399 	struct hubp *hubp,
400 	const struct dc_plane_address *address,
401 	bool flip_immediate)
402 {
403 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
404 
405 	//program flip type
406 	REG_UPDATE(DCSURF_FLIP_CONTROL,
407 			SURFACE_FLIP_TYPE, flip_immediate);
408 
409 	// Program VMID reg
410 	if (flip_immediate == 0)
411 		REG_UPDATE(VMID_SETTINGS_0,
412 			VMID, address->vmid);
413 
414 	if (address->type == PLN_ADDR_TYPE_GRPH_STEREO) {
415 		REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0);
416 		REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x1);
417 
418 	} else {
419 		// turn off stereo if not in stereo
420 		REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x0);
421 		REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x0);
422 	}
423 
424 	/* HW automatically latch rest of address register on write to
425 	 * DCSURF_PRIMARY_SURFACE_ADDRESS if SURFACE_UPDATE_LOCK is not used
426 	 *
427 	 * program high first and then the low addr, order matters!
428 	 */
429 	switch (address->type) {
430 	case PLN_ADDR_TYPE_GRAPHICS:
431 		/* DCN1.0 does not support const color
432 		 * TODO: program DCHUBBUB_RET_PATH_DCC_CFGx_0/1
433 		 * base on address->grph.dcc_const_color
434 		 * x = 0, 2, 4, 6 for pipe 0, 1, 2, 3 for rgb and luma
435 		 * x = 1, 3, 5, 7 for pipe 0, 1, 2, 3 for chroma
436 		 */
437 
438 		if (address->grph.addr.quad_part == 0)
439 			break;
440 
441 		REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
442 				PRIMARY_SURFACE_TMZ, address->tmz_surface,
443 				PRIMARY_META_SURFACE_TMZ, address->tmz_surface);
444 
445 		if (address->grph.meta_addr.quad_part != 0) {
446 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
447 					PRIMARY_META_SURFACE_ADDRESS_HIGH,
448 					address->grph.meta_addr.high_part);
449 
450 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
451 					PRIMARY_META_SURFACE_ADDRESS,
452 					address->grph.meta_addr.low_part);
453 		}
454 
455 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
456 				PRIMARY_SURFACE_ADDRESS_HIGH,
457 				address->grph.addr.high_part);
458 
459 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
460 				PRIMARY_SURFACE_ADDRESS,
461 				address->grph.addr.low_part);
462 		break;
463 	case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
464 		if (address->video_progressive.luma_addr.quad_part == 0
465 				|| address->video_progressive.chroma_addr.quad_part == 0)
466 			break;
467 
468 		REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
469 				PRIMARY_SURFACE_TMZ, address->tmz_surface,
470 				PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
471 				PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
472 				PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
473 
474 		if (address->video_progressive.luma_meta_addr.quad_part != 0) {
475 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
476 					PRIMARY_META_SURFACE_ADDRESS_HIGH_C,
477 					address->video_progressive.chroma_meta_addr.high_part);
478 
479 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0,
480 					PRIMARY_META_SURFACE_ADDRESS_C,
481 					address->video_progressive.chroma_meta_addr.low_part);
482 
483 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
484 					PRIMARY_META_SURFACE_ADDRESS_HIGH,
485 					address->video_progressive.luma_meta_addr.high_part);
486 
487 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
488 					PRIMARY_META_SURFACE_ADDRESS,
489 					address->video_progressive.luma_meta_addr.low_part);
490 		}
491 
492 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
493 				PRIMARY_SURFACE_ADDRESS_HIGH_C,
494 				address->video_progressive.chroma_addr.high_part);
495 
496 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
497 				PRIMARY_SURFACE_ADDRESS_C,
498 				address->video_progressive.chroma_addr.low_part);
499 
500 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
501 				PRIMARY_SURFACE_ADDRESS_HIGH,
502 				address->video_progressive.luma_addr.high_part);
503 
504 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
505 				PRIMARY_SURFACE_ADDRESS,
506 				address->video_progressive.luma_addr.low_part);
507 		break;
508 	case PLN_ADDR_TYPE_GRPH_STEREO:
509 		if (address->grph_stereo.left_addr.quad_part == 0)
510 			break;
511 		if (address->grph_stereo.right_addr.quad_part == 0)
512 			break;
513 
514 		REG_UPDATE_8(DCSURF_SURFACE_CONTROL,
515 				PRIMARY_SURFACE_TMZ, address->tmz_surface,
516 				PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
517 				PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
518 				PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface,
519 				SECONDARY_SURFACE_TMZ, address->tmz_surface,
520 				SECONDARY_SURFACE_TMZ_C, address->tmz_surface,
521 				SECONDARY_META_SURFACE_TMZ, address->tmz_surface,
522 				SECONDARY_META_SURFACE_TMZ_C, address->tmz_surface);
523 
524 		if (address->grph_stereo.right_meta_addr.quad_part != 0) {
525 
526 			REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_C, 0,
527 				SECONDARY_META_SURFACE_ADDRESS_HIGH_C,
528 				address->grph_stereo.right_alpha_meta_addr.high_part);
529 
530 			REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_C, 0,
531 				SECONDARY_META_SURFACE_ADDRESS_C,
532 				address->grph_stereo.right_alpha_meta_addr.low_part);
533 
534 			REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0,
535 					SECONDARY_META_SURFACE_ADDRESS_HIGH,
536 					address->grph_stereo.right_meta_addr.high_part);
537 
538 			REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0,
539 					SECONDARY_META_SURFACE_ADDRESS,
540 					address->grph_stereo.right_meta_addr.low_part);
541 		}
542 		if (address->grph_stereo.left_meta_addr.quad_part != 0) {
543 
544 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
545 				PRIMARY_META_SURFACE_ADDRESS_HIGH_C,
546 				address->grph_stereo.left_alpha_meta_addr.high_part);
547 
548 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0,
549 				PRIMARY_META_SURFACE_ADDRESS_C,
550 				address->grph_stereo.left_alpha_meta_addr.low_part);
551 
552 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
553 					PRIMARY_META_SURFACE_ADDRESS_HIGH,
554 					address->grph_stereo.left_meta_addr.high_part);
555 
556 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
557 					PRIMARY_META_SURFACE_ADDRESS,
558 					address->grph_stereo.left_meta_addr.low_part);
559 		}
560 
561 		REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C, 0,
562 				SECONDARY_SURFACE_ADDRESS_HIGH_C,
563 				address->grph_stereo.right_alpha_addr.high_part);
564 
565 		REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_C, 0,
566 				SECONDARY_SURFACE_ADDRESS_C,
567 				address->grph_stereo.right_alpha_addr.low_part);
568 
569 		REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
570 				SECONDARY_SURFACE_ADDRESS_HIGH,
571 				address->grph_stereo.right_addr.high_part);
572 
573 		REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0,
574 				SECONDARY_SURFACE_ADDRESS,
575 				address->grph_stereo.right_addr.low_part);
576 
577 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
578 				PRIMARY_SURFACE_ADDRESS_HIGH_C,
579 				address->grph_stereo.left_alpha_addr.high_part);
580 
581 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
582 				PRIMARY_SURFACE_ADDRESS_C,
583 				address->grph_stereo.left_alpha_addr.low_part);
584 
585 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
586 				PRIMARY_SURFACE_ADDRESS_HIGH,
587 				address->grph_stereo.left_addr.high_part);
588 
589 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
590 				PRIMARY_SURFACE_ADDRESS,
591 				address->grph_stereo.left_addr.low_part);
592 		break;
593 	case PLN_ADDR_TYPE_RGBEA:
594 		if (address->rgbea.addr.quad_part == 0
595 				|| address->rgbea.alpha_addr.quad_part == 0)
596 			break;
597 
598 		REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
599 				PRIMARY_SURFACE_TMZ, address->tmz_surface,
600 				PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
601 				PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
602 				PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
603 
604 		if (address->rgbea.meta_addr.quad_part != 0) {
605 
606 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
607 					PRIMARY_META_SURFACE_ADDRESS_HIGH_C,
608 					address->rgbea.alpha_meta_addr.high_part);
609 
610 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0,
611 					PRIMARY_META_SURFACE_ADDRESS_C,
612 					address->rgbea.alpha_meta_addr.low_part);
613 
614 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
615 					PRIMARY_META_SURFACE_ADDRESS_HIGH,
616 					address->rgbea.meta_addr.high_part);
617 
618 			REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
619 					PRIMARY_META_SURFACE_ADDRESS,
620 					address->rgbea.meta_addr.low_part);
621 		}
622 
623 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
624 				PRIMARY_SURFACE_ADDRESS_HIGH_C,
625 				address->rgbea.alpha_addr.high_part);
626 
627 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
628 				PRIMARY_SURFACE_ADDRESS_C,
629 				address->rgbea.alpha_addr.low_part);
630 
631 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
632 				PRIMARY_SURFACE_ADDRESS_HIGH,
633 				address->rgbea.addr.high_part);
634 
635 		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
636 				PRIMARY_SURFACE_ADDRESS,
637 				address->rgbea.addr.low_part);
638 		break;
639 	default:
640 		BREAK_TO_DEBUGGER();
641 		break;
642 	}
643 
644 	hubp->request_address = *address;
645 
646 	return true;
647 }
648 void hubp42_setup_interdependent(
649 		struct hubp *hubp,
650 		struct dml2_dchub_per_pipe_register_set *pipe_regs)
651 {
652 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
653 
654 	REG_SET_2(PREFETCH_SETTINGS, 0,
655 			DST_Y_PREFETCH, pipe_regs->dlg_regs.dst_y_prefetch,
656 			VRATIO_PREFETCH, pipe_regs->dlg_regs.vratio_prefetch);
657 
658 	REG_SET(PREFETCH_SETTINGS_C, 0,
659 			VRATIO_PREFETCH_C, pipe_regs->dlg_regs.vratio_prefetch_c);
660 
661 	REG_SET_2(VBLANK_PARAMETERS_0, 0,
662 		DST_Y_PER_VM_VBLANK, pipe_regs->dlg_regs.dst_y_per_vm_vblank,
663 		DST_Y_PER_ROW_VBLANK, pipe_regs->dlg_regs.dst_y_per_row_vblank);
664 
665 	REG_SET_2(FLIP_PARAMETERS_0, 0,
666 		DST_Y_PER_VM_FLIP, pipe_regs->dlg_regs.dst_y_per_vm_flip,
667 		DST_Y_PER_ROW_FLIP, pipe_regs->dlg_regs.dst_y_per_row_flip);
668 
669 	REG_SET(VBLANK_PARAMETERS_3, 0,
670 		REFCYC_PER_META_CHUNK_VBLANK_L, pipe_regs->dlg_regs.refcyc_per_meta_chunk_vblank_l);
671 
672 	REG_SET(VBLANK_PARAMETERS_4, 0,
673 		REFCYC_PER_META_CHUNK_VBLANK_C, pipe_regs->dlg_regs.refcyc_per_meta_chunk_vblank_c);
674 
675 	REG_SET(FLIP_PARAMETERS_2, 0,
676 		REFCYC_PER_META_CHUNK_FLIP_L, pipe_regs->dlg_regs.refcyc_per_meta_chunk_flip_l);
677 
678 	REG_SET_2(PER_LINE_DELIVERY_PRE, 0,
679 		REFCYC_PER_LINE_DELIVERY_PRE_L, pipe_regs->dlg_regs.refcyc_per_line_delivery_pre_l,
680 		REFCYC_PER_LINE_DELIVERY_PRE_C, pipe_regs->dlg_regs.refcyc_per_line_delivery_pre_c);
681 
682 	REG_SET(DCN_SURF0_TTU_CNTL1, 0,
683 		REFCYC_PER_REQ_DELIVERY_PRE,
684 		pipe_regs->ttu_regs.refcyc_per_req_delivery_pre_l);
685 	REG_SET(DCN_SURF1_TTU_CNTL1, 0,
686 		REFCYC_PER_REQ_DELIVERY_PRE,
687 		pipe_regs->ttu_regs.refcyc_per_req_delivery_pre_c);
688 	REG_SET(DCN_CUR0_TTU_CNTL1, 0,
689 		REFCYC_PER_REQ_DELIVERY_PRE, pipe_regs->ttu_regs.refcyc_per_req_delivery_pre_cur0);
690 
691 	REG_SET_2(DCN_GLOBAL_TTU_CNTL, 0,
692 		MIN_TTU_VBLANK, pipe_regs->ttu_regs.min_ttu_vblank,
693 		QoS_LEVEL_FLIP, pipe_regs->ttu_regs.qos_level_flip);
694 
695 	REG_SET(DST_Y_DELTA_DRQ_LIMIT, 0,
696 		DST_Y_DELTA_DRQ_LIMIT, pipe_regs->dlg_regs.dst_y_delta_drq_limit);
697 }
698 struct hubp_funcs dcn42_hubp_funcs = {
699 	.hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
700 	.hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled,
701 	.hubp_program_surface_flip_and_addr = hubp42_program_surface_flip_and_addr,
702 	.hubp_program_surface_config = hubp42_program_surface_config,
703 	.hubp_is_flip_pending = hubp2_is_flip_pending,
704 	.hubp_setup2 = hubp42_setup,
705 	.hubp_setup_interdependent2 = hubp42_setup_interdependent,
706 	.hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings,
707 	.set_blank = hubp2_set_blank,
708 	.set_blank_regs = hubp2_set_blank_regs,
709 	.dcc_control = hubp3_dcc_control,
710 	.hubp_reset = hubp_reset,
711 	.mem_program_viewport = min_set_viewport,
712 	.set_cursor_attributes	= hubp32_cursor_set_attributes,
713 	.set_cursor_position	= hubp401_cursor_set_position,
714 	.hubp_clk_cntl = hubp2_clk_cntl,
715 	.hubp_vtg_sel = hubp2_vtg_sel,
716 	.dmdata_set_attributes = hubp3_dmdata_set_attributes,
717 	.dmdata_load = hubp2_dmdata_load,
718 	.dmdata_status_done = hubp2_dmdata_status_done,
719 	.hubp_read_state = hubp42_read_state,
720 	.hubp_clear_underflow = hubp2_clear_underflow,
721 	.hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl,
722 	.hubp_init = hubp42_init,
723 	.set_unbounded_requesting = hubp31_set_unbounded_requesting,
724 	.hubp_soft_reset = hubp31_soft_reset,
725 	.hubp_set_flip_int = hubp1_set_flip_int,
726 	.hubp_in_blank = hubp1_in_blank,
727 	.program_extended_blank = hubp31_program_extended_blank_value,
728 	.hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
729 	.hubp_program_3dlut_fl_config = hubp42_program_3dlut_fl_config,
730 	.hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
731 	.hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
732 	.hubp_program_3dlut_fl_crossbar = hubp42_program_3dlut_fl_crossbar,
733 	.hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
734 	.hubp_clear_tiling = hubp3_clear_tiling,
735 	.hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config,
736 	.hubp_read_reg_state = hubp3_read_reg_state
737 };
738 
739 bool hubp42_construct(
740 	struct dcn20_hubp *hubp2,
741 	struct dc_context *ctx,
742 	uint32_t inst,
743 	const struct dcn_hubp2_registers *hubp_regs,
744 	const struct dcn_hubp2_shift *hubp_shift,
745 	const struct dcn_hubp2_mask *hubp_mask)
746 {
747 	hubp2->base.funcs = &dcn42_hubp_funcs;
748 	hubp2->base.ctx = ctx;
749 	hubp2->hubp_regs = hubp_regs;
750 	hubp2->hubp_shift = hubp_shift;
751 	hubp2->hubp_mask = hubp_mask;
752 	hubp2->base.inst = inst;
753 	hubp2->base.opp_id = OPP_ID_INVALID;
754 	hubp2->base.mpcc_id = 0xf;
755 
756 	return true;
757 }
758 
759 
760 void hubp42_read_state(struct hubp *hubp)
761 {
762 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
763 	struct dcn_hubp_state *s = &hubp2->state;
764 	struct dcn_fl_regs_st *fl_regs = &s->fl_regs;
765 
766 	hubp401_read_state(hubp);
767 
768 	/* CONTROL */
769 	REG_GET_5(HUBP_3DLUT_CONTROL,
770 			HUBP_3DLUT_ENABLE, &fl_regs->lut_enable,
771 			HUBP_3DLUT_DONE, &fl_regs->lut_done,
772 			HUBP_3DLUT_ADDRESSING_MODE, &fl_regs->lut_addr_mode,
773 			HUBP_3DLUT_WIDTH, &fl_regs->lut_width,
774 			HUBP_3DLUT_MPC_WIDTH, &fl_regs->lut_mpc_width);
775 
776 	REG_GET_4(HUBP_3DLUT_CONTROL,
777 			HUBP_3DLUT_TMZ, &fl_regs->lut_tmz,
778 			HUBP_3DLUT_CROSSBAR_SEL_R, &fl_regs->lut_crossbar_sel_r,
779 			HUBP_3DLUT_CROSSBAR_SEL_G, &fl_regs->lut_crossbar_sel_g,
780 			HUBP_3DLUT_CROSSBAR_SEL_B, &fl_regs->lut_crossbar_sel_b);
781 
782 	/* ADDR */
783 	REG_GET(HUBP_3DLUT_ADDRESS_HIGH,
784 			HUBP_3DLUT_ADDRESS_HIGH, &fl_regs->lut_addr_hi);
785 	REG_GET(HUBP_3DLUT_ADDRESS_LOW,
786 			HUBP_3DLUT_ADDRESS_LOW, &fl_regs->lut_addr_lo);
787 	/* CLK */
788 	REG_GET(HUBP_3DLUT_DLG_PARAM,
789 			REFCYC_PER_3DLUT_GROUP, &fl_regs->refcyc_3dlut_group);
790 	/* FL */
791 	REG_GET_2(_3DLUT_FL_BIAS_SCALE,
792 		HUBP0_3DLUT_FL_BIAS, &fl_regs->lut_fl_bias,
793 		HUBP0_3DLUT_FL_SCALE, &fl_regs->lut_fl_scale);
794 	REG_GET_2(_3DLUT_FL_CONFIG,
795 		HUBP0_3DLUT_FL_MODE, &fl_regs->lut_fl_mode,
796 		HUBP0_3DLUT_FL_FORMAT, &fl_regs->lut_fl_format);
797 }
798