.. | .. |
---|
42 | 42 | int mpcc_id) |
---|
43 | 43 | { |
---|
44 | 44 | 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 | + } |
---|
45 | 52 | |
---|
46 | 53 | /* mpc color is 12 bit. tg_color is 10 bit */ |
---|
47 | 54 | /* todo: might want to use 16 bit to represent color and have each |
---|
48 | 55 | * hw block translate to correct color depth. |
---|
49 | 56 | */ |
---|
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; |
---|
53 | 60 | |
---|
54 | | - REG_SET(MPCC_BG_R_CR[mpcc_id], 0, |
---|
| 61 | + REG_SET(MPCC_BG_R_CR[bottommost_mpcc->mpcc_id], 0, |
---|
55 | 62 | 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, |
---|
57 | 64 | 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, |
---|
59 | 66 | MPCC_BG_B_CB, bg_b_cb); |
---|
60 | 67 | } |
---|
61 | 68 | |
---|
.. | .. |
---|
118 | 125 | while (tmp_mpcc != NULL) { |
---|
119 | 126 | if (tmp_mpcc->dpp_id == dpp_id) |
---|
120 | 127 | 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 | + |
---|
121 | 134 | tmp_mpcc = tmp_mpcc->mpcc_bot; |
---|
122 | 135 | } |
---|
123 | 136 | return NULL; |
---|
.. | .. |
---|
193 | 206 | /* check insert_above_mpcc exist in tree->opp_list */ |
---|
194 | 207 | struct mpcc *temp_mpcc = tree->opp_list; |
---|
195 | 208 | |
---|
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; |
---|
198 | 212 | if (temp_mpcc == NULL) |
---|
199 | 213 | return NULL; |
---|
200 | 214 | } |
---|
.. | .. |
---|
211 | 225 | } else { |
---|
212 | 226 | new_mpcc->mpcc_bot = NULL; |
---|
213 | 227 | 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); |
---|
215 | 229 | } |
---|
216 | 230 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id); |
---|
217 | 231 | 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); |
---|
218 | 235 | |
---|
219 | 236 | /* update mpc tree mux setting */ |
---|
220 | 237 | if (tree->opp_list == insert_above_mpcc) { |
---|
.. | .. |
---|
311 | 328 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
---|
312 | 329 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
---|
313 | 330 | 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); |
---|
314 | 332 | |
---|
315 | 333 | /* mark this mpcc as not in use */ |
---|
316 | 334 | mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id); |
---|
.. | .. |
---|
321 | 339 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
---|
322 | 340 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
---|
323 | 341 | 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); |
---|
324 | 343 | } |
---|
325 | 344 | } |
---|
326 | 345 | |
---|
.. | .. |
---|
354 | 373 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
---|
355 | 374 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
---|
356 | 375 | 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); |
---|
357 | 377 | |
---|
358 | 378 | mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); |
---|
359 | 379 | } |
---|
.. | .. |
---|
363 | 383 | REG_UPDATE(MUX[opp_id], MPC_OUT_MUX, 0xf); |
---|
364 | 384 | } |
---|
365 | 385 | } |
---|
| 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 | + |
---|
366 | 405 | |
---|
367 | 406 | void mpc1_init_mpcc_list_from_hw( |
---|
368 | 407 | struct mpc *mpc, |
---|
.. | .. |
---|
428 | 467 | MPCC_BUSY, &s->busy); |
---|
429 | 468 | } |
---|
430 | 469 | |
---|
| 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 | + |
---|
431 | 477 | static const struct mpc_funcs dcn10_mpc_funcs = { |
---|
432 | 478 | .read_mpcc_state = mpc1_read_mpcc_state, |
---|
433 | 479 | .insert_plane = mpc1_insert_plane, |
---|
434 | 480 | .remove_mpcc = mpc1_remove_mpcc, |
---|
435 | 481 | .mpc_init = mpc1_mpc_init, |
---|
| 482 | + .mpc_init_single_inst = mpc1_mpc_init_single_inst, |
---|
436 | 483 | .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp, |
---|
437 | 484 | .wait_for_idle = mpc1_assert_idle_mpcc, |
---|
438 | 485 | .assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect, |
---|
439 | 486 | .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw, |
---|
440 | 487 | .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, |
---|
441 | 493 | }; |
---|
442 | 494 | |
---|
443 | 495 | void dcn10_mpc_construct(struct dcn10_mpc *mpc10, |
---|