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