From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E947BC433EF for ; Thu, 30 Sep 2021 02:00:20 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A6A3D615A7 for ; Thu, 30 Sep 2021 02:00:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A6A3D615A7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4D2AB6EB1C; Thu, 30 Sep 2021 02:00:20 +0000 (UTC) Received: from mail-oi1-x22f.google.com (mail-oi1-x22f.google.com [IPv6:2607:f8b0:4864:20::22f]) by gabe.freedesktop.org (Postfix) with ESMTPS id 782F16EB1C for ; Thu, 30 Sep 2021 02:00:18 +0000 (UTC) Received: by mail-oi1-x22f.google.com with SMTP id 24so5442947oix.0 for ; Wed, 29 Sep 2021 19:00:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=PtJUKeIUfRTxkedVY5eMUR29Dm7+pNKfKvT41scq+Tw=; b=qn51fslHpLOkSZ5mTfzSt9PV44jh+S1gP25IyCjRzGZyJhJh95F/8Ab9GgBuGvgUQI R8R8Dj4+UFOeMlophGlSOxf3Ft+/7INVrrGiBzhhp+PcS/YhEGbe8KMzCyST/ivR5s0k BciOfy5mjZz8hd6Lgrv2Kr3qksRsY897rYxDGLm8f/XjZmXspRaFJd7W9E9V5ZCZ6tot ApZ34gXv8457NEusCcrTJsLU6zB+ymceJgqENhTq1A+A6OTovcJ7UN2lM+B057p8TCaQ ev7D8ZtUs/4i7pHEY9HjeeWLkIrAAp2IAJ1giCtDfhS7xlQQF2gJpbI4mdEOBgiqxLOA oEpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=PtJUKeIUfRTxkedVY5eMUR29Dm7+pNKfKvT41scq+Tw=; b=NyA+KJ2GSQ58edc0npXJKZvZZyA9UmIIFNeMniB2dz8giflciJrJnHR5RMLI1OZnLe qXJRsVTl9RDSDw6zAOHg8iObXU0uwUvWKK0gleFeD5Jy4MAxP7cCshRerZpcObZuAexx PIktd6rSTw/lZtmkX0jsOyXlg3upREOsxawX6V8iQX4BGzn/9jTuKQgduCf260IRNvh5 q7Sw7/QmEb7giIvxbQGd7XdqDIx5f5IkwRglB0L3xxrLfEky+DAFg/3GsBc4PytJMZZy IGLmaPdDmk30lDB2wwn+NR+3TxiftwOMayEq4Ln6kequ0TPfVgAmYrFJJLsART82Y8wQ zcYQ== X-Gm-Message-State: AOAM5336PP7SVjMMIfEynRkt+Zl1X7NHWCKHWEw5xmljcGy4RDrvjogy yQkyfu1ri203pQBbTq0kVsH6KGskjyAV9N6YUiI7bfNz X-Google-Smtp-Source: ABdhPJzQZb5bpjtxQu7OCU06mvt/sHn7ExkiKh0VlVJsRCC/SBIM979EVnypkqLOU+aSnHsoUvbDZwHkd2hRmx5NanI= X-Received: by 2002:a05:6808:1141:: with SMTP id u1mr637717oiu.123.1632967217034; Wed, 29 Sep 2021 19:00:17 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Alex Deucher Date: Wed, 29 Sep 2021 22:00:04 -0400 Message-ID: Subject: Re: [PATCH 02/02 v2] drm/amd/display: add cyan_skillfish display support To: Mike Lothian Cc: "Liu, Zhan" , "amd-gfx@lists.freedesktop.org" , "Liu, Charlene" , "Deucher, Alexander" , "Wentland, Harry" , "Pillai, Aurabindo" Content-Type: text/plain; charset="UTF-8" X-BeenThere: amd-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Discussion list for AMD gfx List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: amd-gfx-bounces@lists.freedesktop.org Sender: "amd-gfx" On Wed, Sep 29, 2021 at 7:23 PM Mike Lothian wrote: > > Hi > > This patch is causing a failure for me when building with clang: > > > Enable DCN201 support in DC (DRM_AMD_DC_DCN201) [Y/n/?] (NEW) y > Enable HDCP support in DC (DRM_AMD_DC_HDCP) [Y/n/?] y > AMD DC support for Southern Islands ASICs (DRM_AMD_DC_SI) [N/y/?] n > Enable secure display support (DRM_AMD_SECURE_DISPLAY) [Y/n/?] y > DESCEND objtool > CALL scripts/atomic/check-atomics.sh > CALL scripts/checksyscalls.sh > CHK include/generated/compile.h > UPD kernel/config_data > GZIP kernel/config_data.gz > CC kernel/configs.o > AR kernel/built-in.a > CC drivers/gpu/drm/amd/amdgpu/../display/dc/clk_mgr/clk_mgr.o > CC drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_optc.o > clang-12: error: unknown argument: '-mpreferred-stack-boundary=4' > make[4]: *** [scripts/Makefile.build:278: > drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_optc.o] Error 1 > make[4]: *** Waiting for unfinished jobs.... > make[3]: *** [scripts/Makefile.build:540: drivers/gpu/drm/amd/amdgpu] Error 2 > make[2]: *** [scripts/Makefile.build:540: drivers/gpu/drm] Error 2 > make[1]: *** [scripts/Makefile.build:540: drivers/gpu] Error 2 > make: *** [Makefile:1868: drivers] Error 2 The Makefiles for the new stuff added probably need to be fixed up for clang like the other Makefiles. I can take a look tomorrow. Alex > > On Mon, 27 Sept 2021 at 22:16, Liu, Zhan wrote: > > > > [Public] > > > > [Why] > > add display related cyan_skillfish files in. > > > > makefile controlled by CONFIG_DRM_AMD_DC_DCN201 flag. > > > > Signed-off-by: Charlene Liu > > Signed-off-by: Zhan Liu > > Reviewed-by: Charlene Liu > > Acked-by: Jun Lei > > --- > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > > index 1d6cc93..0c669e4 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > > @@ -1968,6 +1968,9 @@ > > case CHIP_VANGOGH: > > chip_name = "vangogh"; > > break; > > + case CHIP_CYAN_SKILLFISH: > > + chip_name = "cyan_skillfish"; > > + break; > > case CHIP_YELLOW_CARP: > > chip_name = "yellow_carp"; > > break; > > @@ -3240,6 +3243,7 @@ > > case CHIP_NAVI14: > > case CHIP_NAVI12: > > case CHIP_RENOIR: > > + case CHIP_CYAN_SKILLFISH: > > case CHIP_SIENNA_CICHLID: > > case CHIP_NAVY_FLOUNDER: > > case CHIP_DIMGREY_CAVEFISH: > > diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c > > index ff80786..d9a10ec 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/nv.c > > +++ b/drivers/gpu/drm/amd/amdgpu/nv.c > > @@ -906,6 +906,8 @@ > > } > > if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) > > amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); > > + else if (amdgpu_device_has_dc_support(adev)) > > + amdgpu_device_ip_block_add(adev, &dm_ip_block); > > amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); > > amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block); > > break; > > diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig > > index 7dffc04..fb074a6 100644 > > --- a/drivers/gpu/drm/amd/display/Kconfig > > +++ b/drivers/gpu/drm/amd/display/Kconfig > > @@ -17,6 +17,15 @@ > > help > > Raven, Navi, and newer family support for display engine > > > > +config DRM_AMD_DC_DCN201 > > + bool "Enable DCN201 support in DC" > > + default y > > + depends on DRM_AMD_DC && X86 > > + depends on DRM_AMD_DC_DCN > > + help > > + Choose this option if you want to have > > + 201 support for display engine > > + > > config DRM_AMD_DC_HDCP > > bool "Enable HDCP support in DC" > > depends on DRM_AMD_DC > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > > index e676d0a..3c7a8f8 100644 > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > > @@ -1352,6 +1352,9 @@ > > case CHIP_YELLOW_CARP: > > init_data.flags.gpu_vm_support = true; > > break; > > + case CHIP_CYAN_SKILLFISH: > > + init_data.flags.disable_dmcu = true; > > + break; > > default: > > break; > > } > > @@ -1647,6 +1650,7 @@ > > case CHIP_BEIGE_GOBY: > > case CHIP_VANGOGH: > > case CHIP_YELLOW_CARP: > > + case CHIP_CYAN_SKILLFISH: > > return 0; > > case CHIP_NAVI12: > > fw_name_dmcu = FIRMWARE_NAVI12_DMCU; > > @@ -4182,6 +4186,7 @@ > > case CHIP_DIMGREY_CAVEFISH: > > case CHIP_BEIGE_GOBY: > > case CHIP_VANGOGH: > > + case CHIP_CYAN_SKILLFISH: > > case CHIP_YELLOW_CARP: > > if (dcn10_register_irq_handlers(dm->adev)) { > > DRM_ERROR("DM: Failed to initialize IRQ\n"); > > @@ -4359,6 +4364,11 @@ > > adev->mode_info.num_hpd = 4; > > adev->mode_info.num_dig = 4; > > break; > > + case CHIP_CYAN_SKILLFISH: > > + adev->mode_info.num_crtc = 2; > > + adev->mode_info.num_hpd = 2; > > + adev->mode_info.num_dig = 2; > > + break; > > case CHIP_NAVI14: > > case CHIP_DIMGREY_CAVEFISH: > > adev->mode_info.num_crtc = 5; > > diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile > > index 943fcb1..520f585 100644 > > --- a/drivers/gpu/drm/amd/display/dc/Makefile > > +++ b/drivers/gpu/drm/amd/display/dc/Makefile > > @@ -30,6 +30,9 @@ > > DC_LIBS += dsc > > DC_LIBS += dcn10 dml > > DC_LIBS += dcn21 > > +ifdef CONFIG_DRM_AMD_DC_DCN201 > > +DC_LIBS += dcn201 > > +endif > > DC_LIBS += dcn30 > > DC_LIBS += dcn301 > > DC_LIBS += dcn302 > > diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c > > index cb3fd44..eedc553 100644 > > --- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c > > +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c > > @@ -70,6 +70,7 @@ > > case DCN_VERSION_1_01: > > case DCN_VERSION_2_0: > > case DCN_VERSION_2_1: > > + case DCN_VERSION_2_01: > > case DCN_VERSION_3_0: > > case DCN_VERSION_3_01: > > case DCN_VERSION_3_02: > > diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile > > index 7fa0b00..7f70985 100644 > > --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile > > +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile > > @@ -93,6 +93,17 @@ > > > > AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN20) > > > > +ifdef CONFIG_DRM_AMD_DC_DCN201 > > +############################################################################### > > +# DCN201 > > +############################################################################### > > +CLK_MGR_DCN201 = dcn201_clk_mgr.o > > + > > +AMD_DAL_CLK_MGR_DCN201 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn201/,$(CLK_MGR_DCN201)) > > + > > +AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN201) > > +endif > > + > > ############################################################################### > > # DCN21 > > ############################################################################### > > diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c > > index bb31541..421f513 100644 > > --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c > > +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c > > @@ -39,6 +39,7 @@ > > #include "dcn10/rv2_clk_mgr.h" > > #include "dcn20/dcn20_clk_mgr.h" > > #include "dcn21/rn_clk_mgr.h" > > +#include "dcn201/dcn201_clk_mgr.h" > > #include "dcn30/dcn30_clk_mgr.h" > > #include "dcn301/vg_clk_mgr.h" > > #include "dcn31/dcn31_clk_mgr.h" > > @@ -256,6 +257,12 @@ > > dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); > > return &clk_mgr->base; > > } > > +#if defined(CONFIG_DRM_AMD_DC_DCN201) > > + if (asic_id.chip_id == DEVICE_ID_NV_13FE) { > > + dcn201_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); > > + return &clk_mgr->base; > > + } > > +#endif > > dcn20_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); > > return &clk_mgr->base; > > } > > diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c > > new file mode 100644 > > index 0000000..46e7efe > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c > > @@ -0,0 +1,260 @@ > > +/* > > + * Copyright 2018 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#include "reg_helper.h" > > +#include "core_types.h" > > +#include "dccg.h" > > +#include "clk_mgr_internal.h" > > +#include "dcn201_clk_mgr.h" > > +#include "dcn20/dcn20_clk_mgr.h" > > +#include "dce100/dce_clk_mgr.h" > > +#include "reg_helper.h" > > +#include "core_types.h" > > +#include "dm_helpers.h" > > +#include "dm_services.h" > > + > > +#include "cyan_skillfish_ip_offset.h" > > +#include "dcn/dcn_2_0_3_offset.h" > > +#include "dcn/dcn_2_0_3_sh_mask.h" > > +#include "clk/clk_11_0_1_offset.h" > > +#include "clk/clk_11_0_1_sh_mask.h" > > + > > +#define REG(reg) \ > > + (clk_mgr->regs->reg) > > + > > +#define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg > > + > > +#define BASE(seg) BASE_INNER(seg) > > + > > +#define SR(reg_name)\ > > + .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \ > > + mm ## reg_name > > + > > +#define CLK_BASE_INNER(seg) \ > > + CLK_BASE__INST0_SEG ## seg > > + > > +#undef FN > > +#define FN(reg_name, field_name) \ > > + clk_mgr->clk_mgr_shift->field_name, clk_mgr->clk_mgr_mask->field_name > > + > > +#define CTX \ > > + clk_mgr->base.ctx > > +#define DC_LOGGER \ > > + clk_mgr->base.ctx->logger > > + > > +static const struct clk_mgr_registers clk_mgr_regs = { > > + CLK_COMMON_REG_LIST_DCN_201() > > +}; > > + > > +static const struct clk_mgr_shift clk_mgr_shift = { > > + CLK_COMMON_MASK_SH_LIST_DCN201_BASE(__SHIFT) > > +}; > > + > > +static const struct clk_mgr_mask clk_mgr_mask = { > > + CLK_COMMON_MASK_SH_LIST_DCN201_BASE(_MASK) > > +}; > > + > > +void dcn201_update_clocks_vbios(struct clk_mgr *clk_mgr, > > + struct dc_state *context, > > + bool safe_to_lower) > > +{ > > + struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk; > > + > > + bool update_dppclk = false; > > + bool update_dispclk = false; > > + > > + if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->clks.dppclk_khz)) { > > + clk_mgr->clks.dppclk_khz = new_clocks->dppclk_khz; > > + update_dppclk = true; > > + } > > + > > + if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr->clks.dispclk_khz)) { > > + clk_mgr->clks.dispclk_khz = new_clocks->dispclk_khz; > > + update_dispclk = true; > > + } > > + > > + if (update_dppclk || update_dispclk) { > > + struct bp_set_dce_clock_parameters dce_clk_params; > > + struct dc_bios *bp = clk_mgr->ctx->dc_bios; > > + > > + if (update_dispclk) { > > + memset(&dce_clk_params, 0, sizeof(dce_clk_params)); > > + dce_clk_params.target_clock_frequency = new_clocks->dispclk_khz; > > + dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; > > + dce_clk_params.clock_type = DCECLOCK_TYPE_DISPLAY_CLOCK; > > + bp->funcs->set_dce_clock(bp, &dce_clk_params); > > + } > > + /* currently there is no DCECLOCK_TYPE_DPPCLK type defined in VBIOS interface. > > + * vbios program DPPCLK to the same DispCLK limitation > > + */ > > + } > > +} > > + > > +static void dcn201_init_clocks(struct clk_mgr *clk_mgr) > > +{ > > + memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); > > + clk_mgr->clks.p_state_change_support = true; > > + clk_mgr->clks.prev_p_state_change_support = true; > > + clk_mgr->clks.max_supported_dppclk_khz = 1200000; > > + clk_mgr->clks.max_supported_dispclk_khz = 1200000; > > +} > > + > > +static void dcn201_update_clocks(struct clk_mgr *clk_mgr_base, > > + struct dc_state *context, > > + bool safe_to_lower) > > +{ > > + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); > > + struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk; > > + struct dc *dc = clk_mgr_base->ctx->dc; > > + int display_count; > > + bool update_dppclk = false; > > + bool update_dispclk = false; > > + bool enter_display_off = false; > > + bool dpp_clock_lowered = false; > > + bool force_reset = false; > > + bool p_state_change_support; > > + int total_plane_count; > > + > > + if (dc->work_arounds.skip_clock_update) > > + return; > > + > > + if (clk_mgr_base->clks.dispclk_khz == 0 || > > + dc->debug.force_clock_mode & 0x1) { > > + force_reset = true; > > + > > + dcn2_read_clocks_from_hw_dentist(clk_mgr_base); > > + } > > + > > + display_count = clk_mgr_helper_get_active_display_cnt(dc, context); > > + > > + if (display_count == 0) > > + enter_display_off = true; > > + > > + if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, clk_mgr_base->clks.phyclk_khz)) > > + clk_mgr_base->clks.phyclk_khz = new_clocks->phyclk_khz; > > + > > + if (dc->debug.force_min_dcfclk_mhz > 0) > > + new_clocks->dcfclk_khz = (new_clocks->dcfclk_khz > (dc->debug.force_min_dcfclk_mhz * 1000)) ? > > + new_clocks->dcfclk_khz : (dc->debug.force_min_dcfclk_mhz * 1000); > > + > > + if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, clk_mgr_base->clks.dcfclk_khz)) > > + clk_mgr_base->clks.dcfclk_khz = new_clocks->dcfclk_khz; > > + > > + if (should_set_clock(safe_to_lower, > > + new_clocks->dcfclk_deep_sleep_khz, clk_mgr_base->clks.dcfclk_deep_sleep_khz)) > > + clk_mgr_base->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz; > > + > > + if (should_set_clock(safe_to_lower, new_clocks->socclk_khz, clk_mgr_base->clks.socclk_khz)) > > + clk_mgr_base->clks.socclk_khz = new_clocks->socclk_khz; > > + > > + total_plane_count = clk_mgr_helper_get_active_plane_cnt(dc, context); > > + p_state_change_support = new_clocks->p_state_change_support || (total_plane_count == 0); > > + if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) { > > + clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support; > > + clk_mgr_base->clks.p_state_change_support = p_state_change_support; > > + } > > + > > + if (should_set_clock(safe_to_lower, new_clocks->dramclk_khz, clk_mgr_base->clks.dramclk_khz)) > > + clk_mgr_base->clks.dramclk_khz = new_clocks->dramclk_khz; > > + > > + if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) { > > + if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz) > > + dpp_clock_lowered = true; > > + clk_mgr->base.clks.dppclk_khz = new_clocks->dppclk_khz; > > + > > + update_dppclk = true; > > + } > > + > > + if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { > > + clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; > > + > > + update_dispclk = true; > > + } > > + > > + if (dc->config.forced_clocks == false || (force_reset && safe_to_lower)) { > > + if (dpp_clock_lowered) { > > + dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); > > + dcn20_update_clocks_update_dentist(clk_mgr, context); > > + } else { > > + if (update_dppclk || update_dispclk) > > + dcn20_update_clocks_update_dentist(clk_mgr, context); > > + if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz) > > + dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); > > + } > > + } > > +} > > + > > +struct clk_mgr_funcs dcn201_funcs = { > > + .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, > > + .update_clocks = dcn201_update_clocks, > > + .init_clocks = dcn201_init_clocks, > > + .get_clock = dcn2_get_clock, > > +}; > > + > > +void dcn201_clk_mgr_construct(struct dc_context *ctx, > > + struct clk_mgr_internal *clk_mgr, > > + struct pp_smu_funcs *pp_smu, > > + struct dccg *dccg) > > +{ > > + struct dc_debug_options *debug = &ctx->dc->debug; > > + struct dc_bios *bp = ctx->dc_bios; > > + clk_mgr->base.ctx = ctx; > > + clk_mgr->base.funcs = &dcn201_funcs; > > + clk_mgr->regs = &clk_mgr_regs; > > + clk_mgr->clk_mgr_shift = &clk_mgr_shift; > > + clk_mgr->clk_mgr_mask = &clk_mgr_mask; > > + > > + clk_mgr->dccg = dccg; > > + > > + clk_mgr->dfs_bypass_disp_clk = 0; > > + > > + clk_mgr->dprefclk_ss_percentage = 0; > > + clk_mgr->dprefclk_ss_divider = 1000; > > + clk_mgr->ss_on_dprefclk = false; > > + > > + if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) { > > + dcn201_funcs.update_clocks = dcn2_update_clocks_fpga; > > + clk_mgr->base.dprefclk_khz = 600000; > > + clk_mgr->base.dentist_vco_freq_khz = 3000000; > > + } else { > > + clk_mgr->base.dprefclk_khz = REG_READ(CLK4_CLK2_CURRENT_CNT); > > + clk_mgr->base.dprefclk_khz *= 100; > > + > > + if (clk_mgr->base.dprefclk_khz == 0) > > + clk_mgr->base.dprefclk_khz = 600000; > > + > > + REG_GET(CLK4_CLK_PLL_REQ, FbMult_int, &clk_mgr->base.dentist_vco_freq_khz); > > + clk_mgr->base.dentist_vco_freq_khz *= 100000; > > + > > + if (clk_mgr->base.dentist_vco_freq_khz == 0) > > + clk_mgr->base.dentist_vco_freq_khz = 3000000; > > + } > > + > > + if (!debug->disable_dfs_bypass && bp->integrated_info) > > + if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) > > + clk_mgr->dfs_bypass_enabled = true; > > + > > + dce_clock_read_ss_info(clk_mgr); > > +} > > \ No newline at end of file > > diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.h > > new file mode 100644 > > index 0000000..ae463ba > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.h > > @@ -0,0 +1,34 @@ > > +/* > > + * Copyright 2018 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#ifndef __DCN201_CLK_MGR_H__ > > +#define __DCN201_CLK_MGR_H__ > > + > > +void dcn201_clk_mgr_construct(struct dc_context *ctx, > > + struct clk_mgr_internal *clk_mgr, > > + struct pp_smu_funcs *pp_smu, > > + struct dccg *dccg); > > + > > +#endif //__DCN201_CLK_MGR_H__ > > \ No newline at end of file > > diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c > > index adc656f..fc490b7 100644 > > --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c > > +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c > > @@ -56,6 +56,7 @@ > > #include "dcn10/dcn10_resource.h" > > #include "dcn20/dcn20_resource.h" > > #include "dcn21/dcn21_resource.h" > > +#include "dcn201/dcn201_resource.h" > > #include "dcn30/dcn30_resource.h" > > #include "dcn301/dcn301_resource.h" > > #include "dcn302/dcn302_resource.h" > > @@ -130,6 +131,10 @@ > > > > case FAMILY_NV: > > dc_version = DCN_VERSION_2_0; > > + if (asic_id.chip_id == DEVICE_ID_NV_13FE) { > > + dc_version = DCN_VERSION_2_01; > > + break; > > + } > > if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev)) > > dc_version = DCN_VERSION_3_0; > > if (ASICREV_IS_DIMGREY_CAVEFISH_P(asic_id.hw_internal_rev)) > > @@ -219,6 +224,11 @@ > > case DCN_VERSION_2_1: > > res_pool = dcn21_create_resource_pool(init_data, dc); > > break; > > +#if defined(CONFIG_DRM_AMD_DC_DCN201) > > + case DCN_VERSION_2_01: > > + res_pool = dcn201_create_resource_pool(init_data, dc); > > + break; > > +#endif > > case DCN_VERSION_3_0: > > res_pool = dcn30_create_resource_pool(init_data, dc); > > break; > > diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h > > index 3139285..692fa23 100644 > > --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h > > +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h > > @@ -76,6 +76,15 @@ > > SRII(PIXEL_RATE_CNTL, OTG, 4),\ > > SRII(PIXEL_RATE_CNTL, OTG, 5) > > > > +#define CS_COMMON_REG_LIST_DCN201(index, pllid) \ > > + SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ > > + SRII(PHASE, DP_DTO, 0),\ > > + SRII(PHASE, DP_DTO, 1),\ > > + SRII(MODULO, DP_DTO, 0),\ > > + SRII(MODULO, DP_DTO, 1),\ > > + SRII(PIXEL_RATE_CNTL, OTG, 0),\ > > + SRII(PIXEL_RATE_CNTL, OTG, 1) > > + > > #define CS_COMMON_REG_LIST_DCN2_1(index, pllid) \ > > SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ > > SRII(PHASE, DP_DTO, 0),\ > > diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h > > index 0464a8f..296b2f8 100644 > > --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h > > +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h > > @@ -70,6 +70,10 @@ > > SRII(PIXEL_RATE_CNTL, blk, 4), \ > > SRII(PIXEL_RATE_CNTL, blk, 5) > > > > +#define HWSEQ_PIXEL_RATE_REG_LIST_201(blk) \ > > + SRII(PIXEL_RATE_CNTL, blk, 0), \ > > + SRII(PIXEL_RATE_CNTL, blk, 1) > > + > > #define HWSEQ_PHYPLL_REG_LIST(blk) \ > > SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \ > > SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1), \ > > @@ -94,6 +98,10 @@ > > SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \ > > SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5) > > > > +#define HWSEQ_PHYPLL_REG_LIST_201(blk) \ > > + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \ > > + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1) > > + > > #define HWSEQ_DCE11_REG_LIST_BASE() \ > > SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \ > > SR(DCFEV_CLOCK_CONTROL), \ > > @@ -337,6 +345,29 @@ > > SR(D6VGA_CONTROL), \ > > SR(DC_IP_REQUEST_CNTL) > > > > +#define HWSEQ_DCN201_REG_LIST()\ > > + HWSEQ_DCN_REG_LIST(), \ > > + HWSEQ_PIXEL_RATE_REG_LIST_201(OTG), \ > > + HWSEQ_PHYPLL_REG_LIST_201(OTG), \ > > + SR(MICROSECOND_TIME_BASE_DIV), \ > > + SR(MILLISECOND_TIME_BASE_DIV), \ > > + SR(DISPCLK_FREQ_CHANGE_CNTL), \ > > + SR(RBBMIF_TIMEOUT_DIS), \ > > + SR(RBBMIF_TIMEOUT_DIS_2), \ > > + SR(DCHUBBUB_CRC_CTRL), \ > > + SR(DPP_TOP0_DPP_CRC_CTRL), \ > > + SR(DPP_TOP0_DPP_CRC_VAL_B_A), \ > > + SR(DPP_TOP0_DPP_CRC_VAL_R_G), \ > > + SR(MPC_CRC_CTRL), \ > > + SR(MPC_CRC_RESULT_GB), \ > > + SR(MPC_CRC_RESULT_C), \ > > + SR(MPC_CRC_RESULT_AR), \ > > + SR(AZALIA_AUDIO_DTO), \ > > + SR(AZALIA_CONTROLLER_CLOCK_GATING), \ > > + MMHUB_SR(MC_VM_FB_LOCATION_BASE), \ > > + MMHUB_SR(MC_VM_FB_LOCATION_TOP), \ > > + MMHUB_SR(MC_VM_FB_OFFSET) > > + > > #define HWSEQ_DCN30_REG_LIST()\ > > HWSEQ_DCN2_REG_LIST(),\ > > HWSEQ_DCN_REG_LIST(), \ > > @@ -637,6 +668,9 @@ > > uint32_t DMU_MEM_PWR_CNTL; > > uint32_t MMHUBBUB_MEM_PWR_CNTL; > > uint32_t DCHUBBUB_ARB_HOSTVM_CNTL; > > + uint32_t MC_VM_FB_LOCATION_BASE; > > + uint32_t MC_VM_FB_LOCATION_TOP; > > + uint32_t MC_VM_FB_OFFSET; > > }; > > /* set field name */ > > #define HWS_SF(blk_name, reg_name, field_name, post_fix)\ > > @@ -872,6 +906,11 @@ > > HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ > > HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh) > > > > +#define HWSEQ_DCN201_MASK_SH_LIST(mask_sh)\ > > + HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ > > + HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ > > + HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh) > > + > > #define HWSEQ_DCN30_MASK_SH_LIST(mask_sh)\ > > HWSEQ_DCN2_MASK_SH_LIST(mask_sh), \ > > HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \ > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h > > index 1ca4907..e2508d6 100644 > > --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h > > +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h > > @@ -60,6 +60,16 @@ > > SRI(CURSOR_HOT_SPOT, CURSOR0_, id), \ > > SRI(CURSOR_DST_OFFSET, CURSOR0_, id) > > > > +#define IPP_REG_LIST_DCN201(id) \ > > + IPP_REG_LIST_DCN(id), \ > > + SRI(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR0_, id), \ > > + SRI(CURSOR_SURFACE_ADDRESS, CURSOR0_, id), \ > > + SRI(CURSOR_SIZE, CURSOR0_, id), \ > > + SRI(CURSOR_CONTROL, CURSOR0_, id), \ > > + SRI(CURSOR_POSITION, CURSOR0_, id), \ > > + SRI(CURSOR_HOT_SPOT, CURSOR0_, id), \ > > + SRI(CURSOR_DST_OFFSET, CURSOR0_, id) > > + > > #define CURSOR0_CURSOR_CONTROL__CURSOR_2X_MAGNIFY__SHIFT 0x4 > > #define CURSOR0_CURSOR_CONTROL__CURSOR_2X_MAGNIFY_MASK 0x00000010L > > > > @@ -116,6 +126,23 @@ > > IPP_SF(CURSOR0_0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \ > > IPP_SF(CURSOR0_0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh) > > > > +#define IPP_MASK_SH_LIST_DCN201(mask_sh) \ > > + IPP_MASK_SH_LIST_DCN(mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_SURFACE_ADDRESS, CURSOR_SURFACE_ADDRESS, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_SIZE, CURSOR_WIDTH, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_SIZE, CURSOR_HEIGHT, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_2X_MAGNIFY, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_POSITION, CURSOR_X_POSITION, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_POSITION, CURSOR_Y_POSITION, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_X, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \ > > + IPP_SF(CURSOR0_0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh) > > + > > #define IPP_DCN10_REG_FIELD_LIST(type) \ > > type CNVC_SURFACE_PIXEL_FORMAT; \ > > type CNVC_BYPASS; \ > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c > > index aeb868a..899d0086 100644 > > --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c > > +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c > > @@ -3167,6 +3167,9 @@ > > if (!context->res_ctx.pipe_ctx[i].stream) > > continue; > > > > + if (dc->ctx->dce_version == DCN_VERSION_2_01) > > + cstate_en = false; > > + > > context->bw_ctx.dml.funcs.rq_dlg_get_dlg_reg(&context->bw_ctx.dml, > > &context->res_ctx.pipe_ctx[i].dlg_regs, > > &context->res_ctx.pipe_ctx[i].ttu_regs, > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/Makefile b/drivers/gpu/drm/amd/display/dc/dcn201/Makefile > > new file mode 100644 > > index 0000000..d98d697 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/Makefile > > @@ -0,0 +1,33 @@ > > +# SPDX-License-Identifier: MIT > > +# > > +# Makefile for DCN. > > +DCN201 = dcn201_init.o dcn201_resource.o dcn201_hwseq.o \ > > + dcn201_hubbub.o\ > > + dcn201_mpc.o dcn201_hubp.o dcn201_opp.o dcn201_optc.o dcn201_dpp.o \ > > + dcn201_dccg.o dcn201_link_encoder.o > > + > > +ifdef CONFIG_X86 > > +CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o := -mhard-float -msse > > +endif > > + > > +ifdef CONFIG_PPC64 > > +CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o := -mhard-float -maltivec > > +endif > > + > > +ifeq ($(call cc-ifversion, -lt, 0701, y), y) > > +IS_OLD_GCC = 1 > > +endif > > + > > +ifdef CONFIG_X86 > > +ifdef IS_OLD_GCC > > +# Stack alignment mismatch, proceed with caution. > > +# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 > > +# (8B stack alignment). > > +CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o += -mpreferred-stack-boundary=4 > > +else > > +CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o += -msse2 > > +endif > > +endif > > +AMD_DAL_DCN201 = $(addprefix $(AMDDALPATH)/dc/dcn201/,$(DCN201)) > > + > > +AMD_DISPLAY_FILES += $(AMD_DAL_DCN201) > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dccg.c > > new file mode 100644 > > index 0000000..f5bf04f > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dccg.c > > @@ -0,0 +1,84 @@ > > +/* > > + * Copyright 2018 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#include "dcn201_dccg.h" > > + > > +#include "reg_helper.h" > > +#include "core_types.h" > > + > > +#define TO_DCN_DCCG(dccg)\ > > + container_of(dccg, struct dcn_dccg, base) > > + > > +#define REG(reg) \ > > + (dccg_dcn->regs->reg) > > + > > +#undef FN > > +#define FN(reg_name, field_name) \ > > + dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name > > + > > +#define CTX \ > > + dccg_dcn->base.ctx > > + > > +#define DC_LOGGER \ > > + dccg->ctx->logger > > + > > +void dccg201_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk) > > +{ > > + /* vbios handles it */ > > +} > > + > > +static const struct dccg_funcs dccg201_funcs = { > > + .update_dpp_dto = dccg201_update_dpp_dto, > > + .get_dccg_ref_freq = dccg2_get_dccg_ref_freq, > > + .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, > > + .otg_add_pixel = dccg2_otg_add_pixel, > > + .otg_drop_pixel = dccg2_otg_drop_pixel, > > + .dccg_init = dccg2_init > > +}; > > + > > +struct dccg *dccg201_create( > > + struct dc_context *ctx, > > + const struct dccg_registers *regs, > > + const struct dccg_shift *dccg_shift, > > + const struct dccg_mask *dccg_mask) > > +{ > > + struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); > > + struct dccg *base; > > + > > + if (dccg_dcn == NULL) { > > + BREAK_TO_DEBUGGER(); > > + return NULL; > > + } > > + > > + base = &dccg_dcn->base; > > + base->ctx = ctx; > > + base->funcs = &dccg201_funcs; > > + > > + dccg_dcn->regs = regs; > > + dccg_dcn->dccg_shift = dccg_shift; > > + dccg_dcn->dccg_mask = dccg_mask; > > + > > + return &dccg_dcn->base; > > +} > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dccg.h > > new file mode 100644 > > index 0000000..80888b0 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dccg.h > > @@ -0,0 +1,37 @@ > > +/* > > + * Copyright 2018 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#ifndef __DCN201_DCCG_H__ > > +#define __DCN201_DCCG_H__ > > + > > +#include "dcn20/dcn20_dccg.h" > > + > > +struct dccg *dccg201_create( > > + struct dc_context *ctx, > > + const struct dccg_registers *regs, > > + const struct dccg_shift *dccg_shift, > > + const struct dccg_mask *dccg_mask); > > + > > +#endif //__DCN201_DCCG_H__ > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dpp.c > > new file mode 100644 > > index 0000000..8b6505b > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dpp.c > > @@ -0,0 +1,316 @@ > > +/* > > + * Copyright 2016 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#include "dm_services.h" > > + > > +#include "core_types.h" > > + > > +#include "reg_helper.h" > > +#include "dcn201_dpp.h" > > +#include "basics/conversion.h" > > + > > +#define REG(reg)\ > > + dpp->tf_regs->reg > > + > > +#define CTX \ > > + dpp->base.ctx > > + > > +#undef FN > > +#define FN(reg_name, field_name) \ > > + dpp->tf_shift->field_name, dpp->tf_mask->field_name > > + > > +static void dpp201_cnv_setup( > > + struct dpp *dpp_base, > > + enum surface_pixel_format format, > > + enum expansion_mode mode, > > + struct dc_csc_transform input_csc_color_matrix, > > + enum dc_color_space input_color_space, > > + struct cnv_alpha_2bit_lut *alpha_2bit_lut) > > +{ > > + struct dcn201_dpp *dpp = TO_DCN201_DPP(dpp_base); > > + uint32_t pixel_format = 0; > > + uint32_t alpha_en = 1; > > + enum dc_color_space color_space = COLOR_SPACE_SRGB; > > + enum dcn10_input_csc_select select = INPUT_CSC_SELECT_BYPASS; > > + bool force_disable_cursor = false; > > + uint32_t is_2bit = 0; > > + > > + REG_SET_2(FORMAT_CONTROL, 0, > > + CNVC_BYPASS, 0, > > + FORMAT_EXPANSION_MODE, mode); > > + > > + REG_UPDATE(FORMAT_CONTROL, FORMAT_CNV16, 0); > > + REG_UPDATE(FORMAT_CONTROL, CNVC_BYPASS_MSB_ALIGN, 0); > > + REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE, 0); > > + REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE_C, 0); > > + > > + switch (format) { > > + case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: > > + pixel_format = 1; > > + break; > > + case SURFACE_PIXEL_FORMAT_GRPH_RGB565: > > + pixel_format = 3; > > + alpha_en = 0; > > + break; > > + case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: > > + case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: > > + pixel_format = 8; > > + break; > > + case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: > > + case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: > > + pixel_format = 10; > > + is_2bit = 1; > > + break; > > + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: > > + force_disable_cursor = false; > > + pixel_format = 65; > > + color_space = COLOR_SPACE_YCBCR709; > > + select = INPUT_CSC_SELECT_ICSC; > > + break; > > + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: > > + force_disable_cursor = true; > > + pixel_format = 64; > > + color_space = COLOR_SPACE_YCBCR709; > > + select = INPUT_CSC_SELECT_ICSC; > > + break; > > + case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: > > + force_disable_cursor = true; > > + pixel_format = 67; > > + color_space = COLOR_SPACE_YCBCR709; > > + select = INPUT_CSC_SELECT_ICSC; > > + break; > > + case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: > > + force_disable_cursor = true; > > + pixel_format = 66; > > + color_space = COLOR_SPACE_YCBCR709; > > + select = INPUT_CSC_SELECT_ICSC; > > + break; > > + case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: > > + pixel_format = 22; > > + break; > > + case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: > > + pixel_format = 24; > > + break; > > + case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: > > + pixel_format = 25; > > + break; > > + case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888: > > + pixel_format = 12; > > + color_space = COLOR_SPACE_YCBCR709; > > + select = INPUT_CSC_SELECT_ICSC; > > + break; > > + case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX: > > + pixel_format = 112; > > + alpha_en = 0; > > + break; > > + case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX: > > + pixel_format = 113; > > + alpha_en = 0; > > + break; > > + case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010: > > + pixel_format = 114; > > + color_space = COLOR_SPACE_YCBCR709; > > + select = INPUT_CSC_SELECT_ICSC; > > + is_2bit = 1; > > + break; > > + case SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102: > > + pixel_format = 115; > > + color_space = COLOR_SPACE_YCBCR709; > > + select = INPUT_CSC_SELECT_ICSC; > > + is_2bit = 1; > > + break; > > + case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT: > > + pixel_format = 118; > > + alpha_en = 0; > > + break; > > + case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT: > > + pixel_format = 119; > > + alpha_en = 0; > > + break; > > + default: > > + break; > > + } > > + > > + if (is_2bit == 1 && alpha_2bit_lut != NULL) { > > + REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0); > > + REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1); > > + REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT2, alpha_2bit_lut->lut2); > > + REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT3, alpha_2bit_lut->lut3); > > + } > > + > > + REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0, > > + CNVC_SURFACE_PIXEL_FORMAT, pixel_format); > > + REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en); > > + > > + dpp1_program_input_csc(dpp_base, color_space, select, NULL); > > + > > + if (force_disable_cursor) { > > + REG_UPDATE(CURSOR_CONTROL, > > + CURSOR_ENABLE, 0); > > + REG_UPDATE(CURSOR0_CONTROL, > > + CUR0_ENABLE, 0); > > + } > > + dpp2_power_on_obuf(dpp_base, true); > > +} > > + > > +#define IDENTITY_RATIO(ratio) (dc_fixpt_u3d19(ratio) == (1 << 19)) > > + > > +static bool dpp201_get_optimal_number_of_taps( > > + struct dpp *dpp, > > + struct scaler_data *scl_data, > > + const struct scaling_taps *in_taps) > > +{ > > + uint32_t pixel_width; > > + > > + if (scl_data->viewport.width > scl_data->recout.width) > > + pixel_width = scl_data->recout.width; > > + else > > + pixel_width = scl_data->viewport.width; > > + > > + if (scl_data->viewport.width != scl_data->h_active && > > + scl_data->viewport.height != scl_data->v_active && > > + dpp->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT && > > + scl_data->format == PIXEL_FORMAT_FP16) > > + return false; > > + > > + if (scl_data->viewport.width > scl_data->h_active && > > + dpp->ctx->dc->debug.max_downscale_src_width != 0 && > > + scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width) > > + return false; > > + > > + if (scl_data->ratios.horz.value == (8ll << 32)) > > + scl_data->ratios.horz.value--; > > + if (scl_data->ratios.vert.value == (8ll << 32)) > > + scl_data->ratios.vert.value--; > > + if (scl_data->ratios.horz_c.value == (8ll << 32)) > > + scl_data->ratios.horz_c.value--; > > + if (scl_data->ratios.vert_c.value == (8ll << 32)) > > + scl_data->ratios.vert_c.value--; > > + > > + if (in_taps->h_taps == 0) { > > + if (dc_fixpt_ceil(scl_data->ratios.horz) > 4) > > + scl_data->taps.h_taps = 8; > > + else > > + scl_data->taps.h_taps = 4; > > + } else > > + scl_data->taps.h_taps = in_taps->h_taps; > > + > > + if (in_taps->v_taps == 0) { > > + if (dc_fixpt_ceil(scl_data->ratios.vert) > 4) > > + scl_data->taps.v_taps = 8; > > + else > > + scl_data->taps.v_taps = 4; > > + } else > > + scl_data->taps.v_taps = in_taps->v_taps; > > + if (in_taps->v_taps_c == 0) { > > + if (dc_fixpt_ceil(scl_data->ratios.vert_c) > 4) > > + scl_data->taps.v_taps_c = 4; > > + else > > + scl_data->taps.v_taps_c = 2; > > + } else > > + scl_data->taps.v_taps_c = in_taps->v_taps_c; > > + if (in_taps->h_taps_c == 0) { > > + if (dc_fixpt_ceil(scl_data->ratios.horz_c) > 4) > > + scl_data->taps.h_taps_c = 4; > > + else > > + scl_data->taps.h_taps_c = 2; > > + } else if ((in_taps->h_taps_c % 2) != 0 && in_taps->h_taps_c != 1) > > + scl_data->taps.h_taps_c = in_taps->h_taps_c - 1; > > + else > > + scl_data->taps.h_taps_c = in_taps->h_taps_c; > > + > > + if (!dpp->ctx->dc->debug.always_scale) { > > + if (IDENTITY_RATIO(scl_data->ratios.horz)) > > + scl_data->taps.h_taps = 1; > > + if (IDENTITY_RATIO(scl_data->ratios.vert)) > > + scl_data->taps.v_taps = 1; > > + if (IDENTITY_RATIO(scl_data->ratios.horz_c)) > > + scl_data->taps.h_taps_c = 1; > > + if (IDENTITY_RATIO(scl_data->ratios.vert_c)) > > + scl_data->taps.v_taps_c = 1; > > + } > > + > > + return true; > > +} > > + > > +static struct dpp_funcs dcn201_dpp_funcs = { > > + .dpp_read_state = dpp20_read_state, > > + .dpp_reset = dpp_reset, > > + .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale, > > + .dpp_get_optimal_number_of_taps = dpp201_get_optimal_number_of_taps, > > + .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap, > > + .dpp_set_csc_adjustment = NULL, > > + .dpp_set_csc_default = NULL, > > + .dpp_program_regamma_pwl = oppn20_dummy_program_regamma_pwl, > > + .dpp_set_degamma = dpp2_set_degamma, > > + .dpp_program_input_lut = dpp2_dummy_program_input_lut, > > + .dpp_full_bypass = dpp1_full_bypass, > > + .dpp_setup = dpp201_cnv_setup, > > + .dpp_program_degamma_pwl = dpp2_set_degamma_pwl, > > + .dpp_program_blnd_lut = dpp20_program_blnd_lut, > > + .dpp_program_shaper_lut = dpp20_program_shaper, > > + .dpp_program_3dlut = dpp20_program_3dlut, > > + .dpp_program_bias_and_scale = NULL, > > + .dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer, > > + .set_cursor_attributes = dpp2_set_cursor_attributes, > > + .set_cursor_position = dpp1_set_cursor_position, > > + .set_optional_cursor_attributes = dpp1_cnv_set_optional_cursor_attributes, > > + .dpp_dppclk_control = dpp1_dppclk_control, > > + .dpp_set_hdr_multiplier = dpp2_set_hdr_multiplier, > > +}; > > + > > +static struct dpp_caps dcn201_dpp_cap = { > > + .dscl_data_proc_format = DSCL_DATA_PRCESSING_FLOAT_FORMAT, > > + .dscl_calc_lb_num_partitions = dscl2_calc_lb_num_partitions, > > +}; > > + > > +bool dpp201_construct( > > + struct dcn201_dpp *dpp, > > + struct dc_context *ctx, > > + uint32_t inst, > > + const struct dcn201_dpp_registers *tf_regs, > > + const struct dcn201_dpp_shift *tf_shift, > > + const struct dcn201_dpp_mask *tf_mask) > > +{ > > + dpp->base.ctx = ctx; > > + > > + dpp->base.inst = inst; > > + dpp->base.funcs = &dcn201_dpp_funcs; > > + dpp->base.caps = &dcn201_dpp_cap; > > + > > + dpp->tf_regs = tf_regs; > > + dpp->tf_shift = tf_shift; > > + dpp->tf_mask = tf_mask; > > + > > + dpp->lb_pixel_depth_supported = > > + LB_PIXEL_DEPTH_18BPP | > > + LB_PIXEL_DEPTH_24BPP | > > + LB_PIXEL_DEPTH_30BPP; > > + > > + dpp->lb_bits_per_entry = LB_BITS_PER_ENTRY; > > + dpp->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; > > + > > + return true; > > +} > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dpp.h > > new file mode 100644 > > index 0000000..cbd5b47 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dpp.h > > @@ -0,0 +1,83 @@ > > +/* Copyright 2016 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#ifndef __DCN201_DPP_H__ > > +#define __DCN201_DPP_H__ > > + > > +#include "dcn20/dcn20_dpp.h" > > + > > +#define TO_DCN201_DPP(dpp)\ > > + container_of(dpp, struct dcn201_dpp, base) > > + > > +#define TF_REG_LIST_DCN201(id) \ > > + TF_REG_LIST_DCN20(id) > > + > > +#define TF_REG_LIST_SH_MASK_DCN201(mask_sh)\ > > + TF_REG_LIST_SH_MASK_DCN20(mask_sh) > > + > > +#define TF_REG_FIELD_LIST_DCN201(type) \ > > + TF_REG_FIELD_LIST_DCN2_0(type) > > + > > +struct dcn201_dpp_shift { > > + TF_REG_FIELD_LIST_DCN201(uint8_t); > > +}; > > + > > +struct dcn201_dpp_mask { > > + TF_REG_FIELD_LIST_DCN201(uint32_t); > > +}; > > + > > +#define DPP_DCN201_REG_VARIABLE_LIST \ > > + DPP_DCN2_REG_VARIABLE_LIST > > + > > +struct dcn201_dpp_registers { > > + DPP_DCN201_REG_VARIABLE_LIST; > > +}; > > + > > +struct dcn201_dpp { > > + struct dpp base; > > + > > + const struct dcn201_dpp_registers *tf_regs; > > + const struct dcn201_dpp_shift *tf_shift; > > + const struct dcn201_dpp_mask *tf_mask; > > + > > + const uint16_t *filter_v; > > + const uint16_t *filter_h; > > + const uint16_t *filter_v_c; > > + const uint16_t *filter_h_c; > > + int lb_pixel_depth_supported; > > + int lb_memory_size; > > + int lb_bits_per_entry; > > + bool is_write_to_ram_a_safe; > > + struct scaler_data scl_data; > > + struct pwl_params pwl_data; > > +}; > > + > > +bool dpp201_construct(struct dcn201_dpp *dpp2, > > + struct dc_context *ctx, > > + uint32_t inst, > > + const struct dcn201_dpp_registers *tf_regs, > > + const struct dcn201_dpp_shift *tf_shift, > > + const struct dcn201_dpp_mask *tf_mask); > > + > > +#endif /* __DC_HWSS_DCN201_H__ */ > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubbub.c > > new file mode 100644 > > index 0000000..037d265 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubbub.c > > @@ -0,0 +1,107 @@ > > +/* > > +* Copyright 2018 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > +#include "dm_services.h" > > +#include "dcn20/dcn20_hubbub.h" > > +#include "dcn201_hubbub.h" > > +#include "reg_helper.h" > > + > > +#define REG(reg)\ > > + hubbub1->regs->reg > > + > > +#define DC_LOGGER \ > > + hubbub1->base.ctx->logger > > + > > +#define CTX \ > > + hubbub1->base.ctx > > + > > +#undef FN > > +#define FN(reg_name, field_name) \ > > + hubbub1->shifts->field_name, hubbub1->masks->field_name > > + > > +#define REG(reg)\ > > + hubbub1->regs->reg > > + > > +#define CTX \ > > + hubbub1->base.ctx > > + > > +#undef FN > > +#define FN(reg_name, field_name) \ > > + hubbub1->shifts->field_name, hubbub1->masks->field_name > > + > > +static bool hubbub201_program_watermarks( > > + struct hubbub *hubbub, > > + struct dcn_watermark_set *watermarks, > > + unsigned int refclk_mhz, > > + bool safe_to_lower) > > +{ > > + struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); > > + bool wm_pending = false; > > + > > + if (hubbub1_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower)) > > + wm_pending = true; > > + > > + if (hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower)) > > + wm_pending = true; > > + > > + REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0, > > + DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); > > + REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, > > + DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68); > > + > > + hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); > > + > > + return wm_pending; > > +} > > + > > +static const struct hubbub_funcs hubbub201_funcs = { > > + .update_dchub = hubbub2_update_dchub, > > + .init_dchub_sys_ctx = NULL, > > + .init_vm_ctx = NULL, > > + .dcc_support_swizzle = hubbub2_dcc_support_swizzle, > > + .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format, > > + .get_dcc_compression_cap = hubbub2_get_dcc_compression_cap, > > + .wm_read_state = hubbub2_wm_read_state, > > + .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq, > > + .program_watermarks = hubbub201_program_watermarks, > > + .hubbub_read_state = hubbub2_read_state, > > +}; > > + > > +void hubbub201_construct(struct dcn20_hubbub *hubbub, > > + struct dc_context *ctx, > > + const struct dcn_hubbub_registers *hubbub_regs, > > + const struct dcn_hubbub_shift *hubbub_shift, > > + const struct dcn_hubbub_mask *hubbub_mask) > > +{ > > + hubbub->base.ctx = ctx; > > + > > + hubbub->base.funcs = &hubbub201_funcs; > > + > > + hubbub->regs = hubbub_regs; > > + hubbub->shifts = hubbub_shift; > > + hubbub->masks = hubbub_mask; > > + > > + hubbub->debug_test_index_pstate = 0xB; > > + hubbub->detile_buf_size = 164 * 1024; > > +} > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubbub.h > > new file mode 100644 > > index 0000000..a1ec699 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubbub.h > > @@ -0,0 +1,45 @@ > > +/* > > +* Copyright 2018 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > +#ifndef DAL_DC_DCN201_DCN201_HUBBUB_H_ > > +#define DAL_DC_DCN201_DCN201_HUBBUB_H_ > > + > > +#include "dcn20/dcn20_hubbub.h" > > + > > +#define HUBBUB_REG_LIST_DCN201(id)\ > > + HUBBUB_REG_LIST_DCN_COMMON(), \ > > + HUBBUB_VM_REG_LIST(), \ > > + SR(DCHUBBUB_CRC_CTRL) > > + > > +#define HUBBUB_MASK_SH_LIST_DCN201(mask_sh)\ > > + HUBBUB_MASK_SH_LIST_DCN_COMMON(mask_sh), \ > > + HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh) > > + > > +void hubbub201_construct(struct dcn20_hubbub *hubbub, > > + struct dc_context *ctx, > > + const struct dcn_hubbub_registers *hubbub_regs, > > + const struct dcn_hubbub_shift *hubbub_shift, > > + const struct dcn_hubbub_mask *hubbub_mask); > > + > > +#endif /* DAL_DC_DCN201_DCN201_HUBBUB_H_ */ > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.c > > new file mode 100644 > > index 0000000..6b6f74d > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.c > > @@ -0,0 +1,150 @@ > > +/* > > + * Copyright 2012-17 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > +#include "dcn201_hubp.h" > > + > > +#include "dm_services.h" > > +#include "dce_calcs.h" > > +#include "reg_helper.h" > > +#include "basics/conversion.h" > > + > > +#define REG(reg)\ > > + hubp201->hubp_regs->reg > > + > > +#define CTX \ > > + hubp201->base.ctx > > + > > +#undef FN > > +#define FN(reg_name, field_name) \ > > + hubp201->hubp_shift->field_name, hubp201->hubp_mask->field_name > > + > > +static void hubp201_program_surface_config( > > + struct hubp *hubp, > > + enum surface_pixel_format format, > > + union dc_tiling_info *tiling_info, > > + struct plane_size *plane_size, > > + enum dc_rotation_angle rotation, > > + struct dc_plane_dcc_param *dcc, > > + bool horizontal_mirror, > > + unsigned int compat_level) > > +{ > > + hubp1_dcc_control(hubp, dcc->enable, dcc->independent_64b_blks); > > + hubp1_program_tiling(hubp, tiling_info, format); > > + hubp1_program_size(hubp, format, plane_size, dcc); > > + hubp1_program_pixel_format(hubp, format); > > +} > > + > > +void hubp201_program_deadline( > > + struct hubp *hubp, > > + struct _vcs_dpi_display_dlg_regs_st *dlg_attr, > > + struct _vcs_dpi_display_ttu_regs_st *ttu_attr) > > +{ > > + hubp1_program_deadline(hubp, dlg_attr, ttu_attr); > > +} > > + > > +void hubp201_program_requestor( > > + struct hubp *hubp, > > + struct _vcs_dpi_display_rq_regs_st *rq_regs) > > +{ > > + struct dcn201_hubp *hubp201 = TO_DCN201_HUBP(hubp); > > + > > + REG_UPDATE(HUBPRET_CONTROL, > > + DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address); > > + > > + REG_SET_4(DCN_EXPANSION_MODE, 0, > > + DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode, > > + PRQ_EXPANSION_MODE, rq_regs->prq_expansion_mode, > > + MRQ_EXPANSION_MODE, rq_regs->mrq_expansion_mode, > > + CRQ_EXPANSION_MODE, rq_regs->crq_expansion_mode); > > + > > + REG_SET_5(DCHUBP_REQ_SIZE_CONFIG, 0, > > + CHUNK_SIZE, rq_regs->rq_regs_l.chunk_size, > > + MIN_CHUNK_SIZE, rq_regs->rq_regs_l.min_chunk_size, > > + META_CHUNK_SIZE, rq_regs->rq_regs_l.meta_chunk_size, > > + MIN_META_CHUNK_SIZE, rq_regs->rq_regs_l.min_meta_chunk_size, > > + SWATH_HEIGHT, rq_regs->rq_regs_l.swath_height); > > + > > + REG_SET_5(DCHUBP_REQ_SIZE_CONFIG_C, 0, > > + CHUNK_SIZE_C, rq_regs->rq_regs_c.chunk_size, > > + MIN_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_chunk_size, > > + META_CHUNK_SIZE_C, rq_regs->rq_regs_c.meta_chunk_size, > > + MIN_META_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_meta_chunk_size, > > + SWATH_HEIGHT_C, rq_regs->rq_regs_c.swath_height); > > +} > > + > > +static void hubp201_setup( > > + struct hubp *hubp, > > + struct _vcs_dpi_display_dlg_regs_st *dlg_attr, > > + struct _vcs_dpi_display_ttu_regs_st *ttu_attr, > > + struct _vcs_dpi_display_rq_regs_st *rq_regs, > > + struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest) > > +{ > > + hubp2_vready_at_or_After_vsync(hubp, pipe_dest); > > + hubp201_program_requestor(hubp, rq_regs); > > + hubp201_program_deadline(hubp, dlg_attr, ttu_attr); > > +} > > + > > +static struct hubp_funcs dcn201_hubp_funcs = { > > + .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, > > + .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled, > > + .hubp_program_surface_flip_and_addr = hubp1_program_surface_flip_and_addr, > > + .hubp_program_surface_config = hubp201_program_surface_config, > > + .hubp_is_flip_pending = hubp1_is_flip_pending, > > + .hubp_setup = hubp201_setup, > > + .hubp_setup_interdependent = hubp2_setup_interdependent, > > + .set_cursor_attributes = hubp2_cursor_set_attributes, > > + .set_cursor_position = hubp1_cursor_set_position, > > + .set_blank = hubp1_set_blank, > > + .dcc_control = hubp1_dcc_control, > > + .mem_program_viewport = min_set_viewport, > > + .hubp_clk_cntl = hubp1_clk_cntl, > > + .hubp_vtg_sel = hubp1_vtg_sel, > > + .dmdata_set_attributes = hubp2_dmdata_set_attributes, > > + .dmdata_load = hubp2_dmdata_load, > > + .dmdata_status_done = hubp2_dmdata_status_done, > > + .hubp_read_state = hubp2_read_state, > > + .hubp_clear_underflow = hubp1_clear_underflow, > > + .hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl, > > + .hubp_init = hubp1_init, > > +}; > > + > > +bool dcn201_hubp_construct( > > + struct dcn201_hubp *hubp201, > > + struct dc_context *ctx, > > + uint32_t inst, > > + const struct dcn201_hubp_registers *hubp_regs, > > + const struct dcn201_hubp_shift *hubp_shift, > > + const struct dcn201_hubp_mask *hubp_mask) > > +{ > > + hubp201->base.funcs = &dcn201_hubp_funcs; > > + hubp201->base.ctx = ctx; > > + hubp201->hubp_regs = hubp_regs; > > + hubp201->hubp_shift = hubp_shift; > > + hubp201->hubp_mask = hubp_mask; > > + hubp201->base.inst = inst; > > + hubp201->base.opp_id = OPP_ID_INVALID; > > + hubp201->base.mpcc_id = 0xf; > > + > > + return true; > > +} > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.h > > new file mode 100644 > > index 0000000..a1e3384 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.h > > @@ -0,0 +1,132 @@ > > +/* > > + * Copyright 2012-17 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#ifndef __DC_MEM_INPUT_DCN201_H__ > > +#define __DC_MEM_INPUT_DCN201_H__ > > + > > +#include "../dcn10/dcn10_hubp.h" > > +#include "../dcn20/dcn20_hubp.h" > > + > > +#define TO_DCN201_HUBP(hubp)\ > > + container_of(hubp, struct dcn201_hubp, base) > > + > > +#define HUBP_REG_LIST_DCN201(id)\ > > + HUBP_REG_LIST_DCN(id),\ > > + SRI(PREFETCH_SETTINGS, HUBPREQ, id),\ > > + SRI(PREFETCH_SETTINGS_C, HUBPREQ, id),\ > > + SRI(DCSURF_FLIP_CONTROL2, HUBPREQ, id), \ > > + SRI(CURSOR_SETTINGS, HUBPREQ, id), \ > > + SRI(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR0_, id), \ > > + SRI(CURSOR_SURFACE_ADDRESS, CURSOR0_, id), \ > > + SRI(CURSOR_SIZE, CURSOR0_, id), \ > > + SRI(CURSOR_CONTROL, CURSOR0_, id), \ > > + SRI(CURSOR_POSITION, CURSOR0_, id), \ > > + SRI(CURSOR_HOT_SPOT, CURSOR0_, id), \ > > + SRI(CURSOR_DST_OFFSET, CURSOR0_, id), \ > > + SRI(DMDATA_ADDRESS_HIGH, CURSOR0_, id), \ > > + SRI(DMDATA_ADDRESS_LOW, CURSOR0_, id), \ > > + SRI(DMDATA_CNTL, CURSOR0_, id), \ > > + SRI(DMDATA_SW_CNTL, CURSOR0_, id), \ > > + SRI(DMDATA_QOS_CNTL, CURSOR0_, id), \ > > + SRI(DMDATA_SW_DATA, CURSOR0_, id), \ > > + SRI(DMDATA_STATUS, CURSOR0_, id),\ > > + SRI(FLIP_PARAMETERS_0, HUBPREQ, id),\ > > + SRI(FLIP_PARAMETERS_2, HUBPREQ, id) > > + > > +#define HUBP_MASK_SH_LIST_DCN201(mask_sh)\ > > + HUBP_MASK_SH_LIST_DCN(mask_sh),\ > > + HUBP_SF(HUBPREQ0_PREFETCH_SETTINGS, DST_Y_PREFETCH, mask_sh),\ > > + HUBP_SF(HUBPREQ0_PREFETCH_SETTINGS, VRATIO_PREFETCH, mask_sh),\ > > + HUBP_SF(HUBPREQ0_PREFETCH_SETTINGS_C, VRATIO_PREFETCH_C, mask_sh),\ > > + HUBP_SF(HUBPREQ0_DCSURF_FLIP_CONTROL2, SURFACE_TRIPLE_BUFFER_ENABLE, mask_sh),\ > > + HUBP_SF(HUBPREQ0_CURSOR_SETTINGS, CURSOR0_DST_Y_OFFSET, mask_sh), \ > > + HUBP_SF(HUBPREQ0_CURSOR_SETTINGS, CURSOR0_CHUNK_HDL_ADJUST, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_SURFACE_ADDRESS, CURSOR_SURFACE_ADDRESS, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_SIZE, CURSOR_WIDTH, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_SIZE, CURSOR_HEIGHT, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_2X_MAGNIFY, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_POSITION, CURSOR_X_POSITION, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_POSITION, CURSOR_Y_POSITION, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_X, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \ > > + HUBP_SF(CURSOR0_0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh), \ > > + HUBP_SF(CURSOR0_0_DMDATA_ADDRESS_HIGH, DMDATA_ADDRESS_HIGH, mask_sh), \ > > + HUBP_SF(CURSOR0_0_DMDATA_CNTL, DMDATA_MODE, mask_sh), \ > > + HUBP_SF(CURSOR0_0_DMDATA_CNTL, DMDATA_UPDATED, mask_sh), \ > > + HUBP_SF(CURSOR0_0_DMDATA_CNTL, DMDATA_REPEAT, mask_sh), \ > > + HUBP_SF(CURSOR0_0_DMDATA_CNTL, DMDATA_SIZE, mask_sh), \ > > + HUBP_SF(CURSOR0_0_DMDATA_SW_CNTL, DMDATA_SW_UPDATED, mask_sh), \ > > + HUBP_SF(CURSOR0_0_DMDATA_SW_CNTL, DMDATA_SW_REPEAT, mask_sh), \ > > + HUBP_SF(CURSOR0_0_DMDATA_SW_CNTL, DMDATA_SW_SIZE, mask_sh), \ > > + HUBP_SF(CURSOR0_0_DMDATA_QOS_CNTL, DMDATA_QOS_MODE, mask_sh), \ > > + HUBP_SF(CURSOR0_0_DMDATA_QOS_CNTL, DMDATA_QOS_LEVEL, mask_sh), \ > > + HUBP_SF(CURSOR0_0_DMDATA_QOS_CNTL, DMDATA_DL_DELTA, mask_sh),\ > > + HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_0, DST_Y_PER_VM_FLIP, mask_sh),\ > > + HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_0, DST_Y_PER_ROW_FLIP, mask_sh),\ > > + HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_2, REFCYC_PER_META_CHUNK_FLIP_L, mask_sh),\ > > + HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_VREADY_AT_OR_AFTER_VSYNC, mask_sh),\ > > + HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_DISABLE_STOP_DATA_DURING_VM, mask_sh),\ > > + HUBP_SF(HUBPREQ0_DCSURF_FLIP_CONTROL, HUBPREQ_MASTER_UPDATE_LOCK_STATUS, mask_sh) > > + > > +#define DCN201_HUBP_REG_VARIABLE_LIST \ > > + DCN2_HUBP_REG_COMMON_VARIABLE_LIST > > + > > +#define DCN201_HUBP_REG_FIELD_VARIABLE_LIST(type) \ > > + DCN2_HUBP_REG_FIELD_VARIABLE_LIST(type) > > + > > +struct dcn201_hubp_registers { > > + DCN201_HUBP_REG_VARIABLE_LIST; > > +}; > > + > > +struct dcn201_hubp_shift { > > + DCN201_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t); > > +}; > > + > > +struct dcn201_hubp_mask { > > + DCN201_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t); > > +}; > > + > > +struct dcn201_hubp { > > + struct hubp base; > > + struct dcn_hubp_state state; > > + const struct dcn201_hubp_registers *hubp_regs; > > + const struct dcn201_hubp_shift *hubp_shift; > > + const struct dcn201_hubp_mask *hubp_mask; > > +}; > > + > > +bool dcn201_hubp_construct( > > + struct dcn201_hubp *hubp201, > > + struct dc_context *ctx, > > + uint32_t inst, > > + const struct dcn201_hubp_registers *hubp_regs, > > + const struct dcn201_hubp_shift *hubp_shift, > > + const struct dcn201_hubp_mask *hubp_mask); > > + > > +#endif /* __DC_HWSS_DCN20_H__ */ > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c > > new file mode 100644 > > index 0000000..ceaaeeb > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c > > @@ -0,0 +1,630 @@ > > +/* > > + * Copyright 2016 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#include "dm_services.h" > > +#include "basics/dc_common.h" > > +#include "core_types.h" > > +#include "resource.h" > > +#include "dcn201_hwseq.h" > > +#include "dcn201_optc.h" > > +#include "dce/dce_hwseq.h" > > +#include "hubp.h" > > +#include "dchubbub.h" > > +#include "timing_generator.h" > > +#include "opp.h" > > +#include "ipp.h" > > +#include "mpc.h" > > +#include "dccg.h" > > +#include "clk_mgr.h" > > +#include "reg_helper.h" > > + > > +#define CTX \ > > + hws->ctx > > + > > +#define REG(reg)\ > > + hws->regs->reg > > + > > +#define DC_LOGGER \ > > + dc->ctx->logger > > + > > +#undef FN > > +#define FN(reg_name, field_name) \ > > + hws->shifts->field_name, hws->masks->field_name > > + > > +static bool patch_address_for_sbs_tb_stereo( > > + struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr) > > +{ > > + struct dc_plane_state *plane_state = pipe_ctx->plane_state; > > + bool sec_split = pipe_ctx->top_pipe && > > + pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state; > > + > > + if (sec_split && plane_state->address.type == PLN_ADDR_TYPE_GRPH_STEREO && > > + (pipe_ctx->stream->timing.timing_3d_format == > > + TIMING_3D_FORMAT_SIDE_BY_SIDE || > > + pipe_ctx->stream->timing.timing_3d_format == > > + TIMING_3D_FORMAT_TOP_AND_BOTTOM)) { > > + *addr = plane_state->address.grph_stereo.left_addr; > > + plane_state->address.grph_stereo.left_addr = > > + plane_state->address.grph_stereo.right_addr; > > + return true; > > + } else { > > + if (pipe_ctx->stream->view_format != VIEW_3D_FORMAT_NONE && > > + plane_state->address.type != PLN_ADDR_TYPE_GRPH_STEREO) { > > + plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO; > > + plane_state->address.grph_stereo.right_addr = > > + plane_state->address.grph_stereo.left_addr; > > + plane_state->address.grph_stereo.right_meta_addr = > > + plane_state->address.grph_stereo.left_meta_addr; > > + } > > + } > > + return false; > > +} > > + > > +static void gpu_addr_to_uma(struct dce_hwseq *hwseq, > > + PHYSICAL_ADDRESS_LOC *addr) > > +{ > > + bool is_in_uma; > > + > > + if (hwseq->fb_base.quad_part <= addr->quad_part && > > + addr->quad_part < hwseq->fb_top.quad_part) { > > + addr->quad_part -= hwseq->fb_base.quad_part; > > + addr->quad_part += hwseq->fb_offset.quad_part; > > + is_in_uma = true; > > + } else if (hwseq->fb_offset.quad_part <= addr->quad_part && > > + addr->quad_part <= hwseq->uma_top.quad_part) { > > + is_in_uma = true; > > + } else if (addr->quad_part == 0) { > > + is_in_uma = false; > > + } else { > > + is_in_uma = false; > > + } > > +} > > + > > +static void plane_address_in_gpu_space_to_uma(struct dce_hwseq *hwseq, > > + struct dc_plane_address *addr) > > +{ > > + switch (addr->type) { > > + case PLN_ADDR_TYPE_GRAPHICS: > > + gpu_addr_to_uma(hwseq, &addr->grph.addr); > > + gpu_addr_to_uma(hwseq, &addr->grph.meta_addr); > > + break; > > + case PLN_ADDR_TYPE_GRPH_STEREO: > > + gpu_addr_to_uma(hwseq, &addr->grph_stereo.left_addr); > > + gpu_addr_to_uma(hwseq, &addr->grph_stereo.left_meta_addr); > > + gpu_addr_to_uma(hwseq, &addr->grph_stereo.right_addr); > > + gpu_addr_to_uma(hwseq, &addr->grph_stereo.right_meta_addr); > > + break; > > + case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE: > > + gpu_addr_to_uma(hwseq, &addr->video_progressive.luma_addr); > > + gpu_addr_to_uma(hwseq, &addr->video_progressive.luma_meta_addr); > > + gpu_addr_to_uma(hwseq, &addr->video_progressive.chroma_addr); > > + gpu_addr_to_uma(hwseq, &addr->video_progressive.chroma_meta_addr); > > + break; > > + default: > > + BREAK_TO_DEBUGGER(); > > + break; > > + } > > +} > > + > > +void dcn201_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx) > > +{ > > + bool addr_patched = false; > > + PHYSICAL_ADDRESS_LOC addr; > > + struct dc_plane_state *plane_state = pipe_ctx->plane_state; > > + struct dce_hwseq *hws = dc->hwseq; > > + struct dc_plane_address uma = plane_state->address; > > + > > + if (plane_state == NULL) > > + return; > > + > > + addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr); > > + > > + plane_address_in_gpu_space_to_uma(hws, &uma); > > + > > + pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr( > > + pipe_ctx->plane_res.hubp, > > + &uma, > > + plane_state->flip_immediate); > > + > > + plane_state->status.requested_address = plane_state->address; > > + > > + if (plane_state->flip_immediate) > > + plane_state->status.current_address = plane_state->address; > > + > > + if (addr_patched) > > + pipe_ctx->plane_state->address.grph_stereo.left_addr = addr; > > +} > > + > > +/* Blank pixel data during initialization */ > > +void dcn201_init_blank( > > + struct dc *dc, > > + struct timing_generator *tg) > > +{ > > + struct dce_hwseq *hws = dc->hwseq; > > + enum dc_color_space color_space; > > + struct tg_color black_color = {0}; > > + struct output_pixel_processor *opp = NULL; > > + uint32_t num_opps, opp_id_src0, opp_id_src1; > > + uint32_t otg_active_width, otg_active_height; > > + > > + /* program opp dpg blank color */ > > + color_space = COLOR_SPACE_SRGB; > > + color_space_to_black_color(dc, color_space, &black_color); > > + > > + /* get the OTG active size */ > > + tg->funcs->get_otg_active_size(tg, > > + &otg_active_width, > > + &otg_active_height); > > + > > + /* get the OPTC source */ > > + tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1); > > + ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp); > > + opp = dc->res_pool->opps[opp_id_src0]; > > + > > + opp->funcs->opp_set_disp_pattern_generator( > > + opp, > > + CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR, > > + CONTROLLER_DP_COLOR_SPACE_UDEFINED, > > + COLOR_DEPTH_UNDEFINED, > > + &black_color, > > + otg_active_width, > > + otg_active_height, > > + 0); > > + > > + hws->funcs.wait_for_blank_complete(opp); > > +} > > + > > +static void read_mmhub_vm_setup(struct dce_hwseq *hws) > > +{ > > + uint32_t fb_base = REG_READ(MC_VM_FB_LOCATION_BASE); > > + uint32_t fb_top = REG_READ(MC_VM_FB_LOCATION_TOP); > > + uint32_t fb_offset = REG_READ(MC_VM_FB_OFFSET); > > + > > + /* MC_VM_FB_LOCATION_TOP is in pages, actual top should add 1 */ > > + fb_top++; > > + > > + /* bit 23:0 in register map to bit 47:24 in address */ > > + hws->fb_base.low_part = fb_base; > > + hws->fb_base.quad_part <<= 24; > > + > > + hws->fb_top.low_part = fb_top; > > + hws->fb_top.quad_part <<= 24; > > + hws->fb_offset.low_part = fb_offset; > > + hws->fb_offset.quad_part <<= 24; > > + > > + hws->uma_top.quad_part = hws->fb_top.quad_part > > + - hws->fb_base.quad_part + hws->fb_offset.quad_part; > > +} > > + > > +void dcn201_init_hw(struct dc *dc) > > +{ > > + int i, j; > > + struct dce_hwseq *hws = dc->hwseq; > > + struct resource_pool *res_pool = dc->res_pool; > > + struct dc_state *context = dc->current_state; > > + > > + if (res_pool->dccg->funcs->dccg_init) > > + res_pool->dccg->funcs->dccg_init(res_pool->dccg); > > + > > + if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) > > + dc->clk_mgr->funcs->init_clocks(dc->clk_mgr); > > + > > + if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { > > + REG_WRITE(RBBMIF_TIMEOUT_DIS, 0xFFFFFFFF); > > + REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF); > > + > > + hws->funcs.dccg_init(hws); > > + > > + REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2); > > + REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1); > > + REG_WRITE(REFCLK_CNTL, 0); > > + } else { > > + hws->funcs.bios_golden_init(dc); > > + > > + if (dc->ctx->dc_bios->fw_info_valid) { > > + res_pool->ref_clocks.xtalin_clock_inKhz = > > + dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency; > > + > > + if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { > > + if (res_pool->dccg && res_pool->hubbub) { > > + (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg, > > + dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency, > > + &res_pool->ref_clocks.dccg_ref_clock_inKhz); > > + > > + (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub, > > + res_pool->ref_clocks.dccg_ref_clock_inKhz, > > + &res_pool->ref_clocks.dchub_ref_clock_inKhz); > > + } else { > > + res_pool->ref_clocks.dccg_ref_clock_inKhz = > > + res_pool->ref_clocks.xtalin_clock_inKhz; > > + res_pool->ref_clocks.dchub_ref_clock_inKhz = > > + res_pool->ref_clocks.xtalin_clock_inKhz; > > + } > > + } > > + } else > > + ASSERT_CRITICAL(false); > > + for (i = 0; i < dc->link_count; i++) { > > + /* Power up AND update implementation according to the > > + * required signal (which may be different from the > > + * default signal on connector). > > + */ > > + struct dc_link *link = dc->links[i]; > > + > > + link->link_enc->funcs->hw_init(link->link_enc); > > + } > > + if (hws->fb_offset.quad_part == 0) > > + read_mmhub_vm_setup(hws); > > + } > > + > > + /* Blank pixel data with OPP DPG */ > > + for (i = 0; i < res_pool->timing_generator_count; i++) { > > + struct timing_generator *tg = res_pool->timing_generators[i]; > > + > > + if (tg->funcs->is_tg_enabled(tg)) { > > + dcn201_init_blank(dc, tg); > > + } > > + } > > + > > + for (i = 0; i < res_pool->timing_generator_count; i++) { > > + struct timing_generator *tg = res_pool->timing_generators[i]; > > + > > + if (tg->funcs->is_tg_enabled(tg)) > > + tg->funcs->lock(tg); > > + } > > + > > + for (i = 0; i < res_pool->pipe_count; i++) { > > + struct dpp *dpp = res_pool->dpps[i]; > > + > > + dpp->funcs->dpp_reset(dpp); > > + } > > + > > + /* Reset all MPCC muxes */ > > + res_pool->mpc->funcs->mpc_init(res_pool->mpc); > > + > > + /* initialize OPP mpc_tree parameter */ > > + for (i = 0; i < res_pool->res_cap->num_opp; i++) { > > + res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst; > > + res_pool->opps[i]->mpc_tree_params.opp_list = NULL; > > + for (j = 0; j < MAX_PIPES; j++) > > + res_pool->opps[i]->mpcc_disconnect_pending[j] = false; > > + } > > + > > + for (i = 0; i < res_pool->timing_generator_count; i++) { > > + struct timing_generator *tg = res_pool->timing_generators[i]; > > + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; > > + struct hubp *hubp = res_pool->hubps[i]; > > + struct dpp *dpp = res_pool->dpps[i]; > > + > > + pipe_ctx->stream_res.tg = tg; > > + pipe_ctx->pipe_idx = i; > > + > > + pipe_ctx->plane_res.hubp = hubp; > > + pipe_ctx->plane_res.dpp = dpp; > > + pipe_ctx->plane_res.mpcc_inst = dpp->inst; > > + hubp->mpcc_id = dpp->inst; > > + hubp->opp_id = OPP_ID_INVALID; > > + hubp->power_gated = false; > > + pipe_ctx->stream_res.opp = NULL; > > + > > + hubp->funcs->hubp_init(hubp); > > + > > + res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true; > > + pipe_ctx->stream_res.opp = res_pool->opps[i]; > > + /*To do: number of MPCC != number of opp*/ > > + hws->funcs.plane_atomic_disconnect(dc, pipe_ctx); > > + } > > + > > + /* initialize DWB pointer to MCIF_WB */ > > + for (i = 0; i < res_pool->res_cap->num_dwb; i++) > > + res_pool->dwbc[i]->mcif = res_pool->mcif_wb[i]; > > + > > + for (i = 0; i < res_pool->timing_generator_count; i++) { > > + struct timing_generator *tg = res_pool->timing_generators[i]; > > + > > + if (tg->funcs->is_tg_enabled(tg)) > > + tg->funcs->unlock(tg); > > + } > > + > > + for (i = 0; i < res_pool->pipe_count; i++) { > > + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; > > + > > + dc->hwss.disable_plane(dc, pipe_ctx); > > + > > + pipe_ctx->stream_res.tg = NULL; > > + pipe_ctx->plane_res.hubp = NULL; > > + } > > + > > + for (i = 0; i < res_pool->timing_generator_count; i++) { > > + struct timing_generator *tg = res_pool->timing_generators[i]; > > + > > + tg->funcs->tg_init(tg); > > + } > > + > > + /* end of FPGA. Below if real ASIC */ > > + if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) > > + return; > > + > > + for (i = 0; i < res_pool->audio_count; i++) { > > + struct audio *audio = res_pool->audios[i]; > > + > > + audio->funcs->hw_init(audio); > > + } > > + > > + /* power AFMT HDMI memory TODO: may move to dis/en output save power*/ > > + REG_WRITE(DIO_MEM_PWR_CTRL, 0); > > + > > + if (!dc->debug.disable_clock_gate) { > > + /* enable all DCN clock gating */ > > + REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); > > + > > + REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); > > + > > + REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); > > + } > > +} > > + > > +/* trigger HW to start disconnect plane from stream on the next vsync */ > > +void dcn201_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx) > > +{ > > + struct dce_hwseq *hws = dc->hwseq; > > + struct hubp *hubp = pipe_ctx->plane_res.hubp; > > + int dpp_id = pipe_ctx->plane_res.dpp->inst; > > + struct mpc *mpc = dc->res_pool->mpc; > > + struct mpc_tree *mpc_tree_params; > > + struct mpcc *mpcc_to_remove = NULL; > > + struct output_pixel_processor *opp = pipe_ctx->stream_res.opp; > > + bool mpcc_removed = false; > > + > > + mpc_tree_params = &(opp->mpc_tree_params); > > + > > + /* check if this plane is being used by an MPCC in the secondary blending chain */ > > + if (mpc->funcs->get_mpcc_for_dpp_from_secondary) > > + mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id); > > + > > + /* remove MPCC from secondary if being used */ > > + if (mpcc_to_remove != NULL && mpc->funcs->remove_mpcc_from_secondary) { > > + mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, mpcc_to_remove); > > + mpcc_removed = true; > > + } > > + > > + /* check if this MPCC is already being used for this plane (dpp) in the primary blending chain */ > > + mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id); > > + if (mpcc_to_remove != NULL) { > > + mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove); > > + mpcc_removed = true; > > + } > > + > > + /*Already reset*/ > > + if (mpcc_removed == false) > > + return; > > + > > + if (opp != NULL) > > + opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true; > > + > > + dc->optimized_required = true; > > + > > + if (hubp->funcs->hubp_disconnect) > > + hubp->funcs->hubp_disconnect(hubp); > > + > > + if (dc->debug.sanity_checks) > > + hws->funcs.verify_allow_pstate_change_high(dc); > > +} > > + > > +void dcn201_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) > > +{ > > + struct hubp *hubp = pipe_ctx->plane_res.hubp; > > + struct mpcc_blnd_cfg blnd_cfg; > > + bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe; > > + int mpcc_id, dpp_id; > > + struct mpcc *new_mpcc; > > + struct mpcc *remove_mpcc; > > + struct mpc *mpc = dc->res_pool->mpc; > > + struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params); > > + > > + if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR) { > > + get_hdr_visual_confirm_color( > > + pipe_ctx, &blnd_cfg.black_color); > > + } else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) { > > + get_surface_visual_confirm_color( > > + pipe_ctx, &blnd_cfg.black_color); > > + } else { > > + color_space_to_black_color( > > + dc, pipe_ctx->stream->output_color_space, > > + &blnd_cfg.black_color); > > + } > > + > > + if (per_pixel_alpha) > > + blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA; > > + else > > + blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA; > > + > > + blnd_cfg.overlap_only = false; > > + > > + if (pipe_ctx->plane_state->global_alpha_value) > > + blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value; > > + else > > + blnd_cfg.global_alpha = 0xff; > > + > > + blnd_cfg.global_gain = 0xff; > > + blnd_cfg.background_color_bpc = 4; > > + blnd_cfg.bottom_gain_mode = 0; > > + blnd_cfg.top_gain = 0x1f000; > > + blnd_cfg.bottom_inside_gain = 0x1f000; > > + blnd_cfg.bottom_outside_gain = 0x1f000; > > + /*the input to MPCC is RGB*/ > > + blnd_cfg.black_color.color_b_cb = 0; > > + blnd_cfg.black_color.color_g_y = 0; > > + blnd_cfg.black_color.color_r_cr = 0; > > + > > + /* DCN1.0 has output CM before MPC which seems to screw with > > + * pre-multiplied alpha. This is a w/a hopefully unnecessary for DCN2. > > + */ > > + blnd_cfg.pre_multiplied_alpha = per_pixel_alpha; > > + > > + /* > > + * TODO: remove hack > > + * Note: currently there is a bug in init_hw such that > > + * on resume from hibernate, BIOS sets up MPCC0, and > > + * we do mpcc_remove but the mpcc cannot go to idle > > + * after remove. This cause us to pick mpcc1 here, > > + * which causes a pstate hang for yet unknown reason. > > + */ > > + dpp_id = hubp->inst; > > + mpcc_id = dpp_id; > > + > > + /* If there is no full update, don't need to touch MPC tree*/ > > + if (!pipe_ctx->plane_state->update_flags.bits.full_update) { > > + dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id); > > + mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id); > > + return; > > + } > > + > > + /* check if this plane is being used by an MPCC in the secondary blending chain */ > > + if (mpc->funcs->get_mpcc_for_dpp_from_secondary) > > + remove_mpcc = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id); > > + > > + /* remove MPCC from secondary if being used */ > > + if (remove_mpcc != NULL && mpc->funcs->remove_mpcc_from_secondary) > > + mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, remove_mpcc); > > + > > + /* check if this MPCC is already being used for this plane (dpp) in the primary blending chain */ > > + remove_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id); > > + /* remove MPCC if being used */ > > + > > + if (remove_mpcc != NULL) > > + mpc->funcs->remove_mpcc(mpc, mpc_tree_params, remove_mpcc); > > + else > > + if (dc->debug.sanity_checks) > > + mpc->funcs->assert_mpcc_idle_before_connect( > > + dc->res_pool->mpc, mpcc_id); > > + > > + /* Call MPC to insert new plane */ > > + dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id); > > + new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc, > > + mpc_tree_params, > > + &blnd_cfg, > > + NULL, > > + NULL, > > + dpp_id, > > + mpcc_id); > > + > > + ASSERT(new_mpcc != NULL); > > + hubp->opp_id = pipe_ctx->stream_res.opp->inst; > > + hubp->mpcc_id = mpcc_id; > > +} > > + > > +void dcn201_pipe_control_lock( > > + struct dc *dc, > > + struct pipe_ctx *pipe, > > + bool lock) > > +{ > > + struct dce_hwseq *hws = dc->hwseq; > > + struct hubp *hubp = NULL; > > + hubp = dc->res_pool->hubps[pipe->pipe_idx]; > > + /* use TG master update lock to lock everything on the TG > > + * therefore only top pipe need to lock > > + */ > > + if (pipe->top_pipe) > > + return; > > + > > + if (dc->debug.sanity_checks) > > + hws->funcs.verify_allow_pstate_change_high(dc); > > + > > + if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) { > > + if (lock) > > + pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg); > > + else > > + pipe->stream_res.tg->funcs->triplebuffer_unlock(pipe->stream_res.tg); > > + } else { > > + if (lock) > > + pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg); > > + else > > + pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg); > > + } > > + > > + if (dc->debug.sanity_checks) > > + hws->funcs.verify_allow_pstate_change_high(dc); > > +} > > + > > +void dcn201_set_cursor_attribute(struct pipe_ctx *pipe_ctx) > > +{ > > + struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; > > + > > + gpu_addr_to_uma(pipe_ctx->stream->ctx->dc->hwseq, &attributes->address); > > + > > + pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes( > > + pipe_ctx->plane_res.hubp, attributes); > > + pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes( > > + pipe_ctx->plane_res.dpp, attributes); > > +} > > + > > +void dcn201_set_dmdata_attributes(struct pipe_ctx *pipe_ctx) > > +{ > > + struct dc_dmdata_attributes attr = { 0 }; > > + struct hubp *hubp = pipe_ctx->plane_res.hubp; > > + > > + gpu_addr_to_uma(pipe_ctx->stream->ctx->dc->hwseq, > > + &pipe_ctx->stream->dmdata_address); > > + > > + attr.dmdata_mode = DMDATA_HW_MODE; > > + attr.dmdata_size = > > + dc_is_hdmi_signal(pipe_ctx->stream->signal) ? 32 : 36; > > + attr.address.quad_part = > > + pipe_ctx->stream->dmdata_address.quad_part; > > + attr.dmdata_dl_delta = 0; > > + attr.dmdata_qos_mode = 0; > > + attr.dmdata_qos_level = 0; > > + attr.dmdata_repeat = 1; /* always repeat */ > > + attr.dmdata_updated = 1; > > + attr.dmdata_sw_data = NULL; > > + > > + hubp->funcs->dmdata_set_attributes(hubp, &attr); > > +} > > + > > +void dcn201_unblank_stream(struct pipe_ctx *pipe_ctx, > > + struct dc_link_settings *link_settings) > > +{ > > + struct encoder_unblank_param params = { { 0 } }; > > + struct dc_stream_state *stream = pipe_ctx->stream; > > + struct dc_link *link = stream->link; > > + struct dce_hwseq *hws = link->dc->hwseq; > > + > > + /* only 3 items below are used by unblank */ > > + params.timing = pipe_ctx->stream->timing; > > + > > + params.link_settings.link_rate = link_settings->link_rate; > > + > > + if (dc_is_dp_signal(pipe_ctx->stream->signal)) { > > + /*check whether it is half the rate*/ > > + if (optc201_is_two_pixels_per_containter(&stream->timing)) > > + params.timing.pix_clk_100hz /= 2; > > + > > + pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, ¶ms); > > + } > > + > > + if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { > > + hws->funcs.edp_backlight_control(link, true); > > + } > > +} > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.h > > new file mode 100644 > > index 0000000..3ee6747 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.h > > @@ -0,0 +1,46 @@ > > +/* > > +* Copyright 2016 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#ifndef __DC_HWSS_DCN201_H__ > > +#define __DC_HWSS_DCN201_H__ > > + > > +#include "hw_sequencer_private.h" > > + > > +void dcn201_set_dmdata_attributes(struct pipe_ctx *pipe_ctx); > > +void dcn201_init_hw(struct dc *dc); > > +void dcn201_unblank_stream(struct pipe_ctx *pipe_ctx, > > + struct dc_link_settings *link_settings); > > +void dcn201_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx); > > +void dcn201_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx); > > +void dcn201_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx); > > +void dcn201_set_cursor_attribute(struct pipe_ctx *pipe_ctx); > > +void dcn201_pipe_control_lock( > > + struct dc *dc, > > + struct pipe_ctx *pipe, > > + bool lock); > > +void dcn201_init_blank( > > + struct dc *dc, > > + struct timing_generator *tg); > > +#endif /* __DC_HWSS_DCN201_H__ */ > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.c > > new file mode 100644 > > index 0000000..f1f89f9 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.c > > @@ -0,0 +1,131 @@ > > +/* > > + * Copyright 2016 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#include "dce110/dce110_hw_sequencer.h" > > +#include "dcn10/dcn10_hw_sequencer.h" > > +#include "dcn20/dcn20_hwseq.h" > > +#include "dcn201_hwseq.h" > > + > > +static const struct hw_sequencer_funcs dcn201_funcs = { > > + .program_gamut_remap = dcn10_program_gamut_remap, > > + .init_hw = dcn201_init_hw, > > + .power_down_on_boot = NULL, > > + .apply_ctx_to_hw = dce110_apply_ctx_to_hw, > > + .apply_ctx_for_surface = NULL, > > + .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, > > + .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, > > + .post_unlock_program_front_end = dcn10_post_unlock_program_front_end, > > + .update_plane_addr = dcn201_update_plane_addr, > > + .update_dchub = dcn10_update_dchub, > > + .update_pending_status = dcn10_update_pending_status, > > + .program_output_csc = dcn20_program_output_csc, > > + .enable_accelerated_mode = dce110_enable_accelerated_mode, > > + .enable_timing_synchronization = dcn10_enable_timing_synchronization, > > + .enable_per_frame_crtc_position_reset = dcn10_enable_per_frame_crtc_position_reset, > > + .update_info_frame = dce110_update_info_frame, > > + .send_immediate_sdp_message = dcn10_send_immediate_sdp_message, > > + .enable_stream = dce110_enable_stream, > > + .disable_stream = dce110_disable_stream, > > + .unblank_stream = dcn201_unblank_stream, > > + .blank_stream = dce110_blank_stream, > > + .enable_audio_stream = dce110_enable_audio_stream, > > + .disable_audio_stream = dce110_disable_audio_stream, > > + .disable_plane = dcn10_disable_plane, > > + .pipe_control_lock = dcn201_pipe_control_lock, > > + .interdependent_update_lock = dcn10_lock_all_pipes, > > + .cursor_lock = dcn10_cursor_lock, > > + .prepare_bandwidth = dcn20_prepare_bandwidth, > > + .optimize_bandwidth = dcn20_optimize_bandwidth, > > + .update_bandwidth = dcn20_update_bandwidth, > > + .set_drr = dcn10_set_drr, > > + .get_position = dcn10_get_position, > > + .set_static_screen_control = dcn10_set_static_screen_control, > > + .setup_stereo = dcn10_setup_stereo, > > + .set_avmute = dce110_set_avmute, > > + .log_hw_state = dcn10_log_hw_state, > > + .get_hw_state = dcn10_get_hw_state, > > + .clear_status_bits = dcn10_clear_status_bits, > > + .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect, > > + .edp_backlight_control = dce110_edp_backlight_control, > > + .edp_power_control = dce110_edp_power_control, > > + .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready, > > + .setup_periodic_interrupt = dcn10_setup_periodic_interrupt, > > + .set_clock = dcn10_set_clock, > > + .get_clock = dcn10_get_clock, > > + .program_triplebuffer = dcn20_program_triple_buffer, > > + .dmdata_status_done = dcn20_dmdata_status_done, > > + .set_dmdata_attributes = dcn201_set_dmdata_attributes, > > + .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, > > + .calc_vupdate_position = dcn10_calc_vupdate_position, > > + .set_cursor_position = dcn10_set_cursor_position, > > + .set_cursor_attribute = dcn201_set_cursor_attribute, > > + .set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level, > > + .set_backlight_level = dce110_set_backlight_level, > > + .set_abm_immediate_disable = dce110_set_abm_immediate_disable, > > + .set_pipe = dce110_set_pipe, > > + .set_disp_pattern_generator = dcn20_set_disp_pattern_generator, > > + .update_visual_confirm_color = dcn20_update_visual_confirm_color, > > +}; > > + > > +static const struct hwseq_private_funcs dcn201_private_funcs = { > > + .init_pipes = NULL, > > + .update_plane_addr = dcn201_update_plane_addr, > > + .plane_atomic_disconnect = dcn201_plane_atomic_disconnect, > > + .program_pipe = dcn10_program_pipe, > > + .update_mpcc = dcn201_update_mpcc, > > + .set_input_transfer_func = dcn20_set_input_transfer_func, > > + .set_output_transfer_func = dcn20_set_output_transfer_func, > > + .power_down = dce110_power_down, > > + .enable_display_power_gating = dcn10_dummy_display_power_gating, > > + .blank_pixel_data = dcn20_blank_pixel_data, > > + .reset_hw_ctx_wrap = dcn10_reset_hw_ctx_wrap, > > + .enable_stream_timing = dcn20_enable_stream_timing, > > + .edp_backlight_control = dce110_edp_backlight_control, > > + .disable_stream_gating = NULL, > > + .enable_stream_gating = NULL, > > + .setup_vupdate_interrupt = dcn20_setup_vupdate_interrupt, > > + .did_underflow_occur = dcn10_did_underflow_occur, > > + .init_blank = dcn201_init_blank, > > + .disable_vga = dcn10_disable_vga, > > + .bios_golden_init = dcn10_bios_golden_init, > > + .plane_atomic_disable = dcn10_plane_atomic_disable, > > + .plane_atomic_power_down = dcn10_plane_atomic_power_down, > > + .enable_power_gating_plane = dcn10_enable_power_gating_plane, > > + .dpp_pg_control = dcn10_dpp_pg_control, > > + .hubp_pg_control = dcn10_hubp_pg_control, > > + .dsc_pg_control = NULL, > > + .set_hdr_multiplier = dcn10_set_hdr_multiplier, > > + .verify_allow_pstate_change_high = dcn10_verify_allow_pstate_change_high, > > + .wait_for_blank_complete = dcn20_wait_for_blank_complete, > > + .dccg_init = dcn20_dccg_init, > > + .set_blend_lut = dcn20_set_blend_lut, > > + .set_shaper_3dlut = dcn20_set_shaper_3dlut, > > +}; > > + > > +void dcn201_hw_sequencer_construct(struct dc *dc) > > +{ > > + dc->hwss = dcn201_funcs; > > + dc->hwseq->funcs = dcn201_private_funcs; > > +} > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.h b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.h > > new file mode 100644 > > index 0000000..1168887 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.h > > @@ -0,0 +1,33 @@ > > +/* > > + * Copyright 2016 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#ifndef __DC_DCN201_INIT_H__ > > +#define __DC_DCN201_INIT_H__ > > + > > +struct dc; > > + > > +void dcn201_hw_sequencer_construct(struct dc *dc); > > + > > +#endif /* __DC_DCN201_INIT_H__ */ > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.c > > new file mode 100644 > > index 0000000..a65e8f7 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.c > > @@ -0,0 +1,209 @@ > > +/* > > + * Copyright 2012-15 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#include "reg_helper.h" > > + > > +#include "core_types.h" > > +#include "link_encoder.h" > > +#include "dcn201_link_encoder.h" > > +#include "stream_encoder.h" > > +#include "i2caux_interface.h" > > +#include "dc_bios_types.h" > > + > > +#include "gpio_service_interface.h" > > + > > +#define CTX \ > > + enc10->base.ctx > > + > > +#define DC_LOGGER \ > > + enc10->base.ctx->logger > > + > > +#define REG(reg)\ > > + (enc10->link_regs->reg) > > + > > +#undef FN > > +#define FN(reg_name, field_name) \ > > + enc10->link_shift->field_name, enc10->link_mask->field_name > > + > > +#define IND_REG(index) \ > > + (enc10->link_regs->index) > > + > > +void dcn201_link_encoder_get_max_link_cap(struct link_encoder *enc, > > + struct dc_link_settings *link_settings) > > +{ > > + uint32_t value1, value2; > > + struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); > > + > > + dcn10_link_encoder_get_max_link_cap(enc, link_settings); > > + REG_GET_2(RDPCSTX_PHY_CNTL2, RDPCS_PHY_DPALT_DISABLE, &value1, > > + RDPCS_PHY_DPALT_DP4, &value2); > > + /*limit to combo_phy*/ > > + if (enc->usbc_combo_phy) { > > + if (!value1 && !value2 && link_settings->lane_count > LANE_COUNT_TWO) > > + link_settings->lane_count = LANE_COUNT_TWO; > > + } > > +} > > + > > +bool dcn201_link_encoder_is_in_alt_mode(struct link_encoder *enc) > > +{ > > + uint32_t value; > > + struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); > > + > > + REG_GET(RDPCSTX_PHY_CNTL2, RDPCS_PHY_DPALT_DISABLE, &value); > > + > > + // if value == 1 alt mode is disabled, otherwise it is enabled > > + return !value; > > +} > > + > > +static const struct link_encoder_funcs dcn201_link_enc_funcs = { > > + .read_state = link_enc2_read_state, > > + .validate_output_with_stream = > > + dcn10_link_encoder_validate_output_with_stream, > > + .hw_init = enc2_hw_init, > > + .setup = dcn10_link_encoder_setup, > > + .enable_tmds_output = dcn10_link_encoder_enable_tmds_output, > > + .enable_dp_output = dcn10_link_encoder_enable_dp_output, > > + .enable_dp_mst_output = dcn10_link_encoder_enable_dp_mst_output, > > + .disable_output = dcn10_link_encoder_disable_output, > > + .dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings, > > + .dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern, > > + .update_mst_stream_allocation_table = > > + dcn10_link_encoder_update_mst_stream_allocation_table, > > + .psr_program_dp_dphy_fast_training = > > + dcn10_psr_program_dp_dphy_fast_training, > > + .psr_program_secondary_packet = dcn10_psr_program_secondary_packet, > > + .connect_dig_be_to_fe = dcn10_link_encoder_connect_dig_be_to_fe, > > + .enable_hpd = dcn10_link_encoder_enable_hpd, > > + .disable_hpd = dcn10_link_encoder_disable_hpd, > > + .is_dig_enabled = dcn10_is_dig_enabled, > > + .destroy = dcn10_link_encoder_destroy, > > + .fec_set_enable = enc2_fec_set_enable, > > + .fec_set_ready = enc2_fec_set_ready, > > + .get_dig_frontend = dcn10_get_dig_frontend, > > + .fec_is_active = enc2_fec_is_active, > > + .is_in_alt_mode = dcn201_link_encoder_is_in_alt_mode, > > + .get_max_link_cap = dcn201_link_encoder_get_max_link_cap, > > +}; > > + > > +void dcn201_link_encoder_construct( > > + struct dcn20_link_encoder *enc20, > > + const struct encoder_init_data *init_data, > > + const struct encoder_feature_support *enc_features, > > + const struct dcn10_link_enc_registers *link_regs, > > + const struct dcn10_link_enc_aux_registers *aux_regs, > > + const struct dcn10_link_enc_hpd_registers *hpd_regs, > > + const struct dcn10_link_enc_shift *link_shift, > > + const struct dcn10_link_enc_mask *link_mask) > > +{ > > + struct bp_encoder_cap_info bp_cap_info = {0}; > > + const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs; > > + enum bp_result result = BP_RESULT_OK; > > + struct dcn10_link_encoder *enc10 = &enc20->enc10; > > + > > + enc10->base.funcs = &dcn201_link_enc_funcs; > > + enc10->base.ctx = init_data->ctx; > > + enc10->base.id = init_data->encoder; > > + > > + enc10->base.hpd_source = init_data->hpd_source; > > + enc10->base.connector = init_data->connector; > > + > > + enc10->base.preferred_engine = ENGINE_ID_UNKNOWN; > > + > > + enc10->base.features = *enc_features; > > + > > + enc10->base.transmitter = init_data->transmitter; > > + > > + /* set the flag to indicate whether driver poll the I2C data pin > > + * while doing the DP sink detect > > + */ > > + > > + /* if (dal_adapter_service_is_feature_supported(as, > > + * FEATURE_DP_SINK_DETECT_POLL_DATA_PIN)) > > + * enc10->base.features.flags.bits. > > + * DP_SINK_DETECT_POLL_DATA_PIN = true; > > + */ > > + > > + enc10->base.output_signals = > > + SIGNAL_TYPE_DVI_SINGLE_LINK | > > + SIGNAL_TYPE_DVI_DUAL_LINK | > > + SIGNAL_TYPE_LVDS | > > + SIGNAL_TYPE_DISPLAY_PORT | > > + SIGNAL_TYPE_DISPLAY_PORT_MST | > > + SIGNAL_TYPE_EDP | > > + SIGNAL_TYPE_HDMI_TYPE_A; > > + > > + /* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE. > > + * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY. > > + * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer > > + * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS. > > + * Prefer DIG assignment is decided by board design. > > + * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design > > + * and VBIOS will filter out 7 UNIPHY for DCE 8.0. > > + * By this, adding DIGG should not hurt DCE 8.0. > > + * This will let DCE 8.1 share DCE 8.0 as much as possible > > + */ > > + > > + enc10->link_regs = link_regs; > > + enc10->aux_regs = aux_regs; > > + enc10->hpd_regs = hpd_regs; > > + enc10->link_shift = link_shift; > > + enc10->link_mask = link_mask; > > + > > + switch (enc10->base.transmitter) { > > + case TRANSMITTER_UNIPHY_A: > > + enc10->base.preferred_engine = ENGINE_ID_DIGA; > > + break; > > + case TRANSMITTER_UNIPHY_B: > > + enc10->base.preferred_engine = ENGINE_ID_DIGB; > > + break; > > + default: > > + ASSERT_CRITICAL(false); > > + enc10->base.preferred_engine = ENGINE_ID_UNKNOWN; > > + } > > + > > + /* default to one to mirror Windows behavior */ > > + enc10->base.features.flags.bits.HDMI_6GB_EN = 1; > > + > > + result = bp_funcs->get_encoder_cap_info(enc10->base.ctx->dc_bios, > > + enc10->base.id, &bp_cap_info); > > + > > + /* Override features with DCE-specific values */ > > + if (result == BP_RESULT_OK) { > > + enc10->base.features.flags.bits.IS_HBR2_CAPABLE = > > + bp_cap_info.DP_HBR2_EN; > > + enc10->base.features.flags.bits.IS_HBR3_CAPABLE = > > + bp_cap_info.DP_HBR3_EN; > > + enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; > > + enc10->base.features.flags.bits.DP_IS_USB_C = > > + bp_cap_info.DP_IS_USB_C; > > + } else { > > + DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", > > + __func__, > > + result); > > + } > > + if (enc10->base.ctx->dc->debug.hdmi20_disable) { > > + enc10->base.features.flags.bits.HDMI_6GB_EN = 0; > > + } > > +} > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.h > > new file mode 100644 > > index 0000000..8b95ef2 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.h > > @@ -0,0 +1,59 @@ > > +/* > > + * Copyright 2012-15 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#ifndef __DC_LINK_ENCODER__DCN201_H__ > > +#define __DC_LINK_ENCODER__DCN201_H__ > > + > > +#include "dcn20/dcn20_link_encoder.h" > > + > > +#define DPCS_DCN201_MASK_SH_LIST(mask_sh)\ > > + DPCS_MASK_SH_LIST(mask_sh),\ > > + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL2, RDPCS_PHY_DPALT_DISABLE_ACK, mask_sh),\ > > + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL2, RDPCS_PHY_DPALT_DISABLE, mask_sh),\ > > + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL2, RDPCS_PHY_DPALT_DP4, mask_sh),\ > > + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL5, RDPCS_PHY_DP_TX0_PSTATE, mask_sh),\ > > + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL5, RDPCS_PHY_DP_TX1_PSTATE, mask_sh),\ > > + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL5, RDPCS_PHY_DP_TX0_MPLL_EN, mask_sh),\ > > + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL5, RDPCS_PHY_DP_TX1_MPLL_EN, mask_sh),\ > > + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX2_WIDTH, mask_sh),\ > > + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX2_RATE, mask_sh),\ > > + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX3_WIDTH, mask_sh),\ > > + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX3_RATE, mask_sh),\ > > + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL11, RDPCS_PHY_DP_REF_CLK_EN, mask_sh) > > + > > +#define DPCS_DCN201_REG_LIST(id) \ > > + DPCS_DCN2_CMN_REG_LIST(id) > > + > > +void dcn201_link_encoder_construct( > > + struct dcn20_link_encoder *enc20, > > + const struct encoder_init_data *init_data, > > + const struct encoder_feature_support *enc_features, > > + const struct dcn10_link_enc_registers *link_regs, > > + const struct dcn10_link_enc_aux_registers *aux_regs, > > + const struct dcn10_link_enc_hpd_registers *hpd_regs, > > + const struct dcn10_link_enc_shift *link_shift, > > + const struct dcn10_link_enc_mask *link_mask); > > + > > +#endif /* __DC_LINK_ENCODER__DCN201_H__ */ > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_mpc.c > > new file mode 100644 > > index 0000000..95c4c55 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_mpc.c > > @@ -0,0 +1,125 @@ > > +/* > > + * Copyright 2012-15 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#include "reg_helper.h" > > +#include "dcn201_mpc.h" > > + > > +#define REG(reg)\ > > + mpc201->mpc_regs->reg > > + > > +#define CTX \ > > + mpc201->base.ctx > > + > > +#define DC_LOGGER \ > > + mpc201->base.ctx->logger > > + > > +#undef FN > > +#define FN(reg_name, field_name) \ > > + mpc201->mpc_shift->field_name, mpc201->mpc_mask->field_name > > + > > +static void mpc201_set_out_rate_control( > > + struct mpc *mpc, > > + int opp_id, > > + bool enable, > > + bool rate_2x_mode, > > + struct mpc_dwb_flow_control *flow_control) > > +{ > > + struct dcn201_mpc *mpc201 = TO_DCN201_MPC(mpc); > > + > > + REG_UPDATE_2(MUX[opp_id], > > + MPC_OUT_RATE_CONTROL_DISABLE, !enable, > > + MPC_OUT_RATE_CONTROL, rate_2x_mode); > > + > > + if (flow_control) > > + REG_UPDATE_3(MUX[opp_id], > > + MPC_OUT_FLOW_CONTROL_MODE, flow_control->flow_ctrl_mode, > > + MPC_OUT_FLOW_CONTROL_COUNT0, flow_control->flow_ctrl_cnt0, > > + MPC_OUT_FLOW_CONTROL_COUNT1, flow_control->flow_ctrl_cnt1); > > +} > > + > > +static void mpc201_init_mpcc(struct mpcc *mpcc, int mpcc_inst) > > +{ > > + mpcc->mpcc_id = mpcc_inst; > > + mpcc->dpp_id = 0xf; > > + mpcc->mpcc_bot = NULL; > > + mpcc->blnd_cfg.overlap_only = false; > > + mpcc->blnd_cfg.global_alpha = 0xff; > > + mpcc->blnd_cfg.global_gain = 0xff; > > + mpcc->blnd_cfg.background_color_bpc = 4; > > + mpcc->blnd_cfg.bottom_gain_mode = 0; > > + mpcc->blnd_cfg.top_gain = 0x1f000; > > + mpcc->blnd_cfg.bottom_inside_gain = 0x1f000; > > + mpcc->blnd_cfg.bottom_outside_gain = 0x1f000; > > + mpcc->sm_cfg.enable = false; > > + mpcc->shared_bottom = false; > > +} > > + > > +const struct mpc_funcs dcn201_mpc_funcs = { > > + .read_mpcc_state = mpc1_read_mpcc_state, > > + .insert_plane = mpc1_insert_plane, > > + .remove_mpcc = mpc1_remove_mpcc, > > + .mpc_init = mpc1_mpc_init, > > + .mpc_init_single_inst = mpc1_mpc_init_single_inst, > > + .update_blending = mpc2_update_blending, > > + .cursor_lock = mpc1_cursor_lock, > > + .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp, > > + .get_mpcc_for_dpp_from_secondary = NULL, > > + .wait_for_idle = mpc2_assert_idle_mpcc, > > + .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect, > > + .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw, > > + .set_denorm = mpc2_set_denorm, > > + .set_denorm_clamp = mpc2_set_denorm_clamp, > > + .set_output_csc = mpc2_set_output_csc, > > + .set_ocsc_default = mpc2_set_ocsc_default, > > + .set_output_gamma = mpc2_set_output_gamma, > > + .set_out_rate_control = mpc201_set_out_rate_control, > > + .power_on_mpc_mem_pwr = mpc20_power_on_ogam_lut, > > + .get_mpc_out_mux = mpc1_get_mpc_out_mux, > > + .set_bg_color = mpc1_set_bg_color, > > +}; > > + > > +void dcn201_mpc_construct(struct dcn201_mpc *mpc201, > > + struct dc_context *ctx, > > + const struct dcn201_mpc_registers *mpc_regs, > > + const struct dcn201_mpc_shift *mpc_shift, > > + const struct dcn201_mpc_mask *mpc_mask, > > + int num_mpcc) > > +{ > > + int i; > > + > > + mpc201->base.ctx = ctx; > > + > > + mpc201->base.funcs = &dcn201_mpc_funcs; > > + > > + mpc201->mpc_regs = mpc_regs; > > + mpc201->mpc_shift = mpc_shift; > > + mpc201->mpc_mask = mpc_mask; > > + > > + mpc201->mpcc_in_use_mask = 0; > > + mpc201->num_mpcc = num_mpcc; > > + > > + for (i = 0; i < MAX_MPCC; i++) > > + mpc201_init_mpcc(&mpc201->base.mpcc_array[i], i); > > +} > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_mpc.h > > new file mode 100644 > > index 0000000..b9ce0c1 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_mpc.h > > @@ -0,0 +1,86 @@ > > +/* Copyright 2012-15 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#ifndef __DC_MPCC_DCN201_H__ > > +#define __DC_MPCC_DCN201_H__ > > + > > +#include "dcn20/dcn20_mpc.h" > > + > > +#define TO_DCN201_MPC(mpc_base) \ > > + container_of(mpc_base, struct dcn201_mpc, base) > > + > > +#define MPC_REG_LIST_DCN201(inst) \ > > + MPC_REG_LIST_DCN2_0(inst) > > + > > +#define MPC_OUT_MUX_REG_LIST_DCN201(inst) \ > > + MPC_OUT_MUX_REG_LIST_DCN2_0(inst) > > + > > +#define MPC_REG_VARIABLE_LIST_DCN201 \ > > + MPC_REG_VARIABLE_LIST_DCN2_0 > > + > > +#define MPC_COMMON_MASK_SH_LIST_DCN201(mask_sh) \ > > + MPC_COMMON_MASK_SH_LIST_DCN2_0(mask_sh),\ > > + SF(MPC_OUT0_MUX, MPC_OUT_RATE_CONTROL, mask_sh),\ > > + SF(MPC_OUT0_MUX, MPC_OUT_RATE_CONTROL_DISABLE, mask_sh),\ > > + SF(MPC_OUT0_MUX, MPC_OUT_FLOW_CONTROL_MODE, mask_sh),\ > > + SF(MPC_OUT0_MUX, MPC_OUT_FLOW_CONTROL_COUNT0, mask_sh),\ > > + SF(MPC_OUT0_MUX, MPC_OUT_FLOW_CONTROL_COUNT1, mask_sh) > > + > > +#define MPC_REG_FIELD_LIST_DCN201(type) \ > > + MPC_REG_FIELD_LIST_DCN2_0(type) \ > > + type MPC_OUT_RATE_CONTROL;\ > > + type MPC_OUT_RATE_CONTROL_DISABLE;\ > > + type MPC_OUT_FLOW_CONTROL_MODE;\ > > + type MPC_OUT_FLOW_CONTROL_COUNT0;\ > > + type MPC_OUT_FLOW_CONTROL_COUNT1; > > + > > +struct dcn201_mpc_registers { > > + MPC_REG_VARIABLE_LIST_DCN201 > > +}; > > + > > +struct dcn201_mpc_shift { > > + MPC_REG_FIELD_LIST_DCN201(uint8_t) > > +}; > > + > > +struct dcn201_mpc_mask { > > + MPC_REG_FIELD_LIST_DCN201(uint32_t) > > +}; > > + > > +struct dcn201_mpc { > > + struct mpc base; > > + int mpcc_in_use_mask; > > + int num_mpcc; > > + const struct dcn201_mpc_registers *mpc_regs; > > + const struct dcn201_mpc_shift *mpc_shift; > > + const struct dcn201_mpc_mask *mpc_mask; > > +}; > > + > > +void dcn201_mpc_construct(struct dcn201_mpc *mpc201, > > + struct dc_context *ctx, > > + const struct dcn201_mpc_registers *mpc_regs, > > + const struct dcn201_mpc_shift *mpc_shift, > > + const struct dcn201_mpc_mask *mpc_mask, > > + int num_mpcc); > > + > > +#endif > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_opp.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_opp.c > > new file mode 100644 > > index 0000000..8e77db4 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_opp.c > > @@ -0,0 +1,72 @@ > > +/* > > + * Copyright 2012-15 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#include "dm_services.h" > > +#include "dcn201_opp.h" > > +#include "reg_helper.h" > > + > > +#define REG(reg) \ > > + (oppn201->regs->reg) > > + > > +#undef FN > > +#define FN(reg_name, field_name) \ > > + oppn201->opp_shift->field_name, oppn201->opp_mask->field_name > > + > > +#define CTX \ > > + oppn201->base.ctx > > + > > +/*****************************************/ > > +/* Constructor, Destructor */ > > +/*****************************************/ > > + > > +static struct opp_funcs dcn201_opp_funcs = { > > + .opp_set_dyn_expansion = opp1_set_dyn_expansion, > > + .opp_program_fmt = opp1_program_fmt, > > + .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction, > > + .opp_program_stereo = opp1_program_stereo, > > + .opp_pipe_clock_control = opp1_pipe_clock_control, > > + .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator, > > + .opp_program_dpg_dimensions = opp2_program_dpg_dimensions, > > + .dpg_is_blanked = opp2_dpg_is_blanked, > > + .opp_dpg_set_blank_color = opp2_dpg_set_blank_color, > > + .opp_destroy = opp1_destroy, > > + .opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel, > > +}; > > + > > +void dcn201_opp_construct(struct dcn201_opp *oppn201, > > + struct dc_context *ctx, > > + uint32_t inst, > > + const struct dcn201_opp_registers *regs, > > + const struct dcn201_opp_shift *opp_shift, > > + const struct dcn201_opp_mask *opp_mask) > > +{ > > + oppn201->base.ctx = ctx; > > + oppn201->base.inst = inst; > > + oppn201->base.funcs = &dcn201_opp_funcs; > > + > > + oppn201->regs = regs; > > + oppn201->opp_shift = opp_shift; > > + oppn201->opp_mask = opp_mask; > > +} > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_opp.h b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_opp.h > > new file mode 100644 > > index 0000000..aca389ec > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_opp.h > > @@ -0,0 +1,74 @@ > > +/* Copyright 2012-15 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#ifndef __DC_OPP_DCN201_H__ > > +#define __DC_OPP_DCN201_H__ > > + > > +#include "dcn20/dcn20_opp.h" > > + > > +#define TO_DCN201_OPP(opp)\ > > + container_of(opp, struct dcn201_opp, base) > > + > > +#define OPP_SF(reg_name, field_name, post_fix)\ > > + .field_name = reg_name ## __ ## field_name ## post_fix > > + > > +#define OPP_REG_LIST_DCN201(id) \ > > + OPP_REG_LIST_DCN10(id), \ > > + OPP_DPG_REG_LIST(id), \ > > + SRI(FMT_422_CONTROL, FMT, id) > > + > > +#define OPP_MASK_SH_LIST_DCN201(mask_sh) \ > > + OPP_MASK_SH_LIST_DCN20(mask_sh) > > + > > +#define OPP_DCN201_REG_FIELD_LIST(type) \ > > + OPP_DCN20_REG_FIELD_LIST(type); > > + > > +struct dcn201_opp_shift { > > + OPP_DCN201_REG_FIELD_LIST(uint8_t); > > +}; > > + > > +struct dcn201_opp_mask { > > + OPP_DCN201_REG_FIELD_LIST(uint32_t); > > +}; > > + > > +struct dcn201_opp_registers { > > + OPP_REG_VARIABLE_LIST_DCN2_0; > > +}; > > + > > +struct dcn201_opp { > > + struct output_pixel_processor base; > > + const struct dcn201_opp_registers *regs; > > + const struct dcn201_opp_shift *opp_shift; > > + const struct dcn201_opp_mask *opp_mask; > > + bool is_write_to_ram_a_safe; > > +}; > > + > > +void dcn201_opp_construct(struct dcn201_opp *oppn201, > > + struct dc_context *ctx, > > + uint32_t inst, > > + const struct dcn201_opp_registers *regs, > > + const struct dcn201_opp_shift *opp_shift, > > + const struct dcn201_opp_mask *opp_mask); > > + > > +#endif > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_optc.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_optc.c > > new file mode 100644 > > index 0000000..730875d > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_optc.c > > @@ -0,0 +1,203 @@ > > +/* > > + * Copyright 2012-15 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#include "reg_helper.h" > > +#include "dcn201_optc.h" > > +#include "dcn10/dcn10_optc.h" > > +#include "dc.h" > > + > > +#define REG(reg)\ > > + optc1->tg_regs->reg > > + > > +#define CTX \ > > + optc1->base.ctx > > + > > +#undef FN > > +#define FN(reg_name, field_name) \ > > + optc1->tg_shift->field_name, optc1->tg_mask->field_name > > + > > +/*TEMP: Need to figure out inheritance model here.*/ > > +bool optc201_is_two_pixels_per_containter(const struct dc_crtc_timing *timing) > > +{ > > + return optc1_is_two_pixels_per_containter(timing); > > +} > > + > > +static void optc201_triplebuffer_lock(struct timing_generator *optc) > > +{ > > + struct optc *optc1 = DCN10TG_FROM_TG(optc); > > + > > + REG_SET(OTG_GLOBAL_CONTROL0, 0, > > + OTG_MASTER_UPDATE_LOCK_SEL, optc->inst); > > + REG_SET(OTG_VUPDATE_KEEPOUT, 0, > > + OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, 1); > > + REG_SET(OTG_MASTER_UPDATE_LOCK, 0, > > + OTG_MASTER_UPDATE_LOCK, 1); > > + > > + if (optc->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS) > > + REG_WAIT(OTG_MASTER_UPDATE_LOCK, > > + UPDATE_LOCK_STATUS, 1, > > + 1, 10); > > +} > > + > > +static void optc201_triplebuffer_unlock(struct timing_generator *optc) > > +{ > > + struct optc *optc1 = DCN10TG_FROM_TG(optc); > > + > > + REG_SET(OTG_MASTER_UPDATE_LOCK, 0, > > + OTG_MASTER_UPDATE_LOCK, 0); > > + REG_SET(OTG_VUPDATE_KEEPOUT, 0, > > + OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, 0); > > + > > +} > > + > > +static bool optc201_validate_timing( > > + struct timing_generator *optc, > > + const struct dc_crtc_timing *timing) > > +{ > > + uint32_t v_blank; > > + uint32_t h_blank; > > + uint32_t min_v_blank; > > + struct optc *optc1 = DCN10TG_FROM_TG(optc); > > + > > + ASSERT(timing != NULL); > > + > > + v_blank = (timing->v_total - timing->v_addressable - > > + timing->v_border_top - timing->v_border_bottom); > > + > > + h_blank = (timing->h_total - timing->h_addressable - > > + timing->h_border_right - > > + timing->h_border_left); > > + > > + if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE && > > + timing->timing_3d_format != TIMING_3D_FORMAT_HW_FRAME_PACKING && > > + timing->timing_3d_format != TIMING_3D_FORMAT_TOP_AND_BOTTOM && > > + timing->timing_3d_format != TIMING_3D_FORMAT_SIDE_BY_SIDE && > > + timing->timing_3d_format != TIMING_3D_FORMAT_FRAME_ALTERNATE && > > + timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA) > > + return false; > > + > > + /* Check maximum number of pixels supported by Timing Generator > > + * (Currently will never fail, in order to fail needs display which > > + * needs more than 8192 horizontal and > > + * more than 8192 vertical total pixels) > > + */ > > + if (timing->h_total > optc1->max_h_total || > > + timing->v_total > optc1->max_v_total) > > + return false; > > + > > + if (h_blank < optc1->min_h_blank) > > + return false; > > + > > + if (timing->h_sync_width < optc1->min_h_sync_width || > > + timing->v_sync_width < optc1->min_v_sync_width) > > + return false; > > + > > + min_v_blank = timing->flags.INTERLACE?optc1->min_v_blank_interlace:optc1->min_v_blank; > > + > > + if (v_blank < min_v_blank) > > + return false; > > + > > + return true; > > + > > +} > > + > > +static void optc201_get_optc_source(struct timing_generator *optc, > > + uint32_t *num_of_src_opp, > > + uint32_t *src_opp_id_0, > > + uint32_t *src_opp_id_1) > > +{ > > + struct optc *optc1 = DCN10TG_FROM_TG(optc); > > + > > + REG_GET(OPTC_DATA_SOURCE_SELECT, > > + OPTC_SEG0_SRC_SEL, src_opp_id_0); > > + > > + *num_of_src_opp = 1; > > +} > > + > > +static struct timing_generator_funcs dcn201_tg_funcs = { > > + .validate_timing = optc201_validate_timing, > > + .program_timing = optc1_program_timing, > > + .setup_vertical_interrupt0 = optc1_setup_vertical_interrupt0, > > + .setup_vertical_interrupt1 = optc1_setup_vertical_interrupt1, > > + .setup_vertical_interrupt2 = optc1_setup_vertical_interrupt2, > > + .program_global_sync = optc1_program_global_sync, > > + .enable_crtc = optc2_enable_crtc, > > + .disable_crtc = optc1_disable_crtc, > > + /* used by enable_timing_synchronization. Not need for FPGA */ > > + .is_counter_moving = optc1_is_counter_moving, > > + .get_position = optc1_get_position, > > + .get_frame_count = optc1_get_vblank_counter, > > + .get_scanoutpos = optc1_get_crtc_scanoutpos, > > + .get_otg_active_size = optc1_get_otg_active_size, > > + .set_early_control = optc1_set_early_control, > > + /* used by enable_timing_synchronization. Not need for FPGA */ > > + .wait_for_state = optc1_wait_for_state, > > + .set_blank = optc1_set_blank, > > + .is_blanked = optc1_is_blanked, > > + .set_blank_color = optc1_program_blank_color, > > + .did_triggered_reset_occur = optc1_did_triggered_reset_occur, > > + .enable_reset_trigger = optc1_enable_reset_trigger, > > + .enable_crtc_reset = optc1_enable_crtc_reset, > > + .disable_reset_trigger = optc1_disable_reset_trigger, > > + .triplebuffer_lock = optc201_triplebuffer_lock, > > + .triplebuffer_unlock = optc201_triplebuffer_unlock, > > + .lock = optc1_lock, > > + .unlock = optc1_unlock, > > + .enable_optc_clock = optc1_enable_optc_clock, > > + .set_drr = optc1_set_drr, > > + .get_last_used_drr_vtotal = NULL, > > + .set_vtotal_min_max = optc1_set_vtotal_min_max, > > + .set_static_screen_control = optc1_set_static_screen_control, > > + .program_stereo = optc1_program_stereo, > > + .is_stereo_left_eye = optc1_is_stereo_left_eye, > > + .set_blank_data_double_buffer = optc1_set_blank_data_double_buffer, > > + .tg_init = optc1_tg_init, > > + .is_tg_enabled = optc1_is_tg_enabled, > > + .is_optc_underflow_occurred = optc1_is_optc_underflow_occurred, > > + .clear_optc_underflow = optc1_clear_optc_underflow, > > + .get_crc = optc1_get_crc, > > + .configure_crc = optc2_configure_crc, > > + .set_dsc_config = optc2_set_dsc_config, > > + .set_dwb_source = NULL, > > + .get_optc_source = optc201_get_optc_source, > > + .set_vtg_params = optc1_set_vtg_params, > > + .program_manual_trigger = optc2_program_manual_trigger, > > + .setup_manual_trigger = optc2_setup_manual_trigger, > > + .get_hw_timing = optc1_get_hw_timing, > > +}; > > + > > +void dcn201_timing_generator_init(struct optc *optc1) > > +{ > > + optc1->base.funcs = &dcn201_tg_funcs; > > + > > + optc1->max_h_total = optc1->tg_mask->OTG_H_TOTAL + 1; > > + optc1->max_v_total = optc1->tg_mask->OTG_V_TOTAL + 1; > > + > > + optc1->min_h_blank = 32; > > + optc1->min_v_blank = 3; > > + optc1->min_v_blank_interlace = 5; > > + optc1->min_h_sync_width = 8; > > + optc1->min_v_sync_width = 1; > > +} > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_optc.h b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_optc.h > > new file mode 100644 > > index 0000000..e9545b7 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_optc.h > > @@ -0,0 +1,74 @@ > > +/* > > + * Copyright 2012-15 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#ifndef __DC_OPTC_DCN201_H__ > > +#define __DC_OPTC_DCN201_H__ > > + > > +#include "dcn20/dcn20_optc.h" > > + > > +#define TG_COMMON_REG_LIST_DCN201(inst) \ > > + TG_COMMON_REG_LIST_DCN(inst),\ > > + SRI(OTG_GLOBAL_CONTROL1, OTG, inst),\ > > + SRI(OTG_GLOBAL_CONTROL2, OTG, inst),\ > > + SRI(OTG_GSL_WINDOW_X, OTG, inst),\ > > + SRI(OTG_GSL_WINDOW_Y, OTG, inst),\ > > + SRI(OTG_VUPDATE_KEEPOUT, OTG, inst),\ > > + SRI(OTG_DSC_START_POSITION, OTG, inst),\ > > + SRI(OPTC_DATA_FORMAT_CONTROL, ODM, inst),\ > > + SRI(OPTC_BYTES_PER_PIXEL, ODM, inst),\ > > + SRI(OPTC_WIDTH_CONTROL, ODM, inst),\ > > + SR(DWB_SOURCE_SELECT) > > + > > +#define TG_COMMON_MASK_SH_LIST_DCN201(mask_sh)\ > > + TG_COMMON_MASK_SH_LIST_DCN(mask_sh),\ > > + SF(OTG0_OTG_GLOBAL_CONTROL1, MASTER_UPDATE_LOCK_DB_X, mask_sh),\ > > + SF(OTG0_OTG_GLOBAL_CONTROL1, MASTER_UPDATE_LOCK_DB_Y, mask_sh),\ > > + SF(OTG0_OTG_GLOBAL_CONTROL1, MASTER_UPDATE_LOCK_DB_EN, mask_sh),\ > > + SF(OTG0_OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, mask_sh),\ > > + SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_RANGE_TIMING_DBUF_UPDATE_MODE, mask_sh),\ > > + SF(OTG0_OTG_GSL_WINDOW_X, OTG_GSL_WINDOW_START_X, mask_sh),\ > > + SF(OTG0_OTG_GSL_WINDOW_X, OTG_GSL_WINDOW_END_X, mask_sh), \ > > + SF(OTG0_OTG_GSL_WINDOW_Y, OTG_GSL_WINDOW_START_Y, mask_sh),\ > > + SF(OTG0_OTG_GSL_WINDOW_Y, OTG_GSL_WINDOW_END_Y, mask_sh),\ > > + SF(OTG0_OTG_VUPDATE_KEEPOUT, OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, mask_sh), \ > > + SF(OTG0_OTG_VUPDATE_KEEPOUT, MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, mask_sh), \ > > + SF(OTG0_OTG_VUPDATE_KEEPOUT, MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, mask_sh), \ > > + SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_MASTER_MODE, mask_sh), \ > > + SF(OTG0_OTG_GSL_CONTROL, OTG_MASTER_UPDATE_LOCK_GSL_EN, mask_sh), \ > > + SF(OTG0_OTG_DSC_START_POSITION, OTG_DSC_START_POSITION_X, mask_sh), \ > > + SF(OTG0_OTG_DSC_START_POSITION, OTG_DSC_START_POSITION_LINE_NUM, mask_sh),\ > > + SF(ODM0_OPTC_DATA_SOURCE_SELECT, OPTC_SEG0_SRC_SEL, mask_sh),\ > > + SF(ODM0_OPTC_DATA_FORMAT_CONTROL, OPTC_DSC_MODE, mask_sh),\ > > + SF(ODM0_OPTC_BYTES_PER_PIXEL, OPTC_DSC_BYTES_PER_PIXEL, mask_sh),\ > > + SF(ODM0_OPTC_WIDTH_CONTROL, OPTC_DSC_SLICE_WIDTH, mask_sh),\ > > + SF(DWB_SOURCE_SELECT, OPTC_DWB0_SOURCE_SELECT, mask_sh),\ > > + SF(DWB_SOURCE_SELECT, OPTC_DWB1_SOURCE_SELECT, mask_sh),\ > > + SF(DWB_SOURCE_SELECT, OPTC_DWB1_SOURCE_SELECT, mask_sh) > > + > > +void dcn201_timing_generator_init(struct optc *optc); > > + > > +bool optc201_is_two_pixels_per_containter(const struct dc_crtc_timing *timing); > > + > > +#endif > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c > > new file mode 100644 > > index 0000000..aec276e > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c > > @@ -0,0 +1,1307 @@ > > +/* > > +* Copyright 2016 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#include "dm_services.h" > > +#include "dc.h" > > + > > +#include "dcn201_init.h" > > +#include "dml/dcn2x/dcn2x.h" > > +#include "resource.h" > > +#include "include/irq_service_interface.h" > > +#include "dcn201_resource.h" > > + > > +#include "dcn20/dcn20_resource.h" > > + > > +#include "dcn10/dcn10_hubp.h" > > +#include "dcn10/dcn10_ipp.h" > > +#include "dcn201_mpc.h" > > +#include "dcn201_hubp.h" > > +#include "irq/dcn201/irq_service_dcn201.h" > > +#include "dcn201/dcn201_dpp.h" > > +#include "dcn201/dcn201_hubbub.h" > > +#include "dcn201_dccg.h" > > +#include "dcn201_optc.h" > > +#include "dcn201_hwseq.h" > > +#include "dce110/dce110_hw_sequencer.h" > > +#include "dcn201_opp.h" > > +#include "dcn201/dcn201_link_encoder.h" > > +#include "dcn20/dcn20_stream_encoder.h" > > +#include "dce/dce_clock_source.h" > > +#include "dce/dce_audio.h" > > +#include "dce/dce_hwseq.h" > > +#include "virtual/virtual_stream_encoder.h" > > +#include "dce110/dce110_resource.h" > > +#include "dce/dce_aux.h" > > +#include "dce/dce_i2c.h" > > +#include "dcn201_hubbub.h" > > +#include "dcn10/dcn10_resource.h" > > + > > +#include "cyan_skillfish_ip_offset.h" > > + > > +#include "dcn/dcn_2_0_3_offset.h" > > +#include "dcn/dcn_2_0_3_sh_mask.h" > > +#include "dpcs/dpcs_2_0_3_offset.h" > > +#include "dpcs/dpcs_2_0_3_sh_mask.h" > > + > > +#include "mmhub/mmhub_2_0_0_offset.h" > > +#include "mmhub/mmhub_2_0_0_sh_mask.h" > > +#include "nbio/nbio_7_4_offset.h" > > + > > +#include "reg_helper.h" > > + > > +#define MIN_DISP_CLK_KHZ 100000 > > +#define MIN_DPP_CLK_KHZ 100000 > > + > > +struct _vcs_dpi_ip_params_st dcn201_ip = { > > + .gpuvm_enable = 0, > > + .hostvm_enable = 0, > > + .gpuvm_max_page_table_levels = 4, > > + .hostvm_max_page_table_levels = 4, > > + .hostvm_cached_page_table_levels = 0, > > + .pte_group_size_bytes = 2048, > > + .rob_buffer_size_kbytes = 168, > > + .det_buffer_size_kbytes = 164, > > + .dpte_buffer_size_in_pte_reqs_luma = 84, > > + .pde_proc_buffer_size_64k_reqs = 48, > > + .dpp_output_buffer_pixels = 2560, > > + .opp_output_buffer_lines = 1, > > + .pixel_chunk_size_kbytes = 8, > > + .pte_chunk_size_kbytes = 2, > > + .meta_chunk_size_kbytes = 2, > > + .writeback_chunk_size_kbytes = 2, > > + .line_buffer_size_bits = 789504, > > + .is_line_buffer_bpp_fixed = 0, > > + .line_buffer_fixed_bpp = 0, > > + .dcc_supported = true, > > + .max_line_buffer_lines = 12, > > + .writeback_luma_buffer_size_kbytes = 12, > > + .writeback_chroma_buffer_size_kbytes = 8, > > + .writeback_chroma_line_buffer_width_pixels = 4, > > + .writeback_max_hscl_ratio = 1, > > + .writeback_max_vscl_ratio = 1, > > + .writeback_min_hscl_ratio = 1, > > + .writeback_min_vscl_ratio = 1, > > + .writeback_max_hscl_taps = 12, > > + .writeback_max_vscl_taps = 12, > > + .writeback_line_buffer_luma_buffer_size = 0, > > + .writeback_line_buffer_chroma_buffer_size = 9600, > > + .cursor_buffer_size = 8, > > + .cursor_chunk_size = 2, > > + .max_num_otg = 2, > > + .max_num_dpp = 4, > > + .max_num_wb = 0, > > + .max_dchub_pscl_bw_pix_per_clk = 4, > > + .max_pscl_lb_bw_pix_per_clk = 2, > > + .max_lb_vscl_bw_pix_per_clk = 4, > > + .max_vscl_hscl_bw_pix_per_clk = 4, > > + .max_hscl_ratio = 8, > > + .max_vscl_ratio = 8, > > + .hscl_mults = 4, > > + .vscl_mults = 4, > > + .max_hscl_taps = 8, > > + .max_vscl_taps = 8, > > + .dispclk_ramp_margin_percent = 1, > > + .underscan_factor = 1.10, > > + .min_vblank_lines = 30, > > + .dppclk_delay_subtotal = 77, > > + .dppclk_delay_scl_lb_only = 16, > > + .dppclk_delay_scl = 50, > > + .dppclk_delay_cnvc_formatter = 8, > > + .dppclk_delay_cnvc_cursor = 6, > > + .dispclk_delay_subtotal = 87, > > + .dcfclk_cstate_latency = 10, > > + .max_inter_dcn_tile_repeaters = 8, > > + .number_of_cursors = 1, > > +}; > > + > > +struct _vcs_dpi_soc_bounding_box_st dcn201_soc = { > > + .clock_limits = { > > + { > > + .state = 0, > > + .dscclk_mhz = 400.0, > > + .dcfclk_mhz = 1000.0, > > + .fabricclk_mhz = 200.0, > > + .dispclk_mhz = 300.0, > > + .dppclk_mhz = 300.0, > > + .phyclk_mhz = 810.0, > > + .socclk_mhz = 1254.0, > > + .dram_speed_mts = 2000.0, > > + }, > > + { > > + .state = 1, > > + .dscclk_mhz = 400.0, > > + .dcfclk_mhz = 1000.0, > > + .fabricclk_mhz = 250.0, > > + .dispclk_mhz = 1200.0, > > + .dppclk_mhz = 1200.0, > > + .phyclk_mhz = 810.0, > > + .socclk_mhz = 1254.0, > > + .dram_speed_mts = 3600.0, > > + }, > > + { > > + .state = 2, > > + .dscclk_mhz = 400.0, > > + .dcfclk_mhz = 1000.0, > > + .fabricclk_mhz = 750.0, > > + .dispclk_mhz = 1200.0, > > + .dppclk_mhz = 1200.0, > > + .phyclk_mhz = 810.0, > > + .socclk_mhz = 1254.0, > > + .dram_speed_mts = 6800.0, > > + }, > > + { > > + .state = 3, > > + .dscclk_mhz = 400.0, > > + .dcfclk_mhz = 1000.0, > > + .fabricclk_mhz = 250.0, > > + .dispclk_mhz = 1200.0, > > + .dppclk_mhz = 1200.0, > > + .phyclk_mhz = 810.0, > > + .socclk_mhz = 1254.0, > > + .dram_speed_mts = 14000.0, > > + }, > > + { > > + .state = 4, > > + .dscclk_mhz = 400.0, > > + .dcfclk_mhz = 1000.0, > > + .fabricclk_mhz = 750.0, > > + .dispclk_mhz = 1200.0, > > + .dppclk_mhz = 1200.0, > > + .phyclk_mhz = 810.0, > > + .socclk_mhz = 1254.0, > > + .dram_speed_mts = 14000.0, > > + } > > + }, > > + .num_states = 4, > > + .sr_exit_time_us = 9.0, > > + .sr_enter_plus_exit_time_us = 11.0, > > + .urgent_latency_us = 4.0, > > + .urgent_latency_pixel_data_only_us = 4.0, > > + .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, > > + .urgent_latency_vm_data_only_us = 4.0, > > + .urgent_out_of_order_return_per_channel_pixel_only_bytes = 256, > > + .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 256, > > + .urgent_out_of_order_return_per_channel_vm_only_bytes = 256, > > + .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0, > > + .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 80.0, > > + .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 80.0, > > + .max_avg_sdp_bw_use_normal_percent = 80.0, > > + .max_avg_dram_bw_use_normal_percent = 69.0, > > + .writeback_latency_us = 12.0, > > + .ideal_dram_bw_after_urgent_percent = 80.0, > > + .max_request_size_bytes = 256, > > + .dram_channel_width_bytes = 2, > > + .fabric_datapath_to_dcn_data_return_bytes = 64, > > + .dcn_downspread_percent = 0.3, > > + .downspread_percent = 0.3, > > + .dram_page_open_time_ns = 50.0, > > + .dram_rw_turnaround_time_ns = 17.5, > > + .dram_return_buffer_per_channel_bytes = 8192, > > + .round_trip_ping_latency_dcfclk_cycles = 128, > > + .urgent_out_of_order_return_per_channel_bytes = 256, > > + .channel_interleave_bytes = 256, > > + .num_banks = 8, > > + .num_chans = 16, > > + .vmm_page_size_bytes = 4096, > > + .dram_clock_change_latency_us = 250.0, > > + .writeback_dram_clock_change_latency_us = 23.0, > > + .return_bus_width_bytes = 64, > > + .dispclk_dppclk_vco_speed_mhz = 3000, > > + .use_urgent_burst_bw = 0, > > +}; > > + > > +enum dcn20_clk_src_array_id { > > + DCN20_CLK_SRC_PLL0, > > + DCN20_CLK_SRC_PLL1, > > + DCN20_CLK_SRC_TOTAL_DCN201 > > +}; > > + > > +/* begin ********************* > > + * macros to expend register list macro defined in HW object header file */ > > + > > +/* DCN */ > > + > > +#undef BASE_INNER > > +#define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg > > + > > +#define BASE(seg) BASE_INNER(seg) > > + > > +#define SR(reg_name)\ > > + .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \ > > + mm ## reg_name > > + > > +#define SRI(reg_name, block, id)\ > > + .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ > > + mm ## block ## id ## _ ## reg_name > > + > > +#define SRIR(var_name, reg_name, block, id)\ > > + .var_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ > > + mm ## block ## id ## _ ## reg_name > > + > > +#define SRII(reg_name, block, id)\ > > + .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ > > + mm ## block ## id ## _ ## reg_name > > + > > +#define SRI_IX(reg_name, block, id)\ > > + .reg_name = ix ## block ## id ## _ ## reg_name > > + > > +#define DCCG_SRII(reg_name, block, id)\ > > + .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ > > + mm ## block ## id ## _ ## reg_name > > + > > +#define VUPDATE_SRII(reg_name, block, id)\ > > + .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ > > + mm ## reg_name ## _ ## block ## id > > + > > +/* NBIO */ > > +#define NBIO_BASE_INNER(seg) \ > > + NBIO_BASE__INST0_SEG ## seg > > + > > +#define NBIO_BASE(seg) \ > > + NBIO_BASE_INNER(seg) > > + > > +#define NBIO_SR(reg_name)\ > > + .reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \ > > + mm ## reg_name > > + > > +/* MMHUB */ > > +#define MMHUB_BASE_INNER(seg) \ > > + MMHUB_BASE__INST0_SEG ## seg > > + > > +#define MMHUB_BASE(seg) \ > > + MMHUB_BASE_INNER(seg) > > + > > +#define MMHUB_SR(reg_name)\ > > + .reg_name = MMHUB_BASE(mmMM ## reg_name ## _BASE_IDX) + \ > > + mmMM ## reg_name > > + > > +static const struct bios_registers bios_regs = { > > + NBIO_SR(BIOS_SCRATCH_3), > > + NBIO_SR(BIOS_SCRATCH_6) > > +}; > > + > > +#define clk_src_regs(index, pllid)\ > > +[index] = {\ > > + CS_COMMON_REG_LIST_DCN201(index, pllid),\ > > +} > > + > > +static const struct dce110_clk_src_regs clk_src_regs[] = { > > + clk_src_regs(0, A), > > + clk_src_regs(1, B) > > +}; > > + > > +static const struct dce110_clk_src_shift cs_shift = { > > + CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT) > > +}; > > + > > +static const struct dce110_clk_src_mask cs_mask = { > > + CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK) > > +}; > > + > > +#define audio_regs(id)\ > > +[id] = {\ > > + AUD_COMMON_REG_LIST(id)\ > > +} > > + > > +static const struct dce_audio_registers audio_regs[] = { > > + audio_regs(0), > > + audio_regs(1), > > +}; > > + > > +#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ > > + SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\ > > + SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\ > > + AUD_COMMON_MASK_SH_LIST_BASE(mask_sh) > > + > > +static const struct dce_audio_shift audio_shift = { > > + DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT) > > +}; > > + > > +static const struct dce_audio_mask audio_mask = { > > + DCE120_AUD_COMMON_MASK_SH_LIST(_MASK) > > +}; > > + > > +#define stream_enc_regs(id)\ > > +[id] = {\ > > + SE_DCN2_REG_LIST(id)\ > > +} > > + > > +static const struct dcn10_stream_enc_registers stream_enc_regs[] = { > > + stream_enc_regs(0), > > + stream_enc_regs(1) > > +}; > > + > > +static const struct dcn10_stream_encoder_shift se_shift = { > > + SE_COMMON_MASK_SH_LIST_DCN20(__SHIFT) > > +}; > > + > > +static const struct dcn10_stream_encoder_mask se_mask = { > > + SE_COMMON_MASK_SH_LIST_DCN20(_MASK) > > +}; > > + > > +static const struct dce110_aux_registers_shift aux_shift = { > > + DCN_AUX_MASK_SH_LIST(__SHIFT) > > +}; > > + > > +static const struct dce110_aux_registers_mask aux_mask = { > > + DCN_AUX_MASK_SH_LIST(_MASK) > > +}; > > + > > +#define aux_regs(id)\ > > +[id] = {\ > > + DCN2_AUX_REG_LIST(id)\ > > +} > > + > > +static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = { > > + aux_regs(0), > > + aux_regs(1), > > +}; > > + > > +#define hpd_regs(id)\ > > +[id] = {\ > > + HPD_REG_LIST(id)\ > > +} > > + > > +static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = { > > + hpd_regs(0), > > + hpd_regs(1), > > +}; > > + > > +#define link_regs(id, phyid)\ > > +[id] = {\ > > + LE_DCN_COMMON_REG_LIST(id), \ > > + UNIPHY_DCN2_REG_LIST(phyid) \ > > +} > > + > > +static const struct dcn10_link_enc_registers link_enc_regs[] = { > > + link_regs(0, A), > > + link_regs(1, B), > > +}; > > + > > +#define LINK_ENCODER_MASK_SH_LIST_DCN201(mask_sh)\ > > + LINK_ENCODER_MASK_SH_LIST_DCN20(mask_sh) > > + > > +static const struct dcn10_link_enc_shift le_shift = { > > + LINK_ENCODER_MASK_SH_LIST_DCN201(__SHIFT) > > +}; > > + > > +static const struct dcn10_link_enc_mask le_mask = { > > + LINK_ENCODER_MASK_SH_LIST_DCN201(_MASK) > > +}; > > + > > +#define ipp_regs(id)\ > > +[id] = {\ > > + IPP_REG_LIST_DCN201(id),\ > > +} > > + > > +static const struct dcn10_ipp_registers ipp_regs[] = { > > + ipp_regs(0), > > + ipp_regs(1), > > + ipp_regs(2), > > + ipp_regs(3), > > +}; > > + > > +static const struct dcn10_ipp_shift ipp_shift = { > > + IPP_MASK_SH_LIST_DCN201(__SHIFT) > > +}; > > + > > +static const struct dcn10_ipp_mask ipp_mask = { > > + IPP_MASK_SH_LIST_DCN201(_MASK) > > +}; > > + > > +#define opp_regs(id)\ > > +[id] = {\ > > + OPP_REG_LIST_DCN201(id),\ > > +} > > + > > +static const struct dcn201_opp_registers opp_regs[] = { > > + opp_regs(0), > > + opp_regs(1), > > +}; > > + > > +static const struct dcn201_opp_shift opp_shift = { > > + OPP_MASK_SH_LIST_DCN201(__SHIFT) > > +}; > > + > > +static const struct dcn201_opp_mask opp_mask = { > > + OPP_MASK_SH_LIST_DCN201(_MASK) > > +}; > > + > > +#define aux_engine_regs(id)\ > > +[id] = {\ > > + AUX_COMMON_REG_LIST0(id), \ > > + .AUX_RESET_MASK = 0 \ > > +} > > + > > +static const struct dce110_aux_registers aux_engine_regs[] = { > > + aux_engine_regs(0), > > + aux_engine_regs(1) > > +}; > > + > > +#define tf_regs(id)\ > > +[id] = {\ > > + TF_REG_LIST_DCN201(id),\ > > +} > > + > > +static const struct dcn201_dpp_registers tf_regs[] = { > > + tf_regs(0), > > + tf_regs(1), > > + tf_regs(2), > > + tf_regs(3), > > +}; > > + > > +static const struct dcn201_dpp_shift tf_shift = { > > + TF_REG_LIST_SH_MASK_DCN201(__SHIFT) > > +}; > > + > > +static const struct dcn201_dpp_mask tf_mask = { > > + TF_REG_LIST_SH_MASK_DCN201(_MASK) > > +}; > > + > > +static const struct dcn201_mpc_registers mpc_regs = { > > + MPC_REG_LIST_DCN201(0), > > + MPC_REG_LIST_DCN201(1), > > + MPC_REG_LIST_DCN201(2), > > + MPC_REG_LIST_DCN201(3), > > + MPC_REG_LIST_DCN201(4), > > + MPC_OUT_MUX_REG_LIST_DCN201(0), > > + MPC_OUT_MUX_REG_LIST_DCN201(1), > > +}; > > + > > +static const struct dcn201_mpc_shift mpc_shift = { > > + MPC_COMMON_MASK_SH_LIST_DCN201(__SHIFT) > > +}; > > + > > +static const struct dcn201_mpc_mask mpc_mask = { > > + MPC_COMMON_MASK_SH_LIST_DCN201(_MASK) > > +}; > > + > > +#define tg_regs_dcn201(id)\ > > +[id] = {TG_COMMON_REG_LIST_DCN201(id)} > > + > > +static const struct dcn_optc_registers tg_regs[] = { > > + tg_regs_dcn201(0), > > + tg_regs_dcn201(1) > > +}; > > + > > +static const struct dcn_optc_shift tg_shift = { > > + TG_COMMON_MASK_SH_LIST_DCN201(__SHIFT) > > +}; > > + > > +static const struct dcn_optc_mask tg_mask = { > > + TG_COMMON_MASK_SH_LIST_DCN201(_MASK) > > +}; > > + > > +#define hubp_regsDCN201(id)\ > > +[id] = {\ > > + HUBP_REG_LIST_DCN201(id)\ > > +} > > + > > +static const struct dcn201_hubp_registers hubp_regs[] = { > > + hubp_regsDCN201(0), > > + hubp_regsDCN201(1), > > + hubp_regsDCN201(2), > > + hubp_regsDCN201(3) > > +}; > > + > > +static const struct dcn201_hubp_shift hubp_shift = { > > + HUBP_MASK_SH_LIST_DCN201(__SHIFT) > > +}; > > + > > +static const struct dcn201_hubp_mask hubp_mask = { > > + HUBP_MASK_SH_LIST_DCN201(_MASK) > > +}; > > + > > +static const struct dcn_hubbub_registers hubbub_reg = { > > + HUBBUB_REG_LIST_DCN201(0) > > +}; > > + > > +static const struct dcn_hubbub_shift hubbub_shift = { > > + HUBBUB_MASK_SH_LIST_DCN201(__SHIFT) > > +}; > > + > > +static const struct dcn_hubbub_mask hubbub_mask = { > > + HUBBUB_MASK_SH_LIST_DCN201(_MASK) > > +}; > > + > > + > > +static const struct dccg_registers dccg_regs = { > > + DCCG_COMMON_REG_LIST_DCN_BASE() > > +}; > > + > > +static const struct dccg_shift dccg_shift = { > > + DCCG_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(__SHIFT) > > +}; > > + > > +static const struct dccg_mask dccg_mask = { > > + DCCG_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(_MASK) > > +}; > > + > > +static const struct resource_caps res_cap_dnc201 = { > > + .num_timing_generator = 2, > > + .num_opp = 2, > > + .num_video_plane = 4, > > + .num_audio = 2, > > + .num_stream_encoder = 2, > > + .num_pll = 2, > > + .num_ddc = 2, > > +}; > > + > > +static const struct dc_plane_cap plane_cap = { > > + .type = DC_PLANE_TYPE_DCN_UNIVERSAL, > > + .blends_with_above = true, > > + .blends_with_below = true, > > + .per_pixel_alpha = true, > > + > > + .pixel_format_support = { > > + .argb8888 = true, > > + .nv12 = false, > > + .fp16 = true, > > + .p010 = false, > > + }, > > + > > + .max_upscale_factor = { > > + .argb8888 = 16000, > > + .nv12 = 16000, > > + .fp16 = 1 > > + }, > > + > > + .max_downscale_factor = { > > + .argb8888 = 250, > > + .nv12 = 250, > > + .fp16 = 250 > > + }, > > + 64, > > + 64 > > +}; > > + > > +static const struct dc_debug_options debug_defaults_drv = { > > + .disable_dmcu = true, > > + .force_abm_enable = false, > > + .timing_trace = false, > > + .clock_trace = true, > > + .disable_pplib_clock_request = true, > > + .pipe_split_policy = MPC_SPLIT_AVOID, > > + .force_single_disp_pipe_split = false, > > + .disable_dcc = DCC_ENABLE, > > + .vsr_support = true, > > + .performance_trace = false, > > + .az_endpoint_mute_only = true, > > + .max_downscale_src_width = 3840, > > + .disable_pplib_wm_range = true, > > + .scl_reset_length10 = true, > > + .sanity_checks = false, > > + .underflow_assert_delay_us = 0xFFFFFFFF, > > + .enable_tri_buf = false, > > +}; > > + > > +static void dcn201_dpp_destroy(struct dpp **dpp) > > +{ > > + kfree(TO_DCN201_DPP(*dpp)); > > + *dpp = NULL; > > +} > > + > > +static struct dpp *dcn201_dpp_create( > > + struct dc_context *ctx, > > + uint32_t inst) > > +{ > > + struct dcn201_dpp *dpp = > > + kzalloc(sizeof(struct dcn201_dpp), GFP_ATOMIC); > > + > > + if (!dpp) > > + return NULL; > > + > > + if (dpp201_construct(dpp, ctx, inst, > > + &tf_regs[inst], &tf_shift, &tf_mask)) > > + return &dpp->base; > > + > > + kfree(dpp); > > + return NULL; > > +} > > + > > +static struct input_pixel_processor *dcn201_ipp_create( > > + struct dc_context *ctx, uint32_t inst) > > +{ > > + struct dcn10_ipp *ipp = > > + kzalloc(sizeof(struct dcn10_ipp), GFP_ATOMIC); > > + > > + if (!ipp) { > > + return NULL; > > + } > > + > > + dcn20_ipp_construct(ipp, ctx, inst, > > + &ipp_regs[inst], &ipp_shift, &ipp_mask); > > + return &ipp->base; > > +} > > + > > + > > +static struct output_pixel_processor *dcn201_opp_create( > > + struct dc_context *ctx, uint32_t inst) > > +{ > > + struct dcn201_opp *opp = > > + kzalloc(sizeof(struct dcn201_opp), GFP_ATOMIC); > > + > > + if (!opp) { > > + return NULL; > > + } > > + > > + dcn201_opp_construct(opp, ctx, inst, > > + &opp_regs[inst], &opp_shift, &opp_mask); > > + return &opp->base; > > +} > > + > > +struct dce_aux *dcn201_aux_engine_create( > > + struct dc_context *ctx, > > + uint32_t inst) > > +{ > > + struct aux_engine_dce110 *aux_engine = > > + kzalloc(sizeof(struct aux_engine_dce110), GFP_ATOMIC); > > + > > + if (!aux_engine) > > + return NULL; > > + > > + dce110_aux_engine_construct(aux_engine, ctx, inst, > > + SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, > > + &aux_engine_regs[inst], > > + &aux_mask, > > + &aux_shift, > > + ctx->dc->caps.extended_aux_timeout_support); > > + > > + return &aux_engine->base; > > +} > > +#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) } > > + > > +static const struct dce_i2c_registers i2c_hw_regs[] = { > > + i2c_inst_regs(1), > > + i2c_inst_regs(2), > > +}; > > + > > +static const struct dce_i2c_shift i2c_shifts = { > > + I2C_COMMON_MASK_SH_LIST_DCN2(__SHIFT) > > +}; > > + > > +static const struct dce_i2c_mask i2c_masks = { > > + I2C_COMMON_MASK_SH_LIST_DCN2(_MASK) > > +}; > > + > > +struct dce_i2c_hw *dcn201_i2c_hw_create( > > + struct dc_context *ctx, > > + uint32_t inst) > > +{ > > + struct dce_i2c_hw *dce_i2c_hw = > > + kzalloc(sizeof(struct dce_i2c_hw), GFP_ATOMIC); > > + > > + if (!dce_i2c_hw) > > + return NULL; > > + > > + dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst, > > + &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks); > > + > > + return dce_i2c_hw; > > +} > > + > > +static struct mpc *dcn201_mpc_create(struct dc_context *ctx, uint32_t num_mpcc) > > +{ > > + struct dcn201_mpc *mpc201 = kzalloc(sizeof(struct dcn201_mpc), > > + GFP_ATOMIC); > > + > > + if (!mpc201) > > + return NULL; > > + > > + dcn201_mpc_construct(mpc201, ctx, > > + &mpc_regs, > > + &mpc_shift, > > + &mpc_mask, > > + num_mpcc); > > + > > + return &mpc201->base; > > +} > > + > > +static struct hubbub *dcn201_hubbub_create(struct dc_context *ctx) > > +{ > > + struct dcn20_hubbub *hubbub = kzalloc(sizeof(struct dcn20_hubbub), > > + GFP_ATOMIC); > > + > > + if (!hubbub) > > + return NULL; > > + > > + hubbub201_construct(hubbub, ctx, > > + &hubbub_reg, > > + &hubbub_shift, > > + &hubbub_mask); > > + > > + return &hubbub->base; > > +} > > + > > +static struct timing_generator *dcn201_timing_generator_create( > > + struct dc_context *ctx, > > + uint32_t instance) > > +{ > > + struct optc *tgn10 = > > + kzalloc(sizeof(struct optc), GFP_ATOMIC); > > + > > + if (!tgn10) > > + return NULL; > > + > > + tgn10->base.inst = instance; > > + tgn10->base.ctx = ctx; > > + > > + tgn10->tg_regs = &tg_regs[instance]; > > + tgn10->tg_shift = &tg_shift; > > + tgn10->tg_mask = &tg_mask; > > + > > + dcn201_timing_generator_init(tgn10); > > + > > + return &tgn10->base; > > +} > > + > > +static const struct encoder_feature_support link_enc_feature = { > > + .max_hdmi_deep_color = COLOR_DEPTH_121212, > > + .max_hdmi_pixel_clock = 600000, > > + .hdmi_ycbcr420_supported = true, > > + .dp_ycbcr420_supported = true, > > + .fec_supported = true, > > + .flags.bits.IS_HBR2_CAPABLE = true, > > + .flags.bits.IS_HBR3_CAPABLE = true, > > + .flags.bits.IS_TPS3_CAPABLE = true, > > + .flags.bits.IS_TPS4_CAPABLE = true > > +}; > > + > > +struct link_encoder *dcn201_link_encoder_create( > > + const struct encoder_init_data *enc_init_data) > > +{ > > + struct dcn20_link_encoder *enc20 = > > + kzalloc(sizeof(struct dcn20_link_encoder), GFP_ATOMIC); > > + struct dcn10_link_encoder *enc10 = &enc20->enc10; > > + > > + if (!enc20) > > + return NULL; > > + > > + dcn201_link_encoder_construct(enc20, > > + enc_init_data, > > + &link_enc_feature, > > + &link_enc_regs[enc_init_data->transmitter], > > + &link_enc_aux_regs[enc_init_data->channel - 1], > > + &link_enc_hpd_regs[enc_init_data->hpd_source], > > + &le_shift, > > + &le_mask); > > + > > + return &enc10->base; > > +} > > + > > +struct clock_source *dcn201_clock_source_create( > > + struct dc_context *ctx, > > + struct dc_bios *bios, > > + enum clock_source_id id, > > + const struct dce110_clk_src_regs *regs, > > + bool dp_clk_src) > > +{ > > + struct dce110_clk_src *clk_src = > > + kzalloc(sizeof(struct dce110_clk_src), GFP_ATOMIC); > > + > > + if (!clk_src) > > + return NULL; > > + > > + if (dce112_clk_src_construct(clk_src, ctx, bios, id, > > + regs, &cs_shift, &cs_mask)) { > > + clk_src->base.dp_clk_src = dp_clk_src; > > + return &clk_src->base; > > + } > > + kfree(clk_src); > > + return NULL; > > +} > > + > > +static void read_dce_straps( > > + struct dc_context *ctx, > > + struct resource_straps *straps) > > +{ > > + generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX), > > + > > + FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio); > > +} > > + > > +static struct audio *dcn201_create_audio( > > + struct dc_context *ctx, unsigned int inst) > > +{ > > + return dce_audio_create(ctx, inst, > > + &audio_regs[inst], &audio_shift, &audio_mask); > > +} > > + > > +static struct stream_encoder *dcn201_stream_encoder_create( > > + enum engine_id eng_id, > > + struct dc_context *ctx) > > +{ > > + struct dcn10_stream_encoder *enc1 = > > + kzalloc(sizeof(struct dcn10_stream_encoder), GFP_ATOMIC); > > + > > + if (!enc1) > > + return NULL; > > + > > + dcn20_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, > > + &stream_enc_regs[eng_id], > > + &se_shift, &se_mask); > > + > > + return &enc1->base; > > +} > > + > > +static const struct dce_hwseq_registers hwseq_reg = { > > + HWSEQ_DCN201_REG_LIST() > > +}; > > + > > +static const struct dce_hwseq_shift hwseq_shift = { > > + HWSEQ_DCN201_MASK_SH_LIST(__SHIFT) > > +}; > > + > > +static const struct dce_hwseq_mask hwseq_mask = { > > + HWSEQ_DCN201_MASK_SH_LIST(_MASK) > > +}; > > + > > +static struct dce_hwseq *dcn201_hwseq_create( > > + struct dc_context *ctx) > > +{ > > + struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_ATOMIC); > > + > > + if (hws) { > > + hws->ctx = ctx; > > + hws->regs = &hwseq_reg; > > + hws->shifts = &hwseq_shift; > > + hws->masks = &hwseq_mask; > > + } > > + return hws; > > +} > > + > > +static const struct resource_create_funcs res_create_funcs = { > > + .read_dce_straps = read_dce_straps, > > + .create_audio = dcn201_create_audio, > > + .create_stream_encoder = dcn201_stream_encoder_create, > > + .create_hwseq = dcn201_hwseq_create, > > +}; > > + > > +static const struct resource_create_funcs res_create_maximus_funcs = { > > + .read_dce_straps = NULL, > > + .create_audio = NULL, > > + .create_stream_encoder = NULL, > > + .create_hwseq = dcn201_hwseq_create, > > +}; > > + > > +void dcn201_clock_source_destroy(struct clock_source **clk_src) > > +{ > > + kfree(TO_DCE110_CLK_SRC(*clk_src)); > > + *clk_src = NULL; > > +} > > + > > +static void dcn201_resource_destruct(struct dcn201_resource_pool *pool) > > +{ > > + unsigned int i; > > + > > + for (i = 0; i < pool->base.stream_enc_count; i++) { > > + if (pool->base.stream_enc[i] != NULL) { > > + kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i])); > > + pool->base.stream_enc[i] = NULL; > > + } > > + } > > + > > + > > + if (pool->base.mpc != NULL) { > > + kfree(TO_DCN201_MPC(pool->base.mpc)); > > + pool->base.mpc = NULL; > > + } > > + > > + if (pool->base.hubbub != NULL) { > > + kfree(pool->base.hubbub); > > + pool->base.hubbub = NULL; > > + } > > + > > + for (i = 0; i < pool->base.pipe_count; i++) { > > + if (pool->base.dpps[i] != NULL) > > + dcn201_dpp_destroy(&pool->base.dpps[i]); > > + > > + if (pool->base.ipps[i] != NULL) > > + pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]); > > + > > + if (pool->base.hubps[i] != NULL) { > > + kfree(TO_DCN10_HUBP(pool->base.hubps[i])); > > + pool->base.hubps[i] = NULL; > > + } > > + > > + if (pool->base.irqs != NULL) { > > + dal_irq_service_destroy(&pool->base.irqs); > > + } > > + } > > + > > + for (i = 0; i < pool->base.res_cap->num_opp; i++) { > > + if (pool->base.opps[i] != NULL) > > + pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]); > > + } > > + > > + for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { > > + if (pool->base.timing_generators[i] != NULL) { > > + kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i])); > > + pool->base.timing_generators[i] = NULL; > > + } > > + } > > + for (i = 0; i < pool->base.audio_count; i++) { > > + if (pool->base.audios[i]) > > + dce_aud_destroy(&pool->base.audios[i]); > > + } > > + > > + for (i = 0; i < pool->base.clk_src_count; i++) { > > + if (pool->base.clock_sources[i] != NULL) { > > + dcn201_clock_source_destroy(&pool->base.clock_sources[i]); > > + pool->base.clock_sources[i] = NULL; > > + } > > + } > > + > > + if (pool->base.dp_clock_source != NULL) { > > + dcn201_clock_source_destroy(&pool->base.dp_clock_source); > > + pool->base.dp_clock_source = NULL; > > + } > > + > > + if (pool->base.dccg != NULL) > > + dcn_dccg_destroy(&pool->base.dccg); > > +} > > + > > +static struct hubp *dcn201_hubp_create( > > + struct dc_context *ctx, > > + uint32_t inst) > > +{ > > + struct dcn201_hubp *hubp201 = > > + kzalloc(sizeof(struct dcn201_hubp), GFP_ATOMIC); > > + > > + if (!hubp201) > > + return NULL; > > + > > + if (dcn201_hubp_construct(hubp201, ctx, inst, > > + &hubp_regs[inst], &hubp_shift, &hubp_mask)) > > + return &hubp201->base; > > + > > + kfree(hubp201); > > + return NULL; > > +} > > + > > +static struct pipe_ctx *dcn201_acquire_idle_pipe_for_layer( > > + struct dc_state *context, > > + const struct resource_pool *pool, > > + struct dc_stream_state *stream) > > +{ > > + struct resource_context *res_ctx = &context->res_ctx; > > + struct pipe_ctx *head_pipe = resource_get_head_pipe_for_stream(res_ctx, stream); > > + struct pipe_ctx *idle_pipe = find_idle_secondary_pipe(res_ctx, pool, head_pipe); > > + > > + if (!head_pipe) > > + ASSERT(0); > > + > > + if (!idle_pipe) > > + return false; > > + > > + idle_pipe->stream = head_pipe->stream; > > + idle_pipe->stream_res.tg = head_pipe->stream_res.tg; > > + idle_pipe->stream_res.opp = head_pipe->stream_res.opp; > > + > > + idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx]; > > + idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx]; > > + idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx]; > > + idle_pipe->plane_res.mpcc_inst = pool->dpps[idle_pipe->pipe_idx]->inst; > > + > > + return idle_pipe; > > +} > > + > > +static bool dcn201_get_dcc_compression_cap(const struct dc *dc, > > + const struct dc_dcc_surface_param *input, > > + struct dc_surface_dcc_cap *output) > > +{ > > + return dc->res_pool->hubbub->funcs->get_dcc_compression_cap( > > + dc->res_pool->hubbub, > > + input, > > + output); > > +} > > + > > + > > +static void dcn201_destroy_resource_pool(struct resource_pool **pool) > > +{ > > + struct dcn201_resource_pool *dcn201_pool = TO_DCN201_RES_POOL(*pool); > > + > > + dcn201_resource_destruct(dcn201_pool); > > + kfree(dcn201_pool); > > + *pool = NULL; > > +} > > + > > +static void dcn201_link_init(struct dc_link *link) > > +{ > > + if (link->ctx->dc_bios->integrated_info) > > + link->dp_ss_off = !link->ctx->dc_bios->integrated_info->dp_ss_control; > > +} > > + > > +static struct dc_cap_funcs cap_funcs = { > > + .get_dcc_compression_cap = dcn201_get_dcc_compression_cap, > > +}; > > + > > +static struct resource_funcs dcn201_res_pool_funcs = { > > + .link_init = dcn201_link_init, > > + .destroy = dcn201_destroy_resource_pool, > > + .link_enc_create = dcn201_link_encoder_create, > > + .panel_cntl_create = NULL, > > + .validate_bandwidth = dcn20_validate_bandwidth, > > + .populate_dml_pipes = dcn20_populate_dml_pipes_from_context, > > + .add_stream_to_ctx = dcn20_add_stream_to_ctx, > > + .add_dsc_to_stream_resource = NULL, > > + .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, > > + .acquire_idle_pipe_for_layer = dcn201_acquire_idle_pipe_for_layer, > > + .patch_unknown_plane_state = dcn20_patch_unknown_plane_state, > > + .populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context, > > + .set_mcif_arb_params = dcn20_set_mcif_arb_params, > > + .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link > > +}; > > + > > +static bool dcn201_resource_construct( > > + uint8_t num_virtual_links, > > + struct dc *dc, > > + struct dcn201_resource_pool *pool) > > +{ > > + int i; > > + struct dc_context *ctx = dc->ctx; > > + > > + ctx->dc_bios->regs = &bios_regs; > > + > > + pool->base.res_cap = &res_cap_dnc201; > > + pool->base.funcs = &dcn201_res_pool_funcs; > > + > > + /************************************************* > > + * Resource + asic cap harcoding * > > + *************************************************/ > > + pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; > > + > > + pool->base.pipe_count = 4; > > + pool->base.mpcc_count = 5; > > + dc->caps.max_downscale_ratio = 200; > > + dc->caps.i2c_speed_in_khz = 100; > > + dc->caps.i2c_speed_in_khz_hdcp = 5; /*1.5 w/a applied by default*/ > > + dc->caps.max_cursor_size = 256; > > + dc->caps.min_horizontal_blanking_period = 80; > > + dc->caps.dmdata_alloc_size = 2048; > > + > > + dc->caps.max_slave_planes = 1; > > + dc->caps.max_slave_yuv_planes = 1; > > + dc->caps.max_slave_rgb_planes = 1; > > + dc->caps.post_blend_color_processing = true; > > + dc->caps.force_dp_tps4_for_cp2520 = true; > > + dc->caps.extended_aux_timeout_support = true; > > + > > + /* Color pipeline capabilities */ > > + dc->caps.color.dpp.dcn_arch = 1; > > + dc->caps.color.dpp.input_lut_shared = 0; > > + dc->caps.color.dpp.icsc = 1; > > + dc->caps.color.dpp.dgam_ram = 1; > > + dc->caps.color.dpp.dgam_rom_caps.srgb = 1; > > + dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1; > > + dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 0; > > + dc->caps.color.dpp.dgam_rom_caps.pq = 0; > > + dc->caps.color.dpp.dgam_rom_caps.hlg = 0; > > + dc->caps.color.dpp.post_csc = 0; > > + dc->caps.color.dpp.gamma_corr = 0; > > + dc->caps.color.dpp.dgam_rom_for_yuv = 1; > > + > > + dc->caps.color.dpp.hw_3d_lut = 1; > > + dc->caps.color.dpp.ogam_ram = 1; > > + // no OGAM ROM on DCN2 > > + dc->caps.color.dpp.ogam_rom_caps.srgb = 0; > > + dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0; > > + dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0; > > + dc->caps.color.dpp.ogam_rom_caps.pq = 0; > > + dc->caps.color.dpp.ogam_rom_caps.hlg = 0; > > + dc->caps.color.dpp.ocsc = 0; > > + > > + dc->caps.color.mpc.gamut_remap = 0; > > + dc->caps.color.mpc.num_3dluts = 0; > > + dc->caps.color.mpc.shared_3d_lut = 0; > > + dc->caps.color.mpc.ogam_ram = 1; > > + dc->caps.color.mpc.ogam_rom_caps.srgb = 0; > > + dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0; > > + dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0; > > + dc->caps.color.mpc.ogam_rom_caps.pq = 0; > > + dc->caps.color.mpc.ogam_rom_caps.hlg = 0; > > + dc->caps.color.mpc.ocsc = 1; > > + > > + dc->debug = debug_defaults_drv; > > + > > + /*a0 only, remove later*/ > > + dc->work_arounds.no_connect_phy_config = true; > > + dc->work_arounds.dedcn20_305_wa = true; > > + /************************************************* > > + * Create resources * > > + *************************************************/ > > + > > + pool->base.clock_sources[DCN20_CLK_SRC_PLL0] = > > + dcn201_clock_source_create(ctx, ctx->dc_bios, > > + CLOCK_SOURCE_COMBO_PHY_PLL0, > > + &clk_src_regs[0], false); > > + pool->base.clock_sources[DCN20_CLK_SRC_PLL1] = > > + dcn201_clock_source_create(ctx, ctx->dc_bios, > > + CLOCK_SOURCE_COMBO_PHY_PLL1, > > + &clk_src_regs[1], false); > > + > > + pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN201; > > + > > + /* todo: not reuse phy_pll registers */ > > + pool->base.dp_clock_source = > > + dcn201_clock_source_create(ctx, ctx->dc_bios, > > + CLOCK_SOURCE_ID_DP_DTO, > > + &clk_src_regs[0], true); > > + > > + for (i = 0; i < pool->base.clk_src_count; i++) { > > + if (pool->base.clock_sources[i] == NULL) { > > + dm_error("DC: failed to create clock sources!\n"); > > + goto create_fail; > > + } > > + } > > + > > + pool->base.dccg = dccg201_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask); > > + if (pool->base.dccg == NULL) { > > + dm_error("DC: failed to create dccg!\n"); > > + goto create_fail; > > + } > > + > > + dcn201_ip.max_num_otg = pool->base.res_cap->num_timing_generator; > > + dcn201_ip.max_num_dpp = pool->base.pipe_count; > > + dml_init_instance(&dc->dml, &dcn201_soc, &dcn201_ip, DML_PROJECT_DCN201); > > + { > > + struct irq_service_init_data init_data; > > + init_data.ctx = dc->ctx; > > + pool->base.irqs = dal_irq_service_dcn201_create(&init_data); > > + if (!pool->base.irqs) > > + goto create_fail; > > + } > > + > > + /* mem input -> ipp -> dpp -> opp -> TG */ > > + for (i = 0; i < pool->base.pipe_count; i++) { > > + pool->base.hubps[i] = dcn201_hubp_create(ctx, i); > > + if (pool->base.hubps[i] == NULL) { > > + dm_error( > > + "DC: failed to create memory input!\n"); > > + goto create_fail; > > + } > > + > > + pool->base.ipps[i] = dcn201_ipp_create(ctx, i); > > + if (pool->base.ipps[i] == NULL) { > > + dm_error( > > + "DC: failed to create input pixel processor!\n"); > > + goto create_fail; > > + } > > + > > + pool->base.dpps[i] = dcn201_dpp_create(ctx, i); > > + if (pool->base.dpps[i] == NULL) { > > + dm_error( > > + "DC: failed to create dpps!\n"); > > + goto create_fail; > > + } > > + } > > + > > + for (i = 0; i < pool->base.res_cap->num_opp; i++) { > > + pool->base.opps[i] = dcn201_opp_create(ctx, i); > > + if (pool->base.opps[i] == NULL) { > > + dm_error( > > + "DC: failed to create output pixel processor!\n"); > > + goto create_fail; > > + } > > + } > > + > > + for (i = 0; i < pool->base.res_cap->num_ddc; i++) { > > + pool->base.engines[i] = dcn201_aux_engine_create(ctx, i); > > + if (pool->base.engines[i] == NULL) { > > + dm_error( > > + "DC:failed to create aux engine!!\n"); > > + goto create_fail; > > + } > > + pool->base.hw_i2cs[i] = dcn201_i2c_hw_create(ctx, i); > > + if (pool->base.hw_i2cs[i] == NULL) { > > + dm_error( > > + "DC:failed to create hw i2c!!\n"); > > + goto create_fail; > > + } > > + pool->base.sw_i2cs[i] = NULL; > > + } > > + > > + for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { > > + pool->base.timing_generators[i] = dcn201_timing_generator_create( > > + ctx, i); > > + if (pool->base.timing_generators[i] == NULL) { > > + dm_error("DC: failed to create tg!\n"); > > + goto create_fail; > > + } > > + } > > + > > + pool->base.timing_generator_count = i; > > + > > + pool->base.mpc = dcn201_mpc_create(ctx, pool->base.mpcc_count); > > + if (pool->base.mpc == NULL) { > > + dm_error("DC: failed to create mpc!\n"); > > + goto create_fail; > > + } > > + > > + pool->base.hubbub = dcn201_hubbub_create(ctx); > > + if (pool->base.hubbub == NULL) { > > + dm_error("DC: failed to create hubbub!\n"); > > + goto create_fail; > > + } > > + > > + if (!resource_construct(num_virtual_links, dc, &pool->base, > > + (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ? > > + &res_create_funcs : &res_create_maximus_funcs))) > > + goto create_fail; > > + > > + dcn201_hw_sequencer_construct(dc); > > + > > + dc->caps.max_planes = pool->base.pipe_count; > > + > > + for (i = 0; i < dc->caps.max_planes; ++i) > > + dc->caps.planes[i] = plane_cap; > > + > > + dc->cap_funcs = cap_funcs; > > + > > + return true; > > + > > +create_fail: > > + > > + dcn201_resource_destruct(pool); > > + > > + return false; > > +} > > + > > +struct resource_pool *dcn201_create_resource_pool( > > + const struct dc_init_data *init_data, > > + struct dc *dc) > > +{ > > + struct dcn201_resource_pool *pool = > > + kzalloc(sizeof(struct dcn201_resource_pool), GFP_ATOMIC); > > + > > + if (!pool) > > + return NULL; > > + > > + if (dcn201_resource_construct(init_data->num_virtual_links, dc, pool)) > > + return &pool->base; > > + > > + kfree(pool); > > + return NULL; > > +} > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.h b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.h > > new file mode 100644 > > index 0000000..e0467d1 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.h > > @@ -0,0 +1,50 @@ > > +/* > > +* Copyright 2017 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#ifndef __DC_RESOURCE_DCN201_H__ > > +#define __DC_RESOURCE_DCN201_H__ > > + > > +#include "core_types.h" > > + > > +#define RRDPCS_PHY_DP_TX_PSTATE_POWER_UP 0x00000000 > > +#define RRDPCS_PHY_DP_TX_PSTATE_HOLD 0x00000001 > > +#define RRDPCS_PHY_DP_TX_PSTATE_HOLD_OFF 0x00000002 > > +#define RRDPCS_PHY_DP_TX_PSTATE_POWER_DOWN 0x00000003 > > + > > +#define TO_DCN201_RES_POOL(pool)\ > > + container_of(pool, struct dcn201_resource_pool, base) > > + > > +struct dc; > > +struct resource_pool; > > +struct _vcs_dpi_display_pipe_params_st; > > + > > +struct dcn201_resource_pool { > > + struct resource_pool base; > > +}; > > +struct resource_pool *dcn201_create_resource_pool( > > + const struct dc_init_data *init_data, > > + struct dc *dc); > > + > > +#endif /* __DC_RESOURCE_DCN201_H__ */ > > diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c > > index 8a5bd91..30db51f 100644 > > --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c > > +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c > > @@ -82,6 +82,7 @@ > > lib->project = project; > > switch (project) { > > case DML_PROJECT_NAVI10: > > + case DML_PROJECT_DCN201: > > lib->funcs = dml20_funcs; > > break; > > case DML_PROJECT_NAVI10v2: > > diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h > > index 72b1957..6905ef1 100644 > > --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h > > +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h > > @@ -36,6 +36,7 @@ > > DML_PROJECT_RAVEN1, > > DML_PROJECT_NAVI10, > > DML_PROJECT_NAVI10v2, > > + DML_PROJECT_DCN201, > > DML_PROJECT_DCN21, > > DML_PROJECT_DCN30, > > DML_PROJECT_DCN31, > > diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c > > index c5c840a..5029d4e 100644 > > --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c > > +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c > > @@ -105,6 +105,7 @@ > > case DCN_VERSION_2_0: > > dal_hw_factory_dcn20_init(factory); > > return true; > > + case DCN_VERSION_2_01: > > case DCN_VERSION_2_1: > > dal_hw_factory_dcn21_init(factory); > > return true; > > diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c > > index 4a98483..904bd30 100644 > > --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c > > +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c > > @@ -100,6 +100,7 @@ > > case DCN_VERSION_2_0: > > dal_hw_translate_dcn20_init(translate); > > return true; > > + case DCN_VERSION_2_01: > > case DCN_VERSION_2_1: > > dal_hw_translate_dcn21_init(translate); > > return true; > > diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h > > index a262f32..1391c20 100644 > > --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h > > +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h > > @@ -102,6 +102,11 @@ > > .MP1_SMN_C2PMSG_83 = mmMP1_SMN_C2PMSG_83, \ > > .MP1_SMN_C2PMSG_67 = mmMP1_SMN_C2PMSG_67 > > > > +#define CLK_COMMON_REG_LIST_DCN_201() \ > > + SR(DENTIST_DISPCLK_CNTL), \ > > + CLK_SRI(CLK4_CLK_PLL_REQ, CLK4, 0), \ > > + CLK_SRI(CLK4_CLK2_CURRENT_CNT, CLK4, 0) > > + > > #define CLK_REG_LIST_NV10() \ > > SR(DENTIST_DISPCLK_CNTL), \ > > CLK_SRI(CLK3_CLK_PLL_REQ, CLK3, 0), \ > > @@ -144,6 +149,12 @@ > > CLK_SF(CLK3_0_CLK3_CLK_PLL_REQ, FbMult_int, mask_sh),\ > > CLK_SF(CLK3_0_CLK3_CLK_PLL_REQ, FbMult_frac, mask_sh) > > > > +#define CLK_COMMON_MASK_SH_LIST_DCN201_BASE(mask_sh) \ > > + CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\ > > + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, mask_sh),\ > > + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, mask_sh),\ > > + CLK_SF(CLK4_0_CLK4_CLK_PLL_REQ, FbMult_int, mask_sh) > > + > > #define CLK_REG_FIELD_LIST(type) \ > > type DPREFCLK_SRC_SEL; \ > > type DENTIST_DPREFCLK_WDIVIDER; \ > > @@ -179,6 +190,8 @@ > > struct clk_mgr_registers { > > uint32_t DPREFCLK_CNTL; > > uint32_t DENTIST_DISPCLK_CNTL; > > + uint32_t CLK4_CLK2_CURRENT_CNT; > > + uint32_t CLK4_CLK_PLL_REQ; > > > > uint32_t CLK3_CLK2_DFS_CNTL; > > uint32_t CLK3_CLK_PLL_REQ; > > diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h > > index 9ccbb2b..fd6572b 100644 > > --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h > > +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h > > @@ -172,8 +172,8 @@ > > bool dwb_is_drc; > > int wb_src_plane_inst;/*hubp, mpcc, inst*/ > > uint32_t mask_id; > > - int otg_inst; > > - bool mvc_cfg; > > + int otg_inst; > > + bool mvc_cfg; > > }; > > > > struct dwbc_funcs { > > diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h > > index 640bb432..04d6ec3 100644 > > --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h > > +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h > > @@ -281,6 +281,7 @@ > > struct mpcc* (*get_mpcc_for_dpp_from_secondary)( > > struct mpc_tree *tree, > > int dpp_id); > > + > > struct mpcc* (*get_mpcc_for_dpp)( > > struct mpc_tree *tree, > > int dpp_id); > > diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h > > index d09eed7..f324285 100644 > > --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h > > +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h > > @@ -154,6 +154,10 @@ > > struct hwseq_wa_state wa_state; > > struct hwseq_private_funcs funcs; > > > > + PHYSICAL_ADDRESS_LOC fb_base; > > + PHYSICAL_ADDRESS_LOC fb_top; > > + PHYSICAL_ADDRESS_LOC fb_offset; > > + PHYSICAL_ADDRESS_LOC uma_top; > > }; > > > > #endif /* __DC_HW_SEQUENCER_PRIVATE_H__ */ > > diff --git a/drivers/gpu/drm/amd/display/dc/irq/Makefile b/drivers/gpu/drm/amd/display/dc/irq/Makefile > > index 0d09181..8a18277 100644 > > --- a/drivers/gpu/drm/amd/display/dc/irq/Makefile > > +++ b/drivers/gpu/drm/amd/display/dc/irq/Makefile > > @@ -93,6 +93,18 @@ > > AMD_DAL_IRQ_DCN21= $(addprefix $(AMDDALPATH)/dc/irq/dcn21/,$(IRQ_DCN21)) > > > > AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN21) > > + > > +ifdef CONFIG_DRM_AMD_DC_DCN201 > > +############################################################################### > > +# DCN 201 > > +############################################################################### > > +IRQ_DCN201 = irq_service_dcn201.o > > + > > +AMD_DAL_IRQ_DCN201 = $(addprefix $(AMDDALPATH)/dc/irq/dcn201/,$(IRQ_DCN201)) > > + > > +AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN201) > > +endif > > + > > ############################################################################### > > # DCN 30 > > ############################################################################### > > diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c b/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c > > new file mode 100644 > > index 0000000..a47f686 > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c > > @@ -0,0 +1,374 @@ > > +/* > > + * Copyright 2018 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#include "dm_services.h" > > + > > +#include "include/logger_interface.h" > > + > > +#include "../dce110/irq_service_dce110.h" > > + > > +#include "dcn/dcn_2_0_3_offset.h" > > +#include "dcn/dcn_2_0_3_sh_mask.h" > > + > > +#include "cyan_skillfish_ip_offset.h" > > +#include "soc15_hw_ip.h" > > + > > +#include "irq_service_dcn201.h" > > + > > +#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h" > > + > > +enum dc_irq_source to_dal_irq_source_dcn201( > > + struct irq_service *irq_service, > > + uint32_t src_id, > > + uint32_t ext_id) > > +{ > > + switch (src_id) { > > + case DCN_1_0__SRCID__DC_D1_OTG_VSTARTUP: > > + return DC_IRQ_SOURCE_VBLANK1; > > + case DCN_1_0__SRCID__DC_D2_OTG_VSTARTUP: > > + return DC_IRQ_SOURCE_VBLANK2; > > + case DCN_1_0__SRCID__OTG1_VERTICAL_INTERRUPT0_CONTROL: > > + return DC_IRQ_SOURCE_DC1_VLINE0; > > + case DCN_1_0__SRCID__OTG2_VERTICAL_INTERRUPT0_CONTROL: > > + return DC_IRQ_SOURCE_DC2_VLINE0; > > + case DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT: > > + return DC_IRQ_SOURCE_PFLIP1; > > + case DCN_1_0__SRCID__HUBP1_FLIP_INTERRUPT: > > + return DC_IRQ_SOURCE_PFLIP2; > > + case DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT: > > + return DC_IRQ_SOURCE_VUPDATE1; > > + case DCN_1_0__SRCID__OTG1_IHC_V_UPDATE_NO_LOCK_INTERRUPT: > > + return DC_IRQ_SOURCE_VUPDATE2; > > + case DCN_1_0__SRCID__DC_HPD1_INT: > > + /* generic src_id for all HPD and HPDRX interrupts */ > > + switch (ext_id) { > > + case DCN_1_0__CTXID__DC_HPD1_INT: > > + return DC_IRQ_SOURCE_HPD1; > > + case DCN_1_0__CTXID__DC_HPD2_INT: > > + return DC_IRQ_SOURCE_HPD2; > > + case DCN_1_0__CTXID__DC_HPD1_RX_INT: > > + return DC_IRQ_SOURCE_HPD1RX; > > + case DCN_1_0__CTXID__DC_HPD2_RX_INT: > > + return DC_IRQ_SOURCE_HPD2RX; > > + default: > > + return DC_IRQ_SOURCE_INVALID; > > + } > > + break; > > + > > + default: > > + return DC_IRQ_SOURCE_INVALID; > > + } > > + return DC_IRQ_SOURCE_INVALID; > > +} > > + > > +static bool hpd_ack( > > + struct irq_service *irq_service, > > + const struct irq_source_info *info) > > +{ > > + uint32_t addr = info->status_reg; > > + uint32_t value = dm_read_reg(irq_service->ctx, addr); > > + uint32_t current_status = > > + get_reg_field_value( > > + value, > > + HPD0_DC_HPD_INT_STATUS, > > + DC_HPD_SENSE_DELAYED); > > + > > + dal_irq_service_ack_generic(irq_service, info); > > + > > + value = dm_read_reg(irq_service->ctx, info->enable_reg); > > + > > + set_reg_field_value( > > + value, > > + current_status ? 0 : 1, > > + HPD0_DC_HPD_INT_CONTROL, > > + DC_HPD_INT_POLARITY); > > + > > + dm_write_reg(irq_service->ctx, info->enable_reg, value); > > + > > + return true; > > +} > > + > > +static const struct irq_source_info_funcs hpd_irq_info_funcs = { > > + .set = NULL, > > + .ack = hpd_ack > > +}; > > + > > +static const struct irq_source_info_funcs hpd_rx_irq_info_funcs = { > > + .set = NULL, > > + .ack = NULL > > +}; > > + > > +static const struct irq_source_info_funcs pflip_irq_info_funcs = { > > + .set = NULL, > > + .ack = NULL > > +}; > > + > > +static const struct irq_source_info_funcs vblank_irq_info_funcs = { > > + .set = NULL, > > + .ack = NULL > > +}; > > + > > +static const struct irq_source_info_funcs vline0_irq_info_funcs = { > > + .set = NULL, > > + .ack = NULL > > +}; > > +static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { > > + .set = NULL, > > + .ack = NULL > > +}; > > + > > +static const struct irq_source_info_funcs dmub_outbox_irq_info_funcs = { > > + .set = NULL, > > + .ack = NULL > > +}; > > + > > +#undef BASE_INNER > > +#define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg > > + > > +#define BASE(seg) BASE_INNER(seg) > > + > > +/* compile time expand base address. */ > > +#define BASE(seg) \ > > + BASE_INNER(seg) > > + > > +#define SRI(reg_name, block, id)\ > > + BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ > > + mm ## block ## id ## _ ## reg_name > > + > > +#define IRQ_REG_ENTRY(block, reg_num, reg1, mask1, reg2, mask2)\ > > + .enable_reg = SRI(reg1, block, reg_num),\ > > + .enable_mask = \ > > + block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\ > > + .enable_value = {\ > > + block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\ > > + ~block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK \ > > + },\ > > + .ack_reg = SRI(reg2, block, reg_num),\ > > + .ack_mask = \ > > + block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK,\ > > + .ack_value = \ > > + block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \ > > + > > +#define hpd_int_entry(reg_num)\ > > + [DC_IRQ_SOURCE_HPD1 + reg_num] = {\ > > + IRQ_REG_ENTRY(HPD, reg_num,\ > > + DC_HPD_INT_CONTROL, DC_HPD_INT_EN,\ > > + DC_HPD_INT_CONTROL, DC_HPD_INT_ACK),\ > > + .status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num),\ > > + .funcs = &hpd_irq_info_funcs\ > > + } > > + > > +#define hpd_rx_int_entry(reg_num)\ > > + [DC_IRQ_SOURCE_HPD1RX + reg_num] = {\ > > + IRQ_REG_ENTRY(HPD, reg_num,\ > > + DC_HPD_INT_CONTROL, DC_HPD_RX_INT_EN,\ > > + DC_HPD_INT_CONTROL, DC_HPD_RX_INT_ACK),\ > > + .status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num),\ > > + .funcs = &hpd_rx_irq_info_funcs\ > > + } > > +#define pflip_int_entry(reg_num)\ > > + [DC_IRQ_SOURCE_PFLIP1 + reg_num] = {\ > > + IRQ_REG_ENTRY(HUBPREQ, reg_num,\ > > + DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_INT_MASK,\ > > + DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_CLEAR),\ > > + .funcs = &pflip_irq_info_funcs\ > > + } > > + > > +#define vupdate_int_entry(reg_num)\ > > + [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\ > > + IRQ_REG_ENTRY(OTG, reg_num,\ > > + OTG_GLOBAL_SYNC_STATUS, VUPDATE_INT_EN,\ > > + OTG_GLOBAL_SYNC_STATUS, VUPDATE_EVENT_CLEAR),\ > > + .funcs = &vblank_irq_info_funcs\ > > + } > > + > > +/* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic > > + * of DCE's DC_IRQ_SOURCE_VUPDATEx. > > + */ > > +#define vupdate_no_lock_int_entry(reg_num)\ > > + [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\ > > + IRQ_REG_ENTRY(OTG, reg_num,\ > > + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_INT_EN,\ > > + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR),\ > > + .funcs = &vupdate_no_lock_irq_info_funcs\ > > + } > > +#define vblank_int_entry(reg_num)\ > > + [DC_IRQ_SOURCE_VBLANK1 + reg_num] = {\ > > + IRQ_REG_ENTRY(OTG, reg_num,\ > > + OTG_GLOBAL_SYNC_STATUS, VSTARTUP_INT_EN,\ > > + OTG_GLOBAL_SYNC_STATUS, VSTARTUP_EVENT_CLEAR),\ > > + .funcs = &vblank_irq_info_funcs\ > > + } > > + > > +#define vline0_int_entry(reg_num)\ > > + [DC_IRQ_SOURCE_DC1_VLINE0 + reg_num] = {\ > > + IRQ_REG_ENTRY(OTG, reg_num,\ > > + OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE,\ > > + OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_CLEAR),\ > > + .funcs = &vline0_irq_info_funcs\ > > + } > > + > > +#define dummy_irq_entry() \ > > + {\ > > + .funcs = &dummy_irq_info_funcs\ > > + } > > + > > +#define i2c_int_entry(reg_num) \ > > + [DC_IRQ_SOURCE_I2C_DDC ## reg_num] = dummy_irq_entry() > > + > > +#define dp_sink_int_entry(reg_num) \ > > + [DC_IRQ_SOURCE_DPSINK ## reg_num] = dummy_irq_entry() > > + > > +#define gpio_pad_int_entry(reg_num) \ > > + [DC_IRQ_SOURCE_GPIOPAD ## reg_num] = dummy_irq_entry() > > + > > +#define dc_underflow_int_entry(reg_num) \ > > + [DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW] = dummy_irq_entry() > > + > > +static const struct irq_source_info_funcs dummy_irq_info_funcs = { > > + .set = dal_irq_service_dummy_set, > > + .ack = dal_irq_service_dummy_ack > > +}; > > + > > +static const struct irq_source_info > > +irq_source_info_dcn201[DAL_IRQ_SOURCES_NUMBER] = { > > + [DC_IRQ_SOURCE_INVALID] = dummy_irq_entry(), > > + hpd_int_entry(0), > > + hpd_int_entry(1), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + hpd_rx_int_entry(0), > > + hpd_rx_int_entry(1), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + i2c_int_entry(1), > > + i2c_int_entry(2), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dp_sink_int_entry(1), > > + dp_sink_int_entry(2), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + [DC_IRQ_SOURCE_TIMER] = dummy_irq_entry(), > > + pflip_int_entry(0), > > + pflip_int_entry(1), > > + pflip_int_entry(2), > > + pflip_int_entry(3), > > + [DC_IRQ_SOURCE_PFLIP5] = dummy_irq_entry(), > > + [DC_IRQ_SOURCE_PFLIP6] = dummy_irq_entry(), > > + [DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(), > > + gpio_pad_int_entry(0), > > + gpio_pad_int_entry(1), > > + gpio_pad_int_entry(2), > > + gpio_pad_int_entry(3), > > + gpio_pad_int_entry(4), > > + gpio_pad_int_entry(5), > > + gpio_pad_int_entry(6), > > + gpio_pad_int_entry(7), > > + gpio_pad_int_entry(8), > > + gpio_pad_int_entry(9), > > + gpio_pad_int_entry(10), > > + gpio_pad_int_entry(11), > > + gpio_pad_int_entry(12), > > + gpio_pad_int_entry(13), > > + gpio_pad_int_entry(14), > > + gpio_pad_int_entry(15), > > + gpio_pad_int_entry(16), > > + gpio_pad_int_entry(17), > > + gpio_pad_int_entry(18), > > + gpio_pad_int_entry(19), > > + gpio_pad_int_entry(20), > > + gpio_pad_int_entry(21), > > + gpio_pad_int_entry(22), > > + gpio_pad_int_entry(23), > > + gpio_pad_int_entry(24), > > + gpio_pad_int_entry(25), > > + gpio_pad_int_entry(26), > > + gpio_pad_int_entry(27), > > + gpio_pad_int_entry(28), > > + gpio_pad_int_entry(29), > > + gpio_pad_int_entry(30), > > + dc_underflow_int_entry(1), > > + dc_underflow_int_entry(2), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + [DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(), > > + [DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(), > > + vupdate_no_lock_int_entry(0), > > + vupdate_no_lock_int_entry(1), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + vblank_int_entry(0), > > + vblank_int_entry(1), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + vline0_int_entry(0), > > + vline0_int_entry(1), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > + dummy_irq_entry(), > > +}; > > + > > +static const struct irq_service_funcs irq_service_funcs_dcn201 = { > > + .to_dal_irq_source = to_dal_irq_source_dcn201 > > +}; > > + > > +static void dcn201_irq_construct( > > + struct irq_service *irq_service, > > + struct irq_service_init_data *init_data) > > +{ > > + dal_irq_service_construct(irq_service, init_data); > > + > > + irq_service->info = irq_source_info_dcn201; > > + irq_service->funcs = &irq_service_funcs_dcn201; > > +} > > + > > +struct irq_service *dal_irq_service_dcn201_create( > > + struct irq_service_init_data *init_data) > > +{ > > + struct irq_service *irq_service = kzalloc(sizeof(*irq_service), > > + GFP_KERNEL); > > + > > + if (!irq_service) > > + return NULL; > > + > > + dcn201_irq_construct(irq_service, init_data); > > + return irq_service; > > +} > > diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.h b/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.h > > new file mode 100644 > > index 0000000..8e27c5e > > --- /dev/null > > +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.h > > @@ -0,0 +1,34 @@ > > +/* > > + * Copyright 2018 Advanced Micro Devices, Inc. > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software"), > > + * to deal in the Software without restriction, including without limitation > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > + * OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: AMD > > + * > > + */ > > + > > +#ifndef __DAL_IRQ_SERVICE_DCN201_H__ > > +#define __DAL_IRQ_SERVICE_DCN201_H__ > > + > > +#include "../irq_service.h" > > + > > +struct irq_service *dal_irq_service_dcn201_create( > > + struct irq_service_init_data *init_data); > > + > > +#endif > > diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h > > index 3d2f081..e4a2dfa 100644 > > --- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h > > +++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h > > @@ -211,6 +211,7 @@ > > #ifndef ASICREV_IS_GREEN_SARDINE > > #define ASICREV_IS_GREEN_SARDINE(eChipRev) ((eChipRev >= GREEN_SARDINE_A0) && (eChipRev < 0xFF)) > > #endif > > +#define DEVICE_ID_NV_13FE 0x13FE // CYAN_SKILLFISH > > #define FAMILY_VGH 144 > > #define DEVICE_ID_VGH_163F 0x163F > > #define VANGOGH_A0 0x01 > > diff --git a/drivers/gpu/drm/amd/display/include/dal_types.h b/drivers/gpu/drm/amd/display/include/dal_types.h > > index fe75ec8..012b7c6 100644 > > --- a/drivers/gpu/drm/amd/display/include/dal_types.h > > +++ b/drivers/gpu/drm/amd/display/include/dal_types.h > > @@ -50,6 +50,7 @@ > > DCN_VERSION_1_0, > > DCN_VERSION_1_01, > > DCN_VERSION_2_0, > > + DCN_VERSION_2_01, > > DCN_VERSION_2_1, > > DCN_VERSION_3_0, > > DCN_VERSION_3_01,