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