linux/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
<<
>>
Prefs
   1/*
   2 * Copyright 2012-15 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * Authors: AMD
  23 *
  24 */
  25
  26#include <linux/slab.h>
  27
  28#include "dm_services.h"
  29
  30#include "link_encoder.h"
  31#include "stream_encoder.h"
  32
  33#include "resource.h"
  34#include "dce110/dce110_resource.h"
  35#include "include/irq_service_interface.h"
  36#include "dce/dce_audio.h"
  37#include "dce110/dce110_timing_generator.h"
  38#include "irq/dce110/irq_service_dce110.h"
  39#include "dce110/dce110_timing_generator_v.h"
  40#include "dce/dce_link_encoder.h"
  41#include "dce/dce_stream_encoder.h"
  42#include "dce/dce_mem_input.h"
  43#include "dce110/dce110_mem_input_v.h"
  44#include "dce/dce_ipp.h"
  45#include "dce/dce_transform.h"
  46#include "dce110/dce110_transform_v.h"
  47#include "dce/dce_opp.h"
  48#include "dce110/dce110_opp_v.h"
  49#include "dce/dce_clock_source.h"
  50#include "dce/dce_hwseq.h"
  51#include "dce110/dce110_hw_sequencer.h"
  52#include "dce/dce_aux.h"
  53#include "dce/dce_abm.h"
  54#include "dce/dce_dmcu.h"
  55#include "dce/dce_i2c.h"
  56#include "dce/dce_panel_cntl.h"
  57
  58#define DC_LOGGER \
  59                dc->ctx->logger
  60
  61#include "dce110/dce110_compressor.h"
  62
  63#include "reg_helper.h"
  64
  65#include "dce/dce_11_0_d.h"
  66#include "dce/dce_11_0_sh_mask.h"
  67
  68#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
  69#include "gmc/gmc_8_2_d.h"
  70#include "gmc/gmc_8_2_sh_mask.h"
  71#endif
  72
  73#ifndef mmDP_DPHY_INTERNAL_CTRL
  74        #define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
  75        #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
  76        #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7
  77        #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7
  78        #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7
  79        #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7
  80        #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7
  81        #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7
  82        #define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7
  83        #define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7
  84#endif
  85
  86#ifndef mmBIOS_SCRATCH_2
  87        #define mmBIOS_SCRATCH_2 0x05CB
  88        #define mmBIOS_SCRATCH_3 0x05CC
  89        #define mmBIOS_SCRATCH_6 0x05CF
  90#endif
  91
  92#ifndef mmDP_DPHY_BS_SR_SWAP_CNTL
  93        #define mmDP_DPHY_BS_SR_SWAP_CNTL                       0x4ADC
  94        #define mmDP0_DP_DPHY_BS_SR_SWAP_CNTL                   0x4ADC
  95        #define mmDP1_DP_DPHY_BS_SR_SWAP_CNTL                   0x4BDC
  96        #define mmDP2_DP_DPHY_BS_SR_SWAP_CNTL                   0x4CDC
  97        #define mmDP3_DP_DPHY_BS_SR_SWAP_CNTL                   0x4DDC
  98        #define mmDP4_DP_DPHY_BS_SR_SWAP_CNTL                   0x4EDC
  99        #define mmDP5_DP_DPHY_BS_SR_SWAP_CNTL                   0x4FDC
 100        #define mmDP6_DP_DPHY_BS_SR_SWAP_CNTL                   0x54DC
 101#endif
 102
 103#ifndef mmDP_DPHY_FAST_TRAINING
 104        #define mmDP_DPHY_FAST_TRAINING                         0x4ABC
 105        #define mmDP0_DP_DPHY_FAST_TRAINING                     0x4ABC
 106        #define mmDP1_DP_DPHY_FAST_TRAINING                     0x4BBC
 107        #define mmDP2_DP_DPHY_FAST_TRAINING                     0x4CBC
 108        #define mmDP3_DP_DPHY_FAST_TRAINING                     0x4DBC
 109        #define mmDP4_DP_DPHY_FAST_TRAINING                     0x4EBC
 110        #define mmDP5_DP_DPHY_FAST_TRAINING                     0x4FBC
 111        #define mmDP6_DP_DPHY_FAST_TRAINING                     0x54BC
 112#endif
 113
 114#ifndef DPHY_RX_FAST_TRAINING_CAPABLE
 115        #define DPHY_RX_FAST_TRAINING_CAPABLE 0x1
 116#endif
 117
 118static const struct dce110_timing_generator_offsets dce110_tg_offsets[] = {
 119        {
 120                .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
 121                .dcp =  (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL),
 122        },
 123        {
 124                .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
 125                .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
 126        },
 127        {
 128                .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
 129                .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
 130        },
 131        {
 132                .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
 133                .dcp =  (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
 134        },
 135        {
 136                .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
 137                .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
 138        },
 139        {
 140                .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
 141                .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
 142        }
 143};
 144
 145/* set register offset */
 146#define SR(reg_name)\
 147        .reg_name = mm ## reg_name
 148
 149/* set register offset with instance */
 150#define SRI(reg_name, block, id)\
 151        .reg_name = mm ## block ## id ## _ ## reg_name
 152
 153static const struct dce_dmcu_registers dmcu_regs = {
 154                DMCU_DCE110_COMMON_REG_LIST()
 155};
 156
 157static const struct dce_dmcu_shift dmcu_shift = {
 158                DMCU_MASK_SH_LIST_DCE110(__SHIFT)
 159};
 160
 161static const struct dce_dmcu_mask dmcu_mask = {
 162                DMCU_MASK_SH_LIST_DCE110(_MASK)
 163};
 164
 165static const struct dce_abm_registers abm_regs = {
 166                ABM_DCE110_COMMON_REG_LIST()
 167};
 168
 169static const struct dce_abm_shift abm_shift = {
 170                ABM_MASK_SH_LIST_DCE110(__SHIFT)
 171};
 172
 173static const struct dce_abm_mask abm_mask = {
 174                ABM_MASK_SH_LIST_DCE110(_MASK)
 175};
 176
 177#define ipp_regs(id)\
 178[id] = {\
 179                IPP_DCE110_REG_LIST_DCE_BASE(id)\
 180}
 181
 182static const struct dce_ipp_registers ipp_regs[] = {
 183                ipp_regs(0),
 184                ipp_regs(1),
 185                ipp_regs(2)
 186};
 187
 188static const struct dce_ipp_shift ipp_shift = {
 189                IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 190};
 191
 192static const struct dce_ipp_mask ipp_mask = {
 193                IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 194};
 195
 196#define transform_regs(id)\
 197[id] = {\
 198                XFM_COMMON_REG_LIST_DCE110(id)\
 199}
 200
 201static const struct dce_transform_registers xfm_regs[] = {
 202                transform_regs(0),
 203                transform_regs(1),
 204                transform_regs(2)
 205};
 206
 207static const struct dce_transform_shift xfm_shift = {
 208                XFM_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
 209};
 210
 211static const struct dce_transform_mask xfm_mask = {
 212                XFM_COMMON_MASK_SH_LIST_DCE110(_MASK)
 213};
 214
 215#define aux_regs(id)\
 216[id] = {\
 217        AUX_REG_LIST(id)\
 218}
 219
 220static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
 221                aux_regs(0),
 222                aux_regs(1),
 223                aux_regs(2),
 224                aux_regs(3),
 225                aux_regs(4),
 226                aux_regs(5)
 227};
 228
 229#define hpd_regs(id)\
 230[id] = {\
 231        HPD_REG_LIST(id)\
 232}
 233
 234static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
 235                hpd_regs(0),
 236                hpd_regs(1),
 237                hpd_regs(2),
 238                hpd_regs(3),
 239                hpd_regs(4),
 240                hpd_regs(5)
 241};
 242
 243
 244#define link_regs(id)\
 245[id] = {\
 246        LE_DCE110_REG_LIST(id)\
 247}
 248
 249static const struct dce110_link_enc_registers link_enc_regs[] = {
 250        link_regs(0),
 251        link_regs(1),
 252        link_regs(2),
 253        link_regs(3),
 254        link_regs(4),
 255        link_regs(5),
 256        link_regs(6),
 257};
 258
 259#define stream_enc_regs(id)\
 260[id] = {\
 261        SE_COMMON_REG_LIST(id),\
 262        .TMDS_CNTL = 0,\
 263}
 264
 265static const struct dce110_stream_enc_registers stream_enc_regs[] = {
 266        stream_enc_regs(0),
 267        stream_enc_regs(1),
 268        stream_enc_regs(2)
 269};
 270
 271static const struct dce_stream_encoder_shift se_shift = {
 272                SE_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
 273};
 274
 275static const struct dce_stream_encoder_mask se_mask = {
 276                SE_COMMON_MASK_SH_LIST_DCE110(_MASK)
 277};
 278
 279static const struct dce_panel_cntl_registers panel_cntl_regs[] = {
 280        { DCE_PANEL_CNTL_REG_LIST() }
 281};
 282
 283static const struct dce_panel_cntl_shift panel_cntl_shift = {
 284        DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT)
 285};
 286
 287static const struct dce_panel_cntl_mask panel_cntl_mask = {
 288        DCE_PANEL_CNTL_MASK_SH_LIST(_MASK)
 289};
 290
 291static const struct dce110_aux_registers_shift aux_shift = {
 292        DCE_AUX_MASK_SH_LIST(__SHIFT)
 293};
 294
 295static const struct dce110_aux_registers_mask aux_mask = {
 296        DCE_AUX_MASK_SH_LIST(_MASK)
 297};
 298
 299#define opp_regs(id)\
 300[id] = {\
 301        OPP_DCE_110_REG_LIST(id),\
 302}
 303
 304static const struct dce_opp_registers opp_regs[] = {
 305        opp_regs(0),
 306        opp_regs(1),
 307        opp_regs(2),
 308        opp_regs(3),
 309        opp_regs(4),
 310        opp_regs(5)
 311};
 312
 313static const struct dce_opp_shift opp_shift = {
 314        OPP_COMMON_MASK_SH_LIST_DCE_110(__SHIFT)
 315};
 316
 317static const struct dce_opp_mask opp_mask = {
 318        OPP_COMMON_MASK_SH_LIST_DCE_110(_MASK)
 319};
 320
 321#define aux_engine_regs(id)\
 322[id] = {\
 323        AUX_COMMON_REG_LIST(id), \
 324        .AUX_RESET_MASK = 0 \
 325}
 326
 327static const struct dce110_aux_registers aux_engine_regs[] = {
 328                aux_engine_regs(0),
 329                aux_engine_regs(1),
 330                aux_engine_regs(2),
 331                aux_engine_regs(3),
 332                aux_engine_regs(4),
 333                aux_engine_regs(5)
 334};
 335
 336#define audio_regs(id)\
 337[id] = {\
 338        AUD_COMMON_REG_LIST(id)\
 339}
 340
 341static const struct dce_audio_registers audio_regs[] = {
 342        audio_regs(0),
 343        audio_regs(1),
 344        audio_regs(2),
 345        audio_regs(3),
 346        audio_regs(4),
 347        audio_regs(5),
 348        audio_regs(6),
 349};
 350
 351static const struct dce_audio_shift audio_shift = {
 352                AUD_COMMON_MASK_SH_LIST(__SHIFT)
 353};
 354
 355static const struct dce_audio_mask audio_mask = {
 356                AUD_COMMON_MASK_SH_LIST(_MASK)
 357};
 358
 359/* AG TBD Needs to be reduced back to 3 pipes once dce10 hw sequencer implemented. */
 360
 361
 362#define clk_src_regs(id)\
 363[id] = {\
 364        CS_COMMON_REG_LIST_DCE_100_110(id),\
 365}
 366
 367static const struct dce110_clk_src_regs clk_src_regs[] = {
 368        clk_src_regs(0),
 369        clk_src_regs(1),
 370        clk_src_regs(2)
 371};
 372
 373static const struct dce110_clk_src_shift cs_shift = {
 374                CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 375};
 376
 377static const struct dce110_clk_src_mask cs_mask = {
 378                CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 379};
 380
 381static const struct bios_registers bios_regs = {
 382        .BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
 383        .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
 384};
 385
 386static const struct resource_caps carrizo_resource_cap = {
 387                .num_timing_generator = 3,
 388                .num_video_plane = 1,
 389                .num_audio = 3,
 390                .num_stream_encoder = 3,
 391                .num_pll = 2,
 392                .num_ddc = 3,
 393};
 394
 395static const struct resource_caps stoney_resource_cap = {
 396                .num_timing_generator = 2,
 397                .num_video_plane = 1,
 398                .num_audio = 3,
 399                .num_stream_encoder = 3,
 400                .num_pll = 2,
 401                .num_ddc = 3,
 402};
 403
 404static const struct dc_plane_cap plane_cap = {
 405                .type = DC_PLANE_TYPE_DCE_RGB,
 406                .blends_with_below = true,
 407                .blends_with_above = true,
 408                .per_pixel_alpha = 1,
 409
 410                .pixel_format_support = {
 411                                .argb8888 = true,
 412                                .nv12 = false,
 413                                .fp16 = true
 414                },
 415
 416                .max_upscale_factor = {
 417                                .argb8888 = 16000,
 418                                .nv12 = 1,
 419                                .fp16 = 1
 420                },
 421
 422                .max_downscale_factor = {
 423                                .argb8888 = 250,
 424                                .nv12 = 1,
 425                                .fp16 = 1
 426                },
 427                64,
 428                64
 429};
 430
 431static const struct dc_plane_cap underlay_plane_cap = {
 432                .type = DC_PLANE_TYPE_DCE_UNDERLAY,
 433                .blends_with_above = true,
 434                .per_pixel_alpha = 1,
 435
 436                .pixel_format_support = {
 437                                .argb8888 = false,
 438                                .nv12 = true,
 439                                .fp16 = false
 440                },
 441
 442                .max_upscale_factor = {
 443                                .argb8888 = 1,
 444                                .nv12 = 16000,
 445                                .fp16 = 1
 446                },
 447
 448                .max_downscale_factor = {
 449                                .argb8888 = 1,
 450                                .nv12 = 250,
 451                                .fp16 = 1
 452                },
 453                64,
 454                64
 455};
 456
 457#define CTX  ctx
 458#define REG(reg) mm ## reg
 459
 460#ifndef mmCC_DC_HDMI_STRAPS
 461#define mmCC_DC_HDMI_STRAPS 0x4819
 462#define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
 463#define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
 464#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
 465#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
 466#endif
 467
 468static int map_transmitter_id_to_phy_instance(
 469        enum transmitter transmitter)
 470{
 471        switch (transmitter) {
 472        case TRANSMITTER_UNIPHY_A:
 473                return 0;
 474        case TRANSMITTER_UNIPHY_B:
 475                return 1;
 476        case TRANSMITTER_UNIPHY_C:
 477                return 2;
 478        case TRANSMITTER_UNIPHY_D:
 479                return 3;
 480        case TRANSMITTER_UNIPHY_E:
 481                return 4;
 482        case TRANSMITTER_UNIPHY_F:
 483                return 5;
 484        case TRANSMITTER_UNIPHY_G:
 485                return 6;
 486        default:
 487                ASSERT(0);
 488                return 0;
 489        }
 490}
 491
 492static void read_dce_straps(
 493        struct dc_context *ctx,
 494        struct resource_straps *straps)
 495{
 496        REG_GET_2(CC_DC_HDMI_STRAPS,
 497                        HDMI_DISABLE, &straps->hdmi_disable,
 498                        AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
 499
 500        REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);
 501}
 502
 503static struct audio *create_audio(
 504                struct dc_context *ctx, unsigned int inst)
 505{
 506        return dce_audio_create(ctx, inst,
 507                        &audio_regs[inst], &audio_shift, &audio_mask);
 508}
 509
 510static struct timing_generator *dce110_timing_generator_create(
 511                struct dc_context *ctx,
 512                uint32_t instance,
 513                const struct dce110_timing_generator_offsets *offsets)
 514{
 515        struct dce110_timing_generator *tg110 =
 516                kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
 517
 518        if (!tg110)
 519                return NULL;
 520
 521        dce110_timing_generator_construct(tg110, ctx, instance, offsets);
 522        return &tg110->base;
 523}
 524
 525static struct stream_encoder *dce110_stream_encoder_create(
 526        enum engine_id eng_id,
 527        struct dc_context *ctx)
 528{
 529        struct dce110_stream_encoder *enc110 =
 530                kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
 531
 532        if (!enc110)
 533                return NULL;
 534
 535        dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
 536                                        &stream_enc_regs[eng_id],
 537                                        &se_shift, &se_mask);
 538        return &enc110->base;
 539}
 540
 541#define SRII(reg_name, block, id)\
 542        .reg_name[id] = mm ## block ## id ## _ ## reg_name
 543
 544static const struct dce_hwseq_registers hwseq_stoney_reg = {
 545                HWSEQ_ST_REG_LIST()
 546};
 547
 548static const struct dce_hwseq_registers hwseq_cz_reg = {
 549                HWSEQ_CZ_REG_LIST()
 550};
 551
 552static const struct dce_hwseq_shift hwseq_shift = {
 553                HWSEQ_DCE11_MASK_SH_LIST(__SHIFT),
 554};
 555
 556static const struct dce_hwseq_mask hwseq_mask = {
 557                HWSEQ_DCE11_MASK_SH_LIST(_MASK),
 558};
 559
 560static struct dce_hwseq *dce110_hwseq_create(
 561        struct dc_context *ctx)
 562{
 563        struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
 564
 565        if (hws) {
 566                hws->ctx = ctx;
 567                hws->regs = ASIC_REV_IS_STONEY(ctx->asic_id.hw_internal_rev) ?
 568                                &hwseq_stoney_reg : &hwseq_cz_reg;
 569                hws->shifts = &hwseq_shift;
 570                hws->masks = &hwseq_mask;
 571                hws->wa.blnd_crtc_trigger = true;
 572        }
 573        return hws;
 574}
 575
 576static const struct resource_create_funcs res_create_funcs = {
 577        .read_dce_straps = read_dce_straps,
 578        .create_audio = create_audio,
 579        .create_stream_encoder = dce110_stream_encoder_create,
 580        .create_hwseq = dce110_hwseq_create,
 581};
 582
 583#define mi_inst_regs(id) { \
 584        MI_DCE11_REG_LIST(id), \
 585        .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
 586}
 587static const struct dce_mem_input_registers mi_regs[] = {
 588                mi_inst_regs(0),
 589                mi_inst_regs(1),
 590                mi_inst_regs(2),
 591};
 592
 593static const struct dce_mem_input_shift mi_shifts = {
 594                MI_DCE11_MASK_SH_LIST(__SHIFT),
 595                .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
 596};
 597
 598static const struct dce_mem_input_mask mi_masks = {
 599                MI_DCE11_MASK_SH_LIST(_MASK),
 600                .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
 601};
 602
 603
 604static struct mem_input *dce110_mem_input_create(
 605        struct dc_context *ctx,
 606        uint32_t inst)
 607{
 608        struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
 609                                               GFP_KERNEL);
 610
 611        if (!dce_mi) {
 612                BREAK_TO_DEBUGGER();
 613                return NULL;
 614        }
 615
 616        dce_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
 617        dce_mi->wa.single_head_rdreq_dmif_limit = 3;
 618        return &dce_mi->base;
 619}
 620
 621static void dce110_transform_destroy(struct transform **xfm)
 622{
 623        kfree(TO_DCE_TRANSFORM(*xfm));
 624        *xfm = NULL;
 625}
 626
 627static struct transform *dce110_transform_create(
 628        struct dc_context *ctx,
 629        uint32_t inst)
 630{
 631        struct dce_transform *transform =
 632                kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
 633
 634        if (!transform)
 635                return NULL;
 636
 637        dce_transform_construct(transform, ctx, inst,
 638                                &xfm_regs[inst], &xfm_shift, &xfm_mask);
 639        return &transform->base;
 640}
 641
 642static struct input_pixel_processor *dce110_ipp_create(
 643        struct dc_context *ctx, uint32_t inst)
 644{
 645        struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
 646
 647        if (!ipp) {
 648                BREAK_TO_DEBUGGER();
 649                return NULL;
 650        }
 651
 652        dce_ipp_construct(ipp, ctx, inst,
 653                        &ipp_regs[inst], &ipp_shift, &ipp_mask);
 654        return &ipp->base;
 655}
 656
 657static const struct encoder_feature_support link_enc_feature = {
 658                .max_hdmi_deep_color = COLOR_DEPTH_121212,
 659                .max_hdmi_pixel_clock = 300000,
 660                .flags.bits.IS_HBR2_CAPABLE = true,
 661                .flags.bits.IS_TPS3_CAPABLE = true
 662};
 663
 664static struct link_encoder *dce110_link_encoder_create(
 665        const struct encoder_init_data *enc_init_data)
 666{
 667        struct dce110_link_encoder *enc110 =
 668                kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
 669        int link_regs_id;
 670
 671        if (!enc110)
 672                return NULL;
 673
 674        link_regs_id =
 675                map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
 676
 677        dce110_link_encoder_construct(enc110,
 678                                      enc_init_data,
 679                                      &link_enc_feature,
 680                                      &link_enc_regs[link_regs_id],
 681                                      &link_enc_aux_regs[enc_init_data->channel - 1],
 682                                      &link_enc_hpd_regs[enc_init_data->hpd_source]);
 683        return &enc110->base;
 684}
 685
 686static struct panel_cntl *dce110_panel_cntl_create(const struct panel_cntl_init_data *init_data)
 687{
 688        struct dce_panel_cntl *panel_cntl =
 689                kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL);
 690
 691        if (!panel_cntl)
 692                return NULL;
 693
 694        dce_panel_cntl_construct(panel_cntl,
 695                        init_data,
 696                        &panel_cntl_regs[init_data->inst],
 697                        &panel_cntl_shift,
 698                        &panel_cntl_mask);
 699
 700        return &panel_cntl->base;
 701}
 702
 703static struct output_pixel_processor *dce110_opp_create(
 704        struct dc_context *ctx,
 705        uint32_t inst)
 706{
 707        struct dce110_opp *opp =
 708                kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
 709
 710        if (!opp)
 711                return NULL;
 712
 713        dce110_opp_construct(opp,
 714                             ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
 715        return &opp->base;
 716}
 717
 718static struct dce_aux *dce110_aux_engine_create(
 719        struct dc_context *ctx,
 720        uint32_t inst)
 721{
 722        struct aux_engine_dce110 *aux_engine =
 723                kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
 724
 725        if (!aux_engine)
 726                return NULL;
 727
 728        dce110_aux_engine_construct(aux_engine, ctx, inst,
 729                                    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 730                                    &aux_engine_regs[inst],
 731                                        &aux_mask,
 732                                        &aux_shift,
 733                                        ctx->dc->caps.extended_aux_timeout_support);
 734
 735        return &aux_engine->base;
 736}
 737#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
 738
 739static const struct dce_i2c_registers i2c_hw_regs[] = {
 740                i2c_inst_regs(1),
 741                i2c_inst_regs(2),
 742                i2c_inst_regs(3),
 743                i2c_inst_regs(4),
 744                i2c_inst_regs(5),
 745                i2c_inst_regs(6),
 746};
 747
 748static const struct dce_i2c_shift i2c_shifts = {
 749                I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
 750};
 751
 752static const struct dce_i2c_mask i2c_masks = {
 753                I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
 754};
 755
 756static struct dce_i2c_hw *dce110_i2c_hw_create(
 757        struct dc_context *ctx,
 758        uint32_t inst)
 759{
 760        struct dce_i2c_hw *dce_i2c_hw =
 761                kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
 762
 763        if (!dce_i2c_hw)
 764                return NULL;
 765
 766        dce100_i2c_hw_construct(dce_i2c_hw, ctx, inst,
 767                                    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
 768
 769        return dce_i2c_hw;
 770}
 771static struct clock_source *dce110_clock_source_create(
 772        struct dc_context *ctx,
 773        struct dc_bios *bios,
 774        enum clock_source_id id,
 775        const struct dce110_clk_src_regs *regs,
 776        bool dp_clk_src)
 777{
 778        struct dce110_clk_src *clk_src =
 779                kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
 780
 781        if (!clk_src)
 782                return NULL;
 783
 784        if (dce110_clk_src_construct(clk_src, ctx, bios, id,
 785                        regs, &cs_shift, &cs_mask)) {
 786                clk_src->base.dp_clk_src = dp_clk_src;
 787                return &clk_src->base;
 788        }
 789
 790        kfree(clk_src);
 791        BREAK_TO_DEBUGGER();
 792        return NULL;
 793}
 794
 795static void dce110_clock_source_destroy(struct clock_source **clk_src)
 796{
 797        struct dce110_clk_src *dce110_clk_src;
 798
 799        if (!clk_src)
 800                return;
 801
 802        dce110_clk_src = TO_DCE110_CLK_SRC(*clk_src);
 803
 804        kfree(dce110_clk_src->dp_ss_params);
 805        kfree(dce110_clk_src->hdmi_ss_params);
 806        kfree(dce110_clk_src->dvi_ss_params);
 807
 808        kfree(dce110_clk_src);
 809        *clk_src = NULL;
 810}
 811
 812static void dce110_resource_destruct(struct dce110_resource_pool *pool)
 813{
 814        unsigned int i;
 815
 816        for (i = 0; i < pool->base.pipe_count; i++) {
 817                if (pool->base.opps[i] != NULL)
 818                        dce110_opp_destroy(&pool->base.opps[i]);
 819
 820                if (pool->base.transforms[i] != NULL)
 821                        dce110_transform_destroy(&pool->base.transforms[i]);
 822
 823                if (pool->base.ipps[i] != NULL)
 824                        dce_ipp_destroy(&pool->base.ipps[i]);
 825
 826                if (pool->base.mis[i] != NULL) {
 827                        kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
 828                        pool->base.mis[i] = NULL;
 829                }
 830
 831                if (pool->base.timing_generators[i] != NULL)    {
 832                        kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
 833                        pool->base.timing_generators[i] = NULL;
 834                }
 835        }
 836
 837        for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
 838                if (pool->base.engines[i] != NULL)
 839                        dce110_engine_destroy(&pool->base.engines[i]);
 840                if (pool->base.hw_i2cs[i] != NULL) {
 841                        kfree(pool->base.hw_i2cs[i]);
 842                        pool->base.hw_i2cs[i] = NULL;
 843                }
 844                if (pool->base.sw_i2cs[i] != NULL) {
 845                        kfree(pool->base.sw_i2cs[i]);
 846                        pool->base.sw_i2cs[i] = NULL;
 847                }
 848        }
 849
 850        for (i = 0; i < pool->base.stream_enc_count; i++) {
 851                if (pool->base.stream_enc[i] != NULL)
 852                        kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
 853        }
 854
 855        for (i = 0; i < pool->base.clk_src_count; i++) {
 856                if (pool->base.clock_sources[i] != NULL) {
 857                        dce110_clock_source_destroy(&pool->base.clock_sources[i]);
 858                }
 859        }
 860
 861        if (pool->base.dp_clock_source != NULL)
 862                dce110_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.abm != NULL)
 871                dce_abm_destroy(&pool->base.abm);
 872
 873        if (pool->base.dmcu != NULL)
 874                dce_dmcu_destroy(&pool->base.dmcu);
 875
 876        if (pool->base.irqs != NULL) {
 877                dal_irq_service_destroy(&pool->base.irqs);
 878        }
 879}
 880
 881
 882static void get_pixel_clock_parameters(
 883        const struct pipe_ctx *pipe_ctx,
 884        struct pixel_clk_params *pixel_clk_params)
 885{
 886        const struct dc_stream_state *stream = pipe_ctx->stream;
 887
 888        /*TODO: is this halved for YCbCr 420? in that case we might want to move
 889         * the pixel clock normalization for hdmi up to here instead of doing it
 890         * in pll_adjust_pix_clk
 891         */
 892        pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz;
 893        pixel_clk_params->encoder_object_id = stream->link->link_enc->id;
 894        pixel_clk_params->signal_type = pipe_ctx->stream->signal;
 895        pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
 896        /* TODO: un-hardcode*/
 897        pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
 898                                                LINK_RATE_REF_FREQ_IN_KHZ;
 899        pixel_clk_params->flags.ENABLE_SS = 0;
 900        pixel_clk_params->color_depth =
 901                stream->timing.display_color_depth;
 902        pixel_clk_params->flags.DISPLAY_BLANKED = 1;
 903        pixel_clk_params->flags.SUPPORT_YCBCR420 = (stream->timing.pixel_encoding ==
 904                        PIXEL_ENCODING_YCBCR420);
 905        pixel_clk_params->pixel_encoding = stream->timing.pixel_encoding;
 906        if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422) {
 907                pixel_clk_params->color_depth = COLOR_DEPTH_888;
 908        }
 909        if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
 910                pixel_clk_params->requested_pix_clk_100hz  = pixel_clk_params->requested_pix_clk_100hz / 2;
 911        }
 912        if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
 913                pixel_clk_params->requested_pix_clk_100hz *= 2;
 914
 915}
 916
 917void dce110_resource_build_pipe_hw_param(struct pipe_ctx *pipe_ctx)
 918{
 919        get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->stream_res.pix_clk_params);
 920        pipe_ctx->clock_source->funcs->get_pix_clk_dividers(
 921                pipe_ctx->clock_source,
 922                &pipe_ctx->stream_res.pix_clk_params,
 923                &pipe_ctx->pll_settings);
 924        resource_build_bit_depth_reduction_params(pipe_ctx->stream,
 925                        &pipe_ctx->stream->bit_depth_params);
 926        pipe_ctx->stream->clamping.pixel_encoding = pipe_ctx->stream->timing.pixel_encoding;
 927}
 928
 929static bool is_surface_pixel_format_supported(struct pipe_ctx *pipe_ctx, unsigned int underlay_idx)
 930{
 931        if (pipe_ctx->pipe_idx != underlay_idx)
 932                return true;
 933        if (!pipe_ctx->plane_state)
 934                return false;
 935        if (pipe_ctx->plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
 936                return false;
 937        return true;
 938}
 939
 940static enum dc_status build_mapped_resource(
 941                const struct dc *dc,
 942                struct dc_state *context,
 943                struct dc_stream_state *stream)
 944{
 945        struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
 946
 947        if (!pipe_ctx)
 948                return DC_ERROR_UNEXPECTED;
 949
 950        if (!is_surface_pixel_format_supported(pipe_ctx,
 951                        dc->res_pool->underlay_pipe_index))
 952                return DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED;
 953
 954        dce110_resource_build_pipe_hw_param(pipe_ctx);
 955
 956        /* TODO: validate audio ASIC caps, encoder */
 957
 958        resource_build_info_frame(pipe_ctx);
 959
 960        return DC_OK;
 961}
 962
 963static bool dce110_validate_bandwidth(
 964        struct dc *dc,
 965        struct dc_state *context,
 966        bool fast_validate)
 967{
 968        bool result = false;
 969
 970        DC_LOG_BANDWIDTH_CALCS(
 971                "%s: start",
 972                __func__);
 973
 974        if (bw_calcs(
 975                        dc->ctx,
 976                        dc->bw_dceip,
 977                        dc->bw_vbios,
 978                        context->res_ctx.pipe_ctx,
 979                        dc->res_pool->pipe_count,
 980                        &context->bw_ctx.bw.dce))
 981                result =  true;
 982
 983        if (!result)
 984                DC_LOG_BANDWIDTH_VALIDATION("%s: %dx%d@%d Bandwidth validation failed!\n",
 985                        __func__,
 986                        context->streams[0]->timing.h_addressable,
 987                        context->streams[0]->timing.v_addressable,
 988                        context->streams[0]->timing.pix_clk_100hz / 10);
 989
 990        if (memcmp(&dc->current_state->bw_ctx.bw.dce,
 991                        &context->bw_ctx.bw.dce, sizeof(context->bw_ctx.bw.dce))) {
 992
 993                DC_LOG_BANDWIDTH_CALCS(
 994                        "%s: finish,\n"
 995                        "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
 996                        "stutMark_b: %d stutMark_a: %d\n"
 997                        "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
 998                        "stutMark_b: %d stutMark_a: %d\n"
 999                        "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
1000                        "stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n"
1001                        "cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n"
1002                        "sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n"
1003                        ,
1004                        __func__,
1005                        context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].b_mark,
1006                        context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].a_mark,
1007                        context->bw_ctx.bw.dce.urgent_wm_ns[0].b_mark,
1008                        context->bw_ctx.bw.dce.urgent_wm_ns[0].a_mark,
1009                        context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].b_mark,
1010                        context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].a_mark,
1011                        context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].b_mark,
1012                        context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].a_mark,
1013                        context->bw_ctx.bw.dce.urgent_wm_ns[1].b_mark,
1014                        context->bw_ctx.bw.dce.urgent_wm_ns[1].a_mark,
1015                        context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].b_mark,
1016                        context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].a_mark,
1017                        context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].b_mark,
1018                        context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].a_mark,
1019                        context->bw_ctx.bw.dce.urgent_wm_ns[2].b_mark,
1020                        context->bw_ctx.bw.dce.urgent_wm_ns[2].a_mark,
1021                        context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].b_mark,
1022                        context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].a_mark,
1023                        context->bw_ctx.bw.dce.stutter_mode_enable,
1024                        context->bw_ctx.bw.dce.cpuc_state_change_enable,
1025                        context->bw_ctx.bw.dce.cpup_state_change_enable,
1026                        context->bw_ctx.bw.dce.nbp_state_change_enable,
1027                        context->bw_ctx.bw.dce.all_displays_in_sync,
1028                        context->bw_ctx.bw.dce.dispclk_khz,
1029                        context->bw_ctx.bw.dce.sclk_khz,
1030                        context->bw_ctx.bw.dce.sclk_deep_sleep_khz,
1031                        context->bw_ctx.bw.dce.yclk_khz,
1032                        context->bw_ctx.bw.dce.blackout_recovery_time_us);
1033        }
1034        return result;
1035}
1036
1037static enum dc_status dce110_validate_plane(const struct dc_plane_state *plane_state,
1038                                            struct dc_caps *caps)
1039{
1040        if (((plane_state->dst_rect.width * 2) < plane_state->src_rect.width) ||
1041            ((plane_state->dst_rect.height * 2) < plane_state->src_rect.height))
1042                return DC_FAIL_SURFACE_VALIDATE;
1043
1044        return DC_OK;
1045}
1046
1047static bool dce110_validate_surface_sets(
1048                struct dc_state *context)
1049{
1050        int i, j;
1051
1052        for (i = 0; i < context->stream_count; i++) {
1053                if (context->stream_status[i].plane_count == 0)
1054                        continue;
1055
1056                if (context->stream_status[i].plane_count > 2)
1057                        return false;
1058
1059                for (j = 0; j < context->stream_status[i].plane_count; j++) {
1060                        struct dc_plane_state *plane =
1061                                context->stream_status[i].plane_states[j];
1062
1063                        /* underlay validation */
1064                        if (plane->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
1065
1066                                if ((plane->src_rect.width > 1920 ||
1067                                        plane->src_rect.height > 1080))
1068                                        return false;
1069
1070                                /* we don't have the logic to support underlay
1071                                 * only yet so block the use case where we get
1072                                 * NV12 plane as top layer
1073                                 */
1074                                if (j == 0)
1075                                        return false;
1076
1077                                /* irrespective of plane format,
1078                                 * stream should be RGB encoded
1079                                 */
1080                                if (context->streams[i]->timing.pixel_encoding
1081                                                != PIXEL_ENCODING_RGB)
1082                                        return false;
1083
1084                        }
1085
1086                }
1087        }
1088
1089        return true;
1090}
1091
1092static enum dc_status dce110_validate_global(
1093                struct dc *dc,
1094                struct dc_state *context)
1095{
1096        if (!dce110_validate_surface_sets(context))
1097                return DC_FAIL_SURFACE_VALIDATE;
1098
1099        return DC_OK;
1100}
1101
1102static enum dc_status dce110_add_stream_to_ctx(
1103                struct dc *dc,
1104                struct dc_state *new_ctx,
1105                struct dc_stream_state *dc_stream)
1106{
1107        enum dc_status result = DC_ERROR_UNEXPECTED;
1108
1109        result = resource_map_pool_resources(dc, new_ctx, dc_stream);
1110
1111        if (result == DC_OK)
1112                result = resource_map_clock_resources(dc, new_ctx, dc_stream);
1113
1114
1115        if (result == DC_OK)
1116                result = build_mapped_resource(dc, new_ctx, dc_stream);
1117
1118        return result;
1119}
1120
1121static struct pipe_ctx *dce110_acquire_underlay(
1122                struct dc_state *context,
1123                const struct resource_pool *pool,
1124                struct dc_stream_state *stream)
1125{
1126        struct dc *dc = stream->ctx->dc;
1127        struct dce_hwseq *hws = dc->hwseq;
1128        struct resource_context *res_ctx = &context->res_ctx;
1129        unsigned int underlay_idx = pool->underlay_pipe_index;
1130        struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[underlay_idx];
1131
1132        if (res_ctx->pipe_ctx[underlay_idx].stream)
1133                return NULL;
1134
1135        pipe_ctx->stream_res.tg = pool->timing_generators[underlay_idx];
1136        pipe_ctx->plane_res.mi = pool->mis[underlay_idx];
1137        /*pipe_ctx->plane_res.ipp = res_ctx->pool->ipps[underlay_idx];*/
1138        pipe_ctx->plane_res.xfm = pool->transforms[underlay_idx];
1139        pipe_ctx->stream_res.opp = pool->opps[underlay_idx];
1140        pipe_ctx->pipe_idx = underlay_idx;
1141
1142        pipe_ctx->stream = stream;
1143
1144        if (!dc->current_state->res_ctx.pipe_ctx[underlay_idx].stream) {
1145                struct tg_color black_color = {0};
1146                struct dc_bios *dcb = dc->ctx->dc_bios;
1147
1148                hws->funcs.enable_display_power_gating(
1149                                dc,
1150                                pipe_ctx->stream_res.tg->inst,
1151                                dcb, PIPE_GATING_CONTROL_DISABLE);
1152
1153                /*
1154                 * This is for powering on underlay, so crtc does not
1155                 * need to be enabled
1156                 */
1157
1158                pipe_ctx->stream_res.tg->funcs->program_timing(pipe_ctx->stream_res.tg,
1159                                &stream->timing,
1160                                0,
1161                                0,
1162                                0,
1163                                0,
1164                                pipe_ctx->stream->signal,
1165                                false);
1166
1167                pipe_ctx->stream_res.tg->funcs->enable_advanced_request(
1168                                pipe_ctx->stream_res.tg,
1169                                true,
1170                                &stream->timing);
1171
1172                pipe_ctx->plane_res.mi->funcs->allocate_mem_input(pipe_ctx->plane_res.mi,
1173                                stream->timing.h_total,
1174                                stream->timing.v_total,
1175                                stream->timing.pix_clk_100hz / 10,
1176                                context->stream_count);
1177
1178                color_space_to_black_color(dc,
1179                                COLOR_SPACE_YCBCR601, &black_color);
1180                pipe_ctx->stream_res.tg->funcs->set_blank_color(
1181                                pipe_ctx->stream_res.tg,
1182                                &black_color);
1183        }
1184
1185        return pipe_ctx;
1186}
1187
1188static void dce110_destroy_resource_pool(struct resource_pool **pool)
1189{
1190        struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
1191
1192        dce110_resource_destruct(dce110_pool);
1193        kfree(dce110_pool);
1194        *pool = NULL;
1195}
1196
1197struct stream_encoder *dce110_find_first_free_match_stream_enc_for_link(
1198                struct resource_context *res_ctx,
1199                const struct resource_pool *pool,
1200                struct dc_stream_state *stream)
1201{
1202        int i;
1203        int j = -1;
1204        struct dc_link *link = stream->link;
1205
1206        for (i = 0; i < pool->stream_enc_count; i++) {
1207                if (!res_ctx->is_stream_enc_acquired[i] &&
1208                                pool->stream_enc[i]) {
1209                        /* Store first available for MST second display
1210                         * in daisy chain use case
1211                         */
1212                        j = i;
1213                        if (pool->stream_enc[i]->id ==
1214                                        link->link_enc->preferred_engine)
1215                                return pool->stream_enc[i];
1216                }
1217        }
1218
1219        /*
1220         * For CZ and later, we can allow DIG FE and BE to differ for all display types
1221         */
1222
1223        if (j >= 0)
1224                return pool->stream_enc[j];
1225
1226        return NULL;
1227}
1228
1229
1230static const struct resource_funcs dce110_res_pool_funcs = {
1231        .destroy = dce110_destroy_resource_pool,
1232        .link_enc_create = dce110_link_encoder_create,
1233        .panel_cntl_create = dce110_panel_cntl_create,
1234        .validate_bandwidth = dce110_validate_bandwidth,
1235        .validate_plane = dce110_validate_plane,
1236        .acquire_idle_pipe_for_layer = dce110_acquire_underlay,
1237        .add_stream_to_ctx = dce110_add_stream_to_ctx,
1238        .validate_global = dce110_validate_global,
1239        .find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link
1240};
1241
1242static bool underlay_create(struct dc_context *ctx, struct resource_pool *pool)
1243{
1244        struct dce110_timing_generator *dce110_tgv = kzalloc(sizeof(*dce110_tgv),
1245                                                             GFP_KERNEL);
1246        struct dce_transform *dce110_xfmv = kzalloc(sizeof(*dce110_xfmv),
1247                                                    GFP_KERNEL);
1248        struct dce_mem_input *dce110_miv = kzalloc(sizeof(*dce110_miv),
1249                                                   GFP_KERNEL);
1250        struct dce110_opp *dce110_oppv = kzalloc(sizeof(*dce110_oppv),
1251                                                 GFP_KERNEL);
1252
1253        if (!dce110_tgv || !dce110_xfmv || !dce110_miv || !dce110_oppv) {
1254                kfree(dce110_tgv);
1255                kfree(dce110_xfmv);
1256                kfree(dce110_miv);
1257                kfree(dce110_oppv);
1258                return false;
1259        }
1260
1261        dce110_opp_v_construct(dce110_oppv, ctx);
1262
1263        dce110_timing_generator_v_construct(dce110_tgv, ctx);
1264        dce110_mem_input_v_construct(dce110_miv, ctx);
1265        dce110_transform_v_construct(dce110_xfmv, ctx);
1266
1267        pool->opps[pool->pipe_count] = &dce110_oppv->base;
1268        pool->timing_generators[pool->pipe_count] = &dce110_tgv->base;
1269        pool->mis[pool->pipe_count] = &dce110_miv->base;
1270        pool->transforms[pool->pipe_count] = &dce110_xfmv->base;
1271        pool->pipe_count++;
1272
1273        /* update the public caps to indicate an underlay is available */
1274        ctx->dc->caps.max_slave_planes = 1;
1275        ctx->dc->caps.max_slave_yuv_planes = 1;
1276        ctx->dc->caps.max_slave_rgb_planes = 0;
1277
1278        return true;
1279}
1280
1281static void bw_calcs_data_update_from_pplib(struct dc *dc)
1282{
1283        struct dm_pp_clock_levels clks = {0};
1284
1285        /*do system clock*/
1286        dm_pp_get_clock_levels_by_type(
1287                        dc->ctx,
1288                        DM_PP_CLOCK_TYPE_ENGINE_CLK,
1289                        &clks);
1290        /* convert all the clock fro kHz to fix point mHz */
1291        dc->bw_vbios->high_sclk = bw_frc_to_fixed(
1292                        clks.clocks_in_khz[clks.num_levels-1], 1000);
1293        dc->bw_vbios->mid1_sclk  = bw_frc_to_fixed(
1294                        clks.clocks_in_khz[clks.num_levels/8], 1000);
1295        dc->bw_vbios->mid2_sclk  = bw_frc_to_fixed(
1296                        clks.clocks_in_khz[clks.num_levels*2/8], 1000);
1297        dc->bw_vbios->mid3_sclk  = bw_frc_to_fixed(
1298                        clks.clocks_in_khz[clks.num_levels*3/8], 1000);
1299        dc->bw_vbios->mid4_sclk  = bw_frc_to_fixed(
1300                        clks.clocks_in_khz[clks.num_levels*4/8], 1000);
1301        dc->bw_vbios->mid5_sclk  = bw_frc_to_fixed(
1302                        clks.clocks_in_khz[clks.num_levels*5/8], 1000);
1303        dc->bw_vbios->mid6_sclk  = bw_frc_to_fixed(
1304                        clks.clocks_in_khz[clks.num_levels*6/8], 1000);
1305        dc->bw_vbios->low_sclk  = bw_frc_to_fixed(
1306                        clks.clocks_in_khz[0], 1000);
1307        dc->sclk_lvls = clks;
1308
1309        /*do display clock*/
1310        dm_pp_get_clock_levels_by_type(
1311                        dc->ctx,
1312                        DM_PP_CLOCK_TYPE_DISPLAY_CLK,
1313                        &clks);
1314        dc->bw_vbios->high_voltage_max_dispclk = bw_frc_to_fixed(
1315                        clks.clocks_in_khz[clks.num_levels-1], 1000);
1316        dc->bw_vbios->mid_voltage_max_dispclk  = bw_frc_to_fixed(
1317                        clks.clocks_in_khz[clks.num_levels>>1], 1000);
1318        dc->bw_vbios->low_voltage_max_dispclk  = bw_frc_to_fixed(
1319                        clks.clocks_in_khz[0], 1000);
1320
1321        /*do memory clock*/
1322        dm_pp_get_clock_levels_by_type(
1323                        dc->ctx,
1324                        DM_PP_CLOCK_TYPE_MEMORY_CLK,
1325                        &clks);
1326
1327        dc->bw_vbios->low_yclk = bw_frc_to_fixed(
1328                clks.clocks_in_khz[0] * MEMORY_TYPE_MULTIPLIER_CZ, 1000);
1329        dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
1330                clks.clocks_in_khz[clks.num_levels>>1] * MEMORY_TYPE_MULTIPLIER_CZ,
1331                1000);
1332        dc->bw_vbios->high_yclk = bw_frc_to_fixed(
1333                clks.clocks_in_khz[clks.num_levels-1] * MEMORY_TYPE_MULTIPLIER_CZ,
1334                1000);
1335}
1336
1337static const struct resource_caps *dce110_resource_cap(
1338        struct hw_asic_id *asic_id)
1339{
1340        if (ASIC_REV_IS_STONEY(asic_id->hw_internal_rev))
1341                return &stoney_resource_cap;
1342        else
1343                return &carrizo_resource_cap;
1344}
1345
1346static bool dce110_resource_construct(
1347        uint8_t num_virtual_links,
1348        struct dc *dc,
1349        struct dce110_resource_pool *pool,
1350        struct hw_asic_id asic_id)
1351{
1352        unsigned int i;
1353        struct dc_context *ctx = dc->ctx;
1354        struct dc_bios *bp;
1355
1356        ctx->dc_bios->regs = &bios_regs;
1357
1358        pool->base.res_cap = dce110_resource_cap(&ctx->asic_id);
1359        pool->base.funcs = &dce110_res_pool_funcs;
1360
1361        /*************************************************
1362         *  Resource + asic cap harcoding                *
1363         *************************************************/
1364
1365        pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
1366        pool->base.underlay_pipe_index = pool->base.pipe_count;
1367        pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
1368        dc->caps.max_downscale_ratio = 150;
1369        dc->caps.i2c_speed_in_khz = 40;
1370        dc->caps.i2c_speed_in_khz_hdcp = 40;
1371        dc->caps.max_cursor_size = 128;
1372        dc->caps.min_horizontal_blanking_period = 80;
1373        dc->caps.is_apu = true;
1374        dc->caps.extended_aux_timeout_support = false;
1375
1376        /*************************************************
1377         *  Create resources                             *
1378         *************************************************/
1379
1380        bp = ctx->dc_bios;
1381
1382        if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
1383                pool->base.dp_clock_source =
1384                                dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
1385
1386                pool->base.clock_sources[0] =
1387                                dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0,
1388                                                &clk_src_regs[0], false);
1389                pool->base.clock_sources[1] =
1390                                dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1,
1391                                                &clk_src_regs[1], false);
1392
1393                pool->base.clk_src_count = 2;
1394
1395                /* TODO: find out if CZ support 3 PLLs */
1396        }
1397
1398        if (pool->base.dp_clock_source == NULL) {
1399                dm_error("DC: failed to create dp clock source!\n");
1400                BREAK_TO_DEBUGGER();
1401                goto res_create_fail;
1402        }
1403
1404        for (i = 0; i < pool->base.clk_src_count; i++) {
1405                if (pool->base.clock_sources[i] == NULL) {
1406                        dm_error("DC: failed to create clock sources!\n");
1407                        BREAK_TO_DEBUGGER();
1408                        goto res_create_fail;
1409                }
1410        }
1411
1412        pool->base.dmcu = dce_dmcu_create(ctx,
1413                        &dmcu_regs,
1414                        &dmcu_shift,
1415                        &dmcu_mask);
1416        if (pool->base.dmcu == NULL) {
1417                dm_error("DC: failed to create dmcu!\n");
1418                BREAK_TO_DEBUGGER();
1419                goto res_create_fail;
1420        }
1421
1422        pool->base.abm = dce_abm_create(ctx,
1423                        &abm_regs,
1424                        &abm_shift,
1425                        &abm_mask);
1426        if (pool->base.abm == NULL) {
1427                dm_error("DC: failed to create abm!\n");
1428                BREAK_TO_DEBUGGER();
1429                goto res_create_fail;
1430        }
1431
1432        {
1433                struct irq_service_init_data init_data;
1434                init_data.ctx = dc->ctx;
1435                pool->base.irqs = dal_irq_service_dce110_create(&init_data);
1436                if (!pool->base.irqs)
1437                        goto res_create_fail;
1438        }
1439
1440        for (i = 0; i < pool->base.pipe_count; i++) {
1441                pool->base.timing_generators[i] = dce110_timing_generator_create(
1442                                ctx, i, &dce110_tg_offsets[i]);
1443                if (pool->base.timing_generators[i] == NULL) {
1444                        BREAK_TO_DEBUGGER();
1445                        dm_error("DC: failed to create tg!\n");
1446                        goto res_create_fail;
1447                }
1448
1449                pool->base.mis[i] = dce110_mem_input_create(ctx, i);
1450                if (pool->base.mis[i] == NULL) {
1451                        BREAK_TO_DEBUGGER();
1452                        dm_error(
1453                                "DC: failed to create memory input!\n");
1454                        goto res_create_fail;
1455                }
1456
1457                pool->base.ipps[i] = dce110_ipp_create(ctx, i);
1458                if (pool->base.ipps[i] == NULL) {
1459                        BREAK_TO_DEBUGGER();
1460                        dm_error(
1461                                "DC: failed to create input pixel processor!\n");
1462                        goto res_create_fail;
1463                }
1464
1465                pool->base.transforms[i] = dce110_transform_create(ctx, i);
1466                if (pool->base.transforms[i] == NULL) {
1467                        BREAK_TO_DEBUGGER();
1468                        dm_error(
1469                                "DC: failed to create transform!\n");
1470                        goto res_create_fail;
1471                }
1472
1473                pool->base.opps[i] = dce110_opp_create(ctx, i);
1474                if (pool->base.opps[i] == NULL) {
1475                        BREAK_TO_DEBUGGER();
1476                        dm_error(
1477                                "DC: failed to create output pixel processor!\n");
1478                        goto res_create_fail;
1479                }
1480        }
1481
1482        for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1483                pool->base.engines[i] = dce110_aux_engine_create(ctx, i);
1484                if (pool->base.engines[i] == NULL) {
1485                        BREAK_TO_DEBUGGER();
1486                        dm_error(
1487                                "DC:failed to create aux engine!!\n");
1488                        goto res_create_fail;
1489                }
1490                pool->base.hw_i2cs[i] = dce110_i2c_hw_create(ctx, i);
1491                if (pool->base.hw_i2cs[i] == NULL) {
1492                        BREAK_TO_DEBUGGER();
1493                        dm_error(
1494                                "DC:failed to create i2c engine!!\n");
1495                        goto res_create_fail;
1496                }
1497                pool->base.sw_i2cs[i] = NULL;
1498        }
1499
1500        if (dc->config.fbc_support)
1501                dc->fbc_compressor = dce110_compressor_create(ctx);
1502
1503        if (!underlay_create(ctx, &pool->base))
1504                goto res_create_fail;
1505
1506        if (!resource_construct(num_virtual_links, dc, &pool->base,
1507                        &res_create_funcs))
1508                goto res_create_fail;
1509
1510        /* Create hardware sequencer */
1511        dce110_hw_sequencer_construct(dc);
1512
1513        dc->caps.max_planes =  pool->base.pipe_count;
1514
1515        for (i = 0; i < pool->base.underlay_pipe_index; ++i)
1516                dc->caps.planes[i] = plane_cap;
1517
1518        dc->caps.planes[pool->base.underlay_pipe_index] = underlay_plane_cap;
1519
1520        bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id);
1521
1522        bw_calcs_data_update_from_pplib(dc);
1523
1524        return true;
1525
1526res_create_fail:
1527        dce110_resource_destruct(pool);
1528        return false;
1529}
1530
1531struct resource_pool *dce110_create_resource_pool(
1532        uint8_t num_virtual_links,
1533        struct dc *dc,
1534        struct hw_asic_id asic_id)
1535{
1536        struct dce110_resource_pool *pool =
1537                kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1538
1539        if (!pool)
1540                return NULL;
1541
1542        if (dce110_resource_construct(num_virtual_links, dc, pool, asic_id))
1543                return &pool->base;
1544
1545        kfree(pool);
1546        BREAK_TO_DEBUGGER();
1547        return NULL;
1548}
1549