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