linux/drivers/gpu/drm/amd/display/dc/dce80/dce80_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 <linux/slab.h>
  27
  28#include "dce/dce_8_0_d.h"
  29#include "dce/dce_8_0_sh_mask.h"
  30
  31#include "dm_services.h"
  32
  33#include "link_encoder.h"
  34#include "stream_encoder.h"
  35
  36#include "resource.h"
  37#include "include/irq_service_interface.h"
  38#include "irq/dce80/irq_service_dce80.h"
  39#include "dce110/dce110_timing_generator.h"
  40#include "dce110/dce110_resource.h"
  41#include "dce80/dce80_timing_generator.h"
  42#include "dce/dce_mem_input.h"
  43#include "dce/dce_link_encoder.h"
  44#include "dce/dce_stream_encoder.h"
  45#include "dce/dce_ipp.h"
  46#include "dce/dce_transform.h"
  47#include "dce/dce_opp.h"
  48#include "dce/dce_clock_source.h"
  49#include "dce/dce_audio.h"
  50#include "dce/dce_hwseq.h"
  51#include "dce80/dce80_hw_sequencer.h"
  52#include "dce100/dce100_resource.h"
  53#include "dce/dce_panel_cntl.h"
  54
  55#include "reg_helper.h"
  56
  57#include "dce/dce_dmcu.h"
  58#include "dce/dce_aux.h"
  59#include "dce/dce_abm.h"
  60#include "dce/dce_i2c.h"
  61/* TODO remove this include */
  62
  63#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
  64#include "gmc/gmc_7_1_d.h"
  65#include "gmc/gmc_7_1_sh_mask.h"
  66#endif
  67
  68#ifndef mmDP_DPHY_INTERNAL_CTRL
  69#define mmDP_DPHY_INTERNAL_CTRL                         0x1CDE
  70#define mmDP0_DP_DPHY_INTERNAL_CTRL                     0x1CDE
  71#define mmDP1_DP_DPHY_INTERNAL_CTRL                     0x1FDE
  72#define mmDP2_DP_DPHY_INTERNAL_CTRL                     0x42DE
  73#define mmDP3_DP_DPHY_INTERNAL_CTRL                     0x45DE
  74#define mmDP4_DP_DPHY_INTERNAL_CTRL                     0x48DE
  75#define mmDP5_DP_DPHY_INTERNAL_CTRL                     0x4BDE
  76#define mmDP6_DP_DPHY_INTERNAL_CTRL                     0x4EDE
  77#endif
  78
  79
  80#ifndef mmBIOS_SCRATCH_2
  81        #define mmBIOS_SCRATCH_2 0x05CB
  82        #define mmBIOS_SCRATCH_3 0x05CC
  83        #define mmBIOS_SCRATCH_6 0x05CF
  84#endif
  85
  86#ifndef mmDP_DPHY_FAST_TRAINING
  87        #define mmDP_DPHY_FAST_TRAINING                         0x1CCE
  88        #define mmDP0_DP_DPHY_FAST_TRAINING                     0x1CCE
  89        #define mmDP1_DP_DPHY_FAST_TRAINING                     0x1FCE
  90        #define mmDP2_DP_DPHY_FAST_TRAINING                     0x42CE
  91        #define mmDP3_DP_DPHY_FAST_TRAINING                     0x45CE
  92        #define mmDP4_DP_DPHY_FAST_TRAINING                     0x48CE
  93        #define mmDP5_DP_DPHY_FAST_TRAINING                     0x4BCE
  94        #define mmDP6_DP_DPHY_FAST_TRAINING                     0x4ECE
  95#endif
  96
  97
  98#ifndef mmHPD_DC_HPD_CONTROL
  99        #define mmHPD_DC_HPD_CONTROL                            0x189A
 100        #define mmHPD0_DC_HPD_CONTROL                           0x189A
 101        #define mmHPD1_DC_HPD_CONTROL                           0x18A2
 102        #define mmHPD2_DC_HPD_CONTROL                           0x18AA
 103        #define mmHPD3_DC_HPD_CONTROL                           0x18B2
 104        #define mmHPD4_DC_HPD_CONTROL                           0x18BA
 105        #define mmHPD5_DC_HPD_CONTROL                           0x18C2
 106#endif
 107
 108#define DCE11_DIG_FE_CNTL 0x4a00
 109#define DCE11_DIG_BE_CNTL 0x4a47
 110#define DCE11_DP_SEC 0x4ac3
 111
 112static const struct dce110_timing_generator_offsets dce80_tg_offsets[] = {
 113                {
 114                        .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
 115                        .dcp =  (mmGRPH_CONTROL - mmGRPH_CONTROL),
 116                        .dmif = (mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL
 117                                        - mmDPG_WATERMARK_MASK_CONTROL),
 118                },
 119                {
 120                        .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
 121                        .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
 122                        .dmif = (mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL
 123                                        - mmDPG_WATERMARK_MASK_CONTROL),
 124                },
 125                {
 126                        .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
 127                        .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
 128                        .dmif = (mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL
 129                                        - mmDPG_WATERMARK_MASK_CONTROL),
 130                },
 131                {
 132                        .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
 133                        .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
 134                        .dmif = (mmDMIF_PG3_DPG_WATERMARK_MASK_CONTROL
 135                                        - mmDPG_WATERMARK_MASK_CONTROL),
 136                },
 137                {
 138                        .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
 139                        .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
 140                        .dmif = (mmDMIF_PG4_DPG_WATERMARK_MASK_CONTROL
 141                                        - mmDPG_WATERMARK_MASK_CONTROL),
 142                },
 143                {
 144                        .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
 145                        .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
 146                        .dmif = (mmDMIF_PG5_DPG_WATERMARK_MASK_CONTROL
 147                                        - mmDPG_WATERMARK_MASK_CONTROL),
 148                }
 149};
 150
 151/* set register offset */
 152#define SR(reg_name)\
 153        .reg_name = mm ## reg_name
 154
 155/* set register offset with instance */
 156#define SRI(reg_name, block, id)\
 157        .reg_name = mm ## block ## id ## _ ## reg_name
 158
 159#define ipp_regs(id)\
 160[id] = {\
 161                IPP_COMMON_REG_LIST_DCE_BASE(id)\
 162}
 163
 164static const struct dce_ipp_registers ipp_regs[] = {
 165                ipp_regs(0),
 166                ipp_regs(1),
 167                ipp_regs(2),
 168                ipp_regs(3),
 169                ipp_regs(4),
 170                ipp_regs(5)
 171};
 172
 173static const struct dce_ipp_shift ipp_shift = {
 174                IPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 175};
 176
 177static const struct dce_ipp_mask ipp_mask = {
 178                IPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 179};
 180
 181#define transform_regs(id)\
 182[id] = {\
 183                XFM_COMMON_REG_LIST_DCE80(id)\
 184}
 185
 186static const struct dce_transform_registers xfm_regs[] = {
 187                transform_regs(0),
 188                transform_regs(1),
 189                transform_regs(2),
 190                transform_regs(3),
 191                transform_regs(4),
 192                transform_regs(5)
 193};
 194
 195static const struct dce_transform_shift xfm_shift = {
 196                XFM_COMMON_MASK_SH_LIST_DCE80(__SHIFT)
 197};
 198
 199static const struct dce_transform_mask xfm_mask = {
 200                XFM_COMMON_MASK_SH_LIST_DCE80(_MASK)
 201};
 202
 203#define aux_regs(id)\
 204[id] = {\
 205        AUX_REG_LIST(id)\
 206}
 207
 208static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
 209        aux_regs(0),
 210        aux_regs(1),
 211        aux_regs(2),
 212        aux_regs(3),
 213        aux_regs(4),
 214        aux_regs(5)
 215};
 216
 217#define hpd_regs(id)\
 218[id] = {\
 219        HPD_REG_LIST(id)\
 220}
 221
 222static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
 223                hpd_regs(0),
 224                hpd_regs(1),
 225                hpd_regs(2),
 226                hpd_regs(3),
 227                hpd_regs(4),
 228                hpd_regs(5)
 229};
 230
 231#define link_regs(id)\
 232[id] = {\
 233        LE_DCE80_REG_LIST(id)\
 234}
 235
 236static const struct dce110_link_enc_registers link_enc_regs[] = {
 237        link_regs(0),
 238        link_regs(1),
 239        link_regs(2),
 240        link_regs(3),
 241        link_regs(4),
 242        link_regs(5),
 243        link_regs(6),
 244};
 245
 246#define stream_enc_regs(id)\
 247[id] = {\
 248        SE_COMMON_REG_LIST_DCE_BASE(id),\
 249        .AFMT_CNTL = 0,\
 250}
 251
 252static const struct dce110_stream_enc_registers stream_enc_regs[] = {
 253        stream_enc_regs(0),
 254        stream_enc_regs(1),
 255        stream_enc_regs(2),
 256        stream_enc_regs(3),
 257        stream_enc_regs(4),
 258        stream_enc_regs(5),
 259        stream_enc_regs(6)
 260};
 261
 262static const struct dce_stream_encoder_shift se_shift = {
 263                SE_COMMON_MASK_SH_LIST_DCE80_100(__SHIFT)
 264};
 265
 266static const struct dce_stream_encoder_mask se_mask = {
 267                SE_COMMON_MASK_SH_LIST_DCE80_100(_MASK)
 268};
 269
 270static const struct dce_panel_cntl_registers panel_cntl_regs[] = {
 271        { DCE_PANEL_CNTL_REG_LIST() }
 272};
 273
 274static const struct dce_panel_cntl_shift panel_cntl_shift = {
 275        DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT)
 276};
 277
 278static const struct dce_panel_cntl_mask panel_cntl_mask = {
 279        DCE_PANEL_CNTL_MASK_SH_LIST(_MASK)
 280};
 281
 282#define opp_regs(id)\
 283[id] = {\
 284        OPP_DCE_80_REG_LIST(id),\
 285}
 286
 287static const struct dce_opp_registers opp_regs[] = {
 288        opp_regs(0),
 289        opp_regs(1),
 290        opp_regs(2),
 291        opp_regs(3),
 292        opp_regs(4),
 293        opp_regs(5)
 294};
 295
 296static const struct dce_opp_shift opp_shift = {
 297        OPP_COMMON_MASK_SH_LIST_DCE_80(__SHIFT)
 298};
 299
 300static const struct dce_opp_mask opp_mask = {
 301        OPP_COMMON_MASK_SH_LIST_DCE_80(_MASK)
 302};
 303
 304static const struct dce110_aux_registers_shift aux_shift = {
 305        DCE10_AUX_MASK_SH_LIST(__SHIFT)
 306};
 307
 308static const struct dce110_aux_registers_mask aux_mask = {
 309        DCE10_AUX_MASK_SH_LIST(_MASK)
 310};
 311
 312#define aux_engine_regs(id)\
 313[id] = {\
 314        AUX_COMMON_REG_LIST(id), \
 315        .AUX_RESET_MASK = 0 \
 316}
 317
 318static const struct dce110_aux_registers aux_engine_regs[] = {
 319                aux_engine_regs(0),
 320                aux_engine_regs(1),
 321                aux_engine_regs(2),
 322                aux_engine_regs(3),
 323                aux_engine_regs(4),
 324                aux_engine_regs(5)
 325};
 326
 327#define audio_regs(id)\
 328[id] = {\
 329        AUD_COMMON_REG_LIST(id)\
 330}
 331
 332static const struct dce_audio_registers audio_regs[] = {
 333        audio_regs(0),
 334        audio_regs(1),
 335        audio_regs(2),
 336        audio_regs(3),
 337        audio_regs(4),
 338        audio_regs(5),
 339        audio_regs(6),
 340};
 341
 342static const struct dce_audio_shift audio_shift = {
 343                AUD_COMMON_MASK_SH_LIST(__SHIFT)
 344};
 345
 346static const struct dce_audio_mask audio_mask = {
 347                AUD_COMMON_MASK_SH_LIST(_MASK)
 348};
 349
 350#define clk_src_regs(id)\
 351[id] = {\
 352        CS_COMMON_REG_LIST_DCE_80(id),\
 353}
 354
 355
 356static const struct dce110_clk_src_regs clk_src_regs[] = {
 357        clk_src_regs(0),
 358        clk_src_regs(1),
 359        clk_src_regs(2)
 360};
 361
 362static const struct dce110_clk_src_shift cs_shift = {
 363                CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 364};
 365
 366static const struct dce110_clk_src_mask cs_mask = {
 367                CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 368};
 369
 370static const struct bios_registers bios_regs = {
 371        .BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
 372        .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
 373};
 374
 375static const struct resource_caps res_cap = {
 376                .num_timing_generator = 6,
 377                .num_audio = 6,
 378                .num_stream_encoder = 6,
 379                .num_pll = 3,
 380                .num_ddc = 6,
 381};
 382
 383static const struct resource_caps res_cap_81 = {
 384                .num_timing_generator = 4,
 385                .num_audio = 7,
 386                .num_stream_encoder = 7,
 387                .num_pll = 3,
 388                .num_ddc = 6,
 389};
 390
 391static const struct resource_caps res_cap_83 = {
 392                .num_timing_generator = 2,
 393                .num_audio = 6,
 394                .num_stream_encoder = 6,
 395                .num_pll = 2,
 396                .num_ddc = 2,
 397};
 398
 399static const struct dc_plane_cap plane_cap = {
 400        .type = DC_PLANE_TYPE_DCE_RGB,
 401
 402        .pixel_format_support = {
 403                        .argb8888 = true,
 404                        .nv12 = false,
 405                        .fp16 = false
 406        },
 407
 408        .max_upscale_factor = {
 409                        .argb8888 = 16000,
 410                        .nv12 = 1,
 411                        .fp16 = 1
 412        },
 413
 414        .max_downscale_factor = {
 415                        .argb8888 = 250,
 416                        .nv12 = 1,
 417                        .fp16 = 1
 418        }
 419};
 420
 421static const struct dce_dmcu_registers dmcu_regs = {
 422                DMCU_DCE80_REG_LIST()
 423};
 424
 425static const struct dce_dmcu_shift dmcu_shift = {
 426                DMCU_MASK_SH_LIST_DCE80(__SHIFT)
 427};
 428
 429static const struct dce_dmcu_mask dmcu_mask = {
 430                DMCU_MASK_SH_LIST_DCE80(_MASK)
 431};
 432static const struct dce_abm_registers abm_regs = {
 433                ABM_DCE110_COMMON_REG_LIST()
 434};
 435
 436static const struct dce_abm_shift abm_shift = {
 437                ABM_MASK_SH_LIST_DCE110(__SHIFT)
 438};
 439
 440static const struct dce_abm_mask abm_mask = {
 441                ABM_MASK_SH_LIST_DCE110(_MASK)
 442};
 443
 444#define CTX  ctx
 445#define REG(reg) mm ## reg
 446
 447#ifndef mmCC_DC_HDMI_STRAPS
 448#define mmCC_DC_HDMI_STRAPS 0x1918
 449#define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
 450#define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
 451#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
 452#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
 453#endif
 454
 455static int map_transmitter_id_to_phy_instance(
 456        enum transmitter transmitter)
 457{
 458        switch (transmitter) {
 459        case TRANSMITTER_UNIPHY_A:
 460                return 0;
 461        break;
 462        case TRANSMITTER_UNIPHY_B:
 463                return 1;
 464        break;
 465        case TRANSMITTER_UNIPHY_C:
 466                return 2;
 467        break;
 468        case TRANSMITTER_UNIPHY_D:
 469                return 3;
 470        break;
 471        case TRANSMITTER_UNIPHY_E:
 472                return 4;
 473        break;
 474        case TRANSMITTER_UNIPHY_F:
 475                return 5;
 476        break;
 477        case TRANSMITTER_UNIPHY_G:
 478                return 6;
 479        break;
 480        default:
 481                ASSERT(0);
 482                return 0;
 483        }
 484}
 485
 486static void read_dce_straps(
 487        struct dc_context *ctx,
 488        struct resource_straps *straps)
 489{
 490        REG_GET_2(CC_DC_HDMI_STRAPS,
 491                        HDMI_DISABLE, &straps->hdmi_disable,
 492                        AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
 493
 494        REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);
 495}
 496
 497static struct audio *create_audio(
 498                struct dc_context *ctx, unsigned int inst)
 499{
 500        return dce_audio_create(ctx, inst,
 501                        &audio_regs[inst], &audio_shift, &audio_mask);
 502}
 503
 504static struct timing_generator *dce80_timing_generator_create(
 505                struct dc_context *ctx,
 506                uint32_t instance,
 507                const struct dce110_timing_generator_offsets *offsets)
 508{
 509        struct dce110_timing_generator *tg110 =
 510                kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
 511
 512        if (!tg110)
 513                return NULL;
 514
 515        dce80_timing_generator_construct(tg110, ctx, instance, offsets);
 516        return &tg110->base;
 517}
 518
 519static struct output_pixel_processor *dce80_opp_create(
 520        struct dc_context *ctx,
 521        uint32_t inst)
 522{
 523        struct dce110_opp *opp =
 524                kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
 525
 526        if (!opp)
 527                return NULL;
 528
 529        dce110_opp_construct(opp,
 530                             ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
 531        return &opp->base;
 532}
 533
 534struct dce_aux *dce80_aux_engine_create(
 535        struct dc_context *ctx,
 536        uint32_t inst)
 537{
 538        struct aux_engine_dce110 *aux_engine =
 539                kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
 540
 541        if (!aux_engine)
 542                return NULL;
 543
 544        dce110_aux_engine_construct(aux_engine, ctx, inst,
 545                                    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 546                                    &aux_engine_regs[inst],
 547                                        &aux_mask,
 548                                        &aux_shift,
 549                                        ctx->dc->caps.extended_aux_timeout_support);
 550
 551        return &aux_engine->base;
 552}
 553#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
 554
 555static const struct dce_i2c_registers i2c_hw_regs[] = {
 556                i2c_inst_regs(1),
 557                i2c_inst_regs(2),
 558                i2c_inst_regs(3),
 559                i2c_inst_regs(4),
 560                i2c_inst_regs(5),
 561                i2c_inst_regs(6),
 562};
 563
 564static const struct dce_i2c_shift i2c_shifts = {
 565                I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 566};
 567
 568static const struct dce_i2c_mask i2c_masks = {
 569                I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 570};
 571
 572struct dce_i2c_hw *dce80_i2c_hw_create(
 573        struct dc_context *ctx,
 574        uint32_t inst)
 575{
 576        struct dce_i2c_hw *dce_i2c_hw =
 577                kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
 578
 579        if (!dce_i2c_hw)
 580                return NULL;
 581
 582        dce_i2c_hw_construct(dce_i2c_hw, ctx, inst,
 583                                    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
 584
 585        return dce_i2c_hw;
 586}
 587
 588struct dce_i2c_sw *dce80_i2c_sw_create(
 589        struct dc_context *ctx)
 590{
 591        struct dce_i2c_sw *dce_i2c_sw =
 592                kzalloc(sizeof(struct dce_i2c_sw), GFP_KERNEL);
 593
 594        if (!dce_i2c_sw)
 595                return NULL;
 596
 597        dce_i2c_sw_construct(dce_i2c_sw, ctx);
 598
 599        return dce_i2c_sw;
 600}
 601static struct stream_encoder *dce80_stream_encoder_create(
 602        enum engine_id eng_id,
 603        struct dc_context *ctx)
 604{
 605        struct dce110_stream_encoder *enc110 =
 606                kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
 607
 608        if (!enc110)
 609                return NULL;
 610
 611        dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
 612                                        &stream_enc_regs[eng_id],
 613                                        &se_shift, &se_mask);
 614        return &enc110->base;
 615}
 616
 617#define SRII(reg_name, block, id)\
 618        .reg_name[id] = mm ## block ## id ## _ ## reg_name
 619
 620static const struct dce_hwseq_registers hwseq_reg = {
 621                HWSEQ_DCE8_REG_LIST()
 622};
 623
 624static const struct dce_hwseq_shift hwseq_shift = {
 625                HWSEQ_DCE8_MASK_SH_LIST(__SHIFT)
 626};
 627
 628static const struct dce_hwseq_mask hwseq_mask = {
 629                HWSEQ_DCE8_MASK_SH_LIST(_MASK)
 630};
 631
 632static struct dce_hwseq *dce80_hwseq_create(
 633        struct dc_context *ctx)
 634{
 635        struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
 636
 637        if (hws) {
 638                hws->ctx = ctx;
 639                hws->regs = &hwseq_reg;
 640                hws->shifts = &hwseq_shift;
 641                hws->masks = &hwseq_mask;
 642        }
 643        return hws;
 644}
 645
 646static const struct resource_create_funcs res_create_funcs = {
 647        .read_dce_straps = read_dce_straps,
 648        .create_audio = create_audio,
 649        .create_stream_encoder = dce80_stream_encoder_create,
 650        .create_hwseq = dce80_hwseq_create,
 651};
 652
 653#define mi_inst_regs(id) { \
 654        MI_DCE8_REG_LIST(id), \
 655        .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
 656}
 657static const struct dce_mem_input_registers mi_regs[] = {
 658                mi_inst_regs(0),
 659                mi_inst_regs(1),
 660                mi_inst_regs(2),
 661                mi_inst_regs(3),
 662                mi_inst_regs(4),
 663                mi_inst_regs(5),
 664};
 665
 666static const struct dce_mem_input_shift mi_shifts = {
 667                MI_DCE8_MASK_SH_LIST(__SHIFT),
 668                .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
 669};
 670
 671static const struct dce_mem_input_mask mi_masks = {
 672                MI_DCE8_MASK_SH_LIST(_MASK),
 673                .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
 674};
 675
 676static struct mem_input *dce80_mem_input_create(
 677        struct dc_context *ctx,
 678        uint32_t inst)
 679{
 680        struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
 681                                               GFP_KERNEL);
 682
 683        if (!dce_mi) {
 684                BREAK_TO_DEBUGGER();
 685                return NULL;
 686        }
 687
 688        dce_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
 689        dce_mi->wa.single_head_rdreq_dmif_limit = 2;
 690        return &dce_mi->base;
 691}
 692
 693static void dce80_transform_destroy(struct transform **xfm)
 694{
 695        kfree(TO_DCE_TRANSFORM(*xfm));
 696        *xfm = NULL;
 697}
 698
 699static struct transform *dce80_transform_create(
 700        struct dc_context *ctx,
 701        uint32_t inst)
 702{
 703        struct dce_transform *transform =
 704                kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
 705
 706        if (!transform)
 707                return NULL;
 708
 709        dce_transform_construct(transform, ctx, inst,
 710                                &xfm_regs[inst], &xfm_shift, &xfm_mask);
 711        transform->prescaler_on = false;
 712        return &transform->base;
 713}
 714
 715static const struct encoder_feature_support link_enc_feature = {
 716                .max_hdmi_deep_color = COLOR_DEPTH_121212,
 717                .max_hdmi_pixel_clock = 297000,
 718                .flags.bits.IS_HBR2_CAPABLE = true,
 719                .flags.bits.IS_TPS3_CAPABLE = true
 720};
 721
 722struct link_encoder *dce80_link_encoder_create(
 723        const struct encoder_init_data *enc_init_data)
 724{
 725        struct dce110_link_encoder *enc110 =
 726                kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
 727        int link_regs_id;
 728
 729        if (!enc110)
 730                return NULL;
 731
 732        link_regs_id =
 733                map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
 734
 735        dce110_link_encoder_construct(enc110,
 736                                      enc_init_data,
 737                                      &link_enc_feature,
 738                                      &link_enc_regs[link_regs_id],
 739                                      &link_enc_aux_regs[enc_init_data->channel - 1],
 740                                      &link_enc_hpd_regs[enc_init_data->hpd_source]);
 741        return &enc110->base;
 742}
 743
 744static struct panel_cntl *dce80_panel_cntl_create(const struct panel_cntl_init_data *init_data)
 745{
 746        struct dce_panel_cntl *panel_cntl =
 747                kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL);
 748
 749        if (!panel_cntl)
 750                return NULL;
 751
 752        dce_panel_cntl_construct(panel_cntl,
 753                        init_data,
 754                        &panel_cntl_regs[init_data->inst],
 755                        &panel_cntl_shift,
 756                        &panel_cntl_mask);
 757
 758        return &panel_cntl->base;
 759}
 760
 761struct clock_source *dce80_clock_source_create(
 762        struct dc_context *ctx,
 763        struct dc_bios *bios,
 764        enum clock_source_id id,
 765        const struct dce110_clk_src_regs *regs,
 766        bool dp_clk_src)
 767{
 768        struct dce110_clk_src *clk_src =
 769                kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
 770
 771        if (!clk_src)
 772                return NULL;
 773
 774        if (dce110_clk_src_construct(clk_src, ctx, bios, id,
 775                        regs, &cs_shift, &cs_mask)) {
 776                clk_src->base.dp_clk_src = dp_clk_src;
 777                return &clk_src->base;
 778        }
 779
 780        kfree(clk_src);
 781        BREAK_TO_DEBUGGER();
 782        return NULL;
 783}
 784
 785void dce80_clock_source_destroy(struct clock_source **clk_src)
 786{
 787        kfree(TO_DCE110_CLK_SRC(*clk_src));
 788        *clk_src = NULL;
 789}
 790
 791static struct input_pixel_processor *dce80_ipp_create(
 792        struct dc_context *ctx, uint32_t inst)
 793{
 794        struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
 795
 796        if (!ipp) {
 797                BREAK_TO_DEBUGGER();
 798                return NULL;
 799        }
 800
 801        dce_ipp_construct(ipp, ctx, inst,
 802                        &ipp_regs[inst], &ipp_shift, &ipp_mask);
 803        return &ipp->base;
 804}
 805
 806static void dce80_resource_destruct(struct dce110_resource_pool *pool)
 807{
 808        unsigned int i;
 809
 810        for (i = 0; i < pool->base.pipe_count; i++) {
 811                if (pool->base.opps[i] != NULL)
 812                        dce110_opp_destroy(&pool->base.opps[i]);
 813
 814                if (pool->base.transforms[i] != NULL)
 815                        dce80_transform_destroy(&pool->base.transforms[i]);
 816
 817                if (pool->base.ipps[i] != NULL)
 818                        dce_ipp_destroy(&pool->base.ipps[i]);
 819
 820                if (pool->base.mis[i] != NULL) {
 821                        kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
 822                        pool->base.mis[i] = NULL;
 823                }
 824
 825                if (pool->base.timing_generators[i] != NULL)    {
 826                        kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
 827                        pool->base.timing_generators[i] = NULL;
 828                }
 829        }
 830
 831        for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
 832                if (pool->base.engines[i] != NULL)
 833                        dce110_engine_destroy(&pool->base.engines[i]);
 834                if (pool->base.hw_i2cs[i] != NULL) {
 835                        kfree(pool->base.hw_i2cs[i]);
 836                        pool->base.hw_i2cs[i] = NULL;
 837                }
 838                if (pool->base.sw_i2cs[i] != NULL) {
 839                        kfree(pool->base.sw_i2cs[i]);
 840                        pool->base.sw_i2cs[i] = NULL;
 841                }
 842        }
 843
 844        for (i = 0; i < pool->base.stream_enc_count; i++) {
 845                if (pool->base.stream_enc[i] != NULL)
 846                        kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
 847        }
 848
 849        for (i = 0; i < pool->base.clk_src_count; i++) {
 850                if (pool->base.clock_sources[i] != NULL) {
 851                        dce80_clock_source_destroy(&pool->base.clock_sources[i]);
 852                }
 853        }
 854
 855        if (pool->base.abm != NULL)
 856                        dce_abm_destroy(&pool->base.abm);
 857
 858        if (pool->base.dmcu != NULL)
 859                        dce_dmcu_destroy(&pool->base.dmcu);
 860
 861        if (pool->base.dp_clock_source != NULL)
 862                dce80_clock_source_destroy(&pool->base.dp_clock_source);
 863
 864        for (i = 0; i < pool->base.audio_count; i++)    {
 865                if (pool->base.audios[i] != NULL) {
 866                        dce_aud_destroy(&pool->base.audios[i]);
 867                }
 868        }
 869
 870        if (pool->base.irqs != NULL) {
 871                dal_irq_service_destroy(&pool->base.irqs);
 872        }
 873}
 874
 875bool dce80_validate_bandwidth(
 876        struct dc *dc,
 877        struct dc_state *context,
 878        bool fast_validate)
 879{
 880        int i;
 881        bool at_least_one_pipe = false;
 882
 883        for (i = 0; i < dc->res_pool->pipe_count; i++) {
 884                if (context->res_ctx.pipe_ctx[i].stream)
 885                        at_least_one_pipe = true;
 886        }
 887
 888        if (at_least_one_pipe) {
 889                /* TODO implement when needed but for now hardcode max value*/
 890                context->bw_ctx.bw.dce.dispclk_khz = 681000;
 891                context->bw_ctx.bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ;
 892        } else {
 893                context->bw_ctx.bw.dce.dispclk_khz = 0;
 894                context->bw_ctx.bw.dce.yclk_khz = 0;
 895        }
 896
 897        return true;
 898}
 899
 900static bool dce80_validate_surface_sets(
 901                struct dc_state *context)
 902{
 903        int i;
 904
 905        for (i = 0; i < context->stream_count; i++) {
 906                if (context->stream_status[i].plane_count == 0)
 907                        continue;
 908
 909                if (context->stream_status[i].plane_count > 1)
 910                        return false;
 911
 912                if (context->stream_status[i].plane_states[0]->format
 913                                >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
 914                        return false;
 915        }
 916
 917        return true;
 918}
 919
 920enum dc_status dce80_validate_global(
 921                struct dc *dc,
 922                struct dc_state *context)
 923{
 924        if (!dce80_validate_surface_sets(context))
 925                return DC_FAIL_SURFACE_VALIDATE;
 926
 927        return DC_OK;
 928}
 929
 930static void dce80_destroy_resource_pool(struct resource_pool **pool)
 931{
 932        struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
 933
 934        dce80_resource_destruct(dce110_pool);
 935        kfree(dce110_pool);
 936        *pool = NULL;
 937}
 938
 939static const struct resource_funcs dce80_res_pool_funcs = {
 940        .destroy = dce80_destroy_resource_pool,
 941        .link_enc_create = dce80_link_encoder_create,
 942        .panel_cntl_create = dce80_panel_cntl_create,
 943        .validate_bandwidth = dce80_validate_bandwidth,
 944        .validate_plane = dce100_validate_plane,
 945        .add_stream_to_ctx = dce100_add_stream_to_ctx,
 946        .validate_global = dce80_validate_global,
 947        .find_first_free_match_stream_enc_for_link = dce100_find_first_free_match_stream_enc_for_link
 948};
 949
 950static bool dce80_construct(
 951        uint8_t num_virtual_links,
 952        struct dc *dc,
 953        struct dce110_resource_pool *pool)
 954{
 955        unsigned int i;
 956        struct dc_context *ctx = dc->ctx;
 957        struct dc_bios *bp;
 958
 959        ctx->dc_bios->regs = &bios_regs;
 960
 961        pool->base.res_cap = &res_cap;
 962        pool->base.funcs = &dce80_res_pool_funcs;
 963
 964
 965        /*************************************************
 966         *  Resource + asic cap harcoding                *
 967         *************************************************/
 968        pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
 969        pool->base.pipe_count = res_cap.num_timing_generator;
 970        pool->base.timing_generator_count = res_cap.num_timing_generator;
 971        dc->caps.max_downscale_ratio = 200;
 972        dc->caps.i2c_speed_in_khz = 40;
 973        dc->caps.max_cursor_size = 128;
 974        dc->caps.dual_link_dvi = true;
 975        dc->caps.extended_aux_timeout_support = false;
 976
 977        /*************************************************
 978         *  Create resources                             *
 979         *************************************************/
 980
 981        bp = ctx->dc_bios;
 982
 983        if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
 984                pool->base.dp_clock_source =
 985                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
 986
 987                pool->base.clock_sources[0] =
 988                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false);
 989                pool->base.clock_sources[1] =
 990                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
 991                pool->base.clock_sources[2] =
 992                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
 993                pool->base.clk_src_count = 3;
 994
 995        } else {
 996                pool->base.dp_clock_source =
 997                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true);
 998
 999                pool->base.clock_sources[0] =
1000                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
1001                pool->base.clock_sources[1] =
1002                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
1003                pool->base.clk_src_count = 2;
1004        }
1005
1006        if (pool->base.dp_clock_source == NULL) {
1007                dm_error("DC: failed to create dp clock source!\n");
1008                BREAK_TO_DEBUGGER();
1009                goto res_create_fail;
1010        }
1011
1012        for (i = 0; i < pool->base.clk_src_count; i++) {
1013                if (pool->base.clock_sources[i] == NULL) {
1014                        dm_error("DC: failed to create clock sources!\n");
1015                        BREAK_TO_DEBUGGER();
1016                        goto res_create_fail;
1017                }
1018        }
1019
1020        pool->base.dmcu = dce_dmcu_create(ctx,
1021                        &dmcu_regs,
1022                        &dmcu_shift,
1023                        &dmcu_mask);
1024        if (pool->base.dmcu == NULL) {
1025                dm_error("DC: failed to create dmcu!\n");
1026                BREAK_TO_DEBUGGER();
1027                goto res_create_fail;
1028        }
1029
1030        pool->base.abm = dce_abm_create(ctx,
1031                        &abm_regs,
1032                        &abm_shift,
1033                        &abm_mask);
1034        if (pool->base.abm == NULL) {
1035                dm_error("DC: failed to create abm!\n");
1036                BREAK_TO_DEBUGGER();
1037                goto res_create_fail;
1038        }
1039
1040        {
1041                struct irq_service_init_data init_data;
1042                init_data.ctx = dc->ctx;
1043                pool->base.irqs = dal_irq_service_dce80_create(&init_data);
1044                if (!pool->base.irqs)
1045                        goto res_create_fail;
1046        }
1047
1048        for (i = 0; i < pool->base.pipe_count; i++) {
1049                pool->base.timing_generators[i] = dce80_timing_generator_create(
1050                                ctx, i, &dce80_tg_offsets[i]);
1051                if (pool->base.timing_generators[i] == NULL) {
1052                        BREAK_TO_DEBUGGER();
1053                        dm_error("DC: failed to create tg!\n");
1054                        goto res_create_fail;
1055                }
1056
1057                pool->base.mis[i] = dce80_mem_input_create(ctx, i);
1058                if (pool->base.mis[i] == NULL) {
1059                        BREAK_TO_DEBUGGER();
1060                        dm_error("DC: failed to create memory input!\n");
1061                        goto res_create_fail;
1062                }
1063
1064                pool->base.ipps[i] = dce80_ipp_create(ctx, i);
1065                if (pool->base.ipps[i] == NULL) {
1066                        BREAK_TO_DEBUGGER();
1067                        dm_error("DC: failed to create input pixel processor!\n");
1068                        goto res_create_fail;
1069                }
1070
1071                pool->base.transforms[i] = dce80_transform_create(ctx, i);
1072                if (pool->base.transforms[i] == NULL) {
1073                        BREAK_TO_DEBUGGER();
1074                        dm_error("DC: failed to create transform!\n");
1075                        goto res_create_fail;
1076                }
1077
1078                pool->base.opps[i] = dce80_opp_create(ctx, i);
1079                if (pool->base.opps[i] == NULL) {
1080                        BREAK_TO_DEBUGGER();
1081                        dm_error("DC: failed to create output pixel processor!\n");
1082                        goto res_create_fail;
1083                }
1084        }
1085
1086        for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1087                pool->base.engines[i] = dce80_aux_engine_create(ctx, i);
1088                if (pool->base.engines[i] == NULL) {
1089                        BREAK_TO_DEBUGGER();
1090                        dm_error(
1091                                "DC:failed to create aux engine!!\n");
1092                        goto res_create_fail;
1093                }
1094                pool->base.hw_i2cs[i] = dce80_i2c_hw_create(ctx, i);
1095                if (pool->base.hw_i2cs[i] == NULL) {
1096                        BREAK_TO_DEBUGGER();
1097                        dm_error(
1098                                "DC:failed to create i2c engine!!\n");
1099                        goto res_create_fail;
1100                }
1101                pool->base.sw_i2cs[i] = dce80_i2c_sw_create(ctx);
1102                if (pool->base.sw_i2cs[i] == NULL) {
1103                        BREAK_TO_DEBUGGER();
1104                        dm_error(
1105                                "DC:failed to create sw i2c!!\n");
1106                        goto res_create_fail;
1107                }
1108        }
1109
1110        dc->caps.max_planes =  pool->base.pipe_count;
1111
1112        for (i = 0; i < dc->caps.max_planes; ++i)
1113                dc->caps.planes[i] = plane_cap;
1114
1115        dc->caps.disable_dp_clk_share = true;
1116
1117        if (!resource_construct(num_virtual_links, dc, &pool->base,
1118                        &res_create_funcs))
1119                goto res_create_fail;
1120
1121        /* Create hardware sequencer */
1122        dce80_hw_sequencer_construct(dc);
1123
1124        return true;
1125
1126res_create_fail:
1127        dce80_resource_destruct(pool);
1128        return false;
1129}
1130
1131struct resource_pool *dce80_create_resource_pool(
1132        uint8_t num_virtual_links,
1133        struct dc *dc)
1134{
1135        struct dce110_resource_pool *pool =
1136                kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1137
1138        if (!pool)
1139                return NULL;
1140
1141        if (dce80_construct(num_virtual_links, dc, pool))
1142                return &pool->base;
1143
1144        BREAK_TO_DEBUGGER();
1145        return NULL;
1146}
1147
1148static bool dce81_construct(
1149        uint8_t num_virtual_links,
1150        struct dc *dc,
1151        struct dce110_resource_pool *pool)
1152{
1153        unsigned int i;
1154        struct dc_context *ctx = dc->ctx;
1155        struct dc_bios *bp;
1156
1157        ctx->dc_bios->regs = &bios_regs;
1158
1159        pool->base.res_cap = &res_cap_81;
1160        pool->base.funcs = &dce80_res_pool_funcs;
1161
1162
1163        /*************************************************
1164         *  Resource + asic cap harcoding                *
1165         *************************************************/
1166        pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1167        pool->base.pipe_count = res_cap_81.num_timing_generator;
1168        pool->base.timing_generator_count = res_cap_81.num_timing_generator;
1169        dc->caps.max_downscale_ratio = 200;
1170        dc->caps.i2c_speed_in_khz = 40;
1171        dc->caps.max_cursor_size = 128;
1172        dc->caps.is_apu = true;
1173
1174        /*************************************************
1175         *  Create resources                             *
1176         *************************************************/
1177
1178        bp = ctx->dc_bios;
1179
1180        if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
1181                pool->base.dp_clock_source =
1182                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
1183
1184                pool->base.clock_sources[0] =
1185                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false);
1186                pool->base.clock_sources[1] =
1187                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
1188                pool->base.clock_sources[2] =
1189                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
1190                pool->base.clk_src_count = 3;
1191
1192        } else {
1193                pool->base.dp_clock_source =
1194                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true);
1195
1196                pool->base.clock_sources[0] =
1197                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
1198                pool->base.clock_sources[1] =
1199                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
1200                pool->base.clk_src_count = 2;
1201        }
1202
1203        if (pool->base.dp_clock_source == NULL) {
1204                dm_error("DC: failed to create dp clock source!\n");
1205                BREAK_TO_DEBUGGER();
1206                goto res_create_fail;
1207        }
1208
1209        for (i = 0; i < pool->base.clk_src_count; i++) {
1210                if (pool->base.clock_sources[i] == NULL) {
1211                        dm_error("DC: failed to create clock sources!\n");
1212                        BREAK_TO_DEBUGGER();
1213                        goto res_create_fail;
1214                }
1215        }
1216
1217        pool->base.dmcu = dce_dmcu_create(ctx,
1218                        &dmcu_regs,
1219                        &dmcu_shift,
1220                        &dmcu_mask);
1221        if (pool->base.dmcu == NULL) {
1222                dm_error("DC: failed to create dmcu!\n");
1223                BREAK_TO_DEBUGGER();
1224                goto res_create_fail;
1225        }
1226
1227        pool->base.abm = dce_abm_create(ctx,
1228                        &abm_regs,
1229                        &abm_shift,
1230                        &abm_mask);
1231        if (pool->base.abm == NULL) {
1232                dm_error("DC: failed to create abm!\n");
1233                BREAK_TO_DEBUGGER();
1234                goto res_create_fail;
1235        }
1236
1237        {
1238                struct irq_service_init_data init_data;
1239                init_data.ctx = dc->ctx;
1240                pool->base.irqs = dal_irq_service_dce80_create(&init_data);
1241                if (!pool->base.irqs)
1242                        goto res_create_fail;
1243        }
1244
1245        for (i = 0; i < pool->base.pipe_count; i++) {
1246                pool->base.timing_generators[i] = dce80_timing_generator_create(
1247                                ctx, i, &dce80_tg_offsets[i]);
1248                if (pool->base.timing_generators[i] == NULL) {
1249                        BREAK_TO_DEBUGGER();
1250                        dm_error("DC: failed to create tg!\n");
1251                        goto res_create_fail;
1252                }
1253
1254                pool->base.mis[i] = dce80_mem_input_create(ctx, i);
1255                if (pool->base.mis[i] == NULL) {
1256                        BREAK_TO_DEBUGGER();
1257                        dm_error("DC: failed to create memory input!\n");
1258                        goto res_create_fail;
1259                }
1260
1261                pool->base.ipps[i] = dce80_ipp_create(ctx, i);
1262                if (pool->base.ipps[i] == NULL) {
1263                        BREAK_TO_DEBUGGER();
1264                        dm_error("DC: failed to create input pixel processor!\n");
1265                        goto res_create_fail;
1266                }
1267
1268                pool->base.transforms[i] = dce80_transform_create(ctx, i);
1269                if (pool->base.transforms[i] == NULL) {
1270                        BREAK_TO_DEBUGGER();
1271                        dm_error("DC: failed to create transform!\n");
1272                        goto res_create_fail;
1273                }
1274
1275                pool->base.opps[i] = dce80_opp_create(ctx, i);
1276                if (pool->base.opps[i] == NULL) {
1277                        BREAK_TO_DEBUGGER();
1278                        dm_error("DC: failed to create output pixel processor!\n");
1279                        goto res_create_fail;
1280                }
1281        }
1282
1283        for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1284                pool->base.engines[i] = dce80_aux_engine_create(ctx, i);
1285                if (pool->base.engines[i] == NULL) {
1286                        BREAK_TO_DEBUGGER();
1287                        dm_error(
1288                                "DC:failed to create aux engine!!\n");
1289                        goto res_create_fail;
1290                }
1291                pool->base.hw_i2cs[i] = dce80_i2c_hw_create(ctx, i);
1292                if (pool->base.hw_i2cs[i] == NULL) {
1293                        BREAK_TO_DEBUGGER();
1294                        dm_error(
1295                                "DC:failed to create i2c engine!!\n");
1296                        goto res_create_fail;
1297                }
1298                pool->base.sw_i2cs[i] = dce80_i2c_sw_create(ctx);
1299                if (pool->base.sw_i2cs[i] == NULL) {
1300                        BREAK_TO_DEBUGGER();
1301                        dm_error(
1302                                "DC:failed to create sw i2c!!\n");
1303                        goto res_create_fail;
1304                }
1305        }
1306
1307        dc->caps.max_planes =  pool->base.pipe_count;
1308
1309        for (i = 0; i < dc->caps.max_planes; ++i)
1310                dc->caps.planes[i] = plane_cap;
1311
1312        dc->caps.disable_dp_clk_share = true;
1313
1314        if (!resource_construct(num_virtual_links, dc, &pool->base,
1315                        &res_create_funcs))
1316                goto res_create_fail;
1317
1318        /* Create hardware sequencer */
1319        dce80_hw_sequencer_construct(dc);
1320
1321        return true;
1322
1323res_create_fail:
1324        dce80_resource_destruct(pool);
1325        return false;
1326}
1327
1328struct resource_pool *dce81_create_resource_pool(
1329        uint8_t num_virtual_links,
1330        struct dc *dc)
1331{
1332        struct dce110_resource_pool *pool =
1333                kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1334
1335        if (!pool)
1336                return NULL;
1337
1338        if (dce81_construct(num_virtual_links, dc, pool))
1339                return &pool->base;
1340
1341        BREAK_TO_DEBUGGER();
1342        return NULL;
1343}
1344
1345static bool dce83_construct(
1346        uint8_t num_virtual_links,
1347        struct dc *dc,
1348        struct dce110_resource_pool *pool)
1349{
1350        unsigned int i;
1351        struct dc_context *ctx = dc->ctx;
1352        struct dc_bios *bp;
1353
1354        ctx->dc_bios->regs = &bios_regs;
1355
1356        pool->base.res_cap = &res_cap_83;
1357        pool->base.funcs = &dce80_res_pool_funcs;
1358
1359
1360        /*************************************************
1361         *  Resource + asic cap harcoding                *
1362         *************************************************/
1363        pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1364        pool->base.pipe_count = res_cap_83.num_timing_generator;
1365        pool->base.timing_generator_count = res_cap_83.num_timing_generator;
1366        dc->caps.max_downscale_ratio = 200;
1367        dc->caps.i2c_speed_in_khz = 40;
1368        dc->caps.max_cursor_size = 128;
1369        dc->caps.is_apu = true;
1370
1371        /*************************************************
1372         *  Create resources                             *
1373         *************************************************/
1374
1375        bp = ctx->dc_bios;
1376
1377        if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
1378                pool->base.dp_clock_source =
1379                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
1380
1381                pool->base.clock_sources[0] =
1382                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], false);
1383                pool->base.clock_sources[1] =
1384                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false);
1385                pool->base.clk_src_count = 2;
1386
1387        } else {
1388                pool->base.dp_clock_source =
1389                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], true);
1390
1391                pool->base.clock_sources[0] =
1392                                dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false);
1393                pool->base.clk_src_count = 1;
1394        }
1395
1396        if (pool->base.dp_clock_source == NULL) {
1397                dm_error("DC: failed to create dp clock source!\n");
1398                BREAK_TO_DEBUGGER();
1399                goto res_create_fail;
1400        }
1401
1402        for (i = 0; i < pool->base.clk_src_count; i++) {
1403                if (pool->base.clock_sources[i] == NULL) {
1404                        dm_error("DC: failed to create clock sources!\n");
1405                        BREAK_TO_DEBUGGER();
1406                        goto res_create_fail;
1407                }
1408        }
1409
1410        pool->base.dmcu = dce_dmcu_create(ctx,
1411                        &dmcu_regs,
1412                        &dmcu_shift,
1413                        &dmcu_mask);
1414        if (pool->base.dmcu == NULL) {
1415                dm_error("DC: failed to create dmcu!\n");
1416                BREAK_TO_DEBUGGER();
1417                goto res_create_fail;
1418        }
1419
1420        pool->base.abm = dce_abm_create(ctx,
1421                        &abm_regs,
1422                        &abm_shift,
1423                        &abm_mask);
1424        if (pool->base.abm == NULL) {
1425                dm_error("DC: failed to create abm!\n");
1426                BREAK_TO_DEBUGGER();
1427                goto res_create_fail;
1428        }
1429
1430        {
1431                struct irq_service_init_data init_data;
1432                init_data.ctx = dc->ctx;
1433                pool->base.irqs = dal_irq_service_dce80_create(&init_data);
1434                if (!pool->base.irqs)
1435                        goto res_create_fail;
1436        }
1437
1438        for (i = 0; i < pool->base.pipe_count; i++) {
1439                pool->base.timing_generators[i] = dce80_timing_generator_create(
1440                                ctx, i, &dce80_tg_offsets[i]);
1441                if (pool->base.timing_generators[i] == NULL) {
1442                        BREAK_TO_DEBUGGER();
1443                        dm_error("DC: failed to create tg!\n");
1444                        goto res_create_fail;
1445                }
1446
1447                pool->base.mis[i] = dce80_mem_input_create(ctx, i);
1448                if (pool->base.mis[i] == NULL) {
1449                        BREAK_TO_DEBUGGER();
1450                        dm_error("DC: failed to create memory input!\n");
1451                        goto res_create_fail;
1452                }
1453
1454                pool->base.ipps[i] = dce80_ipp_create(ctx, i);
1455                if (pool->base.ipps[i] == NULL) {
1456                        BREAK_TO_DEBUGGER();
1457                        dm_error("DC: failed to create input pixel processor!\n");
1458                        goto res_create_fail;
1459                }
1460
1461                pool->base.transforms[i] = dce80_transform_create(ctx, i);
1462                if (pool->base.transforms[i] == NULL) {
1463                        BREAK_TO_DEBUGGER();
1464                        dm_error("DC: failed to create transform!\n");
1465                        goto res_create_fail;
1466                }
1467
1468                pool->base.opps[i] = dce80_opp_create(ctx, i);
1469                if (pool->base.opps[i] == NULL) {
1470                        BREAK_TO_DEBUGGER();
1471                        dm_error("DC: failed to create output pixel processor!\n");
1472                        goto res_create_fail;
1473                }
1474        }
1475
1476        for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1477                pool->base.engines[i] = dce80_aux_engine_create(ctx, i);
1478                if (pool->base.engines[i] == NULL) {
1479                        BREAK_TO_DEBUGGER();
1480                        dm_error(
1481                                "DC:failed to create aux engine!!\n");
1482                        goto res_create_fail;
1483                }
1484                pool->base.hw_i2cs[i] = dce80_i2c_hw_create(ctx, i);
1485                if (pool->base.hw_i2cs[i] == NULL) {
1486                        BREAK_TO_DEBUGGER();
1487                        dm_error(
1488                                "DC:failed to create i2c engine!!\n");
1489                        goto res_create_fail;
1490                }
1491                pool->base.sw_i2cs[i] = dce80_i2c_sw_create(ctx);
1492                if (pool->base.sw_i2cs[i] == NULL) {
1493                        BREAK_TO_DEBUGGER();
1494                        dm_error(
1495                                "DC:failed to create sw i2c!!\n");
1496                        goto res_create_fail;
1497                }
1498        }
1499
1500        dc->caps.max_planes =  pool->base.pipe_count;
1501
1502        for (i = 0; i < dc->caps.max_planes; ++i)
1503                dc->caps.planes[i] = plane_cap;
1504
1505        dc->caps.disable_dp_clk_share = true;
1506
1507        if (!resource_construct(num_virtual_links, dc, &pool->base,
1508                        &res_create_funcs))
1509                goto res_create_fail;
1510
1511        /* Create hardware sequencer */
1512        dce80_hw_sequencer_construct(dc);
1513
1514        return true;
1515
1516res_create_fail:
1517        dce80_resource_destruct(pool);
1518        return false;
1519}
1520
1521struct resource_pool *dce83_create_resource_pool(
1522        uint8_t num_virtual_links,
1523        struct dc *dc)
1524{
1525        struct dce110_resource_pool *pool =
1526                kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1527
1528        if (!pool)
1529                return NULL;
1530
1531        if (dce83_construct(num_virtual_links, dc, pool))
1532                return &pool->base;
1533
1534        BREAK_TO_DEBUGGER();
1535        return NULL;
1536}
1537