aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3020-drm-amd-display-Only-blank-DCN-when-we-have-set_blan.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3020-drm-amd-display-Only-blank-DCN-when-we-have-set_blan.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3020-drm-amd-display-Only-blank-DCN-when-we-have-set_blan.patch3757
1 files changed, 3757 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3020-drm-amd-display-Only-blank-DCN-when-we-have-set_blan.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3020-drm-amd-display-Only-blank-DCN-when-we-have-set_blan.patch
new file mode 100644
index 00000000..7ca6a6a2
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3020-drm-amd-display-Only-blank-DCN-when-we-have-set_blan.patch
@@ -0,0 +1,3757 @@
+From b4b80336420aead17ed60d6133ae6889b11f4866 Mon Sep 17 00:00:00 2001
+From: Yue Hin Lau <Yuehin.Lau@amd.com>
+Date: Mon, 4 Dec 2017 16:58:11 -0500
+Subject: [PATCH 3020/4131] drm/amd/display: Only blank DCN when we have
+ set_blank implementation
+
+Also rename timing_generator to optc
+
+Signed-off-by: Yue Hin Lau <Yuehin.Lau@amd.com>
+Reviewed-by: Eric Bernstein <Eric.Bernstein@amd.com>
+Acked-by: Harry Wentland <harry.wentland@amd.com>
+---
+ drivers/gpu/drm/amd/display/dc/dcn10/Makefile | 2 +-
+ .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 33 +-
+ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | 1279 ++++++++++++++++++++
+ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h | 490 ++++++++
+ .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 2 +-
+ .../amd/display/dc/dcn10/dcn10_timing_generator.c | 1279 --------------------
+ .../amd/display/dc/dcn10/dcn10_timing_generator.h | 490 --------
+ drivers/gpu/drm/amd/display/dc/inc/hw/opp.h | 19 -
+ drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | 1 +
+ 9 files changed, 1798 insertions(+), 1797 deletions(-)
+ create mode 100644 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
+ create mode 100644 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
+ delete mode 100644 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
+ delete mode 100644 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
+index a6ca1f9..e9be515 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
+@@ -2,7 +2,7 @@
+ # Makefile for DCN.
+
+ DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \
+- dcn10_dpp.o dcn10_opp.o dcn10_timing_generator.o \
++ dcn10_dpp.o dcn10_opp.o dcn10_optc.o \
+ dcn10_hubp.o dcn10_mpc.o \
+ dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_cm_common.o \
+ dcn10_hubbub.o
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+index 824de36..c9d717c 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -32,7 +32,7 @@
+ #include "dce/dce_hwseq.h"
+ #include "abm.h"
+ #include "dmcu.h"
+-#include "dcn10/dcn10_timing_generator.h"
++#include "dcn10_optc.h"
+ #include "dcn10/dcn10_dpp.h"
+ #include "dcn10/dcn10_mpc.h"
+ #include "timing_generator.h"
+@@ -465,6 +465,8 @@ static enum dc_status dcn10_prog_pixclk_crtc_otg(
+ bool enableStereo = stream->timing.timing_3d_format == TIMING_3D_FORMAT_NONE ?
+ false:true;
+ bool rightEyePolarity = stream->timing.flags.RIGHT_EYE_3D_POLARITY;
++ int width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
++ int height = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
+
+ /* by upper caller loop, pipe0 is parent pipe and be called first.
+ * back end is set up by for pipe0. Other children pipe share back end
+@@ -518,11 +520,14 @@ static enum dc_status dcn10_prog_pixclk_crtc_otg(
+ /* program otg blank color */
+ color_space = stream->output_color_space;
+ color_space_to_black_color(dc, color_space, &black_color);
+- pipe_ctx->stream_res.tg->funcs->set_blank_color(
+- pipe_ctx->stream_res.tg,
+- &black_color);
+
+- if (!pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg)) {
++ if (pipe_ctx->stream_res.tg->funcs->set_blank_color)
++ pipe_ctx->stream_res.tg->funcs->set_blank_color(
++ pipe_ctx->stream_res.tg,
++ &black_color);
++
++ if (pipe_ctx->stream_res.tg->funcs->is_blanked &&
++ !pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg)) {
+ pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true);
+ hwss_wait_for_blank_complete(pipe_ctx->stream_res.tg);
+ false_optc_underflow_wa(dc, pipe_ctx->stream, pipe_ctx->stream_res.tg);
+@@ -1808,6 +1813,10 @@ static void program_all_pipe_in_tree(
+ struct pipe_ctx *pipe_ctx,
+ struct dc_state *context)
+ {
++ struct dc_stream_state *stream = pipe_ctx->stream;
++ int width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
++ int height = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
++
+ if (pipe_ctx->top_pipe == NULL) {
+
+ pipe_ctx->stream_res.tg->dlg_otg_param.vready_offset = pipe_ctx->pipe_dlg_param.vready_offset;
+@@ -1818,7 +1827,11 @@ static void program_all_pipe_in_tree(
+
+ pipe_ctx->stream_res.tg->funcs->program_global_sync(
+ pipe_ctx->stream_res.tg);
+- pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, !is_pipe_tree_visible(pipe_ctx));
++
++ if (pipe_ctx->stream_res.tg->funcs->set_blank)
++ pipe_ctx->stream_res.tg->funcs->set_blank(
++ pipe_ctx->stream_res.tg,
++ !is_pipe_tree_visible(pipe_ctx));
+ }
+
+ if (pipe_ctx->plane_state != NULL) {
+@@ -1925,9 +1938,12 @@ static void dcn10_apply_ctx_for_surface(
+ {
+ int i;
+ struct timing_generator *tg;
++ struct output_pixel_processor *opp;
+ bool removed_pipe[4] = { false };
+ unsigned int ref_clk_mhz = dc->res_pool->ref_clock_inKhz/1000;
+ bool program_water_mark = false;
++ int width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
++ int height = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
+
+ struct pipe_ctx *top_pipe_to_program =
+ find_top_pipe_for_stream(dc, context, stream);
+@@ -1935,6 +1951,8 @@ static void dcn10_apply_ctx_for_surface(
+ if (!top_pipe_to_program)
+ return;
+
++ opp = top_pipe_to_program->stream_res.opp;
++
+ tg = top_pipe_to_program->stream_res.tg;
+
+ tg->funcs->lock(tg);
+@@ -1942,7 +1960,8 @@ static void dcn10_apply_ctx_for_surface(
+ if (num_planes == 0) {
+
+ /* OTG blank before remove all front end */
+- tg->funcs->set_blank(tg, true);
++ if (tg->funcs->set_blank)
++ tg->funcs->set_blank(tg, true);
+ }
+
+ /* Disconnect unused mpcc */
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
+new file mode 100644
+index 0000000..827dd14
+--- /dev/null
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
+@@ -0,0 +1,1279 @@
++/*
++ * Copyright 2012-15 Advanced Micro Devices, Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ *
++ * Authors: AMD
++ *
++ */
++
++
++#include "reg_helper.h"
++#include "dcn10_optc.h"
++#include "dc.h"
++
++#define REG(reg)\
++ optc1->tg_regs->reg
++
++#define CTX \
++ optc1->base.ctx
++
++#undef FN
++#define FN(reg_name, field_name) \
++ optc1->tg_shift->field_name, optc1->tg_mask->field_name
++
++#define STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN 0x100
++
++/**
++* apply_front_porch_workaround TODO FPGA still need?
++*
++* This is a workaround for a bug that has existed since R5xx and has not been
++* fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive.
++*/
++static void optc1_apply_front_porch_workaround(
++ struct timing_generator *optc,
++ struct dc_crtc_timing *timing)
++{
++ if (timing->flags.INTERLACE == 1) {
++ if (timing->v_front_porch < 2)
++ timing->v_front_porch = 2;
++ } else {
++ if (timing->v_front_porch < 1)
++ timing->v_front_porch = 1;
++ }
++}
++
++void optc1_program_global_sync(
++ struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ if (optc->dlg_otg_param.vstartup_start == 0) {
++ BREAK_TO_DEBUGGER();
++ return;
++ }
++
++ REG_SET(OTG_VSTARTUP_PARAM, 0,
++ VSTARTUP_START, optc->dlg_otg_param.vstartup_start);
++
++ REG_SET_2(OTG_VUPDATE_PARAM, 0,
++ VUPDATE_OFFSET, optc->dlg_otg_param.vupdate_offset,
++ VUPDATE_WIDTH, optc->dlg_otg_param.vupdate_width);
++
++ REG_SET(OTG_VREADY_PARAM, 0,
++ VREADY_OFFSET, optc->dlg_otg_param.vready_offset);
++}
++
++static void optc1_disable_stereo(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ REG_SET(OTG_STEREO_CONTROL, 0,
++ OTG_STEREO_EN, 0);
++
++ REG_SET_3(OTG_3D_STRUCTURE_CONTROL, 0,
++ OTG_3D_STRUCTURE_EN, 0,
++ OTG_3D_STRUCTURE_V_UPDATE_MODE, 0,
++ OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0);
++
++ REG_UPDATE(OPPBUF_CONTROL,
++ OPPBUF_ACTIVE_WIDTH, 0);
++ REG_UPDATE(OPPBUF_3D_PARAMETERS_0,
++ OPPBUF_3D_VACT_SPACE1_SIZE, 0);
++}
++
++/**
++ * program_timing_generator used by mode timing set
++ * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition.
++ * Including SYNC. Call BIOS command table to program Timings.
++ */
++void optc1_program_timing(
++ struct timing_generator *optc,
++ const struct dc_crtc_timing *dc_crtc_timing,
++ bool use_vbios)
++{
++ struct dc_crtc_timing patched_crtc_timing;
++ uint32_t vesa_sync_start;
++ uint32_t asic_blank_end;
++ uint32_t asic_blank_start;
++ uint32_t v_total;
++ uint32_t v_sync_end;
++ uint32_t v_init, v_fp2;
++ uint32_t h_sync_polarity, v_sync_polarity;
++ uint32_t interlace_factor;
++ uint32_t start_point = 0;
++ uint32_t field_num = 0;
++ uint32_t h_div_2;
++ int32_t vertical_line_start;
++
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ patched_crtc_timing = *dc_crtc_timing;
++ optc1_apply_front_porch_workaround(optc, &patched_crtc_timing);
++
++ /* Load horizontal timing */
++
++ /* CRTC_H_TOTAL = vesa.h_total - 1 */
++ REG_SET(OTG_H_TOTAL, 0,
++ OTG_H_TOTAL, patched_crtc_timing.h_total - 1);
++
++ /* h_sync_start = 0, h_sync_end = vesa.h_sync_width */
++ REG_UPDATE_2(OTG_H_SYNC_A,
++ OTG_H_SYNC_A_START, 0,
++ OTG_H_SYNC_A_END, patched_crtc_timing.h_sync_width);
++
++ /* asic_h_blank_end = HsyncWidth + HbackPorch =
++ * vesa. usHorizontalTotal - vesa. usHorizontalSyncStart -
++ * vesa.h_left_border
++ */
++ vesa_sync_start = patched_crtc_timing.h_addressable +
++ patched_crtc_timing.h_border_right +
++ patched_crtc_timing.h_front_porch;
++
++ asic_blank_end = patched_crtc_timing.h_total -
++ vesa_sync_start -
++ patched_crtc_timing.h_border_left;
++
++ /* h_blank_start = v_blank_end + v_active */
++ asic_blank_start = asic_blank_end +
++ patched_crtc_timing.h_border_left +
++ patched_crtc_timing.h_addressable +
++ patched_crtc_timing.h_border_right;
++
++ REG_UPDATE_2(OTG_H_BLANK_START_END,
++ OTG_H_BLANK_START, asic_blank_start,
++ OTG_H_BLANK_END, asic_blank_end);
++
++ /* h_sync polarity */
++ h_sync_polarity = patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY ?
++ 0 : 1;
++
++ REG_UPDATE(OTG_H_SYNC_A_CNTL,
++ OTG_H_SYNC_A_POL, h_sync_polarity);
++
++ /* Load vertical timing */
++
++ /* CRTC_V_TOTAL = v_total - 1 */
++ if (patched_crtc_timing.flags.INTERLACE) {
++ interlace_factor = 2;
++ v_total = 2 * patched_crtc_timing.v_total;
++ } else {
++ interlace_factor = 1;
++ v_total = patched_crtc_timing.v_total - 1;
++ }
++ REG_SET(OTG_V_TOTAL, 0,
++ OTG_V_TOTAL, v_total);
++
++ /* In case of V_TOTAL_CONTROL is on, make sure OTG_V_TOTAL_MAX and
++ * OTG_V_TOTAL_MIN are equal to V_TOTAL.
++ */
++ REG_SET(OTG_V_TOTAL_MAX, 0,
++ OTG_V_TOTAL_MAX, v_total);
++ REG_SET(OTG_V_TOTAL_MIN, 0,
++ OTG_V_TOTAL_MIN, v_total);
++
++ /* v_sync_start = 0, v_sync_end = v_sync_width */
++ v_sync_end = patched_crtc_timing.v_sync_width * interlace_factor;
++
++ REG_UPDATE_2(OTG_V_SYNC_A,
++ OTG_V_SYNC_A_START, 0,
++ OTG_V_SYNC_A_END, v_sync_end);
++
++ vesa_sync_start = patched_crtc_timing.v_addressable +
++ patched_crtc_timing.v_border_bottom +
++ patched_crtc_timing.v_front_porch;
++
++ asic_blank_end = (patched_crtc_timing.v_total -
++ vesa_sync_start -
++ patched_crtc_timing.v_border_top)
++ * interlace_factor;
++
++ /* v_blank_start = v_blank_end + v_active */
++ asic_blank_start = asic_blank_end +
++ (patched_crtc_timing.v_border_top +
++ patched_crtc_timing.v_addressable +
++ patched_crtc_timing.v_border_bottom)
++ * interlace_factor;
++
++ REG_UPDATE_2(OTG_V_BLANK_START_END,
++ OTG_V_BLANK_START, asic_blank_start,
++ OTG_V_BLANK_END, asic_blank_end);
++
++ /* Use OTG_VERTICAL_INTERRUPT2 replace VUPDATE interrupt,
++ * program the reg for interrupt postition.
++ */
++ vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1;
++ if (vertical_line_start < 0) {
++ ASSERT(0);
++ vertical_line_start = 0;
++ }
++ REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0,
++ OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start);
++
++ /* v_sync polarity */
++ v_sync_polarity = patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ?
++ 0 : 1;
++
++ REG_UPDATE(OTG_V_SYNC_A_CNTL,
++ OTG_V_SYNC_A_POL, v_sync_polarity);
++
++ v_init = asic_blank_start;
++ if (optc->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT ||
++ optc->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
++ optc->dlg_otg_param.signal == SIGNAL_TYPE_EDP) {
++ start_point = 1;
++ if (patched_crtc_timing.flags.INTERLACE == 1)
++ field_num = 1;
++ }
++ v_fp2 = 0;
++ if (optc->dlg_otg_param.vstartup_start > asic_blank_end)
++ v_fp2 = optc->dlg_otg_param.vstartup_start > asic_blank_end;
++
++ /* Interlace */
++ if (patched_crtc_timing.flags.INTERLACE == 1) {
++ REG_UPDATE(OTG_INTERLACE_CONTROL,
++ OTG_INTERLACE_ENABLE, 1);
++ v_init = v_init / 2;
++ if ((optc->dlg_otg_param.vstartup_start/2)*2 > asic_blank_end)
++ v_fp2 = v_fp2 / 2;
++ } else
++ REG_UPDATE(OTG_INTERLACE_CONTROL,
++ OTG_INTERLACE_ENABLE, 0);
++
++
++ /* VTG enable set to 0 first VInit */
++ REG_UPDATE(CONTROL,
++ VTG0_ENABLE, 0);
++
++ REG_UPDATE_2(CONTROL,
++ VTG0_FP2, v_fp2,
++ VTG0_VCOUNT_INIT, v_init);
++
++ /* original code is using VTG offset to address OTG reg, seems wrong */
++ REG_UPDATE_2(OTG_CONTROL,
++ OTG_START_POINT_CNTL, start_point,
++ OTG_FIELD_NUMBER_CNTL, field_num);
++
++ optc1_program_global_sync(optc);
++
++ /* TODO
++ * patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1
++ * program_horz_count_by_2
++ * for DVI 30bpp mode, 0 otherwise
++ * program_horz_count_by_2(optc, &patched_crtc_timing);
++ */
++
++ /* Enable stereo - only when we need to pack 3D frame. Other types
++ * of stereo handled in explicit call
++ */
++ h_div_2 = (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ?
++ 1 : 0;
++
++ REG_UPDATE(OTG_H_TIMING_CNTL,
++ OTG_H_TIMING_DIV_BY2, h_div_2);
++
++}
++
++static void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ uint32_t blank_data_double_buffer_enable = enable ? 1 : 0;
++
++ REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
++ OTG_BLANK_DATA_DOUBLE_BUFFER_EN, blank_data_double_buffer_enable);
++}
++
++/**
++ * unblank_crtc
++ * Call ASIC Control Object to UnBlank CRTC.
++ */
++static void optc1_unblank_crtc(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++ uint32_t vertical_interrupt_enable = 0;
++
++ REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL,
++ OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &vertical_interrupt_enable);
++
++ /* temporary work around for vertical interrupt, once vertical interrupt enabled,
++ * this check will be removed.
++ */
++ if (vertical_interrupt_enable)
++ optc1_set_blank_data_double_buffer(optc, true);
++
++ REG_UPDATE_2(OTG_BLANK_CONTROL,
++ OTG_BLANK_DATA_EN, 0,
++ OTG_BLANK_DE_MODE, 0);
++}
++
++/**
++ * blank_crtc
++ * Call ASIC Control Object to Blank CRTC.
++ */
++
++static void optc1_blank_crtc(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ REG_UPDATE_2(OTG_BLANK_CONTROL,
++ OTG_BLANK_DATA_EN, 1,
++ OTG_BLANK_DE_MODE, 0);
++
++ optc1_set_blank_data_double_buffer(optc, false);
++}
++
++void optc1_set_blank(struct timing_generator *optc,
++ bool enable_blanking)
++{
++ if (enable_blanking)
++ optc1_blank_crtc(optc);
++ else
++ optc1_unblank_crtc(optc);
++}
++
++bool optc1_is_blanked(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++ uint32_t blank_en;
++ uint32_t blank_state;
++
++ REG_GET_2(OTG_BLANK_CONTROL,
++ OTG_BLANK_DATA_EN, &blank_en,
++ OTG_CURRENT_BLANK_STATE, &blank_state);
++
++ return blank_en && blank_state;
++}
++
++void optc1_enable_optc_clock(struct timing_generator *optc, bool enable)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ if (enable) {
++ REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
++ OPTC_INPUT_CLK_EN, 1,
++ OPTC_INPUT_CLK_GATE_DIS, 1);
++
++ REG_WAIT(OPTC_INPUT_CLOCK_CONTROL,
++ OPTC_INPUT_CLK_ON, 1,
++ 1, 1000);
++
++ /* Enable clock */
++ REG_UPDATE_2(OTG_CLOCK_CONTROL,
++ OTG_CLOCK_EN, 1,
++ OTG_CLOCK_GATE_DIS, 1);
++ REG_WAIT(OTG_CLOCK_CONTROL,
++ OTG_CLOCK_ON, 1,
++ 1, 1000);
++ } else {
++ REG_UPDATE_2(OTG_CLOCK_CONTROL,
++ OTG_CLOCK_GATE_DIS, 0,
++ OTG_CLOCK_EN, 0);
++
++ REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
++ OPTC_INPUT_CLK_GATE_DIS, 0,
++ OPTC_INPUT_CLK_EN, 0);
++ }
++}
++
++/**
++ * Enable CRTC
++ * Enable CRTC - call ASIC Control Object to enable Timing generator.
++ */
++static bool optc1_enable_crtc(struct timing_generator *optc)
++{
++ /* TODO FPGA wait for answer
++ * OTG_MASTER_UPDATE_MODE != CRTC_MASTER_UPDATE_MODE
++ * OTG_MASTER_UPDATE_LOCK != CRTC_MASTER_UPDATE_LOCK
++ */
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ /* opp instance for OTG. For DCN1.0, ODM is remoed.
++ * OPP and OPTC should 1:1 mapping
++ */
++ REG_UPDATE(OPTC_DATA_SOURCE_SELECT,
++ OPTC_SRC_SEL, optc->inst);
++
++ /* VTG enable first is for HW workaround */
++ REG_UPDATE(CONTROL,
++ VTG0_ENABLE, 1);
++
++ /* Enable CRTC */
++ REG_UPDATE_2(OTG_CONTROL,
++ OTG_DISABLE_POINT_CNTL, 3,
++ OTG_MASTER_EN, 1);
++
++ return true;
++}
++
++/* disable_crtc - call ASIC Control Object to disable Timing generator. */
++bool optc1_disable_crtc(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ /* disable otg request until end of the first line
++ * in the vertical blank region
++ */
++ REG_UPDATE_2(OTG_CONTROL,
++ OTG_DISABLE_POINT_CNTL, 3,
++ OTG_MASTER_EN, 0);
++
++ REG_UPDATE(CONTROL,
++ VTG0_ENABLE, 0);
++
++ /* CRTC disabled, so disable clock. */
++ REG_WAIT(OTG_CLOCK_CONTROL,
++ OTG_BUSY, 0,
++ 1, 100000);
++
++ return true;
++}
++
++
++void optc1_program_blank_color(
++ struct timing_generator *optc,
++ const struct tg_color *black_color)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ REG_SET_3(OTG_BLACK_COLOR, 0,
++ OTG_BLACK_COLOR_B_CB, black_color->color_b_cb,
++ OTG_BLACK_COLOR_G_Y, black_color->color_g_y,
++ OTG_BLACK_COLOR_R_CR, black_color->color_r_cr);
++}
++
++bool optc1_validate_timing(
++ struct timing_generator *optc,
++ const struct dc_crtc_timing *timing)
++{
++ uint32_t interlace_factor;
++ uint32_t v_blank;
++ uint32_t h_blank;
++ uint32_t min_v_blank;
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ ASSERT(timing != NULL);
++
++ interlace_factor = timing->flags.INTERLACE ? 2 : 1;
++ v_blank = (timing->v_total - timing->v_addressable -
++ timing->v_border_top - timing->v_border_bottom) *
++ interlace_factor;
++
++ h_blank = (timing->h_total - timing->h_addressable -
++ timing->h_border_right -
++ timing->h_border_left);
++
++ if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE &&
++ timing->timing_3d_format != TIMING_3D_FORMAT_HW_FRAME_PACKING &&
++ timing->timing_3d_format != TIMING_3D_FORMAT_TOP_AND_BOTTOM &&
++ timing->timing_3d_format != TIMING_3D_FORMAT_SIDE_BY_SIDE &&
++ timing->timing_3d_format != TIMING_3D_FORMAT_FRAME_ALTERNATE &&
++ timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA)
++ return false;
++
++ /* Temporarily blocking interlacing mode until it's supported */
++ if (timing->flags.INTERLACE == 1)
++ return false;
++
++ /* Check maximum number of pixels supported by Timing Generator
++ * (Currently will never fail, in order to fail needs display which
++ * needs more than 8192 horizontal and
++ * more than 8192 vertical total pixels)
++ */
++ if (timing->h_total > optc1->max_h_total ||
++ timing->v_total > optc1->max_v_total)
++ return false;
++
++
++ if (h_blank < optc1->min_h_blank)
++ return false;
++
++ if (timing->h_sync_width < optc1->min_h_sync_width ||
++ timing->v_sync_width < optc1->min_v_sync_width)
++ return false;
++
++ min_v_blank = timing->flags.INTERLACE?optc1->min_v_blank_interlace:optc1->min_v_blank;
++
++ if (v_blank < min_v_blank)
++ return false;
++
++ return true;
++
++}
++
++/*
++ * get_vblank_counter
++ *
++ * @brief
++ * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which
++ * holds the counter of frames.
++ *
++ * @param
++ * struct timing_generator *optc - [in] timing generator which controls the
++ * desired CRTC
++ *
++ * @return
++ * Counter of frames, which should equal to number of vblanks.
++ */
++uint32_t optc1_get_vblank_counter(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++ uint32_t frame_count;
++
++ REG_GET(OTG_STATUS_FRAME_COUNT,
++ OTG_FRAME_COUNT, &frame_count);
++
++ return frame_count;
++}
++
++void optc1_lock(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ REG_SET(OTG_GLOBAL_CONTROL0, 0,
++ OTG_MASTER_UPDATE_LOCK_SEL, optc->inst);
++ REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
++ OTG_MASTER_UPDATE_LOCK, 1);
++
++ /* Should be fast, status does not update on maximus */
++ if (optc->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
++ REG_WAIT(OTG_MASTER_UPDATE_LOCK,
++ UPDATE_LOCK_STATUS, 1,
++ 1, 10);
++}
++
++void optc1_unlock(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
++ OTG_MASTER_UPDATE_LOCK, 0);
++}
++
++void optc1_get_position(struct timing_generator *optc,
++ struct crtc_position *position)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ REG_GET_2(OTG_STATUS_POSITION,
++ OTG_HORZ_COUNT, &position->horizontal_count,
++ OTG_VERT_COUNT, &position->vertical_count);
++
++ REG_GET(OTG_NOM_VERT_POSITION,
++ OTG_VERT_COUNT_NOM, &position->nominal_vcount);
++}
++
++bool optc1_is_counter_moving(struct timing_generator *optc)
++{
++ struct crtc_position position1, position2;
++
++ optc->funcs->get_position(optc, &position1);
++ optc->funcs->get_position(optc, &position2);
++
++ if (position1.horizontal_count == position2.horizontal_count &&
++ position1.vertical_count == position2.vertical_count)
++ return false;
++ else
++ return true;
++}
++
++bool optc1_did_triggered_reset_occur(
++ struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++ uint32_t occurred_force, occurred_vsync;
++
++ REG_GET(OTG_FORCE_COUNT_NOW_CNTL,
++ OTG_FORCE_COUNT_NOW_OCCURRED, &occurred_force);
++
++ REG_GET(OTG_VERT_SYNC_CONTROL,
++ OTG_FORCE_VSYNC_NEXT_LINE_OCCURRED, &occurred_vsync);
++
++ return occurred_vsync != 0 || occurred_force != 0;
++}
++
++void optc1_disable_reset_trigger(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ REG_WRITE(OTG_TRIGA_CNTL, 0);
++
++ REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
++ OTG_FORCE_COUNT_NOW_CLEAR, 1);
++
++ REG_SET(OTG_VERT_SYNC_CONTROL, 0,
++ OTG_FORCE_VSYNC_NEXT_LINE_CLEAR, 1);
++}
++
++void optc1_enable_reset_trigger(struct timing_generator *optc, int source_tg_inst)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++ uint32_t falling_edge;
++
++ REG_GET(OTG_V_SYNC_A_CNTL,
++ OTG_V_SYNC_A_POL, &falling_edge);
++
++ if (falling_edge)
++ REG_SET_3(OTG_TRIGA_CNTL, 0,
++ /* vsync signal from selected OTG pipe based
++ * on OTG_TRIG_SOURCE_PIPE_SELECT setting
++ */
++ OTG_TRIGA_SOURCE_SELECT, 20,
++ OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
++ /* always detect falling edge */
++ OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, 1);
++ else
++ REG_SET_3(OTG_TRIGA_CNTL, 0,
++ /* vsync signal from selected OTG pipe based
++ * on OTG_TRIG_SOURCE_PIPE_SELECT setting
++ */
++ OTG_TRIGA_SOURCE_SELECT, 20,
++ OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
++ /* always detect rising edge */
++ OTG_TRIGA_RISING_EDGE_DETECT_CNTL, 1);
++
++ REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
++ /* force H count to H_TOTAL and V count to V_TOTAL in
++ * progressive mode and V_TOTAL-1 in interlaced mode
++ */
++ OTG_FORCE_COUNT_NOW_MODE, 2);
++}
++
++void optc1_enable_crtc_reset(
++ struct timing_generator *optc,
++ int source_tg_inst,
++ struct crtc_trigger_info *crtc_tp)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++ uint32_t falling_edge = 0;
++ uint32_t rising_edge = 0;
++
++ switch (crtc_tp->event) {
++
++ case CRTC_EVENT_VSYNC_RISING:
++ rising_edge = 1;
++ break;
++
++ case CRTC_EVENT_VSYNC_FALLING:
++ falling_edge = 1;
++ break;
++ }
++
++ REG_SET_4(OTG_TRIGA_CNTL, 0,
++ /* vsync signal from selected OTG pipe based
++ * on OTG_TRIG_SOURCE_PIPE_SELECT setting
++ */
++ OTG_TRIGA_SOURCE_SELECT, 20,
++ OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
++ /* always detect falling edge */
++ OTG_TRIGA_RISING_EDGE_DETECT_CNTL, rising_edge,
++ OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, falling_edge);
++
++ switch (crtc_tp->delay) {
++ case TRIGGER_DELAY_NEXT_LINE:
++ REG_SET(OTG_VERT_SYNC_CONTROL, 0,
++ OTG_AUTO_FORCE_VSYNC_MODE, 1);
++ break;
++ case TRIGGER_DELAY_NEXT_PIXEL:
++ REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
++ /* force H count to H_TOTAL and V count to V_TOTAL in
++ * progressive mode and V_TOTAL-1 in interlaced mode
++ */
++ OTG_FORCE_COUNT_NOW_MODE, 2);
++ break;
++ }
++}
++
++void optc1_wait_for_state(struct timing_generator *optc,
++ enum crtc_state state)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ switch (state) {
++ case CRTC_STATE_VBLANK:
++ REG_WAIT(OTG_STATUS,
++ OTG_V_BLANK, 1,
++ 1, 100000); /* 1 vupdate at 10hz */
++ break;
++
++ case CRTC_STATE_VACTIVE:
++ REG_WAIT(OTG_STATUS,
++ OTG_V_ACTIVE_DISP, 1,
++ 1, 100000); /* 1 vupdate at 10hz */
++ break;
++
++ default:
++ break;
++ }
++}
++
++void optc1_set_early_control(
++ struct timing_generator *optc,
++ uint32_t early_cntl)
++{
++ /* asic design change, do not need this control
++ * empty for share caller logic
++ */
++}
++
++
++void optc1_set_static_screen_control(
++ struct timing_generator *optc,
++ uint32_t value)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ /* Bit 8 is no longer applicable in RV for PSR case,
++ * set bit 8 to 0 if given
++ */
++ if ((value & STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN)
++ != 0)
++ value = value &
++ ~STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN;
++
++ REG_SET_2(OTG_STATIC_SCREEN_CONTROL, 0,
++ OTG_STATIC_SCREEN_EVENT_MASK, value,
++ OTG_STATIC_SCREEN_FRAME_COUNT, 2);
++}
++
++
++/**
++ *****************************************************************************
++ * Function: set_drr
++ *
++ * @brief
++ * Program dynamic refresh rate registers m_OTGx_OTG_V_TOTAL_*.
++ *
++ *****************************************************************************
++ */
++void optc1_set_drr(
++ struct timing_generator *optc,
++ const struct drr_params *params)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ if (params != NULL &&
++ params->vertical_total_max > 0 &&
++ params->vertical_total_min > 0) {
++
++ REG_SET(OTG_V_TOTAL_MAX, 0,
++ OTG_V_TOTAL_MAX, params->vertical_total_max - 1);
++
++ REG_SET(OTG_V_TOTAL_MIN, 0,
++ OTG_V_TOTAL_MIN, params->vertical_total_min - 1);
++
++ REG_UPDATE_5(OTG_V_TOTAL_CONTROL,
++ OTG_V_TOTAL_MIN_SEL, 1,
++ OTG_V_TOTAL_MAX_SEL, 1,
++ OTG_FORCE_LOCK_ON_EVENT, 0,
++ OTG_SET_V_TOTAL_MIN_MASK_EN, 0,
++ OTG_SET_V_TOTAL_MIN_MASK, 0);
++ } else {
++ REG_SET(OTG_V_TOTAL_MIN, 0,
++ OTG_V_TOTAL_MIN, 0);
++
++ REG_SET(OTG_V_TOTAL_MAX, 0,
++ OTG_V_TOTAL_MAX, 0);
++
++ REG_UPDATE_4(OTG_V_TOTAL_CONTROL,
++ OTG_SET_V_TOTAL_MIN_MASK, 0,
++ OTG_V_TOTAL_MIN_SEL, 0,
++ OTG_V_TOTAL_MAX_SEL, 0,
++ OTG_FORCE_LOCK_ON_EVENT, 0);
++ }
++}
++
++static void optc1_set_test_pattern(
++ struct timing_generator *optc,
++ /* 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 optc *optc1 = DCN10TG_FROM_TG(optc);
++ enum test_pattern_color_format bit_depth;
++ enum test_pattern_dyn_range dyn_range;
++ enum test_pattern_mode mode;
++ uint32_t pattern_mask;
++ uint32_t pattern_data;
++ /* 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;
++
++ REG_UPDATE_2(OTG_TEST_PATTERN_PARAMETERS,
++ OTG_TEST_PATTERN_VRES, 6,
++ OTG_TEST_PATTERN_HRES, 6);
++
++ REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL,
++ OTG_TEST_PATTERN_EN, 1,
++ OTG_TEST_PATTERN_MODE, mode,
++ OTG_TEST_PATTERN_DYNAMIC_RANGE, dyn_range,
++ OTG_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);
++ }
++
++ REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 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
++ */
++ pattern_data = 0;
++ for (index = 0; index < 6; index++) {
++ /* prepare color mask, first write PATTERN_DATA
++ * will have all zeros
++ */
++ pattern_mask = (1 << index);
++
++ /* write color component */
++ REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
++ OTG_TEST_PATTERN_MASK, pattern_mask,
++ OTG_TEST_PATTERN_DATA, pattern_data);
++
++ /* prepare next color component,
++ * will be written in the next iteration
++ */
++ pattern_data = dst_color[index];
++ }
++ /* write last color component,
++ * it's been already prepared in the loop
++ */
++ REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
++ OTG_TEST_PATTERN_MASK, pattern_mask,
++ OTG_TEST_PATTERN_DATA, pattern_data);
++
++ /* enable test pattern */
++ REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL,
++ OTG_TEST_PATTERN_EN, 1,
++ OTG_TEST_PATTERN_MODE, mode,
++ OTG_TEST_PATTERN_DYNAMIC_RANGE, 0,
++ OTG_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:
++ {
++ REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
++ OTG_TEST_PATTERN_INC0, inc_base,
++ OTG_TEST_PATTERN_INC1, 0,
++ OTG_TEST_PATTERN_HRES, 6,
++ OTG_TEST_PATTERN_VRES, 6,
++ OTG_TEST_PATTERN_RAMP0_OFFSET, 0);
++ }
++ break;
++ case TEST_PATTERN_COLOR_FORMAT_BPC_8:
++ {
++ REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
++ OTG_TEST_PATTERN_INC0, inc_base,
++ OTG_TEST_PATTERN_INC1, 0,
++ OTG_TEST_PATTERN_HRES, 8,
++ OTG_TEST_PATTERN_VRES, 6,
++ OTG_TEST_PATTERN_RAMP0_OFFSET, 0);
++ }
++ break;
++ case TEST_PATTERN_COLOR_FORMAT_BPC_10:
++ {
++ REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
++ OTG_TEST_PATTERN_INC0, inc_base,
++ OTG_TEST_PATTERN_INC1, inc_base + 2,
++ OTG_TEST_PATTERN_HRES, 8,
++ OTG_TEST_PATTERN_VRES, 5,
++ OTG_TEST_PATTERN_RAMP0_OFFSET, 384 << 6);
++ }
++ break;
++ default:
++ break;
++ }
++
++ REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
++
++ /* enable test pattern */
++ REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
++
++ REG_SET_4(OTG_TEST_PATTERN_CONTROL, 0,
++ OTG_TEST_PATTERN_EN, 1,
++ OTG_TEST_PATTERN_MODE, mode,
++ OTG_TEST_PATTERN_DYNAMIC_RANGE, 0,
++ OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
++ }
++ break;
++ case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
++ {
++ REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
++ REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
++ REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0);
++ }
++ break;
++ default:
++ break;
++
++ }
++}
++
++void optc1_get_crtc_scanoutpos(
++ struct timing_generator *optc,
++ uint32_t *v_blank_start,
++ uint32_t *v_blank_end,
++ uint32_t *h_position,
++ uint32_t *v_position)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++ struct crtc_position position;
++
++ REG_GET_2(OTG_V_BLANK_START_END,
++ OTG_V_BLANK_START, v_blank_start,
++ OTG_V_BLANK_END, v_blank_end);
++
++ optc1_get_position(optc, &position);
++
++ *h_position = position.horizontal_count;
++ *v_position = position.vertical_count;
++}
++
++
++
++static void optc1_enable_stereo(struct timing_generator *optc,
++ const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ uint32_t active_width = timing->h_addressable;
++ uint32_t space1_size = timing->v_total - timing->v_addressable;
++
++ if (flags) {
++ uint32_t stereo_en;
++ stereo_en = flags->FRAME_PACKED == 0 ? 1 : 0;
++
++ if (flags->PROGRAM_STEREO)
++ REG_UPDATE_3(OTG_STEREO_CONTROL,
++ OTG_STEREO_EN, stereo_en,
++ OTG_STEREO_SYNC_OUTPUT_LINE_NUM, 0,
++ OTG_STEREO_SYNC_OUTPUT_POLARITY, 0);
++
++ if (flags->PROGRAM_POLARITY)
++ REG_UPDATE(OTG_STEREO_CONTROL,
++ OTG_STEREO_EYE_FLAG_POLARITY,
++ flags->RIGHT_EYE_POLARITY == 0 ? 0 : 1);
++
++ if (flags->DISABLE_STEREO_DP_SYNC)
++ REG_UPDATE(OTG_STEREO_CONTROL,
++ OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, 1);
++
++ if (flags->PROGRAM_STEREO)
++ REG_UPDATE_3(OTG_3D_STRUCTURE_CONTROL,
++ OTG_3D_STRUCTURE_EN, flags->FRAME_PACKED,
++ OTG_3D_STRUCTURE_V_UPDATE_MODE, flags->FRAME_PACKED,
++ OTG_3D_STRUCTURE_STEREO_SEL_OVR, flags->FRAME_PACKED);
++
++ }
++
++ REG_UPDATE(OPPBUF_CONTROL,
++ OPPBUF_ACTIVE_WIDTH, active_width);
++
++ REG_UPDATE(OPPBUF_3D_PARAMETERS_0,
++ OPPBUF_3D_VACT_SPACE1_SIZE, space1_size);
++}
++
++void optc1_program_stereo(struct timing_generator *optc,
++ const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
++{
++ if (flags->PROGRAM_STEREO)
++ optc1_enable_stereo(optc, timing, flags);
++ else
++ optc1_disable_stereo(optc);
++}
++
++
++bool optc1_is_stereo_left_eye(struct timing_generator *optc)
++{
++ bool ret = false;
++ uint32_t left_eye = 0;
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ REG_GET(OTG_STEREO_STATUS,
++ OTG_STEREO_CURRENT_EYE, &left_eye);
++ if (left_eye == 1)
++ ret = true;
++ else
++ ret = false;
++
++ return ret;
++}
++
++void optc1_read_otg_state(struct optc *optc1,
++ struct dcn_otg_state *s)
++{
++ REG_GET(OTG_CONTROL,
++ OTG_MASTER_EN, &s->otg_enabled);
++
++ REG_GET_2(OTG_V_BLANK_START_END,
++ OTG_V_BLANK_START, &s->v_blank_start,
++ OTG_V_BLANK_END, &s->v_blank_end);
++
++ REG_GET(OTG_V_SYNC_A_CNTL,
++ OTG_V_SYNC_A_POL, &s->v_sync_a_pol);
++
++ REG_GET(OTG_V_TOTAL,
++ OTG_V_TOTAL, &s->v_total);
++
++ REG_GET(OTG_V_TOTAL_MAX,
++ OTG_V_TOTAL_MAX, &s->v_total_max);
++
++ REG_GET(OTG_V_TOTAL_MIN,
++ OTG_V_TOTAL_MIN, &s->v_total_min);
++
++ REG_GET_2(OTG_V_SYNC_A,
++ OTG_V_SYNC_A_START, &s->v_sync_a_start,
++ OTG_V_SYNC_A_END, &s->v_sync_a_end);
++
++ REG_GET_2(OTG_H_BLANK_START_END,
++ OTG_H_BLANK_START, &s->h_blank_start,
++ OTG_H_BLANK_END, &s->h_blank_end);
++
++ REG_GET_2(OTG_H_SYNC_A,
++ OTG_H_SYNC_A_START, &s->h_sync_a_start,
++ OTG_H_SYNC_A_END, &s->h_sync_a_end);
++
++ REG_GET(OTG_H_SYNC_A_CNTL,
++ OTG_H_SYNC_A_POL, &s->h_sync_a_pol);
++
++ REG_GET(OTG_H_TOTAL,
++ OTG_H_TOTAL, &s->h_total);
++
++ REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
++ OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status);
++}
++
++static void optc1_clear_optc_underflow(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ REG_UPDATE(OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, 1);
++}
++
++static void optc1_tg_init(struct timing_generator *optc)
++{
++ optc1_set_blank_data_double_buffer(optc, true);
++ optc1_clear_optc_underflow(optc);
++}
++
++static bool optc1_is_tg_enabled(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++ uint32_t otg_enabled = 0;
++
++ REG_GET(OTG_CONTROL, OTG_MASTER_EN, &otg_enabled);
++
++ return (otg_enabled != 0);
++
++}
++
++static bool optc1_is_optc_underflow_occurred(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++ uint32_t underflow_occurred = 0;
++
++ REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
++ OPTC_UNDERFLOW_OCCURRED_STATUS,
++ &underflow_occurred);
++
++ return (underflow_occurred == 1);
++}
++
++static const struct timing_generator_funcs dcn10_tg_funcs = {
++ .validate_timing = optc1_validate_timing,
++ .program_timing = optc1_program_timing,
++ .program_global_sync = optc1_program_global_sync,
++ .enable_crtc = optc1_enable_crtc,
++ .disable_crtc = optc1_disable_crtc,
++ /* used by enable_timing_synchronization. Not need for FPGA */
++ .is_counter_moving = optc1_is_counter_moving,
++ .get_position = optc1_get_position,
++ .get_frame_count = optc1_get_vblank_counter,
++ .get_scanoutpos = optc1_get_crtc_scanoutpos,
++ .set_early_control = optc1_set_early_control,
++ /* used by enable_timing_synchronization. Not need for FPGA */
++ .wait_for_state = optc1_wait_for_state,
++ .set_blank = optc1_set_blank,
++ .is_blanked = optc1_is_blanked,
++ .set_blank_color = optc1_program_blank_color,
++ .did_triggered_reset_occur = optc1_did_triggered_reset_occur,
++ .enable_reset_trigger = optc1_enable_reset_trigger,
++ .enable_crtc_reset = optc1_enable_crtc_reset,
++ .disable_reset_trigger = optc1_disable_reset_trigger,
++ .lock = optc1_lock,
++ .unlock = optc1_unlock,
++ .enable_optc_clock = optc1_enable_optc_clock,
++ .set_drr = optc1_set_drr,
++ .set_static_screen_control = optc1_set_static_screen_control,
++ .set_test_pattern = optc1_set_test_pattern,
++ .program_stereo = optc1_program_stereo,
++ .is_stereo_left_eye = optc1_is_stereo_left_eye,
++ .set_blank_data_double_buffer = optc1_set_blank_data_double_buffer,
++ .tg_init = optc1_tg_init,
++ .is_tg_enabled = optc1_is_tg_enabled,
++ .is_optc_underflow_occurred = optc1_is_optc_underflow_occurred,
++ .clear_optc_underflow = optc1_clear_optc_underflow,
++};
++
++void dcn10_timing_generator_init(struct optc *optc1)
++{
++ optc1->base.funcs = &dcn10_tg_funcs;
++
++ optc1->max_h_total = optc1->tg_mask->OTG_H_TOTAL + 1;
++ optc1->max_v_total = optc1->tg_mask->OTG_V_TOTAL + 1;
++
++ optc1->min_h_blank = 32;
++ optc1->min_v_blank = 3;
++ optc1->min_v_blank_interlace = 5;
++ optc1->min_h_sync_width = 8;
++ optc1->min_v_sync_width = 1;
++}
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
+new file mode 100644
+index 0000000..eec860fa
+--- /dev/null
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
+@@ -0,0 +1,490 @@
++/*
++ * 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_DCN10_H__
++#define __DC_TIMING_GENERATOR_DCN10_H__
++
++#include "timing_generator.h"
++
++#define DCN10TG_FROM_TG(tg)\
++ container_of(tg, struct optc, base)
++
++#define TG_COMMON_REG_LIST_DCN(inst) \
++ SRI(OTG_VSTARTUP_PARAM, OTG, inst),\
++ SRI(OTG_VUPDATE_PARAM, OTG, inst),\
++ SRI(OTG_VREADY_PARAM, OTG, inst),\
++ SRI(OTG_BLANK_CONTROL, OTG, inst),\
++ SRI(OTG_MASTER_UPDATE_LOCK, OTG, inst),\
++ SRI(OTG_GLOBAL_CONTROL0, OTG, inst),\
++ SRI(OTG_DOUBLE_BUFFER_CONTROL, OTG, inst),\
++ SRI(OTG_H_TOTAL, OTG, inst),\
++ SRI(OTG_H_BLANK_START_END, OTG, inst),\
++ SRI(OTG_H_SYNC_A, OTG, inst),\
++ SRI(OTG_H_SYNC_A_CNTL, OTG, inst),\
++ SRI(OTG_H_TIMING_CNTL, OTG, inst),\
++ SRI(OTG_V_TOTAL, OTG, inst),\
++ SRI(OTG_V_BLANK_START_END, OTG, inst),\
++ SRI(OTG_V_SYNC_A, OTG, inst),\
++ SRI(OTG_V_SYNC_A_CNTL, OTG, inst),\
++ SRI(OTG_INTERLACE_CONTROL, OTG, inst),\
++ SRI(OTG_CONTROL, OTG, inst),\
++ SRI(OTG_STEREO_CONTROL, OTG, inst),\
++ SRI(OTG_3D_STRUCTURE_CONTROL, OTG, inst),\
++ SRI(OTG_STEREO_STATUS, OTG, inst),\
++ SRI(OTG_V_TOTAL_MAX, OTG, inst),\
++ SRI(OTG_V_TOTAL_MIN, OTG, inst),\
++ SRI(OTG_V_TOTAL_CONTROL, OTG, inst),\
++ SRI(OTG_TRIGA_CNTL, OTG, inst),\
++ SRI(OTG_FORCE_COUNT_NOW_CNTL, OTG, inst),\
++ SRI(OTG_STATIC_SCREEN_CONTROL, OTG, inst),\
++ SRI(OTG_STATUS_FRAME_COUNT, OTG, inst),\
++ SRI(OTG_STATUS, OTG, inst),\
++ SRI(OTG_STATUS_POSITION, OTG, inst),\
++ SRI(OTG_NOM_VERT_POSITION, OTG, inst),\
++ SRI(OTG_BLACK_COLOR, OTG, inst),\
++ SRI(OTG_CLOCK_CONTROL, OTG, inst),\
++ SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\
++ SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\
++ SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\
++ SRI(OPTC_DATA_SOURCE_SELECT, ODM, inst),\
++ SRI(OPTC_INPUT_GLOBAL_CONTROL, ODM, inst),\
++ SRI(OPPBUF_CONTROL, OPPBUF, inst),\
++ SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, inst),\
++ SRI(CONTROL, VTG, inst),\
++ SRI(OTG_VERT_SYNC_CONTROL, OTG, inst),\
++ SRI(OTG_MASTER_UPDATE_MODE, OTG, inst),\
++ SRI(OTG_GSL_CONTROL, OTG, inst)
++
++#define TG_COMMON_REG_LIST_DCN1_0(inst) \
++ TG_COMMON_REG_LIST_DCN(inst),\
++ SRI(OTG_TEST_PATTERN_PARAMETERS, OTG, inst),\
++ SRI(OTG_TEST_PATTERN_CONTROL, OTG, inst),\
++ SRI(OTG_TEST_PATTERN_COLOR, OTG, inst)
++
++
++struct dcn_optc_registers {
++ uint32_t OTG_VERT_SYNC_CONTROL;
++ uint32_t OTG_MASTER_UPDATE_MODE;
++ uint32_t OTG_GSL_CONTROL;
++ uint32_t OTG_VSTARTUP_PARAM;
++ uint32_t OTG_VUPDATE_PARAM;
++ uint32_t OTG_VREADY_PARAM;
++ uint32_t OTG_BLANK_CONTROL;
++ uint32_t OTG_MASTER_UPDATE_LOCK;
++ uint32_t OTG_GLOBAL_CONTROL0;
++ uint32_t OTG_DOUBLE_BUFFER_CONTROL;
++ uint32_t OTG_H_TOTAL;
++ uint32_t OTG_H_BLANK_START_END;
++ uint32_t OTG_H_SYNC_A;
++ uint32_t OTG_H_SYNC_A_CNTL;
++ uint32_t OTG_H_TIMING_CNTL;
++ uint32_t OTG_V_TOTAL;
++ uint32_t OTG_V_BLANK_START_END;
++ uint32_t OTG_V_SYNC_A;
++ uint32_t OTG_V_SYNC_A_CNTL;
++ uint32_t OTG_INTERLACE_CONTROL;
++ uint32_t OTG_CONTROL;
++ uint32_t OTG_STEREO_CONTROL;
++ uint32_t OTG_3D_STRUCTURE_CONTROL;
++ uint32_t OTG_STEREO_STATUS;
++ uint32_t OTG_V_TOTAL_MAX;
++ uint32_t OTG_V_TOTAL_MIN;
++ uint32_t OTG_V_TOTAL_CONTROL;
++ uint32_t OTG_TRIGA_CNTL;
++ uint32_t OTG_FORCE_COUNT_NOW_CNTL;
++ uint32_t OTG_STATIC_SCREEN_CONTROL;
++ uint32_t OTG_STATUS_FRAME_COUNT;
++ uint32_t OTG_STATUS;
++ uint32_t OTG_STATUS_POSITION;
++ uint32_t OTG_NOM_VERT_POSITION;
++ uint32_t OTG_BLACK_COLOR;
++ uint32_t OTG_TEST_PATTERN_PARAMETERS;
++ uint32_t OTG_TEST_PATTERN_CONTROL;
++ uint32_t OTG_TEST_PATTERN_COLOR;
++ uint32_t OTG_CLOCK_CONTROL;
++ uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL;
++ uint32_t OTG_VERTICAL_INTERRUPT2_POSITION;
++ uint32_t OPTC_INPUT_CLOCK_CONTROL;
++ uint32_t OPTC_DATA_SOURCE_SELECT;
++ uint32_t OPTC_INPUT_GLOBAL_CONTROL;
++ uint32_t OPPBUF_CONTROL;
++ uint32_t OPPBUF_3D_PARAMETERS_0;
++ uint32_t CONTROL;
++ uint32_t OTG_GSL_WINDOW_X;
++ uint32_t OTG_GSL_WINDOW_Y;
++ uint32_t OTG_VUPDATE_KEEPOUT;
++ uint32_t OTG_DSC_START_POSITION;
++};
++
++#define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
++ SF(OTG0_OTG_VSTARTUP_PARAM, VSTARTUP_START, mask_sh),\
++ SF(OTG0_OTG_VUPDATE_PARAM, VUPDATE_OFFSET, mask_sh),\
++ SF(OTG0_OTG_VUPDATE_PARAM, VUPDATE_WIDTH, mask_sh),\
++ SF(OTG0_OTG_VREADY_PARAM, VREADY_OFFSET, mask_sh),\
++ SF(OTG0_OTG_BLANK_CONTROL, OTG_BLANK_DATA_EN, mask_sh),\
++ SF(OTG0_OTG_BLANK_CONTROL, OTG_BLANK_DE_MODE, mask_sh),\
++ SF(OTG0_OTG_BLANK_CONTROL, OTG_CURRENT_BLANK_STATE, mask_sh),\
++ SF(OTG0_OTG_MASTER_UPDATE_LOCK, OTG_MASTER_UPDATE_LOCK, mask_sh),\
++ SF(OTG0_OTG_MASTER_UPDATE_LOCK, UPDATE_LOCK_STATUS, mask_sh),\
++ SF(OTG0_OTG_GLOBAL_CONTROL0, OTG_MASTER_UPDATE_LOCK_SEL, mask_sh),\
++ SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_UPDATE_PENDING, mask_sh),\
++ SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_BLANK_DATA_DOUBLE_BUFFER_EN, mask_sh),\
++ SF(OTG0_OTG_H_TOTAL, OTG_H_TOTAL, mask_sh),\
++ SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_START, mask_sh),\
++ SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_END, mask_sh),\
++ SF(OTG0_OTG_H_SYNC_A, OTG_H_SYNC_A_START, mask_sh),\
++ SF(OTG0_OTG_H_SYNC_A, OTG_H_SYNC_A_END, mask_sh),\
++ SF(OTG0_OTG_H_SYNC_A_CNTL, OTG_H_SYNC_A_POL, mask_sh),\
++ SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_BY2, mask_sh),\
++ SF(OTG0_OTG_V_TOTAL, OTG_V_TOTAL, mask_sh),\
++ SF(OTG0_OTG_V_BLANK_START_END, OTG_V_BLANK_START, mask_sh),\
++ SF(OTG0_OTG_V_BLANK_START_END, OTG_V_BLANK_END, mask_sh),\
++ SF(OTG0_OTG_V_SYNC_A, OTG_V_SYNC_A_START, mask_sh),\
++ SF(OTG0_OTG_V_SYNC_A, OTG_V_SYNC_A_END, mask_sh),\
++ SF(OTG0_OTG_V_SYNC_A_CNTL, OTG_V_SYNC_A_POL, mask_sh),\
++ SF(OTG0_OTG_INTERLACE_CONTROL, OTG_INTERLACE_ENABLE, mask_sh),\
++ SF(OTG0_OTG_CONTROL, OTG_MASTER_EN, mask_sh),\
++ SF(OTG0_OTG_CONTROL, OTG_START_POINT_CNTL, mask_sh),\
++ SF(OTG0_OTG_CONTROL, OTG_DISABLE_POINT_CNTL, mask_sh),\
++ SF(OTG0_OTG_CONTROL, OTG_FIELD_NUMBER_CNTL, mask_sh),\
++ SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_EN, mask_sh),\
++ SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_SYNC_OUTPUT_LINE_NUM, mask_sh),\
++ SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_SYNC_OUTPUT_POLARITY, mask_sh),\
++ SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_EYE_FLAG_POLARITY, mask_sh),\
++ SF(OTG0_OTG_STEREO_CONTROL, OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, mask_sh),\
++ SF(OTG0_OTG_STEREO_CONTROL, OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, mask_sh),\
++ SF(OTG0_OTG_STEREO_STATUS, OTG_STEREO_CURRENT_EYE, mask_sh),\
++ SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_EN, mask_sh),\
++ SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_V_UPDATE_MODE, mask_sh),\
++ SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_STEREO_SEL_OVR, mask_sh),\
++ SF(OTG0_OTG_V_TOTAL_MAX, OTG_V_TOTAL_MAX, mask_sh),\
++ SF(OTG0_OTG_V_TOTAL_MIN, OTG_V_TOTAL_MIN, mask_sh),\
++ SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_V_TOTAL_MIN_SEL, mask_sh),\
++ SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_V_TOTAL_MAX_SEL, mask_sh),\
++ SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_FORCE_LOCK_ON_EVENT, mask_sh),\
++ SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_SET_V_TOTAL_MIN_MASK_EN, mask_sh),\
++ SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_SET_V_TOTAL_MIN_MASK, mask_sh),\
++ SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_CLEAR, mask_sh),\
++ SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_MODE, mask_sh),\
++ SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_OCCURRED, mask_sh),\
++ SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_SOURCE_SELECT, mask_sh),\
++ SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_SOURCE_PIPE_SELECT, mask_sh),\
++ SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_RISING_EDGE_DETECT_CNTL, mask_sh),\
++ SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, mask_sh),\
++ SF(OTG0_OTG_STATIC_SCREEN_CONTROL, OTG_STATIC_SCREEN_EVENT_MASK, mask_sh),\
++ SF(OTG0_OTG_STATIC_SCREEN_CONTROL, OTG_STATIC_SCREEN_FRAME_COUNT, mask_sh),\
++ SF(OTG0_OTG_STATUS_FRAME_COUNT, OTG_FRAME_COUNT, mask_sh),\
++ SF(OTG0_OTG_STATUS, OTG_V_BLANK, mask_sh),\
++ SF(OTG0_OTG_STATUS, OTG_V_ACTIVE_DISP, mask_sh),\
++ SF(OTG0_OTG_STATUS_POSITION, OTG_HORZ_COUNT, mask_sh),\
++ SF(OTG0_OTG_STATUS_POSITION, OTG_VERT_COUNT, mask_sh),\
++ SF(OTG0_OTG_NOM_VERT_POSITION, OTG_VERT_COUNT_NOM, mask_sh),\
++ SF(OTG0_OTG_BLACK_COLOR, OTG_BLACK_COLOR_B_CB, mask_sh),\
++ SF(OTG0_OTG_BLACK_COLOR, OTG_BLACK_COLOR_G_Y, mask_sh),\
++ SF(OTG0_OTG_BLACK_COLOR, OTG_BLACK_COLOR_R_CR, mask_sh),\
++ SF(OTG0_OTG_CLOCK_CONTROL, OTG_BUSY, mask_sh),\
++ SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\
++ SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\
++ SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, mask_sh),\
++ SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\
++ SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\
++ SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\
++ SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_ON, mask_sh),\
++ SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_GATE_DIS, mask_sh),\
++ SF(ODM0_OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_OCCURRED_STATUS, mask_sh),\
++ SF(ODM0_OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, mask_sh),\
++ SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, mask_sh),\
++ SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE1_SIZE, mask_sh),\
++ SF(VTG0_CONTROL, VTG0_ENABLE, mask_sh),\
++ SF(VTG0_CONTROL, VTG0_FP2, mask_sh),\
++ SF(VTG0_CONTROL, VTG0_VCOUNT_INIT, mask_sh),\
++ SF(OTG0_OTG_VERT_SYNC_CONTROL, OTG_FORCE_VSYNC_NEXT_LINE_OCCURRED, mask_sh),\
++ SF(OTG0_OTG_VERT_SYNC_CONTROL, OTG_FORCE_VSYNC_NEXT_LINE_CLEAR, mask_sh),\
++ SF(OTG0_OTG_VERT_SYNC_CONTROL, OTG_AUTO_FORCE_VSYNC_MODE, mask_sh),\
++ SF(OTG0_OTG_MASTER_UPDATE_MODE, MASTER_UPDATE_INTERLACED_MODE, mask_sh),\
++ SF(OTG0_OTG_GSL_CONTROL, OTG_GSL0_EN, mask_sh),\
++ SF(OTG0_OTG_GSL_CONTROL, OTG_GSL1_EN, mask_sh),\
++ SF(OTG0_OTG_GSL_CONTROL, OTG_GSL2_EN, mask_sh),\
++ SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_MASTER_EN, mask_sh),\
++ SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_FORCE_DELAY, mask_sh),\
++ SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh)
++
++
++#define TG_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
++ TG_COMMON_MASK_SH_LIST_DCN(mask_sh),\
++ SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_INC0, mask_sh),\
++ SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_INC1, mask_sh),\
++ SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_VRES, mask_sh),\
++ SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_HRES, mask_sh),\
++ SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_RAMP0_OFFSET, mask_sh),\
++ SF(OTG0_OTG_TEST_PATTERN_CONTROL, OTG_TEST_PATTERN_EN, mask_sh),\
++ SF(OTG0_OTG_TEST_PATTERN_CONTROL, OTG_TEST_PATTERN_MODE, mask_sh),\
++ SF(OTG0_OTG_TEST_PATTERN_CONTROL, OTG_TEST_PATTERN_DYNAMIC_RANGE, mask_sh),\
++ SF(OTG0_OTG_TEST_PATTERN_CONTROL, OTG_TEST_PATTERN_COLOR_FORMAT, mask_sh),\
++ SF(OTG0_OTG_TEST_PATTERN_COLOR, OTG_TEST_PATTERN_MASK, mask_sh),\
++ SF(OTG0_OTG_TEST_PATTERN_COLOR, OTG_TEST_PATTERN_DATA, mask_sh),\
++ SF(ODM0_OPTC_DATA_SOURCE_SELECT, OPTC_SRC_SEL, mask_sh)
++
++#define TG_REG_FIELD_LIST(type) \
++ type VSTARTUP_START;\
++ type VUPDATE_OFFSET;\
++ type VUPDATE_WIDTH;\
++ type VREADY_OFFSET;\
++ type OTG_BLANK_DATA_EN;\
++ type OTG_BLANK_DE_MODE;\
++ type OTG_CURRENT_BLANK_STATE;\
++ type OTG_MASTER_UPDATE_LOCK;\
++ type UPDATE_LOCK_STATUS;\
++ type OTG_UPDATE_PENDING;\
++ type OTG_MASTER_UPDATE_LOCK_SEL;\
++ type OTG_BLANK_DATA_DOUBLE_BUFFER_EN;\
++ type OTG_H_TOTAL;\
++ type OTG_H_BLANK_START;\
++ type OTG_H_BLANK_END;\
++ type OTG_H_SYNC_A_START;\
++ type OTG_H_SYNC_A_END;\
++ type OTG_H_SYNC_A_POL;\
++ type OTG_H_TIMING_DIV_BY2;\
++ type OTG_V_TOTAL;\
++ type OTG_V_BLANK_START;\
++ type OTG_V_BLANK_END;\
++ type OTG_V_SYNC_A_START;\
++ type OTG_V_SYNC_A_END;\
++ type OTG_V_SYNC_A_POL;\
++ type OTG_INTERLACE_ENABLE;\
++ type OTG_MASTER_EN;\
++ type OTG_START_POINT_CNTL;\
++ type OTG_DISABLE_POINT_CNTL;\
++ type OTG_FIELD_NUMBER_CNTL;\
++ type OTG_STEREO_EN;\
++ type OTG_STEREO_SYNC_OUTPUT_LINE_NUM;\
++ type OTG_STEREO_SYNC_OUTPUT_POLARITY;\
++ type OTG_STEREO_EYE_FLAG_POLARITY;\
++ type OTG_STEREO_CURRENT_EYE;\
++ type OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP;\
++ type OTG_3D_STRUCTURE_EN;\
++ type OTG_3D_STRUCTURE_V_UPDATE_MODE;\
++ type OTG_3D_STRUCTURE_STEREO_SEL_OVR;\
++ type OTG_V_TOTAL_MAX;\
++ type OTG_V_TOTAL_MIN;\
++ type OTG_V_TOTAL_MIN_SEL;\
++ type OTG_V_TOTAL_MAX_SEL;\
++ type OTG_FORCE_LOCK_ON_EVENT;\
++ type OTG_SET_V_TOTAL_MIN_MASK_EN;\
++ type OTG_SET_V_TOTAL_MIN_MASK;\
++ type OTG_FORCE_COUNT_NOW_CLEAR;\
++ type OTG_FORCE_COUNT_NOW_MODE;\
++ type OTG_FORCE_COUNT_NOW_OCCURRED;\
++ type OTG_TRIGA_SOURCE_SELECT;\
++ type OTG_TRIGA_SOURCE_PIPE_SELECT;\
++ type OTG_TRIGA_RISING_EDGE_DETECT_CNTL;\
++ type OTG_TRIGA_FALLING_EDGE_DETECT_CNTL;\
++ type OTG_STATIC_SCREEN_EVENT_MASK;\
++ type OTG_STATIC_SCREEN_FRAME_COUNT;\
++ type OTG_FRAME_COUNT;\
++ type OTG_V_BLANK;\
++ type OTG_V_ACTIVE_DISP;\
++ type OTG_HORZ_COUNT;\
++ type OTG_VERT_COUNT;\
++ type OTG_VERT_COUNT_NOM;\
++ type OTG_BLACK_COLOR_B_CB;\
++ type OTG_BLACK_COLOR_G_Y;\
++ type OTG_BLACK_COLOR_R_CR;\
++ type OTG_TEST_PATTERN_INC0;\
++ type OTG_TEST_PATTERN_INC1;\
++ type OTG_TEST_PATTERN_VRES;\
++ type OTG_TEST_PATTERN_HRES;\
++ type OTG_TEST_PATTERN_RAMP0_OFFSET;\
++ type OTG_TEST_PATTERN_EN;\
++ type OTG_TEST_PATTERN_MODE;\
++ type OTG_TEST_PATTERN_DYNAMIC_RANGE;\
++ type OTG_TEST_PATTERN_COLOR_FORMAT;\
++ type OTG_TEST_PATTERN_MASK;\
++ type OTG_TEST_PATTERN_DATA;\
++ type OTG_BUSY;\
++ type OTG_CLOCK_EN;\
++ type OTG_CLOCK_ON;\
++ type OTG_CLOCK_GATE_DIS;\
++ type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\
++ type OTG_VERTICAL_INTERRUPT2_LINE_START;\
++ type OPTC_INPUT_CLK_EN;\
++ type OPTC_INPUT_CLK_ON;\
++ type OPTC_INPUT_CLK_GATE_DIS;\
++ type OPTC_SRC_SEL;\
++ type OPTC_SEG0_SRC_SEL;\
++ type OPTC_UNDERFLOW_OCCURRED_STATUS;\
++ type OPTC_UNDERFLOW_CLEAR;\
++ type OPPBUF_ACTIVE_WIDTH;\
++ type OPPBUF_3D_VACT_SPACE1_SIZE;\
++ type VTG0_ENABLE;\
++ type VTG0_FP2;\
++ type VTG0_VCOUNT_INIT;\
++ type OTG_FORCE_VSYNC_NEXT_LINE_OCCURRED;\
++ type OTG_FORCE_VSYNC_NEXT_LINE_CLEAR;\
++ type OTG_AUTO_FORCE_VSYNC_MODE;\
++ type MASTER_UPDATE_INTERLACED_MODE;\
++ type OTG_GSL0_EN;\
++ type OTG_GSL1_EN;\
++ type OTG_GSL2_EN;\
++ type OTG_GSL_MASTER_EN;\
++ type OTG_GSL_FORCE_DELAY;\
++ type OTG_GSL_CHECK_ALL_FIELDS;\
++ type OTG_GSL_WINDOW_START_X;\
++ type OTG_GSL_WINDOW_END_X;\
++ type OTG_GSL_WINDOW_START_Y;\
++ type OTG_GSL_WINDOW_END_Y;\
++ type OTG_RANGE_TIMING_DBUF_UPDATE_MODE;\
++ type OTG_GSL_MASTER_MODE;\
++ type OTG_MASTER_UPDATE_LOCK_GSL_EN;\
++ type MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET;\
++ type MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET;\
++ type OTG_DSC_START_POSITION_X;\
++ type OTG_DSC_START_POSITION_LINE_NUM;\
++ type OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN;
++
++
++struct dcn_optc_shift {
++ TG_REG_FIELD_LIST(uint8_t)
++};
++
++struct dcn_optc_mask {
++ TG_REG_FIELD_LIST(uint32_t)
++};
++
++struct optc {
++ struct timing_generator base;
++
++ const struct dcn_optc_registers *tg_regs;
++ const struct dcn_optc_shift *tg_shift;
++ const struct dcn_optc_mask *tg_mask;
++
++ enum controller_id controller_id;
++
++ uint32_t max_h_total;
++ uint32_t max_v_total;
++
++ uint32_t min_h_blank;
++
++ uint32_t min_h_sync_width;
++ uint32_t min_v_sync_width;
++ uint32_t min_v_blank;
++ uint32_t min_v_blank_interlace;
++};
++
++void dcn10_timing_generator_init(struct optc *optc);
++
++struct dcn_otg_state {
++ uint32_t v_blank_start;
++ uint32_t v_blank_end;
++ uint32_t v_sync_a_pol;
++ uint32_t v_total;
++ uint32_t v_total_max;
++ uint32_t v_total_min;
++ uint32_t v_sync_a_start;
++ uint32_t v_sync_a_end;
++ uint32_t h_blank_start;
++ uint32_t h_blank_end;
++ uint32_t h_sync_a_start;
++ uint32_t h_sync_a_end;
++ uint32_t h_sync_a_pol;
++ uint32_t h_total;
++ uint32_t underflow_occurred_status;
++ uint32_t otg_enabled;
++};
++
++void optc1_read_otg_state(struct optc *optc1,
++ struct dcn_otg_state *s);
++
++bool optc1_validate_timing(
++ struct timing_generator *optc,
++ const struct dc_crtc_timing *timing);
++
++void optc1_program_timing(
++ struct timing_generator *optc,
++ const struct dc_crtc_timing *dc_crtc_timing,
++ bool use_vbios);
++
++void optc1_program_global_sync(
++ struct timing_generator *optc);
++
++bool optc1_disable_crtc(struct timing_generator *optc);
++
++bool optc1_is_counter_moving(struct timing_generator *optc);
++
++void optc1_get_position(struct timing_generator *optc,
++ struct crtc_position *position);
++
++uint32_t optc1_get_vblank_counter(struct timing_generator *optc);
++
++void optc1_get_crtc_scanoutpos(
++ struct timing_generator *optc,
++ uint32_t *v_blank_start,
++ uint32_t *v_blank_end,
++ uint32_t *h_position,
++ uint32_t *v_position);
++
++void optc1_set_early_control(
++ struct timing_generator *optc,
++ uint32_t early_cntl);
++
++void optc1_wait_for_state(struct timing_generator *optc,
++ enum crtc_state state);
++
++void optc1_set_blank(struct timing_generator *optc,
++ bool enable_blanking);
++
++bool optc1_is_blanked(struct timing_generator *optc);
++
++void optc1_program_blank_color(
++ struct timing_generator *optc,
++ const struct tg_color *black_color);
++
++bool optc1_did_triggered_reset_occur(
++ struct timing_generator *optc);
++
++void optc1_enable_reset_trigger(struct timing_generator *optc, int source_tg_inst);
++
++void optc1_disable_reset_trigger(struct timing_generator *optc);
++
++void optc1_lock(struct timing_generator *optc);
++
++void optc1_unlock(struct timing_generator *optc);
++
++void optc1_enable_optc_clock(struct timing_generator *optc, bool enable);
++
++void optc1_set_drr(
++ struct timing_generator *optc,
++ const struct drr_params *params);
++
++void optc1_set_static_screen_control(
++ struct timing_generator *optc,
++ uint32_t value);
++
++void optc1_program_stereo(struct timing_generator *optc,
++ const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags);
++
++bool optc1_is_stereo_left_eye(struct timing_generator *optc);
++
++#endif /* __DC_TIMING_GENERATOR_DCN10_H__ */
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+index 65ce96b..44825e2 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+@@ -34,7 +34,7 @@
+ #include "dcn10/dcn10_mpc.h"
+ #include "irq/dcn10/irq_service_dcn10.h"
+ #include "dcn10/dcn10_dpp.h"
+-#include "dcn10/dcn10_timing_generator.h"
++#include "dcn10_optc.h"
+ #include "dcn10/dcn10_hw_sequencer.h"
+ #include "dce110/dce110_hw_sequencer.h"
+ #include "dcn10/dcn10_opp.h"
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
+deleted file mode 100644
+index f73752c..0000000
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
++++ /dev/null
+@@ -1,1279 +0,0 @@
+-/*
+- * Copyright 2012-15 Advanced Micro Devices, Inc.
+- *
+- * Permission is hereby granted, free of charge, to any person obtaining a
+- * copy of this software and associated documentation files (the "Software"),
+- * to deal in the Software without restriction, including without limitation
+- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+- * and/or sell copies of the Software, and to permit persons to whom the
+- * Software is furnished to do so, subject to the following conditions:
+- *
+- * The above copyright notice and this permission notice shall be included in
+- * all copies or substantial portions of the Software.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+- * OTHER DEALINGS IN THE SOFTWARE.
+- *
+- * Authors: AMD
+- *
+- */
+-
+-#include "reg_helper.h"
+-#include "dcn10_timing_generator.h"
+-#include "dc.h"
+-
+-#define REG(reg)\
+- optc1->tg_regs->reg
+-
+-#define CTX \
+- optc1->base.ctx
+-
+-#undef FN
+-#define FN(reg_name, field_name) \
+- optc1->tg_shift->field_name, optc1->tg_mask->field_name
+-
+-#define STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN 0x100
+-
+-/**
+-* apply_front_porch_workaround TODO FPGA still need?
+-*
+-* This is a workaround for a bug that has existed since R5xx and has not been
+-* fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive.
+-*/
+-static void optc1_apply_front_porch_workaround(
+- struct timing_generator *optc,
+- struct dc_crtc_timing *timing)
+-{
+- if (timing->flags.INTERLACE == 1) {
+- if (timing->v_front_porch < 2)
+- timing->v_front_porch = 2;
+- } else {
+- if (timing->v_front_porch < 1)
+- timing->v_front_porch = 1;
+- }
+-}
+-
+-void optc1_program_global_sync(
+- struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- if (optc->dlg_otg_param.vstartup_start == 0) {
+- BREAK_TO_DEBUGGER();
+- return;
+- }
+-
+- REG_SET(OTG_VSTARTUP_PARAM, 0,
+- VSTARTUP_START, optc->dlg_otg_param.vstartup_start);
+-
+- REG_SET_2(OTG_VUPDATE_PARAM, 0,
+- VUPDATE_OFFSET, optc->dlg_otg_param.vupdate_offset,
+- VUPDATE_WIDTH, optc->dlg_otg_param.vupdate_width);
+-
+- REG_SET(OTG_VREADY_PARAM, 0,
+- VREADY_OFFSET, optc->dlg_otg_param.vready_offset);
+-}
+-
+-static void optc1_disable_stereo(struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- REG_SET(OTG_STEREO_CONTROL, 0,
+- OTG_STEREO_EN, 0);
+-
+- REG_SET_3(OTG_3D_STRUCTURE_CONTROL, 0,
+- OTG_3D_STRUCTURE_EN, 0,
+- OTG_3D_STRUCTURE_V_UPDATE_MODE, 0,
+- OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0);
+-
+- REG_UPDATE(OPPBUF_CONTROL,
+- OPPBUF_ACTIVE_WIDTH, 0);
+- REG_UPDATE(OPPBUF_3D_PARAMETERS_0,
+- OPPBUF_3D_VACT_SPACE1_SIZE, 0);
+-}
+-
+-/**
+- * program_timing_generator used by mode timing set
+- * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition.
+- * Including SYNC. Call BIOS command table to program Timings.
+- */
+-void optc1_program_timing(
+- struct timing_generator *optc,
+- const struct dc_crtc_timing *dc_crtc_timing,
+- bool use_vbios)
+-{
+- struct dc_crtc_timing patched_crtc_timing;
+- uint32_t vesa_sync_start;
+- uint32_t asic_blank_end;
+- uint32_t asic_blank_start;
+- uint32_t v_total;
+- uint32_t v_sync_end;
+- uint32_t v_init, v_fp2;
+- uint32_t h_sync_polarity, v_sync_polarity;
+- uint32_t interlace_factor;
+- uint32_t start_point = 0;
+- uint32_t field_num = 0;
+- uint32_t h_div_2;
+- int32_t vertical_line_start;
+-
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- patched_crtc_timing = *dc_crtc_timing;
+- optc1_apply_front_porch_workaround(optc, &patched_crtc_timing);
+-
+- /* Load horizontal timing */
+-
+- /* CRTC_H_TOTAL = vesa.h_total - 1 */
+- REG_SET(OTG_H_TOTAL, 0,
+- OTG_H_TOTAL, patched_crtc_timing.h_total - 1);
+-
+- /* h_sync_start = 0, h_sync_end = vesa.h_sync_width */
+- REG_UPDATE_2(OTG_H_SYNC_A,
+- OTG_H_SYNC_A_START, 0,
+- OTG_H_SYNC_A_END, patched_crtc_timing.h_sync_width);
+-
+- /* asic_h_blank_end = HsyncWidth + HbackPorch =
+- * vesa. usHorizontalTotal - vesa. usHorizontalSyncStart -
+- * vesa.h_left_border
+- */
+- vesa_sync_start = patched_crtc_timing.h_addressable +
+- patched_crtc_timing.h_border_right +
+- patched_crtc_timing.h_front_porch;
+-
+- asic_blank_end = patched_crtc_timing.h_total -
+- vesa_sync_start -
+- patched_crtc_timing.h_border_left;
+-
+- /* h_blank_start = v_blank_end + v_active */
+- asic_blank_start = asic_blank_end +
+- patched_crtc_timing.h_border_left +
+- patched_crtc_timing.h_addressable +
+- patched_crtc_timing.h_border_right;
+-
+- REG_UPDATE_2(OTG_H_BLANK_START_END,
+- OTG_H_BLANK_START, asic_blank_start,
+- OTG_H_BLANK_END, asic_blank_end);
+-
+- /* h_sync polarity */
+- h_sync_polarity = patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY ?
+- 0 : 1;
+-
+- REG_UPDATE(OTG_H_SYNC_A_CNTL,
+- OTG_H_SYNC_A_POL, h_sync_polarity);
+-
+- /* Load vertical timing */
+-
+- /* CRTC_V_TOTAL = v_total - 1 */
+- if (patched_crtc_timing.flags.INTERLACE) {
+- interlace_factor = 2;
+- v_total = 2 * patched_crtc_timing.v_total;
+- } else {
+- interlace_factor = 1;
+- v_total = patched_crtc_timing.v_total - 1;
+- }
+- REG_SET(OTG_V_TOTAL, 0,
+- OTG_V_TOTAL, v_total);
+-
+- /* In case of V_TOTAL_CONTROL is on, make sure OTG_V_TOTAL_MAX and
+- * OTG_V_TOTAL_MIN are equal to V_TOTAL.
+- */
+- REG_SET(OTG_V_TOTAL_MAX, 0,
+- OTG_V_TOTAL_MAX, v_total);
+- REG_SET(OTG_V_TOTAL_MIN, 0,
+- OTG_V_TOTAL_MIN, v_total);
+-
+- /* v_sync_start = 0, v_sync_end = v_sync_width */
+- v_sync_end = patched_crtc_timing.v_sync_width * interlace_factor;
+-
+- REG_UPDATE_2(OTG_V_SYNC_A,
+- OTG_V_SYNC_A_START, 0,
+- OTG_V_SYNC_A_END, v_sync_end);
+-
+- vesa_sync_start = patched_crtc_timing.v_addressable +
+- patched_crtc_timing.v_border_bottom +
+- patched_crtc_timing.v_front_porch;
+-
+- asic_blank_end = (patched_crtc_timing.v_total -
+- vesa_sync_start -
+- patched_crtc_timing.v_border_top)
+- * interlace_factor;
+-
+- /* v_blank_start = v_blank_end + v_active */
+- asic_blank_start = asic_blank_end +
+- (patched_crtc_timing.v_border_top +
+- patched_crtc_timing.v_addressable +
+- patched_crtc_timing.v_border_bottom)
+- * interlace_factor;
+-
+- REG_UPDATE_2(OTG_V_BLANK_START_END,
+- OTG_V_BLANK_START, asic_blank_start,
+- OTG_V_BLANK_END, asic_blank_end);
+-
+- /* Use OTG_VERTICAL_INTERRUPT2 replace VUPDATE interrupt,
+- * program the reg for interrupt postition.
+- */
+- vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1;
+- if (vertical_line_start < 0) {
+- ASSERT(0);
+- vertical_line_start = 0;
+- }
+- REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0,
+- OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start);
+-
+- /* v_sync polarity */
+- v_sync_polarity = patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ?
+- 0 : 1;
+-
+- REG_UPDATE(OTG_V_SYNC_A_CNTL,
+- OTG_V_SYNC_A_POL, v_sync_polarity);
+-
+- v_init = asic_blank_start;
+- if (optc->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT ||
+- optc->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
+- optc->dlg_otg_param.signal == SIGNAL_TYPE_EDP) {
+- start_point = 1;
+- if (patched_crtc_timing.flags.INTERLACE == 1)
+- field_num = 1;
+- }
+- v_fp2 = 0;
+- if (optc->dlg_otg_param.vstartup_start > asic_blank_end)
+- v_fp2 = optc->dlg_otg_param.vstartup_start > asic_blank_end;
+-
+- /* Interlace */
+- if (patched_crtc_timing.flags.INTERLACE == 1) {
+- REG_UPDATE(OTG_INTERLACE_CONTROL,
+- OTG_INTERLACE_ENABLE, 1);
+- v_init = v_init / 2;
+- if ((optc->dlg_otg_param.vstartup_start/2)*2 > asic_blank_end)
+- v_fp2 = v_fp2 / 2;
+- }
+- else
+- REG_UPDATE(OTG_INTERLACE_CONTROL,
+- OTG_INTERLACE_ENABLE, 0);
+-
+-
+- /* VTG enable set to 0 first VInit */
+- REG_UPDATE(CONTROL,
+- VTG0_ENABLE, 0);
+-
+- REG_UPDATE_2(CONTROL,
+- VTG0_FP2, v_fp2,
+- VTG0_VCOUNT_INIT, v_init);
+-
+- /* original code is using VTG offset to address OTG reg, seems wrong */
+- REG_UPDATE_2(OTG_CONTROL,
+- OTG_START_POINT_CNTL, start_point,
+- OTG_FIELD_NUMBER_CNTL, field_num);
+-
+- optc1_program_global_sync(optc);
+-
+- /* TODO
+- * patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1
+- * program_horz_count_by_2
+- * for DVI 30bpp mode, 0 otherwise
+- * program_horz_count_by_2(optc, &patched_crtc_timing);
+- */
+-
+- /* Enable stereo - only when we need to pack 3D frame. Other types
+- * of stereo handled in explicit call
+- */
+- h_div_2 = (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ?
+- 1 : 0;
+-
+- REG_UPDATE(OTG_H_TIMING_CNTL,
+- OTG_H_TIMING_DIV_BY2, h_div_2);
+-
+-}
+-
+-static void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- uint32_t blank_data_double_buffer_enable = enable ? 1 : 0;
+-
+- REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
+- OTG_BLANK_DATA_DOUBLE_BUFFER_EN, blank_data_double_buffer_enable);
+-}
+-
+-/**
+- * unblank_crtc
+- * Call ASIC Control Object to UnBlank CRTC.
+- */
+-static void optc1_unblank_crtc(struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+- uint32_t vertical_interrupt_enable = 0;
+-
+- REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL,
+- OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &vertical_interrupt_enable);
+-
+- /* temporary work around for vertical interrupt, once vertical interrupt enabled,
+- * this check will be removed.
+- */
+- if (vertical_interrupt_enable)
+- optc1_set_blank_data_double_buffer(optc, true);
+-
+- REG_UPDATE_2(OTG_BLANK_CONTROL,
+- OTG_BLANK_DATA_EN, 0,
+- OTG_BLANK_DE_MODE, 0);
+-}
+-
+-/**
+- * blank_crtc
+- * Call ASIC Control Object to Blank CRTC.
+- */
+-
+-static void optc1_blank_crtc(struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- REG_UPDATE_2(OTG_BLANK_CONTROL,
+- OTG_BLANK_DATA_EN, 1,
+- OTG_BLANK_DE_MODE, 0);
+-
+- optc1_set_blank_data_double_buffer(optc, false);
+-}
+-
+-void optc1_set_blank(struct timing_generator *optc,
+- bool enable_blanking)
+-{
+- if (enable_blanking)
+- optc1_blank_crtc(optc);
+- else
+- optc1_unblank_crtc(optc);
+-}
+-
+-bool optc1_is_blanked(struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+- uint32_t blank_en;
+- uint32_t blank_state;
+-
+- REG_GET_2(OTG_BLANK_CONTROL,
+- OTG_BLANK_DATA_EN, &blank_en,
+- OTG_CURRENT_BLANK_STATE, &blank_state);
+-
+- return blank_en && blank_state;
+-}
+-
+-void optc1_enable_optc_clock(struct timing_generator *optc, bool enable)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- if (enable) {
+- REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
+- OPTC_INPUT_CLK_EN, 1,
+- OPTC_INPUT_CLK_GATE_DIS, 1);
+-
+- REG_WAIT(OPTC_INPUT_CLOCK_CONTROL,
+- OPTC_INPUT_CLK_ON, 1,
+- 1, 1000);
+-
+- /* Enable clock */
+- REG_UPDATE_2(OTG_CLOCK_CONTROL,
+- OTG_CLOCK_EN, 1,
+- OTG_CLOCK_GATE_DIS, 1);
+- REG_WAIT(OTG_CLOCK_CONTROL,
+- OTG_CLOCK_ON, 1,
+- 1, 1000);
+- } else {
+- REG_UPDATE_2(OTG_CLOCK_CONTROL,
+- OTG_CLOCK_GATE_DIS, 0,
+- OTG_CLOCK_EN, 0);
+-
+- REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
+- OPTC_INPUT_CLK_GATE_DIS, 0,
+- OPTC_INPUT_CLK_EN, 0);
+- }
+-}
+-
+-/**
+- * Enable CRTC
+- * Enable CRTC - call ASIC Control Object to enable Timing generator.
+- */
+-static bool optc1_enable_crtc(struct timing_generator *optc)
+-{
+- /* TODO FPGA wait for answer
+- * OTG_MASTER_UPDATE_MODE != CRTC_MASTER_UPDATE_MODE
+- * OTG_MASTER_UPDATE_LOCK != CRTC_MASTER_UPDATE_LOCK
+- */
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- /* opp instance for OTG. For DCN1.0, ODM is remoed.
+- * OPP and OPTC should 1:1 mapping
+- */
+- REG_UPDATE(OPTC_DATA_SOURCE_SELECT,
+- OPTC_SRC_SEL, optc->inst);
+-
+- /* VTG enable first is for HW workaround */
+- REG_UPDATE(CONTROL,
+- VTG0_ENABLE, 1);
+-
+- /* Enable CRTC */
+- REG_UPDATE_2(OTG_CONTROL,
+- OTG_DISABLE_POINT_CNTL, 3,
+- OTG_MASTER_EN, 1);
+-
+- return true;
+-}
+-
+-/* disable_crtc - call ASIC Control Object to disable Timing generator. */
+-bool optc1_disable_crtc(struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- /* disable otg request until end of the first line
+- * in the vertical blank region
+- */
+- REG_UPDATE_2(OTG_CONTROL,
+- OTG_DISABLE_POINT_CNTL, 3,
+- OTG_MASTER_EN, 0);
+-
+- REG_UPDATE(CONTROL,
+- VTG0_ENABLE, 0);
+-
+- /* CRTC disabled, so disable clock. */
+- REG_WAIT(OTG_CLOCK_CONTROL,
+- OTG_BUSY, 0,
+- 1, 100000);
+-
+- return true;
+-}
+-
+-
+-void optc1_program_blank_color(
+- struct timing_generator *optc,
+- const struct tg_color *black_color)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- REG_SET_3(OTG_BLACK_COLOR, 0,
+- OTG_BLACK_COLOR_B_CB, black_color->color_b_cb,
+- OTG_BLACK_COLOR_G_Y, black_color->color_g_y,
+- OTG_BLACK_COLOR_R_CR, black_color->color_r_cr);
+-}
+-
+-bool optc1_validate_timing(
+- struct timing_generator *optc,
+- const struct dc_crtc_timing *timing)
+-{
+- uint32_t interlace_factor;
+- uint32_t v_blank;
+- uint32_t h_blank;
+- uint32_t min_v_blank;
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- ASSERT(timing != NULL);
+-
+- interlace_factor = timing->flags.INTERLACE ? 2 : 1;
+- v_blank = (timing->v_total - timing->v_addressable -
+- timing->v_border_top - timing->v_border_bottom) *
+- interlace_factor;
+-
+- h_blank = (timing->h_total - timing->h_addressable -
+- timing->h_border_right -
+- timing->h_border_left);
+-
+- if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE &&
+- timing->timing_3d_format != TIMING_3D_FORMAT_HW_FRAME_PACKING &&
+- timing->timing_3d_format != TIMING_3D_FORMAT_TOP_AND_BOTTOM &&
+- timing->timing_3d_format != TIMING_3D_FORMAT_SIDE_BY_SIDE &&
+- timing->timing_3d_format != TIMING_3D_FORMAT_FRAME_ALTERNATE &&
+- timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA)
+- return false;
+-
+- /* Temporarily blocking interlacing mode until it's supported */
+- if (timing->flags.INTERLACE == 1)
+- return false;
+-
+- /* Check maximum number of pixels supported by Timing Generator
+- * (Currently will never fail, in order to fail needs display which
+- * needs more than 8192 horizontal and
+- * more than 8192 vertical total pixels)
+- */
+- if (timing->h_total > optc1->max_h_total ||
+- timing->v_total > optc1->max_v_total)
+- return false;
+-
+-
+- if (h_blank < optc1->min_h_blank)
+- return false;
+-
+- if (timing->h_sync_width < optc1->min_h_sync_width ||
+- timing->v_sync_width < optc1->min_v_sync_width)
+- return false;
+-
+- min_v_blank = timing->flags.INTERLACE?optc1->min_v_blank_interlace:optc1->min_v_blank;
+-
+- if (v_blank < min_v_blank)
+- return false;
+-
+- return true;
+-
+-}
+-
+-/*
+- * get_vblank_counter
+- *
+- * @brief
+- * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which
+- * holds the counter of frames.
+- *
+- * @param
+- * struct timing_generator *optc - [in] timing generator which controls the
+- * desired CRTC
+- *
+- * @return
+- * Counter of frames, which should equal to number of vblanks.
+- */
+-uint32_t optc1_get_vblank_counter(struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+- uint32_t frame_count;
+-
+- REG_GET(OTG_STATUS_FRAME_COUNT,
+- OTG_FRAME_COUNT, &frame_count);
+-
+- return frame_count;
+-}
+-
+-void optc1_lock(struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- REG_SET(OTG_GLOBAL_CONTROL0, 0,
+- OTG_MASTER_UPDATE_LOCK_SEL, optc->inst);
+- REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
+- OTG_MASTER_UPDATE_LOCK, 1);
+-
+- /* Should be fast, status does not update on maximus */
+- if (optc->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
+- REG_WAIT(OTG_MASTER_UPDATE_LOCK,
+- UPDATE_LOCK_STATUS, 1,
+- 1, 10);
+-}
+-
+-void optc1_unlock(struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
+- OTG_MASTER_UPDATE_LOCK, 0);
+-}
+-
+-void optc1_get_position(struct timing_generator *optc,
+- struct crtc_position *position)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- REG_GET_2(OTG_STATUS_POSITION,
+- OTG_HORZ_COUNT, &position->horizontal_count,
+- OTG_VERT_COUNT, &position->vertical_count);
+-
+- REG_GET(OTG_NOM_VERT_POSITION,
+- OTG_VERT_COUNT_NOM, &position->nominal_vcount);
+-}
+-
+-bool optc1_is_counter_moving(struct timing_generator *optc)
+-{
+- struct crtc_position position1, position2;
+-
+- optc->funcs->get_position(optc, &position1);
+- optc->funcs->get_position(optc, &position2);
+-
+- if (position1.horizontal_count == position2.horizontal_count &&
+- position1.vertical_count == position2.vertical_count)
+- return false;
+- else
+- return true;
+-}
+-
+-bool optc1_did_triggered_reset_occur(
+- struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+- uint32_t occurred_force, occurred_vsync;
+-
+- REG_GET(OTG_FORCE_COUNT_NOW_CNTL,
+- OTG_FORCE_COUNT_NOW_OCCURRED, &occurred_force);
+-
+- REG_GET(OTG_VERT_SYNC_CONTROL,
+- OTG_FORCE_VSYNC_NEXT_LINE_OCCURRED, &occurred_vsync);
+-
+- return occurred_vsync != 0 || occurred_force != 0;
+-}
+-
+-void optc1_disable_reset_trigger(struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- REG_WRITE(OTG_TRIGA_CNTL, 0);
+-
+- REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
+- OTG_FORCE_COUNT_NOW_CLEAR, 1);
+-
+- REG_SET(OTG_VERT_SYNC_CONTROL, 0,
+- OTG_FORCE_VSYNC_NEXT_LINE_CLEAR, 1);
+-}
+-
+-void optc1_enable_reset_trigger(struct timing_generator *optc, int source_tg_inst)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+- uint32_t falling_edge;
+-
+- REG_GET(OTG_V_SYNC_A_CNTL,
+- OTG_V_SYNC_A_POL, &falling_edge);
+-
+- if (falling_edge)
+- REG_SET_3(OTG_TRIGA_CNTL, 0,
+- /* vsync signal from selected OTG pipe based
+- * on OTG_TRIG_SOURCE_PIPE_SELECT setting
+- */
+- OTG_TRIGA_SOURCE_SELECT, 20,
+- OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
+- /* always detect falling edge */
+- OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, 1);
+- else
+- REG_SET_3(OTG_TRIGA_CNTL, 0,
+- /* vsync signal from selected OTG pipe based
+- * on OTG_TRIG_SOURCE_PIPE_SELECT setting
+- */
+- OTG_TRIGA_SOURCE_SELECT, 20,
+- OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
+- /* always detect rising edge */
+- OTG_TRIGA_RISING_EDGE_DETECT_CNTL, 1);
+-
+- REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
+- /* force H count to H_TOTAL and V count to V_TOTAL in
+- * progressive mode and V_TOTAL-1 in interlaced mode
+- */
+- OTG_FORCE_COUNT_NOW_MODE, 2);
+-}
+-
+-void optc1_enable_crtc_reset(
+- struct timing_generator *optc,
+- int source_tg_inst,
+- struct crtc_trigger_info *crtc_tp)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+- uint32_t falling_edge = 0;
+- uint32_t rising_edge = 0;
+-
+- switch (crtc_tp->event) {
+-
+- case CRTC_EVENT_VSYNC_RISING:
+- rising_edge = 1;
+- break;
+-
+- case CRTC_EVENT_VSYNC_FALLING:
+- falling_edge = 1;
+- break;
+- }
+-
+- REG_SET_4(OTG_TRIGA_CNTL, 0,
+- /* vsync signal from selected OTG pipe based
+- * on OTG_TRIG_SOURCE_PIPE_SELECT setting
+- */
+- OTG_TRIGA_SOURCE_SELECT, 20,
+- OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
+- /* always detect falling edge */
+- OTG_TRIGA_RISING_EDGE_DETECT_CNTL, rising_edge,
+- OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, falling_edge);
+-
+- switch (crtc_tp->delay) {
+- case TRIGGER_DELAY_NEXT_LINE:
+- REG_SET(OTG_VERT_SYNC_CONTROL, 0,
+- OTG_AUTO_FORCE_VSYNC_MODE, 1);
+- break;
+- case TRIGGER_DELAY_NEXT_PIXEL:
+- REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
+- /* force H count to H_TOTAL and V count to V_TOTAL in
+- * progressive mode and V_TOTAL-1 in interlaced mode
+- */
+- OTG_FORCE_COUNT_NOW_MODE, 2);
+- break;
+- }
+-}
+-
+-void optc1_wait_for_state(struct timing_generator *optc,
+- enum crtc_state state)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- switch (state) {
+- case CRTC_STATE_VBLANK:
+- REG_WAIT(OTG_STATUS,
+- OTG_V_BLANK, 1,
+- 1, 100000); /* 1 vupdate at 10hz */
+- break;
+-
+- case CRTC_STATE_VACTIVE:
+- REG_WAIT(OTG_STATUS,
+- OTG_V_ACTIVE_DISP, 1,
+- 1, 100000); /* 1 vupdate at 10hz */
+- break;
+-
+- default:
+- break;
+- }
+-}
+-
+-void optc1_set_early_control(
+- struct timing_generator *optc,
+- uint32_t early_cntl)
+-{
+- /* asic design change, do not need this control
+- * empty for share caller logic
+- */
+-}
+-
+-
+-void optc1_set_static_screen_control(
+- struct timing_generator *optc,
+- uint32_t value)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- /* Bit 8 is no longer applicable in RV for PSR case,
+- * set bit 8 to 0 if given
+- */
+- if ((value & STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN)
+- != 0)
+- value = value &
+- ~STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN;
+-
+- REG_SET_2(OTG_STATIC_SCREEN_CONTROL, 0,
+- OTG_STATIC_SCREEN_EVENT_MASK, value,
+- OTG_STATIC_SCREEN_FRAME_COUNT, 2);
+-}
+-
+-
+-/**
+- *****************************************************************************
+- * Function: set_drr
+- *
+- * @brief
+- * Program dynamic refresh rate registers m_OTGx_OTG_V_TOTAL_*.
+- *
+- *****************************************************************************
+- */
+-void optc1_set_drr(
+- struct timing_generator *optc,
+- const struct drr_params *params)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- if (params != NULL &&
+- params->vertical_total_max > 0 &&
+- params->vertical_total_min > 0) {
+-
+- REG_SET(OTG_V_TOTAL_MAX, 0,
+- OTG_V_TOTAL_MAX, params->vertical_total_max - 1);
+-
+- REG_SET(OTG_V_TOTAL_MIN, 0,
+- OTG_V_TOTAL_MIN, params->vertical_total_min - 1);
+-
+- REG_UPDATE_5(OTG_V_TOTAL_CONTROL,
+- OTG_V_TOTAL_MIN_SEL, 1,
+- OTG_V_TOTAL_MAX_SEL, 1,
+- OTG_FORCE_LOCK_ON_EVENT, 0,
+- OTG_SET_V_TOTAL_MIN_MASK_EN, 0,
+- OTG_SET_V_TOTAL_MIN_MASK, 0);
+- } else {
+- REG_SET(OTG_V_TOTAL_MIN, 0,
+- OTG_V_TOTAL_MIN, 0);
+-
+- REG_SET(OTG_V_TOTAL_MAX, 0,
+- OTG_V_TOTAL_MAX, 0);
+-
+- REG_UPDATE_4(OTG_V_TOTAL_CONTROL,
+- OTG_SET_V_TOTAL_MIN_MASK, 0,
+- OTG_V_TOTAL_MIN_SEL, 0,
+- OTG_V_TOTAL_MAX_SEL, 0,
+- OTG_FORCE_LOCK_ON_EVENT, 0);
+- }
+-}
+-
+-static void optc1_set_test_pattern(
+- struct timing_generator *optc,
+- /* 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 optc *optc1 = DCN10TG_FROM_TG(optc);
+- enum test_pattern_color_format bit_depth;
+- enum test_pattern_dyn_range dyn_range;
+- enum test_pattern_mode mode;
+- uint32_t pattern_mask;
+- uint32_t pattern_data;
+- /* 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;
+-
+- REG_UPDATE_2(OTG_TEST_PATTERN_PARAMETERS,
+- OTG_TEST_PATTERN_VRES, 6,
+- OTG_TEST_PATTERN_HRES, 6);
+-
+- REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL,
+- OTG_TEST_PATTERN_EN, 1,
+- OTG_TEST_PATTERN_MODE, mode,
+- OTG_TEST_PATTERN_DYNAMIC_RANGE, dyn_range,
+- OTG_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);
+- }
+-
+- REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 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
+- */
+- pattern_data = 0;
+- for (index = 0; index < 6; index++) {
+- /* prepare color mask, first write PATTERN_DATA
+- * will have all zeros
+- */
+- pattern_mask = (1 << index);
+-
+- /* write color component */
+- REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
+- OTG_TEST_PATTERN_MASK, pattern_mask,
+- OTG_TEST_PATTERN_DATA, pattern_data);
+-
+- /* prepare next color component,
+- * will be written in the next iteration
+- */
+- pattern_data = dst_color[index];
+- }
+- /* write last color component,
+- * it's been already prepared in the loop
+- */
+- REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
+- OTG_TEST_PATTERN_MASK, pattern_mask,
+- OTG_TEST_PATTERN_DATA, pattern_data);
+-
+- /* enable test pattern */
+- REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL,
+- OTG_TEST_PATTERN_EN, 1,
+- OTG_TEST_PATTERN_MODE, mode,
+- OTG_TEST_PATTERN_DYNAMIC_RANGE, 0,
+- OTG_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:
+- {
+- REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
+- OTG_TEST_PATTERN_INC0, inc_base,
+- OTG_TEST_PATTERN_INC1, 0,
+- OTG_TEST_PATTERN_HRES, 6,
+- OTG_TEST_PATTERN_VRES, 6,
+- OTG_TEST_PATTERN_RAMP0_OFFSET, 0);
+- }
+- break;
+- case TEST_PATTERN_COLOR_FORMAT_BPC_8:
+- {
+- REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
+- OTG_TEST_PATTERN_INC0, inc_base,
+- OTG_TEST_PATTERN_INC1, 0,
+- OTG_TEST_PATTERN_HRES, 8,
+- OTG_TEST_PATTERN_VRES, 6,
+- OTG_TEST_PATTERN_RAMP0_OFFSET, 0);
+- }
+- break;
+- case TEST_PATTERN_COLOR_FORMAT_BPC_10:
+- {
+- REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
+- OTG_TEST_PATTERN_INC0, inc_base,
+- OTG_TEST_PATTERN_INC1, inc_base + 2,
+- OTG_TEST_PATTERN_HRES, 8,
+- OTG_TEST_PATTERN_VRES, 5,
+- OTG_TEST_PATTERN_RAMP0_OFFSET, 384 << 6);
+- }
+- break;
+- default:
+- break;
+- }
+-
+- REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
+-
+- /* enable test pattern */
+- REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
+-
+- REG_SET_4(OTG_TEST_PATTERN_CONTROL, 0,
+- OTG_TEST_PATTERN_EN, 1,
+- OTG_TEST_PATTERN_MODE, mode,
+- OTG_TEST_PATTERN_DYNAMIC_RANGE, 0,
+- OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
+- }
+- break;
+- case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
+- {
+- REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
+- REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
+- REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0);
+- }
+- break;
+- default:
+- break;
+-
+- }
+-}
+-
+-void optc1_get_crtc_scanoutpos(
+- struct timing_generator *optc,
+- uint32_t *v_blank_start,
+- uint32_t *v_blank_end,
+- uint32_t *h_position,
+- uint32_t *v_position)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+- struct crtc_position position;
+-
+- REG_GET_2(OTG_V_BLANK_START_END,
+- OTG_V_BLANK_START, v_blank_start,
+- OTG_V_BLANK_END, v_blank_end);
+-
+- optc1_get_position(optc, &position);
+-
+- *h_position = position.horizontal_count;
+- *v_position = position.vertical_count;
+-}
+-
+-
+-
+-static void optc1_enable_stereo(struct timing_generator *optc,
+- const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- uint32_t active_width = timing->h_addressable;
+- uint32_t space1_size = timing->v_total - timing->v_addressable;
+-
+- if (flags) {
+- uint32_t stereo_en;
+- stereo_en = flags->FRAME_PACKED == 0 ? 1 : 0;
+-
+- if (flags->PROGRAM_STEREO)
+- REG_UPDATE_3(OTG_STEREO_CONTROL,
+- OTG_STEREO_EN, stereo_en,
+- OTG_STEREO_SYNC_OUTPUT_LINE_NUM, 0,
+- OTG_STEREO_SYNC_OUTPUT_POLARITY, 0);
+-
+- if (flags->PROGRAM_POLARITY)
+- REG_UPDATE(OTG_STEREO_CONTROL,
+- OTG_STEREO_EYE_FLAG_POLARITY,
+- flags->RIGHT_EYE_POLARITY == 0 ? 0 : 1);
+-
+- if (flags->DISABLE_STEREO_DP_SYNC)
+- REG_UPDATE(OTG_STEREO_CONTROL,
+- OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, 1);
+-
+- if (flags->PROGRAM_STEREO)
+- REG_UPDATE_3(OTG_3D_STRUCTURE_CONTROL,
+- OTG_3D_STRUCTURE_EN, flags->FRAME_PACKED,
+- OTG_3D_STRUCTURE_V_UPDATE_MODE, flags->FRAME_PACKED,
+- OTG_3D_STRUCTURE_STEREO_SEL_OVR, flags->FRAME_PACKED);
+-
+- }
+-
+- REG_UPDATE(OPPBUF_CONTROL,
+- OPPBUF_ACTIVE_WIDTH, active_width);
+-
+- REG_UPDATE(OPPBUF_3D_PARAMETERS_0,
+- OPPBUF_3D_VACT_SPACE1_SIZE, space1_size);
+-}
+-
+-void optc1_program_stereo(struct timing_generator *optc,
+- const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
+-{
+- if (flags->PROGRAM_STEREO)
+- optc1_enable_stereo(optc, timing, flags);
+- else
+- optc1_disable_stereo(optc);
+-}
+-
+-
+-bool optc1_is_stereo_left_eye(struct timing_generator *optc)
+-{
+- bool ret = false;
+- uint32_t left_eye = 0;
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- REG_GET(OTG_STEREO_STATUS,
+- OTG_STEREO_CURRENT_EYE, &left_eye);
+- if (left_eye == 1)
+- ret = true;
+- else
+- ret = false;
+-
+- return ret;
+-}
+-
+-void optc1_read_otg_state(struct optc *optc1,
+- struct dcn_otg_state *s)
+-{
+- REG_GET(OTG_CONTROL,
+- OTG_MASTER_EN, &s->otg_enabled);
+-
+- REG_GET_2(OTG_V_BLANK_START_END,
+- OTG_V_BLANK_START, &s->v_blank_start,
+- OTG_V_BLANK_END, &s->v_blank_end);
+-
+- REG_GET(OTG_V_SYNC_A_CNTL,
+- OTG_V_SYNC_A_POL, &s->v_sync_a_pol);
+-
+- REG_GET(OTG_V_TOTAL,
+- OTG_V_TOTAL, &s->v_total);
+-
+- REG_GET(OTG_V_TOTAL_MAX,
+- OTG_V_TOTAL_MAX, &s->v_total_max);
+-
+- REG_GET(OTG_V_TOTAL_MIN,
+- OTG_V_TOTAL_MIN, &s->v_total_min);
+-
+- REG_GET_2(OTG_V_SYNC_A,
+- OTG_V_SYNC_A_START, &s->v_sync_a_start,
+- OTG_V_SYNC_A_END, &s->v_sync_a_end);
+-
+- REG_GET_2(OTG_H_BLANK_START_END,
+- OTG_H_BLANK_START, &s->h_blank_start,
+- OTG_H_BLANK_END, &s->h_blank_end);
+-
+- REG_GET_2(OTG_H_SYNC_A,
+- OTG_H_SYNC_A_START, &s->h_sync_a_start,
+- OTG_H_SYNC_A_END, &s->h_sync_a_end);
+-
+- REG_GET(OTG_H_SYNC_A_CNTL,
+- OTG_H_SYNC_A_POL, &s->h_sync_a_pol);
+-
+- REG_GET(OTG_H_TOTAL,
+- OTG_H_TOTAL, &s->h_total);
+-
+- REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
+- OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status);
+-}
+-
+-static void optc1_clear_optc_underflow(struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-
+- REG_UPDATE(OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, 1);
+-}
+-
+-static void optc1_tg_init(struct timing_generator *optc)
+-{
+- optc1_set_blank_data_double_buffer(optc, true);
+- optc1_clear_optc_underflow(optc);
+-}
+-
+-static bool optc1_is_tg_enabled(struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+- uint32_t otg_enabled = 0;
+-
+- REG_GET(OTG_CONTROL, OTG_MASTER_EN, &otg_enabled);
+-
+- return (otg_enabled != 0);
+-
+-}
+-
+-static bool optc1_is_optc_underflow_occurred(struct timing_generator *optc)
+-{
+- struct optc *optc1 = DCN10TG_FROM_TG(optc);
+- uint32_t underflow_occurred = 0;
+-
+- REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
+- OPTC_UNDERFLOW_OCCURRED_STATUS,
+- &underflow_occurred);
+-
+- return (underflow_occurred == 1);
+-}
+-
+-static const struct timing_generator_funcs dcn10_tg_funcs = {
+- .validate_timing = optc1_validate_timing,
+- .program_timing = optc1_program_timing,
+- .program_global_sync = optc1_program_global_sync,
+- .enable_crtc = optc1_enable_crtc,
+- .disable_crtc = optc1_disable_crtc,
+- /* used by enable_timing_synchronization. Not need for FPGA */
+- .is_counter_moving = optc1_is_counter_moving,
+- .get_position = optc1_get_position,
+- .get_frame_count = optc1_get_vblank_counter,
+- .get_scanoutpos = optc1_get_crtc_scanoutpos,
+- .set_early_control = optc1_set_early_control,
+- /* used by enable_timing_synchronization. Not need for FPGA */
+- .wait_for_state = optc1_wait_for_state,
+- .set_blank = optc1_set_blank,
+- .is_blanked = optc1_is_blanked,
+- .set_blank_color = optc1_program_blank_color,
+- .did_triggered_reset_occur = optc1_did_triggered_reset_occur,
+- .enable_reset_trigger = optc1_enable_reset_trigger,
+- .enable_crtc_reset = optc1_enable_crtc_reset,
+- .disable_reset_trigger = optc1_disable_reset_trigger,
+- .lock = optc1_lock,
+- .unlock = optc1_unlock,
+- .enable_optc_clock = optc1_enable_optc_clock,
+- .set_drr = optc1_set_drr,
+- .set_static_screen_control = optc1_set_static_screen_control,
+- .set_test_pattern = optc1_set_test_pattern,
+- .program_stereo = optc1_program_stereo,
+- .is_stereo_left_eye = optc1_is_stereo_left_eye,
+- .set_blank_data_double_buffer = optc1_set_blank_data_double_buffer,
+- .tg_init = optc1_tg_init,
+- .is_tg_enabled = optc1_is_tg_enabled,
+- .is_optc_underflow_occurred = optc1_is_optc_underflow_occurred,
+- .clear_optc_underflow = optc1_clear_optc_underflow,
+-};
+-
+-void dcn10_timing_generator_init(struct optc *optc1)
+-{
+- optc1->base.funcs = &dcn10_tg_funcs;
+-
+- optc1->max_h_total = optc1->tg_mask->OTG_H_TOTAL + 1;
+- optc1->max_v_total = optc1->tg_mask->OTG_V_TOTAL + 1;
+-
+- optc1->min_h_blank = 32;
+- optc1->min_v_blank = 3;
+- optc1->min_v_blank_interlace = 5;
+- optc1->min_h_sync_width = 8;
+- optc1->min_v_sync_width = 1;
+-}
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h
+deleted file mode 100644
+index eec860fa..0000000
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h
++++ /dev/null
+@@ -1,490 +0,0 @@
+-/*
+- * 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_DCN10_H__
+-#define __DC_TIMING_GENERATOR_DCN10_H__
+-
+-#include "timing_generator.h"
+-
+-#define DCN10TG_FROM_TG(tg)\
+- container_of(tg, struct optc, base)
+-
+-#define TG_COMMON_REG_LIST_DCN(inst) \
+- SRI(OTG_VSTARTUP_PARAM, OTG, inst),\
+- SRI(OTG_VUPDATE_PARAM, OTG, inst),\
+- SRI(OTG_VREADY_PARAM, OTG, inst),\
+- SRI(OTG_BLANK_CONTROL, OTG, inst),\
+- SRI(OTG_MASTER_UPDATE_LOCK, OTG, inst),\
+- SRI(OTG_GLOBAL_CONTROL0, OTG, inst),\
+- SRI(OTG_DOUBLE_BUFFER_CONTROL, OTG, inst),\
+- SRI(OTG_H_TOTAL, OTG, inst),\
+- SRI(OTG_H_BLANK_START_END, OTG, inst),\
+- SRI(OTG_H_SYNC_A, OTG, inst),\
+- SRI(OTG_H_SYNC_A_CNTL, OTG, inst),\
+- SRI(OTG_H_TIMING_CNTL, OTG, inst),\
+- SRI(OTG_V_TOTAL, OTG, inst),\
+- SRI(OTG_V_BLANK_START_END, OTG, inst),\
+- SRI(OTG_V_SYNC_A, OTG, inst),\
+- SRI(OTG_V_SYNC_A_CNTL, OTG, inst),\
+- SRI(OTG_INTERLACE_CONTROL, OTG, inst),\
+- SRI(OTG_CONTROL, OTG, inst),\
+- SRI(OTG_STEREO_CONTROL, OTG, inst),\
+- SRI(OTG_3D_STRUCTURE_CONTROL, OTG, inst),\
+- SRI(OTG_STEREO_STATUS, OTG, inst),\
+- SRI(OTG_V_TOTAL_MAX, OTG, inst),\
+- SRI(OTG_V_TOTAL_MIN, OTG, inst),\
+- SRI(OTG_V_TOTAL_CONTROL, OTG, inst),\
+- SRI(OTG_TRIGA_CNTL, OTG, inst),\
+- SRI(OTG_FORCE_COUNT_NOW_CNTL, OTG, inst),\
+- SRI(OTG_STATIC_SCREEN_CONTROL, OTG, inst),\
+- SRI(OTG_STATUS_FRAME_COUNT, OTG, inst),\
+- SRI(OTG_STATUS, OTG, inst),\
+- SRI(OTG_STATUS_POSITION, OTG, inst),\
+- SRI(OTG_NOM_VERT_POSITION, OTG, inst),\
+- SRI(OTG_BLACK_COLOR, OTG, inst),\
+- SRI(OTG_CLOCK_CONTROL, OTG, inst),\
+- SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\
+- SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\
+- SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\
+- SRI(OPTC_DATA_SOURCE_SELECT, ODM, inst),\
+- SRI(OPTC_INPUT_GLOBAL_CONTROL, ODM, inst),\
+- SRI(OPPBUF_CONTROL, OPPBUF, inst),\
+- SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, inst),\
+- SRI(CONTROL, VTG, inst),\
+- SRI(OTG_VERT_SYNC_CONTROL, OTG, inst),\
+- SRI(OTG_MASTER_UPDATE_MODE, OTG, inst),\
+- SRI(OTG_GSL_CONTROL, OTG, inst)
+-
+-#define TG_COMMON_REG_LIST_DCN1_0(inst) \
+- TG_COMMON_REG_LIST_DCN(inst),\
+- SRI(OTG_TEST_PATTERN_PARAMETERS, OTG, inst),\
+- SRI(OTG_TEST_PATTERN_CONTROL, OTG, inst),\
+- SRI(OTG_TEST_PATTERN_COLOR, OTG, inst)
+-
+-
+-struct dcn_optc_registers {
+- uint32_t OTG_VERT_SYNC_CONTROL;
+- uint32_t OTG_MASTER_UPDATE_MODE;
+- uint32_t OTG_GSL_CONTROL;
+- uint32_t OTG_VSTARTUP_PARAM;
+- uint32_t OTG_VUPDATE_PARAM;
+- uint32_t OTG_VREADY_PARAM;
+- uint32_t OTG_BLANK_CONTROL;
+- uint32_t OTG_MASTER_UPDATE_LOCK;
+- uint32_t OTG_GLOBAL_CONTROL0;
+- uint32_t OTG_DOUBLE_BUFFER_CONTROL;
+- uint32_t OTG_H_TOTAL;
+- uint32_t OTG_H_BLANK_START_END;
+- uint32_t OTG_H_SYNC_A;
+- uint32_t OTG_H_SYNC_A_CNTL;
+- uint32_t OTG_H_TIMING_CNTL;
+- uint32_t OTG_V_TOTAL;
+- uint32_t OTG_V_BLANK_START_END;
+- uint32_t OTG_V_SYNC_A;
+- uint32_t OTG_V_SYNC_A_CNTL;
+- uint32_t OTG_INTERLACE_CONTROL;
+- uint32_t OTG_CONTROL;
+- uint32_t OTG_STEREO_CONTROL;
+- uint32_t OTG_3D_STRUCTURE_CONTROL;
+- uint32_t OTG_STEREO_STATUS;
+- uint32_t OTG_V_TOTAL_MAX;
+- uint32_t OTG_V_TOTAL_MIN;
+- uint32_t OTG_V_TOTAL_CONTROL;
+- uint32_t OTG_TRIGA_CNTL;
+- uint32_t OTG_FORCE_COUNT_NOW_CNTL;
+- uint32_t OTG_STATIC_SCREEN_CONTROL;
+- uint32_t OTG_STATUS_FRAME_COUNT;
+- uint32_t OTG_STATUS;
+- uint32_t OTG_STATUS_POSITION;
+- uint32_t OTG_NOM_VERT_POSITION;
+- uint32_t OTG_BLACK_COLOR;
+- uint32_t OTG_TEST_PATTERN_PARAMETERS;
+- uint32_t OTG_TEST_PATTERN_CONTROL;
+- uint32_t OTG_TEST_PATTERN_COLOR;
+- uint32_t OTG_CLOCK_CONTROL;
+- uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL;
+- uint32_t OTG_VERTICAL_INTERRUPT2_POSITION;
+- uint32_t OPTC_INPUT_CLOCK_CONTROL;
+- uint32_t OPTC_DATA_SOURCE_SELECT;
+- uint32_t OPTC_INPUT_GLOBAL_CONTROL;
+- uint32_t OPPBUF_CONTROL;
+- uint32_t OPPBUF_3D_PARAMETERS_0;
+- uint32_t CONTROL;
+- uint32_t OTG_GSL_WINDOW_X;
+- uint32_t OTG_GSL_WINDOW_Y;
+- uint32_t OTG_VUPDATE_KEEPOUT;
+- uint32_t OTG_DSC_START_POSITION;
+-};
+-
+-#define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
+- SF(OTG0_OTG_VSTARTUP_PARAM, VSTARTUP_START, mask_sh),\
+- SF(OTG0_OTG_VUPDATE_PARAM, VUPDATE_OFFSET, mask_sh),\
+- SF(OTG0_OTG_VUPDATE_PARAM, VUPDATE_WIDTH, mask_sh),\
+- SF(OTG0_OTG_VREADY_PARAM, VREADY_OFFSET, mask_sh),\
+- SF(OTG0_OTG_BLANK_CONTROL, OTG_BLANK_DATA_EN, mask_sh),\
+- SF(OTG0_OTG_BLANK_CONTROL, OTG_BLANK_DE_MODE, mask_sh),\
+- SF(OTG0_OTG_BLANK_CONTROL, OTG_CURRENT_BLANK_STATE, mask_sh),\
+- SF(OTG0_OTG_MASTER_UPDATE_LOCK, OTG_MASTER_UPDATE_LOCK, mask_sh),\
+- SF(OTG0_OTG_MASTER_UPDATE_LOCK, UPDATE_LOCK_STATUS, mask_sh),\
+- SF(OTG0_OTG_GLOBAL_CONTROL0, OTG_MASTER_UPDATE_LOCK_SEL, mask_sh),\
+- SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_UPDATE_PENDING, mask_sh),\
+- SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_BLANK_DATA_DOUBLE_BUFFER_EN, mask_sh),\
+- SF(OTG0_OTG_H_TOTAL, OTG_H_TOTAL, mask_sh),\
+- SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_START, mask_sh),\
+- SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_END, mask_sh),\
+- SF(OTG0_OTG_H_SYNC_A, OTG_H_SYNC_A_START, mask_sh),\
+- SF(OTG0_OTG_H_SYNC_A, OTG_H_SYNC_A_END, mask_sh),\
+- SF(OTG0_OTG_H_SYNC_A_CNTL, OTG_H_SYNC_A_POL, mask_sh),\
+- SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_BY2, mask_sh),\
+- SF(OTG0_OTG_V_TOTAL, OTG_V_TOTAL, mask_sh),\
+- SF(OTG0_OTG_V_BLANK_START_END, OTG_V_BLANK_START, mask_sh),\
+- SF(OTG0_OTG_V_BLANK_START_END, OTG_V_BLANK_END, mask_sh),\
+- SF(OTG0_OTG_V_SYNC_A, OTG_V_SYNC_A_START, mask_sh),\
+- SF(OTG0_OTG_V_SYNC_A, OTG_V_SYNC_A_END, mask_sh),\
+- SF(OTG0_OTG_V_SYNC_A_CNTL, OTG_V_SYNC_A_POL, mask_sh),\
+- SF(OTG0_OTG_INTERLACE_CONTROL, OTG_INTERLACE_ENABLE, mask_sh),\
+- SF(OTG0_OTG_CONTROL, OTG_MASTER_EN, mask_sh),\
+- SF(OTG0_OTG_CONTROL, OTG_START_POINT_CNTL, mask_sh),\
+- SF(OTG0_OTG_CONTROL, OTG_DISABLE_POINT_CNTL, mask_sh),\
+- SF(OTG0_OTG_CONTROL, OTG_FIELD_NUMBER_CNTL, mask_sh),\
+- SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_EN, mask_sh),\
+- SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_SYNC_OUTPUT_LINE_NUM, mask_sh),\
+- SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_SYNC_OUTPUT_POLARITY, mask_sh),\
+- SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_EYE_FLAG_POLARITY, mask_sh),\
+- SF(OTG0_OTG_STEREO_CONTROL, OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, mask_sh),\
+- SF(OTG0_OTG_STEREO_CONTROL, OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, mask_sh),\
+- SF(OTG0_OTG_STEREO_STATUS, OTG_STEREO_CURRENT_EYE, mask_sh),\
+- SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_EN, mask_sh),\
+- SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_V_UPDATE_MODE, mask_sh),\
+- SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_STEREO_SEL_OVR, mask_sh),\
+- SF(OTG0_OTG_V_TOTAL_MAX, OTG_V_TOTAL_MAX, mask_sh),\
+- SF(OTG0_OTG_V_TOTAL_MIN, OTG_V_TOTAL_MIN, mask_sh),\
+- SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_V_TOTAL_MIN_SEL, mask_sh),\
+- SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_V_TOTAL_MAX_SEL, mask_sh),\
+- SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_FORCE_LOCK_ON_EVENT, mask_sh),\
+- SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_SET_V_TOTAL_MIN_MASK_EN, mask_sh),\
+- SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_SET_V_TOTAL_MIN_MASK, mask_sh),\
+- SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_CLEAR, mask_sh),\
+- SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_MODE, mask_sh),\
+- SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_OCCURRED, mask_sh),\
+- SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_SOURCE_SELECT, mask_sh),\
+- SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_SOURCE_PIPE_SELECT, mask_sh),\
+- SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_RISING_EDGE_DETECT_CNTL, mask_sh),\
+- SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, mask_sh),\
+- SF(OTG0_OTG_STATIC_SCREEN_CONTROL, OTG_STATIC_SCREEN_EVENT_MASK, mask_sh),\
+- SF(OTG0_OTG_STATIC_SCREEN_CONTROL, OTG_STATIC_SCREEN_FRAME_COUNT, mask_sh),\
+- SF(OTG0_OTG_STATUS_FRAME_COUNT, OTG_FRAME_COUNT, mask_sh),\
+- SF(OTG0_OTG_STATUS, OTG_V_BLANK, mask_sh),\
+- SF(OTG0_OTG_STATUS, OTG_V_ACTIVE_DISP, mask_sh),\
+- SF(OTG0_OTG_STATUS_POSITION, OTG_HORZ_COUNT, mask_sh),\
+- SF(OTG0_OTG_STATUS_POSITION, OTG_VERT_COUNT, mask_sh),\
+- SF(OTG0_OTG_NOM_VERT_POSITION, OTG_VERT_COUNT_NOM, mask_sh),\
+- SF(OTG0_OTG_BLACK_COLOR, OTG_BLACK_COLOR_B_CB, mask_sh),\
+- SF(OTG0_OTG_BLACK_COLOR, OTG_BLACK_COLOR_G_Y, mask_sh),\
+- SF(OTG0_OTG_BLACK_COLOR, OTG_BLACK_COLOR_R_CR, mask_sh),\
+- SF(OTG0_OTG_CLOCK_CONTROL, OTG_BUSY, mask_sh),\
+- SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\
+- SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\
+- SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, mask_sh),\
+- SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\
+- SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\
+- SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\
+- SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_ON, mask_sh),\
+- SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_GATE_DIS, mask_sh),\
+- SF(ODM0_OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_OCCURRED_STATUS, mask_sh),\
+- SF(ODM0_OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, mask_sh),\
+- SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, mask_sh),\
+- SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE1_SIZE, mask_sh),\
+- SF(VTG0_CONTROL, VTG0_ENABLE, mask_sh),\
+- SF(VTG0_CONTROL, VTG0_FP2, mask_sh),\
+- SF(VTG0_CONTROL, VTG0_VCOUNT_INIT, mask_sh),\
+- SF(OTG0_OTG_VERT_SYNC_CONTROL, OTG_FORCE_VSYNC_NEXT_LINE_OCCURRED, mask_sh),\
+- SF(OTG0_OTG_VERT_SYNC_CONTROL, OTG_FORCE_VSYNC_NEXT_LINE_CLEAR, mask_sh),\
+- SF(OTG0_OTG_VERT_SYNC_CONTROL, OTG_AUTO_FORCE_VSYNC_MODE, mask_sh),\
+- SF(OTG0_OTG_MASTER_UPDATE_MODE, MASTER_UPDATE_INTERLACED_MODE, mask_sh),\
+- SF(OTG0_OTG_GSL_CONTROL, OTG_GSL0_EN, mask_sh),\
+- SF(OTG0_OTG_GSL_CONTROL, OTG_GSL1_EN, mask_sh),\
+- SF(OTG0_OTG_GSL_CONTROL, OTG_GSL2_EN, mask_sh),\
+- SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_MASTER_EN, mask_sh),\
+- SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_FORCE_DELAY, mask_sh),\
+- SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh)
+-
+-
+-#define TG_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
+- TG_COMMON_MASK_SH_LIST_DCN(mask_sh),\
+- SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_INC0, mask_sh),\
+- SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_INC1, mask_sh),\
+- SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_VRES, mask_sh),\
+- SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_HRES, mask_sh),\
+- SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_RAMP0_OFFSET, mask_sh),\
+- SF(OTG0_OTG_TEST_PATTERN_CONTROL, OTG_TEST_PATTERN_EN, mask_sh),\
+- SF(OTG0_OTG_TEST_PATTERN_CONTROL, OTG_TEST_PATTERN_MODE, mask_sh),\
+- SF(OTG0_OTG_TEST_PATTERN_CONTROL, OTG_TEST_PATTERN_DYNAMIC_RANGE, mask_sh),\
+- SF(OTG0_OTG_TEST_PATTERN_CONTROL, OTG_TEST_PATTERN_COLOR_FORMAT, mask_sh),\
+- SF(OTG0_OTG_TEST_PATTERN_COLOR, OTG_TEST_PATTERN_MASK, mask_sh),\
+- SF(OTG0_OTG_TEST_PATTERN_COLOR, OTG_TEST_PATTERN_DATA, mask_sh),\
+- SF(ODM0_OPTC_DATA_SOURCE_SELECT, OPTC_SRC_SEL, mask_sh)
+-
+-#define TG_REG_FIELD_LIST(type) \
+- type VSTARTUP_START;\
+- type VUPDATE_OFFSET;\
+- type VUPDATE_WIDTH;\
+- type VREADY_OFFSET;\
+- type OTG_BLANK_DATA_EN;\
+- type OTG_BLANK_DE_MODE;\
+- type OTG_CURRENT_BLANK_STATE;\
+- type OTG_MASTER_UPDATE_LOCK;\
+- type UPDATE_LOCK_STATUS;\
+- type OTG_UPDATE_PENDING;\
+- type OTG_MASTER_UPDATE_LOCK_SEL;\
+- type OTG_BLANK_DATA_DOUBLE_BUFFER_EN;\
+- type OTG_H_TOTAL;\
+- type OTG_H_BLANK_START;\
+- type OTG_H_BLANK_END;\
+- type OTG_H_SYNC_A_START;\
+- type OTG_H_SYNC_A_END;\
+- type OTG_H_SYNC_A_POL;\
+- type OTG_H_TIMING_DIV_BY2;\
+- type OTG_V_TOTAL;\
+- type OTG_V_BLANK_START;\
+- type OTG_V_BLANK_END;\
+- type OTG_V_SYNC_A_START;\
+- type OTG_V_SYNC_A_END;\
+- type OTG_V_SYNC_A_POL;\
+- type OTG_INTERLACE_ENABLE;\
+- type OTG_MASTER_EN;\
+- type OTG_START_POINT_CNTL;\
+- type OTG_DISABLE_POINT_CNTL;\
+- type OTG_FIELD_NUMBER_CNTL;\
+- type OTG_STEREO_EN;\
+- type OTG_STEREO_SYNC_OUTPUT_LINE_NUM;\
+- type OTG_STEREO_SYNC_OUTPUT_POLARITY;\
+- type OTG_STEREO_EYE_FLAG_POLARITY;\
+- type OTG_STEREO_CURRENT_EYE;\
+- type OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP;\
+- type OTG_3D_STRUCTURE_EN;\
+- type OTG_3D_STRUCTURE_V_UPDATE_MODE;\
+- type OTG_3D_STRUCTURE_STEREO_SEL_OVR;\
+- type OTG_V_TOTAL_MAX;\
+- type OTG_V_TOTAL_MIN;\
+- type OTG_V_TOTAL_MIN_SEL;\
+- type OTG_V_TOTAL_MAX_SEL;\
+- type OTG_FORCE_LOCK_ON_EVENT;\
+- type OTG_SET_V_TOTAL_MIN_MASK_EN;\
+- type OTG_SET_V_TOTAL_MIN_MASK;\
+- type OTG_FORCE_COUNT_NOW_CLEAR;\
+- type OTG_FORCE_COUNT_NOW_MODE;\
+- type OTG_FORCE_COUNT_NOW_OCCURRED;\
+- type OTG_TRIGA_SOURCE_SELECT;\
+- type OTG_TRIGA_SOURCE_PIPE_SELECT;\
+- type OTG_TRIGA_RISING_EDGE_DETECT_CNTL;\
+- type OTG_TRIGA_FALLING_EDGE_DETECT_CNTL;\
+- type OTG_STATIC_SCREEN_EVENT_MASK;\
+- type OTG_STATIC_SCREEN_FRAME_COUNT;\
+- type OTG_FRAME_COUNT;\
+- type OTG_V_BLANK;\
+- type OTG_V_ACTIVE_DISP;\
+- type OTG_HORZ_COUNT;\
+- type OTG_VERT_COUNT;\
+- type OTG_VERT_COUNT_NOM;\
+- type OTG_BLACK_COLOR_B_CB;\
+- type OTG_BLACK_COLOR_G_Y;\
+- type OTG_BLACK_COLOR_R_CR;\
+- type OTG_TEST_PATTERN_INC0;\
+- type OTG_TEST_PATTERN_INC1;\
+- type OTG_TEST_PATTERN_VRES;\
+- type OTG_TEST_PATTERN_HRES;\
+- type OTG_TEST_PATTERN_RAMP0_OFFSET;\
+- type OTG_TEST_PATTERN_EN;\
+- type OTG_TEST_PATTERN_MODE;\
+- type OTG_TEST_PATTERN_DYNAMIC_RANGE;\
+- type OTG_TEST_PATTERN_COLOR_FORMAT;\
+- type OTG_TEST_PATTERN_MASK;\
+- type OTG_TEST_PATTERN_DATA;\
+- type OTG_BUSY;\
+- type OTG_CLOCK_EN;\
+- type OTG_CLOCK_ON;\
+- type OTG_CLOCK_GATE_DIS;\
+- type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\
+- type OTG_VERTICAL_INTERRUPT2_LINE_START;\
+- type OPTC_INPUT_CLK_EN;\
+- type OPTC_INPUT_CLK_ON;\
+- type OPTC_INPUT_CLK_GATE_DIS;\
+- type OPTC_SRC_SEL;\
+- type OPTC_SEG0_SRC_SEL;\
+- type OPTC_UNDERFLOW_OCCURRED_STATUS;\
+- type OPTC_UNDERFLOW_CLEAR;\
+- type OPPBUF_ACTIVE_WIDTH;\
+- type OPPBUF_3D_VACT_SPACE1_SIZE;\
+- type VTG0_ENABLE;\
+- type VTG0_FP2;\
+- type VTG0_VCOUNT_INIT;\
+- type OTG_FORCE_VSYNC_NEXT_LINE_OCCURRED;\
+- type OTG_FORCE_VSYNC_NEXT_LINE_CLEAR;\
+- type OTG_AUTO_FORCE_VSYNC_MODE;\
+- type MASTER_UPDATE_INTERLACED_MODE;\
+- type OTG_GSL0_EN;\
+- type OTG_GSL1_EN;\
+- type OTG_GSL2_EN;\
+- type OTG_GSL_MASTER_EN;\
+- type OTG_GSL_FORCE_DELAY;\
+- type OTG_GSL_CHECK_ALL_FIELDS;\
+- type OTG_GSL_WINDOW_START_X;\
+- type OTG_GSL_WINDOW_END_X;\
+- type OTG_GSL_WINDOW_START_Y;\
+- type OTG_GSL_WINDOW_END_Y;\
+- type OTG_RANGE_TIMING_DBUF_UPDATE_MODE;\
+- type OTG_GSL_MASTER_MODE;\
+- type OTG_MASTER_UPDATE_LOCK_GSL_EN;\
+- type MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET;\
+- type MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET;\
+- type OTG_DSC_START_POSITION_X;\
+- type OTG_DSC_START_POSITION_LINE_NUM;\
+- type OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN;
+-
+-
+-struct dcn_optc_shift {
+- TG_REG_FIELD_LIST(uint8_t)
+-};
+-
+-struct dcn_optc_mask {
+- TG_REG_FIELD_LIST(uint32_t)
+-};
+-
+-struct optc {
+- struct timing_generator base;
+-
+- const struct dcn_optc_registers *tg_regs;
+- const struct dcn_optc_shift *tg_shift;
+- const struct dcn_optc_mask *tg_mask;
+-
+- enum controller_id controller_id;
+-
+- uint32_t max_h_total;
+- uint32_t max_v_total;
+-
+- uint32_t min_h_blank;
+-
+- uint32_t min_h_sync_width;
+- uint32_t min_v_sync_width;
+- uint32_t min_v_blank;
+- uint32_t min_v_blank_interlace;
+-};
+-
+-void dcn10_timing_generator_init(struct optc *optc);
+-
+-struct dcn_otg_state {
+- uint32_t v_blank_start;
+- uint32_t v_blank_end;
+- uint32_t v_sync_a_pol;
+- uint32_t v_total;
+- uint32_t v_total_max;
+- uint32_t v_total_min;
+- uint32_t v_sync_a_start;
+- uint32_t v_sync_a_end;
+- uint32_t h_blank_start;
+- uint32_t h_blank_end;
+- uint32_t h_sync_a_start;
+- uint32_t h_sync_a_end;
+- uint32_t h_sync_a_pol;
+- uint32_t h_total;
+- uint32_t underflow_occurred_status;
+- uint32_t otg_enabled;
+-};
+-
+-void optc1_read_otg_state(struct optc *optc1,
+- struct dcn_otg_state *s);
+-
+-bool optc1_validate_timing(
+- struct timing_generator *optc,
+- const struct dc_crtc_timing *timing);
+-
+-void optc1_program_timing(
+- struct timing_generator *optc,
+- const struct dc_crtc_timing *dc_crtc_timing,
+- bool use_vbios);
+-
+-void optc1_program_global_sync(
+- struct timing_generator *optc);
+-
+-bool optc1_disable_crtc(struct timing_generator *optc);
+-
+-bool optc1_is_counter_moving(struct timing_generator *optc);
+-
+-void optc1_get_position(struct timing_generator *optc,
+- struct crtc_position *position);
+-
+-uint32_t optc1_get_vblank_counter(struct timing_generator *optc);
+-
+-void optc1_get_crtc_scanoutpos(
+- struct timing_generator *optc,
+- uint32_t *v_blank_start,
+- uint32_t *v_blank_end,
+- uint32_t *h_position,
+- uint32_t *v_position);
+-
+-void optc1_set_early_control(
+- struct timing_generator *optc,
+- uint32_t early_cntl);
+-
+-void optc1_wait_for_state(struct timing_generator *optc,
+- enum crtc_state state);
+-
+-void optc1_set_blank(struct timing_generator *optc,
+- bool enable_blanking);
+-
+-bool optc1_is_blanked(struct timing_generator *optc);
+-
+-void optc1_program_blank_color(
+- struct timing_generator *optc,
+- const struct tg_color *black_color);
+-
+-bool optc1_did_triggered_reset_occur(
+- struct timing_generator *optc);
+-
+-void optc1_enable_reset_trigger(struct timing_generator *optc, int source_tg_inst);
+-
+-void optc1_disable_reset_trigger(struct timing_generator *optc);
+-
+-void optc1_lock(struct timing_generator *optc);
+-
+-void optc1_unlock(struct timing_generator *optc);
+-
+-void optc1_enable_optc_clock(struct timing_generator *optc, bool enable);
+-
+-void optc1_set_drr(
+- struct timing_generator *optc,
+- const struct drr_params *params);
+-
+-void optc1_set_static_screen_control(
+- struct timing_generator *optc,
+- uint32_t value);
+-
+-void optc1_program_stereo(struct timing_generator *optc,
+- const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags);
+-
+-bool optc1_is_stereo_left_eye(struct timing_generator *optc);
+-
+-#endif /* __DC_TIMING_GENERATOR_DCN10_H__ */
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
+index 6da125d..17e143e 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
+@@ -282,25 +282,6 @@ struct opp_funcs {
+ bool enable,
+ bool rightEyePolarity);
+
+- void (*opp_set_test_pattern)(
+- struct output_pixel_processor *opp,
+- enum controller_dp_test_pattern test_pattern,
+- enum dc_color_depth color_depth,
+- int width,
+- int height);
+-
+- void (*opp_dpg_blank_enable)(
+- struct output_pixel_processor *opp,
+- bool enable,
+- const struct tg_color *color,
+- int width,
+- int height);
+-
+- void (*opp_convert_pti)(
+- struct output_pixel_processor *opp,
+- bool enable,
+- bool polarity);
+-
+ };
+
+ #endif
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+index a32c745..4c0aa56 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+@@ -28,6 +28,7 @@
+ #include "dc_types.h"
+ #include "clock_source.h"
+ #include "inc/hw/timing_generator.h"
++#include "inc/hw/opp.h"
+ #include "inc/hw/link_encoder.h"
+ #include "core_status.h"
+
+--
+2.7.4
+