hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
....@@ -42,20 +42,27 @@
4242 int mpcc_id)
4343 {
4444 struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
45
+ struct mpcc *bottommost_mpcc = mpc1_get_mpcc(mpc, mpcc_id);
46
+ uint32_t bg_r_cr, bg_g_y, bg_b_cb;
47
+
48
+ /* find bottommost mpcc. */
49
+ while (bottommost_mpcc->mpcc_bot) {
50
+ bottommost_mpcc = bottommost_mpcc->mpcc_bot;
51
+ }
4552
4653 /* mpc color is 12 bit. tg_color is 10 bit */
4754 /* todo: might want to use 16 bit to represent color and have each
4855 * hw block translate to correct color depth.
4956 */
50
- uint32_t bg_r_cr = bg_color->color_r_cr << 2;
51
- uint32_t bg_g_y = bg_color->color_g_y << 2;
52
- uint32_t bg_b_cb = bg_color->color_b_cb << 2;
57
+ bg_r_cr = bg_color->color_r_cr << 2;
58
+ bg_g_y = bg_color->color_g_y << 2;
59
+ bg_b_cb = bg_color->color_b_cb << 2;
5360
54
- REG_SET(MPCC_BG_R_CR[mpcc_id], 0,
61
+ REG_SET(MPCC_BG_R_CR[bottommost_mpcc->mpcc_id], 0,
5562 MPCC_BG_R_CR, bg_r_cr);
56
- REG_SET(MPCC_BG_G_Y[mpcc_id], 0,
63
+ REG_SET(MPCC_BG_G_Y[bottommost_mpcc->mpcc_id], 0,
5764 MPCC_BG_G_Y, bg_g_y);
58
- REG_SET(MPCC_BG_B_CB[mpcc_id], 0,
65
+ REG_SET(MPCC_BG_B_CB[bottommost_mpcc->mpcc_id], 0,
5966 MPCC_BG_B_CB, bg_b_cb);
6067 }
6168
....@@ -118,6 +125,12 @@
118125 while (tmp_mpcc != NULL) {
119126 if (tmp_mpcc->dpp_id == dpp_id)
120127 return tmp_mpcc;
128
+
129
+ /* avoid circular linked list */
130
+ ASSERT(tmp_mpcc != tmp_mpcc->mpcc_bot);
131
+ if (tmp_mpcc == tmp_mpcc->mpcc_bot)
132
+ break;
133
+
121134 tmp_mpcc = tmp_mpcc->mpcc_bot;
122135 }
123136 return NULL;
....@@ -193,8 +206,9 @@
193206 /* check insert_above_mpcc exist in tree->opp_list */
194207 struct mpcc *temp_mpcc = tree->opp_list;
195208
196
- while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc)
197
- temp_mpcc = temp_mpcc->mpcc_bot;
209
+ if (temp_mpcc != insert_above_mpcc)
210
+ while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc)
211
+ temp_mpcc = temp_mpcc->mpcc_bot;
198212 if (temp_mpcc == NULL)
199213 return NULL;
200214 }
....@@ -211,10 +225,13 @@
211225 } else {
212226 new_mpcc->mpcc_bot = NULL;
213227 REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
214
- REG_UPDATE(MPCC_CONTROL[mpcc_id], MPCC_MODE, MPCC_BLEND_MODE_TOP_LAYER_PASSTHROUGH);
228
+ REG_UPDATE(MPCC_CONTROL[mpcc_id], MPCC_MODE, MPCC_BLEND_MODE_TOP_LAYER_ONLY);
215229 }
216230 REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id);
217231 REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id);
232
+
233
+ /* Configure VUPDATE lock set for this MPCC to map to the OPP */
234
+ REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, tree->opp_id);
218235
219236 /* update mpc tree mux setting */
220237 if (tree->opp_list == insert_above_mpcc) {
....@@ -311,6 +328,7 @@
311328 REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
312329 REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
313330 REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
331
+ REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
314332
315333 /* mark this mpcc as not in use */
316334 mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id);
....@@ -321,6 +339,7 @@
321339 REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
322340 REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
323341 REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
342
+ REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
324343 }
325344 }
326345
....@@ -354,6 +373,7 @@
354373 REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
355374 REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
356375 REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
376
+ REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
357377
358378 mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
359379 }
....@@ -363,6 +383,25 @@
363383 REG_UPDATE(MUX[opp_id], MPC_OUT_MUX, 0xf);
364384 }
365385 }
386
+
387
+void mpc1_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id)
388
+{
389
+ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
390
+ int opp_id;
391
+
392
+ REG_GET(MPCC_OPP_ID[mpcc_id], MPCC_OPP_ID, &opp_id);
393
+
394
+ REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
395
+ REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
396
+ REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
397
+ REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
398
+
399
+ mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
400
+
401
+ if (opp_id < MAX_OPP && REG(MUX[opp_id]))
402
+ REG_UPDATE(MUX[opp_id], MPC_OUT_MUX, 0xf);
403
+}
404
+
366405
367406 void mpc1_init_mpcc_list_from_hw(
368407 struct mpc *mpc,
....@@ -428,16 +467,29 @@
428467 MPCC_BUSY, &s->busy);
429468 }
430469
470
+void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock)
471
+{
472
+ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
473
+
474
+ REG_SET(CUR[opp_id], 0, CUR_VUPDATE_LOCK_SET, lock ? 1 : 0);
475
+}
476
+
431477 static const struct mpc_funcs dcn10_mpc_funcs = {
432478 .read_mpcc_state = mpc1_read_mpcc_state,
433479 .insert_plane = mpc1_insert_plane,
434480 .remove_mpcc = mpc1_remove_mpcc,
435481 .mpc_init = mpc1_mpc_init,
482
+ .mpc_init_single_inst = mpc1_mpc_init_single_inst,
436483 .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
437484 .wait_for_idle = mpc1_assert_idle_mpcc,
438485 .assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect,
439486 .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
440487 .update_blending = mpc1_update_blending,
488
+ .cursor_lock = mpc1_cursor_lock,
489
+ .set_denorm = NULL,
490
+ .set_denorm_clamp = NULL,
491
+ .set_output_csc = NULL,
492
+ .set_output_gamma = NULL,
441493 };
442494
443495 void dcn10_mpc_construct(struct dcn10_mpc *mpc10,