linux/drivers/gpu/drm/amd/display/dc/dce100/dce100_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#include "dm_services.h"
  26
  27#include "link_encoder.h"
  28#include "stream_encoder.h"
  29
  30#include "resource.h"
  31#include "include/irq_service_interface.h"
  32#include "../virtual/virtual_stream_encoder.h"
  33#include "dce110/dce110_resource.h"
  34#include "dce110/dce110_timing_generator.h"
  35#include "irq/dce110/irq_service_dce110.h"
  36#include "dce/dce_link_encoder.h"
  37#include "dce/dce_stream_encoder.h"
  38
  39#include "dce/dce_clk_mgr.h"
  40#include "dce/dce_mem_input.h"
  41#include "dce/dce_ipp.h"
  42#include "dce/dce_transform.h"
  43#include "dce/dce_opp.h"
  44#include "dce/dce_clock_source.h"
  45#include "dce/dce_audio.h"
  46#include "dce/dce_hwseq.h"
  47#include "dce100/dce100_hw_sequencer.h"
  48
  49#include "reg_helper.h"
  50
  51#include "dce/dce_10_0_d.h"
  52#include "dce/dce_10_0_sh_mask.h"
  53
  54#include "dce/dce_dmcu.h"
  55#include "dce/dce_aux.h"
  56#include "dce/dce_abm.h"
  57#include "dce/dce_i2c.h"
  58
  59#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
  60#include "gmc/gmc_8_2_d.h"
  61#include "gmc/gmc_8_2_sh_mask.h"
  62#endif
  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
 105static const struct dce110_timing_generator_offsets dce100_tg_offsets[] = {
 106        {
 107                .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
 108                .dcp =  (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL),
 109        },
 110        {
 111                .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
 112                .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
 113        },
 114        {
 115                .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
 116                .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
 117        },
 118        {
 119                .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
 120                .dcp =  (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
 121        },
 122        {
 123                .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
 124                .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
 125        },
 126        {
 127                .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
 128                .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
 129        }
 130};
 131
 132/* set register offset */
 133#define SR(reg_name)\
 134        .reg_name = mm ## reg_name
 135
 136/* set register offset with instance */
 137#define SRI(reg_name, block, id)\
 138        .reg_name = mm ## block ## id ## _ ## reg_name
 139
 140
 141static const struct clk_mgr_registers disp_clk_regs = {
 142                CLK_COMMON_REG_LIST_DCE_BASE()
 143};
 144
 145static const struct clk_mgr_shift disp_clk_shift = {
 146                CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 147};
 148
 149static const struct clk_mgr_mask disp_clk_mask = {
 150                CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 151};
 152
 153#define ipp_regs(id)\
 154[id] = {\
 155                IPP_DCE100_REG_LIST_DCE_BASE(id)\
 156}
 157
 158static const struct dce_ipp_registers ipp_regs[] = {
 159                ipp_regs(0),
 160                ipp_regs(1),
 161                ipp_regs(2),
 162                ipp_regs(3),
 163                ipp_regs(4),
 164                ipp_regs(5)
 165};
 166
 167static const struct dce_ipp_shift ipp_shift = {
 168                IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 169};
 170
 171static const struct dce_ipp_mask ipp_mask = {
 172                IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 173};
 174
 175#define transform_regs(id)\
 176[id] = {\
 177                XFM_COMMON_REG_LIST_DCE100(id)\
 178}
 179
 180static const struct dce_transform_registers xfm_regs[] = {
 181                transform_regs(0),
 182                transform_regs(1),
 183                transform_regs(2),
 184                transform_regs(3),
 185                transform_regs(4),
 186                transform_regs(5)
 187};
 188
 189static const struct dce_transform_shift xfm_shift = {
 190                XFM_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
 191};
 192
 193static const struct dce_transform_mask xfm_mask = {
 194                XFM_COMMON_MASK_SH_LIST_DCE110(_MASK)
 195};
 196
 197#define aux_regs(id)\
 198[id] = {\
 199        AUX_REG_LIST(id)\
 200}
 201
 202static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
 203                aux_regs(0),
 204                aux_regs(1),
 205                aux_regs(2),
 206                aux_regs(3),
 207                aux_regs(4),
 208                aux_regs(5)
 209};
 210
 211#define hpd_regs(id)\
 212[id] = {\
 213        HPD_REG_LIST(id)\
 214}
 215
 216static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
 217                hpd_regs(0),
 218                hpd_regs(1),
 219                hpd_regs(2),
 220                hpd_regs(3),
 221                hpd_regs(4),
 222                hpd_regs(5)
 223};
 224
 225#define link_regs(id)\
 226[id] = {\
 227        LE_DCE100_REG_LIST(id)\
 228}
 229
 230static const struct dce110_link_enc_registers link_enc_regs[] = {
 231        link_regs(0),
 232        link_regs(1),
 233        link_regs(2),
 234        link_regs(3),
 235        link_regs(4),
 236        link_regs(5),
 237        link_regs(6),
 238};
 239
 240#define stream_enc_regs(id)\
 241[id] = {\
 242        SE_COMMON_REG_LIST_DCE_BASE(id),\
 243        .AFMT_CNTL = 0,\
 244}
 245
 246static const struct dce110_stream_enc_registers stream_enc_regs[] = {
 247        stream_enc_regs(0),
 248        stream_enc_regs(1),
 249        stream_enc_regs(2),
 250        stream_enc_regs(3),
 251        stream_enc_regs(4),
 252        stream_enc_regs(5),
 253        stream_enc_regs(6)
 254};
 255
 256static const struct dce_stream_encoder_shift se_shift = {
 257                SE_COMMON_MASK_SH_LIST_DCE80_100(__SHIFT)
 258};
 259
 260static const struct dce_stream_encoder_mask se_mask = {
 261                SE_COMMON_MASK_SH_LIST_DCE80_100(_MASK)
 262};
 263
 264#define opp_regs(id)\
 265[id] = {\
 266        OPP_DCE_100_REG_LIST(id),\
 267}
 268
 269static const struct dce_opp_registers opp_regs[] = {
 270        opp_regs(0),
 271        opp_regs(1),
 272        opp_regs(2),
 273        opp_regs(3),
 274        opp_regs(4),
 275        opp_regs(5)
 276};
 277
 278static const struct dce_opp_shift opp_shift = {
 279        OPP_COMMON_MASK_SH_LIST_DCE_100(__SHIFT)
 280};
 281
 282static const struct dce_opp_mask opp_mask = {
 283        OPP_COMMON_MASK_SH_LIST_DCE_100(_MASK)
 284};
 285#define aux_engine_regs(id)\
 286[id] = {\
 287        AUX_COMMON_REG_LIST(id), \
 288        .AUX_RESET_MASK = 0 \
 289}
 290
 291static const struct dce110_aux_registers aux_engine_regs[] = {
 292                aux_engine_regs(0),
 293                aux_engine_regs(1),
 294                aux_engine_regs(2),
 295                aux_engine_regs(3),
 296                aux_engine_regs(4),
 297                aux_engine_regs(5)
 298};
 299
 300#define audio_regs(id)\
 301[id] = {\
 302        AUD_COMMON_REG_LIST(id)\
 303}
 304
 305static const struct dce_audio_registers audio_regs[] = {
 306        audio_regs(0),
 307        audio_regs(1),
 308        audio_regs(2),
 309        audio_regs(3),
 310        audio_regs(4),
 311        audio_regs(5),
 312        audio_regs(6),
 313};
 314
 315static const struct dce_audio_shift audio_shift = {
 316                AUD_COMMON_MASK_SH_LIST(__SHIFT)
 317};
 318
 319static const struct dce_aduio_mask audio_mask = {
 320                AUD_COMMON_MASK_SH_LIST(_MASK)
 321};
 322
 323#define clk_src_regs(id)\
 324[id] = {\
 325        CS_COMMON_REG_LIST_DCE_100_110(id),\
 326}
 327
 328static const struct dce110_clk_src_regs clk_src_regs[] = {
 329        clk_src_regs(0),
 330        clk_src_regs(1),
 331        clk_src_regs(2)
 332};
 333
 334static const struct dce110_clk_src_shift cs_shift = {
 335                CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 336};
 337
 338static const struct dce110_clk_src_mask cs_mask = {
 339                CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 340};
 341
 342static const struct dce_dmcu_registers dmcu_regs = {
 343                DMCU_DCE110_COMMON_REG_LIST()
 344};
 345
 346static const struct dce_dmcu_shift dmcu_shift = {
 347                DMCU_MASK_SH_LIST_DCE110(__SHIFT)
 348};
 349
 350static const struct dce_dmcu_mask dmcu_mask = {
 351                DMCU_MASK_SH_LIST_DCE110(_MASK)
 352};
 353
 354static const struct dce_abm_registers abm_regs = {
 355                ABM_DCE110_COMMON_REG_LIST()
 356};
 357
 358static const struct dce_abm_shift abm_shift = {
 359                ABM_MASK_SH_LIST_DCE110(__SHIFT)
 360};
 361
 362static const struct dce_abm_mask abm_mask = {
 363                ABM_MASK_SH_LIST_DCE110(_MASK)
 364};
 365
 366#define DCFE_MEM_PWR_CTRL_REG_BASE 0x1b03
 367
 368static const struct bios_registers bios_regs = {
 369        .BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
 370        .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
 371};
 372
 373static const struct resource_caps res_cap = {
 374        .num_timing_generator = 6,
 375        .num_audio = 6,
 376        .num_stream_encoder = 6,
 377        .num_pll = 3,
 378        .num_ddc = 6,
 379};
 380
 381#define CTX  ctx
 382#define REG(reg) mm ## reg
 383
 384#ifndef mmCC_DC_HDMI_STRAPS
 385#define mmCC_DC_HDMI_STRAPS 0x1918
 386#define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
 387#define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
 388#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
 389#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
 390#endif
 391
 392static void read_dce_straps(
 393        struct dc_context *ctx,
 394        struct resource_straps *straps)
 395{
 396        REG_GET_2(CC_DC_HDMI_STRAPS,
 397                        HDMI_DISABLE, &straps->hdmi_disable,
 398                        AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
 399
 400        REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);
 401}
 402
 403static struct audio *create_audio(
 404                struct dc_context *ctx, unsigned int inst)
 405{
 406        return dce_audio_create(ctx, inst,
 407                        &audio_regs[inst], &audio_shift, &audio_mask);
 408}
 409
 410static struct timing_generator *dce100_timing_generator_create(
 411                struct dc_context *ctx,
 412                uint32_t instance,
 413                const struct dce110_timing_generator_offsets *offsets)
 414{
 415        struct dce110_timing_generator *tg110 =
 416                kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
 417
 418        if (!tg110)
 419                return NULL;
 420
 421        dce110_timing_generator_construct(tg110, ctx, instance, offsets);
 422        return &tg110->base;
 423}
 424
 425static struct stream_encoder *dce100_stream_encoder_create(
 426        enum engine_id eng_id,
 427        struct dc_context *ctx)
 428{
 429        struct dce110_stream_encoder *enc110 =
 430                kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
 431
 432        if (!enc110)
 433                return NULL;
 434
 435        dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
 436                                        &stream_enc_regs[eng_id], &se_shift, &se_mask);
 437        return &enc110->base;
 438}
 439
 440#define SRII(reg_name, block, id)\
 441        .reg_name[id] = mm ## block ## id ## _ ## reg_name
 442
 443static const struct dce_hwseq_registers hwseq_reg = {
 444                HWSEQ_DCE10_REG_LIST()
 445};
 446
 447static const struct dce_hwseq_shift hwseq_shift = {
 448                HWSEQ_DCE10_MASK_SH_LIST(__SHIFT)
 449};
 450
 451static const struct dce_hwseq_mask hwseq_mask = {
 452                HWSEQ_DCE10_MASK_SH_LIST(_MASK)
 453};
 454
 455static struct dce_hwseq *dce100_hwseq_create(
 456        struct dc_context *ctx)
 457{
 458        struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
 459
 460        if (hws) {
 461                hws->ctx = ctx;
 462                hws->regs = &hwseq_reg;
 463                hws->shifts = &hwseq_shift;
 464                hws->masks = &hwseq_mask;
 465        }
 466        return hws;
 467}
 468
 469static const struct resource_create_funcs res_create_funcs = {
 470        .read_dce_straps = read_dce_straps,
 471        .create_audio = create_audio,
 472        .create_stream_encoder = dce100_stream_encoder_create,
 473        .create_hwseq = dce100_hwseq_create,
 474};
 475
 476#define mi_inst_regs(id) { \
 477        MI_DCE8_REG_LIST(id), \
 478        .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
 479}
 480static const struct dce_mem_input_registers mi_regs[] = {
 481                mi_inst_regs(0),
 482                mi_inst_regs(1),
 483                mi_inst_regs(2),
 484                mi_inst_regs(3),
 485                mi_inst_regs(4),
 486                mi_inst_regs(5),
 487};
 488
 489static const struct dce_mem_input_shift mi_shifts = {
 490                MI_DCE8_MASK_SH_LIST(__SHIFT),
 491                .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
 492};
 493
 494static const struct dce_mem_input_mask mi_masks = {
 495                MI_DCE8_MASK_SH_LIST(_MASK),
 496                .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
 497};
 498
 499static struct mem_input *dce100_mem_input_create(
 500        struct dc_context *ctx,
 501        uint32_t inst)
 502{
 503        struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
 504                                               GFP_KERNEL);
 505
 506        if (!dce_mi) {
 507                BREAK_TO_DEBUGGER();
 508                return NULL;
 509        }
 510
 511        dce_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
 512        dce_mi->wa.single_head_rdreq_dmif_limit = 2;
 513        return &dce_mi->base;
 514}
 515
 516static void dce100_transform_destroy(struct transform **xfm)
 517{
 518        kfree(TO_DCE_TRANSFORM(*xfm));
 519        *xfm = NULL;
 520}
 521
 522static struct transform *dce100_transform_create(
 523        struct dc_context *ctx,
 524        uint32_t inst)
 525{
 526        struct dce_transform *transform =
 527                kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
 528
 529        if (!transform)
 530                return NULL;
 531
 532        dce_transform_construct(transform, ctx, inst,
 533                                &xfm_regs[inst], &xfm_shift, &xfm_mask);
 534        return &transform->base;
 535}
 536
 537static struct input_pixel_processor *dce100_ipp_create(
 538        struct dc_context *ctx, uint32_t inst)
 539{
 540        struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
 541
 542        if (!ipp) {
 543                BREAK_TO_DEBUGGER();
 544                return NULL;
 545        }
 546
 547        dce_ipp_construct(ipp, ctx, inst,
 548                        &ipp_regs[inst], &ipp_shift, &ipp_mask);
 549        return &ipp->base;
 550}
 551
 552static const struct encoder_feature_support link_enc_feature = {
 553                .max_hdmi_deep_color = COLOR_DEPTH_121212,
 554                .max_hdmi_pixel_clock = 300000,
 555                .flags.bits.IS_HBR2_CAPABLE = true,
 556                .flags.bits.IS_TPS3_CAPABLE = true
 557};
 558
 559struct link_encoder *dce100_link_encoder_create(
 560        const struct encoder_init_data *enc_init_data)
 561{
 562        struct dce110_link_encoder *enc110 =
 563                kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
 564
 565        if (!enc110)
 566                return NULL;
 567
 568        dce110_link_encoder_construct(enc110,
 569                                      enc_init_data,
 570                                      &link_enc_feature,
 571                                      &link_enc_regs[enc_init_data->transmitter],
 572                                      &link_enc_aux_regs[enc_init_data->channel - 1],
 573                                      &link_enc_hpd_regs[enc_init_data->hpd_source]);
 574        return &enc110->base;
 575}
 576
 577struct output_pixel_processor *dce100_opp_create(
 578        struct dc_context *ctx,
 579        uint32_t inst)
 580{
 581        struct dce110_opp *opp =
 582                kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
 583
 584        if (!opp)
 585                return NULL;
 586
 587        dce110_opp_construct(opp,
 588                             ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
 589        return &opp->base;
 590}
 591
 592struct dce_aux *dce100_aux_engine_create(
 593        struct dc_context *ctx,
 594        uint32_t inst)
 595{
 596        struct aux_engine_dce110 *aux_engine =
 597                kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
 598
 599        if (!aux_engine)
 600                return NULL;
 601
 602        dce110_aux_engine_construct(aux_engine, ctx, inst,
 603                                    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 604                                    &aux_engine_regs[inst]);
 605
 606        return &aux_engine->base;
 607}
 608#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
 609
 610static const struct dce_i2c_registers i2c_hw_regs[] = {
 611                i2c_inst_regs(1),
 612                i2c_inst_regs(2),
 613                i2c_inst_regs(3),
 614                i2c_inst_regs(4),
 615                i2c_inst_regs(5),
 616                i2c_inst_regs(6),
 617};
 618
 619static const struct dce_i2c_shift i2c_shifts = {
 620                I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 621};
 622
 623static const struct dce_i2c_mask i2c_masks = {
 624                I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 625};
 626
 627struct dce_i2c_hw *dce100_i2c_hw_create(
 628        struct dc_context *ctx,
 629        uint32_t inst)
 630{
 631        struct dce_i2c_hw *dce_i2c_hw =
 632                kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
 633
 634        if (!dce_i2c_hw)
 635                return NULL;
 636
 637        dce100_i2c_hw_construct(dce_i2c_hw, ctx, inst,
 638                                    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
 639
 640        return dce_i2c_hw;
 641}
 642struct clock_source *dce100_clock_source_create(
 643        struct dc_context *ctx,
 644        struct dc_bios *bios,
 645        enum clock_source_id id,
 646        const struct dce110_clk_src_regs *regs,
 647        bool dp_clk_src)
 648{
 649        struct dce110_clk_src *clk_src =
 650                kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
 651
 652        if (!clk_src)
 653                return NULL;
 654
 655        if (dce110_clk_src_construct(clk_src, ctx, bios, id,
 656                        regs, &cs_shift, &cs_mask)) {
 657                clk_src->base.dp_clk_src = dp_clk_src;
 658                return &clk_src->base;
 659        }
 660
 661        BREAK_TO_DEBUGGER();
 662        return NULL;
 663}
 664
 665void dce100_clock_source_destroy(struct clock_source **clk_src)
 666{
 667        kfree(TO_DCE110_CLK_SRC(*clk_src));
 668        *clk_src = NULL;
 669}
 670
 671static void destruct(struct dce110_resource_pool *pool)
 672{
 673        unsigned int i;
 674
 675        for (i = 0; i < pool->base.pipe_count; i++) {
 676                if (pool->base.opps[i] != NULL)
 677                        dce110_opp_destroy(&pool->base.opps[i]);
 678
 679                if (pool->base.transforms[i] != NULL)
 680                        dce100_transform_destroy(&pool->base.transforms[i]);
 681
 682                if (pool->base.ipps[i] != NULL)
 683                        dce_ipp_destroy(&pool->base.ipps[i]);
 684
 685                if (pool->base.mis[i] != NULL) {
 686                        kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
 687                        pool->base.mis[i] = NULL;
 688                }
 689
 690                if (pool->base.timing_generators[i] != NULL)    {
 691                        kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
 692                        pool->base.timing_generators[i] = NULL;
 693                }
 694        }
 695
 696        for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
 697                if (pool->base.engines[i] != NULL)
 698                        dce110_engine_destroy(&pool->base.engines[i]);
 699                if (pool->base.hw_i2cs[i] != NULL) {
 700                        kfree(pool->base.hw_i2cs[i]);
 701                        pool->base.hw_i2cs[i] = NULL;
 702                }
 703                if (pool->base.sw_i2cs[i] != NULL) {
 704                        kfree(pool->base.sw_i2cs[i]);
 705                        pool->base.sw_i2cs[i] = NULL;
 706                }
 707        }
 708
 709        for (i = 0; i < pool->base.stream_enc_count; i++) {
 710                if (pool->base.stream_enc[i] != NULL)
 711                        kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
 712        }
 713
 714        for (i = 0; i < pool->base.clk_src_count; i++) {
 715                if (pool->base.clock_sources[i] != NULL)
 716                        dce100_clock_source_destroy(&pool->base.clock_sources[i]);
 717        }
 718
 719        if (pool->base.dp_clock_source != NULL)
 720                dce100_clock_source_destroy(&pool->base.dp_clock_source);
 721
 722        for (i = 0; i < pool->base.audio_count; i++)    {
 723                if (pool->base.audios[i] != NULL)
 724                        dce_aud_destroy(&pool->base.audios[i]);
 725        }
 726
 727        if (pool->base.clk_mgr != NULL)
 728                dce_clk_mgr_destroy(&pool->base.clk_mgr);
 729
 730        if (pool->base.abm != NULL)
 731                                dce_abm_destroy(&pool->base.abm);
 732
 733        if (pool->base.dmcu != NULL)
 734                        dce_dmcu_destroy(&pool->base.dmcu);
 735
 736        if (pool->base.irqs != NULL)
 737                dal_irq_service_destroy(&pool->base.irqs);
 738}
 739
 740static enum dc_status build_mapped_resource(
 741                const struct dc  *dc,
 742                struct dc_state *context,
 743                struct dc_stream_state *stream)
 744{
 745        struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
 746
 747        if (!pipe_ctx)
 748                return DC_ERROR_UNEXPECTED;
 749
 750        dce110_resource_build_pipe_hw_param(pipe_ctx);
 751
 752        resource_build_info_frame(pipe_ctx);
 753
 754        return DC_OK;
 755}
 756
 757bool dce100_validate_bandwidth(
 758        struct dc  *dc,
 759        struct dc_state *context)
 760{
 761        int i;
 762        bool at_least_one_pipe = false;
 763
 764        for (i = 0; i < dc->res_pool->pipe_count; i++) {
 765                if (context->res_ctx.pipe_ctx[i].stream)
 766                        at_least_one_pipe = true;
 767        }
 768
 769        if (at_least_one_pipe) {
 770                /* TODO implement when needed but for now hardcode max value*/
 771                context->bw.dce.dispclk_khz = 681000;
 772                context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ;
 773        } else {
 774                context->bw.dce.dispclk_khz = 0;
 775                context->bw.dce.yclk_khz = 0;
 776        }
 777
 778        return true;
 779}
 780
 781static bool dce100_validate_surface_sets(
 782                struct dc_state *context)
 783{
 784        int i;
 785
 786        for (i = 0; i < context->stream_count; i++) {
 787                if (context->stream_status[i].plane_count == 0)
 788                        continue;
 789
 790                if (context->stream_status[i].plane_count > 1)
 791                        return false;
 792
 793                if (context->stream_status[i].plane_states[0]->format
 794                                >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
 795                        return false;
 796        }
 797
 798        return true;
 799}
 800
 801enum dc_status dce100_validate_global(
 802                struct dc  *dc,
 803                struct dc_state *context)
 804{
 805        if (!dce100_validate_surface_sets(context))
 806                return DC_FAIL_SURFACE_VALIDATE;
 807
 808        return DC_OK;
 809}
 810
 811enum dc_status dce100_add_stream_to_ctx(
 812                struct dc *dc,
 813                struct dc_state *new_ctx,
 814                struct dc_stream_state *dc_stream)
 815{
 816        enum dc_status result = DC_ERROR_UNEXPECTED;
 817
 818        result = resource_map_pool_resources(dc, new_ctx, dc_stream);
 819
 820        if (result == DC_OK)
 821                result = resource_map_clock_resources(dc, new_ctx, dc_stream);
 822
 823        if (result == DC_OK)
 824                result = build_mapped_resource(dc, new_ctx, dc_stream);
 825
 826        return result;
 827}
 828
 829static void dce100_destroy_resource_pool(struct resource_pool **pool)
 830{
 831        struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
 832
 833        destruct(dce110_pool);
 834        kfree(dce110_pool);
 835        *pool = NULL;
 836}
 837
 838enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
 839{
 840
 841        if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
 842                return DC_OK;
 843
 844        return DC_FAIL_SURFACE_VALIDATE;
 845}
 846
 847static const struct resource_funcs dce100_res_pool_funcs = {
 848        .destroy = dce100_destroy_resource_pool,
 849        .link_enc_create = dce100_link_encoder_create,
 850        .validate_bandwidth = dce100_validate_bandwidth,
 851        .validate_plane = dce100_validate_plane,
 852        .add_stream_to_ctx = dce100_add_stream_to_ctx,
 853        .validate_global = dce100_validate_global
 854};
 855
 856static bool construct(
 857        uint8_t num_virtual_links,
 858        struct dc  *dc,
 859        struct dce110_resource_pool *pool)
 860{
 861        unsigned int i;
 862        struct dc_context *ctx = dc->ctx;
 863        struct dc_firmware_info info;
 864        struct dc_bios *bp;
 865
 866        ctx->dc_bios->regs = &bios_regs;
 867
 868        pool->base.res_cap = &res_cap;
 869        pool->base.funcs = &dce100_res_pool_funcs;
 870        pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
 871
 872        bp = ctx->dc_bios;
 873
 874        if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
 875                info.external_clock_source_frequency_for_dp != 0) {
 876                pool->base.dp_clock_source =
 877                                dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
 878
 879                pool->base.clock_sources[0] =
 880                                dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false);
 881                pool->base.clock_sources[1] =
 882                                dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
 883                pool->base.clock_sources[2] =
 884                                dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
 885                pool->base.clk_src_count = 3;
 886
 887        } else {
 888                pool->base.dp_clock_source =
 889                                dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true);
 890
 891                pool->base.clock_sources[0] =
 892                                dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
 893                pool->base.clock_sources[1] =
 894                                dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
 895                pool->base.clk_src_count = 2;
 896        }
 897
 898        if (pool->base.dp_clock_source == NULL) {
 899                dm_error("DC: failed to create dp clock source!\n");
 900                BREAK_TO_DEBUGGER();
 901                goto res_create_fail;
 902        }
 903
 904        for (i = 0; i < pool->base.clk_src_count; i++) {
 905                if (pool->base.clock_sources[i] == NULL) {
 906                        dm_error("DC: failed to create clock sources!\n");
 907                        BREAK_TO_DEBUGGER();
 908                        goto res_create_fail;
 909                }
 910        }
 911
 912        pool->base.clk_mgr = dce_clk_mgr_create(ctx,
 913                        &disp_clk_regs,
 914                        &disp_clk_shift,
 915                        &disp_clk_mask);
 916        if (pool->base.clk_mgr == NULL) {
 917                dm_error("DC: failed to create display clock!\n");
 918                BREAK_TO_DEBUGGER();
 919                goto res_create_fail;
 920        }
 921
 922        pool->base.dmcu = dce_dmcu_create(ctx,
 923                        &dmcu_regs,
 924                        &dmcu_shift,
 925                        &dmcu_mask);
 926        if (pool->base.dmcu == NULL) {
 927                dm_error("DC: failed to create dmcu!\n");
 928                BREAK_TO_DEBUGGER();
 929                goto res_create_fail;
 930        }
 931
 932        pool->base.abm = dce_abm_create(ctx,
 933                                &abm_regs,
 934                                &abm_shift,
 935                                &abm_mask);
 936        if (pool->base.abm == NULL) {
 937                dm_error("DC: failed to create abm!\n");
 938                BREAK_TO_DEBUGGER();
 939                goto res_create_fail;
 940        }
 941
 942        {
 943                struct irq_service_init_data init_data;
 944                init_data.ctx = dc->ctx;
 945                pool->base.irqs = dal_irq_service_dce110_create(&init_data);
 946                if (!pool->base.irqs)
 947                        goto res_create_fail;
 948        }
 949
 950        /*************************************************
 951        *  Resource + asic cap harcoding                *
 952        *************************************************/
 953        pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
 954        pool->base.pipe_count = res_cap.num_timing_generator;
 955        pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
 956        dc->caps.max_downscale_ratio = 200;
 957        dc->caps.i2c_speed_in_khz = 40;
 958        dc->caps.max_cursor_size = 128;
 959        dc->caps.dual_link_dvi = true;
 960        dc->caps.disable_dp_clk_share = true;
 961        for (i = 0; i < pool->base.pipe_count; i++) {
 962                pool->base.timing_generators[i] =
 963                        dce100_timing_generator_create(
 964                                ctx,
 965                                i,
 966                                &dce100_tg_offsets[i]);
 967                if (pool->base.timing_generators[i] == NULL) {
 968                        BREAK_TO_DEBUGGER();
 969                        dm_error("DC: failed to create tg!\n");
 970                        goto res_create_fail;
 971                }
 972
 973                pool->base.mis[i] = dce100_mem_input_create(ctx, i);
 974                if (pool->base.mis[i] == NULL) {
 975                        BREAK_TO_DEBUGGER();
 976                        dm_error(
 977                                "DC: failed to create memory input!\n");
 978                        goto res_create_fail;
 979                }
 980
 981                pool->base.ipps[i] = dce100_ipp_create(ctx, i);
 982                if (pool->base.ipps[i] == NULL) {
 983                        BREAK_TO_DEBUGGER();
 984                        dm_error(
 985                                "DC: failed to create input pixel processor!\n");
 986                        goto res_create_fail;
 987                }
 988
 989                pool->base.transforms[i] = dce100_transform_create(ctx, i);
 990                if (pool->base.transforms[i] == NULL) {
 991                        BREAK_TO_DEBUGGER();
 992                        dm_error(
 993                                "DC: failed to create transform!\n");
 994                        goto res_create_fail;
 995                }
 996
 997                pool->base.opps[i] = dce100_opp_create(ctx, i);
 998                if (pool->base.opps[i] == NULL) {
 999                        BREAK_TO_DEBUGGER();
1000                        dm_error(
1001                                "DC: failed to create output pixel processor!\n");
1002                        goto res_create_fail;
1003                }
1004        }
1005
1006        for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1007                pool->base.engines[i] = dce100_aux_engine_create(ctx, i);
1008                if (pool->base.engines[i] == NULL) {
1009                        BREAK_TO_DEBUGGER();
1010                        dm_error(
1011                                "DC:failed to create aux engine!!\n");
1012                        goto res_create_fail;
1013                }
1014                pool->base.hw_i2cs[i] = dce100_i2c_hw_create(ctx, i);
1015                if (pool->base.hw_i2cs[i] == NULL) {
1016                        BREAK_TO_DEBUGGER();
1017                        dm_error(
1018                                "DC:failed to create i2c engine!!\n");
1019                        goto res_create_fail;
1020                }
1021                pool->base.sw_i2cs[i] = NULL;
1022        }
1023
1024        dc->caps.max_planes =  pool->base.pipe_count;
1025
1026        if (!resource_construct(num_virtual_links, dc, &pool->base,
1027                        &res_create_funcs))
1028                goto res_create_fail;
1029
1030        /* Create hardware sequencer */
1031        dce100_hw_sequencer_construct(dc);
1032        return true;
1033
1034res_create_fail:
1035        destruct(pool);
1036
1037        return false;
1038}
1039
1040struct resource_pool *dce100_create_resource_pool(
1041        uint8_t num_virtual_links,
1042        struct dc  *dc)
1043{
1044        struct dce110_resource_pool *pool =
1045                kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1046
1047        if (!pool)
1048                return NULL;
1049
1050        if (construct(num_virtual_links, dc, pool))
1051                return &pool->base;
1052
1053        BREAK_TO_DEBUGGER();
1054        return NULL;
1055}
1056
1057