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