root/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c

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

DEFINITIONS

This source file includes following definitions.
  1. read_dce_straps
  2. create_audio
  3. dce112_timing_generator_create
  4. dce112_stream_encoder_create
  5. dce112_hwseq_create
  6. dce112_mem_input_create
  7. dce112_transform_destroy
  8. dce112_transform_create
  9. dce112_link_encoder_create
  10. dce112_ipp_create
  11. dce112_opp_create
  12. dce112_aux_engine_create
  13. dce112_i2c_hw_create
  14. dce112_clock_source_create
  15. dce112_clock_source_destroy
  16. destruct
  17. find_matching_pll
  18. build_mapped_resource
  19. dce112_validate_bandwidth
  20. resource_map_phy_clock_resources
  21. dce112_validate_surface_sets
  22. dce112_add_stream_to_ctx
  23. dce112_validate_global
  24. dce112_destroy_resource_pool
  25. bw_calcs_data_update_from_pplib
  26. dce112_resource_cap
  27. construct
  28. dce112_create_resource_pool

   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 <linux/slab.h>
  27 
  28 #include "dm_services.h"
  29 
  30 #include "link_encoder.h"
  31 #include "stream_encoder.h"
  32 
  33 #include "resource.h"
  34 #include "include/irq_service_interface.h"
  35 #include "dce110/dce110_resource.h"
  36 #include "dce110/dce110_timing_generator.h"
  37 
  38 #include "irq/dce110/irq_service_dce110.h"
  39 #include "dce/dce_mem_input.h"
  40 #include "dce/dce_transform.h"
  41 #include "dce/dce_link_encoder.h"
  42 #include "dce/dce_stream_encoder.h"
  43 #include "dce/dce_audio.h"
  44 #include "dce/dce_opp.h"
  45 #include "dce/dce_ipp.h"
  46 #include "dce/dce_clock_source.h"
  47 
  48 #include "dce/dce_hwseq.h"
  49 #include "dce112/dce112_hw_sequencer.h"
  50 #include "dce/dce_abm.h"
  51 #include "dce/dce_dmcu.h"
  52 #include "dce/dce_aux.h"
  53 #include "dce/dce_i2c.h"
  54 
  55 #include "reg_helper.h"
  56 
  57 #include "dce/dce_11_2_d.h"
  58 #include "dce/dce_11_2_sh_mask.h"
  59 
  60 #include "dce100/dce100_resource.h"
  61 #define DC_LOGGER \
  62                 dc->ctx->logger
  63 
  64 #ifndef mmDP_DPHY_INTERNAL_CTRL
  65         #define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
  66         #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
  67         #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7
  68         #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7
  69         #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7
  70         #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7
  71         #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7
  72         #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7
  73         #define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7
  74         #define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7
  75 #endif
  76 
  77 #ifndef mmBIOS_SCRATCH_2
  78         #define mmBIOS_SCRATCH_2 0x05CB
  79         #define mmBIOS_SCRATCH_3 0x05CC
  80         #define mmBIOS_SCRATCH_6 0x05CF
  81 #endif
  82 
  83 #ifndef mmDP_DPHY_BS_SR_SWAP_CNTL
  84         #define mmDP_DPHY_BS_SR_SWAP_CNTL                       0x4ADC
  85         #define mmDP0_DP_DPHY_BS_SR_SWAP_CNTL                   0x4ADC
  86         #define mmDP1_DP_DPHY_BS_SR_SWAP_CNTL                   0x4BDC
  87         #define mmDP2_DP_DPHY_BS_SR_SWAP_CNTL                   0x4CDC
  88         #define mmDP3_DP_DPHY_BS_SR_SWAP_CNTL                   0x4DDC
  89         #define mmDP4_DP_DPHY_BS_SR_SWAP_CNTL                   0x4EDC
  90         #define mmDP5_DP_DPHY_BS_SR_SWAP_CNTL                   0x4FDC
  91         #define mmDP6_DP_DPHY_BS_SR_SWAP_CNTL                   0x54DC
  92 #endif
  93 
  94 #ifndef mmDP_DPHY_FAST_TRAINING
  95         #define mmDP_DPHY_FAST_TRAINING                         0x4ABC
  96         #define mmDP0_DP_DPHY_FAST_TRAINING                     0x4ABC
  97         #define mmDP1_DP_DPHY_FAST_TRAINING                     0x4BBC
  98         #define mmDP2_DP_DPHY_FAST_TRAINING                     0x4CBC
  99         #define mmDP3_DP_DPHY_FAST_TRAINING                     0x4DBC
 100         #define mmDP4_DP_DPHY_FAST_TRAINING                     0x4EBC
 101         #define mmDP5_DP_DPHY_FAST_TRAINING                     0x4FBC
 102         #define mmDP6_DP_DPHY_FAST_TRAINING                     0x54BC
 103 #endif
 104 
 105 enum dce112_clk_src_array_id {
 106         DCE112_CLK_SRC_PLL0,
 107         DCE112_CLK_SRC_PLL1,
 108         DCE112_CLK_SRC_PLL2,
 109         DCE112_CLK_SRC_PLL3,
 110         DCE112_CLK_SRC_PLL4,
 111         DCE112_CLK_SRC_PLL5,
 112 
 113         DCE112_CLK_SRC_TOTAL
 114 };
 115 
 116 static const struct dce110_timing_generator_offsets dce112_tg_offsets[] = {
 117         {
 118                 .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
 119                 .dcp =  (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL),
 120         },
 121         {
 122                 .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
 123                 .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
 124         },
 125         {
 126                 .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
 127                 .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
 128         },
 129         {
 130                 .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
 131                 .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
 132         },
 133         {
 134                 .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
 135                 .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
 136         },
 137         {
 138                 .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
 139                 .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
 140         }
 141 };
 142 
 143 /* set register offset */
 144 #define SR(reg_name)\
 145         .reg_name = mm ## reg_name
 146 
 147 /* set register offset with instance */
 148 #define SRI(reg_name, block, id)\
 149         .reg_name = mm ## block ## id ## _ ## reg_name
 150 
 151 static const struct dce_dmcu_registers dmcu_regs = {
 152                 DMCU_DCE110_COMMON_REG_LIST()
 153 };
 154 
 155 static const struct dce_dmcu_shift dmcu_shift = {
 156                 DMCU_MASK_SH_LIST_DCE110(__SHIFT)
 157 };
 158 
 159 static const struct dce_dmcu_mask dmcu_mask = {
 160                 DMCU_MASK_SH_LIST_DCE110(_MASK)
 161 };
 162 
 163 static const struct dce_abm_registers abm_regs = {
 164                 ABM_DCE110_COMMON_REG_LIST()
 165 };
 166 
 167 static const struct dce_abm_shift abm_shift = {
 168                 ABM_MASK_SH_LIST_DCE110(__SHIFT)
 169 };
 170 
 171 static const struct dce_abm_mask abm_mask = {
 172                 ABM_MASK_SH_LIST_DCE110(_MASK)
 173 };
 174 
 175 #define ipp_regs(id)\
 176 [id] = {\
 177                 IPP_DCE110_REG_LIST_DCE_BASE(id)\
 178 }
 179 
 180 static const struct dce_ipp_registers ipp_regs[] = {
 181                 ipp_regs(0),
 182                 ipp_regs(1),
 183                 ipp_regs(2),
 184                 ipp_regs(3),
 185                 ipp_regs(4),
 186                 ipp_regs(5)
 187 };
 188 
 189 static const struct dce_ipp_shift ipp_shift = {
 190                 IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 191 };
 192 
 193 static const struct dce_ipp_mask ipp_mask = {
 194                 IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 195 };
 196 
 197 #define transform_regs(id)\
 198 [id] = {\
 199                 XFM_COMMON_REG_LIST_DCE110(id)\
 200 }
 201 
 202 static const struct dce_transform_registers xfm_regs[] = {
 203                 transform_regs(0),
 204                 transform_regs(1),
 205                 transform_regs(2),
 206                 transform_regs(3),
 207                 transform_regs(4),
 208                 transform_regs(5)
 209 };
 210 
 211 static const struct dce_transform_shift xfm_shift = {
 212                 XFM_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
 213 };
 214 
 215 static const struct dce_transform_mask xfm_mask = {
 216                 XFM_COMMON_MASK_SH_LIST_DCE110(_MASK)
 217 };
 218 
 219 #define aux_regs(id)\
 220 [id] = {\
 221         AUX_REG_LIST(id)\
 222 }
 223 
 224 static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
 225                 aux_regs(0),
 226                 aux_regs(1),
 227                 aux_regs(2),
 228                 aux_regs(3),
 229                 aux_regs(4),
 230                 aux_regs(5)
 231 };
 232 
 233 #define hpd_regs(id)\
 234 [id] = {\
 235         HPD_REG_LIST(id)\
 236 }
 237 
 238 static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
 239                 hpd_regs(0),
 240                 hpd_regs(1),
 241                 hpd_regs(2),
 242                 hpd_regs(3),
 243                 hpd_regs(4),
 244                 hpd_regs(5)
 245 };
 246 
 247 #define link_regs(id)\
 248 [id] = {\
 249         LE_DCE110_REG_LIST(id)\
 250 }
 251 
 252 static const struct dce110_link_enc_registers link_enc_regs[] = {
 253         link_regs(0),
 254         link_regs(1),
 255         link_regs(2),
 256         link_regs(3),
 257         link_regs(4),
 258         link_regs(5),
 259         link_regs(6),
 260 };
 261 
 262 #define stream_enc_regs(id)\
 263 [id] = {\
 264         SE_COMMON_REG_LIST(id),\
 265         .TMDS_CNTL = 0,\
 266 }
 267 
 268 static const struct dce110_stream_enc_registers stream_enc_regs[] = {
 269         stream_enc_regs(0),
 270         stream_enc_regs(1),
 271         stream_enc_regs(2),
 272         stream_enc_regs(3),
 273         stream_enc_regs(4),
 274         stream_enc_regs(5)
 275 };
 276 
 277 static const struct dce_stream_encoder_shift se_shift = {
 278                 SE_COMMON_MASK_SH_LIST_DCE112(__SHIFT)
 279 };
 280 
 281 static const struct dce_stream_encoder_mask se_mask = {
 282                 SE_COMMON_MASK_SH_LIST_DCE112(_MASK)
 283 };
 284 
 285 #define opp_regs(id)\
 286 [id] = {\
 287         OPP_DCE_112_REG_LIST(id),\
 288 }
 289 
 290 static const struct dce_opp_registers opp_regs[] = {
 291         opp_regs(0),
 292         opp_regs(1),
 293         opp_regs(2),
 294         opp_regs(3),
 295         opp_regs(4),
 296         opp_regs(5)
 297 };
 298 
 299 static const struct dce_opp_shift opp_shift = {
 300         OPP_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)
 301 };
 302 
 303 static const struct dce_opp_mask opp_mask = {
 304         OPP_COMMON_MASK_SH_LIST_DCE_112(_MASK)
 305 };
 306 
 307 #define aux_engine_regs(id)\
 308 [id] = {\
 309         AUX_COMMON_REG_LIST(id), \
 310         .AUX_RESET_MASK = 0 \
 311 }
 312 
 313 static const struct dce110_aux_registers aux_engine_regs[] = {
 314                 aux_engine_regs(0),
 315                 aux_engine_regs(1),
 316                 aux_engine_regs(2),
 317                 aux_engine_regs(3),
 318                 aux_engine_regs(4),
 319                 aux_engine_regs(5)
 320 };
 321 
 322 #define audio_regs(id)\
 323 [id] = {\
 324         AUD_COMMON_REG_LIST(id)\
 325 }
 326 
 327 static const struct dce_audio_registers audio_regs[] = {
 328         audio_regs(0),
 329         audio_regs(1),
 330         audio_regs(2),
 331         audio_regs(3),
 332         audio_regs(4),
 333         audio_regs(5)
 334 };
 335 
 336 static const struct dce_audio_shift audio_shift = {
 337                 AUD_COMMON_MASK_SH_LIST(__SHIFT)
 338 };
 339 
 340 static const struct dce_audio_mask audio_mask = {
 341                 AUD_COMMON_MASK_SH_LIST(_MASK)
 342 };
 343 
 344 #define clk_src_regs(index, id)\
 345 [index] = {\
 346         CS_COMMON_REG_LIST_DCE_112(id),\
 347 }
 348 
 349 static const struct dce110_clk_src_regs clk_src_regs[] = {
 350         clk_src_regs(0, A),
 351         clk_src_regs(1, B),
 352         clk_src_regs(2, C),
 353         clk_src_regs(3, D),
 354         clk_src_regs(4, E),
 355         clk_src_regs(5, F)
 356 };
 357 
 358 static const struct dce110_clk_src_shift cs_shift = {
 359                 CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)
 360 };
 361 
 362 static const struct dce110_clk_src_mask cs_mask = {
 363                 CS_COMMON_MASK_SH_LIST_DCE_112(_MASK)
 364 };
 365 
 366 static const struct bios_registers bios_regs = {
 367         .BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
 368         .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
 369 };
 370 
 371 static const struct resource_caps polaris_10_resource_cap = {
 372                 .num_timing_generator = 6,
 373                 .num_audio = 6,
 374                 .num_stream_encoder = 6,
 375                 .num_pll = 8, /* why 8? 6 combo PHY PLL + 2 regular PLLs? */
 376                 .num_ddc = 6,
 377 };
 378 
 379 static const struct resource_caps polaris_11_resource_cap = {
 380                 .num_timing_generator = 5,
 381                 .num_audio = 5,
 382                 .num_stream_encoder = 5,
 383                 .num_pll = 8, /* why 8? 6 combo PHY PLL + 2 regular PLLs? */
 384                 .num_ddc = 5,
 385 };
 386 
 387 static const struct dc_plane_cap plane_cap = {
 388         .type = DC_PLANE_TYPE_DCE_RGB,
 389 
 390         .pixel_format_support = {
 391                         .argb8888 = true,
 392                         .nv12 = false,
 393                         .fp16 = false
 394         },
 395 
 396         .max_upscale_factor = {
 397                         .argb8888 = 16000,
 398                         .nv12 = 1,
 399                         .fp16 = 1
 400         },
 401 
 402         .max_downscale_factor = {
 403                         .argb8888 = 250,
 404                         .nv12 = 1,
 405                         .fp16 = 1
 406         }
 407 };
 408 
 409 #define CTX  ctx
 410 #define REG(reg) mm ## reg
 411 
 412 #ifndef mmCC_DC_HDMI_STRAPS
 413 #define mmCC_DC_HDMI_STRAPS 0x4819
 414 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
 415 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
 416 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
 417 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
 418 #endif
 419 
 420 static void read_dce_straps(
 421         struct dc_context *ctx,
 422         struct resource_straps *straps)
 423 {
 424         REG_GET_2(CC_DC_HDMI_STRAPS,
 425                         HDMI_DISABLE, &straps->hdmi_disable,
 426                         AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
 427 
 428         REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);
 429 }
 430 
 431 static struct audio *create_audio(
 432                 struct dc_context *ctx, unsigned int inst)
 433 {
 434         return dce_audio_create(ctx, inst,
 435                         &audio_regs[inst], &audio_shift, &audio_mask);
 436 }
 437 
 438 
 439 static struct timing_generator *dce112_timing_generator_create(
 440                 struct dc_context *ctx,
 441                 uint32_t instance,
 442                 const struct dce110_timing_generator_offsets *offsets)
 443 {
 444         struct dce110_timing_generator *tg110 =
 445                 kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
 446 
 447         if (!tg110)
 448                 return NULL;
 449 
 450         dce110_timing_generator_construct(tg110, ctx, instance, offsets);
 451         return &tg110->base;
 452 }
 453 
 454 static struct stream_encoder *dce112_stream_encoder_create(
 455         enum engine_id eng_id,
 456         struct dc_context *ctx)
 457 {
 458         struct dce110_stream_encoder *enc110 =
 459                 kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
 460 
 461         if (!enc110)
 462                 return NULL;
 463 
 464         dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
 465                                         &stream_enc_regs[eng_id],
 466                                         &se_shift, &se_mask);
 467         return &enc110->base;
 468 }
 469 
 470 #define SRII(reg_name, block, id)\
 471         .reg_name[id] = mm ## block ## id ## _ ## reg_name
 472 
 473 static const struct dce_hwseq_registers hwseq_reg = {
 474                 HWSEQ_DCE112_REG_LIST()
 475 };
 476 
 477 static const struct dce_hwseq_shift hwseq_shift = {
 478                 HWSEQ_DCE112_MASK_SH_LIST(__SHIFT)
 479 };
 480 
 481 static const struct dce_hwseq_mask hwseq_mask = {
 482                 HWSEQ_DCE112_MASK_SH_LIST(_MASK)
 483 };
 484 
 485 static struct dce_hwseq *dce112_hwseq_create(
 486         struct dc_context *ctx)
 487 {
 488         struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
 489 
 490         if (hws) {
 491                 hws->ctx = ctx;
 492                 hws->regs = &hwseq_reg;
 493                 hws->shifts = &hwseq_shift;
 494                 hws->masks = &hwseq_mask;
 495         }
 496         return hws;
 497 }
 498 
 499 static const struct resource_create_funcs res_create_funcs = {
 500         .read_dce_straps = read_dce_straps,
 501         .create_audio = create_audio,
 502         .create_stream_encoder = dce112_stream_encoder_create,
 503         .create_hwseq = dce112_hwseq_create,
 504 };
 505 
 506 #define mi_inst_regs(id) { MI_DCE11_2_REG_LIST(id) }
 507 static const struct dce_mem_input_registers mi_regs[] = {
 508                 mi_inst_regs(0),
 509                 mi_inst_regs(1),
 510                 mi_inst_regs(2),
 511                 mi_inst_regs(3),
 512                 mi_inst_regs(4),
 513                 mi_inst_regs(5),
 514 };
 515 
 516 static const struct dce_mem_input_shift mi_shifts = {
 517                 MI_DCE11_2_MASK_SH_LIST(__SHIFT)
 518 };
 519 
 520 static const struct dce_mem_input_mask mi_masks = {
 521                 MI_DCE11_2_MASK_SH_LIST(_MASK)
 522 };
 523 
 524 static struct mem_input *dce112_mem_input_create(
 525         struct dc_context *ctx,
 526         uint32_t inst)
 527 {
 528         struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
 529                                                GFP_KERNEL);
 530 
 531         if (!dce_mi) {
 532                 BREAK_TO_DEBUGGER();
 533                 return NULL;
 534         }
 535 
 536         dce112_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
 537         return &dce_mi->base;
 538 }
 539 
 540 static void dce112_transform_destroy(struct transform **xfm)
 541 {
 542         kfree(TO_DCE_TRANSFORM(*xfm));
 543         *xfm = NULL;
 544 }
 545 
 546 static struct transform *dce112_transform_create(
 547         struct dc_context *ctx,
 548         uint32_t inst)
 549 {
 550         struct dce_transform *transform =
 551                 kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
 552 
 553         if (!transform)
 554                 return NULL;
 555 
 556         dce_transform_construct(transform, ctx, inst,
 557                                 &xfm_regs[inst], &xfm_shift, &xfm_mask);
 558         transform->lb_memory_size = 0x1404; /*5124*/
 559         return &transform->base;
 560 }
 561 
 562 static const struct encoder_feature_support link_enc_feature = {
 563                 .max_hdmi_deep_color = COLOR_DEPTH_121212,
 564                 .max_hdmi_pixel_clock = 600000,
 565                 .hdmi_ycbcr420_supported = true,
 566                 .dp_ycbcr420_supported = false,
 567                 .flags.bits.IS_HBR2_CAPABLE = true,
 568                 .flags.bits.IS_HBR3_CAPABLE = true,
 569                 .flags.bits.IS_TPS3_CAPABLE = true,
 570                 .flags.bits.IS_TPS4_CAPABLE = true
 571 };
 572 
 573 struct link_encoder *dce112_link_encoder_create(
 574         const struct encoder_init_data *enc_init_data)
 575 {
 576         struct dce110_link_encoder *enc110 =
 577                 kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
 578 
 579         if (!enc110)
 580                 return NULL;
 581 
 582         dce110_link_encoder_construct(enc110,
 583                                       enc_init_data,
 584                                       &link_enc_feature,
 585                                       &link_enc_regs[enc_init_data->transmitter],
 586                                       &link_enc_aux_regs[enc_init_data->channel - 1],
 587                                       &link_enc_hpd_regs[enc_init_data->hpd_source]);
 588         return &enc110->base;
 589 }
 590 
 591 static struct input_pixel_processor *dce112_ipp_create(
 592         struct dc_context *ctx, uint32_t inst)
 593 {
 594         struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
 595 
 596         if (!ipp) {
 597                 BREAK_TO_DEBUGGER();
 598                 return NULL;
 599         }
 600 
 601         dce_ipp_construct(ipp, ctx, inst,
 602                         &ipp_regs[inst], &ipp_shift, &ipp_mask);
 603         return &ipp->base;
 604 }
 605 
 606 struct output_pixel_processor *dce112_opp_create(
 607         struct dc_context *ctx,
 608         uint32_t inst)
 609 {
 610         struct dce110_opp *opp =
 611                 kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
 612 
 613         if (!opp)
 614                 return NULL;
 615 
 616         dce110_opp_construct(opp,
 617                              ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
 618         return &opp->base;
 619 }
 620 
 621 struct dce_aux *dce112_aux_engine_create(
 622         struct dc_context *ctx,
 623         uint32_t inst)
 624 {
 625         struct aux_engine_dce110 *aux_engine =
 626                 kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
 627 
 628         if (!aux_engine)
 629                 return NULL;
 630 
 631         dce110_aux_engine_construct(aux_engine, ctx, inst,
 632                                     SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 633                                     &aux_engine_regs[inst]);
 634 
 635         return &aux_engine->base;
 636 }
 637 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
 638 
 639 static const struct dce_i2c_registers i2c_hw_regs[] = {
 640                 i2c_inst_regs(1),
 641                 i2c_inst_regs(2),
 642                 i2c_inst_regs(3),
 643                 i2c_inst_regs(4),
 644                 i2c_inst_regs(5),
 645                 i2c_inst_regs(6),
 646 };
 647 
 648 static const struct dce_i2c_shift i2c_shifts = {
 649                 I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
 650 };
 651 
 652 static const struct dce_i2c_mask i2c_masks = {
 653                 I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
 654 };
 655 
 656 struct dce_i2c_hw *dce112_i2c_hw_create(
 657         struct dc_context *ctx,
 658         uint32_t inst)
 659 {
 660         struct dce_i2c_hw *dce_i2c_hw =
 661                 kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
 662 
 663         if (!dce_i2c_hw)
 664                 return NULL;
 665 
 666         dce112_i2c_hw_construct(dce_i2c_hw, ctx, inst,
 667                                     &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
 668 
 669         return dce_i2c_hw;
 670 }
 671 struct clock_source *dce112_clock_source_create(
 672         struct dc_context *ctx,
 673         struct dc_bios *bios,
 674         enum clock_source_id id,
 675         const struct dce110_clk_src_regs *regs,
 676         bool dp_clk_src)
 677 {
 678         struct dce110_clk_src *clk_src =
 679                 kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
 680 
 681         if (!clk_src)
 682                 return NULL;
 683 
 684         if (dce112_clk_src_construct(clk_src, ctx, bios, id,
 685                         regs, &cs_shift, &cs_mask)) {
 686                 clk_src->base.dp_clk_src = dp_clk_src;
 687                 return &clk_src->base;
 688         }
 689 
 690         kfree(clk_src);
 691         BREAK_TO_DEBUGGER();
 692         return NULL;
 693 }
 694 
 695 void dce112_clock_source_destroy(struct clock_source **clk_src)
 696 {
 697         kfree(TO_DCE110_CLK_SRC(*clk_src));
 698         *clk_src = NULL;
 699 }
 700 
 701 static void destruct(struct dce110_resource_pool *pool)
 702 {
 703         unsigned int i;
 704 
 705         for (i = 0; i < pool->base.pipe_count; i++) {
 706                 if (pool->base.opps[i] != NULL)
 707                         dce110_opp_destroy(&pool->base.opps[i]);
 708 
 709                 if (pool->base.transforms[i] != NULL)
 710                         dce112_transform_destroy(&pool->base.transforms[i]);
 711 
 712                 if (pool->base.ipps[i] != NULL)
 713                         dce_ipp_destroy(&pool->base.ipps[i]);
 714 
 715                 if (pool->base.mis[i] != NULL) {
 716                         kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
 717                         pool->base.mis[i] = NULL;
 718                 }
 719 
 720                 if (pool->base.timing_generators[i] != NULL) {
 721                         kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
 722                         pool->base.timing_generators[i] = NULL;
 723                 }
 724         }
 725 
 726         for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
 727                 if (pool->base.engines[i] != NULL)
 728                         dce110_engine_destroy(&pool->base.engines[i]);
 729                 if (pool->base.hw_i2cs[i] != NULL) {
 730                         kfree(pool->base.hw_i2cs[i]);
 731                         pool->base.hw_i2cs[i] = NULL;
 732                 }
 733                 if (pool->base.sw_i2cs[i] != NULL) {
 734                         kfree(pool->base.sw_i2cs[i]);
 735                         pool->base.sw_i2cs[i] = NULL;
 736                 }
 737         }
 738 
 739         for (i = 0; i < pool->base.stream_enc_count; i++) {
 740                 if (pool->base.stream_enc[i] != NULL)
 741                         kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
 742         }
 743 
 744         for (i = 0; i < pool->base.clk_src_count; i++) {
 745                 if (pool->base.clock_sources[i] != NULL) {
 746                         dce112_clock_source_destroy(&pool->base.clock_sources[i]);
 747                 }
 748         }
 749 
 750         if (pool->base.dp_clock_source != NULL)
 751                 dce112_clock_source_destroy(&pool->base.dp_clock_source);
 752 
 753         for (i = 0; i < pool->base.audio_count; i++)    {
 754                 if (pool->base.audios[i] != NULL) {
 755                         dce_aud_destroy(&pool->base.audios[i]);
 756                 }
 757         }
 758 
 759         if (pool->base.abm != NULL)
 760                 dce_abm_destroy(&pool->base.abm);
 761 
 762         if (pool->base.dmcu != NULL)
 763                 dce_dmcu_destroy(&pool->base.dmcu);
 764 
 765         if (pool->base.irqs != NULL) {
 766                 dal_irq_service_destroy(&pool->base.irqs);
 767         }
 768 }
 769 
 770 static struct clock_source *find_matching_pll(
 771                 struct resource_context *res_ctx,
 772                 const struct resource_pool *pool,
 773                 const struct dc_stream_state *const stream)
 774 {
 775         switch (stream->link->link_enc->transmitter) {
 776         case TRANSMITTER_UNIPHY_A:
 777                 return pool->clock_sources[DCE112_CLK_SRC_PLL0];
 778         case TRANSMITTER_UNIPHY_B:
 779                 return pool->clock_sources[DCE112_CLK_SRC_PLL1];
 780         case TRANSMITTER_UNIPHY_C:
 781                 return pool->clock_sources[DCE112_CLK_SRC_PLL2];
 782         case TRANSMITTER_UNIPHY_D:
 783                 return pool->clock_sources[DCE112_CLK_SRC_PLL3];
 784         case TRANSMITTER_UNIPHY_E:
 785                 return pool->clock_sources[DCE112_CLK_SRC_PLL4];
 786         case TRANSMITTER_UNIPHY_F:
 787                 return pool->clock_sources[DCE112_CLK_SRC_PLL5];
 788         default:
 789                 return NULL;
 790         };
 791 
 792         return 0;
 793 }
 794 
 795 static enum dc_status build_mapped_resource(
 796                 const struct dc *dc,
 797                 struct dc_state *context,
 798                 struct dc_stream_state *stream)
 799 {
 800         struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
 801 
 802         if (!pipe_ctx)
 803                 return DC_ERROR_UNEXPECTED;
 804 
 805         dce110_resource_build_pipe_hw_param(pipe_ctx);
 806 
 807         resource_build_info_frame(pipe_ctx);
 808 
 809         return DC_OK;
 810 }
 811 
 812 bool dce112_validate_bandwidth(
 813         struct dc *dc,
 814         struct dc_state *context,
 815         bool fast_validate)
 816 {
 817         bool result = false;
 818 
 819         DC_LOG_BANDWIDTH_CALCS(
 820                 "%s: start",
 821                 __func__);
 822 
 823         if (bw_calcs(
 824                         dc->ctx,
 825                         dc->bw_dceip,
 826                         dc->bw_vbios,
 827                         context->res_ctx.pipe_ctx,
 828                         dc->res_pool->pipe_count,
 829                         &context->bw_ctx.bw.dce))
 830                 result = true;
 831 
 832         if (!result)
 833                 DC_LOG_BANDWIDTH_VALIDATION(
 834                         "%s: Bandwidth validation failed!",
 835                         __func__);
 836 
 837         if (memcmp(&dc->current_state->bw_ctx.bw.dce,
 838                         &context->bw_ctx.bw.dce, sizeof(context->bw_ctx.bw.dce))) {
 839 
 840                 DC_LOG_BANDWIDTH_CALCS(
 841                         "%s: finish,\n"
 842                         "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
 843                         "stutMark_b: %d stutMark_a: %d\n"
 844                         "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
 845                         "stutMark_b: %d stutMark_a: %d\n"
 846                         "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
 847                         "stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n"
 848                         "cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n"
 849                         "sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n"
 850                         ,
 851                         __func__,
 852                         context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].b_mark,
 853                         context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].a_mark,
 854                         context->bw_ctx.bw.dce.urgent_wm_ns[0].b_mark,
 855                         context->bw_ctx.bw.dce.urgent_wm_ns[0].a_mark,
 856                         context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].b_mark,
 857                         context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].a_mark,
 858                         context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].b_mark,
 859                         context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].a_mark,
 860                         context->bw_ctx.bw.dce.urgent_wm_ns[1].b_mark,
 861                         context->bw_ctx.bw.dce.urgent_wm_ns[1].a_mark,
 862                         context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].b_mark,
 863                         context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].a_mark,
 864                         context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].b_mark,
 865                         context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].a_mark,
 866                         context->bw_ctx.bw.dce.urgent_wm_ns[2].b_mark,
 867                         context->bw_ctx.bw.dce.urgent_wm_ns[2].a_mark,
 868                         context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].b_mark,
 869                         context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].a_mark,
 870                         context->bw_ctx.bw.dce.stutter_mode_enable,
 871                         context->bw_ctx.bw.dce.cpuc_state_change_enable,
 872                         context->bw_ctx.bw.dce.cpup_state_change_enable,
 873                         context->bw_ctx.bw.dce.nbp_state_change_enable,
 874                         context->bw_ctx.bw.dce.all_displays_in_sync,
 875                         context->bw_ctx.bw.dce.dispclk_khz,
 876                         context->bw_ctx.bw.dce.sclk_khz,
 877                         context->bw_ctx.bw.dce.sclk_deep_sleep_khz,
 878                         context->bw_ctx.bw.dce.yclk_khz,
 879                         context->bw_ctx.bw.dce.blackout_recovery_time_us);
 880         }
 881         return result;
 882 }
 883 
 884 enum dc_status resource_map_phy_clock_resources(
 885                 const struct dc *dc,
 886                 struct dc_state *context,
 887                 struct dc_stream_state *stream)
 888 {
 889 
 890         /* acquire new resources */
 891         struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(
 892                         &context->res_ctx, stream);
 893 
 894         if (!pipe_ctx)
 895                 return DC_ERROR_UNEXPECTED;
 896 
 897         if (dc_is_dp_signal(pipe_ctx->stream->signal)
 898                 || dc_is_virtual_signal(pipe_ctx->stream->signal))
 899                 pipe_ctx->clock_source =
 900                                 dc->res_pool->dp_clock_source;
 901         else
 902                 pipe_ctx->clock_source = find_matching_pll(
 903                         &context->res_ctx, dc->res_pool,
 904                         stream);
 905 
 906         if (pipe_ctx->clock_source == NULL)
 907                 return DC_NO_CLOCK_SOURCE_RESOURCE;
 908 
 909         resource_reference_clock_source(
 910                 &context->res_ctx,
 911                 dc->res_pool,
 912                 pipe_ctx->clock_source);
 913 
 914         return DC_OK;
 915 }
 916 
 917 static bool dce112_validate_surface_sets(
 918                 struct dc_state *context)
 919 {
 920         int i;
 921 
 922         for (i = 0; i < context->stream_count; i++) {
 923                 if (context->stream_status[i].plane_count == 0)
 924                         continue;
 925 
 926                 if (context->stream_status[i].plane_count > 1)
 927                         return false;
 928 
 929                 if (context->stream_status[i].plane_states[0]->format
 930                                 >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
 931                         return false;
 932         }
 933 
 934         return true;
 935 }
 936 
 937 enum dc_status dce112_add_stream_to_ctx(
 938                 struct dc *dc,
 939                 struct dc_state *new_ctx,
 940                 struct dc_stream_state *dc_stream)
 941 {
 942         enum dc_status result = DC_ERROR_UNEXPECTED;
 943 
 944         result = resource_map_pool_resources(dc, new_ctx, dc_stream);
 945 
 946         if (result == DC_OK)
 947                 result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream);
 948 
 949 
 950         if (result == DC_OK)
 951                 result = build_mapped_resource(dc, new_ctx, dc_stream);
 952 
 953         return result;
 954 }
 955 
 956 enum dc_status dce112_validate_global(
 957                 struct dc *dc,
 958                 struct dc_state *context)
 959 {
 960         if (!dce112_validate_surface_sets(context))
 961                 return DC_FAIL_SURFACE_VALIDATE;
 962 
 963         return DC_OK;
 964 }
 965 
 966 static void dce112_destroy_resource_pool(struct resource_pool **pool)
 967 {
 968         struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
 969 
 970         destruct(dce110_pool);
 971         kfree(dce110_pool);
 972         *pool = NULL;
 973 }
 974 
 975 static const struct resource_funcs dce112_res_pool_funcs = {
 976         .destroy = dce112_destroy_resource_pool,
 977         .link_enc_create = dce112_link_encoder_create,
 978         .validate_bandwidth = dce112_validate_bandwidth,
 979         .validate_plane = dce100_validate_plane,
 980         .add_stream_to_ctx = dce112_add_stream_to_ctx,
 981         .validate_global = dce112_validate_global,
 982         .find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link
 983 };
 984 
 985 static void bw_calcs_data_update_from_pplib(struct dc *dc)
 986 {
 987         struct dm_pp_clock_levels_with_latency eng_clks = {0};
 988         struct dm_pp_clock_levels_with_latency mem_clks = {0};
 989         struct dm_pp_wm_sets_with_clock_ranges clk_ranges = {0};
 990         struct dm_pp_clock_levels clks = {0};
 991         int memory_type_multiplier = MEMORY_TYPE_MULTIPLIER_CZ;
 992 
 993         if (dc->bw_vbios && dc->bw_vbios->memory_type == bw_def_hbm)
 994                 memory_type_multiplier = MEMORY_TYPE_HBM;
 995 
 996         /*do system clock  TODO PPLIB: after PPLIB implement,
 997          * then remove old way
 998          */
 999         if (!dm_pp_get_clock_levels_by_type_with_latency(
1000                         dc->ctx,
1001                         DM_PP_CLOCK_TYPE_ENGINE_CLK,
1002                         &eng_clks)) {
1003 
1004                 /* This is only for temporary */
1005                 dm_pp_get_clock_levels_by_type(
1006                                 dc->ctx,
1007                                 DM_PP_CLOCK_TYPE_ENGINE_CLK,
1008                                 &clks);
1009                 /* convert all the clock fro kHz to fix point mHz */
1010                 dc->bw_vbios->high_sclk = bw_frc_to_fixed(
1011                                 clks.clocks_in_khz[clks.num_levels-1], 1000);
1012                 dc->bw_vbios->mid1_sclk  = bw_frc_to_fixed(
1013                                 clks.clocks_in_khz[clks.num_levels/8], 1000);
1014                 dc->bw_vbios->mid2_sclk  = bw_frc_to_fixed(
1015                                 clks.clocks_in_khz[clks.num_levels*2/8], 1000);
1016                 dc->bw_vbios->mid3_sclk  = bw_frc_to_fixed(
1017                                 clks.clocks_in_khz[clks.num_levels*3/8], 1000);
1018                 dc->bw_vbios->mid4_sclk  = bw_frc_to_fixed(
1019                                 clks.clocks_in_khz[clks.num_levels*4/8], 1000);
1020                 dc->bw_vbios->mid5_sclk  = bw_frc_to_fixed(
1021                                 clks.clocks_in_khz[clks.num_levels*5/8], 1000);
1022                 dc->bw_vbios->mid6_sclk  = bw_frc_to_fixed(
1023                                 clks.clocks_in_khz[clks.num_levels*6/8], 1000);
1024                 dc->bw_vbios->low_sclk  = bw_frc_to_fixed(
1025                                 clks.clocks_in_khz[0], 1000);
1026 
1027                 /*do memory clock*/
1028                 dm_pp_get_clock_levels_by_type(
1029                                 dc->ctx,
1030                                 DM_PP_CLOCK_TYPE_MEMORY_CLK,
1031                                 &clks);
1032 
1033                 dc->bw_vbios->low_yclk = bw_frc_to_fixed(
1034                         clks.clocks_in_khz[0] * memory_type_multiplier, 1000);
1035                 dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
1036                         clks.clocks_in_khz[clks.num_levels>>1] * memory_type_multiplier,
1037                         1000);
1038                 dc->bw_vbios->high_yclk = bw_frc_to_fixed(
1039                         clks.clocks_in_khz[clks.num_levels-1] * memory_type_multiplier,
1040                         1000);
1041 
1042                 return;
1043         }
1044 
1045         /* convert all the clock fro kHz to fix point mHz  TODO: wloop data */
1046         dc->bw_vbios->high_sclk = bw_frc_to_fixed(
1047                 eng_clks.data[eng_clks.num_levels-1].clocks_in_khz, 1000);
1048         dc->bw_vbios->mid1_sclk  = bw_frc_to_fixed(
1049                 eng_clks.data[eng_clks.num_levels/8].clocks_in_khz, 1000);
1050         dc->bw_vbios->mid2_sclk  = bw_frc_to_fixed(
1051                 eng_clks.data[eng_clks.num_levels*2/8].clocks_in_khz, 1000);
1052         dc->bw_vbios->mid3_sclk  = bw_frc_to_fixed(
1053                 eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz, 1000);
1054         dc->bw_vbios->mid4_sclk  = bw_frc_to_fixed(
1055                 eng_clks.data[eng_clks.num_levels*4/8].clocks_in_khz, 1000);
1056         dc->bw_vbios->mid5_sclk  = bw_frc_to_fixed(
1057                 eng_clks.data[eng_clks.num_levels*5/8].clocks_in_khz, 1000);
1058         dc->bw_vbios->mid6_sclk  = bw_frc_to_fixed(
1059                 eng_clks.data[eng_clks.num_levels*6/8].clocks_in_khz, 1000);
1060         dc->bw_vbios->low_sclk  = bw_frc_to_fixed(
1061                         eng_clks.data[0].clocks_in_khz, 1000);
1062 
1063         /*do memory clock*/
1064         dm_pp_get_clock_levels_by_type_with_latency(
1065                         dc->ctx,
1066                         DM_PP_CLOCK_TYPE_MEMORY_CLK,
1067                         &mem_clks);
1068 
1069         /* we don't need to call PPLIB for validation clock since they
1070          * also give us the highest sclk and highest mclk (UMA clock).
1071          * ALSO always convert UMA clock (from PPLIB)  to YCLK (HW formula):
1072          * YCLK = UMACLK*m_memoryTypeMultiplier
1073          */
1074         dc->bw_vbios->low_yclk = bw_frc_to_fixed(
1075                 mem_clks.data[0].clocks_in_khz * memory_type_multiplier, 1000);
1076         dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
1077                 mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * memory_type_multiplier,
1078                 1000);
1079         dc->bw_vbios->high_yclk = bw_frc_to_fixed(
1080                 mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * memory_type_multiplier,
1081                 1000);
1082 
1083         /* Now notify PPLib/SMU about which Watermarks sets they should select
1084          * depending on DPM state they are in. And update BW MGR GFX Engine and
1085          * Memory clock member variables for Watermarks calculations for each
1086          * Watermark Set
1087          */
1088         clk_ranges.num_wm_sets = 4;
1089         clk_ranges.wm_clk_ranges[0].wm_set_id = WM_SET_A;
1090         clk_ranges.wm_clk_ranges[0].wm_min_eng_clk_in_khz =
1091                         eng_clks.data[0].clocks_in_khz;
1092         clk_ranges.wm_clk_ranges[0].wm_max_eng_clk_in_khz =
1093                         eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
1094         clk_ranges.wm_clk_ranges[0].wm_min_mem_clk_in_khz =
1095                         mem_clks.data[0].clocks_in_khz;
1096         clk_ranges.wm_clk_ranges[0].wm_max_mem_clk_in_khz =
1097                         mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
1098 
1099         clk_ranges.wm_clk_ranges[1].wm_set_id = WM_SET_B;
1100         clk_ranges.wm_clk_ranges[1].wm_min_eng_clk_in_khz =
1101                         eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
1102         /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
1103         clk_ranges.wm_clk_ranges[1].wm_max_eng_clk_in_khz = 5000000;
1104         clk_ranges.wm_clk_ranges[1].wm_min_mem_clk_in_khz =
1105                         mem_clks.data[0].clocks_in_khz;
1106         clk_ranges.wm_clk_ranges[1].wm_max_mem_clk_in_khz =
1107                         mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
1108 
1109         clk_ranges.wm_clk_ranges[2].wm_set_id = WM_SET_C;
1110         clk_ranges.wm_clk_ranges[2].wm_min_eng_clk_in_khz =
1111                         eng_clks.data[0].clocks_in_khz;
1112         clk_ranges.wm_clk_ranges[2].wm_max_eng_clk_in_khz =
1113                         eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
1114         clk_ranges.wm_clk_ranges[2].wm_min_mem_clk_in_khz =
1115                         mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
1116         /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
1117         clk_ranges.wm_clk_ranges[2].wm_max_mem_clk_in_khz = 5000000;
1118 
1119         clk_ranges.wm_clk_ranges[3].wm_set_id = WM_SET_D;
1120         clk_ranges.wm_clk_ranges[3].wm_min_eng_clk_in_khz =
1121                         eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
1122         /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
1123         clk_ranges.wm_clk_ranges[3].wm_max_eng_clk_in_khz = 5000000;
1124         clk_ranges.wm_clk_ranges[3].wm_min_mem_clk_in_khz =
1125                         mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
1126         /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
1127         clk_ranges.wm_clk_ranges[3].wm_max_mem_clk_in_khz = 5000000;
1128 
1129         /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
1130         dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges);
1131 }
1132 
1133 const struct resource_caps *dce112_resource_cap(
1134         struct hw_asic_id *asic_id)
1135 {
1136         if (ASIC_REV_IS_POLARIS11_M(asic_id->hw_internal_rev) ||
1137             ASIC_REV_IS_POLARIS12_V(asic_id->hw_internal_rev))
1138                 return &polaris_11_resource_cap;
1139         else
1140                 return &polaris_10_resource_cap;
1141 }
1142 
1143 static bool construct(
1144         uint8_t num_virtual_links,
1145         struct dc *dc,
1146         struct dce110_resource_pool *pool)
1147 {
1148         unsigned int i;
1149         struct dc_context *ctx = dc->ctx;
1150 
1151         ctx->dc_bios->regs = &bios_regs;
1152 
1153         pool->base.res_cap = dce112_resource_cap(&ctx->asic_id);
1154         pool->base.funcs = &dce112_res_pool_funcs;
1155 
1156         /*************************************************
1157          *  Resource + asic cap harcoding                *
1158          *************************************************/
1159         pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1160         pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
1161         pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
1162         dc->caps.max_downscale_ratio = 200;
1163         dc->caps.i2c_speed_in_khz = 100;
1164         dc->caps.max_cursor_size = 128;
1165         dc->caps.dual_link_dvi = true;
1166 
1167 
1168         /*************************************************
1169          *  Create resources                             *
1170          *************************************************/
1171 
1172         pool->base.clock_sources[DCE112_CLK_SRC_PLL0] =
1173                         dce112_clock_source_create(
1174                                 ctx, ctx->dc_bios,
1175                                 CLOCK_SOURCE_COMBO_PHY_PLL0,
1176                                 &clk_src_regs[0], false);
1177         pool->base.clock_sources[DCE112_CLK_SRC_PLL1] =
1178                         dce112_clock_source_create(
1179                                 ctx, ctx->dc_bios,
1180                                 CLOCK_SOURCE_COMBO_PHY_PLL1,
1181                                 &clk_src_regs[1], false);
1182         pool->base.clock_sources[DCE112_CLK_SRC_PLL2] =
1183                         dce112_clock_source_create(
1184                                 ctx, ctx->dc_bios,
1185                                 CLOCK_SOURCE_COMBO_PHY_PLL2,
1186                                 &clk_src_regs[2], false);
1187         pool->base.clock_sources[DCE112_CLK_SRC_PLL3] =
1188                         dce112_clock_source_create(
1189                                 ctx, ctx->dc_bios,
1190                                 CLOCK_SOURCE_COMBO_PHY_PLL3,
1191                                 &clk_src_regs[3], false);
1192         pool->base.clock_sources[DCE112_CLK_SRC_PLL4] =
1193                         dce112_clock_source_create(
1194                                 ctx, ctx->dc_bios,
1195                                 CLOCK_SOURCE_COMBO_PHY_PLL4,
1196                                 &clk_src_regs[4], false);
1197         pool->base.clock_sources[DCE112_CLK_SRC_PLL5] =
1198                         dce112_clock_source_create(
1199                                 ctx, ctx->dc_bios,
1200                                 CLOCK_SOURCE_COMBO_PHY_PLL5,
1201                                 &clk_src_regs[5], false);
1202         pool->base.clk_src_count = DCE112_CLK_SRC_TOTAL;
1203 
1204         pool->base.dp_clock_source =  dce112_clock_source_create(
1205                 ctx, ctx->dc_bios,
1206                 CLOCK_SOURCE_ID_DP_DTO, &clk_src_regs[0], true);
1207 
1208 
1209         for (i = 0; i < pool->base.clk_src_count; i++) {
1210                 if (pool->base.clock_sources[i] == NULL) {
1211                         dm_error("DC: failed to create clock sources!\n");
1212                         BREAK_TO_DEBUGGER();
1213                         goto res_create_fail;
1214                 }
1215         }
1216 
1217         pool->base.dmcu = dce_dmcu_create(ctx,
1218                         &dmcu_regs,
1219                         &dmcu_shift,
1220                         &dmcu_mask);
1221         if (pool->base.dmcu == NULL) {
1222                 dm_error("DC: failed to create dmcu!\n");
1223                 BREAK_TO_DEBUGGER();
1224                 goto res_create_fail;
1225         }
1226 
1227         pool->base.abm = dce_abm_create(ctx,
1228                         &abm_regs,
1229                         &abm_shift,
1230                         &abm_mask);
1231         if (pool->base.abm == NULL) {
1232                 dm_error("DC: failed to create abm!\n");
1233                 BREAK_TO_DEBUGGER();
1234                 goto res_create_fail;
1235         }
1236 
1237         {
1238                 struct irq_service_init_data init_data;
1239                 init_data.ctx = dc->ctx;
1240                 pool->base.irqs = dal_irq_service_dce110_create(&init_data);
1241                 if (!pool->base.irqs)
1242                         goto res_create_fail;
1243         }
1244 
1245         for (i = 0; i < pool->base.pipe_count; i++) {
1246                 pool->base.timing_generators[i] =
1247                                 dce112_timing_generator_create(
1248                                         ctx,
1249                                         i,
1250                                         &dce112_tg_offsets[i]);
1251                 if (pool->base.timing_generators[i] == NULL) {
1252                         BREAK_TO_DEBUGGER();
1253                         dm_error("DC: failed to create tg!\n");
1254                         goto res_create_fail;
1255                 }
1256 
1257                 pool->base.mis[i] = dce112_mem_input_create(ctx, i);
1258                 if (pool->base.mis[i] == NULL) {
1259                         BREAK_TO_DEBUGGER();
1260                         dm_error(
1261                                 "DC: failed to create memory input!\n");
1262                         goto res_create_fail;
1263                 }
1264 
1265                 pool->base.ipps[i] = dce112_ipp_create(ctx, i);
1266                 if (pool->base.ipps[i] == NULL) {
1267                         BREAK_TO_DEBUGGER();
1268                         dm_error(
1269                                 "DC:failed to create input pixel processor!\n");
1270                         goto res_create_fail;
1271                 }
1272 
1273                 pool->base.transforms[i] = dce112_transform_create(ctx, i);
1274                 if (pool->base.transforms[i] == NULL) {
1275                         BREAK_TO_DEBUGGER();
1276                         dm_error(
1277                                 "DC: failed to create transform!\n");
1278                         goto res_create_fail;
1279                 }
1280 
1281                 pool->base.opps[i] = dce112_opp_create(
1282                         ctx,
1283                         i);
1284                 if (pool->base.opps[i] == NULL) {
1285                         BREAK_TO_DEBUGGER();
1286                         dm_error(
1287                                 "DC:failed to create output pixel processor!\n");
1288                         goto res_create_fail;
1289                 }
1290         }
1291 
1292         for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1293                 pool->base.engines[i] = dce112_aux_engine_create(ctx, i);
1294                 if (pool->base.engines[i] == NULL) {
1295                         BREAK_TO_DEBUGGER();
1296                         dm_error(
1297                                 "DC:failed to create aux engine!!\n");
1298                         goto res_create_fail;
1299                 }
1300                 pool->base.hw_i2cs[i] = dce112_i2c_hw_create(ctx, i);
1301                 if (pool->base.hw_i2cs[i] == NULL) {
1302                         BREAK_TO_DEBUGGER();
1303                         dm_error(
1304                                 "DC:failed to create i2c engine!!\n");
1305                         goto res_create_fail;
1306                 }
1307                 pool->base.sw_i2cs[i] = NULL;
1308         }
1309 
1310         if (!resource_construct(num_virtual_links, dc, &pool->base,
1311                           &res_create_funcs))
1312                 goto res_create_fail;
1313 
1314         dc->caps.max_planes =  pool->base.pipe_count;
1315 
1316         for (i = 0; i < dc->caps.max_planes; ++i)
1317                 dc->caps.planes[i] = plane_cap;
1318 
1319         /* Create hardware sequencer */
1320         dce112_hw_sequencer_construct(dc);
1321 
1322         bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id);
1323 
1324         bw_calcs_data_update_from_pplib(dc);
1325 
1326         return true;
1327 
1328 res_create_fail:
1329         destruct(pool);
1330         return false;
1331 }
1332 
1333 struct resource_pool *dce112_create_resource_pool(
1334         uint8_t num_virtual_links,
1335         struct dc *dc)
1336 {
1337         struct dce110_resource_pool *pool =
1338                 kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1339 
1340         if (!pool)
1341                 return NULL;
1342 
1343         if (construct(num_virtual_links, dc, pool))
1344                 return &pool->base;
1345 
1346         kfree(pool);
1347         BREAK_TO_DEBUGGER();
1348         return NULL;
1349 }

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