aboutsummaryrefslogtreecommitdiffstats
path: root/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0276-drm-amd-display-Add-DCE12-core-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0276-drm-amd-display-Add-DCE12-core-support.patch')
-rw-r--r--meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0276-drm-amd-display-Add-DCE12-core-support.patch3496
1 files changed, 0 insertions, 3496 deletions
diff --git a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0276-drm-amd-display-Add-DCE12-core-support.patch b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0276-drm-amd-display-Add-DCE12-core-support.patch
deleted file mode 100644
index 774d72e3..00000000
--- a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0276-drm-amd-display-Add-DCE12-core-support.patch
+++ /dev/null
@@ -1,3496 +0,0 @@
-From 0babc74552e1f38dce837f82f72ecf0d189e171c Mon Sep 17 00:00:00 2001
-From: Harry Wentland <harry.wentland@amd.com>
-Date: Mon, 6 Mar 2017 14:36:02 -0500
-Subject: [PATCH 0276/4131] drm/amd/display: Add DCE12 core support
-
-Signed-off-by: Harry Wentland <harry.wentland@amd.com>
-Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
----
- .../amd/display/dc/dce120/dce120_hw_sequencer.c | 197 ++++
- .../amd/display/dc/dce120/dce120_hw_sequencer.h | 36 +
- drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp.c | 58 +
- drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp.h | 62 ++
- .../drm/amd/display/dc/dce120/dce120_ipp_cursor.c | 202 ++++
- .../drm/amd/display/dc/dce120/dce120_ipp_gamma.c | 167 +++
- .../drm/amd/display/dc/dce120/dce120_mem_input.c | 340 ++++++
- .../drm/amd/display/dc/dce120/dce120_mem_input.h | 37 +
- .../drm/amd/display/dc/dce120/dce120_resource.c | 1099 +++++++++++++++++++
- .../drm/amd/display/dc/dce120/dce120_resource.h | 39 +
- .../display/dc/dce120/dce120_timing_generator.c | 1109 ++++++++++++++++++++
- .../display/dc/dce120/dce120_timing_generator.h | 41 +
- 12 files changed, 3387 insertions(+)
- create mode 100644 drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c
- create mode 100644 drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.h
- create mode 100644 drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp.c
- create mode 100644 drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp.h
- create mode 100644 drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp_cursor.c
- create mode 100644 drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp_gamma.c
- create mode 100644 drivers/gpu/drm/amd/display/dc/dce120/dce120_mem_input.c
- create mode 100644 drivers/gpu/drm/amd/display/dc/dce120/dce120_mem_input.h
- create mode 100644 drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
- create mode 100644 drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.h
- create mode 100644 drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
- create mode 100644 drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.h
-
-diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c
-new file mode 100644
-index 0000000..f5ffd8f6
---- /dev/null
-+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c
-@@ -0,0 +1,197 @@
-+/*
-+ * Copyright 2015 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 "core_dc.h"
-+#include "core_types.h"
-+#include "dce120_hw_sequencer.h"
-+
-+#include "dce110/dce110_hw_sequencer.h"
-+
-+/* include DCE12.0 register header files */
-+#include "vega10/DC/dce_12_0_offset.h"
-+#include "vega10/DC/dce_12_0_sh_mask.h"
-+#include "vega10/soc15ip.h"
-+#include "reg_helper.h"
-+
-+struct dce120_hw_seq_reg_offsets {
-+ uint32_t crtc;
-+};
-+
-+static const struct dce120_hw_seq_reg_offsets reg_offsets[] = {
-+{
-+ .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-+},
-+{
-+ .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-+},
-+{
-+ .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-+},
-+{
-+ .crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-+},
-+{
-+ .crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-+},
-+{
-+ .crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-+}
-+};
-+
-+#define HW_REG_CRTC(reg, id)\
-+ (reg + reg_offsets[id].crtc)
-+
-+#define CNTL_ID(controller_id)\
-+ controller_id
-+/*******************************************************************************
-+ * Private definitions
-+ ******************************************************************************/
-+#if 0
-+static void dce120_init_pte(struct dc_context *ctx, uint8_t controller_id)
-+{
-+ uint32_t addr;
-+ uint32_t value = 0;
-+ uint32_t chunk_int = 0;
-+ uint32_t chunk_mul = 0;
-+/*
-+ addr = mmDCP0_DVMM_PTE_CONTROL + controller_id *
-+ (mmDCP1_DVMM_PTE_CONTROL- mmDCP0_DVMM_PTE_CONTROL);
-+
-+ value = dm_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value, 0, DCP, controller_id,
-+ DVMM_PTE_CONTROL,
-+ DVMM_USE_SINGLE_PTE);
-+
-+ set_reg_field_value_soc15(
-+ value, 1, DCP, controller_id,
-+ DVMM_PTE_CONTROL,
-+ DVMM_PTE_BUFFER_MODE0);
-+
-+ set_reg_field_value_soc15(
-+ value, 1, DCP, controller_id,
-+ DVMM_PTE_CONTROL,
-+ DVMM_PTE_BUFFER_MODE1);
-+
-+ dm_write_reg(ctx, addr, value);*/
-+
-+ addr = mmDVMM_PTE_REQ;
-+ value = dm_read_reg(ctx, addr);
-+
-+ chunk_int = get_reg_field_value(
-+ value,
-+ DVMM_PTE_REQ,
-+ HFLIP_PTEREQ_PER_CHUNK_INT);
-+
-+ chunk_mul = get_reg_field_value(
-+ value,
-+ DVMM_PTE_REQ,
-+ HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
-+
-+ if (chunk_int != 0x4 || chunk_mul != 0x4) {
-+
-+ set_reg_field_value(
-+ value,
-+ 255,
-+ DVMM_PTE_REQ,
-+ MAX_PTEREQ_TO_ISSUE);
-+
-+ set_reg_field_value(
-+ value,
-+ 4,
-+ DVMM_PTE_REQ,
-+ HFLIP_PTEREQ_PER_CHUNK_INT);
-+
-+ set_reg_field_value(
-+ value,
-+ 4,
-+ DVMM_PTE_REQ,
-+ HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
-+
-+ dm_write_reg(ctx, addr, value);
-+ }
-+}
-+#endif
-+
-+static bool dce120_enable_display_power_gating(
-+ struct core_dc *dc,
-+ uint8_t controller_id,
-+ struct dc_bios *dcb,
-+ enum pipe_gating_control power_gating)
-+{
-+ /* disable for bringup */
-+#if 0
-+ enum bp_result bp_result = BP_RESULT_OK;
-+ enum bp_pipe_control_action cntl;
-+ struct dc_context *ctx = dc->ctx;
-+
-+ if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
-+ return true;
-+
-+ if (power_gating == PIPE_GATING_CONTROL_INIT)
-+ cntl = ASIC_PIPE_INIT;
-+ else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
-+ cntl = ASIC_PIPE_ENABLE;
-+ else
-+ cntl = ASIC_PIPE_DISABLE;
-+
-+ if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) {
-+
-+ bp_result = dcb->funcs->enable_disp_power_gating(
-+ dcb, controller_id + 1, cntl);
-+
-+ /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
-+ * by default when command table is called
-+ */
-+ dm_write_reg(ctx,
-+ HW_REG_CRTC(mmCRTC0_CRTC_MASTER_UPDATE_MODE, controller_id),
-+ 0);
-+ }
-+
-+ if (power_gating != PIPE_GATING_CONTROL_ENABLE)
-+ dce120_init_pte(ctx, controller_id);
-+
-+ if (bp_result == BP_RESULT_OK)
-+ return true;
-+ else
-+ return false;
-+#endif
-+ return false;
-+}
-+
-+bool dce120_hw_sequencer_construct(struct core_dc *dc)
-+{
-+ /* All registers used by dce11.2 match those in dce11 in offset and
-+ * structure
-+ */
-+ dce110_hw_sequencer_construct(dc);
-+ dc->hwss.enable_display_power_gating = dce120_enable_display_power_gating;
-+
-+ return true;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.h
-new file mode 100644
-index 0000000..3402413
---- /dev/null
-+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.h
-@@ -0,0 +1,36 @@
-+/*
-+* 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_HWSS_DCE120_H__
-+#define __DC_HWSS_DCE120_H__
-+
-+#include "core_types.h"
-+
-+struct core_dc;
-+
-+bool dce120_hw_sequencer_construct(struct core_dc *dc);
-+
-+#endif /* __DC_HWSS_DCE112_H__ */
-+
-diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp.c
-new file mode 100644
-index 0000000..f450569
---- /dev/null
-+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp.c
-@@ -0,0 +1,58 @@
-+/*
-+ * 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 "include/logger_interface.h"
-+
-+#include "vega10/DC/dce_12_0_offset.h"
-+#include "vega10/DC/dce_12_0_sh_mask.h"
-+#include "vega10/soc15ip.h"
-+
-+#include "dce120_ipp.h"
-+
-+static const struct ipp_funcs funcs = {
-+ .ipp_cursor_set_attributes = dce120_ipp_cursor_set_attributes,
-+ .ipp_cursor_set_position = dce120_ipp_cursor_set_position,
-+ .ipp_program_prescale = dce120_ipp_program_prescale,
-+ .ipp_program_input_lut = dce120_ipp_program_input_lut,
-+ .ipp_set_degamma = dce120_ipp_set_degamma,
-+};
-+
-+bool dce120_ipp_construct(
-+ struct dce110_ipp *ipp,
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_ipp_reg_offsets *offset)
-+{
-+ if (!dce110_ipp_construct(ipp, ctx, inst, offset)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ ipp->base.funcs = &funcs;
-+
-+ return true;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp.h b/drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp.h
-new file mode 100644
-index 0000000..4b326bc
---- /dev/null
-+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp.h
-@@ -0,0 +1,62 @@
-+/*
-+ * 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_IPP_DCE120_H__
-+#define __DC_IPP_DCE120_H__
-+
-+#include "ipp.h"
-+#include "../dce110/dce110_ipp.h"
-+
-+
-+bool dce120_ipp_construct(
-+ struct dce110_ipp *ipp,
-+ struct dc_context *ctx,
-+ enum controller_id id,
-+ const struct dce110_ipp_reg_offsets *offset);
-+
-+/* CURSOR RELATED */
-+void dce120_ipp_cursor_set_position(
-+ struct input_pixel_processor *ipp,
-+ const struct dc_cursor_position *position,
-+ const struct dc_cursor_mi_param *param);
-+
-+bool dce120_ipp_cursor_set_attributes(
-+ struct input_pixel_processor *ipp,
-+ const struct dc_cursor_attributes *attributes);
-+
-+/* DEGAMMA RELATED */
-+bool dce120_ipp_set_degamma(
-+ struct input_pixel_processor *ipp,
-+ enum ipp_degamma_mode mode);
-+
-+void dce120_ipp_program_prescale(
-+ struct input_pixel_processor *ipp,
-+ struct ipp_prescale_params *params);
-+
-+void dce120_ipp_program_input_lut(
-+ struct input_pixel_processor *ipp,
-+ const struct dc_gamma *gamma);
-+
-+#endif /*__DC_IPP_DCE120_H__*/
-diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp_cursor.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp_cursor.c
-new file mode 100644
-index 0000000..d520b5d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp_cursor.c
-@@ -0,0 +1,202 @@
-+/*
-+ * 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 "include/logger_interface.h"
-+
-+#include "vega10/DC/dce_12_0_offset.h"
-+#include "vega10/DC/dce_12_0_sh_mask.h"
-+#include "vega10/soc15ip.h"
-+
-+#include "../dce110/dce110_ipp.h"
-+
-+
-+#define DCP_REG_UPDATE_N(reg_name, n, ...) \
-+ generic_reg_update_soc15(ipp110->base.ctx, ipp110->offsets.dcp_offset, reg_name, n, __VA_ARGS__)
-+
-+#define DCP_REG_SET_N(reg_name, n, ...) \
-+ generic_reg_set_soc15(ipp110->base.ctx, ipp110->offsets.dcp_offset, reg_name, n, __VA_ARGS__)
-+
-+#define DCP_REG_UPDATE(reg, field, val) \
-+ DCP_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)
-+
-+#define DCP_REG_UPDATE_2(reg, field1, val1, field2, val2) \
-+ DCP_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+#define DCP_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3) \
-+ DCP_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-+
-+#define DCP_REG_SET(reg, field, val) \
-+ DCP_REG_SET_N(reg, 1, FD(reg##__##field), val)
-+
-+#define DCP_REG_SET_2(reg, field1, val1, field2, val2) \
-+ DCP_REG_SET_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+#define DCP_REG_SET_3(reg, field1, val1, field2, val2, field3, val3) \
-+ DCP_REG_SET_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-+
-+/* TODO: DAL3 does not implement cursor memory control
-+ * MCIF_MEM_CONTROL, DMIF_CURSOR_MEM_CONTROL
-+ */
-+static void lock(
-+ struct dce110_ipp *ipp110, bool lock)
-+{
-+ DCP_REG_UPDATE(DCP0_CUR_UPDATE, CURSOR_UPDATE_LOCK, lock);
-+}
-+
-+static bool program_control(
-+ struct dce110_ipp *ipp110,
-+ enum dc_cursor_color_format color_format,
-+ bool enable_magnification,
-+ bool inverse_transparent_clamping)
-+{
-+ uint32_t mode = 0;
-+
-+ switch (color_format) {
-+ case CURSOR_MODE_MONO:
-+ mode = 0;
-+ break;
-+ case CURSOR_MODE_COLOR_1BIT_AND:
-+ mode = 1;
-+ break;
-+ case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
-+ mode = 2;
-+ break;
-+ case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
-+ mode = 3;
-+ break;
-+ default:
-+ return false;
-+ }
-+
-+ DCP_REG_UPDATE_3(
-+ DCP0_CUR_CONTROL,
-+ CURSOR_MODE, mode,
-+ CURSOR_2X_MAGNIFY, enable_magnification,
-+ CUR_INV_TRANS_CLAMP, inverse_transparent_clamping);
-+
-+ if (color_format == CURSOR_MODE_MONO) {
-+ DCP_REG_SET_3(
-+ DCP0_CUR_COLOR1,
-+ CUR_COLOR1_BLUE, 0,
-+ CUR_COLOR1_GREEN, 0,
-+ CUR_COLOR1_RED, 0);
-+
-+ DCP_REG_SET_3(
-+ DCP0_CUR_COLOR2,
-+ CUR_COLOR2_BLUE, 0xff,
-+ CUR_COLOR2_GREEN, 0xff,
-+ CUR_COLOR2_RED, 0xff);
-+ }
-+ return true;
-+}
-+
-+static void program_address(
-+ struct dce110_ipp *ipp110,
-+ PHYSICAL_ADDRESS_LOC address)
-+{
-+ /* SURFACE_ADDRESS_HIGH: Higher order bits (39:32) of hardware cursor
-+ * surface base address in byte. It is 4K byte aligned.
-+ * The correct way to program cursor surface address is to first write
-+ * to CUR_SURFACE_ADDRESS_HIGH, and then write to CUR_SURFACE_ADDRESS
-+ */
-+
-+ DCP_REG_SET(
-+ DCP0_CUR_SURFACE_ADDRESS_HIGH,
-+ CURSOR_SURFACE_ADDRESS_HIGH, address.high_part);
-+
-+ DCP_REG_SET(
-+ DCP0_CUR_SURFACE_ADDRESS,
-+ CURSOR_SURFACE_ADDRESS, address.low_part);
-+}
-+
-+void dce120_ipp_cursor_set_position(
-+ struct input_pixel_processor *ipp,
-+ const struct dc_cursor_position *position,
-+ const struct dc_cursor_mi_param *param)
-+{
-+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
-+
-+ /* lock cursor registers */
-+ lock(ipp110, true);
-+
-+ /* Flag passed in structure differentiates cursor enable/disable. */
-+ /* Update if it differs from cached state. */
-+ DCP_REG_UPDATE(DCP0_CUR_CONTROL, CURSOR_EN, position->enable);
-+
-+ DCP_REG_SET_2(
-+ DCP0_CUR_POSITION,
-+ CURSOR_X_POSITION, position->x,
-+ CURSOR_Y_POSITION, position->y);
-+
-+ if (position->hot_spot_enable)
-+ DCP_REG_SET_2(
-+ DCP0_CUR_HOT_SPOT,
-+ CURSOR_HOT_SPOT_X, position->x_hotspot,
-+ CURSOR_HOT_SPOT_Y, position->y_hotspot);
-+
-+ /* unlock cursor registers */
-+ lock(ipp110, false);
-+}
-+
-+bool dce120_ipp_cursor_set_attributes(
-+ struct input_pixel_processor *ipp,
-+ const struct dc_cursor_attributes *attributes)
-+{
-+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
-+ /* Lock cursor registers */
-+ lock(ipp110, true);
-+
-+ /* Program cursor control */
-+ program_control(
-+ ipp110,
-+ attributes->color_format,
-+ attributes->attribute_flags.bits.ENABLE_MAGNIFICATION,
-+ attributes->attribute_flags.bits.INVERSE_TRANSPARENT_CLAMPING);
-+
-+ /* Program hot spot coordinates */
-+ DCP_REG_SET_2(
-+ DCP0_CUR_HOT_SPOT,
-+ CURSOR_HOT_SPOT_X, attributes->x_hot,
-+ CURSOR_HOT_SPOT_Y, attributes->y_hot);
-+
-+ /*
-+ * Program cursor size -- NOTE: HW spec specifies that HW register
-+ * stores size as (height - 1, width - 1)
-+ */
-+ DCP_REG_SET_2(
-+ DCP0_CUR_SIZE,
-+ CURSOR_WIDTH, attributes->width-1,
-+ CURSOR_HEIGHT, attributes->height-1);
-+
-+ /* Program cursor surface address */
-+ program_address(ipp110, attributes->address);
-+
-+ /* Unlock Cursor registers. */
-+ lock(ipp110, false);
-+
-+ return true;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp_gamma.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp_gamma.c
-new file mode 100644
-index 0000000..7aa5a49
---- /dev/null
-+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_ipp_gamma.c
-@@ -0,0 +1,167 @@
-+/*
-+ * 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 "include/logger_interface.h"
-+#include "include/fixed31_32.h"
-+#include "basics/conversion.h"
-+
-+#include "vega10/DC/dce_12_0_offset.h"
-+#include "vega10/DC/dce_12_0_sh_mask.h"
-+#include "vega10/soc15ip.h"
-+
-+#include "../dce110/dce110_ipp.h"
-+
-+#define DCP_REG_UPDATE_N(reg_name, n, ...) \
-+ generic_reg_update_soc15(ipp110->base.ctx, ipp110->offsets.dcp_offset, reg_name, n, __VA_ARGS__)
-+
-+#define DCP_REG_SET_N(reg_name, n, ...) \
-+ generic_reg_set_soc15(ipp110->base.ctx, ipp110->offsets.dcp_offset, reg_name, n, __VA_ARGS__)
-+
-+#define DCP_REG_UPDATE(reg, field, val) \
-+ DCP_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)
-+
-+#define DCP_REG_UPDATE_2(reg, field1, val1, field2, val2) \
-+ DCP_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+#define DCP_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3) \
-+ DCP_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-+
-+#define DCP_REG_SET(reg, field, val) \
-+ DCP_REG_SET_N(reg, 1, FD(reg##__##field), val)
-+
-+#define DCP_REG_SET_2(reg, field1, val1, field2, val2) \
-+ DCP_REG_SET_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+#define DCP_REG_SET_3(reg, field1, val1, field2, val2, field3, val3) \
-+ DCP_REG_SET_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-+
-+
-+bool dce120_ipp_set_degamma(
-+ struct input_pixel_processor *ipp,
-+ enum ipp_degamma_mode mode)
-+{
-+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
-+ uint32_t degamma_type = (mode == IPP_DEGAMMA_MODE_HW_sRGB) ? 1 : 0;
-+
-+ ASSERT(mode == IPP_DEGAMMA_MODE_BYPASS ||
-+ mode == IPP_DEGAMMA_MODE_HW_sRGB);
-+
-+ DCP_REG_SET_3(
-+ DCP0_DEGAMMA_CONTROL,
-+ GRPH_DEGAMMA_MODE, degamma_type,
-+ CURSOR_DEGAMMA_MODE, degamma_type,
-+ CURSOR2_DEGAMMA_MODE, degamma_type);
-+
-+ return true;
-+}
-+
-+void dce120_ipp_program_prescale(
-+ struct input_pixel_processor *ipp,
-+ struct ipp_prescale_params *params)
-+{
-+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
-+
-+ /* set to bypass mode first before change */
-+ DCP_REG_UPDATE(
-+ DCP0_PRESCALE_GRPH_CONTROL,
-+ GRPH_PRESCALE_BYPASS,
-+ 1);
-+
-+ DCP_REG_SET_2(
-+ DCP0_PRESCALE_VALUES_GRPH_R,
-+ GRPH_PRESCALE_SCALE_R, params->scale,
-+ GRPH_PRESCALE_BIAS_R, params->bias);
-+
-+ DCP_REG_SET_2(
-+ DCP0_PRESCALE_VALUES_GRPH_G,
-+ GRPH_PRESCALE_SCALE_G, params->scale,
-+ GRPH_PRESCALE_BIAS_G, params->bias);
-+
-+ DCP_REG_SET_2(
-+ DCP0_PRESCALE_VALUES_GRPH_B,
-+ GRPH_PRESCALE_SCALE_B, params->scale,
-+ GRPH_PRESCALE_BIAS_B, params->bias);
-+
-+ if (params->mode != IPP_PRESCALE_MODE_BYPASS) {
-+ DCP_REG_UPDATE(DCP0_PRESCALE_GRPH_CONTROL,
-+ GRPH_PRESCALE_BYPASS, 0);
-+
-+ /* If prescale is in use, then legacy lut should be bypassed */
-+ DCP_REG_UPDATE(DCP0_INPUT_GAMMA_CONTROL,
-+ GRPH_INPUT_GAMMA_MODE, 1);
-+ }
-+}
-+
-+static void dce120_helper_select_lut(struct dce110_ipp *ipp110)
-+{
-+ /* enable all */
-+ DCP_REG_SET(
-+ DCP0_DC_LUT_WRITE_EN_MASK,
-+ DC_LUT_WRITE_EN_MASK,
-+ 0x7);
-+
-+ /* 256 entry mode */
-+ DCP_REG_UPDATE(DCP0_DC_LUT_RW_MODE, DC_LUT_RW_MODE, 0);
-+
-+ /* LUT-256, unsigned, integer, new u0.12 format */
-+ DCP_REG_SET_3(
-+ DCP0_DC_LUT_CONTROL,
-+ DC_LUT_DATA_R_FORMAT, 3,
-+ DC_LUT_DATA_G_FORMAT, 3,
-+ DC_LUT_DATA_B_FORMAT, 3);
-+
-+ /* start from index 0 */
-+ DCP_REG_SET(
-+ DCP0_DC_LUT_RW_INDEX,
-+ DC_LUT_RW_INDEX,
-+ 0);
-+}
-+
-+void dce120_ipp_program_input_lut(
-+ struct input_pixel_processor *ipp,
-+ const struct dc_gamma *gamma)
-+{
-+ int i;
-+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
-+
-+ /* power on LUT memory */
-+ DCP_REG_SET(DCFE0_DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, 1);
-+
-+ dce120_helper_select_lut(ipp110);
-+
-+ for (i = 0; i < INPUT_LUT_ENTRIES; i++) {
-+ DCP_REG_SET(DCP0_DC_LUT_SEQ_COLOR, DC_LUT_SEQ_COLOR, gamma->red[i]);
-+ DCP_REG_SET(DCP0_DC_LUT_SEQ_COLOR, DC_LUT_SEQ_COLOR, gamma->green[i]);
-+ DCP_REG_SET(DCP0_DC_LUT_SEQ_COLOR, DC_LUT_SEQ_COLOR, gamma->blue[i]);
-+ }
-+
-+ /* power off LUT memory */
-+ DCP_REG_SET(DCFE0_DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, 0);
-+
-+ /* bypass prescale, enable legacy LUT */
-+ DCP_REG_UPDATE(DCP0_PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_BYPASS, 1);
-+ DCP_REG_UPDATE(DCP0_INPUT_GAMMA_CONTROL, GRPH_INPUT_GAMMA_MODE, 0);
-+}
-diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_mem_input.c
-new file mode 100644
-index 0000000..c067721
---- /dev/null
-+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_mem_input.c
-@@ -0,0 +1,340 @@
-+/*
-+ * 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 "dce120_mem_input.h"
-+
-+
-+#include "vega10/DC/dce_12_0_offset.h"
-+#include "vega10/DC/dce_12_0_sh_mask.h"
-+#include "vega10/soc15ip.h"
-+
-+#define GENERAL_REG_UPDATE_N(reg_name, n, ...) \
-+ generic_reg_update_soc15(mem_input110->base.ctx, 0, reg_name, n, __VA_ARGS__)
-+
-+#define GENERAL_REG_UPDATE(reg, field, val) \
-+ GENERAL_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)
-+
-+#define GENERAL_REG_UPDATE_2(reg, field1, val1, field2, val2) \
-+ GENERAL_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+
-+
-+#define DCP_REG_UPDATE_N(reg_name, n, ...) \
-+ generic_reg_update_soc15(mem_input110->base.ctx, mem_input110->offsets.dcp, reg_name, n, __VA_ARGS__)
-+
-+#define DCP_REG_SET_N(reg_name, n, ...) \
-+ generic_reg_set_soc15(mem_input110->base.ctx, mem_input110->offsets.dcp, reg_name, n, __VA_ARGS__)
-+
-+#define DCP_REG_UPDATE(reg, field, val) \
-+ DCP_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)
-+
-+#define DCP_REG_UPDATE_2(reg, field1, val1, field2, val2) \
-+ DCP_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+#define DCP_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3) \
-+ DCP_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-+
-+#define DCP_REG_SET(reg, field, val) \
-+ DCP_REG_SET_N(reg, 1, FD(reg##__##field), val)
-+
-+#define DCP_REG_SET_2(reg, field1, val1, field2, val2) \
-+ DCP_REG_SET_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+#define DCP_REG_SET_3(reg, field1, val1, field2, val2, field3, val3) \
-+ DCP_REG_SET_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-+
-+
-+
-+#define DMIF_REG_UPDATE_N(reg_name, n, ...) \
-+ generic_reg_update_soc15(mem_input110->base.ctx, mem_input110->offsets.dmif, reg_name, n, __VA_ARGS__)
-+
-+#define DMIF_REG_SET_N(reg_name, n, ...) \
-+ generic_reg_set_soc15(mem_input110->base.ctx, mem_input110->offsets.dmif, reg_name, n, __VA_ARGS__)
-+
-+#define DMIF_REG_UPDATE(reg, field, val) \
-+ DMIF_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)
-+
-+#define DMIF_REG_UPDATE_2(reg, field1, val1, field2, val2) \
-+ DMIF_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+#define DMIF_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3) \
-+ DMIF_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-+
-+#define DMIF_REG_SET(reg, field, val) \
-+ DMIF_REG_SET_N(reg, 1, FD(reg##__##field), val)
-+
-+#define DMIF_REG_SET_2(reg, field1, val1, field2, val2) \
-+ DMIF_REG_SET_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+#define DMIF_REG_SET_3(reg, field1, val1, field2, val2, field3, val3) \
-+ DMIF_REG_SET_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-+
-+
-+
-+#define PIPE_REG_UPDATE_N(reg_name, n, ...) \
-+ generic_reg_update_soc15(mem_input110->base.ctx, mem_input110->offsets.pipe, reg_name, n, __VA_ARGS__)
-+
-+#define PIPE_REG_SET_N(reg_name, n, ...) \
-+ generic_reg_set_soc15(mem_input110->base.ctx, mem_input110->offsets.pipe, reg_name, n, __VA_ARGS__)
-+
-+#define PIPE_REG_UPDATE(reg, field, val) \
-+ PIPE_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)
-+
-+#define PIPE_REG_UPDATE_2(reg, field1, val1, field2, val2) \
-+ PIPE_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+#define PIPE_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3) \
-+ PIPE_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-+
-+#define PIPE_REG_SET(reg, field, val) \
-+ PIPE_REG_SET_N(reg, 1, FD(reg##__##field), val)
-+
-+#define PIPE_REG_SET_2(reg, field1, val1, field2, val2) \
-+ PIPE_REG_SET_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+#define PIPE_REG_SET_3(reg, field1, val1, field2, val2, field3, val3) \
-+ PIPE_REG_SET_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-+
-+
-+
-+static void program_sec_addr(
-+ struct dce110_mem_input *mem_input110,
-+ PHYSICAL_ADDRESS_LOC address)
-+{
-+ uint32_t temp;
-+
-+ /*high register MUST be programmed first*/
-+ temp = address.high_part &
-+ DCP0_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__GRPH_SECONDARY_SURFACE_ADDRESS_HIGH_MASK;
-+
-+ DCP_REG_SET(
-+ DCP0_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
-+ GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
-+ temp);
-+
-+ temp = address.low_part >>
-+ DCP0_GRPH_SECONDARY_SURFACE_ADDRESS__GRPH_SECONDARY_SURFACE_ADDRESS__SHIFT;
-+
-+ DCP_REG_SET_2(
-+ DCP0_GRPH_SECONDARY_SURFACE_ADDRESS,
-+ GRPH_SECONDARY_SURFACE_ADDRESS, temp,
-+ GRPH_SECONDARY_DFQ_ENABLE, 0);
-+}
-+
-+static void program_pri_addr(
-+ struct dce110_mem_input *mem_input110,
-+ PHYSICAL_ADDRESS_LOC address)
-+{
-+ uint32_t temp;
-+
-+ /*high register MUST be programmed first*/
-+ temp = address.high_part &
-+ DCP0_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_MASK;
-+
-+ DCP_REG_SET(
-+ DCP0_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
-+ GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
-+ temp);
-+
-+ temp = address.low_part >>
-+ DCP0_GRPH_PRIMARY_SURFACE_ADDRESS__GRPH_PRIMARY_SURFACE_ADDRESS__SHIFT;
-+
-+ DCP_REG_SET(
-+ DCP0_GRPH_PRIMARY_SURFACE_ADDRESS,
-+ GRPH_PRIMARY_SURFACE_ADDRESS,
-+ temp);
-+}
-+
-+
-+static bool mem_input_is_flip_pending(struct mem_input *mem_input)
-+{
-+ struct dce110_mem_input *mem_input110 = TO_DCE110_MEM_INPUT(mem_input);
-+ uint32_t value;
-+
-+ value = dm_read_reg_soc15(mem_input110->base.ctx,
-+ mmDCP0_GRPH_UPDATE, mem_input110->offsets.dcp);
-+
-+ if (get_reg_field_value(value, DCP0_GRPH_UPDATE,
-+ GRPH_SURFACE_UPDATE_PENDING))
-+ return true;
-+
-+ mem_input->current_address = mem_input->request_address;
-+ return false;
-+}
-+
-+static bool mem_input_program_surface_flip_and_addr(
-+ struct mem_input *mem_input,
-+ const struct dc_plane_address *address,
-+ bool flip_immediate)
-+{
-+ struct dce110_mem_input *mem_input110 = TO_DCE110_MEM_INPUT(mem_input);
-+
-+ /* TODO: Figure out if two modes are needed:
-+ * non-XDMA Mode: GRPH_SURFACE_UPDATE_IMMEDIATE_EN = 1
-+ * XDMA Mode: GRPH_SURFACE_UPDATE_H_RETRACE_EN = 1
-+ */
-+ DCP_REG_UPDATE(DCP0_GRPH_UPDATE,
-+ GRPH_UPDATE_LOCK, 1);
-+
-+ if (flip_immediate) {
-+ DCP_REG_UPDATE_2(
-+ DCP0_GRPH_FLIP_CONTROL,
-+ GRPH_SURFACE_UPDATE_IMMEDIATE_EN, 0,
-+ GRPH_SURFACE_UPDATE_H_RETRACE_EN, 1);
-+ } else {
-+ DCP_REG_UPDATE_2(
-+ DCP0_GRPH_FLIP_CONTROL,
-+ GRPH_SURFACE_UPDATE_IMMEDIATE_EN, 0,
-+ GRPH_SURFACE_UPDATE_H_RETRACE_EN, 0);
-+ }
-+
-+ switch (address->type) {
-+ case PLN_ADDR_TYPE_GRAPHICS:
-+ if (address->grph.addr.quad_part == 0)
-+ break;
-+ program_pri_addr(mem_input110, address->grph.addr);
-+ break;
-+ case PLN_ADDR_TYPE_GRPH_STEREO:
-+ if (address->grph_stereo.left_addr.quad_part == 0
-+ || address->grph_stereo.right_addr.quad_part == 0)
-+ break;
-+ program_pri_addr(mem_input110, address->grph_stereo.left_addr);
-+ program_sec_addr(mem_input110, address->grph_stereo.right_addr);
-+ break;
-+ default:
-+ /* not supported */
-+ BREAK_TO_DEBUGGER();
-+ break;
-+ }
-+
-+ mem_input->request_address = *address;
-+
-+ if (flip_immediate)
-+ mem_input->current_address = *address;
-+
-+ DCP_REG_UPDATE(DCP0_GRPH_UPDATE,
-+ GRPH_UPDATE_LOCK, 0);
-+
-+ return true;
-+}
-+
-+static void mem_input_update_dchub(struct mem_input *mi,
-+ struct dchub_init_data *dh_data)
-+{
-+ struct dce110_mem_input *mem_input110 = TO_DCE110_MEM_INPUT(mi);
-+ /* TODO: port code from dal2 */
-+ switch (dh_data->fb_mode) {
-+ case FRAME_BUFFER_MODE_ZFB_ONLY:
-+ /*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/
-+ GENERAL_REG_UPDATE_2(
-+ DCHUB_FB_LOCATION,
-+ FB_TOP, 0,
-+ FB_BASE, 0x0FFFF);
-+
-+ GENERAL_REG_UPDATE(
-+ DCHUB_AGP_BASE,
-+ AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
-+
-+ GENERAL_REG_UPDATE(
-+ DCHUB_AGP_BOT,
-+ AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
-+
-+ GENERAL_REG_UPDATE(
-+ DCHUB_AGP_TOP,
-+ AGP_TOP, (dh_data->zfb_mc_base_addr + dh_data->zfb_size_in_byte - 1) >> 22);
-+ break;
-+ case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL:
-+ /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
-+ GENERAL_REG_UPDATE(
-+ DCHUB_AGP_BASE,
-+ AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
-+
-+ GENERAL_REG_UPDATE(
-+ DCHUB_AGP_BOT,
-+ AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
-+
-+ GENERAL_REG_UPDATE(
-+ DCHUB_AGP_TOP,
-+ AGP_TOP, (dh_data->zfb_mc_base_addr + dh_data->zfb_size_in_byte - 1) >> 22);
-+ break;
-+ case FRAME_BUFFER_MODE_LOCAL_ONLY:
-+ /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
-+ GENERAL_REG_UPDATE(
-+ DCHUB_AGP_BASE,
-+ AGP_BASE, 0);
-+
-+ GENERAL_REG_UPDATE(
-+ DCHUB_AGP_BOT,
-+ AGP_BOT, 0x03FFFF);
-+
-+ GENERAL_REG_UPDATE(
-+ DCHUB_AGP_TOP,
-+ AGP_TOP, 0);
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ dh_data->dchub_initialzied = true;
-+ dh_data->dchub_info_valid = false;
-+}
-+
-+static struct mem_input_funcs dce120_mem_input_funcs = {
-+ .mem_input_program_display_marks = dce_mem_input_program_display_marks,
-+ .allocate_mem_input = dce_mem_input_allocate_dmif,
-+ .free_mem_input = dce_mem_input_free_dmif,
-+ .mem_input_program_surface_flip_and_addr =
-+ mem_input_program_surface_flip_and_addr,
-+ .mem_input_program_pte_vm = dce_mem_input_program_pte_vm,
-+ .mem_input_program_surface_config =
-+ dce_mem_input_program_surface_config,
-+ .mem_input_is_flip_pending = mem_input_is_flip_pending,
-+ .mem_input_update_dchub = mem_input_update_dchub
-+};
-+
-+/*****************************************/
-+/* Constructor, Destructor */
-+/*****************************************/
-+
-+bool dce120_mem_input_construct(
-+ struct dce110_mem_input *mem_input110,
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_mem_input_reg_offsets *offsets)
-+{
-+ /* supported stutter method
-+ * STUTTER_MODE_ENHANCED
-+ * STUTTER_MODE_QUAD_DMIF_BUFFER
-+ * STUTTER_MODE_WATERMARK_NBP_STATE
-+ */
-+
-+ if (!dce110_mem_input_construct(mem_input110, ctx, inst, offsets))
-+ return false;
-+
-+ mem_input110->base.funcs = &dce120_mem_input_funcs;
-+ mem_input110->offsets = *offsets;
-+
-+ return true;
-+}
-diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_mem_input.h b/drivers/gpu/drm/amd/display/dc/dce120/dce120_mem_input.h
-new file mode 100644
-index 0000000..379fd72
---- /dev/null
-+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_mem_input.h
-@@ -0,0 +1,37 @@
-+/* 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_MEM_INPUT_DCE120_H__
-+#define __DC_MEM_INPUT_DCE120_H__
-+
-+#include "mem_input.h"
-+#include "dce110/dce110_mem_input.h"
-+
-+bool dce120_mem_input_construct(
-+ struct dce110_mem_input *mem_input110,
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_mem_input_reg_offsets *offsets);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
-new file mode 100644
-index 0000000..9a1984b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
-@@ -0,0 +1,1099 @@
-+/*
-+* Copyright 2012-15 Advanced Micro Devices, Inc.cls
-+*
-+ *
-+ * 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 "stream_encoder.h"
-+#include "resource.h"
-+#include "include/irq_service_interface.h"
-+#include "dce120_resource.h"
-+#include "dce112/dce112_resource.h"
-+
-+#include "dce110/dce110_resource.h"
-+#include "../virtual/virtual_stream_encoder.h"
-+#include "dce120_timing_generator.h"
-+#include "irq/dce120/irq_service_dce120.h"
-+#include "dce/dce_opp.h"
-+#include "dce/dce_clock_source.h"
-+#include "dce/dce_clocks.h"
-+#include "dce120_ipp.h"
-+#include "dce110/dce110_mem_input.h"
-+#include "dce120/dce120_mem_input.h"
-+
-+#include "dce110/dce110_hw_sequencer.h"
-+#include "dce120/dce120_hw_sequencer.h"
-+#include "dce/dce_transform.h"
-+
-+#include "dce/dce_audio.h"
-+#include "dce/dce_link_encoder.h"
-+#include "dce/dce_stream_encoder.h"
-+#include "dce/dce_hwseq.h"
-+#include "dce/dce_abm.h"
-+#include "dce/dce_dmcu.h"
-+
-+#include "vega10/DC/dce_12_0_offset.h"
-+#include "vega10/DC/dce_12_0_sh_mask.h"
-+#include "vega10/soc15ip.h"
-+#include "vega10/NBIO/nbio_6_1_offset.h"
-+#include "reg_helper.h"
-+
-+#ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
-+ #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
-+ #define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
-+ #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x220f
-+ #define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
-+ #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x230f
-+ #define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
-+ #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x240f
-+ #define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
-+ #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x250f
-+ #define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
-+ #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x260f
-+ #define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
-+ #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x270f
-+ #define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
-+#endif
-+
-+enum dce120_clk_src_array_id {
-+ DCE120_CLK_SRC_PLL0,
-+ DCE120_CLK_SRC_PLL1,
-+ DCE120_CLK_SRC_PLL2,
-+ DCE120_CLK_SRC_PLL3,
-+ DCE120_CLK_SRC_PLL4,
-+ DCE120_CLK_SRC_PLL5,
-+
-+ DCE120_CLK_SRC_TOTAL
-+};
-+
-+static const struct dce110_timing_generator_offsets dce120_tg_offsets[] = {
-+ {
-+ .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
-+ }
-+};
-+
-+/* begin *********************
-+ * macros to expend register list macro defined in HW object header file */
-+
-+#define BASE_INNER(seg) \
-+ DCE_BASE__INST0_SEG ## seg
-+
-+#define NBIO_BASE_INNER(seg) \
-+ NBIF_BASE__INST0_SEG ## seg
-+
-+#define NBIO_BASE(seg) \
-+ NBIO_BASE_INNER(seg)
-+
-+/* compile time expand base address. */
-+#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
-+
-+/* macros to expend register list macro defined in HW object header file
-+ * end *********************/
-+
-+
-+static const struct dce_disp_clk_registers disp_clk_regs = {
-+ CLK_COMMON_REG_LIST_DCE_BASE()
-+};
-+
-+static const struct dce_disp_clk_shift disp_clk_shift = {
-+ CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
-+};
-+
-+static const struct dce_disp_clk_mask disp_clk_mask = {
-+ CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
-+};
-+
-+static const struct dce_dmcu_registers dmcu_regs = {
-+ DMCU_DCE110_COMMON_REG_LIST()
-+};
-+
-+static const struct dce_dmcu_shift dmcu_shift = {
-+ DMCU_MASK_SH_LIST_DCE110(__SHIFT)
-+};
-+
-+static const struct dce_dmcu_mask dmcu_mask = {
-+ DMCU_MASK_SH_LIST_DCE110(_MASK)
-+};
-+
-+static const struct dce_abm_registers abm_regs = {
-+ ABM_DCE110_COMMON_REG_LIST()
-+};
-+
-+static const struct dce_abm_shift abm_shift = {
-+ ABM_MASK_SH_LIST_DCE110(__SHIFT)
-+};
-+
-+static const struct dce_abm_mask abm_mask = {
-+ ABM_MASK_SH_LIST_DCE110(_MASK)
-+};
-+
-+#define transform_regs(id)\
-+[id] = {\
-+ XFM_COMMON_REG_LIST_DCE110(id)\
-+}
-+
-+static const struct dce_transform_registers xfm_regs[] = {
-+ transform_regs(0),
-+ transform_regs(1),
-+ transform_regs(2),
-+ transform_regs(3),
-+ transform_regs(4),
-+ transform_regs(5)
-+};
-+
-+static const struct dce_transform_shift xfm_shift = {
-+ XFM_COMMON_MASK_SH_LIST_SOC_BASE(__SHIFT)
-+};
-+
-+static const struct dce_transform_mask xfm_mask = {
-+ XFM_COMMON_MASK_SH_LIST_SOC_BASE(_MASK)
-+};
-+
-+#define aux_regs(id)\
-+[id] = {\
-+ AUX_REG_LIST(id)\
-+}
-+
-+static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
-+ aux_regs(0),
-+ aux_regs(1),
-+ aux_regs(2),
-+ aux_regs(3),
-+ aux_regs(4),
-+ aux_regs(5)
-+};
-+
-+#define hpd_regs(id)\
-+[id] = {\
-+ HPD_REG_LIST(id)\
-+}
-+
-+static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
-+ hpd_regs(0),
-+ hpd_regs(1),
-+ hpd_regs(2),
-+ hpd_regs(3),
-+ hpd_regs(4),
-+ hpd_regs(5)
-+};
-+
-+#define link_regs(id)\
-+[id] = {\
-+ LE_DCE120_REG_LIST(id), \
-+ SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
-+}
-+
-+static const struct dce110_link_enc_registers link_enc_regs[] = {
-+ link_regs(0),
-+ link_regs(1),
-+ link_regs(2),
-+ link_regs(3),
-+ link_regs(4),
-+ link_regs(5),
-+ link_regs(6),
-+};
-+
-+
-+#define stream_enc_regs(id)\
-+[id] = {\
-+ SE_COMMON_REG_LIST(id),\
-+ .TMDS_CNTL = 0,\
-+}
-+
-+static const struct dce110_stream_enc_registers stream_enc_regs[] = {
-+ stream_enc_regs(0),
-+ stream_enc_regs(1),
-+ stream_enc_regs(2),
-+ stream_enc_regs(3),
-+ stream_enc_regs(4),
-+ stream_enc_regs(5)
-+};
-+
-+static const struct dce_stream_encoder_shift se_shift = {
-+ SE_COMMON_MASK_SH_LIST_DCE120(__SHIFT)
-+};
-+
-+static const struct dce_stream_encoder_mask se_mask = {
-+ SE_COMMON_MASK_SH_LIST_DCE120(_MASK)
-+};
-+
-+#define opp_regs(id)\
-+[id] = {\
-+ OPP_DCE_120_REG_LIST(id),\
-+}
-+
-+static const struct dce_opp_registers opp_regs[] = {
-+ opp_regs(0),
-+ opp_regs(1),
-+ opp_regs(2),
-+ opp_regs(3),
-+ opp_regs(4),
-+ opp_regs(5)
-+};
-+
-+static const struct dce_opp_shift opp_shift = {
-+ OPP_COMMON_MASK_SH_LIST_DCE_120(__SHIFT)
-+};
-+
-+static const struct dce_opp_mask opp_mask = {
-+ OPP_COMMON_MASK_SH_LIST_DCE_120(_MASK)
-+};
-+
-+#define audio_regs(id)\
-+[id] = {\
-+ AUD_COMMON_REG_LIST(id)\
-+}
-+
-+static struct dce_audio_registers audio_regs[] = {
-+ audio_regs(0),
-+ audio_regs(1),
-+ audio_regs(2),
-+ audio_regs(3),
-+ audio_regs(4),
-+ audio_regs(5)
-+};
-+
-+#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_aduio_mask audio_mask = {
-+ DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
-+};
-+
-+#define clk_src_regs(index, id)\
-+[index] = {\
-+ CS_COMMON_REG_LIST_DCE_112(id),\
-+}
-+
-+static const struct dce110_clk_src_regs clk_src_regs[] = {
-+ clk_src_regs(0, A),
-+ clk_src_regs(1, B),
-+ clk_src_regs(2, C),
-+ clk_src_regs(3, D),
-+ clk_src_regs(4, E),
-+ clk_src_regs(5, F)
-+};
-+
-+static const struct dce110_clk_src_shift cs_shift = {
-+ CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)
-+};
-+
-+static const struct dce110_clk_src_mask cs_mask = {
-+ CS_COMMON_MASK_SH_LIST_DCE_112(_MASK)
-+};
-+
-+struct output_pixel_processor *dce120_opp_create(
-+ struct dc_context *ctx,
-+ uint32_t inst)
-+{
-+ struct dce110_opp *opp =
-+ dm_alloc(sizeof(struct dce110_opp));
-+
-+ if (!opp)
-+ return NULL;
-+
-+ if (dce110_opp_construct(opp,
-+ ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask))
-+ return &opp->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(opp);
-+ return NULL;
-+}
-+
-+static const struct dce110_ipp_reg_offsets dce120_ipp_reg_offsets[] = {
-+ {
-+ .dcp_offset = (mmDCP0_CUR_CONTROL - mmDCP0_CUR_CONTROL),
-+ },
-+ {
-+ .dcp_offset = (mmDCP1_CUR_CONTROL - mmDCP0_CUR_CONTROL),
-+ },
-+ {
-+ .dcp_offset = (mmDCP2_CUR_CONTROL - mmDCP0_CUR_CONTROL),
-+ },
-+ {
-+ .dcp_offset = (mmDCP3_CUR_CONTROL - mmDCP0_CUR_CONTROL),
-+ },
-+ {
-+ .dcp_offset = (mmDCP4_CUR_CONTROL - mmDCP0_CUR_CONTROL),
-+ },
-+ {
-+ .dcp_offset = (mmDCP5_CUR_CONTROL - mmDCP0_CUR_CONTROL),
-+ }
-+};
-+
-+static const struct dce110_mem_input_reg_offsets dce120_mi_reg_offsets[] = {
-+ {
-+ .dcp = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif = (mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL
-+ - mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE0_DMIF_BUFFER_CONTROL
-+ - mmPIPE0_DMIF_BUFFER_CONTROL),
-+ },
-+ {
-+ .dcp = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif = (mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL
-+ - mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE1_DMIF_BUFFER_CONTROL
-+ - mmPIPE0_DMIF_BUFFER_CONTROL),
-+ },
-+ {
-+ .dcp = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif = (mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL
-+ - mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE2_DMIF_BUFFER_CONTROL
-+ - mmPIPE0_DMIF_BUFFER_CONTROL),
-+ },
-+ {
-+ .dcp = (mmDCP3_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif = (mmDMIF_PG3_DPG_WATERMARK_MASK_CONTROL
-+ - mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE3_DMIF_BUFFER_CONTROL
-+ - mmPIPE0_DMIF_BUFFER_CONTROL),
-+ },
-+ {
-+ .dcp = (mmDCP4_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif = (mmDMIF_PG4_DPG_WATERMARK_MASK_CONTROL
-+ - mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE4_DMIF_BUFFER_CONTROL
-+ - mmPIPE0_DMIF_BUFFER_CONTROL),
-+ },
-+ {
-+ .dcp = (mmDCP5_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif = (mmDMIF_PG5_DPG_WATERMARK_MASK_CONTROL
-+ - mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE5_DMIF_BUFFER_CONTROL
-+ - mmPIPE0_DMIF_BUFFER_CONTROL),
-+ }
-+};
-+
-+static const struct bios_registers bios_regs = {
-+ .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 + NBIO_BASE(mmBIOS_SCRATCH_6_BASE_IDX)
-+};
-+
-+static const struct resource_caps res_cap = {
-+ .num_timing_generator = 3,
-+ .num_audio = 7,
-+ .num_stream_encoder = 6,
-+ .num_pll = 6,
-+};
-+
-+static const struct dc_debug debug_defaults = {
-+ .disable_clock_gate = true,
-+};
-+
-+struct clock_source *dce120_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 =
-+ dm_alloc(sizeof(struct dce110_clk_src));
-+
-+ if (!clk_src)
-+ return NULL;
-+
-+ if (dce110_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;
-+ }
-+
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+}
-+
-+void dce120_clock_source_destroy(struct clock_source **clk_src)
-+{
-+ dm_free(TO_DCE110_CLK_SRC(*clk_src));
-+ *clk_src = NULL;
-+}
-+
-+
-+bool dce120_hw_sequencer_create(struct core_dc *dc)
-+{
-+ /* All registers used by dce11.2 match those in dce11 in offset and
-+ * structure
-+ */
-+ dce120_hw_sequencer_construct(dc);
-+
-+ /*TODO Move to separate file and Override what is needed */
-+
-+ return true;
-+}
-+
-+static struct timing_generator *dce120_timing_generator_create(
-+ struct dc_context *ctx,
-+ uint32_t instance,
-+ const struct dce110_timing_generator_offsets *offsets)
-+{
-+ struct dce110_timing_generator *tg110 =
-+ dm_alloc(sizeof(struct dce110_timing_generator));
-+
-+ if (!tg110)
-+ return NULL;
-+
-+ if (dce120_timing_generator_construct(tg110, ctx, instance, offsets))
-+ return &tg110->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(tg110);
-+ return NULL;
-+}
-+
-+static void dce120_ipp_destroy(struct input_pixel_processor **ipp)
-+{
-+ dm_free(TO_DCE110_IPP(*ipp));
-+ *ipp = NULL;
-+}
-+
-+static void dce120_transform_destroy(struct transform **xfm)
-+{
-+ dm_free(TO_DCE_TRANSFORM(*xfm));
-+ *xfm = NULL;
-+}
-+
-+static void destruct(struct dce110_resource_pool *pool)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < pool->base.pipe_count; i++) {
-+ if (pool->base.opps[i] != NULL)
-+ dce110_opp_destroy(&pool->base.opps[i]);
-+
-+ if (pool->base.transforms[i] != NULL)
-+ dce120_transform_destroy(&pool->base.transforms[i]);
-+
-+ if (pool->base.ipps[i] != NULL)
-+ dce120_ipp_destroy(&pool->base.ipps[i]);
-+
-+ if (pool->base.mis[i] != NULL) {
-+ dm_free(TO_DCE110_MEM_INPUT(pool->base.mis[i]));
-+ pool->base.mis[i] = NULL;
-+ }
-+
-+ if (pool->base.irqs != NULL) {
-+ dal_irq_service_destroy(&pool->base.irqs);
-+ }
-+
-+ if (pool->base.timing_generators[i] != NULL) {
-+ dm_free(DCE110TG_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.stream_enc_count; i++) {
-+ if (pool->base.stream_enc[i] != NULL)
-+ dm_free(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
-+ }
-+
-+ for (i = 0; i < pool->base.clk_src_count; i++) {
-+ if (pool->base.clock_sources[i] != NULL)
-+ dce120_clock_source_destroy(
-+ &pool->base.clock_sources[i]);
-+ }
-+
-+ if (pool->base.dp_clock_source != NULL)
-+ dce120_clock_source_destroy(&pool->base.dp_clock_source);
-+
-+ if (pool->base.abm != NULL)
-+ dce_abm_destroy(&pool->base.abm);
-+
-+ if (pool->base.dmcu != NULL)
-+ dce_dmcu_destroy(&pool->base.dmcu);
-+
-+ if (pool->base.display_clock != NULL)
-+ dce_disp_clk_destroy(&pool->base.display_clock);
-+}
-+
-+static void read_dce_straps(
-+ struct dc_context *ctx,
-+ struct resource_straps *straps)
-+{
-+ /* TODO: Registers are missing */
-+ /*REG_GET_2(CC_DC_HDMI_STRAPS,
-+ HDMI_DISABLE, &straps->hdmi_disable,
-+ AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
-+
-+ REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);*/
-+}
-+
-+static struct audio *create_audio(
-+ struct dc_context *ctx, unsigned int inst)
-+{
-+ return dce_audio_create(ctx, inst,
-+ &audio_regs[inst], &audio_shift, &audio_mask);
-+}
-+
-+static const struct encoder_feature_support link_enc_feature = {
-+ .max_hdmi_deep_color = COLOR_DEPTH_121212,
-+ .max_hdmi_pixel_clock = 600000,
-+ .ycbcr420_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,
-+ .flags.bits.IS_YCBCR_CAPABLE = true
-+};
-+
-+struct link_encoder *dce120_link_encoder_create(
-+ const struct encoder_init_data *enc_init_data)
-+{
-+ struct dce110_link_encoder *enc110 =
-+ dm_alloc(sizeof(struct dce110_link_encoder));
-+
-+ if (!enc110)
-+ return NULL;
-+
-+ if (dce110_link_encoder_construct(
-+ enc110,
-+ 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])) {
-+
-+ return &enc110->base;
-+ }
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(enc110);
-+ return NULL;
-+}
-+
-+static struct input_pixel_processor *dce120_ipp_create(
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_ipp_reg_offsets *offset)
-+{
-+ struct dce110_ipp *ipp = dm_alloc(sizeof(struct dce110_ipp));
-+
-+ if (!ipp)
-+ return NULL;
-+
-+ if (dce120_ipp_construct(ipp, ctx, inst, offset))
-+ return &ipp->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(ipp);
-+ return NULL;
-+}
-+
-+static struct stream_encoder *dce120_stream_encoder_create(
-+ enum engine_id eng_id,
-+ struct dc_context *ctx)
-+{
-+ struct dce110_stream_encoder *enc110 =
-+ dm_alloc(sizeof(struct dce110_stream_encoder));
-+
-+ if (!enc110)
-+ return NULL;
-+
-+ if (dce110_stream_encoder_construct(
-+ enc110, ctx, ctx->dc_bios, eng_id,
-+ &stream_enc_regs[eng_id], &se_shift, &se_mask))
-+ return &enc110->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(enc110);
-+ return NULL;
-+}
-+
-+#define SRII(reg_name, block, id)\
-+ .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
-+ mm ## block ## id ## _ ## reg_name
-+
-+static const struct dce_hwseq_registers hwseq_reg = {
-+ HWSEQ_DCE112_REG_LIST()
-+};
-+
-+static const struct dce_hwseq_shift hwseq_shift = {
-+ HWSEQ_DCE12_MASK_SH_LIST(__SHIFT)
-+};
-+
-+static const struct dce_hwseq_mask hwseq_mask = {
-+ HWSEQ_DCE12_MASK_SH_LIST(_MASK)
-+};
-+
-+static struct dce_hwseq *dce120_hwseq_create(
-+ struct dc_context *ctx)
-+{
-+ struct dce_hwseq *hws = dm_alloc(sizeof(struct dce_hwseq));
-+
-+ 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 = create_audio,
-+ .create_stream_encoder = dce120_stream_encoder_create,
-+ .create_hwseq = dce120_hwseq_create,
-+};
-+
-+#define mi_inst_regs(id) { MI_DCE12_REG_LIST(id) }
-+static const struct dce_mem_input_registers mi_regs[] = {
-+ mi_inst_regs(0),
-+ mi_inst_regs(1),
-+ mi_inst_regs(2),
-+ mi_inst_regs(3),
-+ mi_inst_regs(4),
-+ mi_inst_regs(5),
-+};
-+
-+static const struct dce_mem_input_shift mi_shifts = {
-+ MI_DCE12_MASK_SH_LIST(__SHIFT)
-+};
-+
-+static const struct dce_mem_input_mask mi_masks = {
-+ MI_DCE12_MASK_SH_LIST(_MASK)
-+};
-+
-+static struct mem_input *dce120_mem_input_create(
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_mem_input_reg_offsets *offset)
-+{
-+ struct dce110_mem_input *mem_input110 =
-+ dm_alloc(sizeof(struct dce110_mem_input));
-+
-+ if (!mem_input110)
-+ return NULL;
-+
-+ if (dce120_mem_input_construct(mem_input110, ctx, inst, offset)) {
-+ struct mem_input *mi = &mem_input110->base;
-+
-+ mi->regs = &mi_regs[inst];
-+ mi->shifts = &mi_shifts;
-+ mi->masks = &mi_masks;
-+ return mi;
-+ }
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(mem_input110);
-+ return NULL;
-+}
-+
-+static struct transform *dce120_transform_create(
-+ struct dc_context *ctx,
-+ uint32_t inst)
-+{
-+ struct dce_transform *transform =
-+ dm_alloc(sizeof(struct dce_transform));
-+
-+ if (!transform)
-+ return NULL;
-+
-+ if (dce_transform_construct(transform, ctx, inst,
-+ &xfm_regs[inst], &xfm_shift, &xfm_mask)) {
-+ transform->lb_memory_size = 0x1404; /*5124*/
-+ return &transform->base;
-+ }
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(transform);
-+ return NULL;
-+}
-+
-+static void dce120_destroy_resource_pool(struct resource_pool **pool)
-+{
-+ struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
-+
-+ destruct(dce110_pool);
-+ dm_free(dce110_pool);
-+ *pool = NULL;
-+}
-+
-+static const struct resource_funcs dce120_res_pool_funcs = {
-+ .destroy = dce120_destroy_resource_pool,
-+ .link_enc_create = dce120_link_encoder_create,
-+ .validate_with_context = dce112_validate_with_context,
-+ .validate_guaranteed = dce112_validate_guaranteed,
-+ .validate_bandwidth = dce112_validate_bandwidth
-+};
-+
-+static void bw_calcs_data_update_from_pplib(struct core_dc *dc)
-+{
-+ struct dm_pp_clock_levels_with_latency eng_clks = {0};
-+ struct dm_pp_clock_levels_with_latency mem_clks = {0};
-+ struct dm_pp_wm_sets_with_clock_ranges clk_ranges = {0};
-+ int i;
-+ unsigned int clk;
-+ unsigned int latency;
-+
-+ /*do system clock*/
-+ if (!dm_pp_get_clock_levels_by_type_with_latency(
-+ dc->ctx,
-+ DM_PP_CLOCK_TYPE_ENGINE_CLK,
-+ &eng_clks) || eng_clks.num_levels == 0) {
-+
-+ eng_clks.num_levels = 8;
-+ clk = 300000;
-+
-+ for (i = 0; i < eng_clks.num_levels; i++) {
-+ eng_clks.data[i].clocks_in_khz = clk;
-+ clk += 100000;
-+ }
-+ }
-+
-+ /* convert all the clock fro kHz to fix point mHz TODO: wloop data */
-+ dc->bw_vbios.high_sclk = bw_frc_to_fixed(
-+ eng_clks.data[eng_clks.num_levels-1].clocks_in_khz, 1000);
-+ dc->bw_vbios.mid1_sclk = bw_frc_to_fixed(
-+ eng_clks.data[eng_clks.num_levels/8].clocks_in_khz, 1000);
-+ dc->bw_vbios.mid2_sclk = bw_frc_to_fixed(
-+ eng_clks.data[eng_clks.num_levels*2/8].clocks_in_khz, 1000);
-+ dc->bw_vbios.mid3_sclk = bw_frc_to_fixed(
-+ eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz, 1000);
-+ dc->bw_vbios.mid4_sclk = bw_frc_to_fixed(
-+ eng_clks.data[eng_clks.num_levels*4/8].clocks_in_khz, 1000);
-+ dc->bw_vbios.mid5_sclk = bw_frc_to_fixed(
-+ eng_clks.data[eng_clks.num_levels*5/8].clocks_in_khz, 1000);
-+ dc->bw_vbios.mid6_sclk = bw_frc_to_fixed(
-+ eng_clks.data[eng_clks.num_levels*6/8].clocks_in_khz, 1000);
-+ dc->bw_vbios.low_sclk = bw_frc_to_fixed(
-+ eng_clks.data[0].clocks_in_khz, 1000);
-+
-+ /*do memory clock*/
-+ if (!dm_pp_get_clock_levels_by_type_with_latency(
-+ dc->ctx,
-+ DM_PP_CLOCK_TYPE_MEMORY_CLK,
-+ &mem_clks) || mem_clks.num_levels == 0) {
-+
-+ mem_clks.num_levels = 3;
-+ clk = 250000;
-+ latency = 45;
-+
-+ for (i = 0; i < eng_clks.num_levels; i++) {
-+ mem_clks.data[i].clocks_in_khz = clk;
-+ mem_clks.data[i].latency_in_us = latency;
-+ clk += 500000;
-+ latency -= 5;
-+ }
-+
-+ }
-+
-+ /* we don't need to call PPLIB for validation clock since they
-+ * also give us the highest sclk and highest mclk (UMA clock).
-+ * ALSO always convert UMA clock (from PPLIB) to YCLK (HW formula):
-+ * YCLK = UMACLK*m_memoryTypeMultiplier
-+ */
-+ dc->bw_vbios.low_yclk = bw_frc_to_fixed(
-+ mem_clks.data[0].clocks_in_khz * MEMORY_TYPE_MULTIPLIER, 1000);
-+ dc->bw_vbios.mid_yclk = bw_frc_to_fixed(
-+ mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER,
-+ 1000);
-+ dc->bw_vbios.high_yclk = bw_frc_to_fixed(
-+ mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER,
-+ 1000);
-+
-+ /* Now notify PPLib/SMU about which Watermarks sets they should select
-+ * depending on DPM state they are in. And update BW MGR GFX Engine and
-+ * Memory clock member variables for Watermarks calculations for each
-+ * Watermark Set
-+ */
-+ clk_ranges.num_wm_sets = 4;
-+ clk_ranges.wm_clk_ranges[0].wm_set_id = WM_SET_A;
-+ clk_ranges.wm_clk_ranges[0].wm_min_eng_clk_in_khz =
-+ eng_clks.data[0].clocks_in_khz;
-+ clk_ranges.wm_clk_ranges[0].wm_max_eng_clk_in_khz =
-+ eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
-+ clk_ranges.wm_clk_ranges[0].wm_min_memg_clk_in_khz =
-+ mem_clks.data[0].clocks_in_khz;
-+ clk_ranges.wm_clk_ranges[0].wm_max_mem_clk_in_khz =
-+ mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
-+
-+ clk_ranges.wm_clk_ranges[1].wm_set_id = WM_SET_B;
-+ clk_ranges.wm_clk_ranges[1].wm_min_eng_clk_in_khz =
-+ eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
-+ /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
-+ clk_ranges.wm_clk_ranges[1].wm_max_eng_clk_in_khz = 5000000;
-+ clk_ranges.wm_clk_ranges[1].wm_min_memg_clk_in_khz =
-+ mem_clks.data[0].clocks_in_khz;
-+ clk_ranges.wm_clk_ranges[1].wm_max_mem_clk_in_khz =
-+ mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
-+
-+ clk_ranges.wm_clk_ranges[2].wm_set_id = WM_SET_C;
-+ clk_ranges.wm_clk_ranges[2].wm_min_eng_clk_in_khz =
-+ eng_clks.data[0].clocks_in_khz;
-+ clk_ranges.wm_clk_ranges[2].wm_max_eng_clk_in_khz =
-+ eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
-+ clk_ranges.wm_clk_ranges[2].wm_min_memg_clk_in_khz =
-+ mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
-+ /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
-+ clk_ranges.wm_clk_ranges[2].wm_max_mem_clk_in_khz = 5000000;
-+
-+ clk_ranges.wm_clk_ranges[3].wm_set_id = WM_SET_D;
-+ clk_ranges.wm_clk_ranges[3].wm_min_eng_clk_in_khz =
-+ eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
-+ /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
-+ clk_ranges.wm_clk_ranges[3].wm_max_eng_clk_in_khz = 5000000;
-+ clk_ranges.wm_clk_ranges[3].wm_min_memg_clk_in_khz =
-+ mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
-+ /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
-+ clk_ranges.wm_clk_ranges[3].wm_max_mem_clk_in_khz = 5000000;
-+
-+ /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
-+ dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges);
-+}
-+
-+static bool construct(
-+ uint8_t num_virtual_links,
-+ struct core_dc *dc,
-+ struct dce110_resource_pool *pool)
-+{
-+ unsigned int i;
-+ struct dc_context *ctx = dc->ctx;
-+
-+ ctx->dc_bios->regs = &bios_regs;
-+
-+ pool->base.res_cap = &res_cap;
-+ pool->base.funcs = &dce120_res_pool_funcs;
-+
-+ /* TODO: Fill more data from GreenlandAsicCapability.cpp */
-+ pool->base.pipe_count = 6;
-+ pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
-+
-+ dc->public.caps.max_downscale_ratio = 200;
-+ dc->public.caps.i2c_speed_in_khz = 100;
-+ dc->public.caps.max_cursor_size = 128;
-+ dc->public.debug = debug_defaults;
-+
-+ /*************************************************
-+ * Create resources *
-+ *************************************************/
-+
-+ pool->base.clock_sources[DCE120_CLK_SRC_PLL0] =
-+ dce120_clock_source_create(ctx, ctx->dc_bios,
-+ CLOCK_SOURCE_COMBO_PHY_PLL0,
-+ &clk_src_regs[0], false);
-+ pool->base.clock_sources[DCE120_CLK_SRC_PLL1] =
-+ dce120_clock_source_create(ctx, ctx->dc_bios,
-+ CLOCK_SOURCE_COMBO_PHY_PLL1,
-+ &clk_src_regs[1], false);
-+ pool->base.clock_sources[DCE120_CLK_SRC_PLL2] =
-+ dce120_clock_source_create(ctx, ctx->dc_bios,
-+ CLOCK_SOURCE_COMBO_PHY_PLL2,
-+ &clk_src_regs[2], false);
-+ pool->base.clock_sources[DCE120_CLK_SRC_PLL3] =
-+ dce120_clock_source_create(ctx, ctx->dc_bios,
-+ CLOCK_SOURCE_COMBO_PHY_PLL3,
-+ &clk_src_regs[3], false);
-+ pool->base.clock_sources[DCE120_CLK_SRC_PLL4] =
-+ dce120_clock_source_create(ctx, ctx->dc_bios,
-+ CLOCK_SOURCE_COMBO_PHY_PLL4,
-+ &clk_src_regs[4], false);
-+ pool->base.clock_sources[DCE120_CLK_SRC_PLL5] =
-+ dce120_clock_source_create(ctx, ctx->dc_bios,
-+ CLOCK_SOURCE_COMBO_PHY_PLL5,
-+ &clk_src_regs[5], false);
-+ pool->base.clk_src_count = DCE120_CLK_SRC_TOTAL;
-+
-+ pool->base.dp_clock_source =
-+ dce120_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");
-+ BREAK_TO_DEBUGGER();
-+ goto clk_src_create_fail;
-+ }
-+ }
-+
-+ pool->base.display_clock = dce120_disp_clk_create(ctx,
-+ &disp_clk_regs,
-+ &disp_clk_shift,
-+ &disp_clk_mask);
-+ if (pool->base.display_clock == NULL) {
-+ dm_error("DC: failed to create display clock!\n");
-+ BREAK_TO_DEBUGGER();
-+ goto disp_clk_create_fail;
-+ }
-+
-+ pool->base.dmcu = dce_dmcu_create(ctx,
-+ &dmcu_regs,
-+ &dmcu_shift,
-+ &dmcu_mask);
-+ if (pool->base.dmcu == NULL) {
-+ dm_error("DC: failed to create dmcu!\n");
-+ BREAK_TO_DEBUGGER();
-+ goto res_create_fail;
-+ }
-+
-+ pool->base.abm = dce_abm_create(ctx,
-+ &abm_regs,
-+ &abm_shift,
-+ &abm_mask);
-+ if (pool->base.abm == NULL) {
-+ dm_error("DC: failed to create abm!\n");
-+ BREAK_TO_DEBUGGER();
-+ goto res_create_fail;
-+ }
-+
-+ {
-+ #if defined(CONFIG_DRM_AMD_DC_DCE12_0)
-+ struct irq_service_init_data init_data;
-+ init_data.ctx = dc->ctx;
-+ pool->base.irqs = dal_irq_service_dce120_create(&init_data);
-+ if (!pool->base.irqs)
-+ goto irqs_create_fail;
-+ #endif
-+ }
-+
-+ for (i = 0; i < pool->base.pipe_count; i++) {
-+ pool->base.timing_generators[i] =
-+ dce120_timing_generator_create(
-+ ctx,
-+ i,
-+ &dce120_tg_offsets[i]);
-+ if (pool->base.timing_generators[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_error("DC: failed to create tg!\n");
-+ goto controller_create_fail;
-+ }
-+
-+ pool->base.mis[i] = dce120_mem_input_create(ctx,
-+ i, &dce120_mi_reg_offsets[i]);
-+
-+ if (pool->base.mis[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_error(
-+ "DC: failed to create memory input!\n");
-+ goto controller_create_fail;
-+ }
-+
-+ pool->base.ipps[i] = dce120_ipp_create(ctx, i,
-+ &dce120_ipp_reg_offsets[i]);
-+ if (pool->base.ipps[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_error(
-+ "DC: failed to create input pixel processor!\n");
-+ goto controller_create_fail;
-+ }
-+
-+ pool->base.transforms[i] = dce120_transform_create(ctx, i);
-+ if (pool->base.transforms[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_error(
-+ "DC: failed to create transform!\n");
-+ goto res_create_fail;
-+ }
-+
-+ pool->base.opps[i] = dce120_opp_create(
-+ ctx,
-+ i);
-+ if (pool->base.opps[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_error(
-+ "DC: failed to create output pixel processor!\n");
-+ }
-+ }
-+
-+ if (!resource_construct(num_virtual_links, dc, &pool->base,
-+ &res_create_funcs))
-+ goto res_create_fail;
-+
-+ /* Create hardware sequencer */
-+ if (!dce120_hw_sequencer_create(dc))
-+ goto controller_create_fail;
-+
-+ bw_calcs_init(&dc->bw_dceip, &dc->bw_vbios, dc->ctx->asic_id);
-+
-+ bw_calcs_data_update_from_pplib(dc);
-+
-+ return true;
-+
-+irqs_create_fail:
-+controller_create_fail:
-+disp_clk_create_fail:
-+clk_src_create_fail:
-+res_create_fail:
-+
-+ destruct(pool);
-+
-+ return false;
-+}
-+
-+struct resource_pool *dce120_create_resource_pool(
-+ uint8_t num_virtual_links,
-+ struct core_dc *dc)
-+{
-+ struct dce110_resource_pool *pool =
-+ dm_alloc(sizeof(struct dce110_resource_pool));
-+
-+ if (!pool)
-+ return NULL;
-+
-+ if (construct(num_virtual_links, dc, pool))
-+ return &pool->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.h b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.h
-new file mode 100644
-index 0000000..038c78d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.h
-@@ -0,0 +1,39 @@
-+/*
-+* 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_RESOURCE_DCE120_H__
-+#define __DC_RESOURCE_DCE120_H__
-+
-+#include "core_types.h"
-+
-+struct core_dc;
-+struct resource_pool;
-+
-+struct resource_pool *dce120_create_resource_pool(
-+ uint8_t num_virtual_links,
-+ struct core_dc *dc);
-+
-+#endif /* __DC_RESOURCE_DCE120_H__ */
-+
-diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
-new file mode 100644
-index 0000000..d7e787b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
-@@ -0,0 +1,1109 @@
-+/*
-+ * 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 "vega10/DC/dce_12_0_offset.h"
-+#include "vega10/DC/dce_12_0_sh_mask.h"
-+#include "vega10/soc15ip.h"
-+
-+#include "dc_types.h"
-+#include "dc_bios_types.h"
-+
-+#include "include/grph_object_id.h"
-+#include "include/logger_interface.h"
-+#include "dce120_timing_generator.h"
-+
-+#include "timing_generator.h"
-+
-+#define CRTC_REG_UPDATE_N(reg_name, n, ...) \
-+ generic_reg_update_soc15(tg110->base.ctx, tg110->offsets.crtc, reg_name, n, __VA_ARGS__)
-+
-+#define CRTC_REG_SET_N(reg_name, n, ...) \
-+ generic_reg_set_soc15(tg110->base.ctx, tg110->offsets.crtc, reg_name, n, __VA_ARGS__)
-+
-+#define CRTC_REG_UPDATE(reg, field, val) \
-+ CRTC_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)
-+
-+#define CRTC_REG_UPDATE_2(reg, field1, val1, field2, val2) \
-+ CRTC_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+#define CRTC_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3) \
-+ CRTC_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-+
-+#define CRTC_REG_UPDATE_4(reg, field1, val1, field2, val2, field3, val3, field4, val4) \
-+ CRTC_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3, FD(reg##__##field4), val4)
-+
-+#define CRTC_REG_UPDATE_5(reg, field1, val1, field2, val2, field3, val3, field4, val4, field5, val5) \
-+ CRTC_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3, FD(reg##__##field4), val4, FD(reg##__##field5), val5)
-+
-+#define CRTC_REG_SET(reg, field, val) \
-+ CRTC_REG_SET_N(reg, 1, FD(reg##__##field), val)
-+
-+#define CRTC_REG_SET_2(reg, field1, val1, field2, val2) \
-+ CRTC_REG_SET_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-+
-+#define CRTC_REG_SET_3(reg, field1, val1, field2, val2, field3, val3) \
-+ CRTC_REG_SET_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-+
-+/**
-+ *****************************************************************************
-+ * Function: is_in_vertical_blank
-+ *
-+ * @brief
-+ * check the current status of CRTC to check if we are in Vertical Blank
-+ * regioneased" state
-+ *
-+ * @return
-+ * true if currently in blank region, false otherwise
-+ *
-+ *****************************************************************************
-+ */
-+static bool dce120_timing_generator_is_in_vertical_blank(
-+ struct timing_generator *tg)
-+{
-+ uint32_t field = 0;
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+ uint32_t value = dm_read_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_STATUS,
-+ tg110->offsets.crtc);
-+
-+ field = get_reg_field_value(value, CRTC0_CRTC_STATUS, CRTC_V_BLANK);
-+ return field == 1;
-+}
-+
-+
-+/* determine if given timing can be supported by TG */
-+bool dce120_timing_generator_validate_timing(
-+ struct timing_generator *tg,
-+ const struct dc_crtc_timing *timing,
-+ enum signal_type signal)
-+{
-+ uint32_t interlace_factor = timing->flags.INTERLACE ? 2 : 1;
-+ uint32_t v_blank =
-+ (timing->v_total - timing->v_addressable -
-+ timing->v_border_top - timing->v_border_bottom) *
-+ interlace_factor;
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ if (!dce110_timing_generator_validate_timing(
-+ tg,
-+ timing,
-+ signal))
-+ return false;
-+
-+
-+ if (v_blank < tg110->min_v_blank ||
-+ timing->h_sync_width < tg110->min_h_sync_width ||
-+ timing->v_sync_width < tg110->min_v_sync_width)
-+ return false;
-+
-+ return true;
-+}
-+
-+bool dce120_tg_validate_timing(struct timing_generator *tg,
-+ const struct dc_crtc_timing *timing)
-+{
-+ return dce120_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE);
-+}
-+
-+/******** HW programming ************/
-+/* Disable/Enable Timing Generator */
-+bool dce120_timing_generator_enable_crtc(struct timing_generator *tg)
-+{
-+ enum bp_result result;
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ /* Set MASTER_UPDATE_MODE to 0
-+ * This is needed for DRR, and also suggested to be default value by Syed.*/
-+
-+ CRTC_REG_UPDATE(CRTC0_CRTC_MASTER_UPDATE_MODE,
-+ MASTER_UPDATE_MODE, 0);
-+
-+ CRTC_REG_UPDATE(CRTC0_CRTC_MASTER_UPDATE_LOCK,
-+ UNDERFLOW_UPDATE_LOCK, 0);
-+
-+ /* TODO API for AtomFirmware didn't change*/
-+ result = tg->bp->funcs->enable_crtc(tg->bp, tg110->controller_id, true);
-+
-+ return result == BP_RESULT_OK;
-+}
-+
-+void dce120_timing_generator_set_early_control(
-+ struct timing_generator *tg,
-+ uint32_t early_cntl)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ CRTC_REG_UPDATE(CRTC0_CRTC_CONTROL,
-+ CRTC_HBLANK_EARLY_CONTROL, early_cntl);
-+}
-+
-+/**************** TG current status ******************/
-+
-+/* return the current frame counter. Used by Linux kernel DRM */
-+uint32_t dce120_timing_generator_get_vblank_counter(
-+ struct timing_generator *tg)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+ uint32_t value = dm_read_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_STATUS_FRAME_COUNT,
-+ tg110->offsets.crtc);
-+ uint32_t field = get_reg_field_value(
-+ value, CRTC0_CRTC_STATUS_FRAME_COUNT, CRTC_FRAME_COUNT);
-+
-+ return field;
-+}
-+
-+/* Get current H and V position */
-+void dce120_timing_generator_get_crtc_positions(
-+ struct timing_generator *tg,
-+ int32_t *h_position,
-+ int32_t *v_position)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+ uint32_t value = dm_read_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_STATUS_POSITION,
-+ tg110->offsets.crtc);
-+
-+ *h_position = get_reg_field_value(
-+ value, CRTC0_CRTC_STATUS_POSITION, CRTC_HORZ_COUNT);
-+
-+ *v_position = get_reg_field_value(
-+ value, CRTC0_CRTC_STATUS_POSITION, CRTC_VERT_COUNT);
-+}
-+
-+/* wait until TG is in beginning of vertical blank region */
-+void dce120_timing_generator_wait_for_vblank(struct timing_generator *tg)
-+{
-+ /* We want to catch beginning of VBlank here, so if the first try are
-+ * in VBlank, we might be very close to Active, in this case wait for
-+ * another frame
-+ */
-+ while (dce120_timing_generator_is_in_vertical_blank(tg)) {
-+ if (!tg->funcs->is_counter_moving(tg)) {
-+ /* error - no point to wait if counter is not moving */
-+ break;
-+ }
-+ }
-+
-+ while (!dce120_timing_generator_is_in_vertical_blank(tg)) {
-+ if (!tg->funcs->is_counter_moving(tg)) {
-+ /* error - no point to wait if counter is not moving */
-+ break;
-+ }
-+ }
-+}
-+
-+/* wait until TG is in beginning of active region */
-+void dce120_timing_generator_wait_for_vactive(struct timing_generator *tg)
-+{
-+ while (dce120_timing_generator_is_in_vertical_blank(tg)) {
-+ if (!tg->funcs->is_counter_moving(tg)) {
-+ /* error - no point to wait if counter is not moving */
-+ break;
-+ }
-+ }
-+}
-+
-+/*********** Timing Generator Synchronization routines ****/
-+
-+/* Setups Global Swap Lock group, TimingServer or TimingClient*/
-+void dce120_timing_generator_setup_global_swap_lock(
-+ struct timing_generator *tg,
-+ const struct dcp_gsl_params *gsl_params)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+ uint32_t value_crtc_vtotal =
-+ dm_read_reg_soc15(tg->ctx,
-+ mmCRTC0_CRTC_V_TOTAL,
-+ tg110->offsets.crtc);
-+ /* Checkpoint relative to end of frame */
-+ uint32_t check_point =
-+ get_reg_field_value(value_crtc_vtotal,
-+ CRTC0_CRTC_V_TOTAL,
-+ CRTC_V_TOTAL);
-+
-+
-+ dm_write_reg_soc15(tg->ctx, mmCRTC0_CRTC_GSL_WINDOW, tg110->offsets.crtc, 0);
-+
-+ CRTC_REG_UPDATE_N(DCP0_DCP_GSL_CONTROL, 6,
-+ /* This pipe will belong to GSL Group zero. */
-+ FD(DCP0_DCP_GSL_CONTROL__DCP_GSL0_EN), 1,
-+ FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_MASTER_EN), gsl_params->gsl_master == tg->inst,
-+ FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_FORCE_DELAY), HFLIP_READY_DELAY,
-+ /* Keep signal low (pending high) during 6 lines.
-+ * Also defines minimum interval before re-checking signal. */
-+ FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_CHECK_DELAY), HFLIP_CHECK_DELAY,
-+ /* DCP_GSL_PURPOSE_SURFACE_FLIP */
-+ FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_SYNC_SOURCE), 0,
-+ FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_DELAY_SURFACE_UPDATE_PENDING), 1);
-+
-+ CRTC_REG_SET_2(
-+ CRTC0_CRTC_GSL_CONTROL,
-+ CRTC_GSL_CHECK_LINE_NUM, check_point - FLIP_READY_BACK_LOOKUP,
-+ CRTC_GSL_FORCE_DELAY, VFLIP_READY_DELAY);
-+}
-+
-+/* Clear all the register writes done by setup_global_swap_lock */
-+void dce120_timing_generator_tear_down_global_swap_lock(
-+ struct timing_generator *tg)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ /* Settig HW default values from reg specs */
-+ CRTC_REG_SET_N(DCP0_DCP_GSL_CONTROL, 6,
-+ FD(DCP0_DCP_GSL_CONTROL__DCP_GSL0_EN), 0,
-+ FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_MASTER_EN), 0,
-+ FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_FORCE_DELAY), HFLIP_READY_DELAY,
-+ FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_CHECK_DELAY), HFLIP_CHECK_DELAY,
-+ /* DCP_GSL_PURPOSE_SURFACE_FLIP */
-+ FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_SYNC_SOURCE), 0,
-+ FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_DELAY_SURFACE_UPDATE_PENDING), 0);
-+
-+ CRTC_REG_SET_2(
-+ CRTC0_CRTC_GSL_CONTROL,
-+ CRTC_GSL_CHECK_LINE_NUM, 0,
-+ CRTC_GSL_FORCE_DELAY, 0x2); /*TODO Why this value here ?*/
-+}
-+
-+/* Reset slave controllers on master VSync */
-+void dce120_timing_generator_enable_reset_trigger(
-+ struct timing_generator *tg,
-+ int source)
-+{
-+ enum trigger_source_select trig_src_select = TRIGGER_SOURCE_SELECT_LOGIC_ZERO;
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+ uint32_t rising_edge = 0;
-+ uint32_t falling_edge = 0;
-+ /* Setup trigger edge */
-+ uint32_t pol_value = dm_read_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_V_SYNC_A_CNTL,
-+ tg110->offsets.crtc);
-+
-+ /* Register spec has reversed definition:
-+ * 0 for positive, 1 for negative */
-+ if (get_reg_field_value(pol_value,
-+ CRTC0_CRTC_V_SYNC_A_CNTL,
-+ CRTC_V_SYNC_A_POL) == 0) {
-+ rising_edge = 1;
-+ } else {
-+ falling_edge = 1;
-+ }
-+
-+ /* TODO What about other sources ?*/
-+ trig_src_select = TRIGGER_SOURCE_SELECT_GSL_GROUP0;
-+
-+ CRTC_REG_UPDATE_N(CRTC0_CRTC_TRIGB_CNTL, 7,
-+ FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_SOURCE_SELECT), trig_src_select,
-+ FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_POLARITY_SELECT), TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
-+ FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_RISING_EDGE_DETECT_CNTL), rising_edge,
-+ FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_FALLING_EDGE_DETECT_CNTL), falling_edge,
-+ /* send every signal */
-+ FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_FREQUENCY_SELECT), 0,
-+ /* no delay */
-+ FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_DELAY), 0,
-+ /* clear trigger status */
-+ FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_CLEAR), 1);
-+
-+ CRTC_REG_UPDATE_3(
-+ CRTC0_CRTC_FORCE_COUNT_NOW_CNTL,
-+ CRTC_FORCE_COUNT_NOW_MODE, 2,
-+ CRTC_FORCE_COUNT_NOW_TRIG_SEL, 1,
-+ CRTC_FORCE_COUNT_NOW_CLEAR, 1);
-+}
-+
-+/* disabling trigger-reset */
-+void dce120_timing_generator_disable_reset_trigger(
-+ struct timing_generator *tg)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ CRTC_REG_UPDATE_2(
-+ CRTC0_CRTC_FORCE_COUNT_NOW_CNTL,
-+ CRTC_FORCE_COUNT_NOW_MODE, 0,
-+ CRTC_FORCE_COUNT_NOW_CLEAR, 1);
-+
-+ CRTC_REG_UPDATE_3(
-+ CRTC0_CRTC_TRIGB_CNTL,
-+ CRTC_TRIGB_SOURCE_SELECT, TRIGGER_SOURCE_SELECT_LOGIC_ZERO,
-+ CRTC_TRIGB_POLARITY_SELECT, TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
-+ /* clear trigger status */
-+ CRTC_TRIGB_CLEAR, 1);
-+
-+}
-+
-+/* Checks whether CRTC triggered reset occurred */
-+bool dce120_timing_generator_did_triggered_reset_occur(
-+ struct timing_generator *tg)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+ uint32_t value = dm_read_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_FORCE_COUNT_NOW_CNTL,
-+ tg110->offsets.crtc);
-+
-+ return get_reg_field_value(value,
-+ CRTC0_CRTC_FORCE_COUNT_NOW_CNTL,
-+ CRTC_FORCE_COUNT_NOW_OCCURRED) != 0;
-+}
-+
-+
-+/******** Stuff to move to other virtual HW objects *****************/
-+/* Move to enable accelerated mode */
-+void dce120_timing_generator_disable_vga(struct timing_generator *tg)
-+{
-+ uint32_t addr = 0;
-+ uint32_t offset = 0;
-+ uint32_t value = 0;
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ switch (tg110->controller_id) {
-+ case CONTROLLER_ID_D0:
-+ addr = mmD1VGA_CONTROL;
-+ offset = 0;
-+ break;
-+ case CONTROLLER_ID_D1:
-+ addr = mmD2VGA_CONTROL;
-+ offset = mmD2VGA_CONTROL - mmD1VGA_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D2:
-+ addr = mmD3VGA_CONTROL;
-+ offset = mmD3VGA_CONTROL - mmD1VGA_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D3:
-+ addr = mmD4VGA_CONTROL;
-+ offset = mmD4VGA_CONTROL - mmD1VGA_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D4:
-+ addr = mmD1VGA_CONTROL;
-+ offset = mmD1VGA_CONTROL - mmD1VGA_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D5:
-+ addr = mmD6VGA_CONTROL;
-+ offset = mmD6VGA_CONTROL - mmD1VGA_CONTROL;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ value = dm_read_reg_soc15(tg->ctx, mmD1VGA_CONTROL, offset);
-+
-+ set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_MODE_ENABLE);
-+ set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_TIMING_SELECT);
-+ set_reg_field_value(
-+ value, 0, D1VGA_CONTROL, D1VGA_SYNC_POLARITY_SELECT);
-+ set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_OVERSCAN_COLOR_EN);
-+
-+ dm_write_reg_soc15(tg->ctx, mmD1VGA_CONTROL, offset, value);
-+}
-+/* TODO: Should we move it to transform */
-+/* Fully program CRTC timing in timing generator */
-+void dce120_timing_generator_program_blanking(
-+ struct timing_generator *tg,
-+ const struct dc_crtc_timing *timing)
-+{
-+ uint32_t tmp1 = 0;
-+ uint32_t tmp2 = 0;
-+ uint32_t vsync_offset = timing->v_border_bottom +
-+ timing->v_front_porch;
-+ uint32_t v_sync_start = timing->v_addressable + vsync_offset;
-+
-+ uint32_t hsync_offset = timing->h_border_right +
-+ timing->h_front_porch;
-+ uint32_t h_sync_start = timing->h_addressable + hsync_offset;
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ CRTC_REG_UPDATE(
-+ CRTC0_CRTC_H_TOTAL,
-+ CRTC_H_TOTAL,
-+ timing->h_total - 1);
-+
-+ CRTC_REG_UPDATE(
-+ CRTC0_CRTC_V_TOTAL,
-+ CRTC_V_TOTAL,
-+ timing->v_total - 1);
-+
-+ tmp1 = timing->h_total -
-+ (h_sync_start + timing->h_border_left);
-+ tmp2 = tmp1 + timing->h_addressable +
-+ timing->h_border_left + timing->h_border_right;
-+
-+ CRTC_REG_UPDATE_2(
-+ CRTC0_CRTC_H_BLANK_START_END,
-+ CRTC_H_BLANK_END, tmp1,
-+ CRTC_H_BLANK_START, tmp2);
-+
-+ tmp1 = timing->v_total - (v_sync_start + timing->v_border_top);
-+ tmp2 = tmp1 + timing->v_addressable + timing->v_border_top +
-+ timing->v_border_bottom;
-+
-+ CRTC_REG_UPDATE_2(
-+ CRTC0_CRTC_V_BLANK_START_END,
-+ CRTC_V_BLANK_END, tmp1,
-+ CRTC_V_BLANK_START, tmp2);
-+}
-+
-+/* TODO: Should we move it to opp? */
-+/* Combine with below and move YUV/RGB color conversion to SW layer */
-+void dce120_timing_generator_program_blank_color(
-+ struct timing_generator *tg,
-+ const struct tg_color *black_color)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ CRTC_REG_UPDATE_3(
-+ CRTC0_CRTC_BLACK_COLOR,
-+ CRTC_BLACK_COLOR_B_CB, black_color->color_b_cb,
-+ CRTC_BLACK_COLOR_G_Y, black_color->color_g_y,
-+ CRTC_BLACK_COLOR_R_CR, black_color->color_r_cr);
-+}
-+/* Combine with above and move YUV/RGB color conversion to SW layer */
-+void dce120_timing_generator_set_overscan_color_black(
-+ struct timing_generator *tg,
-+ const struct tg_color *color)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+ uint32_t value = 0;
-+ CRTC_REG_SET_3(
-+ CRTC0_CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_BLUE, color->color_b_cb,
-+ CRTC_OVERSCAN_COLOR_GREEN, color->color_g_y,
-+ CRTC_OVERSCAN_COLOR_RED, color->color_r_cr);
-+
-+ value = dm_read_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_OVERSCAN_COLOR,
-+ tg110->offsets.crtc);
-+
-+ dm_write_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_BLACK_COLOR,
-+ tg110->offsets.crtc,
-+ value);
-+
-+ /* This is desirable to have a constant DAC output voltage during the
-+ * blank time that is higher than the 0 volt reference level that the
-+ * DAC outputs when the NBLANK signal
-+ * is asserted low, such as for output to an analog TV. */
-+ dm_write_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_BLANK_DATA_COLOR,
-+ tg110->offsets.crtc,
-+ value);
-+
-+ /* TO DO we have to program EXT registers and we need to know LB DATA
-+ * format because it is used when more 10 , i.e. 12 bits per color
-+ *
-+ * m_mmDxCRTC_OVERSCAN_COLOR_EXT
-+ * m_mmDxCRTC_BLACK_COLOR_EXT
-+ * m_mmDxCRTC_BLANK_DATA_COLOR_EXT
-+ */
-+}
-+
-+void dce120_timing_generator_set_drr(
-+ struct timing_generator *tg,
-+ const struct drr_params *params)
-+{
-+
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ if (params != NULL &&
-+ params->vertical_total_max > 0 &&
-+ params->vertical_total_min > 0) {
-+
-+ CRTC_REG_UPDATE(
-+ CRTC0_CRTC_V_TOTAL_MIN,
-+ CRTC_V_TOTAL_MIN, params->vertical_total_min - 1);
-+ CRTC_REG_UPDATE(
-+ CRTC0_CRTC_V_TOTAL_MAX,
-+ CRTC_V_TOTAL_MAX, params->vertical_total_max - 1);
-+ CRTC_REG_SET_N(CRTC0_CRTC_V_TOTAL_CONTROL, 6,
-+ FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MIN_SEL), 1,
-+ FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MAX_SEL), 1,
-+ FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_ON_EVENT), 0,
-+ FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_TO_MASTER_VSYNC), 0,
-+ FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK_EN), 0,
-+ FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK), 0);
-+ CRTC_REG_UPDATE(
-+ CRTC0_CRTC_STATIC_SCREEN_CONTROL,
-+ CRTC_STATIC_SCREEN_EVENT_MASK,
-+ 0x180);
-+
-+ } else {
-+ CRTC_REG_UPDATE(
-+ CRTC0_CRTC_V_TOTAL_MIN,
-+ CRTC_V_TOTAL_MIN, 0);
-+ CRTC_REG_UPDATE(
-+ CRTC0_CRTC_V_TOTAL_MAX,
-+ CRTC_V_TOTAL_MAX, 0);
-+ CRTC_REG_SET_N(CRTC0_CRTC_V_TOTAL_CONTROL, 5,
-+ FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MIN_SEL), 0,
-+ FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MAX_SEL), 0,
-+ FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_ON_EVENT), 0,
-+ FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_TO_MASTER_VSYNC), 0,
-+ FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK), 0);
-+ CRTC_REG_UPDATE(
-+ CRTC0_CRTC_STATIC_SCREEN_CONTROL,
-+ CRTC_STATIC_SCREEN_EVENT_MASK,
-+ 0);
-+ }
-+}
-+
-+uint32_t dce120_timing_generator_get_crtc_scanoutpos(
-+ struct timing_generator *tg,
-+ uint32_t *vbl,
-+ uint32_t *position)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ *vbl = dm_read_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_V_BLANK_START_END,
-+ tg110->offsets.crtc);
-+
-+ *position = dm_read_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_STATUS_POSITION,
-+ tg110->offsets.crtc);
-+
-+ return 0;
-+}
-+
-+void dce120_timing_generator_enable_advanced_request(
-+ struct timing_generator *tg,
-+ bool enable,
-+ const struct dc_crtc_timing *timing)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+ uint32_t v_sync_width_and_b_porch =
-+ timing->v_total - timing->v_addressable -
-+ timing->v_border_bottom - timing->v_front_porch;
-+ uint32_t value = dm_read_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_START_LINE_CONTROL,
-+ tg110->offsets.crtc);
-+
-+
-+ if (enable) {
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ CRTC0_CRTC_START_LINE_CONTROL,
-+ CRTC_LEGACY_REQUESTOR_EN);
-+ } else {
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ CRTC0_CRTC_START_LINE_CONTROL,
-+ CRTC_LEGACY_REQUESTOR_EN);
-+ }
-+
-+ /* Program advanced line position acc.to the best case from fetching data perspective to hide MC latency
-+ * and prefilling Line Buffer in V Blank (to 10 lines as LB can store max 10 lines)
-+ */
-+ if (v_sync_width_and_b_porch > 10)
-+ set_reg_field_value(
-+ value,
-+ 10,
-+ CRTC0_CRTC_START_LINE_CONTROL,
-+ CRTC_ADVANCED_START_LINE_POSITION);
-+ else
-+ set_reg_field_value(
-+ value,
-+ v_sync_width_and_b_porch,
-+ CRTC0_CRTC_START_LINE_CONTROL,
-+ CRTC_ADVANCED_START_LINE_POSITION);
-+
-+ dm_write_reg_soc15(tg->ctx,
-+ mmCRTC0_CRTC_START_LINE_CONTROL,
-+ tg110->offsets.crtc,
-+ value);
-+}
-+
-+void dce120_tg_program_blank_color(struct timing_generator *tg,
-+ const struct tg_color *black_color)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+ uint32_t value = 0;
-+
-+ CRTC_REG_UPDATE_3(
-+ CRTC0_CRTC_BLACK_COLOR,
-+ CRTC_BLACK_COLOR_B_CB, black_color->color_b_cb,
-+ CRTC_BLACK_COLOR_G_Y, black_color->color_g_y,
-+ CRTC_BLACK_COLOR_R_CR, black_color->color_r_cr);
-+
-+ value = dm_read_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_BLACK_COLOR,
-+ tg110->offsets.crtc);
-+ dm_write_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_BLANK_DATA_COLOR,
-+ tg110->offsets.crtc,
-+ value);
-+}
-+
-+void dce120_tg_set_overscan_color(struct timing_generator *tg,
-+ const struct tg_color *overscan_color)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ CRTC_REG_SET_3(
-+ CRTC0_CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_BLUE, overscan_color->color_b_cb,
-+ CRTC_OVERSCAN_COLOR_GREEN, overscan_color->color_g_y,
-+ CRTC_OVERSCAN_COLOR_RED, overscan_color->color_r_cr);
-+}
-+
-+void dce120_tg_program_timing(struct timing_generator *tg,
-+ const struct dc_crtc_timing *timing,
-+ bool use_vbios)
-+{
-+ if (use_vbios)
-+ dce110_timing_generator_program_timing_generator(tg, timing);
-+ else
-+ dce120_timing_generator_program_blanking(tg, timing);
-+}
-+
-+bool dce120_tg_is_blanked(struct timing_generator *tg)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+ uint32_t value = dm_read_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_BLANK_CONTROL,
-+ tg110->offsets.crtc);
-+
-+ if (
-+ get_reg_field_value(
-+ value,
-+ CRTC0_CRTC_BLANK_CONTROL,
-+ CRTC_BLANK_DATA_EN) == 1 &&
-+ get_reg_field_value(
-+ value,
-+ CRTC0_CRTC_BLANK_CONTROL,
-+ CRTC_CURRENT_BLANK_STATE) == 1)
-+ return true;
-+
-+ return false;
-+}
-+
-+void dce120_tg_set_blank(struct timing_generator *tg,
-+ bool enable_blanking)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ CRTC_REG_SET(
-+ CRTC0_CRTC_DOUBLE_BUFFER_CONTROL,
-+ CRTC_BLANK_DATA_DOUBLE_BUFFER_EN, 0);
-+
-+ if (enable_blanking) {
-+ CRTC_REG_SET(
-+ CRTC0_CRTC_BLANK_CONTROL,
-+ CRTC_BLANK_DATA_EN, 1);
-+
-+ } else
-+ dm_write_reg_soc15(
-+ tg->ctx,
-+ mmCRTC0_CRTC_BLANK_CONTROL,
-+ tg110->offsets.crtc,
-+ 0);
-+}
-+
-+bool dce120_tg_validate_timing(struct timing_generator *tg,
-+ const struct dc_crtc_timing *timing);
-+
-+void dce120_tg_wait_for_state(struct timing_generator *tg,
-+ enum crtc_state state)
-+{
-+ switch (state) {
-+ case CRTC_STATE_VBLANK:
-+ dce120_timing_generator_wait_for_vblank(tg);
-+ break;
-+
-+ case CRTC_STATE_VACTIVE:
-+ dce120_timing_generator_wait_for_vactive(tg);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+}
-+
-+void dce120_tg_set_colors(struct timing_generator *tg,
-+ const struct tg_color *blank_color,
-+ const struct tg_color *overscan_color)
-+{
-+ if (blank_color != NULL)
-+ dce120_tg_program_blank_color(tg, blank_color);
-+
-+ if (overscan_color != NULL)
-+ dce120_tg_set_overscan_color(tg, overscan_color);
-+}
-+
-+static void dce120_timing_generator_set_static_screen_control(
-+ struct timing_generator *tg,
-+ uint32_t value)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+
-+ CRTC_REG_UPDATE_2(CRTC0_CRTC_STATIC_SCREEN_CONTROL,
-+ CRTC_STATIC_SCREEN_EVENT_MASK, value,
-+ CRTC_STATIC_SCREEN_FRAME_COUNT, 2);
-+}
-+
-+void dce120_timing_generator_set_test_pattern(
-+ struct timing_generator *tg,
-+ /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
-+ * because this is not DP-specific (which is probably somewhere in DP
-+ * encoder) */
-+ enum controller_dp_test_pattern test_pattern,
-+ enum dc_color_depth color_depth)
-+{
-+ struct dc_context *ctx = tg->ctx;
-+ uint32_t value;
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+ enum test_pattern_color_format bit_depth;
-+ enum test_pattern_dyn_range dyn_range;
-+ enum test_pattern_mode mode;
-+ /* color ramp generator mixes 16-bits color */
-+ uint32_t src_bpc = 16;
-+ /* requested bpc */
-+ uint32_t dst_bpc;
-+ uint32_t index;
-+ /* RGB values of the color bars.
-+ * Produce two RGB colors: RGB0 - white (all Fs)
-+ * and RGB1 - black (all 0s)
-+ * (three RGB components for two colors)
-+ */
-+ uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
-+ 0x0000, 0x0000};
-+ /* dest color (converted to the specified color format) */
-+ uint16_t dst_color[6];
-+ uint32_t inc_base;
-+
-+ /* translate to bit depth */
-+ switch (color_depth) {
-+ case COLOR_DEPTH_666:
-+ bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
-+ break;
-+ case COLOR_DEPTH_888:
-+ bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
-+ break;
-+ case COLOR_DEPTH_101010:
-+ bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
-+ break;
-+ case COLOR_DEPTH_121212:
-+ bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
-+ break;
-+ default:
-+ bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
-+ break;
-+ }
-+
-+ switch (test_pattern) {
-+ case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
-+ case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
-+ {
-+ dyn_range = (test_pattern ==
-+ CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
-+ TEST_PATTERN_DYN_RANGE_CEA :
-+ TEST_PATTERN_DYN_RANGE_VESA);
-+ mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
-+
-+ CRTC_REG_UPDATE_2(CRTC0_CRTC_TEST_PATTERN_PARAMETERS,
-+ CRTC_TEST_PATTERN_VRES, 6,
-+ CRTC_TEST_PATTERN_HRES, 6);
-+
-+ CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL,
-+ CRTC_TEST_PATTERN_EN, 1,
-+ CRTC_TEST_PATTERN_MODE, mode,
-+ CRTC_TEST_PATTERN_DYNAMIC_RANGE, dyn_range,
-+ CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth);
-+ }
-+ break;
-+
-+ case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
-+ case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
-+ {
-+ mode = (test_pattern ==
-+ CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
-+ TEST_PATTERN_MODE_VERTICALBARS :
-+ TEST_PATTERN_MODE_HORIZONTALBARS);
-+
-+ switch (bit_depth) {
-+ case TEST_PATTERN_COLOR_FORMAT_BPC_6:
-+ dst_bpc = 6;
-+ break;
-+ case TEST_PATTERN_COLOR_FORMAT_BPC_8:
-+ dst_bpc = 8;
-+ break;
-+ case TEST_PATTERN_COLOR_FORMAT_BPC_10:
-+ dst_bpc = 10;
-+ break;
-+ default:
-+ dst_bpc = 8;
-+ break;
-+ }
-+
-+ /* adjust color to the required colorFormat */
-+ for (index = 0; index < 6; index++) {
-+ /* dst = 2^dstBpc * src / 2^srcBpc = src >>
-+ * (srcBpc - dstBpc);
-+ */
-+ dst_color[index] =
-+ src_color[index] >> (src_bpc - dst_bpc);
-+ /* CRTC_TEST_PATTERN_DATA has 16 bits,
-+ * lowest 6 are hardwired to ZERO
-+ * color bits should be left aligned aligned to MSB
-+ * XXXXXXXXXX000000 for 10 bit,
-+ * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6
-+ */
-+ dst_color[index] <<= (16 - dst_bpc);
-+ }
-+
-+ dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_PARAMETERS, tg110->offsets.crtc, 0);
-+
-+ /* We have to write the mask before data, similar to pipeline.
-+ * For example, for 8 bpc, if we want RGB0 to be magenta,
-+ * and RGB1 to be cyan,
-+ * we need to make 7 writes:
-+ * MASK DATA
-+ * 000001 00000000 00000000 set mask to R0
-+ * 000010 11111111 00000000 R0 255, 0xFF00, set mask to G0
-+ * 000100 00000000 00000000 G0 0, 0x0000, set mask to B0
-+ * 001000 11111111 00000000 B0 255, 0xFF00, set mask to R1
-+ * 010000 00000000 00000000 R1 0, 0x0000, set mask to G1
-+ * 100000 11111111 00000000 G1 255, 0xFF00, set mask to B1
-+ * 100000 11111111 00000000 B1 255, 0xFF00
-+ *
-+ * we will make a loop of 6 in which we prepare the mask,
-+ * then write, then prepare the color for next write.
-+ * first iteration will write mask only,
-+ * but each next iteration color prepared in
-+ * previous iteration will be written within new mask,
-+ * the last component will written separately,
-+ * mask is not changing between 6th and 7th write
-+ * and color will be prepared by last iteration
-+ */
-+
-+ /* write color, color values mask in CRTC_TEST_PATTERN_MASK
-+ * is B1, G1, R1, B0, G0, R0
-+ */
-+ value = 0;
-+ for (index = 0; index < 6; index++) {
-+ /* prepare color mask, first write PATTERN_DATA
-+ * will have all zeros
-+ */
-+ set_reg_field_value(
-+ value,
-+ (1 << index),
-+ CRTC0_CRTC_TEST_PATTERN_COLOR,
-+ CRTC_TEST_PATTERN_MASK);
-+ /* write color component */
-+ dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value);
-+ /* prepare next color component,
-+ * will be written in the next iteration
-+ */
-+ set_reg_field_value(
-+ value,
-+ dst_color[index],
-+ CRTC0_CRTC_TEST_PATTERN_COLOR,
-+ CRTC_TEST_PATTERN_DATA);
-+ }
-+ /* write last color component,
-+ * it's been already prepared in the loop
-+ */
-+ dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value);
-+
-+ /* enable test pattern */
-+ CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL,
-+ CRTC_TEST_PATTERN_EN, 1,
-+ CRTC_TEST_PATTERN_MODE, mode,
-+ CRTC_TEST_PATTERN_DYNAMIC_RANGE, 0,
-+ CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth);
-+ }
-+ break;
-+
-+ case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
-+ {
-+ mode = (bit_depth ==
-+ TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
-+ TEST_PATTERN_MODE_DUALRAMP_RGB :
-+ TEST_PATTERN_MODE_SINGLERAMP_RGB);
-+
-+ switch (bit_depth) {
-+ case TEST_PATTERN_COLOR_FORMAT_BPC_6:
-+ dst_bpc = 6;
-+ break;
-+ case TEST_PATTERN_COLOR_FORMAT_BPC_8:
-+ dst_bpc = 8;
-+ break;
-+ case TEST_PATTERN_COLOR_FORMAT_BPC_10:
-+ dst_bpc = 10;
-+ break;
-+ default:
-+ dst_bpc = 8;
-+ break;
-+ }
-+
-+ /* increment for the first ramp for one color gradation
-+ * 1 gradation for 6-bit color is 2^10
-+ * gradations in 16-bit color
-+ */
-+ inc_base = (src_bpc - dst_bpc);
-+
-+ switch (bit_depth) {
-+ case TEST_PATTERN_COLOR_FORMAT_BPC_6:
-+ {
-+ CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS,
-+ CRTC_TEST_PATTERN_INC0, inc_base,
-+ CRTC_TEST_PATTERN_INC1, 0,
-+ CRTC_TEST_PATTERN_HRES, 6,
-+ CRTC_TEST_PATTERN_VRES, 6,
-+ CRTC_TEST_PATTERN_RAMP0_OFFSET, 0);
-+ }
-+ break;
-+ case TEST_PATTERN_COLOR_FORMAT_BPC_8:
-+ {
-+ CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS,
-+ CRTC_TEST_PATTERN_INC0, inc_base,
-+ CRTC_TEST_PATTERN_INC1, 0,
-+ CRTC_TEST_PATTERN_HRES, 8,
-+ CRTC_TEST_PATTERN_VRES, 6,
-+ CRTC_TEST_PATTERN_RAMP0_OFFSET, 0);
-+ }
-+ break;
-+ case TEST_PATTERN_COLOR_FORMAT_BPC_10:
-+ {
-+ CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS,
-+ CRTC_TEST_PATTERN_INC0, inc_base,
-+ CRTC_TEST_PATTERN_INC1, inc_base + 2,
-+ CRTC_TEST_PATTERN_HRES, 8,
-+ CRTC_TEST_PATTERN_VRES, 5,
-+ CRTC_TEST_PATTERN_RAMP0_OFFSET, 384 << 6);
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, 0);
-+
-+ /* enable test pattern */
-+ dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_CONTROL, tg110->offsets.crtc, 0);
-+
-+ CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL,
-+ CRTC_TEST_PATTERN_EN, 1,
-+ CRTC_TEST_PATTERN_MODE, mode,
-+ CRTC_TEST_PATTERN_DYNAMIC_RANGE, 0,
-+ CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth);
-+ }
-+ break;
-+ case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
-+ {
-+ value = 0;
-+ dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_CONTROL, tg110->offsets.crtc, value);
-+ dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value);
-+ dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_PARAMETERS, tg110->offsets.crtc, value);
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static struct timing_generator_funcs dce120_tg_funcs = {
-+ .validate_timing = dce120_tg_validate_timing,
-+ .program_timing = dce120_tg_program_timing,
-+ .enable_crtc = dce120_timing_generator_enable_crtc,
-+ .disable_crtc = dce110_timing_generator_disable_crtc,
-+ /* used by enable_timing_synchronization. Not need for FPGA */
-+ .is_counter_moving = dce110_timing_generator_is_counter_moving,
-+ /* never be called */
-+ .get_position = dce120_timing_generator_get_crtc_positions,
-+ .get_frame_count = dce120_timing_generator_get_vblank_counter,
-+ .get_scanoutpos = dce120_timing_generator_get_crtc_scanoutpos,
-+ .set_early_control = dce120_timing_generator_set_early_control,
-+ /* used by enable_timing_synchronization. Not need for FPGA */
-+ .wait_for_state = dce120_tg_wait_for_state,
-+ .set_blank = dce120_tg_set_blank,
-+ .is_blanked = dce120_tg_is_blanked,
-+ /* never be called */
-+ .set_colors = dce120_tg_set_colors,
-+ .set_overscan_blank_color = dce120_timing_generator_set_overscan_color_black,
-+ .set_blank_color = dce120_timing_generator_program_blank_color,
-+ .disable_vga = dce120_timing_generator_disable_vga,
-+ .did_triggered_reset_occur = dce120_timing_generator_did_triggered_reset_occur,
-+ .setup_global_swap_lock = dce120_timing_generator_setup_global_swap_lock,
-+ .enable_reset_trigger = dce120_timing_generator_enable_reset_trigger,
-+ .disable_reset_trigger = dce120_timing_generator_disable_reset_trigger,
-+ .tear_down_global_swap_lock = dce120_timing_generator_tear_down_global_swap_lock,
-+ .enable_advanced_request = dce120_timing_generator_enable_advanced_request,
-+ .set_drr = dce120_timing_generator_set_drr,
-+ .set_static_screen_control = dce120_timing_generator_set_static_screen_control,
-+ .set_test_pattern = dce120_timing_generator_set_test_pattern
-+};
-+
-+
-+bool dce120_timing_generator_construct(
-+ struct dce110_timing_generator *tg110,
-+ struct dc_context *ctx,
-+ uint32_t instance,
-+ const struct dce110_timing_generator_offsets *offsets)
-+{
-+ if (!tg110)
-+ return false;
-+
-+ tg110->controller_id = CONTROLLER_ID_D0 + instance;
-+ tg110->base.inst = instance;
-+
-+ tg110->offsets = *offsets;
-+
-+ tg110->base.funcs = &dce120_tg_funcs;
-+
-+ tg110->base.ctx = ctx;
-+ tg110->base.bp = ctx->dc_bios;
-+
-+ tg110->max_h_total = CRTC0_CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1;
-+ tg110->max_v_total = CRTC0_CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1;
-+
-+ /*//CRTC requires a minimum HBLANK = 32 pixels and o
-+ * Minimum HSYNC = 8 pixels*/
-+ tg110->min_h_blank = 32;
-+ /*DCE12_CRTC_Block_ARch.doc*/
-+ tg110->min_h_front_porch = 0;
-+ tg110->min_h_back_porch = 0;
-+
-+ tg110->min_h_sync_width = 8;
-+ tg110->min_v_sync_width = 1;
-+ tg110->min_v_blank = 3;
-+
-+ return true;
-+}
-diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.h b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.h
-new file mode 100644
-index 0000000..243c0a3
---- /dev/null
-+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.h
-@@ -0,0 +1,41 @@
-+/*
-+ * 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_TIMING_GENERATOR_DCE120_H__
-+#define __DC_TIMING_GENERATOR_DCE120_H__
-+
-+#include "timing_generator.h"
-+#include "../include/grph_object_id.h"
-+#include "../include/hw_sequencer_types.h"
-+#include "dce110/dce110_timing_generator.h"
-+
-+
-+bool dce120_timing_generator_construct(
-+ struct dce110_timing_generator *tg110,
-+ struct dc_context *ctx,
-+ uint32_t instance,
-+ const struct dce110_timing_generator_offsets *offsets);
-+
-+#endif /* __DC_TIMING_GENERATOR_DCE120_H__ */
---
-2.7.4
-