root/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mpc1_set_bg_color
  2. mpc1_update_blending
  3. mpc1_update_stereo_mix
  4. mpc1_assert_idle_mpcc
  5. mpc1_get_mpcc
  6. mpc1_get_mpcc_for_dpp
  7. mpc1_is_mpcc_idle
  8. mpc1_assert_mpcc_idle_before_connect
  9. mpc1_insert_plane
  10. mpc1_remove_mpcc
  11. mpc1_init_mpcc
  12. mpc1_mpc_init
  13. mpc1_mpc_init_single_inst
  14. mpc1_init_mpcc_list_from_hw
  15. mpc1_read_mpcc_state
  16. dcn10_mpc_construct

   1 /*
   2  * Copyright 2012-15 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 "reg_helper.h"
  27 #include "dcn10_mpc.h"
  28 
  29 #define REG(reg)\
  30         mpc10->mpc_regs->reg
  31 
  32 #define CTX \
  33         mpc10->base.ctx
  34 
  35 #undef FN
  36 #define FN(reg_name, field_name) \
  37         mpc10->mpc_shift->field_name, mpc10->mpc_mask->field_name
  38 
  39 
  40 void mpc1_set_bg_color(struct mpc *mpc,
  41                 struct tg_color *bg_color,
  42                 int mpcc_id)
  43 {
  44         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
  45 
  46         /* mpc color is 12 bit.  tg_color is 10 bit */
  47         /* todo: might want to use 16 bit to represent color and have each
  48          * hw block translate to correct color depth.
  49          */
  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;
  53 
  54         REG_SET(MPCC_BG_R_CR[mpcc_id], 0,
  55                         MPCC_BG_R_CR, bg_r_cr);
  56         REG_SET(MPCC_BG_G_Y[mpcc_id], 0,
  57                         MPCC_BG_G_Y, bg_g_y);
  58         REG_SET(MPCC_BG_B_CB[mpcc_id], 0,
  59                         MPCC_BG_B_CB, bg_b_cb);
  60 }
  61 
  62 static void mpc1_update_blending(
  63         struct mpc *mpc,
  64         struct mpcc_blnd_cfg *blnd_cfg,
  65         int mpcc_id)
  66 {
  67         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
  68         struct mpcc *mpcc = mpc1_get_mpcc(mpc, mpcc_id);
  69 
  70         REG_UPDATE_5(MPCC_CONTROL[mpcc_id],
  71                         MPCC_ALPHA_BLND_MODE,           blnd_cfg->alpha_mode,
  72                         MPCC_ALPHA_MULTIPLIED_MODE,     blnd_cfg->pre_multiplied_alpha,
  73                         MPCC_BLND_ACTIVE_OVERLAP_ONLY,  blnd_cfg->overlap_only,
  74                         MPCC_GLOBAL_ALPHA,              blnd_cfg->global_alpha,
  75                         MPCC_GLOBAL_GAIN,               blnd_cfg->global_gain);
  76 
  77         mpc1_set_bg_color(mpc, &blnd_cfg->black_color, mpcc_id);
  78         mpcc->blnd_cfg = *blnd_cfg;
  79 }
  80 
  81 void mpc1_update_stereo_mix(
  82         struct mpc *mpc,
  83         struct mpcc_sm_cfg *sm_cfg,
  84         int mpcc_id)
  85 {
  86         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
  87 
  88         REG_UPDATE_6(MPCC_SM_CONTROL[mpcc_id],
  89                         MPCC_SM_EN,                     sm_cfg->enable,
  90                         MPCC_SM_MODE,                   sm_cfg->sm_mode,
  91                         MPCC_SM_FRAME_ALT,              sm_cfg->frame_alt,
  92                         MPCC_SM_FIELD_ALT,              sm_cfg->field_alt,
  93                         MPCC_SM_FORCE_NEXT_FRAME_POL,   sm_cfg->force_next_frame_porlarity,
  94                         MPCC_SM_FORCE_NEXT_TOP_POL,     sm_cfg->force_next_field_polarity);
  95 }
  96 void mpc1_assert_idle_mpcc(struct mpc *mpc, int id)
  97 {
  98         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
  99 
 100         ASSERT(!(mpc10->mpcc_in_use_mask & 1 << id));
 101         REG_WAIT(MPCC_STATUS[id],
 102                         MPCC_IDLE, 1,
 103                         1, 100000);
 104 }
 105 
 106 struct mpcc *mpc1_get_mpcc(struct mpc *mpc, int mpcc_id)
 107 {
 108         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
 109 
 110         ASSERT(mpcc_id < mpc10->num_mpcc);
 111         return &(mpc->mpcc_array[mpcc_id]);
 112 }
 113 
 114 struct mpcc *mpc1_get_mpcc_for_dpp(struct mpc_tree *tree, int dpp_id)
 115 {
 116         struct mpcc *tmp_mpcc = tree->opp_list;
 117 
 118         while (tmp_mpcc != NULL) {
 119                 if (tmp_mpcc->dpp_id == dpp_id)
 120                         return tmp_mpcc;
 121                 tmp_mpcc = tmp_mpcc->mpcc_bot;
 122         }
 123         return NULL;
 124 }
 125 
 126 bool mpc1_is_mpcc_idle(struct mpc *mpc, int mpcc_id)
 127 {
 128         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
 129         unsigned int top_sel;
 130         unsigned int opp_id;
 131         unsigned int idle;
 132 
 133         REG_GET(MPCC_TOP_SEL[mpcc_id], MPCC_TOP_SEL, &top_sel);
 134         REG_GET(MPCC_OPP_ID[mpcc_id],  MPCC_OPP_ID, &opp_id);
 135         REG_GET(MPCC_STATUS[mpcc_id],  MPCC_IDLE,   &idle);
 136         if (top_sel == 0xf && opp_id == 0xf && idle)
 137                 return true;
 138         else
 139                 return false;
 140 }
 141 
 142 void mpc1_assert_mpcc_idle_before_connect(struct mpc *mpc, int mpcc_id)
 143 {
 144         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
 145         unsigned int top_sel, mpc_busy, mpc_idle;
 146 
 147         REG_GET(MPCC_TOP_SEL[mpcc_id],
 148                         MPCC_TOP_SEL, &top_sel);
 149 
 150         if (top_sel == 0xf) {
 151                 REG_GET_2(MPCC_STATUS[mpcc_id],
 152                                 MPCC_BUSY, &mpc_busy,
 153                                 MPCC_IDLE, &mpc_idle);
 154 
 155                 ASSERT(mpc_busy == 0);
 156                 ASSERT(mpc_idle == 1);
 157         }
 158 }
 159 
 160 /*
 161  * Insert DPP into MPC tree based on specified blending position.
 162  * Only used for planes that are part of blending chain for OPP output
 163  *
 164  * Parameters:
 165  * [in/out] mpc         - MPC context.
 166  * [in/out] tree        - MPC tree structure that plane will be added to.
 167  * [in] blnd_cfg        - MPCC blending configuration for the new blending layer.
 168  * [in] sm_cfg          - MPCC stereo mix configuration for the new blending layer.
 169  *                        stereo mix must disable for the very bottom layer of the tree config.
 170  * [in] insert_above_mpcc - Insert new plane above this MPCC.  If NULL, insert as bottom plane.
 171  * [in] dpp_id          - DPP instance for the plane to be added.
 172  * [in] mpcc_id         - The MPCC physical instance to use for blending.
 173  *
 174  * Return:  struct mpcc* - MPCC that was added.
 175  */
 176 struct mpcc *mpc1_insert_plane(
 177         struct mpc *mpc,
 178         struct mpc_tree *tree,
 179         struct mpcc_blnd_cfg *blnd_cfg,
 180         struct mpcc_sm_cfg *sm_cfg,
 181         struct mpcc *insert_above_mpcc,
 182         int dpp_id,
 183         int mpcc_id)
 184 {
 185         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
 186         struct mpcc *new_mpcc = NULL;
 187 
 188         /* sanity check parameters */
 189         ASSERT(mpcc_id < mpc10->num_mpcc);
 190         ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
 191 
 192         if (insert_above_mpcc) {
 193                 /* check insert_above_mpcc exist in tree->opp_list */
 194                 struct mpcc *temp_mpcc = tree->opp_list;
 195 
 196                 while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc)
 197                         temp_mpcc = temp_mpcc->mpcc_bot;
 198                 if (temp_mpcc == NULL)
 199                         return NULL;
 200         }
 201 
 202         /* Get and update MPCC struct parameters */
 203         new_mpcc = mpc1_get_mpcc(mpc, mpcc_id);
 204         new_mpcc->dpp_id = dpp_id;
 205 
 206         /* program mux and MPCC_MODE */
 207         if (insert_above_mpcc) {
 208                 new_mpcc->mpcc_bot = insert_above_mpcc;
 209                 REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, insert_above_mpcc->mpcc_id);
 210                 REG_UPDATE(MPCC_CONTROL[mpcc_id], MPCC_MODE, MPCC_BLEND_MODE_TOP_BOT_BLENDING);
 211         } else {
 212                 new_mpcc->mpcc_bot = NULL;
 213                 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_ONLY);
 215         }
 216         REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id);
 217         REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id);
 218 
 219         /* update mpc tree mux setting */
 220         if (tree->opp_list == insert_above_mpcc) {
 221                 /* insert the toppest mpcc */
 222                 tree->opp_list = new_mpcc;
 223                 REG_UPDATE(MUX[tree->opp_id], MPC_OUT_MUX, mpcc_id);
 224         } else {
 225                 /* find insert position */
 226                 struct mpcc *temp_mpcc = tree->opp_list;
 227 
 228                 while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc)
 229                         temp_mpcc = temp_mpcc->mpcc_bot;
 230                 if (temp_mpcc && temp_mpcc->mpcc_bot == insert_above_mpcc) {
 231                         REG_SET(MPCC_BOT_SEL[temp_mpcc->mpcc_id], 0, MPCC_BOT_SEL, mpcc_id);
 232                         temp_mpcc->mpcc_bot = new_mpcc;
 233                         if (!insert_above_mpcc)
 234                                 REG_UPDATE(MPCC_CONTROL[temp_mpcc->mpcc_id],
 235                                                 MPCC_MODE, MPCC_BLEND_MODE_TOP_BOT_BLENDING);
 236                 }
 237         }
 238 
 239         /* update the blending configuration */
 240         mpc->funcs->update_blending(mpc, blnd_cfg, mpcc_id);
 241 
 242         /* update the stereo mix settings, if provided */
 243         if (sm_cfg != NULL) {
 244                 new_mpcc->sm_cfg = *sm_cfg;
 245                 mpc1_update_stereo_mix(mpc, sm_cfg, mpcc_id);
 246         }
 247 
 248         /* mark this mpcc as in use */
 249         mpc10->mpcc_in_use_mask |= 1 << mpcc_id;
 250 
 251         return new_mpcc;
 252 }
 253 
 254 /*
 255  * Remove a specified MPCC from the MPC tree.
 256  *
 257  * Parameters:
 258  * [in/out] mpc         - MPC context.
 259  * [in/out] tree        - MPC tree structure that plane will be removed from.
 260  * [in/out] mpcc        - MPCC to be removed from tree.
 261  *
 262  * Return:  void
 263  */
 264 void mpc1_remove_mpcc(
 265         struct mpc *mpc,
 266         struct mpc_tree *tree,
 267         struct mpcc *mpcc_to_remove)
 268 {
 269         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
 270         bool found = false;
 271         int mpcc_id = mpcc_to_remove->mpcc_id;
 272 
 273         if (tree->opp_list == mpcc_to_remove) {
 274                 found = true;
 275                 /* remove MPCC from top of tree */
 276                 if (mpcc_to_remove->mpcc_bot) {
 277                         /* set the next MPCC in list to be the top MPCC */
 278                         tree->opp_list = mpcc_to_remove->mpcc_bot;
 279                         REG_UPDATE(MUX[tree->opp_id], MPC_OUT_MUX, tree->opp_list->mpcc_id);
 280                 } else {
 281                         /* there are no other MPCC is list */
 282                         tree->opp_list = NULL;
 283                         REG_UPDATE(MUX[tree->opp_id], MPC_OUT_MUX, 0xf);
 284                 }
 285         } else {
 286                 /* find mpcc to remove MPCC list */
 287                 struct mpcc *temp_mpcc = tree->opp_list;
 288 
 289                 while (temp_mpcc && temp_mpcc->mpcc_bot != mpcc_to_remove)
 290                         temp_mpcc = temp_mpcc->mpcc_bot;
 291 
 292                 if (temp_mpcc && temp_mpcc->mpcc_bot == mpcc_to_remove) {
 293                         found = true;
 294                         temp_mpcc->mpcc_bot = mpcc_to_remove->mpcc_bot;
 295                         if (mpcc_to_remove->mpcc_bot) {
 296                                 /* remove MPCC in middle of list */
 297                                 REG_SET(MPCC_BOT_SEL[temp_mpcc->mpcc_id], 0,
 298                                                 MPCC_BOT_SEL, mpcc_to_remove->mpcc_bot->mpcc_id);
 299                         } else {
 300                                 /* remove MPCC from bottom of list */
 301                                 REG_SET(MPCC_BOT_SEL[temp_mpcc->mpcc_id], 0,
 302                                                 MPCC_BOT_SEL, 0xf);
 303                                 REG_UPDATE(MPCC_CONTROL[temp_mpcc->mpcc_id],
 304                                                 MPCC_MODE, MPCC_BLEND_MODE_TOP_LAYER_PASSTHROUGH);
 305                         }
 306                 }
 307         }
 308 
 309         if (found) {
 310                 /* turn off MPCC mux registers */
 311                 REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
 312                 REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
 313                 REG_SET(MPCC_OPP_ID[mpcc_id],  0, MPCC_OPP_ID,  0xf);
 314 
 315                 /* mark this mpcc as not in use */
 316                 mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id);
 317                 mpcc_to_remove->dpp_id = 0xf;
 318                 mpcc_to_remove->mpcc_bot = NULL;
 319         } else {
 320                 /* In case of resume from S3/S4, remove mpcc from bios left over */
 321                 REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
 322                 REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
 323                 REG_SET(MPCC_OPP_ID[mpcc_id],  0, MPCC_OPP_ID,  0xf);
 324         }
 325 }
 326 
 327 static void mpc1_init_mpcc(struct mpcc *mpcc, int mpcc_inst)
 328 {
 329         mpcc->mpcc_id = mpcc_inst;
 330         mpcc->dpp_id = 0xf;
 331         mpcc->mpcc_bot = NULL;
 332         mpcc->blnd_cfg.overlap_only = false;
 333         mpcc->blnd_cfg.global_alpha = 0xff;
 334         mpcc->blnd_cfg.global_gain = 0xff;
 335         mpcc->sm_cfg.enable = false;
 336 }
 337 
 338 /*
 339  * Reset the MPCC HW status by disconnecting all muxes.
 340  *
 341  * Parameters:
 342  * [in/out] mpc         - MPC context.
 343  *
 344  * Return:  void
 345  */
 346 void mpc1_mpc_init(struct mpc *mpc)
 347 {
 348         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
 349         int mpcc_id;
 350         int opp_id;
 351 
 352         mpc10->mpcc_in_use_mask = 0;
 353         for (mpcc_id = 0; mpcc_id < mpc10->num_mpcc; mpcc_id++) {
 354                 REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
 355                 REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
 356                 REG_SET(MPCC_OPP_ID[mpcc_id],  0, MPCC_OPP_ID,  0xf);
 357 
 358                 mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
 359         }
 360 
 361         for (opp_id = 0; opp_id < MAX_OPP; opp_id++) {
 362                 if (REG(MUX[opp_id]))
 363                         REG_UPDATE(MUX[opp_id], MPC_OUT_MUX, 0xf);
 364         }
 365 }
 366 
 367 void mpc1_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id)
 368 {
 369         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
 370         int opp_id;
 371 
 372         REG_GET(MPCC_OPP_ID[mpcc_id], MPCC_OPP_ID, &opp_id);
 373 
 374         REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
 375         REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
 376         REG_SET(MPCC_OPP_ID[mpcc_id],  0, MPCC_OPP_ID,  0xf);
 377 
 378         mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
 379 
 380         if (opp_id < MAX_OPP && REG(MUX[opp_id]))
 381                 REG_UPDATE(MUX[opp_id], MPC_OUT_MUX, 0xf);
 382 }
 383 
 384 
 385 void mpc1_init_mpcc_list_from_hw(
 386         struct mpc *mpc,
 387         struct mpc_tree *tree)
 388 {
 389         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
 390         unsigned int opp_id;
 391         unsigned int top_sel;
 392         unsigned int bot_sel;
 393         unsigned int out_mux;
 394         struct mpcc *mpcc;
 395         int mpcc_id;
 396         int bot_mpcc_id;
 397 
 398         REG_GET(MUX[tree->opp_id], MPC_OUT_MUX, &out_mux);
 399 
 400         if (out_mux != 0xf) {
 401                 for (mpcc_id = 0; mpcc_id < mpc10->num_mpcc; mpcc_id++) {
 402                         REG_GET(MPCC_OPP_ID[mpcc_id],  MPCC_OPP_ID,  &opp_id);
 403                         REG_GET(MPCC_TOP_SEL[mpcc_id], MPCC_TOP_SEL, &top_sel);
 404                         REG_GET(MPCC_BOT_SEL[mpcc_id],  MPCC_BOT_SEL, &bot_sel);
 405 
 406                         if (bot_sel == mpcc_id)
 407                                 bot_sel = 0xf;
 408 
 409                         if ((opp_id == tree->opp_id) && (top_sel != 0xf)) {
 410                                 mpcc = mpc1_get_mpcc(mpc, mpcc_id);
 411                                 mpcc->dpp_id = top_sel;
 412                                 mpc10->mpcc_in_use_mask |= 1 << mpcc_id;
 413 
 414                                 if (out_mux == mpcc_id)
 415                                         tree->opp_list = mpcc;
 416                                 if (bot_sel != 0xf && bot_sel < mpc10->num_mpcc) {
 417                                         bot_mpcc_id = bot_sel;
 418                                         REG_GET(MPCC_OPP_ID[bot_mpcc_id],  MPCC_OPP_ID,  &opp_id);
 419                                         REG_GET(MPCC_TOP_SEL[bot_mpcc_id], MPCC_TOP_SEL, &top_sel);
 420                                         if ((opp_id == tree->opp_id) && (top_sel != 0xf)) {
 421                                                 struct mpcc *mpcc_bottom = mpc1_get_mpcc(mpc, bot_mpcc_id);
 422 
 423                                                 mpcc->mpcc_bot = mpcc_bottom;
 424                                         }
 425                                 }
 426                         }
 427                 }
 428         }
 429 }
 430 
 431 void mpc1_read_mpcc_state(
 432                 struct mpc *mpc,
 433                 int mpcc_inst,
 434                 struct mpcc_state *s)
 435 {
 436         struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
 437 
 438         REG_GET(MPCC_OPP_ID[mpcc_inst], MPCC_OPP_ID, &s->opp_id);
 439         REG_GET(MPCC_TOP_SEL[mpcc_inst], MPCC_TOP_SEL, &s->dpp_id);
 440         REG_GET(MPCC_BOT_SEL[mpcc_inst], MPCC_BOT_SEL, &s->bot_mpcc_id);
 441         REG_GET_4(MPCC_CONTROL[mpcc_inst], MPCC_MODE, &s->mode,
 442                         MPCC_ALPHA_BLND_MODE, &s->alpha_mode,
 443                         MPCC_ALPHA_MULTIPLIED_MODE, &s->pre_multiplied_alpha,
 444                         MPCC_BLND_ACTIVE_OVERLAP_ONLY, &s->overlap_only);
 445         REG_GET_2(MPCC_STATUS[mpcc_inst], MPCC_IDLE, &s->idle,
 446                         MPCC_BUSY, &s->busy);
 447 }
 448 
 449 static const struct mpc_funcs dcn10_mpc_funcs = {
 450         .read_mpcc_state = mpc1_read_mpcc_state,
 451         .insert_plane = mpc1_insert_plane,
 452         .remove_mpcc = mpc1_remove_mpcc,
 453         .mpc_init = mpc1_mpc_init,
 454         .mpc_init_single_inst = mpc1_mpc_init_single_inst,
 455         .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
 456         .wait_for_idle = mpc1_assert_idle_mpcc,
 457         .assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect,
 458         .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
 459         .update_blending = mpc1_update_blending,
 460 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 461         .set_denorm = NULL,
 462         .set_denorm_clamp = NULL,
 463         .set_output_csc = NULL,
 464         .set_output_gamma = NULL,
 465 #endif
 466 };
 467 
 468 void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
 469         struct dc_context *ctx,
 470         const struct dcn_mpc_registers *mpc_regs,
 471         const struct dcn_mpc_shift *mpc_shift,
 472         const struct dcn_mpc_mask *mpc_mask,
 473         int num_mpcc)
 474 {
 475         int i;
 476 
 477         mpc10->base.ctx = ctx;
 478 
 479         mpc10->base.funcs = &dcn10_mpc_funcs;
 480 
 481         mpc10->mpc_regs = mpc_regs;
 482         mpc10->mpc_shift = mpc_shift;
 483         mpc10->mpc_mask = mpc_mask;
 484 
 485         mpc10->mpcc_in_use_mask = 0;
 486         mpc10->num_mpcc = num_mpcc;
 487 
 488         for (i = 0; i < MAX_MPCC; i++)
 489                 mpc1_init_mpcc(&mpc10->base.mpcc_array[i], i);
 490 }
 491 

/* [<][>][^][v][top][bottom][index][help] */