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#include "dm_services.h"
26#include "dce_calcs.h"
27#include "reg_helper.h"
28#include "basics/conversion.h"
29#include "dcn10_hubp.h"
30
31#define REG(reg)\
32 hubp1->hubp_regs->reg
33
34#define CTX \
35 hubp1->base.ctx
36
37#undef FN
38#define FN(reg_name, field_name) \
39 hubp1->hubp_shift->field_name, hubp1->hubp_mask->field_name
40
41void hubp1_set_blank(struct hubp *hubp, bool blank)
42{
43 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
44 uint32_t blank_en = blank ? 1 : 0;
45
46 REG_UPDATE_2(DCHUBP_CNTL,
47 HUBP_BLANK_EN, blank_en,
48 HUBP_TTU_DISABLE, blank_en);
49
50 if (blank) {
51 uint32_t reg_val = REG_READ(DCHUBP_CNTL);
52
53 if (reg_val) {
54
55
56
57
58
59
60 REG_WAIT(DCHUBP_CNTL,
61 HUBP_NO_OUTSTANDING_REQ, 1,
62 1, 200);
63 }
64
65 hubp->mpcc_id = 0xf;
66 hubp->opp_id = 0xf;
67 }
68}
69
70static void hubp1_disconnect(struct hubp *hubp)
71{
72 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
73
74 REG_UPDATE(DCHUBP_CNTL,
75 HUBP_TTU_DISABLE, 1);
76
77 REG_UPDATE(CURSOR_CONTROL,
78 CURSOR_ENABLE, 0);
79}
80
81static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank)
82{
83 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
84 uint32_t blank_en = blank ? 1 : 0;
85
86 REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, blank_en);
87}
88
89static void hubp1_vready_workaround(struct hubp *hubp,
90 struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest)
91{
92 uint32_t value = 0;
93 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
94
95
96 value = REG_READ(HUBPREQ_DEBUG_DB);
97
98
99 value |= 0x100;
100 value &= ~0x1000;
101
102 if ((pipe_dest->vstartup_start - 2*(pipe_dest->vready_offset+pipe_dest->vupdate_width
103 + pipe_dest->vupdate_offset) / pipe_dest->htotal) <= pipe_dest->vblank_end) {
104
105
106 value |= 0x1000;
107 }
108
109 REG_WRITE(HUBPREQ_DEBUG_DB, value);
110}
111
112void hubp1_program_tiling(
113 struct hubp *hubp,
114 const union dc_tiling_info *info,
115 const enum surface_pixel_format pixel_format)
116{
117 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
118
119 REG_UPDATE_6(DCSURF_ADDR_CONFIG,
120 NUM_PIPES, log_2(info->gfx9.num_pipes),
121 NUM_BANKS, log_2(info->gfx9.num_banks),
122 PIPE_INTERLEAVE, info->gfx9.pipe_interleave,
123 NUM_SE, log_2(info->gfx9.num_shader_engines),
124 NUM_RB_PER_SE, log_2(info->gfx9.num_rb_per_se),
125 MAX_COMPRESSED_FRAGS, log_2(info->gfx9.max_compressed_frags));
126
127 REG_UPDATE_4(DCSURF_TILING_CONFIG,
128 SW_MODE, info->gfx9.swizzle,
129 META_LINEAR, info->gfx9.meta_linear,
130 RB_ALIGNED, info->gfx9.rb_aligned,
131 PIPE_ALIGNED, info->gfx9.pipe_aligned);
132}
133
134void hubp1_program_size_and_rotation(
135 struct hubp *hubp,
136 enum dc_rotation_angle rotation,
137 enum surface_pixel_format format,
138 const union plane_size *plane_size,
139 struct dc_plane_dcc_param *dcc,
140 bool horizontal_mirror)
141{
142 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
143 uint32_t pitch, meta_pitch, pitch_c, meta_pitch_c, mirror;
144
145
146
147
148 if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
149 pitch = plane_size->video.luma_pitch - 1;
150 meta_pitch = dcc->video.meta_pitch_l - 1;
151 pitch_c = plane_size->video.chroma_pitch - 1;
152 meta_pitch_c = dcc->video.meta_pitch_c - 1;
153 } else {
154 pitch = plane_size->grph.surface_pitch - 1;
155 meta_pitch = dcc->grph.meta_pitch - 1;
156 pitch_c = 0;
157 meta_pitch_c = 0;
158 }
159
160 if (!dcc->enable) {
161 meta_pitch = 0;
162 meta_pitch_c = 0;
163 }
164
165 REG_UPDATE_2(DCSURF_SURFACE_PITCH,
166 PITCH, pitch, META_PITCH, meta_pitch);
167
168 if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
169 REG_UPDATE_2(DCSURF_SURFACE_PITCH_C,
170 PITCH_C, pitch_c, META_PITCH_C, meta_pitch_c);
171
172 if (horizontal_mirror)
173 mirror = 1;
174 else
175 mirror = 0;
176
177
178
179 if (rotation == ROTATION_ANGLE_0)
180 REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
181 ROTATION_ANGLE, 0,
182 H_MIRROR_EN, mirror);
183 else if (rotation == ROTATION_ANGLE_90)
184 REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
185 ROTATION_ANGLE, 1,
186 H_MIRROR_EN, mirror);
187 else if (rotation == ROTATION_ANGLE_180)
188 REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
189 ROTATION_ANGLE, 2,
190 H_MIRROR_EN, mirror);
191 else if (rotation == ROTATION_ANGLE_270)
192 REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
193 ROTATION_ANGLE, 3,
194 H_MIRROR_EN, mirror);
195}
196
197void hubp1_program_pixel_format(
198 struct hubp *hubp,
199 enum surface_pixel_format format)
200{
201 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
202 uint32_t red_bar = 3;
203 uint32_t blue_bar = 2;
204
205
206 if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
207 || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
208 || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
209 || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
210 red_bar = 2;
211 blue_bar = 3;
212 }
213
214 REG_UPDATE_2(HUBPRET_CONTROL,
215 CROSSBAR_SRC_CB_B, blue_bar,
216 CROSSBAR_SRC_CR_R, red_bar);
217
218
219
220 switch (format) {
221 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
222 REG_UPDATE(DCSURF_SURFACE_CONFIG,
223 SURFACE_PIXEL_FORMAT, 1);
224 break;
225 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
226 REG_UPDATE(DCSURF_SURFACE_CONFIG,
227 SURFACE_PIXEL_FORMAT, 3);
228 break;
229 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
230 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
231 REG_UPDATE(DCSURF_SURFACE_CONFIG,
232 SURFACE_PIXEL_FORMAT, 8);
233 break;
234 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
235 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
236 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
237 REG_UPDATE(DCSURF_SURFACE_CONFIG,
238 SURFACE_PIXEL_FORMAT, 10);
239 break;
240 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
241 REG_UPDATE(DCSURF_SURFACE_CONFIG,
242 SURFACE_PIXEL_FORMAT, 22);
243 break;
244 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
245 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
246 REG_UPDATE(DCSURF_SURFACE_CONFIG,
247 SURFACE_PIXEL_FORMAT, 24);
248 break;
249
250 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
251 REG_UPDATE(DCSURF_SURFACE_CONFIG,
252 SURFACE_PIXEL_FORMAT, 65);
253 break;
254 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
255 REG_UPDATE(DCSURF_SURFACE_CONFIG,
256 SURFACE_PIXEL_FORMAT, 64);
257 break;
258 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
259 REG_UPDATE(DCSURF_SURFACE_CONFIG,
260 SURFACE_PIXEL_FORMAT, 67);
261 break;
262 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
263 REG_UPDATE(DCSURF_SURFACE_CONFIG,
264 SURFACE_PIXEL_FORMAT, 66);
265 break;
266 default:
267 BREAK_TO_DEBUGGER();
268 break;
269 }
270
271
272}
273
274bool hubp1_program_surface_flip_and_addr(
275 struct hubp *hubp,
276 const struct dc_plane_address *address,
277 bool flip_immediate)
278{
279 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
280
281
282 REG_SET(DCSURF_FLIP_CONTROL, 0,
283 SURFACE_FLIP_TYPE, flip_immediate);
284
285
286
287
288
289
290 switch (address->type) {
291 case PLN_ADDR_TYPE_GRAPHICS:
292
293
294
295
296
297
298
299 if (address->grph.addr.quad_part == 0)
300 break;
301
302 REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
303 PRIMARY_SURFACE_TMZ, address->tmz_surface,
304 PRIMARY_META_SURFACE_TMZ, address->tmz_surface);
305
306 if (address->grph.meta_addr.quad_part != 0) {
307 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
308 PRIMARY_META_SURFACE_ADDRESS_HIGH,
309 address->grph.meta_addr.high_part);
310
311 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
312 PRIMARY_META_SURFACE_ADDRESS,
313 address->grph.meta_addr.low_part);
314 }
315
316 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
317 PRIMARY_SURFACE_ADDRESS_HIGH,
318 address->grph.addr.high_part);
319
320 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
321 PRIMARY_SURFACE_ADDRESS,
322 address->grph.addr.low_part);
323 break;
324 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
325 if (address->video_progressive.luma_addr.quad_part == 0
326 || address->video_progressive.chroma_addr.quad_part == 0)
327 break;
328
329 REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
330 PRIMARY_SURFACE_TMZ, address->tmz_surface,
331 PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
332 PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
333 PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
334
335 if (address->video_progressive.luma_meta_addr.quad_part != 0) {
336 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
337 PRIMARY_META_SURFACE_ADDRESS_HIGH_C,
338 address->video_progressive.chroma_meta_addr.high_part);
339
340 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0,
341 PRIMARY_META_SURFACE_ADDRESS_C,
342 address->video_progressive.chroma_meta_addr.low_part);
343
344 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
345 PRIMARY_META_SURFACE_ADDRESS_HIGH,
346 address->video_progressive.luma_meta_addr.high_part);
347
348 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
349 PRIMARY_META_SURFACE_ADDRESS,
350 address->video_progressive.luma_meta_addr.low_part);
351 }
352
353 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
354 PRIMARY_SURFACE_ADDRESS_HIGH_C,
355 address->video_progressive.chroma_addr.high_part);
356
357 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
358 PRIMARY_SURFACE_ADDRESS_C,
359 address->video_progressive.chroma_addr.low_part);
360
361 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
362 PRIMARY_SURFACE_ADDRESS_HIGH,
363 address->video_progressive.luma_addr.high_part);
364
365 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
366 PRIMARY_SURFACE_ADDRESS,
367 address->video_progressive.luma_addr.low_part);
368 break;
369 case PLN_ADDR_TYPE_GRPH_STEREO:
370 if (address->grph_stereo.left_addr.quad_part == 0)
371 break;
372 if (address->grph_stereo.right_addr.quad_part == 0)
373 break;
374
375 REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
376 PRIMARY_SURFACE_TMZ, address->tmz_surface,
377 PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
378 PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
379 PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
380
381 if (address->grph_stereo.right_meta_addr.quad_part != 0) {
382
383 REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0,
384 SECONDARY_META_SURFACE_ADDRESS_HIGH,
385 address->grph_stereo.right_meta_addr.high_part);
386
387 REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0,
388 SECONDARY_META_SURFACE_ADDRESS,
389 address->grph_stereo.right_meta_addr.low_part);
390 }
391 if (address->grph_stereo.left_meta_addr.quad_part != 0) {
392
393 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
394 PRIMARY_META_SURFACE_ADDRESS_HIGH,
395 address->grph_stereo.left_meta_addr.high_part);
396
397 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
398 PRIMARY_META_SURFACE_ADDRESS,
399 address->grph_stereo.left_meta_addr.low_part);
400 }
401
402 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
403 SECONDARY_SURFACE_ADDRESS_HIGH,
404 address->grph_stereo.right_addr.high_part);
405
406 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0,
407 SECONDARY_SURFACE_ADDRESS,
408 address->grph_stereo.right_addr.low_part);
409
410 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
411 PRIMARY_SURFACE_ADDRESS_HIGH,
412 address->grph_stereo.left_addr.high_part);
413
414 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
415 PRIMARY_SURFACE_ADDRESS,
416 address->grph_stereo.left_addr.low_part);
417 break;
418 default:
419 BREAK_TO_DEBUGGER();
420 break;
421 }
422
423 hubp->request_address = *address;
424
425 if (flip_immediate)
426 hubp->current_address = *address;
427
428 return true;
429}
430
431void hubp1_dcc_control(struct hubp *hubp, bool enable,
432 bool independent_64b_blks)
433{
434 uint32_t dcc_en = enable ? 1 : 0;
435 uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0;
436 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
437
438 REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
439 PRIMARY_SURFACE_DCC_EN, dcc_en,
440 PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk);
441}
442
443void hubp1_program_surface_config(
444 struct hubp *hubp,
445 enum surface_pixel_format format,
446 union dc_tiling_info *tiling_info,
447 union plane_size *plane_size,
448 enum dc_rotation_angle rotation,
449 struct dc_plane_dcc_param *dcc,
450 bool horizontal_mirror)
451{
452 hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks);
453 hubp1_program_tiling(hubp, tiling_info, format);
454 hubp1_program_size_and_rotation(
455 hubp, rotation, format, plane_size, dcc, horizontal_mirror);
456 hubp1_program_pixel_format(hubp, format);
457}
458
459void hubp1_program_requestor(
460 struct hubp *hubp,
461 struct _vcs_dpi_display_rq_regs_st *rq_regs)
462{
463 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
464
465 REG_UPDATE(HUBPRET_CONTROL,
466 DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address);
467 REG_SET_4(DCN_EXPANSION_MODE, 0,
468 DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode,
469 PRQ_EXPANSION_MODE, rq_regs->prq_expansion_mode,
470 MRQ_EXPANSION_MODE, rq_regs->mrq_expansion_mode,
471 CRQ_EXPANSION_MODE, rq_regs->crq_expansion_mode);
472 REG_SET_8(DCHUBP_REQ_SIZE_CONFIG, 0,
473 CHUNK_SIZE, rq_regs->rq_regs_l.chunk_size,
474 MIN_CHUNK_SIZE, rq_regs->rq_regs_l.min_chunk_size,
475 META_CHUNK_SIZE, rq_regs->rq_regs_l.meta_chunk_size,
476 MIN_META_CHUNK_SIZE, rq_regs->rq_regs_l.min_meta_chunk_size,
477 DPTE_GROUP_SIZE, rq_regs->rq_regs_l.dpte_group_size,
478 MPTE_GROUP_SIZE, rq_regs->rq_regs_l.mpte_group_size,
479 SWATH_HEIGHT, rq_regs->rq_regs_l.swath_height,
480 PTE_ROW_HEIGHT_LINEAR, rq_regs->rq_regs_l.pte_row_height_linear);
481 REG_SET_8(DCHUBP_REQ_SIZE_CONFIG_C, 0,
482 CHUNK_SIZE_C, rq_regs->rq_regs_c.chunk_size,
483 MIN_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_chunk_size,
484 META_CHUNK_SIZE_C, rq_regs->rq_regs_c.meta_chunk_size,
485 MIN_META_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_meta_chunk_size,
486 DPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.dpte_group_size,
487 MPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.mpte_group_size,
488 SWATH_HEIGHT_C, rq_regs->rq_regs_c.swath_height,
489 PTE_ROW_HEIGHT_LINEAR_C, rq_regs->rq_regs_c.pte_row_height_linear);
490}
491
492
493void hubp1_program_deadline(
494 struct hubp *hubp,
495 struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
496 struct _vcs_dpi_display_ttu_regs_st *ttu_attr)
497{
498 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
499
500
501 REG_SET_2(BLANK_OFFSET_0, 0,
502 REFCYC_H_BLANK_END, dlg_attr->refcyc_h_blank_end,
503 DLG_V_BLANK_END, dlg_attr->dlg_vblank_end);
504
505 REG_SET(BLANK_OFFSET_1, 0,
506 MIN_DST_Y_NEXT_START, dlg_attr->min_dst_y_next_start);
507
508 REG_SET(DST_DIMENSIONS, 0,
509 REFCYC_PER_HTOTAL, dlg_attr->refcyc_per_htotal);
510
511 REG_SET_2(DST_AFTER_SCALER, 0,
512 REFCYC_X_AFTER_SCALER, dlg_attr->refcyc_x_after_scaler,
513 DST_Y_AFTER_SCALER, dlg_attr->dst_y_after_scaler);
514
515 if (REG(PREFETCH_SETTINS))
516 REG_SET_2(PREFETCH_SETTINS, 0,
517 DST_Y_PREFETCH, dlg_attr->dst_y_prefetch,
518 VRATIO_PREFETCH, dlg_attr->vratio_prefetch);
519 else
520 REG_SET_2(PREFETCH_SETTINGS, 0,
521 DST_Y_PREFETCH, dlg_attr->dst_y_prefetch,
522 VRATIO_PREFETCH, dlg_attr->vratio_prefetch);
523
524 REG_SET_2(VBLANK_PARAMETERS_0, 0,
525 DST_Y_PER_VM_VBLANK, dlg_attr->dst_y_per_vm_vblank,
526 DST_Y_PER_ROW_VBLANK, dlg_attr->dst_y_per_row_vblank);
527
528 REG_SET(REF_FREQ_TO_PIX_FREQ, 0,
529 REF_FREQ_TO_PIX_FREQ, dlg_attr->ref_freq_to_pix_freq);
530
531
532 REG_SET(VBLANK_PARAMETERS_1, 0,
533 REFCYC_PER_PTE_GROUP_VBLANK_L, dlg_attr->refcyc_per_pte_group_vblank_l);
534
535 REG_SET(VBLANK_PARAMETERS_3, 0,
536 REFCYC_PER_META_CHUNK_VBLANK_L, dlg_attr->refcyc_per_meta_chunk_vblank_l);
537
538 REG_SET(NOM_PARAMETERS_0, 0,
539 DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l);
540
541 REG_SET(NOM_PARAMETERS_1, 0,
542 REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l);
543
544 REG_SET(NOM_PARAMETERS_4, 0,
545 DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l);
546
547 REG_SET(NOM_PARAMETERS_5, 0,
548 REFCYC_PER_META_CHUNK_NOM_L, dlg_attr->refcyc_per_meta_chunk_nom_l);
549
550 REG_SET_2(PER_LINE_DELIVERY_PRE, 0,
551 REFCYC_PER_LINE_DELIVERY_PRE_L, dlg_attr->refcyc_per_line_delivery_pre_l,
552 REFCYC_PER_LINE_DELIVERY_PRE_C, dlg_attr->refcyc_per_line_delivery_pre_c);
553
554 REG_SET_2(PER_LINE_DELIVERY, 0,
555 REFCYC_PER_LINE_DELIVERY_L, dlg_attr->refcyc_per_line_delivery_l,
556 REFCYC_PER_LINE_DELIVERY_C, dlg_attr->refcyc_per_line_delivery_c);
557
558 if (REG(PREFETCH_SETTINS_C))
559 REG_SET(PREFETCH_SETTINS_C, 0,
560 VRATIO_PREFETCH_C, dlg_attr->vratio_prefetch_c);
561 else
562 REG_SET(PREFETCH_SETTINGS_C, 0,
563 VRATIO_PREFETCH_C, dlg_attr->vratio_prefetch_c);
564
565 REG_SET(VBLANK_PARAMETERS_2, 0,
566 REFCYC_PER_PTE_GROUP_VBLANK_C, dlg_attr->refcyc_per_pte_group_vblank_c);
567
568 REG_SET(VBLANK_PARAMETERS_4, 0,
569 REFCYC_PER_META_CHUNK_VBLANK_C, dlg_attr->refcyc_per_meta_chunk_vblank_c);
570
571 REG_SET(NOM_PARAMETERS_2, 0,
572 DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c);
573
574 REG_SET(NOM_PARAMETERS_3, 0,
575 REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c);
576
577 REG_SET(NOM_PARAMETERS_6, 0,
578 DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c);
579
580 REG_SET(NOM_PARAMETERS_7, 0,
581 REFCYC_PER_META_CHUNK_NOM_C, dlg_attr->refcyc_per_meta_chunk_nom_c);
582
583
584 REG_SET_2(DCN_TTU_QOS_WM, 0,
585 QoS_LEVEL_LOW_WM, ttu_attr->qos_level_low_wm,
586 QoS_LEVEL_HIGH_WM, ttu_attr->qos_level_high_wm);
587
588 REG_SET_2(DCN_GLOBAL_TTU_CNTL, 0,
589 MIN_TTU_VBLANK, ttu_attr->min_ttu_vblank,
590 QoS_LEVEL_FLIP, ttu_attr->qos_level_flip);
591
592
593
594
595 REG_SET_3(DCN_SURF0_TTU_CNTL0, 0,
596 REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_l,
597 QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_l,
598 QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_l);
599
600 REG_SET(DCN_SURF0_TTU_CNTL1, 0,
601 REFCYC_PER_REQ_DELIVERY_PRE,
602 ttu_attr->refcyc_per_req_delivery_pre_l);
603
604 REG_SET_3(DCN_SURF1_TTU_CNTL0, 0,
605 REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_c,
606 QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_c,
607 QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_c);
608
609 REG_SET(DCN_SURF1_TTU_CNTL1, 0,
610 REFCYC_PER_REQ_DELIVERY_PRE,
611 ttu_attr->refcyc_per_req_delivery_pre_c);
612}
613
614static void hubp1_setup(
615 struct hubp *hubp,
616 struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
617 struct _vcs_dpi_display_ttu_regs_st *ttu_attr,
618 struct _vcs_dpi_display_rq_regs_st *rq_regs,
619 struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest)
620{
621
622
623
624 hubp1_program_requestor(hubp, rq_regs);
625 hubp1_program_deadline(hubp, dlg_attr, ttu_attr);
626 hubp1_vready_workaround(hubp, pipe_dest);
627}
628
629bool hubp1_is_flip_pending(struct hubp *hubp)
630{
631 uint32_t flip_pending = 0;
632 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
633 struct dc_plane_address earliest_inuse_address;
634
635 REG_GET(DCSURF_FLIP_CONTROL,
636 SURFACE_FLIP_PENDING, &flip_pending);
637
638 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE,
639 SURFACE_EARLIEST_INUSE_ADDRESS, &earliest_inuse_address.grph.addr.low_part);
640
641 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH,
642 SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &earliest_inuse_address.grph.addr.high_part);
643
644 if (flip_pending)
645 return true;
646
647 if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
648 return true;
649
650 hubp->current_address = hubp->request_address;
651 return false;
652}
653
654uint32_t aperture_default_system = 1;
655uint32_t context0_default_system;
656
657static void hubp1_set_vm_system_aperture_settings(struct hubp *hubp,
658 struct vm_system_aperture_param *apt)
659{
660 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
661 PHYSICAL_ADDRESS_LOC mc_vm_apt_default;
662 PHYSICAL_ADDRESS_LOC mc_vm_apt_low;
663 PHYSICAL_ADDRESS_LOC mc_vm_apt_high;
664
665 mc_vm_apt_default.quad_part = apt->sys_default.quad_part >> 12;
666 mc_vm_apt_low.quad_part = apt->sys_low.quad_part >> 12;
667 mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 12;
668
669 REG_SET_2(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0,
670 MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, aperture_default_system,
671 MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mc_vm_apt_default.high_part);
672 REG_SET(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0,
673 MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mc_vm_apt_default.low_part);
674
675 REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0,
676 MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, mc_vm_apt_low.high_part);
677 REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0,
678 MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, mc_vm_apt_low.low_part);
679
680 REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0,
681 MC_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, mc_vm_apt_high.high_part);
682 REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0,
683 MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mc_vm_apt_high.low_part);
684}
685
686static void hubp1_set_vm_context0_settings(struct hubp *hubp,
687 const struct vm_context0_param *vm0)
688{
689 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
690
691 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, 0,
692 VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, vm0->pte_base.high_part);
693 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, 0,
694 VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, vm0->pte_base.low_part);
695
696
697 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, 0,
698 VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, vm0->pte_start.high_part);
699 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, 0,
700 VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, vm0->pte_start.low_part);
701
702
703 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, 0,
704 VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, vm0->pte_end.high_part);
705 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, 0,
706 VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, vm0->pte_end.low_part);
707
708
709 REG_SET_2(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0,
710 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, vm0->fault_default.high_part,
711 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, context0_default_system);
712 REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, 0,
713 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, vm0->fault_default.low_part);
714
715
716 REG_SET_2(DCN_VM_MX_L1_TLB_CNTL, 0,
717 ENABLE_L1_TLB, 1,
718 SYSTEM_ACCESS_MODE, 3);
719}
720
721void min_set_viewport(
722 struct hubp *hubp,
723 const struct rect *viewport,
724 const struct rect *viewport_c)
725{
726 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
727
728 REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0,
729 PRI_VIEWPORT_WIDTH, viewport->width,
730 PRI_VIEWPORT_HEIGHT, viewport->height);
731
732 REG_SET_2(DCSURF_PRI_VIEWPORT_START, 0,
733 PRI_VIEWPORT_X_START, viewport->x,
734 PRI_VIEWPORT_Y_START, viewport->y);
735
736
737 REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION, 0,
738 SEC_VIEWPORT_WIDTH, viewport->width,
739 SEC_VIEWPORT_HEIGHT, viewport->height);
740
741 REG_SET_2(DCSURF_SEC_VIEWPORT_START, 0,
742 SEC_VIEWPORT_X_START, viewport->x,
743 SEC_VIEWPORT_Y_START, viewport->y);
744
745
746 REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION_C, 0,
747 PRI_VIEWPORT_WIDTH_C, viewport_c->width,
748 PRI_VIEWPORT_HEIGHT_C, viewport_c->height);
749
750 REG_SET_2(DCSURF_PRI_VIEWPORT_START_C, 0,
751 PRI_VIEWPORT_X_START_C, viewport_c->x,
752 PRI_VIEWPORT_Y_START_C, viewport_c->y);
753}
754
755void hubp1_read_state(struct dcn10_hubp *hubp1,
756 struct dcn_hubp_state *s)
757{
758 REG_GET(DCSURF_SURFACE_CONFIG,
759 SURFACE_PIXEL_FORMAT, &s->pixel_format);
760
761 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH,
762 SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &s->inuse_addr_hi);
763
764 REG_GET_2(DCSURF_PRI_VIEWPORT_DIMENSION,
765 PRI_VIEWPORT_WIDTH, &s->viewport_width,
766 PRI_VIEWPORT_HEIGHT, &s->viewport_height);
767
768 REG_GET_2(DCSURF_SURFACE_CONFIG,
769 ROTATION_ANGLE, &s->rotation_angle,
770 H_MIRROR_EN, &s->h_mirror_en);
771
772 REG_GET(DCSURF_TILING_CONFIG,
773 SW_MODE, &s->sw_mode);
774
775 REG_GET(DCSURF_SURFACE_CONTROL,
776 PRIMARY_SURFACE_DCC_EN, &s->dcc_en);
777
778 REG_GET_3(DCHUBP_CNTL,
779 HUBP_BLANK_EN, &s->blank_en,
780 HUBP_TTU_DISABLE, &s->ttu_disable,
781 HUBP_UNDERFLOW_STATUS, &s->underflow_status);
782
783 REG_GET(DCN_GLOBAL_TTU_CNTL,
784 MIN_TTU_VBLANK, &s->min_ttu_vblank);
785
786 REG_GET_2(DCN_TTU_QOS_WM,
787 QoS_LEVEL_LOW_WM, &s->qos_level_low_wm,
788 QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
789}
790
791enum cursor_pitch hubp1_get_cursor_pitch(unsigned int pitch)
792{
793 enum cursor_pitch hw_pitch;
794
795 switch (pitch) {
796 case 64:
797 hw_pitch = CURSOR_PITCH_64_PIXELS;
798 break;
799 case 128:
800 hw_pitch = CURSOR_PITCH_128_PIXELS;
801 break;
802 case 256:
803 hw_pitch = CURSOR_PITCH_256_PIXELS;
804 break;
805 default:
806 DC_ERR("Invalid cursor pitch of %d. "
807 "Only 64/128/256 is supported on DCN.\n", pitch);
808 hw_pitch = CURSOR_PITCH_64_PIXELS;
809 break;
810 }
811 return hw_pitch;
812}
813
814static enum cursor_lines_per_chunk hubp1_get_lines_per_chunk(
815 unsigned int cur_width,
816 enum dc_cursor_color_format format)
817{
818 enum cursor_lines_per_chunk line_per_chunk;
819
820 if (format == CURSOR_MODE_MONO)
821
822 line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
823 else if (cur_width <= 32)
824 line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
825 else if (cur_width <= 64)
826 line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
827 else if (cur_width <= 128)
828 line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
829 else
830 line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
831
832 return line_per_chunk;
833}
834
835void hubp1_cursor_set_attributes(
836 struct hubp *hubp,
837 const struct dc_cursor_attributes *attr)
838{
839 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
840 enum cursor_pitch hw_pitch = hubp1_get_cursor_pitch(attr->pitch);
841 enum cursor_lines_per_chunk lpc = hubp1_get_lines_per_chunk(
842 attr->width, attr->color_format);
843
844 hubp->curs_attr = *attr;
845
846 REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
847 CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
848 REG_UPDATE(CURSOR_SURFACE_ADDRESS,
849 CURSOR_SURFACE_ADDRESS, attr->address.low_part);
850
851 REG_UPDATE_2(CURSOR_SIZE,
852 CURSOR_WIDTH, attr->width,
853 CURSOR_HEIGHT, attr->height);
854
855 REG_UPDATE_3(CURSOR_CONTROL,
856 CURSOR_MODE, attr->color_format,
857 CURSOR_PITCH, hw_pitch,
858 CURSOR_LINES_PER_CHUNK, lpc);
859
860 REG_SET_2(CURSOR_SETTINS, 0,
861
862 CURSOR0_DST_Y_OFFSET, 0,
863
864 CURSOR0_CHUNK_HDL_ADJUST, 3);
865}
866
867void hubp1_cursor_set_position(
868 struct hubp *hubp,
869 const struct dc_cursor_position *pos,
870 const struct dc_cursor_mi_param *param)
871{
872 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
873 int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
874 uint32_t cur_en = pos->enable ? 1 : 0;
875 uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
876
877
878
879
880
881
882
883
884 if (hubp->curs_attr.address.quad_part == 0)
885 return;
886
887 dst_x_offset *= param->ref_clk_khz;
888 dst_x_offset /= param->pixel_clk_khz;
889
890 ASSERT(param->h_scale_ratio.value);
891
892 if (param->h_scale_ratio.value)
893 dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
894 dal_fixed31_32_from_int(dst_x_offset),
895 param->h_scale_ratio));
896
897 if (src_x_offset >= (int)param->viewport_width)
898 cur_en = 0;
899
900 if (src_x_offset + (int)hubp->curs_attr.width < 0)
901 cur_en = 0;
902
903 if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
904 hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
905
906 REG_UPDATE(CURSOR_CONTROL,
907 CURSOR_ENABLE, cur_en);
908
909 REG_SET_2(CURSOR_POSITION, 0,
910 CURSOR_X_POSITION, pos->x,
911 CURSOR_Y_POSITION, pos->y);
912
913 REG_SET_2(CURSOR_HOT_SPOT, 0,
914 CURSOR_HOT_SPOT_X, pos->x_hotspot,
915 CURSOR_HOT_SPOT_Y, pos->y_hotspot);
916
917 REG_SET(CURSOR_DST_OFFSET, 0,
918 CURSOR_DST_X_OFFSET, dst_x_offset);
919
920}
921
922void hubp1_clk_cntl(struct hubp *hubp, bool enable)
923{
924 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
925 uint32_t clk_enable = enable ? 1 : 0;
926
927 REG_UPDATE(HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, clk_enable);
928}
929
930void hubp1_vtg_sel(struct hubp *hubp, uint32_t otg_inst)
931{
932 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
933
934 REG_UPDATE(DCHUBP_CNTL, HUBP_VTG_SEL, otg_inst);
935}
936
937static struct hubp_funcs dcn10_hubp_funcs = {
938 .hubp_program_surface_flip_and_addr =
939 hubp1_program_surface_flip_and_addr,
940 .hubp_program_surface_config =
941 hubp1_program_surface_config,
942 .hubp_is_flip_pending = hubp1_is_flip_pending,
943 .hubp_setup = hubp1_setup,
944 .hubp_set_vm_system_aperture_settings = hubp1_set_vm_system_aperture_settings,
945 .hubp_set_vm_context0_settings = hubp1_set_vm_context0_settings,
946 .set_blank = hubp1_set_blank,
947 .dcc_control = hubp1_dcc_control,
948 .mem_program_viewport = min_set_viewport,
949 .set_hubp_blank_en = hubp1_set_hubp_blank_en,
950 .set_cursor_attributes = hubp1_cursor_set_attributes,
951 .set_cursor_position = hubp1_cursor_set_position,
952 .hubp_disconnect = hubp1_disconnect,
953 .hubp_clk_cntl = hubp1_clk_cntl,
954 .hubp_vtg_sel = hubp1_vtg_sel,
955};
956
957
958
959
960
961void dcn10_hubp_construct(
962 struct dcn10_hubp *hubp1,
963 struct dc_context *ctx,
964 uint32_t inst,
965 const struct dcn_mi_registers *hubp_regs,
966 const struct dcn_mi_shift *hubp_shift,
967 const struct dcn_mi_mask *hubp_mask)
968{
969 hubp1->base.funcs = &dcn10_hubp_funcs;
970 hubp1->base.ctx = ctx;
971 hubp1->hubp_regs = hubp_regs;
972 hubp1->hubp_shift = hubp_shift;
973 hubp1->hubp_mask = hubp_mask;
974 hubp1->base.inst = inst;
975 hubp1->base.opp_id = 0xf;
976 hubp1->base.mpcc_id = 0xf;
977}
978
979
980