linux/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
<<
>>
Prefs
   1/*
   2* Copyright 2012-15 Advanced Micro Devices, Inc.cls
   3*
   4 *
   5 * Permission is hereby granted, free of charge, to any person obtaining a
   6 * copy of this software and associated documentation files (the "Software"),
   7 * to deal in the Software without restriction, including without limitation
   8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   9 * and/or sell copies of the Software, and to permit persons to whom the
  10 * Software is furnished to do so, subject to the following conditions:
  11 *
  12 * The above copyright notice and this permission notice shall be included in
  13 * all copies or substantial portions of the Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21 * OTHER DEALINGS IN THE SOFTWARE.
  22 *
  23 * Authors: AMD
  24 *
  25 */
  26
  27#include "dm_services.h"
  28
  29
  30#include "stream_encoder.h"
  31#include "resource.h"
  32#include "include/irq_service_interface.h"
  33#include "dce120_resource.h"
  34
  35#include "dce112/dce112_resource.h"
  36
  37#include "dce110/dce110_resource.h"
  38#include "../virtual/virtual_stream_encoder.h"
  39#include "dce120_timing_generator.h"
  40#include "irq/dce120/irq_service_dce120.h"
  41#include "dce/dce_opp.h"
  42#include "dce/dce_clock_source.h"
  43#include "dce/dce_ipp.h"
  44#include "dce/dce_mem_input.h"
  45
  46#include "dce110/dce110_hw_sequencer.h"
  47#include "dce120/dce120_hw_sequencer.h"
  48#include "dce/dce_transform.h"
  49
  50#include "dce/dce_clk_mgr.h"
  51#include "dce/dce_audio.h"
  52#include "dce/dce_link_encoder.h"
  53#include "dce/dce_stream_encoder.h"
  54#include "dce/dce_hwseq.h"
  55#include "dce/dce_abm.h"
  56#include "dce/dce_dmcu.h"
  57#include "dce/dce_aux.h"
  58#include "dce/dce_i2c.h"
  59
  60#include "dce/dce_12_0_offset.h"
  61#include "dce/dce_12_0_sh_mask.h"
  62#include "soc15_hw_ip.h"
  63#include "vega10_ip_offset.h"
  64#include "nbio/nbio_6_1_offset.h"
  65#include "reg_helper.h"
  66
  67#include "dce100/dce100_resource.h"
  68
  69#ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
  70        #define mmDP0_DP_DPHY_INTERNAL_CTRL             0x210f
  71        #define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX    2
  72        #define mmDP1_DP_DPHY_INTERNAL_CTRL             0x220f
  73        #define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX    2
  74        #define mmDP2_DP_DPHY_INTERNAL_CTRL             0x230f
  75        #define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX    2
  76        #define mmDP3_DP_DPHY_INTERNAL_CTRL             0x240f
  77        #define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX    2
  78        #define mmDP4_DP_DPHY_INTERNAL_CTRL             0x250f
  79        #define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX    2
  80        #define mmDP5_DP_DPHY_INTERNAL_CTRL             0x260f
  81        #define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX    2
  82        #define mmDP6_DP_DPHY_INTERNAL_CTRL             0x270f
  83        #define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX    2
  84#endif
  85
  86enum dce120_clk_src_array_id {
  87        DCE120_CLK_SRC_PLL0,
  88        DCE120_CLK_SRC_PLL1,
  89        DCE120_CLK_SRC_PLL2,
  90        DCE120_CLK_SRC_PLL3,
  91        DCE120_CLK_SRC_PLL4,
  92        DCE120_CLK_SRC_PLL5,
  93
  94        DCE120_CLK_SRC_TOTAL
  95};
  96
  97static const struct dce110_timing_generator_offsets dce120_tg_offsets[] = {
  98        {
  99                .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
 100        },
 101        {
 102                .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
 103        },
 104        {
 105                .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
 106        },
 107        {
 108                .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
 109        },
 110        {
 111                .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
 112        },
 113        {
 114                .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
 115        }
 116};
 117
 118/* begin *********************
 119 * macros to expend register list macro defined in HW object header file */
 120
 121#define BASE_INNER(seg) \
 122        DCE_BASE__INST0_SEG ## seg
 123
 124#define NBIO_BASE_INNER(seg) \
 125        NBIF_BASE__INST0_SEG ## seg
 126
 127#define NBIO_BASE(seg) \
 128        NBIO_BASE_INNER(seg)
 129
 130/* compile time expand base address. */
 131#define BASE(seg) \
 132        BASE_INNER(seg)
 133
 134#define SR(reg_name)\
 135                .reg_name = BASE(mm ## reg_name ## _BASE_IDX) +  \
 136                                        mm ## reg_name
 137
 138#define SRI(reg_name, block, id)\
 139        .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
 140                                        mm ## block ## id ## _ ## reg_name
 141
 142/* macros to expend register list macro defined in HW object header file
 143 * end *********************/
 144
 145
 146static const struct dce_dmcu_registers dmcu_regs = {
 147                DMCU_DCE110_COMMON_REG_LIST()
 148};
 149
 150static const struct dce_dmcu_shift dmcu_shift = {
 151                DMCU_MASK_SH_LIST_DCE110(__SHIFT)
 152};
 153
 154static const struct dce_dmcu_mask dmcu_mask = {
 155                DMCU_MASK_SH_LIST_DCE110(_MASK)
 156};
 157
 158static const struct dce_abm_registers abm_regs = {
 159                ABM_DCE110_COMMON_REG_LIST()
 160};
 161
 162static const struct dce_abm_shift abm_shift = {
 163                ABM_MASK_SH_LIST_DCE110(__SHIFT)
 164};
 165
 166static const struct dce_abm_mask abm_mask = {
 167                ABM_MASK_SH_LIST_DCE110(_MASK)
 168};
 169
 170#define ipp_regs(id)\
 171[id] = {\
 172                IPP_DCE110_REG_LIST_DCE_BASE(id)\
 173}
 174
 175static const struct dce_ipp_registers ipp_regs[] = {
 176                ipp_regs(0),
 177                ipp_regs(1),
 178                ipp_regs(2),
 179                ipp_regs(3),
 180                ipp_regs(4),
 181                ipp_regs(5)
 182};
 183
 184static const struct dce_ipp_shift ipp_shift = {
 185                IPP_DCE120_MASK_SH_LIST_SOC_BASE(__SHIFT)
 186};
 187
 188static const struct dce_ipp_mask ipp_mask = {
 189                IPP_DCE120_MASK_SH_LIST_SOC_BASE(_MASK)
 190};
 191
 192#define transform_regs(id)\
 193[id] = {\
 194                XFM_COMMON_REG_LIST_DCE110(id)\
 195}
 196
 197static const struct dce_transform_registers xfm_regs[] = {
 198                transform_regs(0),
 199                transform_regs(1),
 200                transform_regs(2),
 201                transform_regs(3),
 202                transform_regs(4),
 203                transform_regs(5)
 204};
 205
 206static const struct dce_transform_shift xfm_shift = {
 207                XFM_COMMON_MASK_SH_LIST_SOC_BASE(__SHIFT)
 208};
 209
 210static const struct dce_transform_mask xfm_mask = {
 211                XFM_COMMON_MASK_SH_LIST_SOC_BASE(_MASK)
 212};
 213
 214#define aux_regs(id)\
 215[id] = {\
 216        AUX_REG_LIST(id)\
 217}
 218
 219static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
 220                aux_regs(0),
 221                aux_regs(1),
 222                aux_regs(2),
 223                aux_regs(3),
 224                aux_regs(4),
 225                aux_regs(5)
 226};
 227
 228#define hpd_regs(id)\
 229[id] = {\
 230        HPD_REG_LIST(id)\
 231}
 232
 233static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
 234                hpd_regs(0),
 235                hpd_regs(1),
 236                hpd_regs(2),
 237                hpd_regs(3),
 238                hpd_regs(4),
 239                hpd_regs(5)
 240};
 241
 242#define link_regs(id)\
 243[id] = {\
 244        LE_DCE120_REG_LIST(id), \
 245        SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
 246}
 247
 248static const struct dce110_link_enc_registers link_enc_regs[] = {
 249        link_regs(0),
 250        link_regs(1),
 251        link_regs(2),
 252        link_regs(3),
 253        link_regs(4),
 254        link_regs(5),
 255        link_regs(6),
 256};
 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        stream_enc_regs(3),
 270        stream_enc_regs(4),
 271        stream_enc_regs(5)
 272};
 273
 274static const struct dce_stream_encoder_shift se_shift = {
 275                SE_COMMON_MASK_SH_LIST_DCE120(__SHIFT)
 276};
 277
 278static const struct dce_stream_encoder_mask se_mask = {
 279                SE_COMMON_MASK_SH_LIST_DCE120(_MASK)
 280};
 281
 282#define opp_regs(id)\
 283[id] = {\
 284        OPP_DCE_120_REG_LIST(id),\
 285}
 286
 287static const struct dce_opp_registers opp_regs[] = {
 288        opp_regs(0),
 289        opp_regs(1),
 290        opp_regs(2),
 291        opp_regs(3),
 292        opp_regs(4),
 293        opp_regs(5)
 294};
 295
 296static const struct dce_opp_shift opp_shift = {
 297        OPP_COMMON_MASK_SH_LIST_DCE_120(__SHIFT)
 298};
 299
 300static const struct dce_opp_mask opp_mask = {
 301        OPP_COMMON_MASK_SH_LIST_DCE_120(_MASK)
 302};
 303 #define aux_engine_regs(id)\
 304[id] = {\
 305        AUX_COMMON_REG_LIST(id), \
 306        .AUX_RESET_MASK = 0 \
 307}
 308
 309static const struct dce110_aux_registers aux_engine_regs[] = {
 310                aux_engine_regs(0),
 311                aux_engine_regs(1),
 312                aux_engine_regs(2),
 313                aux_engine_regs(3),
 314                aux_engine_regs(4),
 315                aux_engine_regs(5)
 316};
 317
 318#define audio_regs(id)\
 319[id] = {\
 320        AUD_COMMON_REG_LIST(id)\
 321}
 322
 323static const struct dce_audio_registers audio_regs[] = {
 324        audio_regs(0),
 325        audio_regs(1),
 326        audio_regs(2),
 327        audio_regs(3),
 328        audio_regs(4),
 329        audio_regs(5)
 330};
 331
 332#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
 333                SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
 334                SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
 335                AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
 336
 337static const struct dce_audio_shift audio_shift = {
 338                DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
 339};
 340
 341static const struct dce_aduio_mask audio_mask = {
 342                DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
 343};
 344
 345#define clk_src_regs(index, id)\
 346[index] = {\
 347        CS_COMMON_REG_LIST_DCE_112(id),\
 348}
 349
 350static const struct dce110_clk_src_regs clk_src_regs[] = {
 351        clk_src_regs(0, A),
 352        clk_src_regs(1, B),
 353        clk_src_regs(2, C),
 354        clk_src_regs(3, D),
 355        clk_src_regs(4, E),
 356        clk_src_regs(5, F)
 357};
 358
 359static const struct dce110_clk_src_shift cs_shift = {
 360                CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)
 361};
 362
 363static const struct dce110_clk_src_mask cs_mask = {
 364                CS_COMMON_MASK_SH_LIST_DCE_112(_MASK)
 365};
 366
 367struct output_pixel_processor *dce120_opp_create(
 368        struct dc_context *ctx,
 369        uint32_t inst)
 370{
 371        struct dce110_opp *opp =
 372                kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
 373
 374        if (!opp)
 375                return NULL;
 376
 377        dce110_opp_construct(opp,
 378                             ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
 379        return &opp->base;
 380}
 381struct aux_engine *dce120_aux_engine_create(
 382        struct dc_context *ctx,
 383        uint32_t inst)
 384{
 385        struct aux_engine_dce110 *aux_engine =
 386                kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
 387
 388        if (!aux_engine)
 389                return NULL;
 390
 391        dce110_aux_engine_construct(aux_engine, ctx, inst,
 392                                    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 393                                    &aux_engine_regs[inst]);
 394
 395        return &aux_engine->base;
 396}
 397#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
 398
 399static const struct dce_i2c_registers i2c_hw_regs[] = {
 400                i2c_inst_regs(1),
 401                i2c_inst_regs(2),
 402                i2c_inst_regs(3),
 403                i2c_inst_regs(4),
 404                i2c_inst_regs(5),
 405                i2c_inst_regs(6),
 406};
 407
 408static const struct dce_i2c_shift i2c_shifts = {
 409                I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
 410};
 411
 412static const struct dce_i2c_mask i2c_masks = {
 413                I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
 414};
 415
 416struct dce_i2c_hw *dce120_i2c_hw_create(
 417        struct dc_context *ctx,
 418        uint32_t inst)
 419{
 420        struct dce_i2c_hw *dce_i2c_hw =
 421                kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
 422
 423        if (!dce_i2c_hw)
 424                return NULL;
 425
 426        dce112_i2c_hw_construct(dce_i2c_hw, ctx, inst,
 427                                    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
 428
 429        return dce_i2c_hw;
 430}
 431static const struct bios_registers bios_regs = {
 432        .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 + NBIO_BASE(mmBIOS_SCRATCH_6_BASE_IDX)
 433};
 434
 435static const struct resource_caps res_cap = {
 436                .num_timing_generator = 6,
 437                .num_audio = 7,
 438                .num_stream_encoder = 6,
 439                .num_pll = 6,
 440                .num_ddc = 6,
 441};
 442
 443static const struct dc_debug_options debug_defaults = {
 444                .disable_clock_gate = true,
 445};
 446
 447struct clock_source *dce120_clock_source_create(
 448        struct dc_context *ctx,
 449        struct dc_bios *bios,
 450        enum clock_source_id id,
 451        const struct dce110_clk_src_regs *regs,
 452        bool dp_clk_src)
 453{
 454        struct dce110_clk_src *clk_src =
 455                kzalloc(sizeof(*clk_src), GFP_KERNEL);
 456
 457        if (!clk_src)
 458                return NULL;
 459
 460        if (dce112_clk_src_construct(clk_src, ctx, bios, id,
 461                                     regs, &cs_shift, &cs_mask)) {
 462                clk_src->base.dp_clk_src = dp_clk_src;
 463                return &clk_src->base;
 464        }
 465
 466        BREAK_TO_DEBUGGER();
 467        return NULL;
 468}
 469
 470void dce120_clock_source_destroy(struct clock_source **clk_src)
 471{
 472        kfree(TO_DCE110_CLK_SRC(*clk_src));
 473        *clk_src = NULL;
 474}
 475
 476
 477bool dce120_hw_sequencer_create(struct dc *dc)
 478{
 479        /* All registers used by dce11.2 match those in dce11 in offset and
 480         * structure
 481         */
 482        dce120_hw_sequencer_construct(dc);
 483
 484        /*TODO  Move to separate file and Override what is needed */
 485
 486        return true;
 487}
 488
 489static struct timing_generator *dce120_timing_generator_create(
 490                struct dc_context *ctx,
 491                uint32_t instance,
 492                const struct dce110_timing_generator_offsets *offsets)
 493{
 494        struct dce110_timing_generator *tg110 =
 495                kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
 496
 497        if (!tg110)
 498                return NULL;
 499
 500        dce120_timing_generator_construct(tg110, ctx, instance, offsets);
 501        return &tg110->base;
 502}
 503
 504static void dce120_transform_destroy(struct transform **xfm)
 505{
 506        kfree(TO_DCE_TRANSFORM(*xfm));
 507        *xfm = NULL;
 508}
 509
 510static void destruct(struct dce110_resource_pool *pool)
 511{
 512        unsigned int i;
 513
 514        for (i = 0; i < pool->base.pipe_count; i++) {
 515                if (pool->base.opps[i] != NULL)
 516                        dce110_opp_destroy(&pool->base.opps[i]);
 517
 518                if (pool->base.transforms[i] != NULL)
 519                        dce120_transform_destroy(&pool->base.transforms[i]);
 520
 521                if (pool->base.ipps[i] != NULL)
 522                        dce_ipp_destroy(&pool->base.ipps[i]);
 523
 524                if (pool->base.mis[i] != NULL) {
 525                        kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
 526                        pool->base.mis[i] = NULL;
 527                }
 528
 529                if (pool->base.irqs != NULL) {
 530                        dal_irq_service_destroy(&pool->base.irqs);
 531                }
 532
 533                if (pool->base.timing_generators[i] != NULL) {
 534                        kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
 535                        pool->base.timing_generators[i] = NULL;
 536                }
 537        }
 538
 539        for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
 540                if (pool->base.engines[i] != NULL)
 541                        dce110_engine_destroy(&pool->base.engines[i]);
 542                if (pool->base.hw_i2cs[i] != NULL) {
 543                        kfree(pool->base.hw_i2cs[i]);
 544                        pool->base.hw_i2cs[i] = NULL;
 545                }
 546                if (pool->base.sw_i2cs[i] != NULL) {
 547                        kfree(pool->base.sw_i2cs[i]);
 548                        pool->base.sw_i2cs[i] = NULL;
 549                }
 550        }
 551
 552        for (i = 0; i < pool->base.audio_count; i++) {
 553                if (pool->base.audios[i])
 554                        dce_aud_destroy(&pool->base.audios[i]);
 555        }
 556
 557        for (i = 0; i < pool->base.stream_enc_count; i++) {
 558                if (pool->base.stream_enc[i] != NULL)
 559                        kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
 560        }
 561
 562        for (i = 0; i < pool->base.clk_src_count; i++) {
 563                if (pool->base.clock_sources[i] != NULL)
 564                        dce120_clock_source_destroy(
 565                                &pool->base.clock_sources[i]);
 566        }
 567
 568        if (pool->base.dp_clock_source != NULL)
 569                dce120_clock_source_destroy(&pool->base.dp_clock_source);
 570
 571        if (pool->base.abm != NULL)
 572                dce_abm_destroy(&pool->base.abm);
 573
 574        if (pool->base.dmcu != NULL)
 575                dce_dmcu_destroy(&pool->base.dmcu);
 576
 577        if (pool->base.clk_mgr != NULL)
 578                dce_clk_mgr_destroy(&pool->base.clk_mgr);
 579}
 580
 581static void read_dce_straps(
 582        struct dc_context *ctx,
 583        struct resource_straps *straps)
 584{
 585        uint32_t reg_val = dm_read_reg_soc15(ctx, mmCC_DC_MISC_STRAPS, 0);
 586
 587        straps->audio_stream_number = get_reg_field_value(reg_val,
 588                                                          CC_DC_MISC_STRAPS,
 589                                                          AUDIO_STREAM_NUMBER);
 590        straps->hdmi_disable = get_reg_field_value(reg_val,
 591                                                   CC_DC_MISC_STRAPS,
 592                                                   HDMI_DISABLE);
 593
 594        reg_val = dm_read_reg_soc15(ctx, mmDC_PINSTRAPS, 0);
 595        straps->dc_pinstraps_audio = get_reg_field_value(reg_val,
 596                                                         DC_PINSTRAPS,
 597                                                         DC_PINSTRAPS_AUDIO);
 598}
 599
 600static struct audio *create_audio(
 601                struct dc_context *ctx, unsigned int inst)
 602{
 603        return dce_audio_create(ctx, inst,
 604                        &audio_regs[inst], &audio_shift, &audio_mask);
 605}
 606
 607static const struct encoder_feature_support link_enc_feature = {
 608                .max_hdmi_deep_color = COLOR_DEPTH_121212,
 609                .max_hdmi_pixel_clock = 600000,
 610                .hdmi_ycbcr420_supported = true,
 611                .dp_ycbcr420_supported = false,
 612                .flags.bits.IS_HBR2_CAPABLE = true,
 613                .flags.bits.IS_HBR3_CAPABLE = true,
 614                .flags.bits.IS_TPS3_CAPABLE = true,
 615                .flags.bits.IS_TPS4_CAPABLE = true,
 616};
 617
 618static struct link_encoder *dce120_link_encoder_create(
 619        const struct encoder_init_data *enc_init_data)
 620{
 621        struct dce110_link_encoder *enc110 =
 622                kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
 623
 624        if (!enc110)
 625                return NULL;
 626
 627        dce110_link_encoder_construct(enc110,
 628                                      enc_init_data,
 629                                      &link_enc_feature,
 630                                      &link_enc_regs[enc_init_data->transmitter],
 631                                      &link_enc_aux_regs[enc_init_data->channel - 1],
 632                                      &link_enc_hpd_regs[enc_init_data->hpd_source]);
 633
 634        return &enc110->base;
 635}
 636
 637static struct input_pixel_processor *dce120_ipp_create(
 638        struct dc_context *ctx, uint32_t inst)
 639{
 640        struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
 641
 642        if (!ipp) {
 643                BREAK_TO_DEBUGGER();
 644                return NULL;
 645        }
 646
 647        dce_ipp_construct(ipp, ctx, inst,
 648                        &ipp_regs[inst], &ipp_shift, &ipp_mask);
 649        return &ipp->base;
 650}
 651
 652static struct stream_encoder *dce120_stream_encoder_create(
 653        enum engine_id eng_id,
 654        struct dc_context *ctx)
 655{
 656        struct dce110_stream_encoder *enc110 =
 657                kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
 658
 659        if (!enc110)
 660                return NULL;
 661
 662        dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
 663                                        &stream_enc_regs[eng_id],
 664                                        &se_shift, &se_mask);
 665        return &enc110->base;
 666}
 667
 668#define SRII(reg_name, block, id)\
 669        .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
 670                                        mm ## block ## id ## _ ## reg_name
 671
 672static const struct dce_hwseq_registers hwseq_reg = {
 673                HWSEQ_DCE120_REG_LIST()
 674};
 675
 676static const struct dce_hwseq_shift hwseq_shift = {
 677                HWSEQ_DCE12_MASK_SH_LIST(__SHIFT)
 678};
 679
 680static const struct dce_hwseq_mask hwseq_mask = {
 681                HWSEQ_DCE12_MASK_SH_LIST(_MASK)
 682};
 683
 684static struct dce_hwseq *dce120_hwseq_create(
 685        struct dc_context *ctx)
 686{
 687        struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
 688
 689        if (hws) {
 690                hws->ctx = ctx;
 691                hws->regs = &hwseq_reg;
 692                hws->shifts = &hwseq_shift;
 693                hws->masks = &hwseq_mask;
 694        }
 695        return hws;
 696}
 697
 698static const struct resource_create_funcs res_create_funcs = {
 699        .read_dce_straps = read_dce_straps,
 700        .create_audio = create_audio,
 701        .create_stream_encoder = dce120_stream_encoder_create,
 702        .create_hwseq = dce120_hwseq_create,
 703};
 704
 705#define mi_inst_regs(id) { MI_DCE12_REG_LIST(id) }
 706static const struct dce_mem_input_registers mi_regs[] = {
 707                mi_inst_regs(0),
 708                mi_inst_regs(1),
 709                mi_inst_regs(2),
 710                mi_inst_regs(3),
 711                mi_inst_regs(4),
 712                mi_inst_regs(5),
 713};
 714
 715static const struct dce_mem_input_shift mi_shifts = {
 716                MI_DCE12_MASK_SH_LIST(__SHIFT)
 717};
 718
 719static const struct dce_mem_input_mask mi_masks = {
 720                MI_DCE12_MASK_SH_LIST(_MASK)
 721};
 722
 723static struct mem_input *dce120_mem_input_create(
 724        struct dc_context *ctx,
 725        uint32_t inst)
 726{
 727        struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
 728                                               GFP_KERNEL);
 729
 730        if (!dce_mi) {
 731                BREAK_TO_DEBUGGER();
 732                return NULL;
 733        }
 734
 735        dce120_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
 736        return &dce_mi->base;
 737}
 738
 739static struct transform *dce120_transform_create(
 740        struct dc_context *ctx,
 741        uint32_t inst)
 742{
 743        struct dce_transform *transform =
 744                kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
 745
 746        if (!transform)
 747                return NULL;
 748
 749        dce_transform_construct(transform, ctx, inst,
 750                                &xfm_regs[inst], &xfm_shift, &xfm_mask);
 751        transform->lb_memory_size = 0x1404; /*5124*/
 752        return &transform->base;
 753}
 754
 755static void dce120_destroy_resource_pool(struct resource_pool **pool)
 756{
 757        struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
 758
 759        destruct(dce110_pool);
 760        kfree(dce110_pool);
 761        *pool = NULL;
 762}
 763
 764static const struct resource_funcs dce120_res_pool_funcs = {
 765        .destroy = dce120_destroy_resource_pool,
 766        .link_enc_create = dce120_link_encoder_create,
 767        .validate_bandwidth = dce112_validate_bandwidth,
 768        .validate_plane = dce100_validate_plane,
 769        .add_stream_to_ctx = dce112_add_stream_to_ctx
 770};
 771
 772static void bw_calcs_data_update_from_pplib(struct dc *dc)
 773{
 774        struct dm_pp_clock_levels_with_latency eng_clks = {0};
 775        struct dm_pp_clock_levels_with_latency mem_clks = {0};
 776        struct dm_pp_wm_sets_with_clock_ranges clk_ranges = {0};
 777        int i;
 778        unsigned int clk;
 779        unsigned int latency;
 780
 781        /*do system clock*/
 782        if (!dm_pp_get_clock_levels_by_type_with_latency(
 783                                dc->ctx,
 784                                DM_PP_CLOCK_TYPE_ENGINE_CLK,
 785                                &eng_clks) || eng_clks.num_levels == 0) {
 786
 787                eng_clks.num_levels = 8;
 788                clk = 300000;
 789
 790                for (i = 0; i < eng_clks.num_levels; i++) {
 791                        eng_clks.data[i].clocks_in_khz = clk;
 792                        clk += 100000;
 793                }
 794        }
 795
 796        /* convert all the clock fro kHz to fix point mHz  TODO: wloop data */
 797        dc->bw_vbios->high_sclk = bw_frc_to_fixed(
 798                eng_clks.data[eng_clks.num_levels-1].clocks_in_khz, 1000);
 799        dc->bw_vbios->mid1_sclk  = bw_frc_to_fixed(
 800                eng_clks.data[eng_clks.num_levels/8].clocks_in_khz, 1000);
 801        dc->bw_vbios->mid2_sclk  = bw_frc_to_fixed(
 802                eng_clks.data[eng_clks.num_levels*2/8].clocks_in_khz, 1000);
 803        dc->bw_vbios->mid3_sclk  = bw_frc_to_fixed(
 804                eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz, 1000);
 805        dc->bw_vbios->mid4_sclk  = bw_frc_to_fixed(
 806                eng_clks.data[eng_clks.num_levels*4/8].clocks_in_khz, 1000);
 807        dc->bw_vbios->mid5_sclk  = bw_frc_to_fixed(
 808                eng_clks.data[eng_clks.num_levels*5/8].clocks_in_khz, 1000);
 809        dc->bw_vbios->mid6_sclk  = bw_frc_to_fixed(
 810                eng_clks.data[eng_clks.num_levels*6/8].clocks_in_khz, 1000);
 811        dc->bw_vbios->low_sclk  = bw_frc_to_fixed(
 812                        eng_clks.data[0].clocks_in_khz, 1000);
 813
 814        /*do memory clock*/
 815        if (!dm_pp_get_clock_levels_by_type_with_latency(
 816                        dc->ctx,
 817                        DM_PP_CLOCK_TYPE_MEMORY_CLK,
 818                        &mem_clks) || mem_clks.num_levels == 0) {
 819
 820                mem_clks.num_levels = 3;
 821                clk = 250000;
 822                latency = 45;
 823
 824                for (i = 0; i < eng_clks.num_levels; i++) {
 825                        mem_clks.data[i].clocks_in_khz = clk;
 826                        mem_clks.data[i].latency_in_us = latency;
 827                        clk += 500000;
 828                        latency -= 5;
 829                }
 830
 831        }
 832
 833        /* we don't need to call PPLIB for validation clock since they
 834         * also give us the highest sclk and highest mclk (UMA clock).
 835         * ALSO always convert UMA clock (from PPLIB)  to YCLK (HW formula):
 836         * YCLK = UMACLK*m_memoryTypeMultiplier
 837         */
 838        dc->bw_vbios->low_yclk = bw_frc_to_fixed(
 839                mem_clks.data[0].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ, 1000);
 840        dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
 841                mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ,
 842                1000);
 843        dc->bw_vbios->high_yclk = bw_frc_to_fixed(
 844                mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ,
 845                1000);
 846
 847        /* Now notify PPLib/SMU about which Watermarks sets they should select
 848         * depending on DPM state they are in. And update BW MGR GFX Engine and
 849         * Memory clock member variables for Watermarks calculations for each
 850         * Watermark Set
 851         */
 852        clk_ranges.num_wm_sets = 4;
 853        clk_ranges.wm_clk_ranges[0].wm_set_id = WM_SET_A;
 854        clk_ranges.wm_clk_ranges[0].wm_min_eng_clk_in_khz =
 855                        eng_clks.data[0].clocks_in_khz;
 856        clk_ranges.wm_clk_ranges[0].wm_max_eng_clk_in_khz =
 857                        eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
 858        clk_ranges.wm_clk_ranges[0].wm_min_mem_clk_in_khz =
 859                        mem_clks.data[0].clocks_in_khz;
 860        clk_ranges.wm_clk_ranges[0].wm_max_mem_clk_in_khz =
 861                        mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
 862
 863        clk_ranges.wm_clk_ranges[1].wm_set_id = WM_SET_B;
 864        clk_ranges.wm_clk_ranges[1].wm_min_eng_clk_in_khz =
 865                        eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
 866        /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
 867        clk_ranges.wm_clk_ranges[1].wm_max_eng_clk_in_khz = 5000000;
 868        clk_ranges.wm_clk_ranges[1].wm_min_mem_clk_in_khz =
 869                        mem_clks.data[0].clocks_in_khz;
 870        clk_ranges.wm_clk_ranges[1].wm_max_mem_clk_in_khz =
 871                        mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
 872
 873        clk_ranges.wm_clk_ranges[2].wm_set_id = WM_SET_C;
 874        clk_ranges.wm_clk_ranges[2].wm_min_eng_clk_in_khz =
 875                        eng_clks.data[0].clocks_in_khz;
 876        clk_ranges.wm_clk_ranges[2].wm_max_eng_clk_in_khz =
 877                        eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
 878        clk_ranges.wm_clk_ranges[2].wm_min_mem_clk_in_khz =
 879                        mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
 880        /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
 881        clk_ranges.wm_clk_ranges[2].wm_max_mem_clk_in_khz = 5000000;
 882
 883        clk_ranges.wm_clk_ranges[3].wm_set_id = WM_SET_D;
 884        clk_ranges.wm_clk_ranges[3].wm_min_eng_clk_in_khz =
 885                        eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
 886        /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
 887        clk_ranges.wm_clk_ranges[3].wm_max_eng_clk_in_khz = 5000000;
 888        clk_ranges.wm_clk_ranges[3].wm_min_mem_clk_in_khz =
 889                        mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
 890        /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
 891        clk_ranges.wm_clk_ranges[3].wm_max_mem_clk_in_khz = 5000000;
 892
 893        /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
 894        dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges);
 895}
 896
 897static uint32_t read_pipe_fuses(struct dc_context *ctx)
 898{
 899        uint32_t value = dm_read_reg_soc15(ctx, mmCC_DC_PIPE_DIS, 0);
 900        /* VG20 support max 6 pipes */
 901        value = value & 0x3f;
 902        return value;
 903}
 904
 905static bool construct(
 906        uint8_t num_virtual_links,
 907        struct dc *dc,
 908        struct dce110_resource_pool *pool)
 909{
 910        unsigned int i;
 911        int j;
 912        struct dc_context *ctx = dc->ctx;
 913        struct irq_service_init_data irq_init_data;
 914        bool harvest_enabled = ASICREV_IS_VEGA20_P(ctx->asic_id.hw_internal_rev);
 915        uint32_t pipe_fuses;
 916
 917        ctx->dc_bios->regs = &bios_regs;
 918
 919        pool->base.res_cap = &res_cap;
 920        pool->base.funcs = &dce120_res_pool_funcs;
 921
 922        /* TODO: Fill more data from GreenlandAsicCapability.cpp */
 923        pool->base.pipe_count = res_cap.num_timing_generator;
 924        pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
 925        pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
 926
 927        dc->caps.max_downscale_ratio = 200;
 928        dc->caps.i2c_speed_in_khz = 100;
 929        dc->caps.max_cursor_size = 128;
 930        dc->caps.dual_link_dvi = true;
 931        dc->caps.psp_setup_panel_mode = true;
 932
 933        dc->debug = debug_defaults;
 934
 935        /*************************************************
 936         *  Create resources                             *
 937         *************************************************/
 938
 939        pool->base.clock_sources[DCE120_CLK_SRC_PLL0] =
 940                        dce120_clock_source_create(ctx, ctx->dc_bios,
 941                                CLOCK_SOURCE_COMBO_PHY_PLL0,
 942                                &clk_src_regs[0], false);
 943        pool->base.clock_sources[DCE120_CLK_SRC_PLL1] =
 944                        dce120_clock_source_create(ctx, ctx->dc_bios,
 945                                CLOCK_SOURCE_COMBO_PHY_PLL1,
 946                                &clk_src_regs[1], false);
 947        pool->base.clock_sources[DCE120_CLK_SRC_PLL2] =
 948                        dce120_clock_source_create(ctx, ctx->dc_bios,
 949                                CLOCK_SOURCE_COMBO_PHY_PLL2,
 950                                &clk_src_regs[2], false);
 951        pool->base.clock_sources[DCE120_CLK_SRC_PLL3] =
 952                        dce120_clock_source_create(ctx, ctx->dc_bios,
 953                                CLOCK_SOURCE_COMBO_PHY_PLL3,
 954                                &clk_src_regs[3], false);
 955        pool->base.clock_sources[DCE120_CLK_SRC_PLL4] =
 956                        dce120_clock_source_create(ctx, ctx->dc_bios,
 957                                CLOCK_SOURCE_COMBO_PHY_PLL4,
 958                                &clk_src_regs[4], false);
 959        pool->base.clock_sources[DCE120_CLK_SRC_PLL5] =
 960                        dce120_clock_source_create(ctx, ctx->dc_bios,
 961                                CLOCK_SOURCE_COMBO_PHY_PLL5,
 962                                &clk_src_regs[5], false);
 963        pool->base.clk_src_count = DCE120_CLK_SRC_TOTAL;
 964
 965        pool->base.dp_clock_source =
 966                        dce120_clock_source_create(ctx, ctx->dc_bios,
 967                                CLOCK_SOURCE_ID_DP_DTO,
 968                                &clk_src_regs[0], true);
 969
 970        for (i = 0; i < pool->base.clk_src_count; i++) {
 971                if (pool->base.clock_sources[i] == NULL) {
 972                        dm_error("DC: failed to create clock sources!\n");
 973                        BREAK_TO_DEBUGGER();
 974                        goto clk_src_create_fail;
 975                }
 976        }
 977
 978        pool->base.clk_mgr = dce120_clk_mgr_create(ctx);
 979        if (pool->base.clk_mgr == NULL) {
 980                dm_error("DC: failed to create display clock!\n");
 981                BREAK_TO_DEBUGGER();
 982                goto dccg_create_fail;
 983        }
 984
 985        pool->base.dmcu = dce_dmcu_create(ctx,
 986                        &dmcu_regs,
 987                        &dmcu_shift,
 988                        &dmcu_mask);
 989        if (pool->base.dmcu == NULL) {
 990                dm_error("DC: failed to create dmcu!\n");
 991                BREAK_TO_DEBUGGER();
 992                goto res_create_fail;
 993        }
 994
 995        pool->base.abm = dce_abm_create(ctx,
 996                        &abm_regs,
 997                        &abm_shift,
 998                        &abm_mask);
 999        if (pool->base.abm == NULL) {
1000                dm_error("DC: failed to create abm!\n");
1001                BREAK_TO_DEBUGGER();
1002                goto res_create_fail;
1003        }
1004
1005
1006        irq_init_data.ctx = dc->ctx;
1007        pool->base.irqs = dal_irq_service_dce120_create(&irq_init_data);
1008        if (!pool->base.irqs)
1009                goto irqs_create_fail;
1010
1011        /* retrieve valid pipe fuses */
1012        if (harvest_enabled)
1013                pipe_fuses = read_pipe_fuses(ctx);
1014
1015        /* index to valid pipe resource */
1016        j = 0;
1017        for (i = 0; i < pool->base.pipe_count; i++) {
1018                if (harvest_enabled) {
1019                        if ((pipe_fuses & (1 << i)) != 0) {
1020                                dm_error("DC: skip invalid pipe %d!\n", i);
1021                                continue;
1022                        }
1023                }
1024
1025                pool->base.timing_generators[j] =
1026                                dce120_timing_generator_create(
1027                                        ctx,
1028                                        i,
1029                                        &dce120_tg_offsets[i]);
1030                if (pool->base.timing_generators[j] == NULL) {
1031                        BREAK_TO_DEBUGGER();
1032                        dm_error("DC: failed to create tg!\n");
1033                        goto controller_create_fail;
1034                }
1035
1036                pool->base.mis[j] = dce120_mem_input_create(ctx, i);
1037
1038                if (pool->base.mis[j] == NULL) {
1039                        BREAK_TO_DEBUGGER();
1040                        dm_error(
1041                                "DC: failed to create memory input!\n");
1042                        goto controller_create_fail;
1043                }
1044
1045                pool->base.ipps[j] = dce120_ipp_create(ctx, i);
1046                if (pool->base.ipps[i] == NULL) {
1047                        BREAK_TO_DEBUGGER();
1048                        dm_error(
1049                                "DC: failed to create input pixel processor!\n");
1050                        goto controller_create_fail;
1051                }
1052
1053                pool->base.transforms[j] = dce120_transform_create(ctx, i);
1054                if (pool->base.transforms[i] == NULL) {
1055                        BREAK_TO_DEBUGGER();
1056                        dm_error(
1057                                "DC: failed to create transform!\n");
1058                        goto res_create_fail;
1059                }
1060
1061                pool->base.opps[j] = dce120_opp_create(
1062                        ctx,
1063                        i);
1064                if (pool->base.opps[j] == NULL) {
1065                        BREAK_TO_DEBUGGER();
1066                        dm_error(
1067                                "DC: failed to create output pixel processor!\n");
1068                }
1069
1070                /* check next valid pipe */
1071                j++;
1072        }
1073
1074        for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1075                pool->base.engines[i] = dce120_aux_engine_create(ctx, i);
1076                if (pool->base.engines[i] == NULL) {
1077                        BREAK_TO_DEBUGGER();
1078                        dm_error(
1079                                "DC:failed to create aux engine!!\n");
1080                        goto res_create_fail;
1081                }
1082                pool->base.hw_i2cs[i] = dce120_i2c_hw_create(ctx, i);
1083                if (pool->base.hw_i2cs[i] == NULL) {
1084                        BREAK_TO_DEBUGGER();
1085                        dm_error(
1086                                "DC:failed to create i2c engine!!\n");
1087                        goto res_create_fail;
1088                }
1089                pool->base.sw_i2cs[i] = NULL;
1090        }
1091
1092        /* valid pipe num */
1093        pool->base.pipe_count = j;
1094        pool->base.timing_generator_count = j;
1095
1096        if (!resource_construct(num_virtual_links, dc, &pool->base,
1097                         &res_create_funcs))
1098                goto res_create_fail;
1099
1100        /* Create hardware sequencer */
1101        if (!dce120_hw_sequencer_create(dc))
1102                goto controller_create_fail;
1103
1104        dc->caps.max_planes =  pool->base.pipe_count;
1105
1106        bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id);
1107
1108        bw_calcs_data_update_from_pplib(dc);
1109
1110        return true;
1111
1112irqs_create_fail:
1113controller_create_fail:
1114dccg_create_fail:
1115clk_src_create_fail:
1116res_create_fail:
1117
1118        destruct(pool);
1119
1120        return false;
1121}
1122
1123struct resource_pool *dce120_create_resource_pool(
1124        uint8_t num_virtual_links,
1125        struct dc *dc)
1126{
1127        struct dce110_resource_pool *pool =
1128                kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1129
1130        if (!pool)
1131                return NULL;
1132
1133        if (construct(num_virtual_links, dc, pool))
1134                return &pool->base;
1135
1136        BREAK_TO_DEBUGGER();
1137        return NULL;
1138}
1139