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