summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc')
-rw-r--r--drivers/gpu/drm/amd/display/dc/Makefile21
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/Makefile23
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/conversion.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c28
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/grph_object_id.c75
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/Makefile21
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/bios_parser.c60
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table.c21
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table2.c13
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/Makefile21
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c17
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c27
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c70
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c51
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_debug.c22
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c145
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link.c183
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c101
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_stream.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_helper.c22
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_hw_types.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_stream.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_types.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/Makefile21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_abm.c18
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_abm.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c34
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c15
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce100/Makefile21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h23
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/Makefile21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c90
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c23
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce112/Makefile21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce120/Makefile23
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce80/Makefile21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/Makefile23
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c294
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h10
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c19
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h493
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c67
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c91
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h224
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c568
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c532
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h91
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c74
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h43
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c (renamed from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c)353
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h (renamed from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h)117
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c13
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/Makefile21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c29
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c10
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/Makefile21
-rw-r--r--drivers/gpu/drm/amd/display/dc/i2caux/Makefile21
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/core_types.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/abm.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h14
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h63
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h22
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h159
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/opp.h39
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h22
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h60
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h11
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/Makefile21
-rw-r--r--drivers/gpu/drm/amd/display/dc/os_types.h14
-rw-r--r--drivers/gpu/drm/amd/display/dc/virtual/Makefile21
87 files changed, 2951 insertions, 1980 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile
index 4f83e3011743..aed538a4d1ba 100644
--- a/drivers/gpu/drm/amd/display/dc/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for Display Core (dc) component.
#
diff --git a/drivers/gpu/drm/amd/display/dc/basics/Makefile b/drivers/gpu/drm/amd/display/dc/basics/Makefile
index 43c5ccdeeb72..bca33bd9a0d2 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/basics/Makefile
@@ -1,9 +1,30 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the 'utils' sub-component of DAL.
# It provides the general basic services required by other DAL
# subcomponents.
-BASICS = conversion.o fixpt31_32.o fixpt32_32.o grph_object_id.o \
+BASICS = conversion.o fixpt31_32.o fixpt32_32.o \
logger.o log_helpers.o vector.o
AMD_DAL_BASICS = $(addprefix $(AMDDALPATH)/dc/basics/,$(BASICS))
diff --git a/drivers/gpu/drm/amd/display/dc/basics/conversion.c b/drivers/gpu/drm/amd/display/dc/basics/conversion.c
index 23c9a0ec0181..310964915a83 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/conversion.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/conversion.c
@@ -46,7 +46,7 @@ uint16_t fixed_point_to_int_frac(
arg));
if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor))
- numerator = (uint16_t)dal_fixed31_32_floor(
+ numerator = (uint16_t)dal_fixed31_32_round(
dal_fixed31_32_mul_int(
arg,
divisor));
diff --git a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
index 26936892c6f5..011a97f82fb6 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
@@ -554,6 +554,22 @@ static inline uint32_t ux_dy(
return result | fractional_part;
}
+static inline uint32_t clamp_ux_dy(
+ int64_t value,
+ uint32_t integer_bits,
+ uint32_t fractional_bits,
+ uint32_t min_clamp)
+{
+ uint32_t truncated_val = ux_dy(value, integer_bits, fractional_bits);
+
+ if (value >= (1LL << (integer_bits + FIXED31_32_BITS_PER_FRACTIONAL_PART)))
+ return (1 << (integer_bits + fractional_bits)) - 1;
+ else if (truncated_val > min_clamp)
+ return truncated_val;
+ else
+ return min_clamp;
+}
+
uint32_t dal_fixed31_32_u2d19(
struct fixed31_32 arg)
{
@@ -565,3 +581,15 @@ uint32_t dal_fixed31_32_u0d19(
{
return ux_dy(arg.value, 0, 19);
}
+
+uint32_t dal_fixed31_32_clamp_u0d14(
+ struct fixed31_32 arg)
+{
+ return clamp_ux_dy(arg.value, 0, 14, 1);
+}
+
+uint32_t dal_fixed31_32_clamp_u0d10(
+ struct fixed31_32 arg)
+{
+ return clamp_ux_dy(arg.value, 0, 10, 1);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/basics/grph_object_id.c b/drivers/gpu/drm/amd/display/dc/basics/grph_object_id.c
deleted file mode 100644
index 147822545252..000000000000
--- a/drivers/gpu/drm/amd/display/dc/basics/grph_object_id.c
+++ /dev/null
@@ -1,75 +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 "dm_services.h"
-#include "include/grph_object_id.h"
-
-static bool dal_graphics_object_id_is_valid(struct graphics_object_id id)
-{
- bool rc = true;
-
- switch (id.type) {
- case OBJECT_TYPE_UNKNOWN:
- rc = false;
- break;
- case OBJECT_TYPE_GPU:
- case OBJECT_TYPE_ENGINE:
- /* do NOT check for id.id == 0 */
- if (id.enum_id == ENUM_ID_UNKNOWN)
- rc = false;
- break;
- default:
- if (id.id == 0 || id.enum_id == ENUM_ID_UNKNOWN)
- rc = false;
- break;
- }
-
- return rc;
-}
-
-bool dal_graphics_object_id_is_equal(
- struct graphics_object_id id1,
- struct graphics_object_id id2)
-{
- if (false == dal_graphics_object_id_is_valid(id1)) {
- dm_output_to_console(
- "%s: Warning: comparing invalid object 'id1'!\n", __func__);
- return false;
- }
-
- if (false == dal_graphics_object_id_is_valid(id2)) {
- dm_output_to_console(
- "%s: Warning: comparing invalid object 'id2'!\n", __func__);
- return false;
- }
-
- if (id1.id == id2.id && id1.enum_id == id2.enum_id
- && id1.type == id2.type)
- return true;
-
- return false;
-}
-
-
diff --git a/drivers/gpu/drm/amd/display/dc/bios/Makefile b/drivers/gpu/drm/amd/display/dc/bios/Makefile
index 6ec815dce9cc..239e86bbec5a 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/bios/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the 'bios' sub-component of DAL.
# It provides the parsing and executing controls for atom bios image.
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
index 86e6438c5cf3..c00e405b63e8 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
@@ -190,6 +190,7 @@ static struct graphics_object_id bios_parser_get_connector_id(
struct bios_parser *bp = BP_FROM_DCB(dcb);
struct graphics_object_id object_id = dal_graphics_object_id_init(
0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
+ uint16_t id;
uint32_t connector_table_offset = bp->object_info_tbl_offset
+ le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset);
@@ -197,12 +198,19 @@ static struct graphics_object_id bios_parser_get_connector_id(
ATOM_OBJECT_TABLE *tbl =
GET_IMAGE(ATOM_OBJECT_TABLE, connector_table_offset);
- if (tbl && tbl->ucNumberOfObjects > i) {
- const uint16_t id = le16_to_cpu(tbl->asObjects[i].usObjectID);
+ if (!tbl) {
+ dm_error("Can't get connector table from atom bios.\n");
+ return object_id;
+ }
- object_id = object_id_from_bios_object_id(id);
+ if (tbl->ucNumberOfObjects <= i) {
+ dm_error("Can't find connector id %d in connector table of size %d.\n",
+ i, tbl->ucNumberOfObjects);
+ return object_id;
}
+ id = le16_to_cpu(tbl->asObjects[i].usObjectID);
+ object_id = object_id_from_bios_object_id(id);
return object_id;
}
@@ -2254,6 +2262,52 @@ static enum bp_result get_gpio_i2c_info(struct bios_parser *bp,
return BP_RESULT_OK;
}
+static bool dal_graphics_object_id_is_valid(struct graphics_object_id id)
+{
+ bool rc = true;
+
+ switch (id.type) {
+ case OBJECT_TYPE_UNKNOWN:
+ rc = false;
+ break;
+ case OBJECT_TYPE_GPU:
+ case OBJECT_TYPE_ENGINE:
+ /* do NOT check for id.id == 0 */
+ if (id.enum_id == ENUM_ID_UNKNOWN)
+ rc = false;
+ break;
+ default:
+ if (id.id == 0 || id.enum_id == ENUM_ID_UNKNOWN)
+ rc = false;
+ break;
+ }
+
+ return rc;
+}
+
+static bool dal_graphics_object_id_is_equal(
+ struct graphics_object_id id1,
+ struct graphics_object_id id2)
+{
+ if (false == dal_graphics_object_id_is_valid(id1)) {
+ dm_output_to_console(
+ "%s: Warning: comparing invalid object 'id1'!\n", __func__);
+ return false;
+ }
+
+ if (false == dal_graphics_object_id_is_valid(id2)) {
+ dm_output_to_console(
+ "%s: Warning: comparing invalid object 'id2'!\n", __func__);
+ return false;
+ }
+
+ if (id1.id == id2.id && id1.enum_id == id2.enum_id
+ && id1.type == id2.type)
+ return true;
+
+ return false;
+}
+
static ATOM_OBJECT *get_bios_object(struct bios_parser *bp,
struct graphics_object_id id)
{
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
index 3f7b2dabc2b0..1aefed8cf98b 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
@@ -387,6 +387,7 @@ static void init_transmitter_control(struct bios_parser *bp)
bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
break;
default:
+ dm_error("Don't have transmitter_control for v%d\n", crev);
bp->cmd_tbl.transmitter_control = NULL;
break;
}
@@ -910,6 +911,8 @@ static void init_set_pixel_clock(struct bios_parser *bp)
bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
break;
default:
+ dm_error("Don't have set_pixel_clock for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock));
bp->cmd_tbl.set_pixel_clock = NULL;
break;
}
@@ -1227,6 +1230,8 @@ static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp)
enable_spread_spectrum_on_ppll_v3;
break;
default:
+ dm_error("Don't have enable_spread_spectrum_on_ppll for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL));
bp->cmd_tbl.enable_spread_spectrum_on_ppll = NULL;
break;
}
@@ -1422,6 +1427,8 @@ static void init_adjust_display_pll(struct bios_parser *bp)
bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v3;
break;
default:
+ dm_error("Don't have adjust_display_pll for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll));
bp->cmd_tbl.adjust_display_pll = NULL;
break;
}
@@ -1695,6 +1702,8 @@ static void init_set_crtc_timing(struct bios_parser *bp)
set_crtc_using_dtd_timing_v3;
break;
default:
+ dm_error("Don't have set_crtc_timing for dtd v%d\n",
+ dtd_version);
bp->cmd_tbl.set_crtc_timing = NULL;
break;
}
@@ -1704,6 +1713,8 @@ static void init_set_crtc_timing(struct bios_parser *bp)
bp->cmd_tbl.set_crtc_timing = set_crtc_timing_v1;
break;
default:
+ dm_error("Don't have set_crtc_timing for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing));
bp->cmd_tbl.set_crtc_timing = NULL;
break;
}
@@ -1890,6 +1901,8 @@ static void init_select_crtc_source(struct bios_parser *bp)
bp->cmd_tbl.select_crtc_source = select_crtc_source_v3;
break;
default:
+ dm_error("Don't select_crtc_source enable_crtc for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(SelectCRTC_Source));
bp->cmd_tbl.select_crtc_source = NULL;
break;
}
@@ -1997,6 +2010,8 @@ static void init_enable_crtc(struct bios_parser *bp)
bp->cmd_tbl.enable_crtc = enable_crtc_v1;
break;
default:
+ dm_error("Don't have enable_crtc for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC));
bp->cmd_tbl.enable_crtc = NULL;
break;
}
@@ -2103,6 +2118,8 @@ static void init_program_clock(struct bios_parser *bp)
bp->cmd_tbl.program_clock = program_clock_v6;
break;
default:
+ dm_error("Don't have program_clock for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock));
bp->cmd_tbl.program_clock = NULL;
break;
}
@@ -2324,6 +2341,8 @@ static void init_enable_disp_power_gating(
enable_disp_power_gating_v2_1;
break;
default:
+ dm_error("Don't enable_disp_power_gating enable_crtc for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating));
bp->cmd_tbl.enable_disp_power_gating = NULL;
break;
}
@@ -2371,6 +2390,8 @@ static void init_set_dce_clock(struct bios_parser *bp)
bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
break;
default:
+ dm_error("Don't have set_dce_clock for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock));
bp->cmd_tbl.set_dce_clock = NULL;
break;
}
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
index ba68693758a7..946db12388d6 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
@@ -118,6 +118,7 @@ static void init_dig_encoder_control(struct bios_parser *bp)
bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5;
break;
default:
+ dm_error("Don't have dig_encoder_control for v%d\n", version);
bp->cmd_tbl.dig_encoder_control = NULL;
break;
}
@@ -205,6 +206,7 @@ static void init_transmitter_control(struct bios_parser *bp)
bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
break;
default:
+ dm_error("Don't have transmitter_control for v%d\n", crev);
bp->cmd_tbl.transmitter_control = NULL;
break;
}
@@ -268,6 +270,8 @@ static void init_set_pixel_clock(struct bios_parser *bp)
bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
break;
default:
+ dm_error("Don't have set_pixel_clock for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(setpixelclock));
bp->cmd_tbl.set_pixel_clock = NULL;
break;
}
@@ -379,6 +383,7 @@ static void init_set_crtc_timing(struct bios_parser *bp)
set_crtc_using_dtd_timing_v3;
break;
default:
+ dm_error("Don't have set_crtc_timing for v%d\n", dtd_version);
bp->cmd_tbl.set_crtc_timing = NULL;
break;
}
@@ -498,6 +503,8 @@ static void init_select_crtc_source(struct bios_parser *bp)
bp->cmd_tbl.select_crtc_source = select_crtc_source_v3;
break;
default:
+ dm_error("Don't select_crtc_source enable_crtc for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(selectcrtc_source));
bp->cmd_tbl.select_crtc_source = NULL;
break;
}
@@ -565,6 +572,8 @@ static void init_enable_crtc(struct bios_parser *bp)
bp->cmd_tbl.enable_crtc = enable_crtc_v1;
break;
default:
+ dm_error("Don't have enable_crtc for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(enablecrtc));
bp->cmd_tbl.enable_crtc = NULL;
break;
}
@@ -661,6 +670,8 @@ static void init_enable_disp_power_gating(
enable_disp_power_gating_v2_1;
break;
default:
+ dm_error("Don't enable_disp_power_gating enable_crtc for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating));
bp->cmd_tbl.enable_disp_power_gating = NULL;
break;
}
@@ -710,6 +721,8 @@ static void init_set_dce_clock(struct bios_parser *bp)
bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
break;
default:
+ dm_error("Don't have set_dce_clock for v%d\n",
+ BIOS_CMD_TABLE_PARA_REVISION(setdceclock));
bp->cmd_tbl.set_dce_clock = NULL;
break;
}
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/calcs/Makefile
index 41ef35995b02..7959e382ed28 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the 'calcs' sub-component of DAL.
# It calculates Bandwidth and Watermarks values for HW programming
#
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
index 6347712db834..2e11fac2a63d 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
@@ -29,6 +29,15 @@
#include "core_types.h"
#include "dal_asic_id.h"
+/*
+ * NOTE:
+ * This file is gcc-parseable HW gospel, coming straight from HW engineers.
+ *
+ * It doesn't adhere to Linux kernel style and sometimes will do things in odd
+ * ways. Unless there is something clearly wrong with it the code should
+ * remain as-is as it provides us with a guarantee from HW that it is correct.
+ */
+
/*******************************************************************************
* Private Functions
******************************************************************************/
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c
index 626f9cf8aad2..5e2ea12fbb73 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c
@@ -27,6 +27,15 @@
#include "dcn_calc_auto.h"
#include "dcn_calc_math.h"
+/*
+ * NOTE:
+ * This file is gcc-parseable HW gospel, coming straight from HW engineers.
+ *
+ * It doesn't adhere to Linux kernel style and sometimes will do things in odd
+ * ways. Unless there is something clearly wrong with it the code should
+ * remain as-is as it provides us with a guarantee from HW that it is correct.
+ */
+
/*REVISION#250*/
void scaler_settings_calculation(struct dcn_bw_internal_vars *v)
{
@@ -773,11 +782,11 @@ void mode_support_and_system_configuration(struct dcn_bw_internal_vars *v)
v->dst_y_after_scaler = 0.0;
}
v->time_calc = 24.0 / v->projected_dcfclk_deep_sleep;
- v->v_update_offset[k] =dcn_bw_ceil2(v->htotal[k] / 4.0, 1.0);
+ v->v_update_offset[k][j] = dcn_bw_ceil2(v->htotal[k] / 4.0, 1.0);
v->total_repeater_delay = v->max_inter_dcn_tile_repeaters * (2.0 / (v->required_dispclk[i][j] / (j + 1)) + 3.0 / v->required_dispclk[i][j]);
- v->v_update_width[k] = (14.0 / v->projected_dcfclk_deep_sleep + 12.0 / (v->required_dispclk[i][j] / (j + 1)) + v->total_repeater_delay) * v->pixel_clock[k];
- v->v_ready_offset[k] =dcn_bw_max2(150.0 / (v->required_dispclk[i][j] / (j + 1)), v->total_repeater_delay + 20.0 / v->projected_dcfclk_deep_sleep + 10.0 / (v->required_dispclk[i][j] / (j + 1))) * v->pixel_clock[k];
- v->time_setup = (v->v_update_offset[k] + v->v_update_width[k] + v->v_ready_offset[k]) / v->pixel_clock[k];
+ v->v_update_width[k][j] = (14.0 / v->projected_dcfclk_deep_sleep + 12.0 / (v->required_dispclk[i][j] / (j + 1)) + v->total_repeater_delay) * v->pixel_clock[k];
+ v->v_ready_offset[k][j] = dcn_bw_max2(150.0 / (v->required_dispclk[i][j] / (j + 1)), v->total_repeater_delay + 20.0 / v->projected_dcfclk_deep_sleep + 10.0 / (v->required_dispclk[i][j] / (j + 1))) * v->pixel_clock[k];
+ v->time_setup = (v->v_update_offset[k][j] + v->v_update_width[k][j] + v->v_ready_offset[k][j]) / v->pixel_clock[k];
v->extra_latency = v->urgent_round_trip_and_out_of_order_latency_per_state[i] + (v->total_number_of_active_dpp[i][j] * v->pixel_chunk_size_in_kbyte + v->total_number_of_dcc_active_dpp[i][j] * v->meta_chunk_size) * 1024.0 / v->return_bw_per_state[i];
if (v->pte_enable == dcn_bw_yes) {
v->extra_latency = v->extra_latency + v->total_number_of_active_dpp[i][j] * v->pte_chunk_size * 1024.0 / v->return_bw_per_state[i];
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c
index b6abe0f3bb15..7600a4a4abc7 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c
@@ -25,37 +25,44 @@
#include "dcn_calc_math.h"
+#define isNaN(number) ((number) != (number))
+
+/*
+ * NOTE:
+ * This file is gcc-parseable HW gospel, coming straight from HW engineers.
+ *
+ * It doesn't adhere to Linux kernel style and sometimes will do things in odd
+ * ways. Unless there is something clearly wrong with it the code should
+ * remain as-is as it provides us with a guarantee from HW that it is correct.
+ */
+
float dcn_bw_mod(const float arg1, const float arg2)
{
- if (arg1 != arg1)
+ if (isNaN(arg1))
return arg2;
- if (arg2 != arg2)
+ if (isNaN(arg2))
return arg1;
return arg1 - arg1 * ((int) (arg1 / arg2));
}
float dcn_bw_min2(const float arg1, const float arg2)
{
- if (arg1 != arg1)
+ if (isNaN(arg1))
return arg2;
- if (arg2 != arg2)
+ if (isNaN(arg2))
return arg1;
return arg1 < arg2 ? arg1 : arg2;
}
unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2)
{
- if (arg1 != arg1)
- return arg2;
- if (arg2 != arg2)
- return arg1;
return arg1 > arg2 ? arg1 : arg2;
}
float dcn_bw_max2(const float arg1, const float arg2)
{
- if (arg1 != arg1)
+ if (isNaN(arg1))
return arg2;
- if (arg2 != arg2)
+ if (isNaN(arg2))
return arg1;
return arg1 > arg2 ? arg1 : arg2;
}
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
index a4fbca34bcdf..331891c2c71a 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
@@ -33,6 +33,15 @@
#include "dcn10/dcn10_resource.h"
#include "dcn_calc_math.h"
+/*
+ * NOTE:
+ * This file is gcc-parseable HW gospel, coming straight from HW engineers.
+ *
+ * It doesn't adhere to Linux kernel style and sometimes will do things in odd
+ * ways. Unless there is something clearly wrong with it the code should
+ * remain as-is as it provides us with a guarantee from HW that it is correct.
+ */
+
/* Defaults from spreadsheet rev#247 */
const struct dcn_soc_bounding_box dcn10_soc_defaults = {
/* latencies */
@@ -878,6 +887,17 @@ bool dcn_validate_bandwidth(
+ pipe->bottom_pipe->plane_res.scl_data.recout.width;
}
+ if (pipe->plane_state->rotation % 2 == 0) {
+ ASSERT(pipe->plane_res.scl_data.ratios.horz.value != dal_fixed31_32_one.value
+ || v->scaler_rec_out_width[input_idx] == v->viewport_width[input_idx]);
+ ASSERT(pipe->plane_res.scl_data.ratios.vert.value != dal_fixed31_32_one.value
+ || v->scaler_recout_height[input_idx] == v->viewport_height[input_idx]);
+ } else {
+ ASSERT(pipe->plane_res.scl_data.ratios.horz.value != dal_fixed31_32_one.value
+ || v->scaler_recout_height[input_idx] == v->viewport_width[input_idx]);
+ ASSERT(pipe->plane_res.scl_data.ratios.vert.value != dal_fixed31_32_one.value
+ || v->scaler_rec_out_width[input_idx] == v->viewport_height[input_idx]);
+ }
v->dcc_enable[input_idx] = pipe->plane_state->dcc.enable ? dcn_bw_yes : dcn_bw_no;
v->source_pixel_format[input_idx] = tl_pixel_format_to_bw_defs(
pipe->plane_state->format);
@@ -888,6 +908,15 @@ bool dcn_validate_bandwidth(
v->override_vta_ps[input_idx] = pipe->plane_res.scl_data.taps.v_taps;
v->override_hta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.h_taps_c;
v->override_vta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.v_taps_c;
+ /*
+ * Spreadsheet doesn't handle taps_c is one properly,
+ * need to force Chroma to always be scaled to pass
+ * bandwidth validation.
+ */
+ if (v->override_hta_pschroma[input_idx] == 1)
+ v->override_hta_pschroma[input_idx] = 2;
+ if (v->override_vta_pschroma[input_idx] == 1)
+ v->override_vta_pschroma[input_idx] = 2;
v->source_scan[input_idx] = (pipe->plane_state->rotation % 2) ? dcn_bw_vert : dcn_bw_hor;
}
if (v->is_line_buffer_bpp_fixed == dcn_bw_yes)
@@ -985,9 +1014,9 @@ bool dcn_validate_bandwidth(
if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state)
continue;
- pipe->pipe_dlg_param.vupdate_width = v->v_update_width[input_idx];
- pipe->pipe_dlg_param.vupdate_offset = v->v_update_offset[input_idx];
- pipe->pipe_dlg_param.vready_offset = v->v_ready_offset[input_idx];
+ pipe->pipe_dlg_param.vupdate_width = v->v_update_width[input_idx][v->dpp_per_plane[input_idx] == 2 ? 1 : 0];
+ pipe->pipe_dlg_param.vupdate_offset = v->v_update_offset[input_idx][v->dpp_per_plane[input_idx] == 2 ? 1 : 0];
+ pipe->pipe_dlg_param.vready_offset = v->v_ready_offset[input_idx][v->dpp_per_plane[input_idx] == 2 ? 1 : 0];
pipe->pipe_dlg_param.vstartup_start = v->v_startup[input_idx];
pipe->pipe_dlg_param.htotal = pipe->stream->timing.h_total;
@@ -1026,9 +1055,9 @@ bool dcn_validate_bandwidth(
TIMING_3D_FORMAT_SIDE_BY_SIDE))) {
if (hsplit_pipe && hsplit_pipe->plane_state == pipe->plane_state) {
/* update previously split pipe */
- hsplit_pipe->pipe_dlg_param.vupdate_width = v->v_update_width[input_idx];
- hsplit_pipe->pipe_dlg_param.vupdate_offset = v->v_update_offset[input_idx];
- hsplit_pipe->pipe_dlg_param.vready_offset = v->v_ready_offset[input_idx];
+ hsplit_pipe->pipe_dlg_param.vupdate_width = v->v_update_width[input_idx][v->dpp_per_plane[input_idx] == 2 ? 1 : 0];
+ hsplit_pipe->pipe_dlg_param.vupdate_offset = v->v_update_offset[input_idx][v->dpp_per_plane[input_idx] == 2 ? 1 : 0];
+ hsplit_pipe->pipe_dlg_param.vready_offset = v->v_ready_offset[input_idx][v->dpp_per_plane[input_idx] == 2 ? 1 : 0];
hsplit_pipe->pipe_dlg_param.vstartup_start = v->v_startup[input_idx];
hsplit_pipe->pipe_dlg_param.htotal = pipe->stream->timing.h_total;
@@ -1556,35 +1585,6 @@ void dcn_bw_sync_calcs_and_dml(struct dc *dc)
dc->dcn_ip->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one,
dc->dcn_ip->bug_forcing_luma_and_chroma_request_to_same_size_fixed,
dc->dcn_ip->dcfclk_cstate_latency);
- dc->dml.soc.vmin.socclk_mhz = dc->dcn_soc->socclk;
- dc->dml.soc.vmid.socclk_mhz = dc->dcn_soc->socclk;
- dc->dml.soc.vnom.socclk_mhz = dc->dcn_soc->socclk;
- dc->dml.soc.vmax.socclk_mhz = dc->dcn_soc->socclk;
-
- dc->dml.soc.vmin.dcfclk_mhz = dc->dcn_soc->dcfclkv_min0p65;
- dc->dml.soc.vmid.dcfclk_mhz = dc->dcn_soc->dcfclkv_mid0p72;
- dc->dml.soc.vnom.dcfclk_mhz = dc->dcn_soc->dcfclkv_nom0p8;
- dc->dml.soc.vmax.dcfclk_mhz = dc->dcn_soc->dcfclkv_max0p9;
-
- dc->dml.soc.vmin.dispclk_mhz = dc->dcn_soc->max_dispclk_vmin0p65;
- dc->dml.soc.vmid.dispclk_mhz = dc->dcn_soc->max_dispclk_vmid0p72;
- dc->dml.soc.vnom.dispclk_mhz = dc->dcn_soc->max_dispclk_vnom0p8;
- dc->dml.soc.vmax.dispclk_mhz = dc->dcn_soc->max_dispclk_vmax0p9;
-
- dc->dml.soc.vmin.dppclk_mhz = dc->dcn_soc->max_dppclk_vmin0p65;
- dc->dml.soc.vmid.dppclk_mhz = dc->dcn_soc->max_dppclk_vmid0p72;
- dc->dml.soc.vnom.dppclk_mhz = dc->dcn_soc->max_dppclk_vnom0p8;
- dc->dml.soc.vmax.dppclk_mhz = dc->dcn_soc->max_dppclk_vmax0p9;
-
- dc->dml.soc.vmin.phyclk_mhz = dc->dcn_soc->phyclkv_min0p65;
- dc->dml.soc.vmid.phyclk_mhz = dc->dcn_soc->phyclkv_mid0p72;
- dc->dml.soc.vnom.phyclk_mhz = dc->dcn_soc->phyclkv_nom0p8;
- dc->dml.soc.vmax.phyclk_mhz = dc->dcn_soc->phyclkv_max0p9;
-
- dc->dml.soc.vmin.dram_bw_per_chan_gbps = dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65;
- dc->dml.soc.vmid.dram_bw_per_chan_gbps = dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72;
- dc->dml.soc.vnom.dram_bw_per_chan_gbps = dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8;
- dc->dml.soc.vmax.dram_bw_per_chan_gbps = dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9;
dc->dml.soc.sr_exit_time_us = dc->dcn_soc->sr_exit_time;
dc->dml.soc.sr_enter_plus_exit_time_us = dc->dcn_soc->sr_enter_plus_exit_time;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index d1488d5ee028..35e84ed031de 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -283,19 +283,17 @@ static bool construct(struct dc *dc,
const struct dc_init_data *init_params)
{
struct dal_logger *logger;
- struct dc_context *dc_ctx = kzalloc(sizeof(*dc_ctx), GFP_KERNEL);
- struct bw_calcs_dceip *dc_dceip = kzalloc(sizeof(*dc_dceip),
- GFP_KERNEL);
- struct bw_calcs_vbios *dc_vbios = kzalloc(sizeof(*dc_vbios),
- GFP_KERNEL);
+ struct dc_context *dc_ctx;
+ struct bw_calcs_dceip *dc_dceip;
+ struct bw_calcs_vbios *dc_vbios;
#ifdef CONFIG_DRM_AMD_DC_DCN1_0
- struct dcn_soc_bounding_box *dcn_soc = kzalloc(sizeof(*dcn_soc),
- GFP_KERNEL);
- struct dcn_ip_params *dcn_ip = kzalloc(sizeof(*dcn_ip), GFP_KERNEL);
+ struct dcn_soc_bounding_box *dcn_soc;
+ struct dcn_ip_params *dcn_ip;
#endif
enum dce_version dc_version = DCE_VERSION_UNKNOWN;
+ dc_dceip = kzalloc(sizeof(*dc_dceip), GFP_KERNEL);
if (!dc_dceip) {
dm_error("%s: failed to create dceip\n", __func__);
goto fail;
@@ -303,6 +301,7 @@ static bool construct(struct dc *dc,
dc->bw_dceip = dc_dceip;
+ dc_vbios = kzalloc(sizeof(*dc_vbios), GFP_KERNEL);
if (!dc_vbios) {
dm_error("%s: failed to create vbios\n", __func__);
goto fail;
@@ -310,6 +309,7 @@ static bool construct(struct dc *dc,
dc->bw_vbios = dc_vbios;
#ifdef CONFIG_DRM_AMD_DC_DCN1_0
+ dcn_soc = kzalloc(sizeof(*dcn_soc), GFP_KERNEL);
if (!dcn_soc) {
dm_error("%s: failed to create dcn_soc\n", __func__);
goto fail;
@@ -317,6 +317,7 @@ static bool construct(struct dc *dc,
dc->dcn_soc = dcn_soc;
+ dcn_ip = kzalloc(sizeof(*dcn_ip), GFP_KERNEL);
if (!dcn_ip) {
dm_error("%s: failed to create dcn_ip\n", __func__);
goto fail;
@@ -325,11 +326,18 @@ static bool construct(struct dc *dc,
dc->dcn_ip = dcn_ip;
#endif
+ dc_ctx = kzalloc(sizeof(*dc_ctx), GFP_KERNEL);
if (!dc_ctx) {
dm_error("%s: failed to create ctx\n", __func__);
goto fail;
}
+ dc_ctx->cgs_device = init_params->cgs_device;
+ dc_ctx->driver_context = init_params->driver;
+ dc_ctx->dc = dc;
+ dc_ctx->asic_id = init_params->asic_id;
+ dc->ctx = dc_ctx;
+
dc->current_state = dc_create_state();
if (!dc->current_state) {
@@ -337,11 +345,6 @@ static bool construct(struct dc *dc,
goto fail;
}
- dc_ctx->cgs_device = init_params->cgs_device;
- dc_ctx->driver_context = init_params->driver;
- dc_ctx->dc = dc;
- dc_ctx->asic_id = init_params->asic_id;
-
/* Create logger */
logger = dal_logger_create(dc_ctx, init_params->log_mask);
@@ -351,11 +354,10 @@ static bool construct(struct dc *dc,
goto fail;
}
dc_ctx->logger = logger;
- dc->ctx = dc_ctx;
- dc->ctx->dce_environment = init_params->dce_environment;
+ dc_ctx->dce_environment = init_params->dce_environment;
dc_version = resource_parse_asic_id(init_params->asic_id);
- dc->ctx->dce_version = dc_version;
+ dc_ctx->dce_version = dc_version;
#if defined(CONFIG_DRM_AMD_DC_FBC)
dc->ctx->fbc_gpu_addr = init_params->fbc_gpu_addr;
@@ -578,7 +580,7 @@ static void program_timing_sync(
for (j = 0; j < group_size; j++) {
struct pipe_ctx *temp;
- if (!pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg)) {
+ if (pipe_set[j]->stream_res.tg->funcs->is_blanked && !pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg)) {
if (j == 0)
break;
@@ -591,7 +593,7 @@ static void program_timing_sync(
/* remove any other unblanked pipes as they have already been synced */
for (j = j + 1; j < group_size; j++) {
- if (!pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg)) {
+ if (pipe_set[j]->stream_res.tg->funcs->is_blanked && !pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg)) {
group_size--;
pipe_set[j] = pipe_set[group_size];
j--;
@@ -786,6 +788,8 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]);
}
+ dc->optimized_required = false;
+
/* 3rd param should be true, temp w/a for RV*/
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
dc->hwss.set_bandwidth(dc, context, dc->ctx->dce_version < DCN_VERSION_1_0);
@@ -981,6 +985,11 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa
if (u->plane_info->per_pixel_alpha != u->surface->per_pixel_alpha)
update_flags->bits.per_pixel_alpha_change = 1;
+ if (u->plane_info->dcc.enable != u->surface->dcc.enable
+ || u->plane_info->dcc.grph.independent_64b_blks != u->surface->dcc.grph.independent_64b_blks
+ || u->plane_info->dcc.grph.meta_pitch != u->surface->dcc.grph.meta_pitch)
+ update_flags->bits.dcc_change = 1;
+
if (pixel_format_to_bpp(u->plane_info->format) !=
pixel_format_to_bpp(u->surface->format))
/* different bytes per element will require full bandwidth
@@ -1178,12 +1187,6 @@ static void commit_planes_for_stream(struct dc *dc,
if (update_type == UPDATE_TYPE_FULL) {
dc->hwss.set_bandwidth(dc, context, false);
context_clock_trace(dc, context);
-
- for (j = 0; j < dc->res_pool->pipe_count; j++) {
- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
-
- dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
- }
}
if (surface_count == 0) {
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
index 2e509382935f..1babac07bcc9 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
@@ -1,4 +1,26 @@
/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+/*
* dc_debug.c
*
* Created on: Nov 3, 2016
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 71993d5983bf..ebc96b720083 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -28,6 +28,8 @@
#include "timing_generator.h"
#include "hw_sequencer.h"
+#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
+
/* used as index in array of black_color_format */
enum black_color_format {
BLACK_COLOR_FORMAT_RGB_FULLRANGE = 0,
@@ -38,6 +40,15 @@ enum black_color_format {
BLACK_COLOR_FORMAT_DEBUG,
};
+enum dc_color_space_type {
+ COLOR_SPACE_RGB_TYPE,
+ COLOR_SPACE_RGB_LIMITED_TYPE,
+ COLOR_SPACE_YCBCR601_TYPE,
+ COLOR_SPACE_YCBCR709_TYPE,
+ COLOR_SPACE_YCBCR601_LIMITED_TYPE,
+ COLOR_SPACE_YCBCR709_LIMITED_TYPE
+};
+
static const struct tg_color black_color_format[] = {
/* BlackColorFormat_RGB_FullRange */
{0, 0, 0},
@@ -53,6 +64,140 @@ static const struct tg_color black_color_format[] = {
{0xff, 0xff, 0},
};
+struct out_csc_color_matrix_type {
+ enum dc_color_space_type color_space_type;
+ uint16_t regval[12];
+};
+
+static const struct out_csc_color_matrix_type output_csc_matrix[] = {
+ { COLOR_SPACE_RGB_TYPE,
+ { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
+ { COLOR_SPACE_RGB_LIMITED_TYPE,
+ { 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} },
+ { COLOR_SPACE_YCBCR601_TYPE,
+ { 0xE04, 0xF444, 0xFDB9, 0x1004, 0x831, 0x1016, 0x320, 0x201, 0xFB45,
+ 0xF6B7, 0xE04, 0x1004} },
+ { COLOR_SPACE_YCBCR709_TYPE,
+ { 0xE04, 0xF345, 0xFEB7, 0x1004, 0x5D3, 0x1399, 0x1FA,
+ 0x201, 0xFCCA, 0xF533, 0xE04, 0x1004} },
+
+ /* TODO: correct values below */
+ { COLOR_SPACE_YCBCR601_LIMITED_TYPE,
+ { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
+ 0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
+ { COLOR_SPACE_YCBCR709_LIMITED_TYPE,
+ { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
+ 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
+};
+
+static bool is_rgb_type(
+ enum dc_color_space color_space)
+{
+ bool ret = false;
+
+ if (color_space == COLOR_SPACE_SRGB ||
+ color_space == COLOR_SPACE_XR_RGB ||
+ color_space == COLOR_SPACE_MSREF_SCRGB ||
+ color_space == COLOR_SPACE_2020_RGB_FULLRANGE ||
+ color_space == COLOR_SPACE_ADOBERGB ||
+ color_space == COLOR_SPACE_DCIP3 ||
+ color_space == COLOR_SPACE_DOLBYVISION)
+ ret = true;
+ return ret;
+}
+
+static bool is_rgb_limited_type(
+ enum dc_color_space color_space)
+{
+ bool ret = false;
+
+ if (color_space == COLOR_SPACE_SRGB_LIMITED ||
+ color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE)
+ ret = true;
+ return ret;
+}
+
+static bool is_ycbcr601_type(
+ enum dc_color_space color_space)
+{
+ bool ret = false;
+
+ if (color_space == COLOR_SPACE_YCBCR601 ||
+ color_space == COLOR_SPACE_XV_YCC_601)
+ ret = true;
+ return ret;
+}
+
+static bool is_ycbcr601_limited_type(
+ enum dc_color_space color_space)
+{
+ bool ret = false;
+
+ if (color_space == COLOR_SPACE_YCBCR601_LIMITED)
+ ret = true;
+ return ret;
+}
+
+static bool is_ycbcr709_type(
+ enum dc_color_space color_space)
+{
+ bool ret = false;
+
+ if (color_space == COLOR_SPACE_YCBCR709 ||
+ color_space == COLOR_SPACE_XV_YCC_709)
+ ret = true;
+ return ret;
+}
+
+static bool is_ycbcr709_limited_type(
+ enum dc_color_space color_space)
+{
+ bool ret = false;
+
+ if (color_space == COLOR_SPACE_YCBCR709_LIMITED)
+ ret = true;
+ return ret;
+}
+enum dc_color_space_type get_color_space_type(enum dc_color_space color_space)
+{
+ enum dc_color_space_type type = COLOR_SPACE_RGB_TYPE;
+
+ if (is_rgb_type(color_space))
+ type = COLOR_SPACE_RGB_TYPE;
+ else if (is_rgb_limited_type(color_space))
+ type = COLOR_SPACE_RGB_LIMITED_TYPE;
+ else if (is_ycbcr601_type(color_space))
+ type = COLOR_SPACE_YCBCR601_TYPE;
+ else if (is_ycbcr709_type(color_space))
+ type = COLOR_SPACE_YCBCR709_TYPE;
+ else if (is_ycbcr601_limited_type(color_space))
+ type = COLOR_SPACE_YCBCR601_LIMITED_TYPE;
+ else if (is_ycbcr709_limited_type(color_space))
+ type = COLOR_SPACE_YCBCR709_LIMITED_TYPE;
+
+ return type;
+}
+
+const uint16_t *find_color_matrix(enum dc_color_space color_space,
+ uint32_t *array_size)
+{
+ int i;
+ enum dc_color_space_type type;
+ const uint16_t *val = NULL;
+ int arr_size = NUM_ELEMENTS(output_csc_matrix);
+
+ type = get_color_space_type(color_space);
+ for (i = 0; i < arr_size; i++)
+ if (output_csc_matrix[i].color_space_type == type) {
+ val = output_csc_matrix[i].regval;
+ *array_size = 12;
+ break;
+ }
+
+ return val;
+}
+
+
void color_space_to_black_color(
const struct dc *dc,
enum dc_color_space colorspace,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 7b0e43c0685c..a37428271573 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -938,8 +938,9 @@ static bool construct(
link->link_id = bios->funcs->get_connector_id(bios, init_params->connector_index);
if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
- dm_error("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d!\n",
- __func__, init_params->connector_index);
+ dm_error("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
+ __func__, init_params->connector_index,
+ link->link_id.type, OBJECT_TYPE_CONNECTOR);
goto create_fail;
}
@@ -1271,6 +1272,24 @@ static enum dc_status enable_link_dp(
return status;
}
+static enum dc_status enable_link_edp(
+ struct dc_state *state,
+ struct pipe_ctx *pipe_ctx)
+{
+ enum dc_status status;
+ struct dc_stream_state *stream = pipe_ctx->stream;
+ struct dc_link *link = stream->sink->link;
+
+ link->dc->hwss.edp_power_control(link, true);
+ link->dc->hwss.edp_wait_for_hpd_ready(link, true);
+
+ status = enable_link_dp(state, pipe_ctx);
+
+ link->dc->hwss.edp_backlight_control(link, true);
+
+ return status;
+}
+
static enum dc_status enable_link_dp_mst(
struct dc_state *state,
struct pipe_ctx *pipe_ctx)
@@ -1746,9 +1765,11 @@ static enum dc_status enable_link(
enum dc_status status = DC_ERROR_UNEXPECTED;
switch (pipe_ctx->stream->signal) {
case SIGNAL_TYPE_DISPLAY_PORT:
- case SIGNAL_TYPE_EDP:
status = enable_link_dp(state, pipe_ctx);
break;
+ case SIGNAL_TYPE_EDP:
+ status = enable_link_edp(state, pipe_ctx);
+ break;
case SIGNAL_TYPE_DISPLAY_PORT_MST:
status = enable_link_dp_mst(state, pipe_ctx);
msleep(200);
@@ -1801,7 +1822,7 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
link->link_enc->funcs->disable_output(link->link_enc, signal);
}
-bool dp_active_dongle_validate_timing(
+static bool dp_active_dongle_validate_timing(
const struct dc_crtc_timing *timing,
const struct dc_dongle_caps *dongle_caps)
{
@@ -1833,6 +1854,8 @@ bool dp_active_dongle_validate_timing(
/* Check Color Depth and Pixel Clock */
if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
required_pix_clk /= 2;
+ else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
+ required_pix_clk = required_pix_clk * 2 / 3;
switch (timing->display_color_depth) {
case COLOR_DEPTH_666:
@@ -1907,12 +1930,18 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level,
{
struct dc *core_dc = link->ctx->dc;
struct abm *abm = core_dc->res_pool->abm;
+ struct dmcu *dmcu = core_dc->res_pool->dmcu;
unsigned int controller_id = 0;
+ bool use_smooth_brightness = true;
int i;
- if ((abm == NULL) || (abm->funcs->set_backlight_level == NULL))
+ if ((dmcu == NULL) ||
+ (abm == NULL) ||
+ (abm->funcs->set_backlight_level == NULL))
return false;
+ use_smooth_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
+
dm_logger_write(link->ctx->logger, LOG_BACKLIGHT,
"New Backlight level: %d (0x%X)\n", level, level);
@@ -1935,7 +1964,8 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level,
abm,
level,
frame_ramp,
- controller_id);
+ controller_id,
+ use_smooth_brightness);
}
return true;
@@ -1952,144 +1982,6 @@ bool dc_link_set_psr_enable(const struct dc_link *link, bool enable, bool wait)
return true;
}
-bool dc_link_get_psr_state(const struct dc_link *link, uint32_t *psr_state)
-{
- struct dc *core_dc = link->ctx->dc;
- struct dmcu *dmcu = core_dc->res_pool->dmcu;
-
- if (dmcu != NULL && link->psr_enabled)
- dmcu->funcs->get_psr_state(dmcu, psr_state);
-
- return true;
-}
-
-bool dc_link_setup_psr(struct dc_link *link,
- const struct dc_stream_state *stream, struct psr_config *psr_config,
- struct psr_context *psr_context)
-{
- struct dc *core_dc = link->ctx->dc;
- struct dmcu *dmcu = core_dc->res_pool->dmcu;
- int i;
-
- psr_context->controllerId = CONTROLLER_ID_UNDEFINED;
-
- if (link != NULL &&
- dmcu != NULL) {
- /* updateSinkPsrDpcdConfig*/
- union dpcd_psr_configuration psr_configuration;
-
- memset(&psr_configuration, 0, sizeof(psr_configuration));
-
- psr_configuration.bits.ENABLE = 1;
- psr_configuration.bits.CRC_VERIFICATION = 1;
- psr_configuration.bits.FRAME_CAPTURE_INDICATION =
- psr_config->psr_frame_capture_indication_req;
-
- /* Check for PSR v2*/
- if (psr_config->psr_version == 0x2) {
- /* For PSR v2 selective update.
- * Indicates whether sink should start capturing
- * immediately following active scan line,
- * or starting with the 2nd active scan line.
- */
- psr_configuration.bits.LINE_CAPTURE_INDICATION = 0;
- /*For PSR v2, determines whether Sink should generate
- * IRQ_HPD when CRC mismatch is detected.
- */
- psr_configuration.bits.IRQ_HPD_WITH_CRC_ERROR = 1;
- }
-
- dm_helpers_dp_write_dpcd(
- link->ctx,
- link,
- 368,
- &psr_configuration.raw,
- sizeof(psr_configuration.raw));
-
- psr_context->channel = link->ddc->ddc_pin->hw_info.ddc_channel;
- psr_context->transmitterId = link->link_enc->transmitter;
- psr_context->engineId = link->link_enc->preferred_engine;
-
- for (i = 0; i < MAX_PIPES; i++) {
- if (core_dc->current_state->res_ctx.pipe_ctx[i].stream
- == stream) {
- /* dmcu -1 for all controller id values,
- * therefore +1 here
- */
- psr_context->controllerId =
- core_dc->current_state->res_ctx.
- pipe_ctx[i].stream_res.tg->inst + 1;
- break;
- }
- }
-
- /* Hardcoded for now. Can be Pcie or Uniphy (or Unknown)*/
- psr_context->phyType = PHY_TYPE_UNIPHY;
- /*PhyId is associated with the transmitter id*/
- psr_context->smuPhyId = link->link_enc->transmitter;
-
- psr_context->crtcTimingVerticalTotal = stream->timing.v_total;
- psr_context->vsyncRateHz = div64_u64(div64_u64((stream->
- timing.pix_clk_khz * 1000),
- stream->timing.v_total),
- stream->timing.h_total);
-
- psr_context->psrSupportedDisplayConfig = true;
- psr_context->psrExitLinkTrainingRequired =
- psr_config->psr_exit_link_training_required;
- psr_context->sdpTransmitLineNumDeadline =
- psr_config->psr_sdp_transmit_line_num_deadline;
- psr_context->psrFrameCaptureIndicationReq =
- psr_config->psr_frame_capture_indication_req;
-
- psr_context->skipPsrWaitForPllLock = 0; /* only = 1 in KV */
-
- psr_context->numberOfControllers =
- link->dc->res_pool->res_cap->num_timing_generator;
-
- psr_context->rfb_update_auto_en = true;
-
- /* 2 frames before enter PSR. */
- psr_context->timehyst_frames = 2;
- /* half a frame
- * (units in 100 lines, i.e. a value of 1 represents 100 lines)
- */
- psr_context->hyst_lines = stream->timing.v_total / 2 / 100;
- psr_context->aux_repeats = 10;
-
- psr_context->psr_level.u32all = 0;
-
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
- /*skip power down the single pipe since it blocks the cstate*/
- if (ASIC_REV_IS_RAVEN(link->ctx->asic_id.hw_internal_rev))
- psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
-#endif
-
- /* SMU will perform additional powerdown sequence.
- * For unsupported ASICs, set psr_level flag to skip PSR
- * static screen notification to SMU.
- * (Always set for DAL2, did not check ASIC)
- */
- psr_context->psr_level.bits.SKIP_SMU_NOTIFICATION = 1;
-
- /* Complete PSR entry before aborting to prevent intermittent
- * freezes on certain eDPs
- */
- psr_context->psr_level.bits.DISABLE_PSR_ENTRY_ABORT = 1;
-
- /* Controls additional delay after remote frame capture before
- * continuing power down, default = 0
- */
- psr_context->frame_delay = 0;
-
- link->psr_enabled = true;
- dmcu->funcs->setup_psr(dmcu, link, psr_context);
- return true;
- } else
- return false;
-
-}
-
const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
{
return &link->link_status;
@@ -2418,6 +2310,9 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
deallocate_mst_payload(pipe_ctx);
+ if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP)
+ core_dc->hwss.edp_backlight_control(pipe_ctx->stream->sink->link, false);
+
core_dc->hwss.disable_stream(pipe_ctx, option);
disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 00528b214a9f..61e8c3e02d16 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1470,6 +1470,12 @@ void decide_link_settings(struct dc_stream_state *stream,
return;
}
+ /* EDP use the link cap setting */
+ if (stream->sink->sink_signal == SIGNAL_TYPE_EDP) {
+ *link_setting = link->verified_link_cap;
+ return;
+ }
+
/* search for the minimum link setting that:
* 1. is supported according to the link training result
* 2. could support the b/w requested by the timing
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index f2902569be2e..2096f2a179f2 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -88,15 +88,7 @@ void dp_enable_link_phy(
}
if (dc_is_dp_sst_signal(signal)) {
- if (signal == SIGNAL_TYPE_EDP) {
- link->dc->hwss.edp_power_control(link, true);
- link_enc->funcs->enable_dp_output(
- link_enc,
- link_settings,
- clock_source);
- link->dc->hwss.edp_backlight_control(link, true);
- } else
- link_enc->funcs->enable_dp_output(
+ link_enc->funcs->enable_dp_output(
link_enc,
link_settings,
clock_source);
@@ -138,7 +130,6 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
dp_receiver_power_ctrl(link, false);
if (signal == SIGNAL_TYPE_EDP) {
- link->dc->hwss.edp_backlight_control(link, false);
edp_receiver_ready_T9(link);
link->link_enc->funcs->disable_output(link->link_enc, signal);
link->dc->hwss.edp_power_control(link, false);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 9c5e879f18b3..95b8dd0e53c6 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1,5 +1,5 @@
/*
-* Copyright 2012-15 Advanced Micro Devices, Inc.
+ * 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"),
@@ -498,26 +498,15 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
data->viewport_c.height = (data->viewport.height + vpc_div - 1) / vpc_div;
/* Handle hsplit */
- if (pri_split || sec_split) {
- /* HMirror XOR Secondary_pipe XOR Rotation_180 */
- bool right_view = (sec_split != plane_state->horizontal_mirror) !=
- (plane_state->rotation == ROTATION_ANGLE_180);
-
- if (plane_state->rotation == ROTATION_ANGLE_90
- || plane_state->rotation == ROTATION_ANGLE_270)
- /* Secondary_pipe XOR Rotation_270 */
- right_view = (plane_state->rotation == ROTATION_ANGLE_270) != sec_split;
-
- if (right_view) {
- data->viewport.x += data->viewport.width / 2;
- data->viewport_c.x += data->viewport_c.width / 2;
- /* Ceil offset pipe */
- data->viewport.width = (data->viewport.width + 1) / 2;
- data->viewport_c.width = (data->viewport_c.width + 1) / 2;
- } else {
- data->viewport.width /= 2;
- data->viewport_c.width /= 2;
- }
+ if (sec_split) {
+ data->viewport.x += data->viewport.width / 2;
+ data->viewport_c.x += data->viewport_c.width / 2;
+ /* Ceil offset pipe */
+ data->viewport.width = (data->viewport.width + 1) / 2;
+ data->viewport_c.width = (data->viewport_c.width + 1) / 2;
+ } else if (pri_split) {
+ data->viewport.width /= 2;
+ data->viewport_c.width /= 2;
}
if (plane_state->rotation == ROTATION_ANGLE_90 ||
@@ -534,6 +523,11 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, struct view *recout_skip
struct rect surf_src = plane_state->src_rect;
struct rect surf_clip = plane_state->clip_rect;
int recout_full_x, recout_full_y;
+ bool pri_split = pipe_ctx->bottom_pipe &&
+ pipe_ctx->bottom_pipe->plane_state == pipe_ctx->plane_state;
+ bool sec_split = pipe_ctx->top_pipe &&
+ pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
+ bool top_bottom_split = stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM;
if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 ||
pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270)
@@ -568,33 +562,43 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, struct view *recout_skip
- pipe_ctx->plane_res.scl_data.recout.y;
/* Handle h & vsplit */
- if (pipe_ctx->top_pipe && pipe_ctx->top_pipe->plane_state ==
- pipe_ctx->plane_state) {
- if (stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
- pipe_ctx->plane_res.scl_data.recout.y += pipe_ctx->plane_res.scl_data.recout.height / 2;
- /* Floor primary pipe, ceil 2ndary pipe */
- pipe_ctx->plane_res.scl_data.recout.height = (pipe_ctx->plane_res.scl_data.recout.height + 1) / 2;
+ if (sec_split && top_bottom_split) {
+ pipe_ctx->plane_res.scl_data.recout.y +=
+ pipe_ctx->plane_res.scl_data.recout.height / 2;
+ /* Floor primary pipe, ceil 2ndary pipe */
+ pipe_ctx->plane_res.scl_data.recout.height =
+ (pipe_ctx->plane_res.scl_data.recout.height + 1) / 2;
+ } else if (pri_split && top_bottom_split)
+ pipe_ctx->plane_res.scl_data.recout.height /= 2;
+ else if (pri_split || sec_split) {
+ /* HMirror XOR Secondary_pipe XOR Rotation_180 */
+ bool right_view = (sec_split != plane_state->horizontal_mirror) !=
+ (plane_state->rotation == ROTATION_ANGLE_180);
+
+ if (plane_state->rotation == ROTATION_ANGLE_90
+ || plane_state->rotation == ROTATION_ANGLE_270)
+ /* Secondary_pipe XOR Rotation_270 */
+ right_view = (plane_state->rotation == ROTATION_ANGLE_270) != sec_split;
+
+ if (right_view) {
+ pipe_ctx->plane_res.scl_data.recout.x +=
+ pipe_ctx->plane_res.scl_data.recout.width / 2;
+ /* Ceil offset pipe */
+ pipe_ctx->plane_res.scl_data.recout.width =
+ (pipe_ctx->plane_res.scl_data.recout.width + 1) / 2;
} else {
- pipe_ctx->plane_res.scl_data.recout.x += pipe_ctx->plane_res.scl_data.recout.width / 2;
- pipe_ctx->plane_res.scl_data.recout.width = (pipe_ctx->plane_res.scl_data.recout.width + 1) / 2;
- }
- } else if (pipe_ctx->bottom_pipe &&
- pipe_ctx->bottom_pipe->plane_state == pipe_ctx->plane_state) {
- if (stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM)
- pipe_ctx->plane_res.scl_data.recout.height /= 2;
- else
pipe_ctx->plane_res.scl_data.recout.width /= 2;
+ }
}
-
/* Unclipped recout offset = stream dst offset + ((surf dst offset - stream surf_src offset)
* * 1/ stream scaling ratio) - (surf surf_src offset * 1/ full scl
* ratio)
*/
- recout_full_x = stream->dst.x + (plane_state->dst_rect.x - stream->src.x)
+ recout_full_x = stream->dst.x + (plane_state->dst_rect.x - stream->src.x)
* stream->dst.width / stream->src.width -
surf_src.x * plane_state->dst_rect.width / surf_src.width
* stream->dst.width / stream->src.width;
- recout_full_y = stream->dst.y + (plane_state->dst_rect.y - stream->src.y)
+ recout_full_y = stream->dst.y + (plane_state->dst_rect.y - stream->src.y)
* stream->dst.height / stream->src.height -
surf_src.y * plane_state->dst_rect.height / surf_src.height
* stream->dst.height / stream->src.height;
@@ -650,7 +654,20 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
struct rect src = pipe_ctx->plane_state->src_rect;
int vpc_div = (data->format == PIXEL_FORMAT_420BPP8
|| data->format == PIXEL_FORMAT_420BPP10) ? 2 : 1;
+ bool flip_vert_scan_dir = false, flip_horz_scan_dir = false;
+ /*
+ * Need to calculate the scan direction for viewport to make adjustments
+ */
+ if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_180) {
+ flip_vert_scan_dir = true;
+ flip_horz_scan_dir = true;
+ } else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90)
+ flip_vert_scan_dir = true;
+ else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270)
+ flip_horz_scan_dir = true;
+ if (pipe_ctx->plane_state->horizontal_mirror)
+ flip_horz_scan_dir = !flip_horz_scan_dir;
if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 ||
pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) {
@@ -715,7 +732,7 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
}
/* Adjust for non-0 viewport offset */
- if (data->viewport.x) {
+ if (data->viewport.x && !flip_horz_scan_dir) {
int int_part;
data->inits.h = dal_fixed31_32_add(data->inits.h, dal_fixed31_32_mul_int(
@@ -736,7 +753,7 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
data->inits.h = dal_fixed31_32_add_int(data->inits.h, int_part);
}
- if (data->viewport_c.x) {
+ if (data->viewport_c.x && !flip_horz_scan_dir) {
int int_part;
data->inits.h_c = dal_fixed31_32_add(data->inits.h_c, dal_fixed31_32_mul_int(
@@ -757,7 +774,7 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
data->inits.h_c = dal_fixed31_32_add_int(data->inits.h_c, int_part);
}
- if (data->viewport.y) {
+ if (data->viewport.y && !flip_vert_scan_dir) {
int int_part;
data->inits.v = dal_fixed31_32_add(data->inits.v, dal_fixed31_32_mul_int(
@@ -778,7 +795,7 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
data->inits.v = dal_fixed31_32_add_int(data->inits.v, int_part);
}
- if (data->viewport_c.y) {
+ if (data->viewport_c.y && !flip_vert_scan_dir) {
int int_part;
data->inits.v_c = dal_fixed31_32_add(data->inits.v_c, dal_fixed31_32_mul_int(
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 375fb457e223..261811e0c094 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -226,7 +226,7 @@ bool dc_stream_set_cursor_attributes(
if (pipe_ctx->plane_res.dpp != NULL &&
pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL)
pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
- pipe_ctx->plane_res.dpp, attributes);
+ pipe_ctx->plane_res.dpp, attributes->color_format);
}
stream->cursor_attributes = *attributes;
@@ -301,6 +301,8 @@ bool dc_stream_set_cursor_position(
}
+ stream->cursor_position = *position;
+
return true;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index c99ed85ba9a2..e2e3c9df79ea 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -38,7 +38,7 @@
#include "inc/compressor.h"
#include "dml/display_mode_lib.h"
-#define DC_VER "3.1.20"
+#define DC_VER "3.1.27"
#define MAX_SURFACES 3
#define MAX_STREAMS 6
@@ -250,6 +250,8 @@ struct dc {
*/
struct dm_pp_display_configuration prev_display_config;
+ bool optimized_required;
+
/* FBC compressor */
#if defined(CONFIG_DRM_AMD_DC_FBC)
struct compressor *fbc_compressor;
@@ -340,7 +342,7 @@ struct dc_hdr_static_metadata {
enum dc_transfer_func_type {
TF_TYPE_PREDEFINED,
TF_TYPE_DISTRIBUTED_POINTS,
- TF_TYPE_BYPASS
+ TF_TYPE_BYPASS,
};
struct dc_transfer_func_distributed_points {
@@ -359,6 +361,7 @@ enum dc_transfer_func_predefined {
TRANSFER_FUNCTION_BT709,
TRANSFER_FUNCTION_PQ,
TRANSFER_FUNCTION_LINEAR,
+ TRANSFER_FUNCTION_UNITY,
};
struct dc_transfer_func {
@@ -385,6 +388,7 @@ union surface_update_flags {
struct {
/* Medium updates */
+ uint32_t dcc_change:1;
uint32_t color_space_change:1;
uint32_t input_tf_change:1;
uint32_t horizontal_mirror_change:1;
@@ -436,6 +440,7 @@ struct dc_plane_state {
enum dc_rotation_angle rotation;
enum plane_stereo_format stereo_format;
+ bool is_tiling_rotated;
bool per_pixel_alpha;
bool visible;
bool flip_immediate;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_helper.c b/drivers/gpu/drm/amd/display/dc/dc_helper.c
index c584252669fd..48e1fcf53d43 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_helper.c
@@ -1,4 +1,26 @@
/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+/*
* dc_helper.c
*
* Created on: Aug 30, 2016
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index 587c0bb3d4ac..03029f72dc3f 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -579,8 +579,6 @@ enum dc_timing_standard {
TIMING_STANDARD_MAX
};
-
-
enum dc_color_depth {
COLOR_DEPTH_UNDEFINED,
COLOR_DEPTH_666,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index fed0e5ea9625..01c60f11b2bd 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -86,6 +86,7 @@ struct dc_stream_state {
struct dc_stream_status status;
struct dc_cursor_attributes cursor_attributes;
+ struct dc_cursor_position cursor_position;
/* from stream struct */
struct kref refcount;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 9291a60126ad..9faddfae241d 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -218,6 +218,7 @@ struct dc_edid_caps {
bool lte_340mcsc_scramble;
bool edid_hdmi;
+ bool hdr_supported;
};
struct view {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/Makefile b/drivers/gpu/drm/amd/display/dc/dce/Makefile
index 8abec0bed379..11401fd8e535 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dce/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for common 'dce' logic
# HW object file under this folder follow similar pattern for HW programming
# - register offset and/or shift + mask stored in the dec_hw struct
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
index 3fe8e697483f..b48190f54907 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
@@ -385,21 +385,12 @@ static bool dce_abm_init_backlight(struct abm *abm)
return true;
}
-static bool is_dmcu_initialized(struct abm *abm)
-{
- struct dce_abm *abm_dce = TO_DCE_ABM(abm);
- unsigned int dmcu_uc_reset;
-
- REG_GET(DMCU_STATUS, UC_IN_RESET, &dmcu_uc_reset);
-
- return !dmcu_uc_reset;
-}
-
static bool dce_abm_set_backlight_level(
struct abm *abm,
unsigned int backlight_level,
unsigned int frame_ramp,
- unsigned int controller_id)
+ unsigned int controller_id,
+ bool use_smooth_brightness)
{
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
@@ -408,7 +399,7 @@ static bool dce_abm_set_backlight_level(
backlight_level, backlight_level);
/* If DMCU is in reset state, DMCU is uninitialized */
- if (is_dmcu_initialized(abm))
+ if (use_smooth_brightness)
dmcu_set_backlight_level(abm_dce,
backlight_level,
frame_ramp,
@@ -425,8 +416,7 @@ static const struct abm_funcs dce_funcs = {
.init_backlight = dce_abm_init_backlight,
.set_backlight_level = dce_abm_set_backlight_level,
.get_current_backlight_8_bit = dce_abm_get_current_backlight_8_bit,
- .set_abm_immediate_disable = dce_abm_immediate_disable,
- .is_dmcu_initialized = is_dmcu_initialized
+ .set_abm_immediate_disable = dce_abm_immediate_disable
};
static void dce_abm_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h
index 59e909ec88f2..ff9436966041 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h
@@ -37,8 +37,7 @@
SR(LVTMA_PWRSEQ_REF_DIV), \
SR(MASTER_COMM_CNTL_REG), \
SR(MASTER_COMM_CMD_REG), \
- SR(MASTER_COMM_DATA_REG1), \
- SR(DMCU_STATUS)
+ SR(MASTER_COMM_DATA_REG1)
#define ABM_DCE110_COMMON_REG_LIST() \
ABM_COMMON_REG_LIST_DCE_BASE(), \
@@ -84,8 +83,7 @@
ABM_SF(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, mask_sh), \
ABM_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, mask_sh), \
ABM_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE1, mask_sh), \
- ABM_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE2, mask_sh), \
- ABM_SF(DMCU_STATUS, UC_IN_RESET, mask_sh)
+ ABM_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE2, mask_sh)
#define ABM_MASK_SH_LIST_DCE110(mask_sh) \
ABM_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh), \
@@ -174,7 +172,6 @@
type MASTER_COMM_CMD_REG_BYTE2; \
type BL_PWM_REF_DIV; \
type BL_PWM_EN; \
- type UC_IN_RESET; \
type BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN; \
type BL_PWM_GRP1_REG_LOCK; \
type BL_PWM_GRP1_REG_UPDATE_PENDING
@@ -206,7 +203,6 @@ struct dce_abm_registers {
uint32_t MASTER_COMM_CMD_REG;
uint32_t MASTER_COMM_DATA_REG1;
uint32_t BIOS_SCRATCH_2;
- uint32_t DMCU_STATUS;
uint32_t BL_PWM_GRP1_REG_LOCK;
};
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
index 9031d22285ea..9e98a5f39a6d 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
@@ -29,7 +29,6 @@
#include "fixed32_32.h"
#include "bios_parser_interface.h"
#include "dc.h"
-#include "dce_abm.h"
#include "dmcu.h"
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
#include "dcn_calcs.h"
@@ -384,7 +383,6 @@ static int dce112_set_clock(
struct bp_set_dce_clock_parameters dce_clk_params;
struct dc_bios *bp = clk->ctx->dc_bios;
struct dc *core_dc = clk->ctx->dc;
- struct abm *abm = core_dc->res_pool->abm;
struct dmcu *dmcu = core_dc->res_pool->dmcu;
int actual_clock = requested_clk_khz;
/* Prepare to program display clock*/
@@ -417,7 +415,7 @@ static int dce112_set_clock(
bp->funcs->set_dce_clock(bp, &dce_clk_params);
- if (abm->funcs->is_dmcu_initialized(abm) && clk_dce->dfs_bypass_disp_clk != actual_clock)
+ if (clk_dce->dfs_bypass_disp_clk != actual_clock)
dmcu->funcs->set_psr_wait_loop(dmcu,
actual_clock / 1000 / 7);
clk_dce->dfs_bypass_disp_clk = actual_clock;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
index a6de99db0444..f663adb33584 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
@@ -263,15 +263,35 @@ static void dce_dmcu_setup_psr(struct dmcu *dmcu,
REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
}
+static bool dce_is_dmcu_initialized(struct dmcu *dmcu)
+{
+ struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
+ unsigned int dmcu_uc_reset;
+
+ /* microcontroller is not running */
+ REG_GET(DMCU_STATUS, UC_IN_RESET, &dmcu_uc_reset);
+
+ /* DMCU is not running */
+ if (dmcu_uc_reset)
+ return false;
+
+ return true;
+}
+
static void dce_psr_wait_loop(
struct dmcu *dmcu,
unsigned int wait_loop_number)
{
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
union dce_dmcu_psr_config_data_wait_loop_reg1 masterCmdData1;
+
if (dmcu->cached_wait_loop_number == wait_loop_number)
return;
+ /* DMCU is not running */
+ if (!dce_is_dmcu_initialized(dmcu))
+ return;
+
/* waitDMCUReadyForCmd */
REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);
@@ -691,6 +711,14 @@ static void dcn10_get_psr_wait_loop(
return;
}
+static bool dcn10_is_dmcu_initialized(struct dmcu *dmcu)
+{
+ /* microcontroller is not running */
+ if (dmcu->dmcu_state != DMCU_RUNNING)
+ return false;
+ return true;
+}
+
#endif
static const struct dmcu_funcs dce_funcs = {
@@ -700,7 +728,8 @@ static const struct dmcu_funcs dce_funcs = {
.setup_psr = dce_dmcu_setup_psr,
.get_psr_state = dce_get_dmcu_psr_state,
.set_psr_wait_loop = dce_psr_wait_loop,
- .get_psr_wait_loop = dce_get_psr_wait_loop
+ .get_psr_wait_loop = dce_get_psr_wait_loop,
+ .is_dmcu_initialized = dce_is_dmcu_initialized
};
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
@@ -711,7 +740,8 @@ static const struct dmcu_funcs dcn10_funcs = {
.setup_psr = dcn10_dmcu_setup_psr,
.get_psr_state = dcn10_get_dmcu_psr_state,
.set_psr_wait_loop = dcn10_psr_wait_loop,
- .get_psr_wait_loop = dcn10_get_psr_wait_loop
+ .get_psr_wait_loop = dcn10_get_psr_wait_loop,
+ .is_dmcu_initialized = dcn10_is_dmcu_initialized
};
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h
index 4c25e2dd28f8..1d4546f23135 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h
@@ -62,6 +62,8 @@
DMCU_ENABLE, mask_sh), \
DMCU_SF(DMCU_STATUS, \
UC_IN_STOP_MODE, mask_sh), \
+ DMCU_SF(DMCU_STATUS, \
+ UC_IN_RESET, mask_sh), \
DMCU_SF(DMCU_RAM_ACCESS_CTRL, \
IRAM_HOST_ACCESS_EN, mask_sh), \
DMCU_SF(DMCU_RAM_ACCESS_CTRL, \
@@ -98,6 +100,7 @@
type IRAM_RD_ADDR_AUTO_INC; \
type DMCU_ENABLE; \
type UC_IN_STOP_MODE; \
+ type UC_IN_RESET; \
type MASTER_COMM_CMD_REG_BYTE0; \
type MASTER_COMM_INTERRUPT; \
type DPHY_RX_FAST_TRAINING_CAPABLE; \
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
index 3b0db253ac22..b73db9e78437 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
@@ -582,7 +582,8 @@ struct dce_hwseq_registers {
type DOMAIN7_PGFSM_PWR_STATUS; \
type DCFCLK_GATE_DIS; \
type DCHUBBUB_GLOBAL_TIMER_REFDIV; \
- type DENTIST_DPPCLK_WDIVIDER;
+ type DENTIST_DPPCLK_WDIVIDER; \
+ type DENTIST_DISPCLK_WDIVIDER;
struct dce_hwseq_shift {
HWSEQ_REG_FIELD_LIST(uint8_t)
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
index bad70c6b3aad..a266e3f5e75f 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
@@ -1072,21 +1072,6 @@ void dce110_link_encoder_disable_output(
/* disable encoder */
if (dc_is_dp_signal(signal))
link_encoder_disable(enc110);
-
- /*
- * TODO: Power control cause regression, we should implement
- * it properly, for now just comment it.
- */
-// if (enc110->base.connector.id == CONNECTOR_ID_EDP) {
-// /* power down eDP panel */
-// link_encoder_edp_wait_for_hpd_ready(
-// enc,
-// enc->connector,
-// false);
-//
-// link_encoder_edp_power_control(
-// enc, false);
-// }
}
void dce110_link_encoder_dp_set_lane_settings(
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/Makefile b/drivers/gpu/drm/amd/display/dc/dce100/Makefile
index ea40870624b3..a822d4e2a169 100644
--- a/drivers/gpu/drm/amd/display/dc/dce100/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dce100/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the 'controller' sub-component of DAL.
# It provides the control and status of HW CRTC block.
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
index 90911258bdb3..3ea43e2a9450 100644
--- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
@@ -1,5 +1,5 @@
/*
-* Copyright 2012-15 Advanced Micro Devices, Inc.
+ * 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"),
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h
index de8fdf438f9b..2f366d66635d 100644
--- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h
@@ -1,4 +1,27 @@
/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+/*
* dce100_resource.h
*
* Created on: 2016-01-20
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/Makefile b/drivers/gpu/drm/amd/display/dc/dce110/Makefile
index 98d956e2f218..d564c0eb8b04 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dce110/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the 'controller' sub-component of DAL.
# It provides the control and status of HW CRTC block.
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index e650bdcd9423..86cdd7b4811f 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -354,8 +354,8 @@ static bool convert_to_custom_float(struct pwl_result_data *rgb_resulted,
return false;
}
- if (!convert_to_custom_float_format(arr_points[2].slope, &fmt,
- &arr_points[2].custom_float_slope)) {
+ if (!convert_to_custom_float_format(arr_points[1].slope, &fmt,
+ &arr_points[1].custom_float_slope)) {
BREAK_TO_DEBUGGER();
return false;
}
@@ -870,8 +870,6 @@ void hwss_edp_power_control(
"%s: Skipping Panel Power action: %s\n",
__func__, (power_up ? "On":"Off"));
}
-
- hwss_edp_wait_for_hpd_ready(link, true);
}
/*todo: cloned in stream enc, fix*/
@@ -972,11 +970,9 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option)
}
/* blank at encoder level */
- if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
- if (pipe_ctx->stream->sink->link->connector_signal == SIGNAL_TYPE_EDP)
- hwss_edp_backlight_control(link, false);
+ if (dc_is_dp_signal(pipe_ctx->stream->signal))
pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
- }
+
link->link_enc->funcs->connect_dig_be_to_fe(
link->link_enc,
pipe_ctx->stream_res.stream_enc->id,
@@ -988,15 +984,12 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
struct dc_link_settings *link_settings)
{
struct encoder_unblank_param params = { { 0 } };
- struct dc_link *link = pipe_ctx->stream->sink->link;
/* only 3 items below are used by unblank */
params.pixel_clk_khz =
pipe_ctx->stream->timing.pix_clk_khz;
params.link_settings.link_rate = link_settings->link_rate;
pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, &params);
- if (link->connector_signal == SIGNAL_TYPE_EDP)
- hwss_edp_backlight_control(link, true);
}
@@ -1342,10 +1335,8 @@ static void power_down_encoders(struct dc *dc)
if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
dp_receiver_power_ctrl(dc->links[i], false);
- if (connector_id == CONNECTOR_ID_EDP) {
+ if (connector_id == CONNECTOR_ID_EDP)
signal = SIGNAL_TYPE_EDP;
- hwss_edp_backlight_control(dc->links[i], false);
- }
}
dc->links[i]->link_enc->funcs->disable_output(
@@ -1698,60 +1689,54 @@ static void apply_min_clocks(
/*
* Check if FBC can be enabled
*/
-static enum dc_status validate_fbc(struct dc *dc,
- struct dc_state *context)
+static bool should_enable_fbc(struct dc *dc,
+ struct dc_state *context)
{
- struct pipe_ctx *pipe_ctx =
- &context->res_ctx.pipe_ctx[0];
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[0];
ASSERT(dc->fbc_compressor);
/* FBC memory should be allocated */
if (!dc->ctx->fbc_gpu_addr)
- return DC_ERROR_UNEXPECTED;
+ return false;
/* Only supports single display */
if (context->stream_count != 1)
- return DC_ERROR_UNEXPECTED;
+ return false;
/* Only supports eDP */
if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP)
- return DC_ERROR_UNEXPECTED;
+ return false;
/* PSR should not be enabled */
if (pipe_ctx->stream->sink->link->psr_enabled)
- return DC_ERROR_UNEXPECTED;
+ return false;
/* Nothing to compress */
if (!pipe_ctx->plane_state)
- return DC_ERROR_UNEXPECTED;
+ return false;
/* Only for non-linear tiling */
if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
- return DC_ERROR_UNEXPECTED;
+ return false;
- return DC_OK;
+ return true;
}
/*
* Enable FBC
*/
-static enum dc_status enable_fbc(struct dc *dc,
- struct dc_state *context)
+static void enable_fbc(struct dc *dc,
+ struct dc_state *context)
{
- enum dc_status status = validate_fbc(dc, context);
-
- if (status == DC_OK) {
+ if (should_enable_fbc(dc, context)) {
/* Program GRPH COMPRESSED ADDRESS and PITCH */
struct compr_addr_and_pitch_params params = {0, 0, 0};
struct compressor *compr = dc->fbc_compressor;
- struct pipe_ctx *pipe_ctx =
- &context->res_ctx.pipe_ctx[0];
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[0];
- params.source_view_width =
- pipe_ctx->stream->timing.h_addressable;
- params.source_view_height =
- pipe_ctx->stream->timing.v_addressable;
+ params.source_view_width = pipe_ctx->stream->timing.h_addressable;
+ params.source_view_height = pipe_ctx->stream->timing.v_addressable;
compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr;
@@ -1760,7 +1745,6 @@ static enum dc_status enable_fbc(struct dc *dc,
compr->funcs->enable_fbc(compr, &params);
}
- return status;
}
#endif
@@ -2026,8 +2010,7 @@ enum dc_status dce110_apply_ctx_to_hw(
if (pipe_ctx->stream == pipe_ctx_old->stream)
continue;
- if (pipe_ctx->stream && pipe_ctx_old->stream
- && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
+ if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
continue;
if (pipe_ctx->top_pipe)
@@ -2063,9 +2046,6 @@ enum dc_status dce110_apply_ctx_to_hw(
context,
dc);
- if (dc->hwss.enable_plane)
- dc->hwss.enable_plane(dc, pipe_ctx, context);
-
if (DC_OK != status)
return status;
}
@@ -2095,16 +2075,8 @@ static void set_default_colors(struct pipe_ctx *pipe_ctx)
struct default_adjustment default_adjust = { 0 };
default_adjust.force_hw_default = false;
- if (pipe_ctx->plane_state == NULL)
- default_adjust.in_color_space = COLOR_SPACE_SRGB;
- else
- default_adjust.in_color_space =
- pipe_ctx->plane_state->color_space;
- if (pipe_ctx->stream == NULL)
- default_adjust.out_color_space = COLOR_SPACE_SRGB;
- else
- default_adjust.out_color_space =
- pipe_ctx->stream->output_color_space;
+ default_adjust.in_color_space = pipe_ctx->plane_state->color_space;
+ default_adjust.out_color_space = pipe_ctx->stream->output_color_space;
default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW;
default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format;
@@ -2872,13 +2844,12 @@ static void dce110_apply_ctx_for_surface(
continue;
/* Need to allocate mem before program front end for Fiji */
- if (pipe_ctx->plane_res.mi != NULL)
- pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
- pipe_ctx->plane_res.mi,
- pipe_ctx->stream->timing.h_total,
- pipe_ctx->stream->timing.v_total,
- pipe_ctx->stream->timing.pix_clk_khz,
- context->stream_count);
+ pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
+ pipe_ctx->plane_res.mi,
+ pipe_ctx->stream->timing.h_total,
+ pipe_ctx->stream->timing.v_total,
+ pipe_ctx->stream->timing.pix_clk_khz,
+ context->stream_count);
dce110_program_front_end_for_pipe(dc, pipe_ctx);
@@ -2985,6 +2956,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.pplib_apply_display_requirements = pplib_apply_display_requirements,
.edp_backlight_control = hwss_edp_backlight_control,
.edp_power_control = hwss_edp_power_control,
+ .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
};
void dce110_hw_sequencer_construct(struct dc *dc)
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
index 2dd6ac637572..fc637647f643 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
@@ -77,5 +77,9 @@ void hwss_edp_backlight_control(
struct dc_link *link,
bool enable);
+void hwss_edp_wait_for_hpd_ready(
+ struct dc_link *link,
+ bool power_up);
+
#endif /* __DC_HWSS_DCE110_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
index 5228ee78f7e6..7c4779578fb7 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
@@ -1,5 +1,5 @@
/*
-* Copyright 2012-15 Advanced Micro Devices, Inc.
+ * 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"),
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
index 07d9303d5477..59b4cd329715 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
@@ -1,3 +1,26 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
#include "dm_services.h"
/* include DCE11 register header files */
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/Makefile b/drivers/gpu/drm/amd/display/dc/dce112/Makefile
index 265ac4310d85..8e090446d511 100644
--- a/drivers/gpu/drm/amd/display/dc/dce112/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dce112/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the 'controller' sub-component of DAL.
# It provides the control and status of HW CRTC block.
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/Makefile b/drivers/gpu/drm/amd/display/dc/dce120/Makefile
index 1779b963525c..37db1f8d45ea 100644
--- a/drivers/gpu/drm/amd/display/dc/dce120/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dce120/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the 'controller' sub-component of DAL.
# It provides the control and status of HW CRTC block.
@@ -8,4 +29,4 @@ dce120_hw_sequencer.o
AMD_DAL_DCE120 = $(addprefix $(AMDDALPATH)/dc/dce120/,$(DCE120))
-AMD_DISPLAY_FILES += $(AMD_DAL_DCE120) \ No newline at end of file
+AMD_DISPLAY_FILES += $(AMD_DAL_DCE120)
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/Makefile b/drivers/gpu/drm/amd/display/dc/dce80/Makefile
index c1105895e5fa..bc388aa4b2f5 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dce80/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the 'controller' sub-component of DAL.
# It provides the control and status of HW CRTC block.
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
index a6ca1f97f748..5469bdfe19f3 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
@@ -1,8 +1,29 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# 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_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index 7f579cb19f4b..53ba3600ee6a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -22,11 +22,12 @@
* Authors: AMD
*
*/
-
+#include "dc.h"
#include "reg_helper.h"
#include "dcn10_dpp.h"
#include "dcn10_cm_common.h"
+#include "custom_float.h"
#define REG(reg) reg
@@ -121,3 +122,294 @@ void cm_helper_program_xfer_func(
}
}
+
+
+
+bool cm_helper_convert_to_custom_float(
+ struct pwl_result_data *rgb_resulted,
+ struct curve_points *arr_points,
+ uint32_t hw_points_num,
+ bool fixpoint)
+{
+ struct custom_float_format fmt;
+
+ struct pwl_result_data *rgb = rgb_resulted;
+
+ uint32_t i = 0;
+
+ fmt.exponenta_bits = 6;
+ fmt.mantissa_bits = 12;
+ fmt.sign = false;
+
+ if (!convert_to_custom_float_format(arr_points[0].x, &fmt,
+ &arr_points[0].custom_float_x)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (!convert_to_custom_float_format(arr_points[0].offset, &fmt,
+ &arr_points[0].custom_float_offset)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (!convert_to_custom_float_format(arr_points[0].slope, &fmt,
+ &arr_points[0].custom_float_slope)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ fmt.mantissa_bits = 10;
+ fmt.sign = false;
+
+ if (!convert_to_custom_float_format(arr_points[1].x, &fmt,
+ &arr_points[1].custom_float_x)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (fixpoint == true)
+ arr_points[1].custom_float_y = dal_fixed31_32_clamp_u0d14(arr_points[1].y);
+ else if (!convert_to_custom_float_format(arr_points[1].y, &fmt,
+ &arr_points[1].custom_float_y)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (!convert_to_custom_float_format(arr_points[1].slope, &fmt,
+ &arr_points[1].custom_float_slope)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (hw_points_num == 0 || rgb_resulted == NULL || fixpoint == true)
+ return true;
+
+ fmt.mantissa_bits = 12;
+ fmt.sign = true;
+
+ while (i != hw_points_num) {
+ if (!convert_to_custom_float_format(rgb->red, &fmt,
+ &rgb->red_reg)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (!convert_to_custom_float_format(rgb->green, &fmt,
+ &rgb->green_reg)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (!convert_to_custom_float_format(rgb->blue, &fmt,
+ &rgb->blue_reg)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (!convert_to_custom_float_format(rgb->delta_red, &fmt,
+ &rgb->delta_red_reg)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (!convert_to_custom_float_format(rgb->delta_green, &fmt,
+ &rgb->delta_green_reg)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (!convert_to_custom_float_format(rgb->delta_blue, &fmt,
+ &rgb->delta_blue_reg)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ ++rgb;
+ ++i;
+ }
+
+ return true;
+}
+
+
+#define MAX_REGIONS_NUMBER 34
+#define MAX_LOW_POINT 25
+#define NUMBER_SEGMENTS 32
+
+bool cm_helper_translate_curve_to_hw_format(
+ const struct dc_transfer_func *output_tf,
+ struct pwl_params *lut_params, bool fixpoint)
+{
+ struct curve_points *arr_points;
+ struct pwl_result_data *rgb_resulted;
+ struct pwl_result_data *rgb;
+ struct pwl_result_data *rgb_plus_1;
+ struct fixed31_32 y_r;
+ struct fixed31_32 y_g;
+ struct fixed31_32 y_b;
+ struct fixed31_32 y1_min;
+ struct fixed31_32 y3_max;
+
+ int32_t segment_start, segment_end;
+ int32_t i;
+ uint32_t j, k, seg_distr[MAX_REGIONS_NUMBER], increment, start_index, hw_points;
+
+ if (output_tf == NULL || lut_params == NULL || output_tf->type == TF_TYPE_BYPASS)
+ return false;
+
+ PERF_TRACE();
+
+ arr_points = lut_params->arr_points;
+ rgb_resulted = lut_params->rgb_resulted;
+ hw_points = 0;
+
+ memset(lut_params, 0, sizeof(struct pwl_params));
+ memset(seg_distr, 0, sizeof(seg_distr));
+
+ if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
+ /* 32 segments
+ * segments are from 2^-25 to 2^7
+ */
+ for (i = 0; i < 32 ; i++)
+ seg_distr[i] = 3;
+
+ segment_start = -25;
+ segment_end = 7;
+ } else {
+ /* 10 segments
+ * segment is from 2^-10 to 2^0
+ * There are less than 256 points, for optimization
+ */
+ seg_distr[0] = 3;
+ seg_distr[1] = 4;
+ seg_distr[2] = 4;
+ seg_distr[3] = 4;
+ seg_distr[4] = 4;
+ seg_distr[5] = 4;
+ seg_distr[6] = 4;
+ seg_distr[7] = 4;
+ seg_distr[8] = 5;
+ seg_distr[9] = 5;
+
+ segment_start = -10;
+ segment_end = 0;
+ }
+
+ for (i = segment_end - segment_start; i < MAX_REGIONS_NUMBER ; i++)
+ seg_distr[i] = -1;
+
+ for (k = 0; k < MAX_REGIONS_NUMBER; k++) {
+ if (seg_distr[k] != -1)
+ hw_points += (1 << seg_distr[k]);
+ }
+
+ j = 0;
+ for (k = 0; k < (segment_end - segment_start); k++) {
+ increment = NUMBER_SEGMENTS / (1 << seg_distr[k]);
+ start_index = (segment_start + k + MAX_LOW_POINT) * NUMBER_SEGMENTS;
+ for (i = start_index; i < start_index + NUMBER_SEGMENTS; i += increment) {
+ if (j == hw_points - 1)
+ break;
+ rgb_resulted[j].red = output_tf->tf_pts.red[i];
+ rgb_resulted[j].green = output_tf->tf_pts.green[i];
+ rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
+ j++;
+ }
+ }
+
+ /* last point */
+ start_index = (segment_end + MAX_LOW_POINT) * NUMBER_SEGMENTS;
+ rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index];
+ rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
+ rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
+
+ arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
+ dal_fixed31_32_from_int(segment_start));
+ arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
+ dal_fixed31_32_from_int(segment_end));
+
+ y_r = rgb_resulted[0].red;
+ y_g = rgb_resulted[0].green;
+ y_b = rgb_resulted[0].blue;
+
+ y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b));
+
+ arr_points[0].y = y1_min;
+ arr_points[0].slope = dal_fixed31_32_div(arr_points[0].y, arr_points[0].x);
+ y_r = rgb_resulted[hw_points - 1].red;
+ y_g = rgb_resulted[hw_points - 1].green;
+ y_b = rgb_resulted[hw_points - 1].blue;
+
+ /* see comment above, m_arrPoints[1].y should be the Y value for the
+ * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
+ */
+ y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b));
+
+ arr_points[1].y = y3_max;
+
+ arr_points[1].slope = dal_fixed31_32_zero;
+
+ if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
+ /* for PQ, we want to have a straight line from last HW X point,
+ * and the slope to be such that we hit 1.0 at 10000 nits.
+ */
+ const struct fixed31_32 end_value =
+ dal_fixed31_32_from_int(125);
+
+ arr_points[1].slope = dal_fixed31_32_div(
+ dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y),
+ dal_fixed31_32_sub(end_value, arr_points[1].x));
+ }
+
+ lut_params->hw_points_num = hw_points;
+
+ i = 1;
+ for (k = 0; k < MAX_REGIONS_NUMBER && i < MAX_REGIONS_NUMBER; k++) {
+ if (seg_distr[k] != -1) {
+ lut_params->arr_curve_points[k].segments_num =
+ seg_distr[k];
+ lut_params->arr_curve_points[i].offset =
+ lut_params->arr_curve_points[k].offset + (1 << seg_distr[k]);
+ }
+ i++;
+ }
+
+ if (seg_distr[k] != -1)
+ lut_params->arr_curve_points[k].segments_num = seg_distr[k];
+
+ rgb = rgb_resulted;
+ rgb_plus_1 = rgb_resulted + 1;
+
+ i = 1;
+ while (i != hw_points + 1) {
+ if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red))
+ rgb_plus_1->red = rgb->red;
+ if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green))
+ rgb_plus_1->green = rgb->green;
+ if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue))
+ rgb_plus_1->blue = rgb->blue;
+
+ rgb->delta_red = dal_fixed31_32_sub(rgb_plus_1->red, rgb->red);
+ rgb->delta_green = dal_fixed31_32_sub(rgb_plus_1->green, rgb->green);
+ rgb->delta_blue = dal_fixed31_32_sub(rgb_plus_1->blue, rgb->blue);
+
+ if (fixpoint == true) {
+ rgb->delta_red_reg = dal_fixed31_32_clamp_u0d10(rgb->delta_red);
+ rgb->delta_green_reg = dal_fixed31_32_clamp_u0d10(rgb->delta_green);
+ rgb->delta_blue_reg = dal_fixed31_32_clamp_u0d10(rgb->delta_blue);
+ rgb->red_reg = dal_fixed31_32_clamp_u0d14(rgb->red);
+ rgb->green_reg = dal_fixed31_32_clamp_u0d14(rgb->green);
+ rgb->blue_reg = dal_fixed31_32_clamp_u0d14(rgb->blue);
+ }
+
+ ++rgb_plus_1;
+ ++rgb;
+ ++i;
+ }
+ cm_helper_convert_to_custom_float(rgb_resulted,
+ lut_params->arr_points,
+ hw_points, fixpoint);
+
+ return true;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
index 64836dcf21f2..64e476b83bcb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
@@ -96,4 +96,14 @@ void cm_helper_program_xfer_func(
const struct pwl_params *params,
const struct xfer_func_reg *reg);
+bool cm_helper_convert_to_custom_float(
+ struct pwl_result_data *rgb_resulted,
+ struct curve_points *arr_points,
+ uint32_t hw_points_num,
+ bool fixpoint);
+
+bool cm_helper_translate_curve_to_hw_format(
+ const struct dc_transfer_func *output_tf,
+ struct pwl_params *lut_params, bool fixpoint);
+
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
index 8df3945370cf..f2a08b156cf0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
@@ -159,11 +159,10 @@ bool dpp_get_optimal_number_of_taps(
scl_data->taps.h_taps = 1;
if (IDENTITY_RATIO(scl_data->ratios.vert))
scl_data->taps.v_taps = 1;
- /*
- * Spreadsheet doesn't handle taps_c is one properly,
- * need to force Chroma to always be scaled to pass
- * bandwidth validation.
- */
+ if (IDENTITY_RATIO(scl_data->ratios.horz_c))
+ scl_data->taps.h_taps_c = 1;
+ if (IDENTITY_RATIO(scl_data->ratios.vert_c))
+ scl_data->taps.v_taps_c = 1;
}
return true;
@@ -386,10 +385,9 @@ void dpp1_cnv_setup (
void dpp1_set_cursor_attributes(
struct dpp *dpp_base,
- const struct dc_cursor_attributes *attr)
+ enum dc_cursor_color_format color_format)
{
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
- enum dc_cursor_color_format color_format = attr->color_format;
REG_UPDATE_2(CURSOR0_CONTROL,
CUR0_MODE, color_format,
@@ -402,13 +400,6 @@ void dpp1_set_cursor_attributes(
REG_UPDATE(CURSOR0_COLOR1,
CUR0_COLOR1, 0xFFFFFFFF);
}
-
- /* TODO: Fixed vs float */
-
- REG_UPDATE_3(FORMAT_CONTROL,
- CNVC_BYPASS, 0,
- FORMAT_CONTROL__ALPHA_EN, 1,
- FORMAT_EXPANSION_MODE, 0);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
index ad71fb50f8a5..f56ee4d08d89 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
@@ -730,8 +730,9 @@
type CM_BLNDGAM_RAMA_EXP_REGION33_NUM_SEGMENTS; \
type CM_BLNDGAM_LUT_WRITE_EN_MASK; \
type CM_BLNDGAM_LUT_WRITE_SEL; \
+ type CM_BLNDGAM_CONFIG_STATUS; \
type CM_BLNDGAM_LUT_INDEX; \
- type CM_BLNDGAM_LUT_DATA; \
+ type BLNDGAM_MEM_PWR_FORCE; \
type CM_3DLUT_MODE; \
type CM_3DLUT_SIZE; \
type CM_3DLUT_INDEX; \
@@ -905,6 +906,7 @@
type CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET; \
type CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS; \
type CM_SHAPER_LUT_WRITE_EN_MASK; \
+ type CM_SHAPER_CONFIG_STATUS; \
type CM_SHAPER_LUT_WRITE_SEL; \
type CM_SHAPER_LUT_INDEX; \
type CM_SHAPER_LUT_DATA; \
@@ -1005,258 +1007,255 @@
type CM_BYPASS; \
type FORMAT_CONTROL__ALPHA_EN; \
type CUR0_COLOR0; \
- type CUR0_COLOR1
-
-
+ type CUR0_COLOR1;
struct dcn_dpp_shift {
- TF_REG_FIELD_LIST(uint8_t);
+ TF_REG_FIELD_LIST(uint8_t)
};
struct dcn_dpp_mask {
- TF_REG_FIELD_LIST(uint32_t);
+ TF_REG_FIELD_LIST(uint32_t)
};
-
-
+#define DPP_COMMON_REG_VARIABLE_LIST \
+ uint32_t DSCL_EXT_OVERSCAN_LEFT_RIGHT; \
+ uint32_t DSCL_EXT_OVERSCAN_TOP_BOTTOM; \
+ uint32_t OTG_H_BLANK; \
+ uint32_t OTG_V_BLANK; \
+ uint32_t SCL_MODE; \
+ uint32_t LB_DATA_FORMAT; \
+ uint32_t LB_MEMORY_CTRL; \
+ uint32_t DSCL_AUTOCAL; \
+ uint32_t SCL_BLACK_OFFSET; \
+ uint32_t SCL_TAP_CONTROL; \
+ uint32_t SCL_COEF_RAM_TAP_SELECT; \
+ uint32_t SCL_COEF_RAM_TAP_DATA; \
+ uint32_t DSCL_2TAP_CONTROL; \
+ uint32_t MPC_SIZE; \
+ uint32_t SCL_HORZ_FILTER_SCALE_RATIO; \
+ uint32_t SCL_VERT_FILTER_SCALE_RATIO; \
+ uint32_t SCL_HORZ_FILTER_SCALE_RATIO_C; \
+ uint32_t SCL_VERT_FILTER_SCALE_RATIO_C; \
+ uint32_t SCL_HORZ_FILTER_INIT; \
+ uint32_t SCL_HORZ_FILTER_INIT_C; \
+ uint32_t SCL_VERT_FILTER_INIT; \
+ uint32_t SCL_VERT_FILTER_INIT_BOT; \
+ uint32_t SCL_VERT_FILTER_INIT_C; \
+ uint32_t SCL_VERT_FILTER_INIT_BOT_C; \
+ uint32_t RECOUT_START; \
+ uint32_t RECOUT_SIZE; \
+ uint32_t CM_GAMUT_REMAP_CONTROL; \
+ uint32_t CM_GAMUT_REMAP_C11_C12; \
+ uint32_t CM_GAMUT_REMAP_C33_C34; \
+ uint32_t CM_COMA_C11_C12; \
+ uint32_t CM_COMA_C33_C34; \
+ uint32_t CM_COMB_C11_C12; \
+ uint32_t CM_COMB_C33_C34; \
+ uint32_t CM_OCSC_CONTROL; \
+ uint32_t CM_OCSC_C11_C12; \
+ uint32_t CM_OCSC_C33_C34; \
+ uint32_t CM_MEM_PWR_CTRL; \
+ uint32_t CM_RGAM_LUT_DATA; \
+ uint32_t CM_RGAM_LUT_WRITE_EN_MASK; \
+ uint32_t CM_RGAM_LUT_INDEX; \
+ uint32_t CM_RGAM_RAMB_START_CNTL_B; \
+ uint32_t CM_RGAM_RAMB_START_CNTL_G; \
+ uint32_t CM_RGAM_RAMB_START_CNTL_R; \
+ uint32_t CM_RGAM_RAMB_SLOPE_CNTL_B; \
+ uint32_t CM_RGAM_RAMB_SLOPE_CNTL_G; \
+ uint32_t CM_RGAM_RAMB_SLOPE_CNTL_R; \
+ uint32_t CM_RGAM_RAMB_END_CNTL1_B; \
+ uint32_t CM_RGAM_RAMB_END_CNTL2_B; \
+ uint32_t CM_RGAM_RAMB_END_CNTL1_G; \
+ uint32_t CM_RGAM_RAMB_END_CNTL2_G; \
+ uint32_t CM_RGAM_RAMB_END_CNTL1_R; \
+ uint32_t CM_RGAM_RAMB_END_CNTL2_R; \
+ uint32_t CM_RGAM_RAMB_REGION_0_1; \
+ uint32_t CM_RGAM_RAMB_REGION_32_33; \
+ uint32_t CM_RGAM_RAMA_START_CNTL_B; \
+ uint32_t CM_RGAM_RAMA_START_CNTL_G; \
+ uint32_t CM_RGAM_RAMA_START_CNTL_R; \
+ uint32_t CM_RGAM_RAMA_SLOPE_CNTL_B; \
+ uint32_t CM_RGAM_RAMA_SLOPE_CNTL_G; \
+ uint32_t CM_RGAM_RAMA_SLOPE_CNTL_R; \
+ uint32_t CM_RGAM_RAMA_END_CNTL1_B; \
+ uint32_t CM_RGAM_RAMA_END_CNTL2_B; \
+ uint32_t CM_RGAM_RAMA_END_CNTL1_G; \
+ uint32_t CM_RGAM_RAMA_END_CNTL2_G; \
+ uint32_t CM_RGAM_RAMA_END_CNTL1_R; \
+ uint32_t CM_RGAM_RAMA_END_CNTL2_R; \
+ uint32_t CM_RGAM_RAMA_REGION_0_1; \
+ uint32_t CM_RGAM_RAMA_REGION_32_33; \
+ uint32_t CM_RGAM_CONTROL; \
+ uint32_t CM_CMOUT_CONTROL; \
+ uint32_t CM_BLNDGAM_LUT_WRITE_EN_MASK; \
+ uint32_t CM_BLNDGAM_CONTROL; \
+ uint32_t CM_BLNDGAM_RAMB_START_CNTL_B; \
+ uint32_t CM_BLNDGAM_RAMB_START_CNTL_G; \
+ uint32_t CM_BLNDGAM_RAMB_START_CNTL_R; \
+ uint32_t CM_BLNDGAM_RAMB_SLOPE_CNTL_B; \
+ uint32_t CM_BLNDGAM_RAMB_SLOPE_CNTL_G; \
+ uint32_t CM_BLNDGAM_RAMB_SLOPE_CNTL_R; \
+ uint32_t CM_BLNDGAM_RAMB_END_CNTL1_B; \
+ uint32_t CM_BLNDGAM_RAMB_END_CNTL2_B; \
+ uint32_t CM_BLNDGAM_RAMB_END_CNTL1_G; \
+ uint32_t CM_BLNDGAM_RAMB_END_CNTL2_G; \
+ uint32_t CM_BLNDGAM_RAMB_END_CNTL1_R; \
+ uint32_t CM_BLNDGAM_RAMB_END_CNTL2_R; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_0_1; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_2_3; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_4_5; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_6_7; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_8_9; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_10_11; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_12_13; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_14_15; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_16_17; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_18_19; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_20_21; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_22_23; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_24_25; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_26_27; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_28_29; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_30_31; \
+ uint32_t CM_BLNDGAM_RAMB_REGION_32_33; \
+ uint32_t CM_BLNDGAM_RAMA_START_CNTL_B; \
+ uint32_t CM_BLNDGAM_RAMA_START_CNTL_G; \
+ uint32_t CM_BLNDGAM_RAMA_START_CNTL_R; \
+ uint32_t CM_BLNDGAM_RAMA_SLOPE_CNTL_B; \
+ uint32_t CM_BLNDGAM_RAMA_SLOPE_CNTL_G; \
+ uint32_t CM_BLNDGAM_RAMA_SLOPE_CNTL_R; \
+ uint32_t CM_BLNDGAM_RAMA_END_CNTL1_B; \
+ uint32_t CM_BLNDGAM_RAMA_END_CNTL2_B; \
+ uint32_t CM_BLNDGAM_RAMA_END_CNTL1_G; \
+ uint32_t CM_BLNDGAM_RAMA_END_CNTL2_G; \
+ uint32_t CM_BLNDGAM_RAMA_END_CNTL1_R; \
+ uint32_t CM_BLNDGAM_RAMA_END_CNTL2_R; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_0_1; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_2_3; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_4_5; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_6_7; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_8_9; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_10_11; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_12_13; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_14_15; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_16_17; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_18_19; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_20_21; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_22_23; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_24_25; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_26_27; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_28_29; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_30_31; \
+ uint32_t CM_BLNDGAM_RAMA_REGION_32_33; \
+ uint32_t CM_BLNDGAM_LUT_INDEX; \
+ uint32_t CM_3DLUT_MODE; \
+ uint32_t CM_3DLUT_INDEX; \
+ uint32_t CM_3DLUT_DATA; \
+ uint32_t CM_3DLUT_DATA_30BIT; \
+ uint32_t CM_3DLUT_READ_WRITE_CONTROL; \
+ uint32_t CM_SHAPER_LUT_WRITE_EN_MASK; \
+ uint32_t CM_SHAPER_CONTROL; \
+ uint32_t CM_SHAPER_RAMB_START_CNTL_B; \
+ uint32_t CM_SHAPER_RAMB_START_CNTL_G; \
+ uint32_t CM_SHAPER_RAMB_START_CNTL_R; \
+ uint32_t CM_SHAPER_RAMB_END_CNTL_B; \
+ uint32_t CM_SHAPER_RAMB_END_CNTL_G; \
+ uint32_t CM_SHAPER_RAMB_END_CNTL_R; \
+ uint32_t CM_SHAPER_RAMB_REGION_0_1; \
+ uint32_t CM_SHAPER_RAMB_REGION_2_3; \
+ uint32_t CM_SHAPER_RAMB_REGION_4_5; \
+ uint32_t CM_SHAPER_RAMB_REGION_6_7; \
+ uint32_t CM_SHAPER_RAMB_REGION_8_9; \
+ uint32_t CM_SHAPER_RAMB_REGION_10_11; \
+ uint32_t CM_SHAPER_RAMB_REGION_12_13; \
+ uint32_t CM_SHAPER_RAMB_REGION_14_15; \
+ uint32_t CM_SHAPER_RAMB_REGION_16_17; \
+ uint32_t CM_SHAPER_RAMB_REGION_18_19; \
+ uint32_t CM_SHAPER_RAMB_REGION_20_21; \
+ uint32_t CM_SHAPER_RAMB_REGION_22_23; \
+ uint32_t CM_SHAPER_RAMB_REGION_24_25; \
+ uint32_t CM_SHAPER_RAMB_REGION_26_27; \
+ uint32_t CM_SHAPER_RAMB_REGION_28_29; \
+ uint32_t CM_SHAPER_RAMB_REGION_30_31; \
+ uint32_t CM_SHAPER_RAMB_REGION_32_33; \
+ uint32_t CM_SHAPER_RAMA_START_CNTL_B; \
+ uint32_t CM_SHAPER_RAMA_START_CNTL_G; \
+ uint32_t CM_SHAPER_RAMA_START_CNTL_R; \
+ uint32_t CM_SHAPER_RAMA_END_CNTL_B; \
+ uint32_t CM_SHAPER_RAMA_END_CNTL_G; \
+ uint32_t CM_SHAPER_RAMA_END_CNTL_R; \
+ uint32_t CM_SHAPER_RAMA_REGION_0_1; \
+ uint32_t CM_SHAPER_RAMA_REGION_2_3; \
+ uint32_t CM_SHAPER_RAMA_REGION_4_5; \
+ uint32_t CM_SHAPER_RAMA_REGION_6_7; \
+ uint32_t CM_SHAPER_RAMA_REGION_8_9; \
+ uint32_t CM_SHAPER_RAMA_REGION_10_11; \
+ uint32_t CM_SHAPER_RAMA_REGION_12_13; \
+ uint32_t CM_SHAPER_RAMA_REGION_14_15; \
+ uint32_t CM_SHAPER_RAMA_REGION_16_17; \
+ uint32_t CM_SHAPER_RAMA_REGION_18_19; \
+ uint32_t CM_SHAPER_RAMA_REGION_20_21; \
+ uint32_t CM_SHAPER_RAMA_REGION_22_23; \
+ uint32_t CM_SHAPER_RAMA_REGION_24_25; \
+ uint32_t CM_SHAPER_RAMA_REGION_26_27; \
+ uint32_t CM_SHAPER_RAMA_REGION_28_29; \
+ uint32_t CM_SHAPER_RAMA_REGION_30_31; \
+ uint32_t CM_SHAPER_RAMA_REGION_32_33; \
+ uint32_t CM_SHAPER_LUT_INDEX; \
+ uint32_t CM_SHAPER_LUT_DATA; \
+ uint32_t CM_ICSC_CONTROL; \
+ uint32_t CM_ICSC_C11_C12; \
+ uint32_t CM_ICSC_C33_C34; \
+ uint32_t CM_BNS_VALUES_R; \
+ uint32_t CM_BNS_VALUES_G; \
+ uint32_t CM_BNS_VALUES_B; \
+ uint32_t CM_DGAM_RAMB_START_CNTL_B; \
+ uint32_t CM_DGAM_RAMB_START_CNTL_G; \
+ uint32_t CM_DGAM_RAMB_START_CNTL_R; \
+ uint32_t CM_DGAM_RAMB_SLOPE_CNTL_B; \
+ uint32_t CM_DGAM_RAMB_SLOPE_CNTL_G; \
+ uint32_t CM_DGAM_RAMB_SLOPE_CNTL_R; \
+ uint32_t CM_DGAM_RAMB_END_CNTL1_B; \
+ uint32_t CM_DGAM_RAMB_END_CNTL2_B; \
+ uint32_t CM_DGAM_RAMB_END_CNTL1_G; \
+ uint32_t CM_DGAM_RAMB_END_CNTL2_G; \
+ uint32_t CM_DGAM_RAMB_END_CNTL1_R; \
+ uint32_t CM_DGAM_RAMB_END_CNTL2_R; \
+ uint32_t CM_DGAM_RAMB_REGION_0_1; \
+ uint32_t CM_DGAM_RAMB_REGION_14_15; \
+ uint32_t CM_DGAM_RAMA_START_CNTL_B; \
+ uint32_t CM_DGAM_RAMA_START_CNTL_G; \
+ uint32_t CM_DGAM_RAMA_START_CNTL_R; \
+ uint32_t CM_DGAM_RAMA_SLOPE_CNTL_B; \
+ uint32_t CM_DGAM_RAMA_SLOPE_CNTL_G; \
+ uint32_t CM_DGAM_RAMA_SLOPE_CNTL_R; \
+ uint32_t CM_DGAM_RAMA_END_CNTL1_B; \
+ uint32_t CM_DGAM_RAMA_END_CNTL2_B; \
+ uint32_t CM_DGAM_RAMA_END_CNTL1_G; \
+ uint32_t CM_DGAM_RAMA_END_CNTL2_G; \
+ uint32_t CM_DGAM_RAMA_END_CNTL1_R; \
+ uint32_t CM_DGAM_RAMA_END_CNTL2_R; \
+ uint32_t CM_DGAM_RAMA_REGION_0_1; \
+ uint32_t CM_DGAM_RAMA_REGION_14_15; \
+ uint32_t CM_DGAM_LUT_WRITE_EN_MASK; \
+ uint32_t CM_DGAM_LUT_INDEX; \
+ uint32_t CM_DGAM_LUT_DATA; \
+ uint32_t CM_CONTROL; \
+ uint32_t CM_DGAM_CONTROL; \
+ uint32_t CM_IGAM_CONTROL; \
+ uint32_t CM_IGAM_LUT_RW_CONTROL; \
+ uint32_t CM_IGAM_LUT_RW_INDEX; \
+ uint32_t CM_IGAM_LUT_SEQ_COLOR; \
+ uint32_t FORMAT_CONTROL; \
+ uint32_t CNVC_SURFACE_PIXEL_FORMAT; \
+ uint32_t CURSOR_CONTROL; \
+ uint32_t CURSOR0_CONTROL; \
+ uint32_t CURSOR0_COLOR0; \
+ uint32_t CURSOR0_COLOR1;
struct dcn_dpp_registers {
- uint32_t DSCL_EXT_OVERSCAN_LEFT_RIGHT;
- uint32_t DSCL_EXT_OVERSCAN_TOP_BOTTOM;
- uint32_t OTG_H_BLANK;
- uint32_t OTG_V_BLANK;
- uint32_t SCL_MODE;
- uint32_t LB_DATA_FORMAT;
- uint32_t LB_MEMORY_CTRL;
- uint32_t DSCL_AUTOCAL;
- uint32_t SCL_BLACK_OFFSET;
- uint32_t SCL_TAP_CONTROL;
- uint32_t SCL_COEF_RAM_TAP_SELECT;
- uint32_t SCL_COEF_RAM_TAP_DATA;
- uint32_t DSCL_2TAP_CONTROL;
- uint32_t MPC_SIZE;
- uint32_t SCL_HORZ_FILTER_SCALE_RATIO;
- uint32_t SCL_VERT_FILTER_SCALE_RATIO;
- uint32_t SCL_HORZ_FILTER_SCALE_RATIO_C;
- uint32_t SCL_VERT_FILTER_SCALE_RATIO_C;
- uint32_t SCL_HORZ_FILTER_INIT;
- uint32_t SCL_HORZ_FILTER_INIT_C;
- uint32_t SCL_VERT_FILTER_INIT;
- uint32_t SCL_VERT_FILTER_INIT_BOT;
- uint32_t SCL_VERT_FILTER_INIT_C;
- uint32_t SCL_VERT_FILTER_INIT_BOT_C;
- uint32_t RECOUT_START;
- uint32_t RECOUT_SIZE;
- uint32_t CM_GAMUT_REMAP_CONTROL;
- uint32_t CM_GAMUT_REMAP_C11_C12;
- uint32_t CM_GAMUT_REMAP_C33_C34;
- uint32_t CM_COMA_C11_C12;
- uint32_t CM_COMA_C33_C34;
- uint32_t CM_COMB_C11_C12;
- uint32_t CM_COMB_C33_C34;
- uint32_t CM_OCSC_CONTROL;
- uint32_t CM_OCSC_C11_C12;
- uint32_t CM_OCSC_C33_C34;
- uint32_t CM_MEM_PWR_CTRL;
- uint32_t CM_RGAM_LUT_DATA;
- uint32_t CM_RGAM_LUT_WRITE_EN_MASK;
- uint32_t CM_RGAM_LUT_INDEX;
- uint32_t CM_RGAM_RAMB_START_CNTL_B;
- uint32_t CM_RGAM_RAMB_START_CNTL_G;
- uint32_t CM_RGAM_RAMB_START_CNTL_R;
- uint32_t CM_RGAM_RAMB_SLOPE_CNTL_B;
- uint32_t CM_RGAM_RAMB_SLOPE_CNTL_G;
- uint32_t CM_RGAM_RAMB_SLOPE_CNTL_R;
- uint32_t CM_RGAM_RAMB_END_CNTL1_B;
- uint32_t CM_RGAM_RAMB_END_CNTL2_B;
- uint32_t CM_RGAM_RAMB_END_CNTL1_G;
- uint32_t CM_RGAM_RAMB_END_CNTL2_G;
- uint32_t CM_RGAM_RAMB_END_CNTL1_R;
- uint32_t CM_RGAM_RAMB_END_CNTL2_R;
- uint32_t CM_RGAM_RAMB_REGION_0_1;
- uint32_t CM_RGAM_RAMB_REGION_32_33;
- uint32_t CM_RGAM_RAMA_START_CNTL_B;
- uint32_t CM_RGAM_RAMA_START_CNTL_G;
- uint32_t CM_RGAM_RAMA_START_CNTL_R;
- uint32_t CM_RGAM_RAMA_SLOPE_CNTL_B;
- uint32_t CM_RGAM_RAMA_SLOPE_CNTL_G;
- uint32_t CM_RGAM_RAMA_SLOPE_CNTL_R;
- uint32_t CM_RGAM_RAMA_END_CNTL1_B;
- uint32_t CM_RGAM_RAMA_END_CNTL2_B;
- uint32_t CM_RGAM_RAMA_END_CNTL1_G;
- uint32_t CM_RGAM_RAMA_END_CNTL2_G;
- uint32_t CM_RGAM_RAMA_END_CNTL1_R;
- uint32_t CM_RGAM_RAMA_END_CNTL2_R;
- uint32_t CM_RGAM_RAMA_REGION_0_1;
- uint32_t CM_RGAM_RAMA_REGION_32_33;
- uint32_t CM_RGAM_CONTROL;
- uint32_t CM_CMOUT_CONTROL;
- uint32_t CM_BLNDGAM_LUT_WRITE_EN_MASK;
- uint32_t CM_BLNDGAM_CONTROL;
- uint32_t CM_BLNDGAM_RAMB_START_CNTL_B;
- uint32_t CM_BLNDGAM_RAMB_START_CNTL_G;
- uint32_t CM_BLNDGAM_RAMB_START_CNTL_R;
- uint32_t CM_BLNDGAM_RAMB_SLOPE_CNTL_B;
- uint32_t CM_BLNDGAM_RAMB_SLOPE_CNTL_G;
- uint32_t CM_BLNDGAM_RAMB_SLOPE_CNTL_R;
- uint32_t CM_BLNDGAM_RAMB_END_CNTL1_B;
- uint32_t CM_BLNDGAM_RAMB_END_CNTL2_B;
- uint32_t CM_BLNDGAM_RAMB_END_CNTL1_G;
- uint32_t CM_BLNDGAM_RAMB_END_CNTL2_G;
- uint32_t CM_BLNDGAM_RAMB_END_CNTL1_R;
- uint32_t CM_BLNDGAM_RAMB_END_CNTL2_R;
- uint32_t CM_BLNDGAM_RAMB_REGION_0_1;
- uint32_t CM_BLNDGAM_RAMB_REGION_2_3;
- uint32_t CM_BLNDGAM_RAMB_REGION_4_5;
- uint32_t CM_BLNDGAM_RAMB_REGION_6_7;
- uint32_t CM_BLNDGAM_RAMB_REGION_8_9;
- uint32_t CM_BLNDGAM_RAMB_REGION_10_11;
- uint32_t CM_BLNDGAM_RAMB_REGION_12_13;
- uint32_t CM_BLNDGAM_RAMB_REGION_14_15;
- uint32_t CM_BLNDGAM_RAMB_REGION_16_17;
- uint32_t CM_BLNDGAM_RAMB_REGION_18_19;
- uint32_t CM_BLNDGAM_RAMB_REGION_20_21;
- uint32_t CM_BLNDGAM_RAMB_REGION_22_23;
- uint32_t CM_BLNDGAM_RAMB_REGION_24_25;
- uint32_t CM_BLNDGAM_RAMB_REGION_26_27;
- uint32_t CM_BLNDGAM_RAMB_REGION_28_29;
- uint32_t CM_BLNDGAM_RAMB_REGION_30_31;
- uint32_t CM_BLNDGAM_RAMB_REGION_32_33;
- uint32_t CM_BLNDGAM_RAMA_START_CNTL_B;
- uint32_t CM_BLNDGAM_RAMA_START_CNTL_G;
- uint32_t CM_BLNDGAM_RAMA_START_CNTL_R;
- uint32_t CM_BLNDGAM_RAMA_SLOPE_CNTL_B;
- uint32_t CM_BLNDGAM_RAMA_SLOPE_CNTL_G;
- uint32_t CM_BLNDGAM_RAMA_SLOPE_CNTL_R;
- uint32_t CM_BLNDGAM_RAMA_END_CNTL1_B;
- uint32_t CM_BLNDGAM_RAMA_END_CNTL2_B;
- uint32_t CM_BLNDGAM_RAMA_END_CNTL1_G;
- uint32_t CM_BLNDGAM_RAMA_END_CNTL2_G;
- uint32_t CM_BLNDGAM_RAMA_END_CNTL1_R;
- uint32_t CM_BLNDGAM_RAMA_END_CNTL2_R;
- uint32_t CM_BLNDGAM_RAMA_REGION_0_1;
- uint32_t CM_BLNDGAM_RAMA_REGION_2_3;
- uint32_t CM_BLNDGAM_RAMA_REGION_4_5;
- uint32_t CM_BLNDGAM_RAMA_REGION_6_7;
- uint32_t CM_BLNDGAM_RAMA_REGION_8_9;
- uint32_t CM_BLNDGAM_RAMA_REGION_10_11;
- uint32_t CM_BLNDGAM_RAMA_REGION_12_13;
- uint32_t CM_BLNDGAM_RAMA_REGION_14_15;
- uint32_t CM_BLNDGAM_RAMA_REGION_16_17;
- uint32_t CM_BLNDGAM_RAMA_REGION_18_19;
- uint32_t CM_BLNDGAM_RAMA_REGION_20_21;
- uint32_t CM_BLNDGAM_RAMA_REGION_22_23;
- uint32_t CM_BLNDGAM_RAMA_REGION_24_25;
- uint32_t CM_BLNDGAM_RAMA_REGION_26_27;
- uint32_t CM_BLNDGAM_RAMA_REGION_28_29;
- uint32_t CM_BLNDGAM_RAMA_REGION_30_31;
- uint32_t CM_BLNDGAM_RAMA_REGION_32_33;
- uint32_t CM_BLNDGAM_LUT_INDEX;
- uint32_t CM_BLNDGAM_LUT_DATA;
- uint32_t CM_3DLUT_MODE;
- uint32_t CM_3DLUT_INDEX;
- uint32_t CM_3DLUT_DATA;
- uint32_t CM_3DLUT_DATA_30BIT;
- uint32_t CM_3DLUT_READ_WRITE_CONTROL;
- uint32_t CM_SHAPER_LUT_WRITE_EN_MASK;
- uint32_t CM_SHAPER_CONTROL;
- uint32_t CM_SHAPER_RAMB_START_CNTL_B;
- uint32_t CM_SHAPER_RAMB_START_CNTL_G;
- uint32_t CM_SHAPER_RAMB_START_CNTL_R;
- uint32_t CM_SHAPER_RAMB_END_CNTL_B;
- uint32_t CM_SHAPER_RAMB_END_CNTL_G;
- uint32_t CM_SHAPER_RAMB_END_CNTL_R;
- uint32_t CM_SHAPER_RAMB_REGION_0_1;
- uint32_t CM_SHAPER_RAMB_REGION_2_3;
- uint32_t CM_SHAPER_RAMB_REGION_4_5;
- uint32_t CM_SHAPER_RAMB_REGION_6_7;
- uint32_t CM_SHAPER_RAMB_REGION_8_9;
- uint32_t CM_SHAPER_RAMB_REGION_10_11;
- uint32_t CM_SHAPER_RAMB_REGION_12_13;
- uint32_t CM_SHAPER_RAMB_REGION_14_15;
- uint32_t CM_SHAPER_RAMB_REGION_16_17;
- uint32_t CM_SHAPER_RAMB_REGION_18_19;
- uint32_t CM_SHAPER_RAMB_REGION_20_21;
- uint32_t CM_SHAPER_RAMB_REGION_22_23;
- uint32_t CM_SHAPER_RAMB_REGION_24_25;
- uint32_t CM_SHAPER_RAMB_REGION_26_27;
- uint32_t CM_SHAPER_RAMB_REGION_28_29;
- uint32_t CM_SHAPER_RAMB_REGION_30_31;
- uint32_t CM_SHAPER_RAMB_REGION_32_33;
- uint32_t CM_SHAPER_RAMA_START_CNTL_B;
- uint32_t CM_SHAPER_RAMA_START_CNTL_G;
- uint32_t CM_SHAPER_RAMA_START_CNTL_R;
- uint32_t CM_SHAPER_RAMA_END_CNTL_B;
- uint32_t CM_SHAPER_RAMA_END_CNTL_G;
- uint32_t CM_SHAPER_RAMA_END_CNTL_R;
- uint32_t CM_SHAPER_RAMA_REGION_0_1;
- uint32_t CM_SHAPER_RAMA_REGION_2_3;
- uint32_t CM_SHAPER_RAMA_REGION_4_5;
- uint32_t CM_SHAPER_RAMA_REGION_6_7;
- uint32_t CM_SHAPER_RAMA_REGION_8_9;
- uint32_t CM_SHAPER_RAMA_REGION_10_11;
- uint32_t CM_SHAPER_RAMA_REGION_12_13;
- uint32_t CM_SHAPER_RAMA_REGION_14_15;
- uint32_t CM_SHAPER_RAMA_REGION_16_17;
- uint32_t CM_SHAPER_RAMA_REGION_18_19;
- uint32_t CM_SHAPER_RAMA_REGION_20_21;
- uint32_t CM_SHAPER_RAMA_REGION_22_23;
- uint32_t CM_SHAPER_RAMA_REGION_24_25;
- uint32_t CM_SHAPER_RAMA_REGION_26_27;
- uint32_t CM_SHAPER_RAMA_REGION_28_29;
- uint32_t CM_SHAPER_RAMA_REGION_30_31;
- uint32_t CM_SHAPER_RAMA_REGION_32_33;
- uint32_t CM_SHAPER_LUT_INDEX;
- uint32_t CM_SHAPER_LUT_DATA;
- uint32_t CM_ICSC_CONTROL;
- uint32_t CM_ICSC_C11_C12;
- uint32_t CM_ICSC_C33_C34;
- uint32_t CM_BNS_VALUES_R;
- uint32_t CM_BNS_VALUES_G;
- uint32_t CM_BNS_VALUES_B;
- uint32_t CM_DGAM_RAMB_START_CNTL_B;
- uint32_t CM_DGAM_RAMB_START_CNTL_G;
- uint32_t CM_DGAM_RAMB_START_CNTL_R;
- uint32_t CM_DGAM_RAMB_SLOPE_CNTL_B;
- uint32_t CM_DGAM_RAMB_SLOPE_CNTL_G;
- uint32_t CM_DGAM_RAMB_SLOPE_CNTL_R;
- uint32_t CM_DGAM_RAMB_END_CNTL1_B;
- uint32_t CM_DGAM_RAMB_END_CNTL2_B;
- uint32_t CM_DGAM_RAMB_END_CNTL1_G;
- uint32_t CM_DGAM_RAMB_END_CNTL2_G;
- uint32_t CM_DGAM_RAMB_END_CNTL1_R;
- uint32_t CM_DGAM_RAMB_END_CNTL2_R;
- uint32_t CM_DGAM_RAMB_REGION_0_1;
- uint32_t CM_DGAM_RAMB_REGION_14_15;
- uint32_t CM_DGAM_RAMA_START_CNTL_B;
- uint32_t CM_DGAM_RAMA_START_CNTL_G;
- uint32_t CM_DGAM_RAMA_START_CNTL_R;
- uint32_t CM_DGAM_RAMA_SLOPE_CNTL_B;
- uint32_t CM_DGAM_RAMA_SLOPE_CNTL_G;
- uint32_t CM_DGAM_RAMA_SLOPE_CNTL_R;
- uint32_t CM_DGAM_RAMA_END_CNTL1_B;
- uint32_t CM_DGAM_RAMA_END_CNTL2_B;
- uint32_t CM_DGAM_RAMA_END_CNTL1_G;
- uint32_t CM_DGAM_RAMA_END_CNTL2_G;
- uint32_t CM_DGAM_RAMA_END_CNTL1_R;
- uint32_t CM_DGAM_RAMA_END_CNTL2_R;
- uint32_t CM_DGAM_RAMA_REGION_0_1;
- uint32_t CM_DGAM_RAMA_REGION_14_15;
- uint32_t CM_DGAM_LUT_WRITE_EN_MASK;
- uint32_t CM_DGAM_LUT_INDEX;
- uint32_t CM_DGAM_LUT_DATA;
- uint32_t CM_CONTROL;
- uint32_t CM_DGAM_CONTROL;
- uint32_t CM_IGAM_CONTROL;
- uint32_t CM_IGAM_LUT_RW_CONTROL;
- uint32_t CM_IGAM_LUT_RW_INDEX;
- uint32_t CM_IGAM_LUT_SEQ_COLOR;
- uint32_t FORMAT_CONTROL;
- uint32_t CNVC_SURFACE_PIXEL_FORMAT;
- uint32_t CURSOR_CONTROL;
- uint32_t CURSOR0_CONTROL;
- uint32_t CURSOR0_COLOR0;
- uint32_t CURSOR0_COLOR1;
+ DPP_COMMON_REG_VARIABLE_LIST
};
struct dcn10_dpp {
@@ -1284,6 +1283,10 @@ enum dcn10_input_csc_select {
INPUT_CSC_SELECT_COMA
};
+void dpp1_set_cursor_attributes(
+ struct dpp *dpp_base,
+ enum dc_cursor_color_format color_format);
+
bool dpp1_dscl_is_lb_conf_valid(
int ceil_vratio,
int num_partitions,
@@ -1371,7 +1374,7 @@ void dpp1_cm_program_regamma_lutb_settings(
const struct pwl_params *params);
void dpp1_cm_set_output_csc_adjustment(
struct dpp *dpp_base,
- const struct out_csc_color_matrix *tbl_entry);
+ const uint16_t *regval);
void dpp1_cm_set_output_csc_default(
struct dpp *dpp_base,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
index 4c90043e7b8c..a5b099023652 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
@@ -49,6 +49,8 @@
#define FN(reg_name, field_name) \
dpp->tf_shift->field_name, dpp->tf_mask->field_name
+#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
+
struct dcn10_input_csc_matrix {
enum dc_color_space color_space;
uint16_t regval[12];
@@ -223,18 +225,18 @@ void dpp1_cm_set_gamut_remap(
static void dpp1_cm_program_color_matrix(
struct dcn10_dpp *dpp,
- const struct out_csc_color_matrix *tbl_entry)
+ const uint16_t *regval)
{
uint32_t mode;
struct color_matrices_reg gam_regs;
REG_GET(CM_OCSC_CONTROL, CM_OCSC_MODE, &mode);
- if (tbl_entry == NULL) {
+ if (regval == NULL) {
BREAK_TO_DEBUGGER();
return;
}
-
+ mode = 4;
gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_OCSC_C11;
gam_regs.masks.csc_c11 = dpp->tf_mask->CM_OCSC_C11;
gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_OCSC_C12;
@@ -247,7 +249,7 @@ static void dpp1_cm_program_color_matrix(
cm_helper_program_color_matrices(
dpp->base.ctx,
- tbl_entry->regval,
+ regval,
&gam_regs);
} else {
@@ -257,7 +259,7 @@ static void dpp1_cm_program_color_matrix(
cm_helper_program_color_matrices(
dpp->base.ctx,
- tbl_entry->regval,
+ regval,
&gam_regs);
}
}
@@ -266,24 +268,18 @@ void dpp1_cm_set_output_csc_default(
struct dpp *dpp_base,
enum dc_color_space colorspace)
{
-
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
- struct out_csc_color_matrix tbl_entry;
- int i, j;
- int arr_size = sizeof(output_csc_matrix) / sizeof(struct output_csc_matrix);
+ const uint16_t *regval = NULL;
+ int arr_size;
uint32_t ocsc_mode = 4;
- tbl_entry.color_space = colorspace;
-
- for (i = 0; i < arr_size; i++)
- if (output_csc_matrix[i].color_space == colorspace) {
- for (j = 0; j < 12; j++)
- tbl_entry.regval[j] = output_csc_matrix[i].regval[j];
- break;
- }
-
+ regval = find_color_matrix(colorspace, &arr_size);
+ if (regval == NULL) {
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+ dpp1_cm_program_color_matrix(dpp, regval);
REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
- dpp1_cm_program_color_matrix(dpp, &tbl_entry);
}
static void dpp1_cm_get_reg_field(
@@ -315,41 +311,12 @@ static void dpp1_cm_get_reg_field(
void dpp1_cm_set_output_csc_adjustment(
struct dpp *dpp_base,
- const struct out_csc_color_matrix *tbl_entry)
+ const uint16_t *regval)
{
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
- //enum csc_color_mode config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
uint32_t ocsc_mode = 4;
-
- /**
- *if (tbl_entry != NULL) {
- * switch (tbl_entry->color_space) {
- * case COLOR_SPACE_SRGB:
- * case COLOR_SPACE_2020_RGB_FULLRANGE:
- * ocsc_mode = 0;
- * break;
- * case COLOR_SPACE_SRGB_LIMITED:
- * case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
- * ocsc_mode = 1;
- * break;
- * case COLOR_SPACE_YCBCR601:
- * case COLOR_SPACE_YCBCR601_LIMITED:
- * ocsc_mode = 2;
- * break;
- * case COLOR_SPACE_YCBCR709:
- * case COLOR_SPACE_YCBCR709_LIMITED:
- * case COLOR_SPACE_2020_YCBCR:
- * ocsc_mode = 3;
- * break;
- * case COLOR_SPACE_UNKNOWN:
- * default:
- * break;
- * }
- *}
- */
-
+ dpp1_cm_program_color_matrix(dpp, regval);
REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
- dpp1_cm_program_color_matrix(dpp, tbl_entry);
}
void dpp1_cm_power_on_regamma_lut(struct dpp *dpp_base,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index 584e82cc5df3..585b33384002 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -48,9 +48,20 @@ void hubp1_set_blank(struct hubp *hubp, bool blank)
HUBP_TTU_DISABLE, blank_en);
if (blank) {
- REG_WAIT(DCHUBP_CNTL,
- HUBP_NO_OUTSTANDING_REQ, 1,
- 1, 200);
+ uint32_t reg_val = REG_READ(DCHUBP_CNTL);
+
+ if (reg_val) {
+ /* init sequence workaround: in case HUBP is
+ * power gated, this wait would timeout.
+ *
+ * we just wrote reg_val to non-0, if it stay 0
+ * it means HUBP is gated
+ */
+ REG_WAIT(DCHUBP_CNTL,
+ HUBP_NO_OUTSTANDING_REQ, 1,
+ 1, 200);
+ }
+
hubp->mpcc_id = 0xf;
hubp->opp_id = 0xf;
}
@@ -96,10 +107,12 @@ static void hubp1_vready_workaround(struct hubp *hubp,
}
void hubp1_program_tiling(
- struct dcn10_hubp *hubp1,
+ struct hubp *hubp,
const union dc_tiling_info *info,
const enum surface_pixel_format pixel_format)
{
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+
REG_UPDATE_6(DCSURF_ADDR_CONFIG,
NUM_PIPES, log_2(info->gfx9.num_pipes),
NUM_BANKS, log_2(info->gfx9.num_banks),
@@ -116,13 +129,14 @@ void hubp1_program_tiling(
}
void hubp1_program_size_and_rotation(
- struct dcn10_hubp *hubp1,
+ struct hubp *hubp,
enum dc_rotation_angle rotation,
enum surface_pixel_format format,
const union plane_size *plane_size,
struct dc_plane_dcc_param *dcc,
bool horizontal_mirror)
{
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
uint32_t pitch, meta_pitch, pitch_c, meta_pitch_c, mirror;
/* Program data and meta surface pitch (calculation from addrlib)
@@ -178,9 +192,10 @@ void hubp1_program_size_and_rotation(
}
void hubp1_program_pixel_format(
- struct dcn10_hubp *hubp1,
+ struct hubp *hubp,
enum surface_pixel_format format)
{
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
uint32_t red_bar = 3;
uint32_t blue_bar = 2;
@@ -424,13 +439,11 @@ void hubp1_program_surface_config(
struct dc_plane_dcc_param *dcc,
bool horizontal_mirror)
{
- struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
-
hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks);
- hubp1_program_tiling(hubp1, tiling_info, format);
+ hubp1_program_tiling(hubp, tiling_info, format);
hubp1_program_size_and_rotation(
- hubp1, rotation, format, plane_size, dcc, horizontal_mirror);
- hubp1_program_pixel_format(hubp1, format);
+ hubp, rotation, format, plane_size, dcc, horizontal_mirror);
+ hubp1_program_pixel_format(hubp, format);
}
void hubp1_program_requestor(
@@ -765,42 +778,7 @@ void hubp1_read_state(struct dcn10_hubp *hubp1,
QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
}
-enum cursor_pitch {
- CURSOR_PITCH_64_PIXELS = 0,
- CURSOR_PITCH_128_PIXELS,
- CURSOR_PITCH_256_PIXELS
-};
-
-enum cursor_lines_per_chunk {
- CURSOR_LINE_PER_CHUNK_2 = 1,
- CURSOR_LINE_PER_CHUNK_4,
- CURSOR_LINE_PER_CHUNK_8,
- CURSOR_LINE_PER_CHUNK_16
-};
-
-static bool ippn10_cursor_program_control(
- struct dcn10_hubp *hubp1,
- bool pixel_data_invert,
- enum dc_cursor_color_format color_format)
-{
- if (REG(CURSOR_SETTINS))
- REG_SET_2(CURSOR_SETTINS, 0,
- /* no shift of the cursor HDL schedule */
- CURSOR0_DST_Y_OFFSET, 0,
- /* used to shift the cursor chunk request deadline */
- CURSOR0_CHUNK_HDL_ADJUST, 3);
- else
- REG_SET_2(CURSOR_SETTINGS, 0,
- /* no shift of the cursor HDL schedule */
- CURSOR0_DST_Y_OFFSET, 0,
- /* used to shift the cursor chunk request deadline */
- CURSOR0_CHUNK_HDL_ADJUST, 3);
-
- return true;
-}
-
-static enum cursor_pitch ippn10_get_cursor_pitch(
- unsigned int pitch)
+enum cursor_pitch hubp1_get_cursor_pitch(unsigned int pitch)
{
enum cursor_pitch hw_pitch;
@@ -823,7 +801,7 @@ static enum cursor_pitch ippn10_get_cursor_pitch(
return hw_pitch;
}
-static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
+static enum cursor_lines_per_chunk hubp1_get_lines_per_chunk(
unsigned int cur_width,
enum dc_cursor_color_format format)
{
@@ -849,8 +827,8 @@ void hubp1_cursor_set_attributes(
const struct dc_cursor_attributes *attr)
{
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
- enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
- enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
+ enum cursor_pitch hw_pitch = hubp1_get_cursor_pitch(attr->pitch);
+ enum cursor_lines_per_chunk lpc = hubp1_get_lines_per_chunk(
attr->width, attr->color_format);
hubp->curs_attr = *attr;
@@ -863,13 +841,17 @@ void hubp1_cursor_set_attributes(
REG_UPDATE_2(CURSOR_SIZE,
CURSOR_WIDTH, attr->width,
CURSOR_HEIGHT, attr->height);
+
REG_UPDATE_3(CURSOR_CONTROL,
CURSOR_MODE, attr->color_format,
CURSOR_PITCH, hw_pitch,
CURSOR_LINES_PER_CHUNK, lpc);
- ippn10_cursor_program_control(hubp1,
- attr->attribute_flags.bits.INVERT_PIXEL_DATA,
- attr->color_format);
+
+ REG_SET_2(CURSOR_SETTINS, 0,
+ /* no shift of the cursor HDL schedule */
+ CURSOR0_DST_Y_OFFSET, 0,
+ /* used to shift the cursor chunk request deadline */
+ CURSOR0_CHUNK_HDL_ADJUST, 3);
}
void hubp1_cursor_set_position(
@@ -909,7 +891,8 @@ void hubp1_cursor_set_position(
cur_en = 0; /* not visible beyond left edge*/
if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
- hubp1_cursor_set_attributes(hubp, &hubp->curs_attr);
+ hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
+
REG_UPDATE(CURSOR_CONTROL,
CURSOR_ENABLE, cur_en);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
index a7834dd50716..33e91d9c010f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
@@ -127,113 +127,110 @@
SRI(CURSOR_HOT_SPOT, CURSOR, id), \
SRI(CURSOR_DST_OFFSET, CURSOR, id)
-
-
-struct dcn_mi_registers {
- uint32_t DCHUBP_CNTL;
- uint32_t HUBPREQ_DEBUG_DB;
- uint32_t DCSURF_ADDR_CONFIG;
- uint32_t DCSURF_TILING_CONFIG;
- uint32_t DCSURF_SURFACE_PITCH;
- uint32_t DCSURF_SURFACE_PITCH_C;
- uint32_t DCSURF_SURFACE_CONFIG;
- uint32_t DCSURF_FLIP_CONTROL;
- uint32_t DCSURF_PRI_VIEWPORT_DIMENSION;
- uint32_t DCSURF_PRI_VIEWPORT_START;
- uint32_t DCSURF_SEC_VIEWPORT_DIMENSION;
- uint32_t DCSURF_SEC_VIEWPORT_START;
- uint32_t DCSURF_PRI_VIEWPORT_DIMENSION_C;
- uint32_t DCSURF_PRI_VIEWPORT_START_C;
- uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH;
- uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS;
- uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH;
- uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS;
- uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH;
- uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS;
- uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH;
- uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS;
- uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C;
- uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_C;
- uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C;
- uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_C;
- uint32_t DCSURF_SURFACE_INUSE;
- uint32_t DCSURF_SURFACE_INUSE_HIGH;
- uint32_t DCSURF_SURFACE_INUSE_C;
- uint32_t DCSURF_SURFACE_INUSE_HIGH_C;
- uint32_t DCSURF_SURFACE_EARLIEST_INUSE;
- uint32_t DCSURF_SURFACE_EARLIEST_INUSE_HIGH;
- uint32_t DCSURF_SURFACE_EARLIEST_INUSE_C;
- uint32_t DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C;
- uint32_t DCSURF_SURFACE_CONTROL;
- uint32_t HUBPRET_CONTROL;
- uint32_t DCN_EXPANSION_MODE;
- uint32_t DCHUBP_REQ_SIZE_CONFIG;
- uint32_t DCHUBP_REQ_SIZE_CONFIG_C;
- uint32_t BLANK_OFFSET_0;
- uint32_t BLANK_OFFSET_1;
- uint32_t DST_DIMENSIONS;
- uint32_t DST_AFTER_SCALER;
- uint32_t PREFETCH_SETTINS;
- uint32_t PREFETCH_SETTINGS;
- uint32_t VBLANK_PARAMETERS_0;
- uint32_t REF_FREQ_TO_PIX_FREQ;
- uint32_t VBLANK_PARAMETERS_1;
- uint32_t VBLANK_PARAMETERS_3;
- uint32_t NOM_PARAMETERS_0;
- uint32_t NOM_PARAMETERS_1;
- uint32_t NOM_PARAMETERS_4;
- uint32_t NOM_PARAMETERS_5;
- uint32_t PER_LINE_DELIVERY_PRE;
- uint32_t PER_LINE_DELIVERY;
- uint32_t PREFETCH_SETTINS_C;
- uint32_t PREFETCH_SETTINGS_C;
- uint32_t VBLANK_PARAMETERS_2;
- uint32_t VBLANK_PARAMETERS_4;
- uint32_t NOM_PARAMETERS_2;
- uint32_t NOM_PARAMETERS_3;
- uint32_t NOM_PARAMETERS_6;
- uint32_t NOM_PARAMETERS_7;
- uint32_t DCN_TTU_QOS_WM;
- uint32_t DCN_GLOBAL_TTU_CNTL;
- uint32_t DCN_SURF0_TTU_CNTL0;
- uint32_t DCN_SURF0_TTU_CNTL1;
- uint32_t DCN_SURF1_TTU_CNTL0;
- uint32_t DCN_SURF1_TTU_CNTL1;
- uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB;
- uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB;
- uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB;
- uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB;
- uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB;
- uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB;
- uint32_t DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB;
- uint32_t DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB;
- uint32_t DCN_VM_MX_L1_TLB_CNTL;
- uint32_t DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB;
- uint32_t DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB;
- uint32_t DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB;
- uint32_t DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB;
- uint32_t DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB;
- uint32_t DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB;
- uint32_t DCN_VM_SYSTEM_APERTURE_LOW_ADDR;
- uint32_t DCN_VM_SYSTEM_APERTURE_HIGH_ADDR;
- uint32_t DCHUBBUB_SDPIF_FB_BASE;
- uint32_t DCHUBBUB_SDPIF_FB_OFFSET;
- uint32_t DCN_VM_FB_LOCATION_TOP;
- uint32_t DCN_VM_FB_LOCATION_BASE;
- uint32_t DCN_VM_FB_OFFSET;
- uint32_t DCN_VM_AGP_BASE;
- uint32_t DCN_VM_AGP_BOT;
- uint32_t DCN_VM_AGP_TOP;
- uint32_t CURSOR_SETTINS;
- uint32_t CURSOR_SETTINGS;
- uint32_t CURSOR_SURFACE_ADDRESS_HIGH;
- uint32_t CURSOR_SURFACE_ADDRESS;
- uint32_t CURSOR_SIZE;
- uint32_t CURSOR_CONTROL;
- uint32_t CURSOR_POSITION;
- uint32_t CURSOR_HOT_SPOT;
- uint32_t CURSOR_DST_OFFSET;
-};
+#define HUBP_COMMON_REG_VARIABLE_LIST \
+ uint32_t DCHUBP_CNTL; \
+ uint32_t HUBPREQ_DEBUG_DB; \
+ uint32_t DCSURF_ADDR_CONFIG; \
+ uint32_t DCSURF_TILING_CONFIG; \
+ uint32_t DCSURF_SURFACE_PITCH; \
+ uint32_t DCSURF_SURFACE_PITCH_C; \
+ uint32_t DCSURF_SURFACE_CONFIG; \
+ uint32_t DCSURF_FLIP_CONTROL; \
+ uint32_t DCSURF_PRI_VIEWPORT_DIMENSION; \
+ uint32_t DCSURF_PRI_VIEWPORT_START; \
+ uint32_t DCSURF_SEC_VIEWPORT_DIMENSION; \
+ uint32_t DCSURF_SEC_VIEWPORT_START; \
+ uint32_t DCSURF_PRI_VIEWPORT_DIMENSION_C; \
+ uint32_t DCSURF_PRI_VIEWPORT_START_C; \
+ uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH; \
+ uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS; \
+ uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH; \
+ uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS; \
+ uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH; \
+ uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS; \
+ uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH; \
+ uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS; \
+ uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C; \
+ uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_C; \
+ uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C; \
+ uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_C; \
+ uint32_t DCSURF_SURFACE_INUSE; \
+ uint32_t DCSURF_SURFACE_INUSE_HIGH; \
+ uint32_t DCSURF_SURFACE_INUSE_C; \
+ uint32_t DCSURF_SURFACE_INUSE_HIGH_C; \
+ uint32_t DCSURF_SURFACE_EARLIEST_INUSE; \
+ uint32_t DCSURF_SURFACE_EARLIEST_INUSE_HIGH; \
+ uint32_t DCSURF_SURFACE_EARLIEST_INUSE_C; \
+ uint32_t DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C; \
+ uint32_t DCSURF_SURFACE_CONTROL; \
+ uint32_t HUBPRET_CONTROL; \
+ uint32_t DCN_EXPANSION_MODE; \
+ uint32_t DCHUBP_REQ_SIZE_CONFIG; \
+ uint32_t DCHUBP_REQ_SIZE_CONFIG_C; \
+ uint32_t BLANK_OFFSET_0; \
+ uint32_t BLANK_OFFSET_1; \
+ uint32_t DST_DIMENSIONS; \
+ uint32_t DST_AFTER_SCALER; \
+ uint32_t PREFETCH_SETTINS; \
+ uint32_t PREFETCH_SETTINGS; \
+ uint32_t VBLANK_PARAMETERS_0; \
+ uint32_t REF_FREQ_TO_PIX_FREQ; \
+ uint32_t VBLANK_PARAMETERS_1; \
+ uint32_t VBLANK_PARAMETERS_3; \
+ uint32_t NOM_PARAMETERS_0; \
+ uint32_t NOM_PARAMETERS_1; \
+ uint32_t NOM_PARAMETERS_4; \
+ uint32_t NOM_PARAMETERS_5; \
+ uint32_t PER_LINE_DELIVERY_PRE; \
+ uint32_t PER_LINE_DELIVERY; \
+ uint32_t PREFETCH_SETTINS_C; \
+ uint32_t PREFETCH_SETTINGS_C; \
+ uint32_t VBLANK_PARAMETERS_2; \
+ uint32_t VBLANK_PARAMETERS_4; \
+ uint32_t NOM_PARAMETERS_2; \
+ uint32_t NOM_PARAMETERS_3; \
+ uint32_t NOM_PARAMETERS_6; \
+ uint32_t NOM_PARAMETERS_7; \
+ uint32_t DCN_TTU_QOS_WM; \
+ uint32_t DCN_GLOBAL_TTU_CNTL; \
+ uint32_t DCN_SURF0_TTU_CNTL0; \
+ uint32_t DCN_SURF0_TTU_CNTL1; \
+ uint32_t DCN_SURF1_TTU_CNTL0; \
+ uint32_t DCN_SURF1_TTU_CNTL1; \
+ uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB; \
+ uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB; \
+ uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB; \
+ uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB; \
+ uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB; \
+ uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB; \
+ uint32_t DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB; \
+ uint32_t DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB; \
+ uint32_t DCN_VM_MX_L1_TLB_CNTL; \
+ uint32_t DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB; \
+ uint32_t DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB; \
+ uint32_t DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB; \
+ uint32_t DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB; \
+ uint32_t DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB; \
+ uint32_t DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB; \
+ uint32_t DCN_VM_SYSTEM_APERTURE_LOW_ADDR; \
+ uint32_t DCN_VM_SYSTEM_APERTURE_HIGH_ADDR; \
+ uint32_t DCHUBBUB_SDPIF_FB_BASE; \
+ uint32_t DCHUBBUB_SDPIF_FB_OFFSET; \
+ uint32_t DCN_VM_FB_LOCATION_TOP; \
+ uint32_t DCN_VM_FB_LOCATION_BASE; \
+ uint32_t DCN_VM_FB_OFFSET; \
+ uint32_t DCN_VM_AGP_BASE; \
+ uint32_t DCN_VM_AGP_BOT; \
+ uint32_t DCN_VM_AGP_TOP; \
+ uint32_t CURSOR_SETTINS; \
+ uint32_t CURSOR_SETTINGS; \
+ uint32_t CURSOR_SURFACE_ADDRESS_HIGH; \
+ uint32_t CURSOR_SURFACE_ADDRESS; \
+ uint32_t CURSOR_SIZE; \
+ uint32_t CURSOR_CONTROL; \
+ uint32_t CURSOR_POSITION; \
+ uint32_t CURSOR_HOT_SPOT; \
+ uint32_t CURSOR_DST_OFFSET
#define HUBP_SF(reg_name, field_name, post_fix)\
.field_name = reg_name ## __ ## field_name ## post_fix
@@ -397,7 +394,6 @@ struct dcn_mi_registers {
HUBP_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \
HUBP_SF(CURSOR0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh)
-
#define DCN_HUBP_REG_FIELD_LIST(type) \
type HUBP_BLANK_EN;\
type HUBP_TTU_DISABLE;\
@@ -577,6 +573,10 @@ struct dcn_mi_registers {
type CURSOR_DST_X_OFFSET; \
type OUTPUT_FP
+struct dcn_mi_registers {
+ HUBP_COMMON_REG_VARIABLE_LIST;
+};
+
struct dcn_mi_shift {
DCN_HUBP_REG_FIELD_LIST(uint8_t);
};
@@ -611,11 +611,11 @@ void hubp1_program_requestor(
struct _vcs_dpi_display_rq_regs_st *rq_regs);
void hubp1_program_pixel_format(
- struct dcn10_hubp *hubp,
+ struct hubp *hubp,
enum surface_pixel_format format);
void hubp1_program_size_and_rotation(
- struct dcn10_hubp *hubp,
+ struct hubp *hubp,
enum dc_rotation_angle rotation,
enum surface_pixel_format format,
const union plane_size *plane_size,
@@ -623,7 +623,7 @@ void hubp1_program_size_and_rotation(
bool horizontal_mirror);
void hubp1_program_tiling(
- struct dcn10_hubp *hubp,
+ struct hubp *hubp,
const union dc_tiling_info *info,
const enum surface_pixel_format pixel_format);
@@ -681,4 +681,6 @@ struct dcn_hubp_state {
void hubp1_read_state(struct dcn10_hubp *hubp1,
struct dcn_hubp_state *s);
+enum cursor_pitch hubp1_get_cursor_pitch(unsigned int pitch);
+
#endif
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 8e2ddbc2129c..82572863acab 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"
@@ -43,6 +43,7 @@
#include "custom_float.h"
#include "dcn10_hubp.h"
#include "dcn10_hubbub.h"
+#include "dcn10_cm_common.h"
#define CTX \
hws->ctx
@@ -158,7 +159,7 @@ void dcn10_log_hw_state(struct dc *dc)
struct timing_generator *tg = pool->timing_generators[i];
struct dcn_otg_state s = {0};
- tgn10_read_otg_state(DCN10TG_FROM_TG(tg), &s);
+ optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
//only print if OTG master is enabled
if ((s.otg_enabled & 1) == 0)
@@ -425,6 +426,34 @@ static void bios_golden_init(struct dc *dc)
}
}
+static void false_optc_underflow_wa(
+ struct dc *dc,
+ const struct dc_stream_state *stream,
+ struct timing_generator *tg)
+{
+ int i;
+ bool underflow;
+
+ if (!dc->hwseq->wa.false_optc_underflow)
+ return;
+
+ underflow = tg->funcs->is_optc_underflow_occurred(tg);
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+
+ if (old_pipe_ctx->stream != stream)
+ continue;
+
+ dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, old_pipe_ctx);
+ }
+
+ tg->funcs->set_blank_data_double_buffer(tg, true);
+
+ if (tg->funcs->is_optc_underflow_occurred(tg) && !underflow)
+ tg->funcs->clear_optc_underflow(tg);
+}
+
static enum dc_status dcn10_prog_pixclk_crtc_otg(
struct pipe_ctx *pipe_ctx,
struct dc_state *context,
@@ -433,9 +462,6 @@ static enum dc_status dcn10_prog_pixclk_crtc_otg(
struct dc_stream_state *stream = pipe_ctx->stream;
enum dc_color_space color_space;
struct tg_color black_color = {0};
- bool enableStereo = stream->timing.timing_3d_format == TIMING_3D_FORMAT_NONE ?
- false:true;
- bool rightEyePolarity = stream->timing.flags.RIGHT_EYE_3D_POLARITY;
/* 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
@@ -470,11 +496,6 @@ static enum dc_status dcn10_prog_pixclk_crtc_otg(
&stream->timing,
true);
- pipe_ctx->stream_res.opp->funcs->opp_set_stereo_polarity(
- pipe_ctx->stream_res.opp,
- enableStereo,
- rightEyePolarity);
-
#if 0 /* move to after enable_crtc */
/* TODO: OPP FMT, ABM. etc. should be done here. */
/* or FPGA now. instance 0 only. TODO: move to opp.c */
@@ -489,12 +510,18 @@ 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);
- pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true);
- hwss_wait_for_blank_complete(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);
+ }
/* VTG is within DCHUB command block. DCFCLK is always on */
if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc(pipe_ctx->stream_res.tg)) {
@@ -573,41 +600,34 @@ static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
int fe_idx = pipe_ctx->pipe_idx;
struct hubp *hubp = dc->res_pool->hubps[fe_idx];
struct mpc *mpc = dc->res_pool->mpc;
- int opp_id, z_idx;
- int mpcc_id = -1;
+ int opp_id;
+ struct mpc_tree *mpc_tree_params;
+ struct mpcc *mpcc_to_remove = NULL;
/* look at tree rather than mi here to know if we already reset */
for (opp_id = 0; opp_id < dc->res_pool->pipe_count; opp_id++) {
struct output_pixel_processor *opp = dc->res_pool->opps[opp_id];
- for (z_idx = 0; z_idx < opp->mpc_tree.num_pipes; z_idx++) {
- if (opp->mpc_tree.dpp[z_idx] == fe_idx) {
- mpcc_id = opp->mpc_tree.mpcc[z_idx];
- break;
- }
- }
- if (mpcc_id != -1)
+ mpc_tree_params = &(opp->mpc_tree_params);
+ mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, fe_idx);
+ if (mpcc_to_remove != NULL)
break;
}
+
/*Already reset*/
if (opp_id == dc->res_pool->pipe_count)
return;
- mpc->funcs->remove(mpc, &(dc->res_pool->opps[opp_id]->mpc_tree),
- dc->res_pool->opps[opp_id]->inst, fe_idx);
+ mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
+ dc->res_pool->opps[opp_id]->mpcc_disconnect_pending[fe_idx] = true;
+
+ dc->optimized_required = true;
if (hubp->funcs->hubp_disconnect)
hubp->funcs->hubp_disconnect(hubp);
if (dc->debug.sanity_checks)
dcn10_verify_allow_pstate_change_high(dc);
-
- pipe_ctx->stream = NULL;
- memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
- memset(&pipe_ctx->plane_res, 0, sizeof(pipe_ctx->plane_res));
- pipe_ctx->top_pipe = NULL;
- pipe_ctx->bottom_pipe = NULL;
- pipe_ctx->plane_state = NULL;
}
static void plane_atomic_power_down(struct dc *dc, int fe_idx)
@@ -636,29 +656,30 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
int fe_idx = pipe_ctx->pipe_idx;
struct dce_hwseq *hws = dc->hwseq;
struct hubp *hubp = dc->res_pool->hubps[fe_idx];
- struct mpc *mpc = dc->res_pool->mpc;
int opp_id = hubp->opp_id;
- struct output_pixel_processor *opp;
- if (opp_id != 0xf) {
- mpc->funcs->wait_for_idle(mpc, hubp->mpcc_id);
- opp = dc->res_pool->opps[hubp->opp_id];
- opp->mpcc_disconnect_pending[hubp->mpcc_id] = false;
- hubp->funcs->set_blank(hubp, true);
- }
+ dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
REG_UPDATE(HUBP_CLK_CNTL[fe_idx],
HUBP_CLOCK_ENABLE, 0);
REG_UPDATE(DPP_CONTROL[fe_idx],
DPP_CLOCK_ENABLE, 0);
- if (opp_id != 0xf && dc->res_pool->opps[opp_id]->mpc_tree.num_pipes == 0)
+ if (opp_id != 0xf && dc->res_pool->opps[opp_id]->mpc_tree_params.opp_list == NULL)
REG_UPDATE(OPP_PIPE_CONTROL[opp_id],
OPP_PIPE_CLOCK_EN, 0);
hubp->power_gated = true;
+ dc->optimized_required = false; /* We're powering off, no need to optimize */
plane_atomic_power_down(dc, fe_idx);
+
+ pipe_ctx->stream = NULL;
+ memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
+ memset(&pipe_ctx->plane_res, 0, sizeof(pipe_ctx->plane_res));
+ pipe_ctx->top_pipe = NULL;
+ pipe_ctx->bottom_pipe = NULL;
+ pipe_ctx->plane_state = NULL;
}
static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
@@ -740,25 +761,27 @@ static void dcn10_init_hw(struct dc *dc)
}
}
+ /* Reset all MPCC muxes */
+ dc->res_pool->mpc->funcs->mpc_init(dc->res_pool->mpc);
+
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct timing_generator *tg = dc->res_pool->timing_generators[i];
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
- struct output_pixel_processor *opp = dc->res_pool->opps[i];
- struct mpc_tree_cfg *mpc_tree = &opp->mpc_tree;
struct hubp *hubp = dc->res_pool->hubps[i];
- mpc_tree->dpp[0] = i;
- mpc_tree->mpcc[0] = i;
- mpc_tree->num_pipes = 1;
-
pipe_ctx->stream_res.tg = tg;
pipe_ctx->pipe_idx = i;
pipe_ctx->plane_res.hubp = hubp;
hubp->mpcc_id = i;
- hubp->opp_id = dc->res_pool->mpc->funcs->get_opp_id(dc->res_pool->mpc, i);
+ hubp->opp_id = 0xf;
hubp->power_gated = false;
+ dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
+ dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
+ dc->res_pool->opps[i]->mpcc_disconnect_pending[i] = true;
+ pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
+
plane_atomic_disconnect(dc, pipe_ctx);
}
@@ -929,280 +952,10 @@ static bool dcn10_set_input_transfer_func(struct pipe_ctx *pipe_ctx,
return result;
}
-/*modify the method to handle rgb for arr_points*/
-static bool convert_to_custom_float(
- struct pwl_result_data *rgb_resulted,
- struct curve_points *arr_points,
- uint32_t hw_points_num)
-{
- struct custom_float_format fmt;
-
- struct pwl_result_data *rgb = rgb_resulted;
-
- uint32_t i = 0;
-
- fmt.exponenta_bits = 6;
- fmt.mantissa_bits = 12;
- fmt.sign = false;
-
- if (!convert_to_custom_float_format(arr_points[0].x, &fmt,
- &arr_points[0].custom_float_x)) {
- BREAK_TO_DEBUGGER();
- return false;
- }
-
- if (!convert_to_custom_float_format(arr_points[0].offset, &fmt,
- &arr_points[0].custom_float_offset)) {
- BREAK_TO_DEBUGGER();
- return false;
- }
-
- if (!convert_to_custom_float_format(arr_points[0].slope, &fmt,
- &arr_points[0].custom_float_slope)) {
- BREAK_TO_DEBUGGER();
- return false;
- }
-
- fmt.mantissa_bits = 10;
- fmt.sign = false;
-
- if (!convert_to_custom_float_format(arr_points[1].x, &fmt,
- &arr_points[1].custom_float_x)) {
- BREAK_TO_DEBUGGER();
- return false;
- }
-
- if (!convert_to_custom_float_format(arr_points[1].y, &fmt,
- &arr_points[1].custom_float_y)) {
- BREAK_TO_DEBUGGER();
- return false;
- }
-
- if (!convert_to_custom_float_format(arr_points[1].slope, &fmt,
- &arr_points[1].custom_float_slope)) {
- BREAK_TO_DEBUGGER();
- return false;
- }
- fmt.mantissa_bits = 12;
- fmt.sign = true;
- while (i != hw_points_num) {
- if (!convert_to_custom_float_format(rgb->red, &fmt,
- &rgb->red_reg)) {
- BREAK_TO_DEBUGGER();
- return false;
- }
-
- if (!convert_to_custom_float_format(rgb->green, &fmt,
- &rgb->green_reg)) {
- BREAK_TO_DEBUGGER();
- return false;
- }
- if (!convert_to_custom_float_format(rgb->blue, &fmt,
- &rgb->blue_reg)) {
- BREAK_TO_DEBUGGER();
- return false;
- }
- if (!convert_to_custom_float_format(rgb->delta_red, &fmt,
- &rgb->delta_red_reg)) {
- BREAK_TO_DEBUGGER();
- return false;
- }
-
- if (!convert_to_custom_float_format(rgb->delta_green, &fmt,
- &rgb->delta_green_reg)) {
- BREAK_TO_DEBUGGER();
- return false;
- }
-
- if (!convert_to_custom_float_format(rgb->delta_blue, &fmt,
- &rgb->delta_blue_reg)) {
- BREAK_TO_DEBUGGER();
- return false;
- }
-
- ++rgb;
- ++i;
- }
-
- return true;
-}
-#define MAX_REGIONS_NUMBER 34
-#define MAX_LOW_POINT 25
-#define NUMBER_SEGMENTS 32
-
-static bool
-dcn10_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
- struct pwl_params *regamma_params)
-{
- struct curve_points *arr_points;
- struct pwl_result_data *rgb_resulted;
- struct pwl_result_data *rgb;
- struct pwl_result_data *rgb_plus_1;
- struct fixed31_32 y_r;
- struct fixed31_32 y_g;
- struct fixed31_32 y_b;
- struct fixed31_32 y1_min;
- struct fixed31_32 y3_max;
-
- int32_t segment_start, segment_end;
- int32_t i;
- uint32_t j, k, seg_distr[MAX_REGIONS_NUMBER], increment, start_index, hw_points;
-
- if (output_tf == NULL || regamma_params == NULL || output_tf->type == TF_TYPE_BYPASS)
- return false;
-
- PERF_TRACE();
-
- arr_points = regamma_params->arr_points;
- rgb_resulted = regamma_params->rgb_resulted;
- hw_points = 0;
-
- memset(regamma_params, 0, sizeof(struct pwl_params));
- memset(seg_distr, 0, sizeof(seg_distr));
-
- if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
- /* 32 segments
- * segments are from 2^-25 to 2^7
- */
- for (i = 0; i < 32 ; i++)
- seg_distr[i] = 3;
-
- segment_start = -25;
- segment_end = 7;
- } else {
- /* 10 segments
- * segment is from 2^-10 to 2^0
- * There are less than 256 points, for optimization
- */
- seg_distr[0] = 3;
- seg_distr[1] = 4;
- seg_distr[2] = 4;
- seg_distr[3] = 4;
- seg_distr[4] = 4;
- seg_distr[5] = 4;
- seg_distr[6] = 4;
- seg_distr[7] = 4;
- seg_distr[8] = 5;
- seg_distr[9] = 5;
-
- segment_start = -10;
- segment_end = 0;
- }
-
- for (i = segment_end - segment_start; i < MAX_REGIONS_NUMBER ; i++)
- seg_distr[i] = -1;
-
- for (k = 0; k < MAX_REGIONS_NUMBER; k++) {
- if (seg_distr[k] != -1)
- hw_points += (1 << seg_distr[k]);
- }
-
- j = 0;
- for (k = 0; k < (segment_end - segment_start); k++) {
- increment = NUMBER_SEGMENTS / (1 << seg_distr[k]);
- start_index = (segment_start + k + MAX_LOW_POINT) * NUMBER_SEGMENTS;
- for (i = start_index; i < start_index + NUMBER_SEGMENTS; i += increment) {
- if (j == hw_points - 1)
- break;
- rgb_resulted[j].red = output_tf->tf_pts.red[i];
- rgb_resulted[j].green = output_tf->tf_pts.green[i];
- rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
- j++;
- }
- }
-
- /* last point */
- start_index = (segment_end + MAX_LOW_POINT) * NUMBER_SEGMENTS;
- rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index];
- rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
- rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
-
- arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
- dal_fixed31_32_from_int(segment_start));
- arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
- dal_fixed31_32_from_int(segment_end));
-
- y_r = rgb_resulted[0].red;
- y_g = rgb_resulted[0].green;
- y_b = rgb_resulted[0].blue;
-
- y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b));
-
- arr_points[0].y = y1_min;
- arr_points[0].slope = dal_fixed31_32_div(arr_points[0].y, arr_points[0].x);
- y_r = rgb_resulted[hw_points - 1].red;
- y_g = rgb_resulted[hw_points - 1].green;
- y_b = rgb_resulted[hw_points - 1].blue;
-
- /* see comment above, m_arrPoints[1].y should be the Y value for the
- * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
- */
- y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b));
-
- arr_points[1].y = y3_max;
-
- arr_points[1].slope = dal_fixed31_32_zero;
-
- if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
- /* for PQ, we want to have a straight line from last HW X point,
- * and the slope to be such that we hit 1.0 at 10000 nits.
- */
- const struct fixed31_32 end_value =
- dal_fixed31_32_from_int(125);
-
- arr_points[1].slope = dal_fixed31_32_div(
- dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y),
- dal_fixed31_32_sub(end_value, arr_points[1].x));
- }
-
- regamma_params->hw_points_num = hw_points;
-
- i = 1;
- for (k = 0; k < MAX_REGIONS_NUMBER && i < MAX_REGIONS_NUMBER; k++) {
- if (seg_distr[k] != -1) {
- regamma_params->arr_curve_points[k].segments_num =
- seg_distr[k];
- regamma_params->arr_curve_points[i].offset =
- regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]);
- }
- i++;
- }
-
- if (seg_distr[k] != -1)
- regamma_params->arr_curve_points[k].segments_num = seg_distr[k];
-
- rgb = rgb_resulted;
- rgb_plus_1 = rgb_resulted + 1;
-
- i = 1;
-
- while (i != hw_points + 1) {
- if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red))
- rgb_plus_1->red = rgb->red;
- if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green))
- rgb_plus_1->green = rgb->green;
- if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue))
- rgb_plus_1->blue = rgb->blue;
-
- rgb->delta_red = dal_fixed31_32_sub(rgb_plus_1->red, rgb->red);
- rgb->delta_green = dal_fixed31_32_sub(rgb_plus_1->green, rgb->green);
- rgb->delta_blue = dal_fixed31_32_sub(rgb_plus_1->blue, rgb->blue);
-
- ++rgb_plus_1;
- ++rgb;
- ++i;
- }
-
- convert_to_custom_float(rgb_resulted, arr_points, hw_points);
-
- PERF_TRACE();
-
- return true;
-}
static bool
dcn10_set_output_transfer_func(struct pipe_ctx *pipe_ctx,
@@ -1223,9 +976,9 @@ dcn10_set_output_transfer_func(struct pipe_ctx *pipe_ctx,
/* dcn10_translate_regamma_to_hw_format takes 750us, only do it when full
* update.
*/
- else if (dcn10_translate_regamma_to_hw_format(
+ else if (cm_helper_translate_curve_to_hw_format(
stream->out_transfer_func,
- &dpp->regamma_params)) {
+ &dpp->regamma_params, false)) {
dpp->funcs->dpp_program_regamma_pwl(
dpp,
&dpp->regamma_params, OPP_REGAMMA_USER);
@@ -1579,7 +1332,6 @@ static void dcn10_enable_plane(
/* make sure OPP_PIPE_CLOCK_EN = 1 */
REG_UPDATE(OPP_PIPE_CONTROL[pipe_ctx->stream_res.tg->inst],
OPP_PIPE_CLOCK_EN, 1);
- /*TODO: REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, 0x1f);*/
/* TODO: enable/disable in dm as per update type.
if (plane_state) {
@@ -1672,60 +1424,15 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
enum dc_color_space colorspace,
uint16_t *matrix)
{
- int i;
- struct out_csc_color_matrix tbl_entry;
-
if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
- enum dc_color_space color_space =
- pipe_ctx->stream->output_color_space;
-
- //uint16_t matrix[12];
- for (i = 0; i < 12; i++)
- tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i];
-
- tbl_entry.color_space = color_space;
- //tbl_entry.regval = matrix;
-
if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL)
- pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, &tbl_entry);
+ pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix);
} else {
if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default != NULL)
pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default(pipe_ctx->plane_res.dpp, colorspace);
}
}
-static void set_mpc_output_csc(struct dc *dc,
- struct pipe_ctx *pipe_ctx,
- enum dc_color_space colorspace,
- uint16_t *matrix,
- int opp_id)
-{
- struct mpc *mpc = dc->res_pool->mpc;
- int i;
- struct out_csc_color_matrix tbl_entry;
- enum mpc_output_csc_mode ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
-
-
- if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
- //uint16_t matrix[12];
- for (i = 0; i < 12; i++)
- tbl_entry.regval[i] = matrix[i];
- tbl_entry.color_space = colorspace;
-
- if (mpc->funcs->set_output_csc != NULL)
- mpc->funcs->set_output_csc(mpc,
- opp_id,
- &tbl_entry,
- ocsc_mode);
- } else {
- if (mpc->funcs->set_ocsc_default != NULL)
- mpc->funcs->set_ocsc_default(mpc,
- opp_id,
- colorspace,
- ocsc_mode);
- }
-}
-
static void program_output_csc(struct dc *dc,
struct pipe_ctx *pipe_ctx,
enum dc_color_space colorspace,
@@ -1736,13 +1443,6 @@ static void program_output_csc(struct dc *dc,
program_csc_matrix(pipe_ctx,
colorspace,
matrix);
- else
- set_mpc_output_csc(dc,
- pipe_ctx,
- colorspace,
- matrix,
- opp_id);
-
}
static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
@@ -1914,35 +1614,73 @@ static void update_dpp(struct dpp *dpp, struct dc_plane_state *plane_state)
static void update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
- struct mpcc_cfg mpcc_cfg = {0};
struct hubp *hubp = pipe_ctx->plane_res.hubp;
- struct pipe_ctx *top_pipe;
- bool per_pixel_alpha =
- pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
+ struct mpcc_blnd_cfg blnd_cfg;
+ bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
+ int mpcc_id;
+ struct mpcc *new_mpcc;
+ struct mpc *mpc = dc->res_pool->mpc;
+ struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
/* TODO: proper fix once fpga works */
- mpcc_cfg.dpp_id = hubp->inst;
- mpcc_cfg.opp_id = pipe_ctx->stream_res.opp->inst;
- mpcc_cfg.tree_cfg = &(pipe_ctx->stream_res.opp->mpc_tree);
- for (top_pipe = pipe_ctx->top_pipe; top_pipe; top_pipe = top_pipe->top_pipe)
- mpcc_cfg.z_index++;
if (dc->debug.surface_visual_confirm)
dcn10_get_surface_visual_confirm_color(
- pipe_ctx, &mpcc_cfg.black_color);
+ pipe_ctx, &blnd_cfg.black_color);
else
color_space_to_black_color(
dc, pipe_ctx->stream->output_color_space,
- &mpcc_cfg.black_color);
- mpcc_cfg.per_pixel_alpha = per_pixel_alpha;
+ &blnd_cfg.black_color);
+
+ if (per_pixel_alpha)
+ blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
+ else
+ blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;
+
+ blnd_cfg.overlap_only = false;
+ blnd_cfg.global_alpha = 0xff;
+ blnd_cfg.global_gain = 0xff;
+
/* DCN1.0 has output CM before MPC which seems to screw with
* pre-multiplied alpha.
*/
- mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace(
+ blnd_cfg.pre_multiplied_alpha = is_rgb_cspace(
pipe_ctx->stream->output_color_space)
&& per_pixel_alpha;
- hubp->mpcc_id = dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg);
- hubp->opp_id = mpcc_cfg.opp_id;
+
+ /*
+ * TODO: remove hack
+ * Note: currently there is a bug in init_hw such that
+ * on resume from hibernate, BIOS sets up MPCC0, and
+ * we do mpcc_remove but the mpcc cannot go to idle
+ * after remove. This cause us to pick mpcc1 here,
+ * which causes a pstate hang for yet unknown reason.
+ */
+ mpcc_id = hubp->inst;
+
+ /* check if this MPCC is already being used */
+ new_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, mpcc_id);
+ /* remove MPCC if being used */
+ if (new_mpcc != NULL)
+ mpc->funcs->remove_mpcc(mpc, mpc_tree_params, new_mpcc);
+ else
+ if (dc->debug.sanity_checks)
+ mpc->funcs->assert_mpcc_idle_before_connect(
+ dc->res_pool->mpc, mpcc_id);
+
+ /* Call MPC to insert new plane */
+ new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc,
+ mpc_tree_params,
+ &blnd_cfg,
+ NULL,
+ NULL,
+ hubp->inst,
+ mpcc_id);
+
+ ASSERT(new_mpcc != NULL);
+
+ hubp->opp_id = pipe_ctx->stream_res.opp->inst;
+ hubp->mpcc_id = mpcc_id;
}
static void update_scaler(struct pipe_ctx *pipe_ctx)
@@ -1971,7 +1709,7 @@ static void update_dchubp_dpp(
union plane_size size = plane_state->plane_size;
/* depends on DML calculation, DPP clock value may change dynamically */
- if (pipe_ctx->plane_state->update_flags.raw != 0) {
+ if (plane_state->update_flags.bits.full_update) {
enable_dppclk(
dc->hwseq,
pipe_ctx->pipe_idx,
@@ -2015,7 +1753,8 @@ static void update_dchubp_dpp(
}
if (plane_state->update_flags.bits.full_update ||
- plane_state->update_flags.bits.scaling_change) {
+ plane_state->update_flags.bits.scaling_change ||
+ plane_state->update_flags.bits.position_change) {
hubp->funcs->mem_program_viewport(
hubp,
&pipe_ctx->plane_res.scl_data.viewport,
@@ -2037,7 +1776,9 @@ static void update_dchubp_dpp(
plane_state->update_flags.bits.horizontal_mirror_change ||
plane_state->update_flags.bits.rotation_change ||
plane_state->update_flags.bits.swizzle_change ||
- plane_state->update_flags.bits.bpp_change) {
+ plane_state->update_flags.bits.dcc_change ||
+ plane_state->update_flags.bits.bpp_change ||
+ plane_state->update_flags.bits.scaling_change) {
hubp->funcs->hubp_program_surface_config(
hubp,
plane_state->format,
@@ -2062,6 +1803,7 @@ static void program_all_pipe_in_tree(
struct pipe_ctx *pipe_ctx,
struct dc_state *context)
{
+
if (pipe_ctx->top_pipe == NULL) {
pipe_ctx->stream_res.tg->dlg_otg_param.vready_offset = pipe_ctx->pipe_dlg_param.vready_offset;
@@ -2072,7 +1814,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) {
@@ -2179,6 +1925,7 @@ 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;
@@ -2189,6 +1936,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);
@@ -2196,7 +1945,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 */
@@ -2236,24 +1986,14 @@ static void dcn10_apply_ctx_for_surface(
}
}
- if (num_planes > 0) {
+ if (num_planes > 0)
program_all_pipe_in_tree(dc, top_pipe_to_program, context);
- /* TODO: this is a hack w/a for switching from mpo to pipe split */
- if (stream->cursor_attributes.address.quad_part != 0) {
- struct dc_cursor_position position = { 0 };
-
- dc_stream_set_cursor_position(
- (struct dc_stream_state *)stream,
- &position);
- dc_stream_set_cursor_attributes(
- (struct dc_stream_state *)stream,
- &stream->cursor_attributes);
- }
- }
-
tg->funcs->unlock(tg);
+ if (num_planes == 0)
+ false_optc_underflow_wa(dc, stream, tg);
+
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *old_pipe_ctx =
&dc->current_state->res_ctx.pipe_ctx[i];
@@ -2264,7 +2004,7 @@ static void dcn10_apply_ctx_for_surface(
pipe_ctx->plane_state->update_flags.bits.full_update)
program_water_mark = true;
- if (removed_pipe[i] && num_planes == 0)
+ if (removed_pipe[i])
dcn10_disable_plane(dc, old_pipe_ctx);
}
@@ -2273,6 +2013,7 @@ static void dcn10_apply_ctx_for_surface(
/* pstate stuck check after watermark update */
dcn10_verify_allow_pstate_change_high(dc);
}
+
/* watermark is for all pipes */
hubbub1_program_watermarks(dc->res_pool->hubbub,
&context->bw.dcn.watermarks, ref_clk_mhz);
@@ -2502,10 +2243,10 @@ static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc)
dcn10_config_stereo_parameters(stream, &flags);
- pipe_ctx->stream_res.opp->funcs->opp_set_stereo_polarity(
+ pipe_ctx->stream_res.opp->funcs->opp_program_stereo(
pipe_ctx->stream_res.opp,
flags.PROGRAM_STEREO == 1 ? true:false,
- stream->timing.flags.RIGHT_EYE_3D_POLARITY == 1 ? true:false);
+ &stream->timing);
pipe_ctx->stream_res.tg->funcs->program_stereo(
pipe_ctx->stream_res.tg,
@@ -2619,7 +2360,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.pplib_apply_display_requirements =
dcn10_pplib_apply_display_requirements,
.edp_backlight_control = hwss_edp_backlight_control,
- .edp_power_control = hwss_edp_power_control
+ .edp_power_control = hwss_edp_power_control,
+ .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
};
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
index b016f4cbd45c..179890b1a8c4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
@@ -25,8 +25,6 @@
#include "reg_helper.h"
#include "dcn10_mpc.h"
-#include "dc.h"
-#include "mem_input.h"
#define REG(reg)\
mpc10->mpc_regs->reg
@@ -38,17 +36,13 @@
#define FN(reg_name, field_name) \
mpc10->mpc_shift->field_name, mpc10->mpc_mask->field_name
-#define MODE_TOP_ONLY 1
-#define MODE_BLEND 3
-#define BLND_PP_ALPHA 0
-#define BLND_GLOBAL_ALPHA 2
-
-static void mpc10_set_bg_color(
- struct dcn10_mpc *mpc10,
+void mpc1_set_bg_color(struct mpc *mpc,
struct tg_color *bg_color,
- int id)
+ int mpcc_id)
{
+ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
+
/* mpc color is 12 bit. tg_color is 10 bit */
/* todo: might want to use 16 bit to represent color and have each
* hw block translate to correct color depth.
@@ -57,15 +51,47 @@ static void mpc10_set_bg_color(
uint32_t bg_g_y = bg_color->color_g_y << 2;
uint32_t bg_b_cb = bg_color->color_b_cb << 2;
- REG_SET(MPCC_BG_R_CR[id], 0,
+ REG_SET(MPCC_BG_R_CR[mpcc_id], 0,
MPCC_BG_R_CR, bg_r_cr);
- REG_SET(MPCC_BG_G_Y[id], 0,
+ REG_SET(MPCC_BG_G_Y[mpcc_id], 0,
MPCC_BG_G_Y, bg_g_y);
- REG_SET(MPCC_BG_B_CB[id], 0,
+ REG_SET(MPCC_BG_B_CB[mpcc_id], 0,
MPCC_BG_B_CB, bg_b_cb);
}
-void mpc10_assert_idle_mpcc(struct mpc *mpc, int id)
+static void mpc1_update_blending(
+ struct mpc *mpc,
+ struct mpcc_blnd_cfg *blnd_cfg,
+ int mpcc_id)
+{
+ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
+
+ REG_UPDATE_5(MPCC_CONTROL[mpcc_id],
+ MPCC_ALPHA_BLND_MODE, blnd_cfg->alpha_mode,
+ MPCC_ALPHA_MULTIPLIED_MODE, blnd_cfg->pre_multiplied_alpha,
+ MPCC_BLND_ACTIVE_OVERLAP_ONLY, blnd_cfg->overlap_only,
+ MPCC_GLOBAL_ALPHA, blnd_cfg->global_alpha,
+ MPCC_GLOBAL_GAIN, blnd_cfg->global_gain);
+
+ mpc1_set_bg_color(mpc, &blnd_cfg->black_color, mpcc_id);
+}
+
+void mpc1_update_stereo_mix(
+ struct mpc *mpc,
+ struct mpcc_sm_cfg *sm_cfg,
+ int mpcc_id)
+{
+ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
+
+ REG_UPDATE_6(MPCC_SM_CONTROL[mpcc_id],
+ MPCC_SM_EN, sm_cfg->enable,
+ MPCC_SM_MODE, sm_cfg->sm_mode,
+ MPCC_SM_FRAME_ALT, sm_cfg->frame_alt,
+ MPCC_SM_FIELD_ALT, sm_cfg->field_alt,
+ MPCC_SM_FORCE_NEXT_FRAME_POL, sm_cfg->force_next_frame_porlarity,
+ MPCC_SM_FORCE_NEXT_TOP_POL, sm_cfg->force_next_field_polarity);
+}
+void mpc1_assert_idle_mpcc(struct mpc *mpc, int id)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
@@ -75,39 +101,52 @@ void mpc10_assert_idle_mpcc(struct mpc *mpc, int id)
1, 100000);
}
-static int mpc10_get_idle_mpcc_id(struct dcn10_mpc *mpc10)
+struct mpcc *mpc1_get_mpcc(struct mpc *mpc, int mpcc_id)
{
- int i;
- int last_free_mpcc_id = -1;
+ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
- for (i = 0; i < mpc10->num_mpcc; i++) {
- uint32_t is_idle = 0;
+ ASSERT(mpcc_id < mpc10->num_mpcc);
+ return &(mpc->mpcc_array[mpcc_id]);
+}
- if (mpc10->mpcc_in_use_mask & 1 << i)
- continue;
+struct mpcc *mpc1_get_mpcc_for_dpp(struct mpc_tree *tree, int dpp_id)
+{
+ struct mpcc *tmp_mpcc = tree->opp_list;
- last_free_mpcc_id = i;
- REG_GET(MPCC_STATUS[i], MPCC_IDLE, &is_idle);
- if (is_idle)
- return i;
+ while (tmp_mpcc != NULL) {
+ if (tmp_mpcc->dpp_id == dpp_id)
+ return tmp_mpcc;
+ tmp_mpcc = tmp_mpcc->mpcc_bot;
}
+ return NULL;
+}
- /* This assert should never trigger, we have mpcc leak if it does */
- ASSERT(last_free_mpcc_id != -1);
-
- mpc10_assert_idle_mpcc(&mpc10->base, last_free_mpcc_id);
- return last_free_mpcc_id;
+bool mpc1_is_mpcc_idle(struct mpc *mpc, int mpcc_id)
+{
+ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
+ unsigned int top_sel;
+ unsigned int opp_id;
+ unsigned int idle;
+
+ REG_GET(MPCC_TOP_SEL[mpcc_id], MPCC_TOP_SEL, &top_sel);
+ REG_GET(MPCC_OPP_ID[mpcc_id], MPCC_OPP_ID, &opp_id);
+ REG_GET(MPCC_STATUS[mpcc_id], MPCC_IDLE, &idle);
+ if (top_sel == 0xf && opp_id == 0xf && idle)
+ return true;
+ else
+ return false;
}
-static void mpc10_assert_mpcc_idle_before_connect(struct dcn10_mpc *mpc10, int id)
+void mpc1_assert_mpcc_idle_before_connect(struct mpc *mpc, int mpcc_id)
{
+ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
unsigned int top_sel, mpc_busy, mpc_idle;
- REG_GET(MPCC_TOP_SEL[id],
+ REG_GET(MPCC_TOP_SEL[mpcc_id],
MPCC_TOP_SEL, &top_sel);
if (top_sel == 0xf) {
- REG_GET_2(MPCC_STATUS[id],
+ REG_GET_2(MPCC_STATUS[mpcc_id],
MPCC_BUSY, &mpc_busy,
MPCC_IDLE, &mpc_idle);
@@ -116,241 +155,269 @@ static void mpc10_assert_mpcc_idle_before_connect(struct dcn10_mpc *mpc10, int i
}
}
-void mpc10_mpcc_remove(
- struct mpc *mpc,
- struct mpc_tree_cfg *tree_cfg,
- int opp_id,
- int dpp_id)
-{
- struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
- int mpcc_id, z_idx;
-
- /* find z_idx for the dpp to be removed */
- for (z_idx = 0; z_idx < tree_cfg->num_pipes; z_idx++)
- if (tree_cfg->dpp[z_idx] == dpp_id)
- break;
-
- if (z_idx == tree_cfg->num_pipes) {
- /* In case of resume from S3/S4, remove mpcc from bios left over */
- REG_SET(MPCC_OPP_ID[dpp_id], 0,
- MPCC_OPP_ID, 0xf);
- REG_SET(MPCC_TOP_SEL[dpp_id], 0,
- MPCC_TOP_SEL, 0xf);
- REG_SET(MPCC_BOT_SEL[dpp_id], 0,
- MPCC_BOT_SEL, 0xf);
- return;
- }
-
- mpcc_id = tree_cfg->mpcc[z_idx];
-
- REG_SET(MPCC_OPP_ID[mpcc_id], 0,
- MPCC_OPP_ID, 0xf);
- REG_SET(MPCC_TOP_SEL[mpcc_id], 0,
- MPCC_TOP_SEL, 0xf);
- REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
- MPCC_BOT_SEL, 0xf);
-
- if (z_idx > 0) {
- int top_mpcc_id = tree_cfg->mpcc[z_idx - 1];
-
- if (z_idx + 1 < tree_cfg->num_pipes)
- /* mpcc to be removed is in the middle of the tree */
- REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
- MPCC_BOT_SEL, tree_cfg->mpcc[z_idx + 1]);
- else {
- /* mpcc to be removed is at the bottom of the tree */
- REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
- MPCC_BOT_SEL, 0xf);
- REG_UPDATE(MPCC_CONTROL[top_mpcc_id],
- MPCC_MODE, MODE_TOP_ONLY);
- }
- } else if (tree_cfg->num_pipes > 1)
- /* mpcc to be removed is at the top of the tree */
- REG_SET(MUX[opp_id], 0,
- MPC_OUT_MUX, tree_cfg->mpcc[z_idx + 1]);
- else
- /* mpcc to be removed is the only one in the tree */
- REG_SET(MUX[opp_id], 0, MPC_OUT_MUX, 0xf);
-
- /* mark this mpcc as not in use */
- mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id);
- tree_cfg->num_pipes--;
- for (; z_idx < tree_cfg->num_pipes; z_idx++) {
- tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx + 1];
- tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx + 1];
- }
- tree_cfg->dpp[tree_cfg->num_pipes] = 0xdeadbeef;
- tree_cfg->mpcc[tree_cfg->num_pipes] = 0xdeadbeef;
-}
-
-static void mpc10_add_to_tree_cfg(
+/*
+ * Insert DPP into MPC tree based on specified blending position.
+ * Only used for planes that are part of blending chain for OPP output
+ *
+ * Parameters:
+ * [in/out] mpc - MPC context.
+ * [in/out] tree - MPC tree structure that plane will be added to.
+ * [in] blnd_cfg - MPCC blending configuration for the new blending layer.
+ * [in] sm_cfg - MPCC stereo mix configuration for the new blending layer.
+ * stereo mix must disable for the very bottom layer of the tree config.
+ * [in] insert_above_mpcc - Insert new plane above this MPCC. If NULL, insert as bottom plane.
+ * [in] dpp_id - DPP instance for the plane to be added.
+ * [in] mpcc_id - The MPCC physical instance to use for blending.
+ *
+ * Return: struct mpcc* - MPCC that was added.
+ */
+struct mpcc *mpc1_insert_plane(
struct mpc *mpc,
- struct mpcc_cfg *cfg,
+ struct mpc_tree *tree,
+ struct mpcc_blnd_cfg *blnd_cfg,
+ struct mpcc_sm_cfg *sm_cfg,
+ struct mpcc *insert_above_mpcc,
+ int dpp_id,
int mpcc_id)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
- int mpcc_mode = MODE_TOP_ONLY;
- int position = cfg->z_index;
- struct mpc_tree_cfg *tree_cfg = cfg->tree_cfg;
- int alpha_blnd_mode = cfg->per_pixel_alpha ?
- BLND_PP_ALPHA : BLND_GLOBAL_ALPHA;
- int z_idx;
+ struct mpcc *new_mpcc = NULL;
- REG_SET(MPCC_OPP_ID[mpcc_id], 0,
- MPCC_OPP_ID, cfg->opp_id);
+ /* sanity check parameters */
+ ASSERT(mpcc_id < mpc10->num_mpcc);
+ ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
- REG_SET(MPCC_TOP_SEL[mpcc_id], 0,
- MPCC_TOP_SEL, cfg->dpp_id);
+ if (insert_above_mpcc) {
+ /* check insert_above_mpcc exist in tree->opp_list */
+ struct mpcc *temp_mpcc = tree->opp_list;
- if (position == 0) {
- /* idle dpp/mpcc is added to the top layer of tree */
+ while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc)
+ temp_mpcc = temp_mpcc->mpcc_bot;
+ if (temp_mpcc == NULL)
+ return NULL;
+ }
- if (tree_cfg->num_pipes > 0) {
- /* get instance of previous top mpcc */
- int prev_top_mpcc_id = tree_cfg->mpcc[0];
+ /* Get and update MPCC struct parameters */
+ new_mpcc = mpc1_get_mpcc(mpc, mpcc_id);
+ new_mpcc->dpp_id = dpp_id;
- REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
- MPCC_BOT_SEL, prev_top_mpcc_id);
- mpcc_mode = MODE_BLEND;
+ /* program mux and MPCC_MODE */
+ if (insert_above_mpcc) {
+ new_mpcc->mpcc_bot = insert_above_mpcc;
+ REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, insert_above_mpcc->mpcc_id);
+ REG_UPDATE(MPCC_CONTROL[mpcc_id], MPCC_MODE, MPCC_BLEND_MODE_TOP_BOT_BLENDING);
+ } else {
+ new_mpcc->mpcc_bot = NULL;
+ REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
+ REG_UPDATE(MPCC_CONTROL[mpcc_id], MPCC_MODE, MPCC_BLEND_MODE_TOP_LAYER_PASSTHROUGH);
+ }
+ REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id);
+ REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id);
+
+ /* update mpc tree mux setting */
+ if (tree->opp_list == insert_above_mpcc) {
+ /* insert the toppest mpcc */
+ tree->opp_list = new_mpcc;
+ REG_UPDATE(MUX[tree->opp_id], MPC_OUT_MUX, mpcc_id);
+ } else {
+ /* find insert position */
+ struct mpcc *temp_mpcc = tree->opp_list;
+
+ while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc)
+ temp_mpcc = temp_mpcc->mpcc_bot;
+ if (temp_mpcc && temp_mpcc->mpcc_bot == insert_above_mpcc) {
+ REG_SET(MPCC_BOT_SEL[temp_mpcc->mpcc_id], 0, MPCC_BOT_SEL, mpcc_id);
+ temp_mpcc->mpcc_bot = new_mpcc;
+ if (!insert_above_mpcc)
+ REG_UPDATE(MPCC_CONTROL[temp_mpcc->mpcc_id],
+ MPCC_MODE, MPCC_BLEND_MODE_TOP_BOT_BLENDING);
}
+ }
- /* opp will get new output. from new added mpcc */
- REG_SET(MUX[cfg->opp_id], 0, MPC_OUT_MUX, mpcc_id);
-
- } else if (position == tree_cfg->num_pipes) {
- /* idle dpp/mpcc is added to the bottom layer of tree */
-
- /* get instance of previous bottom mpcc, set to middle layer */
- int prev_bot_mpcc_id = tree_cfg->mpcc[tree_cfg->num_pipes - 1];
-
- REG_SET(MPCC_BOT_SEL[prev_bot_mpcc_id], 0,
- MPCC_BOT_SEL, mpcc_id);
- REG_UPDATE(MPCC_CONTROL[prev_bot_mpcc_id],
- MPCC_MODE, MODE_BLEND);
-
- /* mpcc_id become new bottom mpcc*/
- REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
- MPCC_BOT_SEL, 0xf);
+ /* update the blending configuration */
+ new_mpcc->blnd_cfg = *blnd_cfg;
+ mpc->funcs->update_blending(mpc, &new_mpcc->blnd_cfg, mpcc_id);
- } else {
- /* idle dpp/mpcc is added to middle of tree */
- int above_mpcc_id = tree_cfg->mpcc[position - 1];
- int below_mpcc_id = tree_cfg->mpcc[position];
-
- /* mpcc above new mpcc_id has new bottom mux*/
- REG_SET(MPCC_BOT_SEL[above_mpcc_id], 0,
- MPCC_BOT_SEL, mpcc_id);
- REG_UPDATE(MPCC_CONTROL[above_mpcc_id],
- MPCC_MODE, MODE_BLEND);
-
- /* mpcc_id bottom mux is from below mpcc*/
- REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
- MPCC_BOT_SEL, below_mpcc_id);
- mpcc_mode = MODE_BLEND;
+ /* update the stereo mix settings, if provided */
+ if (sm_cfg != NULL) {
+ new_mpcc->sm_cfg = *sm_cfg;
+ mpc1_update_stereo_mix(mpc, sm_cfg, mpcc_id);
}
- REG_SET_4(MPCC_CONTROL[mpcc_id], 0xffffffff,
- MPCC_MODE, mpcc_mode,
- MPCC_ALPHA_BLND_MODE, alpha_blnd_mode,
- MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha,
- MPCC_BLND_ACTIVE_OVERLAP_ONLY, false);
+ /* mark this mpcc as in use */
+ mpc10->mpcc_in_use_mask |= 1 << mpcc_id;
- /* update mpc_tree_cfg with new mpcc */
- for (z_idx = tree_cfg->num_pipes; z_idx > position; z_idx--) {
- tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx - 1];
- tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx - 1];
- }
- tree_cfg->dpp[position] = cfg->dpp_id;
- tree_cfg->mpcc[position] = mpcc_id;
- tree_cfg->num_pipes++;
+ return new_mpcc;
}
-int mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
+/*
+ * Remove a specified MPCC from the MPC tree.
+ *
+ * Parameters:
+ * [in/out] mpc - MPC context.
+ * [in/out] tree - MPC tree structure that plane will be removed from.
+ * [in/out] mpcc - MPCC to be removed from tree.
+ *
+ * Return: void
+ */
+void mpc1_remove_mpcc(
+ struct mpc *mpc,
+ struct mpc_tree *tree,
+ struct mpcc *mpcc_to_remove)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
- int mpcc_id, z_idx;
-
- ASSERT(cfg->z_index < mpc10->num_mpcc);
-
- /* check in dpp already exists in mpc tree */
- for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++)
- if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id)
- break;
- if (z_idx == cfg->tree_cfg->num_pipes) {
- ASSERT(cfg->z_index <= cfg->tree_cfg->num_pipes);
- mpcc_id = mpc10_get_idle_mpcc_id(mpc10);
-
- /*
- * TODO: remove hack
- * Note: currently there is a bug in init_hw such that
- * on resume from hibernate, BIOS sets up MPCC0, and
- * we do mpcc_remove but the mpcc cannot go to idle
- * after remove. This cause us to pick mpcc1 here,
- * which causes a pstate hang for yet unknown reason.
- */
- mpcc_id = cfg->dpp_id;
- /* end hack*/
-
- ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
-
- if (mpc->ctx->dc->debug.sanity_checks)
- mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id);
+ bool found = false;
+ int mpcc_id = mpcc_to_remove->mpcc_id;
+
+ if (tree->opp_list == mpcc_to_remove) {
+ found = true;
+ /* remove MPCC from top of tree */
+ if (mpcc_to_remove->mpcc_bot) {
+ /* set the next MPCC in list to be the top MPCC */
+ tree->opp_list = mpcc_to_remove->mpcc_bot;
+ REG_UPDATE(MUX[tree->opp_id], MPC_OUT_MUX, tree->opp_list->mpcc_id);
+ } else {
+ /* there are no other MPCC is list */
+ tree->opp_list = NULL;
+ REG_UPDATE(MUX[tree->opp_id], MPC_OUT_MUX, 0xf);
+ }
} else {
- ASSERT(cfg->z_index < cfg->tree_cfg->num_pipes);
- mpcc_id = cfg->tree_cfg->mpcc[z_idx];
- mpc10_mpcc_remove(mpc, cfg->tree_cfg, cfg->opp_id, cfg->dpp_id);
+ /* find mpcc to remove MPCC list */
+ struct mpcc *temp_mpcc = tree->opp_list;
+
+ while (temp_mpcc && temp_mpcc->mpcc_bot != mpcc_to_remove)
+ temp_mpcc = temp_mpcc->mpcc_bot;
+
+ if (temp_mpcc && temp_mpcc->mpcc_bot == mpcc_to_remove) {
+ found = true;
+ temp_mpcc->mpcc_bot = mpcc_to_remove->mpcc_bot;
+ if (mpcc_to_remove->mpcc_bot) {
+ /* remove MPCC in middle of list */
+ REG_SET(MPCC_BOT_SEL[temp_mpcc->mpcc_id], 0,
+ MPCC_BOT_SEL, mpcc_to_remove->mpcc_bot->mpcc_id);
+ } else {
+ /* remove MPCC from bottom of list */
+ REG_SET(MPCC_BOT_SEL[temp_mpcc->mpcc_id], 0,
+ MPCC_BOT_SEL, 0xf);
+ REG_UPDATE(MPCC_CONTROL[temp_mpcc->mpcc_id],
+ MPCC_MODE, MPCC_BLEND_MODE_TOP_LAYER_PASSTHROUGH);
+ }
+ }
}
- /* add dpp/mpcc pair to mpc_tree_cfg and update mpcc registers */
- mpc10_add_to_tree_cfg(mpc, cfg, mpcc_id);
+ if (found) {
+ /* turn off MPCC mux registers */
+ REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
+ REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
+ REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
- /* set background color */
- mpc10_set_bg_color(mpc10, &cfg->black_color, mpcc_id);
-
- /* mark this mpcc as in use */
- mpc10->mpcc_in_use_mask |= 1 << mpcc_id;
+ /* mark this mpcc as not in use */
+ mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id);
+ mpcc_to_remove->dpp_id = 0xf;
+ mpcc_to_remove->mpcc_bot = NULL;
+ } else {
+ /* In case of resume from S3/S4, remove mpcc from bios left over */
+ REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
+ REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
+ REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
+ }
+}
- return mpcc_id;
+static void mpc1_init_mpcc(struct mpcc *mpcc, int mpcc_inst)
+{
+ mpcc->mpcc_id = mpcc_inst;
+ mpcc->dpp_id = 0xf;
+ mpcc->mpcc_bot = NULL;
+ mpcc->blnd_cfg.overlap_only = false;
+ mpcc->blnd_cfg.global_alpha = 0xff;
+ mpcc->blnd_cfg.global_gain = 0xff;
+ mpcc->sm_cfg.enable = false;
}
-void mpc10_update_blend_mode(
- struct mpc *mpc,
- struct mpcc_cfg *cfg)
+/*
+ * Reset the MPCC HW status by disconnecting all muxes.
+ *
+ * Parameters:
+ * [in/out] mpc - MPC context.
+ *
+ * Return: void
+ */
+void mpc1_mpc_init(struct mpc *mpc)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
- int mpcc_id, z_idx;
- int alpha_blnd_mode = cfg->per_pixel_alpha ?
- BLND_PP_ALPHA : BLND_GLOBAL_ALPHA;
+ int mpcc_id;
+ int opp_id;
- /* find z_idx for the dpp that requires blending mode update*/
- for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++)
- if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id)
- break;
+ mpc10->mpcc_in_use_mask = 0;
+ for (mpcc_id = 0; mpcc_id < mpc10->num_mpcc; mpcc_id++) {
+ REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
+ REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
+ REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
- ASSERT(z_idx < cfg->tree_cfg->num_pipes);
- mpcc_id = cfg->tree_cfg->mpcc[z_idx];
+ mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
+ }
- REG_UPDATE_2(MPCC_CONTROL[mpcc_id],
- MPCC_ALPHA_BLND_MODE, alpha_blnd_mode,
- MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha);
+ for (opp_id = 0; opp_id < MAX_OPP; opp_id++) {
+ if (REG(MUX[opp_id]))
+ REG_UPDATE(MUX[opp_id], MPC_OUT_MUX, 0xf);
+ }
}
-int mpc10_get_opp_id(struct mpc *mpc, int mpcc_id)
+void mpc1_init_mpcc_list_from_hw(
+ struct mpc *mpc,
+ struct mpc_tree *tree)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
- int opp_id = 0xF;
-
- REG_GET(MPCC_OPP_ID[mpcc_id], MPCC_OPP_ID, &opp_id);
-
- return opp_id;
+ unsigned int opp_id;
+ unsigned int top_sel;
+ unsigned int bot_sel;
+ unsigned int out_mux;
+ struct mpcc *mpcc;
+ int mpcc_id;
+ int bot_mpcc_id;
+
+ REG_GET(MUX[tree->opp_id], MPC_OUT_MUX, &out_mux);
+
+ if (out_mux != 0xf) {
+ for (mpcc_id = 0; mpcc_id < mpc10->num_mpcc; mpcc_id++) {
+ REG_GET(MPCC_OPP_ID[mpcc_id], MPCC_OPP_ID, &opp_id);
+ REG_GET(MPCC_TOP_SEL[mpcc_id], MPCC_TOP_SEL, &top_sel);
+ REG_GET(MPCC_BOT_SEL[mpcc_id], MPCC_BOT_SEL, &bot_sel);
+
+ if (bot_sel == mpcc_id)
+ bot_sel = 0xf;
+
+ if ((opp_id == tree->opp_id) && (top_sel != 0xf)) {
+ mpcc = mpc1_get_mpcc(mpc, mpcc_id);
+ mpcc->dpp_id = top_sel;
+ mpc10->mpcc_in_use_mask |= 1 << mpcc_id;
+
+ if (out_mux == mpcc_id)
+ tree->opp_list = mpcc;
+ if (bot_sel != 0xf && bot_sel < mpc10->num_mpcc) {
+ bot_mpcc_id = bot_sel;
+ REG_GET(MPCC_OPP_ID[bot_mpcc_id], MPCC_OPP_ID, &opp_id);
+ REG_GET(MPCC_TOP_SEL[bot_mpcc_id], MPCC_TOP_SEL, &top_sel);
+ if ((opp_id == tree->opp_id) && (top_sel != 0xf)) {
+ struct mpcc *mpcc_bottom = mpc1_get_mpcc(mpc, bot_mpcc_id);
+
+ mpcc->mpcc_bot = mpcc_bottom;
+ }
+ }
+ }
+ }
+ }
}
const struct mpc_funcs dcn10_mpc_funcs = {
- .add = mpc10_mpcc_add,
- .remove = mpc10_mpcc_remove,
- .wait_for_idle = mpc10_assert_idle_mpcc,
- .update_blend_mode = mpc10_update_blend_mode,
- .get_opp_id = mpc10_get_opp_id,
+ .insert_plane = mpc1_insert_plane,
+ .remove_mpcc = mpc1_remove_mpcc,
+ .mpc_init = mpc1_mpc_init,
+ .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
+ .wait_for_idle = mpc1_assert_idle_mpcc,
+ .assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect,
+ .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
+ .update_blending = mpc1_update_blending,
};
void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
@@ -360,6 +427,8 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
const struct dcn_mpc_mask *mpc_mask,
int num_mpcc)
{
+ int i;
+
mpc10->base.ctx = ctx;
mpc10->base.funcs = &dcn10_mpc_funcs;
@@ -370,5 +439,8 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
mpc10->mpcc_in_use_mask = 0;
mpc10->num_mpcc = num_mpcc;
+
+ for (i = 0; i < MAX_MPCC; i++)
+ mpc1_init_mpcc(&mpc10->base.mpcc_array[i], i);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
index e85e1f342266..267a2995ef6e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
@@ -30,9 +30,6 @@
#define TO_DCN10_MPC(mpc_base) \
container_of(mpc_base, struct dcn10_mpc, base)
-#define MAX_MPCC 6
-#define MAX_OPP 6
-
#define MPC_COMMON_REG_LIST_DCN1_0(inst) \
SRII(MPCC_TOP_SEL, MPCC, inst),\
SRII(MPCC_BOT_SEL, MPCC, inst),\
@@ -42,7 +39,8 @@
SRII(MPCC_BG_G_Y, MPCC, inst),\
SRII(MPCC_BG_R_CR, MPCC, inst),\
SRII(MPCC_BG_B_CB, MPCC, inst),\
- SRII(MPCC_BG_B_CB, MPCC, inst)
+ SRII(MPCC_BG_B_CB, MPCC, inst),\
+ SRII(MPCC_SM_CONTROL, MPCC, inst)
#define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \
SRII(MUX, MPC_OUT, inst)
@@ -56,6 +54,7 @@
uint32_t MPCC_BG_G_Y[MAX_MPCC]; \
uint32_t MPCC_BG_R_CR[MAX_MPCC]; \
uint32_t MPCC_BG_B_CB[MAX_MPCC]; \
+ uint32_t MPCC_SM_CONTROL[MAX_MPCC]; \
uint32_t MUX[MAX_OPP];
#define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
@@ -65,12 +64,20 @@
SF(MPCC0_MPCC_CONTROL, MPCC_ALPHA_BLND_MODE, mask_sh),\
SF(MPCC0_MPCC_CONTROL, MPCC_ALPHA_MULTIPLIED_MODE, mask_sh),\
SF(MPCC0_MPCC_CONTROL, MPCC_BLND_ACTIVE_OVERLAP_ONLY, mask_sh),\
+ SF(MPCC0_MPCC_CONTROL, MPCC_GLOBAL_ALPHA, mask_sh),\
+ SF(MPCC0_MPCC_CONTROL, MPCC_GLOBAL_GAIN, mask_sh),\
SF(MPCC0_MPCC_STATUS, MPCC_IDLE, mask_sh),\
SF(MPCC0_MPCC_STATUS, MPCC_BUSY, mask_sh),\
SF(MPCC0_MPCC_OPP_ID, MPCC_OPP_ID, mask_sh),\
SF(MPCC0_MPCC_BG_G_Y, MPCC_BG_G_Y, mask_sh),\
SF(MPCC0_MPCC_BG_R_CR, MPCC_BG_R_CR, mask_sh),\
SF(MPCC0_MPCC_BG_B_CB, MPCC_BG_B_CB, mask_sh),\
+ SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_EN, mask_sh),\
+ SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_MODE, mask_sh),\
+ SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FRAME_ALT, mask_sh),\
+ SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FIELD_ALT, mask_sh),\
+ SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_FRAME_POL, mask_sh),\
+ SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_TOP_POL, mask_sh),\
SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh)
#define MPC_REG_FIELD_LIST(type) \
@@ -80,12 +87,20 @@
type MPCC_ALPHA_BLND_MODE;\
type MPCC_ALPHA_MULTIPLIED_MODE;\
type MPCC_BLND_ACTIVE_OVERLAP_ONLY;\
+ type MPCC_GLOBAL_ALPHA;\
+ type MPCC_GLOBAL_GAIN;\
type MPCC_IDLE;\
type MPCC_BUSY;\
type MPCC_OPP_ID;\
type MPCC_BG_G_Y;\
type MPCC_BG_R_CR;\
type MPCC_BG_B_CB;\
+ type MPCC_SM_EN;\
+ type MPCC_SM_MODE;\
+ type MPCC_SM_FRAME_ALT;\
+ type MPCC_SM_FIELD_ALT;\
+ type MPCC_SM_FORCE_NEXT_FRAME_POL;\
+ type MPCC_SM_FORCE_NEXT_TOP_POL;\
type MPC_OUT_MUX;
struct dcn_mpc_registers {
@@ -117,23 +132,55 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpcc10,
const struct dcn_mpc_mask *mpc_mask,
int num_mpcc);
-int mpc10_mpcc_add(
- struct mpc *mpc,
- struct mpcc_cfg *cfg);
-
-void mpc10_mpcc_remove(
- struct mpc *mpc,
- struct mpc_tree_cfg *tree_cfg,
- int opp_id,
- int dpp_id);
-
-void mpc10_assert_idle_mpcc(
- struct mpc *mpc,
- int id);
-
-void mpc10_update_blend_mode(
- struct mpc *mpc,
- struct mpcc_cfg *cfg);
-int mpc10_get_opp_id(struct mpc *mpc, int mpcc_id);
+struct mpcc *mpc1_insert_plane(
+ struct mpc *mpc,
+ struct mpc_tree *tree,
+ struct mpcc_blnd_cfg *blnd_cfg,
+ struct mpcc_sm_cfg *sm_cfg,
+ struct mpcc *insert_above_mpcc,
+ int dpp_id,
+ int mpcc_id);
+
+void mpc1_remove_mpcc(
+ struct mpc *mpc,
+ struct mpc_tree *tree,
+ struct mpcc *mpcc);
+
+void mpc1_mpc_init(
+ struct mpc *mpc);
+
+void mpc1_assert_idle_mpcc(
+ struct mpc *mpc,
+ int id);
+
+void mpc1_set_bg_color(
+ struct mpc *mpc,
+ struct tg_color *bg_color,
+ int id);
+
+void mpc1_update_stereo_mix(
+ struct mpc *mpc,
+ struct mpcc_sm_cfg *sm_cfg,
+ int mpcc_id);
+
+bool mpc1_is_mpcc_idle(
+ struct mpc *mpc,
+ int mpcc_id);
+
+void mpc1_assert_mpcc_idle_before_connect(
+ struct mpc *mpc,
+ int mpcc_id);
+
+void mpc1_init_mpcc_list_from_hw(
+ struct mpc *mpc,
+ struct mpc_tree *tree);
+
+struct mpcc *mpc1_get_mpcc(
+ struct mpc *mpc,
+ int mpcc_id);
+
+struct mpcc *mpc1_get_mpcc_for_dpp(
+ struct mpc_tree *tree,
+ int dpp_id);
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
index 6d6f67b7d30e..f6ba0eef4489 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
@@ -296,13 +296,75 @@ void opp1_program_fmt(
return;
}
-void opp1_set_stereo_polarity(
- struct output_pixel_processor *opp,
- bool enable, bool rightEyePolarity)
+void opp1_program_stereo(
+ struct output_pixel_processor *opp,
+ bool enable,
+ const struct dc_crtc_timing *timing)
{
struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp);
- REG_UPDATE(FMT_CONTROL, FMT_STEREOSYNC_OVERRIDE, enable);
+ uint32_t active_width = timing->h_addressable - timing->h_border_right - timing->h_border_right;
+ uint32_t space1_size = timing->v_total - timing->v_addressable;
+ /* TODO: confirm computation of space2_size */
+ uint32_t space2_size = timing->v_total - timing->v_addressable;
+
+ if (!enable) {
+ active_width = 0;
+ space1_size = 0;
+ space2_size = 0;
+ }
+
+ /* TODO: for which cases should FMT_STEREOSYNC_OVERRIDE be set? */
+ REG_UPDATE(FMT_CONTROL, FMT_STEREOSYNC_OVERRIDE, 0);
+
+ REG_UPDATE(OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, active_width);
+
+ /* Program OPPBUF_3D_VACT_SPACE1_SIZE and OPPBUF_VACT_SPACE2_SIZE registers
+ * In 3D progressive frames, Vactive space happens only in between the 2 frames,
+ * so only need to program OPPBUF_3D_VACT_SPACE1_SIZE
+ * In 3D alternative frames, left and right frames, top and bottom field.
+ */
+ if (timing->timing_3d_format == TIMING_3D_FORMAT_FRAME_ALTERNATE)
+ REG_UPDATE(OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE2_SIZE, space2_size);
+ else
+ REG_UPDATE(OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE1_SIZE, space1_size);
+
+ /* TODO: Is programming of OPPBUF_DUMMY_DATA_R/G/B needed? */
+ /*
+ REG_UPDATE(OPPBUF_3D_PARAMETERS_0,
+ OPPBUF_DUMMY_DATA_R, data_r);
+ REG_UPDATE(OPPBUF_3D_PARAMETERS_1,
+ OPPBUF_DUMMY_DATA_G, data_g);
+ REG_UPDATE(OPPBUF_3D_PARAMETERS_1,
+ OPPBUF_DUMMY_DATA_B, _data_b);
+ */
+}
+
+void opp1_program_oppbuf(
+ struct output_pixel_processor *opp,
+ struct oppbuf_params *oppbuf)
+{
+ struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp);
+
+ /* Program the oppbuf active width to be the frame width from mpc */
+ REG_UPDATE(OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, oppbuf->active_width);
+
+ /* Specifies the number of segments in multi-segment mode (DP-MSO operation)
+ * description "In 1/2/4 segment mode, specifies the horizontal active width in pixels of the display panel.
+ * In 4 segment split left/right mode, specifies the horizontal 1/2 active width in pixels of the display panel.
+ * Used to determine segment boundaries in multi-segment mode. Used to determine the width of the vertical active space in 3D frame packed modes.
+ * OPPBUF_ACTIVE_WIDTH must be integer divisible by the total number of segments."
+ */
+ REG_UPDATE(OPPBUF_CONTROL, OPPBUF_DISPLAY_SEGMENTATION, oppbuf->mso_segmentation);
+
+ /* description "Specifies the number of overlap pixels (1-8 overlapping pixels supported), used in multi-segment mode (DP-MSO operation)" */
+ REG_UPDATE(OPPBUF_CONTROL, OPPBUF_OVERLAP_PIXEL_NUM, oppbuf->mso_overlap_pixel_num);
+
+ /* description "Specifies the number of times a pixel is replicated (0-15 pixel replications supported).
+ * A value of 0 disables replication. The total number of times a pixel is output is OPPBUF_PIXEL_REPETITION + 1."
+ */
+ REG_UPDATE(OPPBUF_CONTROL, OPPBUF_PIXEL_REPETITION, oppbuf->pixel_repetition);
+
}
/*****************************************/
@@ -319,7 +381,7 @@ static struct opp_funcs dcn10_opp_funcs = {
.opp_set_dyn_expansion = opp1_set_dyn_expansion,
.opp_program_fmt = opp1_program_fmt,
.opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction,
- .opp_set_stereo_polarity = opp1_set_stereo_polarity,
+ .opp_program_stereo = opp1_program_stereo,
.opp_destroy = opp1_destroy
};
@@ -330,6 +392,7 @@ void dcn10_opp_construct(struct dcn10_opp *oppn10,
const struct dcn10_opp_shift *opp_shift,
const struct dcn10_opp_mask *opp_mask)
{
+
oppn10->base.ctx = ctx;
oppn10->base.inst = inst;
oppn10->base.funcs = &dcn10_opp_funcs;
@@ -338,4 +401,3 @@ void dcn10_opp_construct(struct dcn10_opp *oppn10,
oppn10->opp_shift = opp_shift;
oppn10->opp_mask = opp_mask;
}
-
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h
index f3c298ec37fb..bc5058af6266 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h
@@ -41,7 +41,10 @@
SRI(FMT_DITHER_RAND_B_SEED, FMT, id), \
SRI(FMT_CLAMP_CNTL, FMT, id), \
SRI(FMT_DYNAMIC_EXP_CNTL, FMT, id), \
- SRI(FMT_MAP420_MEMORY_CONTROL, FMT, id)
+ SRI(FMT_MAP420_MEMORY_CONTROL, FMT, id), \
+ SRI(OPPBUF_CONTROL, OPPBUF, id),\
+ SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, id), \
+ SRI(OPPBUF_3D_PARAMETERS_1, OPPBUF, id)
#define OPP_REG_LIST_DCN10(id) \
OPP_REG_LIST_DCN(id)
@@ -54,7 +57,11 @@
uint32_t FMT_DITHER_RAND_B_SEED; \
uint32_t FMT_CLAMP_CNTL; \
uint32_t FMT_DYNAMIC_EXP_CNTL; \
- uint32_t FMT_MAP420_MEMORY_CONTROL;
+ uint32_t FMT_MAP420_MEMORY_CONTROL; \
+ uint32_t OPPBUF_CONTROL; \
+ uint32_t OPPBUF_CONTROL1; \
+ uint32_t OPPBUF_3D_PARAMETERS_0; \
+ uint32_t OPPBUF_3D_PARAMETERS_1
#define OPP_MASK_SH_LIST_DCN(mask_sh) \
OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, mask_sh), \
@@ -78,10 +85,16 @@
OPP_SF(FMT0_FMT_CLAMP_CNTL, FMT_CLAMP_COLOR_FORMAT, mask_sh), \
OPP_SF(FMT0_FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN, mask_sh), \
OPP_SF(FMT0_FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE, mask_sh), \
- OPP_SF(FMT0_FMT_MAP420_MEMORY_CONTROL, FMT_MAP420MEM_PWR_FORCE, mask_sh)
+ OPP_SF(FMT0_FMT_MAP420_MEMORY_CONTROL, FMT_MAP420MEM_PWR_FORCE, mask_sh), \
+ OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, mask_sh),\
+ OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_PIXEL_REPETITION, mask_sh),\
+ OPP_SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE1_SIZE, mask_sh), \
+ OPP_SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE2_SIZE, mask_sh)
#define OPP_MASK_SH_LIST_DCN10(mask_sh) \
- OPP_MASK_SH_LIST_DCN(mask_sh)
+ OPP_MASK_SH_LIST_DCN(mask_sh), \
+ OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_DISPLAY_SEGMENTATION, mask_sh),\
+ OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_OVERLAP_PIXEL_NUM, mask_sh)
#define OPP_DCN10_REG_FIELD_LIST(type) \
type FMT_TRUNCATE_EN; \
@@ -105,18 +118,25 @@
type FMT_DYNAMIC_EXP_EN; \
type FMT_DYNAMIC_EXP_MODE; \
type FMT_MAP420MEM_PWR_FORCE; \
- type FMT_STEREOSYNC_OVERRIDE;
+ type FMT_STEREOSYNC_OVERRIDE; \
+ type OPPBUF_ACTIVE_WIDTH;\
+ type OPPBUF_PIXEL_REPETITION;\
+ type OPPBUF_DISPLAY_SEGMENTATION;\
+ type OPPBUF_OVERLAP_PIXEL_NUM;\
+ type OPPBUF_NUM_SEGMENT_PADDED_PIXELS; \
+ type OPPBUF_3D_VACT_SPACE1_SIZE; \
+ type OPPBUF_3D_VACT_SPACE2_SIZE
struct dcn10_opp_registers {
- OPP_COMMON_REG_VARIABLE_LIST
+ OPP_COMMON_REG_VARIABLE_LIST;
};
struct dcn10_opp_shift {
- OPP_DCN10_REG_FIELD_LIST(uint8_t)
+ OPP_DCN10_REG_FIELD_LIST(uint8_t);
};
struct dcn10_opp_mask {
- OPP_DCN10_REG_FIELD_LIST(uint32_t)
+ OPP_DCN10_REG_FIELD_LIST(uint32_t);
};
struct dcn10_opp {
@@ -151,9 +171,10 @@ void opp1_program_bit_depth_reduction(
struct output_pixel_processor *opp,
const struct bit_depth_reduction_params *params);
-void opp1_set_stereo_polarity(
- struct output_pixel_processor *opp,
- bool enable, bool rightEyePolarity);
+void opp1_program_stereo(
+ struct output_pixel_processor *opp,
+ bool enable,
+ const struct dc_crtc_timing *timing);
void opp1_destroy(struct output_pixel_processor **opp);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
index 73ff78f9cae1..4bf64d1b2c60 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
@@ -23,19 +23,20 @@
*
*/
+
#include "reg_helper.h"
-#include "dcn10_timing_generator.h"
+#include "dcn10_optc.h"
#include "dc.h"
#define REG(reg)\
- tgn10->tg_regs->reg
+ optc1->tg_regs->reg
#define CTX \
- tgn10->base.ctx
+ optc1->base.ctx
#undef FN
#define FN(reg_name, field_name) \
- tgn10->tg_shift->field_name, tgn10->tg_mask->field_name
+ optc1->tg_shift->field_name, optc1->tg_mask->field_name
#define STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN 0x100
@@ -45,8 +46,8 @@
* 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 tgn10_apply_front_porch_workaround(
- struct timing_generator *tg,
+static void optc1_apply_front_porch_workaround(
+ struct timing_generator *optc,
struct dc_crtc_timing *timing)
{
if (timing->flags.INTERLACE == 1) {
@@ -58,30 +59,30 @@ static void tgn10_apply_front_porch_workaround(
}
}
-static void tgn10_program_global_sync(
- struct timing_generator *tg)
+void optc1_program_global_sync(
+ struct timing_generator *optc)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
- if (tg->dlg_otg_param.vstartup_start == 0) {
+ if (optc->dlg_otg_param.vstartup_start == 0) {
BREAK_TO_DEBUGGER();
return;
}
REG_SET(OTG_VSTARTUP_PARAM, 0,
- VSTARTUP_START, tg->dlg_otg_param.vstartup_start);
+ VSTARTUP_START, optc->dlg_otg_param.vstartup_start);
REG_SET_2(OTG_VUPDATE_PARAM, 0,
- VUPDATE_OFFSET, tg->dlg_otg_param.vupdate_offset,
- VUPDATE_WIDTH, tg->dlg_otg_param.vupdate_width);
+ VUPDATE_OFFSET, optc->dlg_otg_param.vupdate_offset,
+ VUPDATE_WIDTH, optc->dlg_otg_param.vupdate_width);
REG_SET(OTG_VREADY_PARAM, 0,
- VREADY_OFFSET, tg->dlg_otg_param.vready_offset);
+ VREADY_OFFSET, optc->dlg_otg_param.vready_offset);
}
-static void tgn10_disable_stereo(struct timing_generator *tg)
+static void optc1_disable_stereo(struct timing_generator *optc)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
REG_SET(OTG_STEREO_CONTROL, 0,
OTG_STEREO_EN, 0);
@@ -90,11 +91,6 @@ static void tgn10_disable_stereo(struct timing_generator *tg)
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);
}
/**
@@ -102,8 +98,8 @@ static void tgn10_disable_stereo(struct timing_generator *tg)
* Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition.
* Including SYNC. Call BIOS command table to program Timings.
*/
-static void tgn10_program_timing(
- struct timing_generator *tg,
+void optc1_program_timing(
+ struct timing_generator *optc,
const struct dc_crtc_timing *dc_crtc_timing,
bool use_vbios)
{
@@ -121,10 +117,10 @@ static void tgn10_program_timing(
uint32_t h_div_2;
int32_t vertical_line_start;
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
patched_crtc_timing = *dc_crtc_timing;
- tgn10_apply_front_porch_workaround(tg, &patched_crtc_timing);
+ optc1_apply_front_porch_workaround(optc, &patched_crtc_timing);
/* Load horizontal timing */
@@ -217,7 +213,7 @@ static void tgn10_program_timing(
/* Use OTG_VERTICAL_INTERRUPT2 replace VUPDATE interrupt,
* program the reg for interrupt postition.
*/
- vertical_line_start = asic_blank_end - tg->dlg_otg_param.vstartup_start + 1;
+ vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1;
if (vertical_line_start < 0) {
ASSERT(0);
vertical_line_start = 0;
@@ -233,26 +229,25 @@ static void tgn10_program_timing(
OTG_V_SYNC_A_POL, v_sync_polarity);
v_init = asic_blank_start;
- if (tg->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT ||
- tg->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
- tg->dlg_otg_param.signal == SIGNAL_TYPE_EDP) {
+ 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 (tg->dlg_otg_param.vstartup_start > asic_blank_end)
- v_fp2 = tg->dlg_otg_param.vstartup_start > asic_blank_end;
+ 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 ((tg->dlg_otg_param.vstartup_start/2)*2 > asic_blank_end)
+ if ((optc->dlg_otg_param.vstartup_start/2)*2 > asic_blank_end)
v_fp2 = v_fp2 / 2;
- }
- else
+ } else
REG_UPDATE(OTG_INTERLACE_CONTROL,
OTG_INTERLACE_ENABLE, 0);
@@ -270,13 +265,13 @@ static void tgn10_program_timing(
OTG_START_POINT_CNTL, start_point,
OTG_FIELD_NUMBER_CNTL, field_num);
- tgn10_program_global_sync(tg);
+ 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(tg, &patched_crtc_timing);
+ * program_horz_count_by_2(optc, &patched_crtc_timing);
*/
/* Enable stereo - only when we need to pack 3D frame. Other types
@@ -290,9 +285,9 @@ static void tgn10_program_timing(
}
-static void tgn10_set_blank_data_double_buffer(struct timing_generator *tg, bool enable)
+static void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
uint32_t blank_data_double_buffer_enable = enable ? 1 : 0;
@@ -304,9 +299,9 @@ static void tgn10_set_blank_data_double_buffer(struct timing_generator *tg, bool
* unblank_crtc
* Call ASIC Control Object to UnBlank CRTC.
*/
-static void tgn10_unblank_crtc(struct timing_generator *tg)
+static void optc1_unblank_crtc(struct timing_generator *optc)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
uint32_t vertical_interrupt_enable = 0;
REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL,
@@ -316,7 +311,7 @@ static void tgn10_unblank_crtc(struct timing_generator *tg)
* this check will be removed.
*/
if (vertical_interrupt_enable)
- tgn10_set_blank_data_double_buffer(tg, true);
+ optc1_set_blank_data_double_buffer(optc, true);
REG_UPDATE_2(OTG_BLANK_CONTROL,
OTG_BLANK_DATA_EN, 0,
@@ -328,36 +323,29 @@ static void tgn10_unblank_crtc(struct timing_generator *tg)
* Call ASIC Control Object to Blank CRTC.
*/
-static void tgn10_blank_crtc(struct timing_generator *tg)
+static void optc1_blank_crtc(struct timing_generator *optc)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
REG_UPDATE_2(OTG_BLANK_CONTROL,
OTG_BLANK_DATA_EN, 1,
OTG_BLANK_DE_MODE, 0);
- /* todo: why are we waiting for BLANK_DATA_EN? shouldn't we be waiting
- * for status?
- */
- REG_WAIT(OTG_BLANK_CONTROL,
- OTG_BLANK_DATA_EN, 1,
- 1, 100000);
-
- tgn10_set_blank_data_double_buffer(tg, false);
+ optc1_set_blank_data_double_buffer(optc, false);
}
-static void tgn10_set_blank(struct timing_generator *tg,
+void optc1_set_blank(struct timing_generator *optc,
bool enable_blanking)
{
if (enable_blanking)
- tgn10_blank_crtc(tg);
+ optc1_blank_crtc(optc);
else
- tgn10_unblank_crtc(tg);
+ optc1_unblank_crtc(optc);
}
-static bool tgn10_is_blanked(struct timing_generator *tg)
+bool optc1_is_blanked(struct timing_generator *optc)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
uint32_t blank_en;
uint32_t blank_state;
@@ -368,9 +356,9 @@ static bool tgn10_is_blanked(struct timing_generator *tg)
return blank_en && blank_state;
}
-static void tgn10_enable_optc_clock(struct timing_generator *tg, bool enable)
+void optc1_enable_optc_clock(struct timing_generator *optc, bool enable)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
if (enable) {
REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
@@ -403,19 +391,19 @@ static void tgn10_enable_optc_clock(struct timing_generator *tg, bool enable)
* Enable CRTC
* Enable CRTC - call ASIC Control Object to enable Timing generator.
*/
-static bool tgn10_enable_crtc(struct timing_generator *tg)
+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 dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ 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, tg->inst);
+ OPTC_SRC_SEL, optc->inst);
/* VTG enable first is for HW workaround */
REG_UPDATE(CONTROL,
@@ -430,9 +418,9 @@ static bool tgn10_enable_crtc(struct timing_generator *tg)
}
/* disable_crtc - call ASIC Control Object to disable Timing generator. */
-static bool tgn10_disable_crtc(struct timing_generator *tg)
+bool optc1_disable_crtc(struct timing_generator *optc)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
/* disable otg request until end of the first line
* in the vertical blank region
@@ -453,11 +441,11 @@ static bool tgn10_disable_crtc(struct timing_generator *tg)
}
-static void tgn10_program_blank_color(
- struct timing_generator *tg,
+void optc1_program_blank_color(
+ struct timing_generator *optc,
const struct tg_color *black_color)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
REG_SET_3(OTG_BLACK_COLOR, 0,
OTG_BLACK_COLOR_B_CB, black_color->color_b_cb,
@@ -465,15 +453,15 @@ static void tgn10_program_blank_color(
OTG_BLACK_COLOR_R_CR, black_color->color_r_cr);
}
-static bool tgn10_validate_timing(
- struct timing_generator *tg,
+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 dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
ASSERT(timing != NULL);
@@ -503,19 +491,19 @@ static bool tgn10_validate_timing(
* needs more than 8192 horizontal and
* more than 8192 vertical total pixels)
*/
- if (timing->h_total > tgn10->max_h_total ||
- timing->v_total > tgn10->max_v_total)
+ if (timing->h_total > optc1->max_h_total ||
+ timing->v_total > optc1->max_v_total)
return false;
- if (h_blank < tgn10->min_h_blank)
+ if (h_blank < optc1->min_h_blank)
return false;
- if (timing->h_sync_width < tgn10->min_h_sync_width ||
- timing->v_sync_width < tgn10->min_v_sync_width)
+ 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?tgn10->min_v_blank_interlace:tgn10->min_v_blank;
+ min_v_blank = timing->flags.INTERLACE?optc1->min_v_blank_interlace:optc1->min_v_blank;
if (v_blank < min_v_blank)
return false;
@@ -532,15 +520,15 @@ static bool tgn10_validate_timing(
* holds the counter of frames.
*
* @param
- * struct timing_generator *tg - [in] timing generator which controls the
+ * struct timing_generator *optc - [in] timing generator which controls the
* desired CRTC
*
* @return
* Counter of frames, which should equal to number of vblanks.
*/
-static uint32_t tgn10_get_vblank_counter(struct timing_generator *tg)
+uint32_t optc1_get_vblank_counter(struct timing_generator *optc)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
uint32_t frame_count;
REG_GET(OTG_STATUS_FRAME_COUNT,
@@ -549,34 +537,34 @@ static uint32_t tgn10_get_vblank_counter(struct timing_generator *tg)
return frame_count;
}
-static void tgn10_lock(struct timing_generator *tg)
+void optc1_lock(struct timing_generator *optc)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
REG_SET(OTG_GLOBAL_CONTROL0, 0,
- OTG_MASTER_UPDATE_LOCK_SEL, tg->inst);
+ 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 (tg->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
+ if (optc->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
REG_WAIT(OTG_MASTER_UPDATE_LOCK,
UPDATE_LOCK_STATUS, 1,
1, 10);
}
-static void tgn10_unlock(struct timing_generator *tg)
+void optc1_unlock(struct timing_generator *optc)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
OTG_MASTER_UPDATE_LOCK, 0);
}
-static void tgn10_get_position(struct timing_generator *tg,
+void optc1_get_position(struct timing_generator *optc,
struct crtc_position *position)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
REG_GET_2(OTG_STATUS_POSITION,
OTG_HORZ_COUNT, &position->horizontal_count,
@@ -586,12 +574,12 @@ static void tgn10_get_position(struct timing_generator *tg,
OTG_VERT_COUNT_NOM, &position->nominal_vcount);
}
-static bool tgn10_is_counter_moving(struct timing_generator *tg)
+bool optc1_is_counter_moving(struct timing_generator *optc)
{
struct crtc_position position1, position2;
- tg->funcs->get_position(tg, &position1);
- tg->funcs->get_position(tg, &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)
@@ -600,10 +588,10 @@ static bool tgn10_is_counter_moving(struct timing_generator *tg)
return true;
}
-static bool tgn10_did_triggered_reset_occur(
- struct timing_generator *tg)
+bool optc1_did_triggered_reset_occur(
+ struct timing_generator *optc)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
uint32_t occurred_force, occurred_vsync;
REG_GET(OTG_FORCE_COUNT_NOW_CNTL,
@@ -615,9 +603,9 @@ static bool tgn10_did_triggered_reset_occur(
return occurred_vsync != 0 || occurred_force != 0;
}
-static void tgn10_disable_reset_trigger(struct timing_generator *tg)
+void optc1_disable_reset_trigger(struct timing_generator *optc)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
REG_WRITE(OTG_TRIGA_CNTL, 0);
@@ -628,9 +616,9 @@ static void tgn10_disable_reset_trigger(struct timing_generator *tg)
OTG_FORCE_VSYNC_NEXT_LINE_CLEAR, 1);
}
-static void tgn10_enable_reset_trigger(struct timing_generator *tg, int source_tg_inst)
+void optc1_enable_reset_trigger(struct timing_generator *optc, int source_tg_inst)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
uint32_t falling_edge;
REG_GET(OTG_V_SYNC_A_CNTL,
@@ -662,12 +650,12 @@ static void tgn10_enable_reset_trigger(struct timing_generator *tg, int source_t
OTG_FORCE_COUNT_NOW_MODE, 2);
}
-void tgn10_enable_crtc_reset(
- struct timing_generator *tg,
+void optc1_enable_crtc_reset(
+ struct timing_generator *optc,
int source_tg_inst,
struct crtc_trigger_info *crtc_tp)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
uint32_t falling_edge = 0;
uint32_t rising_edge = 0;
@@ -707,10 +695,10 @@ void tgn10_enable_crtc_reset(
}
}
-static void tgn10_wait_for_state(struct timing_generator *tg,
+void optc1_wait_for_state(struct timing_generator *optc,
enum crtc_state state)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
switch (state) {
case CRTC_STATE_VBLANK:
@@ -730,8 +718,8 @@ static void tgn10_wait_for_state(struct timing_generator *tg,
}
}
-static void tgn10_set_early_control(
- struct timing_generator *tg,
+void optc1_set_early_control(
+ struct timing_generator *optc,
uint32_t early_cntl)
{
/* asic design change, do not need this control
@@ -740,11 +728,11 @@ static void tgn10_set_early_control(
}
-static void tgn10_set_static_screen_control(
- struct timing_generator *tg,
+void optc1_set_static_screen_control(
+ struct timing_generator *optc,
uint32_t value)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ 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
@@ -769,11 +757,11 @@ static void tgn10_set_static_screen_control(
*
*****************************************************************************
*/
-static void tgn10_set_drr(
- struct timing_generator *tg,
+void optc1_set_drr(
+ struct timing_generator *optc,
const struct drr_params *params)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
if (params != NULL &&
params->vertical_total_max > 0 &&
@@ -806,15 +794,15 @@ static void tgn10_set_drr(
}
}
-static void tgn10_set_test_pattern(
- struct timing_generator *tg,
+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 dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ 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;
@@ -1065,35 +1053,30 @@ static void tgn10_set_test_pattern(
}
}
-static void tgn10_get_crtc_scanoutpos(
- struct timing_generator *tg,
+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 dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ 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);
- tgn10_get_position(tg, &position);
+ optc1_get_position(optc, &position);
*h_position = position.horizontal_count;
*v_position = position.vertical_count;
}
-
-
-static void tgn10_enable_stereo(struct timing_generator *tg,
+static void optc1_enable_stereo(struct timing_generator *optc,
const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
-
- uint32_t active_width = timing->h_addressable;
- uint32_t space1_size = timing->v_total - timing->v_addressable;
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
if (flags) {
uint32_t stereo_en;
@@ -1121,29 +1104,23 @@ static void tgn10_enable_stereo(struct timing_generator *tg,
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);
}
-static void tgn10_program_stereo(struct timing_generator *tg,
+void optc1_program_stereo(struct timing_generator *optc,
const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
{
if (flags->PROGRAM_STEREO)
- tgn10_enable_stereo(tg, timing, flags);
+ optc1_enable_stereo(optc, timing, flags);
else
- tgn10_disable_stereo(tg);
+ optc1_disable_stereo(optc);
}
-static bool tgn10_is_stereo_left_eye(struct timing_generator *tg)
+bool optc1_is_stereo_left_eye(struct timing_generator *optc)
{
bool ret = false;
uint32_t left_eye = 0;
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
REG_GET(OTG_STEREO_STATUS,
OTG_STEREO_CURRENT_EYE, &left_eye);
@@ -1155,7 +1132,7 @@ static bool tgn10_is_stereo_left_eye(struct timing_generator *tg)
return ret;
}
-void tgn10_read_otg_state(struct dcn10_timing_generator *tgn10,
+void optc1_read_otg_state(struct optc *optc1,
struct dcn_otg_state *s)
{
REG_GET(OTG_CONTROL,
@@ -1199,17 +1176,22 @@ void tgn10_read_otg_state(struct dcn10_timing_generator *tgn10,
OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status);
}
-static void tgn10_tg_init(struct timing_generator *tg)
+static void optc1_clear_optc_underflow(struct timing_generator *optc)
{
- struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
- tgn10_set_blank_data_double_buffer(tg, true);
REG_UPDATE(OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, 1);
}
-static bool tgn10_is_tg_enabled(struct timing_generator *tg)
+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 dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
uint32_t otg_enabled = 0;
REG_GET(OTG_CONTROL, OTG_MASTER_EN, &otg_enabled);
@@ -1217,50 +1199,65 @@ static bool tgn10_is_tg_enabled(struct timing_generator *tg)
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 = tgn10_validate_timing,
- .program_timing = tgn10_program_timing,
- .program_global_sync = tgn10_program_global_sync,
- .enable_crtc = tgn10_enable_crtc,
- .disable_crtc = tgn10_disable_crtc,
+ .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 = tgn10_is_counter_moving,
- .get_position = tgn10_get_position,
- .get_frame_count = tgn10_get_vblank_counter,
- .get_scanoutpos = tgn10_get_crtc_scanoutpos,
- .set_early_control = tgn10_set_early_control,
+ .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 = tgn10_wait_for_state,
- .set_blank = tgn10_set_blank,
- .is_blanked = tgn10_is_blanked,
- .set_blank_color = tgn10_program_blank_color,
- .did_triggered_reset_occur = tgn10_did_triggered_reset_occur,
- .enable_reset_trigger = tgn10_enable_reset_trigger,
- .enable_crtc_reset = tgn10_enable_crtc_reset,
- .disable_reset_trigger = tgn10_disable_reset_trigger,
- .lock = tgn10_lock,
- .unlock = tgn10_unlock,
- .enable_optc_clock = tgn10_enable_optc_clock,
- .set_drr = tgn10_set_drr,
- .set_static_screen_control = tgn10_set_static_screen_control,
- .set_test_pattern = tgn10_set_test_pattern,
- .program_stereo = tgn10_program_stereo,
- .is_stereo_left_eye = tgn10_is_stereo_left_eye,
- .set_blank_data_double_buffer = tgn10_set_blank_data_double_buffer,
- .tg_init = tgn10_tg_init,
- .is_tg_enabled = tgn10_is_tg_enabled,
+ .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 dcn10_timing_generator *tgn10)
+void dcn10_timing_generator_init(struct optc *optc1)
{
- tgn10->base.funcs = &dcn10_tg_funcs;
+ optc1->base.funcs = &dcn10_tg_funcs;
- tgn10->max_h_total = tgn10->tg_mask->OTG_H_TOTAL + 1;
- tgn10->max_v_total = tgn10->tg_mask->OTG_V_TOTAL + 1;
+ optc1->max_h_total = optc1->tg_mask->OTG_H_TOTAL + 1;
+ optc1->max_v_total = optc1->tg_mask->OTG_V_TOTAL + 1;
- tgn10->min_h_blank = 32;
- tgn10->min_v_blank = 3;
- tgn10->min_v_blank_interlace = 5;
- tgn10->min_h_sync_width = 8;
- tgn10->min_v_sync_width = 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_optc.h
index bb1cbfdc3554..a3c7c2012f05 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
@@ -29,7 +29,7 @@
#include "timing_generator.h"
#define DCN10TG_FROM_TG(tg)\
- container_of(tg, struct dcn10_timing_generator, base)
+ container_of(tg, struct optc, base)
#define TG_COMMON_REG_LIST_DCN(inst) \
SRI(OTG_VSTARTUP_PARAM, OTG, inst),\
@@ -70,8 +70,6 @@
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),\
@@ -84,7 +82,7 @@
SRI(OTG_TEST_PATTERN_COLOR, OTG, inst)
-struct dcn_tg_registers {
+struct dcn_optc_registers {
uint32_t OTG_VERT_SYNC_CONTROL;
uint32_t OTG_MASTER_UPDATE_MODE;
uint32_t OTG_GSL_CONTROL;
@@ -129,9 +127,11 @@ struct dcn_tg_registers {
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)\
@@ -211,8 +211,6 @@ struct dcn_tg_registers {
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),\
@@ -332,8 +330,6 @@ struct dcn_tg_registers {
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;\
@@ -346,22 +342,35 @@ struct dcn_tg_registers {
type OTG_GSL2_EN;\
type OTG_GSL_MASTER_EN;\
type OTG_GSL_FORCE_DELAY;\
- type OTG_GSL_CHECK_ALL_FIELDS;
+ 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_tg_shift {
+
+struct dcn_optc_shift {
TG_REG_FIELD_LIST(uint8_t)
};
-struct dcn_tg_mask {
+struct dcn_optc_mask {
TG_REG_FIELD_LIST(uint32_t)
};
-struct dcn10_timing_generator {
+struct optc {
struct timing_generator base;
- const struct dcn_tg_registers *tg_regs;
- const struct dcn_tg_shift *tg_shift;
- const struct dcn_tg_mask *tg_mask;
+ 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;
@@ -376,7 +385,7 @@ struct dcn10_timing_generator {
uint32_t min_v_blank_interlace;
};
-void dcn10_timing_generator_init(struct dcn10_timing_generator *tg);
+void dcn10_timing_generator_init(struct optc *optc);
struct dcn_otg_state {
uint32_t v_blank_start;
@@ -397,7 +406,77 @@ struct dcn_otg_state {
uint32_t otg_enabled;
};
-void tgn10_read_otg_state(struct dcn10_timing_generator *tgn10,
+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 10cce51d31d2..44825e2c9ebb 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"
@@ -348,18 +348,18 @@ static const struct dcn_mpc_mask mpc_mask = {
#define tg_regs(id)\
[id] = {TG_COMMON_REG_LIST_DCN1_0(id)}
-static const struct dcn_tg_registers tg_regs[] = {
+static const struct dcn_optc_registers tg_regs[] = {
tg_regs(0),
tg_regs(1),
tg_regs(2),
tg_regs(3),
};
-static const struct dcn_tg_shift tg_shift = {
+static const struct dcn_optc_shift tg_shift = {
TG_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT)
};
-static const struct dcn_tg_mask tg_mask = {
+static const struct dcn_optc_mask tg_mask = {
TG_COMMON_MASK_SH_LIST_DCN1_0(_MASK)
};
@@ -553,8 +553,8 @@ static struct timing_generator *dcn10_timing_generator_create(
struct dc_context *ctx,
uint32_t instance)
{
- struct dcn10_timing_generator *tgn10 =
- kzalloc(sizeof(struct dcn10_timing_generator), GFP_KERNEL);
+ struct optc *tgn10 =
+ kzalloc(sizeof(struct optc), GFP_KERNEL);
if (!tgn10)
return NULL;
@@ -678,6 +678,7 @@ static struct dce_hwseq *dcn10_hwseq_create(
hws->shifts = &hwseq_shift;
hws->masks = &hwseq_mask;
hws->wa.DEGVIDCN10_253 = true;
+ hws->wa.false_optc_underflow = true;
}
return hws;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile
index 87bab8e8139f..3488af2b5786 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the 'utils' sub-component of DAL.
# It provides the general basic services required by other DAL
# subcomponents.
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
index 4c31fa54af39..c109b2c34c8f 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
@@ -35,35 +35,6 @@ static void set_soc_bounding_box(struct _vcs_dpi_soc_bounding_box_st *soc, enum
soc->writeback_latency_us = 12.0;
soc->ideal_dram_bw_after_urgent_percent = 80.0;
soc->max_request_size_bytes = 256;
-
- soc->vmin.dcfclk_mhz = 300.0;
- soc->vmin.dispclk_mhz = 608.0;
- soc->vmin.dppclk_mhz = 435.0;
- soc->vmin.dram_bw_per_chan_gbps = 12.8;
- soc->vmin.phyclk_mhz = 540.0;
- soc->vmin.socclk_mhz = 208.0;
-
- soc->vmid.dcfclk_mhz = 600.0;
- soc->vmid.dispclk_mhz = 661.0;
- soc->vmid.dppclk_mhz = 661.0;
- soc->vmid.dram_bw_per_chan_gbps = 12.8;
- soc->vmid.phyclk_mhz = 540.0;
- soc->vmid.socclk_mhz = 208.0;
-
- soc->vnom.dcfclk_mhz = 600.0;
- soc->vnom.dispclk_mhz = 661.0;
- soc->vnom.dppclk_mhz = 661.0;
- soc->vnom.dram_bw_per_chan_gbps = 38.4;
- soc->vnom.phyclk_mhz = 810;
- soc->vnom.socclk_mhz = 208.0;
-
- soc->vmax.dcfclk_mhz = 600.0;
- soc->vmax.dispclk_mhz = 1086.0;
- soc->vmax.dppclk_mhz = 661.0;
- soc->vmax.dram_bw_per_chan_gbps = 38.4;
- soc->vmax.phyclk_mhz = 810.0;
- soc->vmax.socclk_mhz = 208.0;
-
soc->downspread_percent = 0.5;
soc->dram_page_open_time_ns = 50.0;
soc->dram_rw_turnaround_time_ns = 17.5;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
index 2d9d6298f0d3..aeebd8bee628 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
@@ -79,10 +79,6 @@ struct _vcs_dpi_soc_bounding_box_st {
double writeback_latency_us;
double ideal_dram_bw_after_urgent_percent;
unsigned int max_request_size_bytes;
- struct _vcs_dpi_voltage_scaling_st vmin;
- struct _vcs_dpi_voltage_scaling_st vmid;
- struct _vcs_dpi_voltage_scaling_st vnom;
- struct _vcs_dpi_voltage_scaling_st vmax;
double downspread_percent;
double dram_page_open_time_ns;
double dram_rw_turnaround_time_ns;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
index 1f337ecfeab0..260e113fcc02 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
@@ -28,6 +28,15 @@
#include "dml_inline_defs.h"
+/*
+ * NOTE:
+ * This file is gcc-parseable HW gospel, coming straight from HW engineers.
+ *
+ * It doesn't adhere to Linux kernel style and sometimes will do things in odd
+ * ways. Unless there is something clearly wrong with it the code should
+ * remain as-is as it provides us with a guarantee from HW that it is correct.
+ */
+
#define BPP_INVALID 0
#define BPP_BLENDED_PIPE 0xffffffff
static const unsigned int NumberOfStates = DC__VOLTAGE_STATES;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c
index 8ba962df42e6..325dd2b757d6 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c
@@ -27,6 +27,15 @@
#include "display_mode_vba.h"
#include "display_rq_dlg_calc.h"
+/*
+ * NOTE:
+ * This file is gcc-parseable HW gospel, coming straight from HW engineers.
+ *
+ * It doesn't adhere to Linux kernel style and sometimes will do things in odd
+ * ways. Unless there is something clearly wrong with it the code should
+ * remain as-is as it provides us with a guarantee from HW that it is correct.
+ */
+
static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
double *refcyc_per_req_delivery_pre_cur,
double *refcyc_per_req_delivery_cur,
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
index 1e4b1e383401..c2037daa8e66 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
@@ -28,6 +28,15 @@
#include "dml_inline_defs.h"
+/*
+ * NOTE:
+ * This file is gcc-parseable HW gospel, coming straight from HW engineers.
+ *
+ * It doesn't adhere to Linux kernel style and sometimes will do things in odd
+ * ways. Unless there is something clearly wrong with it the code should
+ * remain as-is as it provides us with a guarantee from HW that it is correct.
+ */
+
static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
{
unsigned int ret_val = 0;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c
index bc7d8c707221..324239c77958 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c
@@ -27,6 +27,16 @@
#include "dc_features.h"
#include "dml_inline_defs.h"
+
+/*
+ * NOTE:
+ * This file is gcc-parseable HW gospel, coming straight from HW engineers.
+ *
+ * It doesn't adhere to Linux kernel style and sometimes will do things in odd
+ * ways. Unless there is something clearly wrong with it the code should
+ * remain as-is as it provides us with a guarantee from HW that it is correct.
+ */
+
void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box)
{
to_box->dram_clock_change_latency_us = from_box->dram_clock_change_latency_us;
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/Makefile b/drivers/gpu/drm/amd/display/dc/gpio/Makefile
index 70d01a9e9676..562ee189d780 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/gpio/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the 'gpio' sub-component of DAL.
# It provides the control and status of HW GPIO pins.
diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/Makefile b/drivers/gpu/drm/amd/display/dc/i2caux/Makefile
index 55603400acd9..352885cb4d07 100644
--- a/drivers/gpu/drm/amd/display/dc/i2caux/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/i2caux/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the 'i2c' sub-component of DAL.
# It provides the control and status of HW i2c engine of the adapter.
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index d680b565af6f..d6971054ec07 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -212,7 +212,6 @@ struct pipe_ctx {
struct _vcs_dpi_display_rq_regs_st rq_regs;
struct _vcs_dpi_display_pipe_dest_params_st pipe_dlg_param;
#endif
- struct dwbc *dwbc;
};
struct resource_context {
@@ -241,6 +240,7 @@ struct dce_bw_output {
struct dcn_bw_clocks {
int dispclk_khz;
+ int dppclk_khz;
bool dppclk_div;
int dcfclk_khz;
int dcfclk_deep_sleep_khz;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h
index 1e231f6de732..132d18d4b293 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h
@@ -349,10 +349,10 @@ struct dcn_bw_internal_vars {
float dst_x_after_scaler;
float dst_y_after_scaler;
float time_calc;
- float v_update_offset[number_of_planes_minus_one + 1];
+ float v_update_offset[number_of_planes_minus_one + 1][2];
float total_repeater_delay;
- float v_update_width[number_of_planes_minus_one + 1];
- float v_ready_offset[number_of_planes_minus_one + 1];
+ float v_update_width[number_of_planes_minus_one + 1][2];
+ float v_ready_offset[number_of_planes_minus_one + 1][2];
float time_setup;
float extra_latency;
float maximum_vstartup;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
index 48217ecfabd4..a83a48494613 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
@@ -50,9 +50,9 @@ struct abm_funcs {
bool (*set_backlight_level)(struct abm *abm,
unsigned int backlight_level,
unsigned int frame_ramp,
- unsigned int controller_id);
+ unsigned int controller_id,
+ bool use_smooth_brightness);
unsigned int (*get_current_backlight_8_bit)(struct abm *abm);
- bool (*is_dmcu_initialized)(struct abm *abm);
};
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
index b59712b41b81..ce206355461b 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
@@ -63,6 +63,7 @@ struct dmcu_funcs {
unsigned int wait_loop_number);
void (*get_psr_wait_loop)(struct dmcu *dmcu,
unsigned int *psr_wait_loop_number);
+ bool (*is_dmcu_initialized)(struct dmcu *dmcu);
};
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
index ccb4896975c2..25edbde6163e 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
@@ -68,7 +68,7 @@ struct dpp_funcs {
void (*dpp_set_csc_adjustment)(
struct dpp *dpp,
- const struct out_csc_color_matrix *tbl_entry);
+ const uint16_t *regval);
void (*dpp_power_on_regamma_lut)(
struct dpp *dpp,
@@ -122,7 +122,7 @@ struct dpp_funcs {
void (*set_cursor_attributes)(
struct dpp *dpp_base,
- const struct dc_cursor_attributes *attr);
+ enum dc_cursor_color_format color_format);
void (*set_cursor_position)(
struct dpp *dpp_base,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
index 49b12f602e79..b7c7e70022e4 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
@@ -28,6 +28,20 @@
#include "mem_input.h"
+
+enum cursor_pitch {
+ CURSOR_PITCH_64_PIXELS = 0,
+ CURSOR_PITCH_128_PIXELS,
+ CURSOR_PITCH_256_PIXELS
+};
+
+enum cursor_lines_per_chunk {
+ CURSOR_LINE_PER_CHUNK_2 = 1,
+ CURSOR_LINE_PER_CHUNK_4,
+ CURSOR_LINE_PER_CHUNK_8,
+ CURSOR_LINE_PER_CHUNK_16
+};
+
struct hubp {
struct hubp_funcs *funcs;
struct dc_context *ctx;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
index ddc56700109b..e3f0b4056318 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
@@ -126,36 +126,12 @@ struct default_adjustment {
bool force_hw_default;
};
-struct out_csc_color_matrix {
- enum dc_color_space color_space;
- uint16_t regval[12];
-};
-struct output_csc_matrix {
+struct out_csc_color_matrix {
enum dc_color_space color_space;
uint16_t regval[12];
};
-static const struct output_csc_matrix output_csc_matrix[] = {
- { COLOR_SPACE_SRGB,
- { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
- { COLOR_SPACE_SRGB_LIMITED,
- { 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} },
- { COLOR_SPACE_YCBCR601,
- { 0xE04, 0xF444, 0xFDB9, 0x1004, 0x831, 0x1016, 0x320, 0x201, 0xFB45,
- 0xF6B7, 0xE04, 0x1004} },
- { COLOR_SPACE_YCBCR709,
- { 0xE04, 0xF345, 0xFEB7, 0x1004, 0x5D3, 0x1399, 0x1FA,
- 0x201, 0xFCCA, 0xF533, 0xE04, 0x1004} },
-
- /* TODO: correct values below */
- { COLOR_SPACE_YCBCR601_LIMITED,
- { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
- 0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
- { COLOR_SPACE_YCBCR709_LIMITED,
- { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
- 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
-};
enum opp_regamma {
OPP_REGAMMA_BYPASS = 0,
@@ -178,4 +154,41 @@ struct dc_bias_and_scale {
uint16_t bias_blue;
};
+enum test_pattern_dyn_range {
+ TEST_PATTERN_DYN_RANGE_VESA = 0,
+ TEST_PATTERN_DYN_RANGE_CEA
+};
+
+enum test_pattern_mode {
+ TEST_PATTERN_MODE_COLORSQUARES_RGB = 0,
+ TEST_PATTERN_MODE_COLORSQUARES_YCBCR601,
+ TEST_PATTERN_MODE_COLORSQUARES_YCBCR709,
+ TEST_PATTERN_MODE_VERTICALBARS,
+ TEST_PATTERN_MODE_HORIZONTALBARS,
+ TEST_PATTERN_MODE_SINGLERAMP_RGB,
+ TEST_PATTERN_MODE_DUALRAMP_RGB
+};
+
+enum test_pattern_color_format {
+ TEST_PATTERN_COLOR_FORMAT_BPC_6 = 0,
+ TEST_PATTERN_COLOR_FORMAT_BPC_8,
+ TEST_PATTERN_COLOR_FORMAT_BPC_10,
+ TEST_PATTERN_COLOR_FORMAT_BPC_12
+};
+
+enum controller_dp_test_pattern {
+ CONTROLLER_DP_TEST_PATTERN_D102 = 0,
+ CONTROLLER_DP_TEST_PATTERN_SYMBOLERROR,
+ CONTROLLER_DP_TEST_PATTERN_PRBS7,
+ CONTROLLER_DP_TEST_PATTERN_COLORSQUARES,
+ CONTROLLER_DP_TEST_PATTERN_VERTICALBARS,
+ CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS,
+ CONTROLLER_DP_TEST_PATTERN_COLORRAMP,
+ CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
+ CONTROLLER_DP_TEST_PATTERN_RESERVED_8,
+ CONTROLLER_DP_TEST_PATTERN_RESERVED_9,
+ CONTROLLER_DP_TEST_PATTERN_RESERVED_A,
+ CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA
+};
+
#endif /* __DAL_HW_SHARED_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
index 8a08f0a97f94..0fd329deacd8 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -1,4 +1,26 @@
/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+/*
* link_encoder.h
*
* Created on: Oct 6, 2015
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
index 72ea33526a5c..23a8d5e53a89 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
@@ -26,7 +26,10 @@
#define __DC_MPCC_H__
#include "dc_hw_types.h"
-#include "opp.h"
+#include "hw_shared.h"
+
+#define MAX_MPCC 6
+#define MAX_OPP 6
enum mpc_output_csc_mode {
MPC_OUTPUT_CSC_DISABLE = 0,
@@ -34,45 +37,151 @@ enum mpc_output_csc_mode {
MPC_OUTPUT_CSC_COEF_B
};
-struct mpcc_cfg {
- int dpp_id;
- int opp_id;
- struct mpc_tree_cfg *tree_cfg;
- unsigned int z_index;
- struct tg_color black_color;
- bool per_pixel_alpha;
- bool pre_multiplied_alpha;
+enum mpcc_blend_mode {
+ MPCC_BLEND_MODE_BYPASS,
+ MPCC_BLEND_MODE_TOP_LAYER_PASSTHROUGH,
+ MPCC_BLEND_MODE_TOP_LAYER_ONLY,
+ MPCC_BLEND_MODE_TOP_BOT_BLENDING
+};
+
+enum mpcc_alpha_blend_mode {
+ MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA,
+ MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN,
+ MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA
+};
+
+/*
+ * MPCC blending configuration
+ */
+struct mpcc_blnd_cfg {
+ struct tg_color black_color; /* background color */
+ enum mpcc_alpha_blend_mode alpha_mode; /* alpha blend mode */
+ bool pre_multiplied_alpha; /* alpha pre-multiplied mode flag */
+ int global_gain;
+ int global_alpha;
+ bool overlap_only;
+
+};
+
+struct mpcc_sm_cfg {
+ bool enable;
+ /* 0-single plane,2-row subsampling,4-column subsampling,6-checkboard subsampling */
+ int sm_mode;
+ /* 0- disable frame alternate, 1- enable frame alternate */
+ bool frame_alt;
+ /* 0- disable field alternate, 1- enable field alternate */
+ bool field_alt;
+ /* 0-no force,2-force frame polarity from top,3-force frame polarity from bottom */
+ int force_next_frame_porlarity;
+ /* 0-no force,2-force field polarity from top,3-force field polarity from bottom */
+ int force_next_field_polarity;
+};
+
+/*
+ * MPCC connection and blending configuration for a single MPCC instance.
+ * This struct is used as a node in an MPC tree.
+ */
+struct mpcc {
+ int mpcc_id; /* MPCC physical instance */
+ int dpp_id; /* DPP input to this MPCC */
+ struct mpcc *mpcc_bot; /* pointer to bottom layer MPCC. NULL when not connected */
+ struct mpcc_blnd_cfg blnd_cfg; /* The blending configuration for this MPCC */
+ struct mpcc_sm_cfg sm_cfg; /* stereo mix setting for this MPCC */
+};
+
+/*
+ * MPC tree represents all MPCC connections for a pipe.
+ */
+struct mpc_tree {
+ int opp_id; /* The OPP instance that owns this MPC tree */
+ struct mpcc *opp_list; /* The top MPCC layer of the MPC tree that outputs to OPP endpoint */
};
struct mpc {
const struct mpc_funcs *funcs;
struct dc_context *ctx;
+
+ struct mpcc mpcc_array[MAX_MPCC];
};
struct mpc_funcs {
- int (*add)(struct mpc *mpc, struct mpcc_cfg *cfg);
+ /*
+ * Insert DPP into MPC tree based on specified blending position.
+ * Only used for planes that are part of blending chain for OPP output
+ *
+ * Parameters:
+ * [in/out] mpc - MPC context.
+ * [in/out] tree - MPC tree structure that plane will be added to.
+ * [in] blnd_cfg - MPCC blending configuration for the new blending layer.
+ * [in] sm_cfg - MPCC stereo mix configuration for the new blending layer.
+ * stereo mix must disable for the very bottom layer of the tree config.
+ * [in] insert_above_mpcc - Insert new plane above this MPCC. If NULL, insert as bottom plane.
+ * [in] dpp_id - DPP instance for the plane to be added.
+ * [in] mpcc_id - The MPCC physical instance to use for blending.
+ *
+ * Return: struct mpcc* - MPCC that was added.
+ */
+ struct mpcc* (*insert_plane)(
+ struct mpc *mpc,
+ struct mpc_tree *tree,
+ struct mpcc_blnd_cfg *blnd_cfg,
+ struct mpcc_sm_cfg *sm_cfg,
+ struct mpcc *insert_above_mpcc,
+ int dpp_id,
+ int mpcc_id);
- void (*remove)(struct mpc *mpc,
- struct mpc_tree_cfg *tree_cfg,
- int opp_id,
- int mpcc_inst);
+ /*
+ * Remove a specified MPCC from the MPC tree.
+ *
+ * Parameters:
+ * [in/out] mpc - MPC context.
+ * [in/out] tree - MPC tree structure that plane will be removed from.
+ * [in/out] mpcc - MPCC to be removed from tree.
+ *
+ * Return: void
+ */
+ void (*remove_mpcc)(
+ struct mpc *mpc,
+ struct mpc_tree *tree,
+ struct mpcc *mpcc);
- void (*wait_for_idle)(struct mpc *mpc, int id);
+ /*
+ * Reset the MPCC HW status by disconnecting all muxes.
+ *
+ * Parameters:
+ * [in/out] mpc - MPC context.
+ *
+ * Return: void
+ */
+ void (*mpc_init)(struct mpc *mpc);
- void (*update_blend_mode)(struct mpc *mpc, struct mpcc_cfg *cfg);
+ /*
+ * Update the blending configuration for a specified MPCC.
+ *
+ * Parameters:
+ * [in/out] mpc - MPC context.
+ * [in] blnd_cfg - MPCC blending configuration.
+ * [in] mpcc_id - The MPCC physical instance.
+ *
+ * Return: void
+ */
+ void (*update_blending)(
+ struct mpc *mpc,
+ struct mpcc_blnd_cfg *blnd_cfg,
+ int mpcc_id);
- int (*get_opp_id)(struct mpc *mpc, int mpcc_id);
+ struct mpcc* (*get_mpcc_for_dpp)(
+ struct mpc_tree *tree,
+ int dpp_id);
+
+ void (*wait_for_idle)(struct mpc *mpc, int id);
- void (*set_output_csc)(struct mpc *mpc,
- int opp_id,
- const struct out_csc_color_matrix *tbl_entry,
- enum mpc_output_csc_mode ocsc_mode);
+ void (*assert_mpcc_idle_before_connect)(struct mpc *mpc, int mpcc_id);
- void (*set_ocsc_default)(struct mpc *mpc,
- int opp_id,
- enum dc_color_space color_space,
- enum mpc_output_csc_mode ocsc_mode);
+ void (*init_mpcc_list_from_hw)(
+ struct mpc *mpc,
+ struct mpc_tree *tree);
};
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 579d1059a3d4..ab8fb77f1ae5 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
@@ -29,6 +29,7 @@
#include "hw_shared.h"
#include "dc_hw_types.h"
#include "transform.h"
+#include "mpc.h"
struct fixed31_32;
@@ -204,7 +205,7 @@ struct output_pixel_processor {
struct dc_context *ctx;
uint32_t inst;
struct pwl_params regamma_params;
- struct mpc_tree_cfg mpc_tree;
+ struct mpc_tree mpc_tree_params;
bool mpcc_disconnect_pending[MAX_PIPES];
const struct opp_funcs *funcs;
};
@@ -248,6 +249,21 @@ enum ovl_csc_adjust_item {
OVERLAY_COLOR_TEMPERATURE
};
+enum oppbuf_display_segmentation {
+ OPPBUF_DISPLAY_SEGMENTATION_1_SEGMENT = 0,
+ OPPBUF_DISPLAY_SEGMENTATION_2_SEGMENT = 1,
+ OPPBUF_DISPLAY_SEGMENTATION_4_SEGMENT = 2,
+ OPPBUF_DISPLAY_SEGMENTATION_4_SEGMENT_SPLIT_LEFT = 3,
+ OPPBUF_DISPLAY_SEGMENTATION_4_SEGMENT_SPLIT_RIGHT = 4
+};
+
+struct oppbuf_params {
+ uint32_t active_width;
+ enum oppbuf_display_segmentation mso_segmentation;
+ uint32_t mso_overlap_pixel_num;
+ uint32_t pixel_repetition;
+};
+
struct opp_funcs {
@@ -276,26 +292,11 @@ struct opp_funcs {
void (*opp_destroy)(struct output_pixel_processor **opp);
- void (*opp_set_stereo_polarity)(
- struct output_pixel_processor *opp,
- bool enable,
- bool rightEyePolarity);
-
- void (*opp_set_test_pattern)(
- struct output_pixel_processor *opp,
- bool enable);
-
- 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)(
+ void (*opp_program_stereo)(
struct output_pixel_processor *opp,
bool enable,
- bool polarity);
+ const struct dc_crtc_timing *timing);
+
};
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
index 3050afe8e8a9..b5db1692393c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
@@ -1,4 +1,26 @@
/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+/*
* stream_encoder.h
*
*/
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
index 860259913d78..ec312f1a3e55 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
@@ -26,6 +26,8 @@
#ifndef __DAL_TIMING_GENERATOR_TYPES_H__
#define __DAL_TIMING_GENERATOR_TYPES_H__
+#include "hw_shared.h"
+
struct dc_bios;
/* Contains CRTC vertical/horizontal pixel counters */
@@ -40,6 +42,19 @@ struct dcp_gsl_params {
int gsl_master;
};
+struct gsl_params {
+ int gsl0_en;
+ int gsl1_en;
+ int gsl2_en;
+ int gsl_master_en;
+ int gsl_master_mode;
+ int master_update_lock_gsl_en;
+ int gsl_window_start_x;
+ int gsl_window_end_x;
+ int gsl_window_start_y;
+ int gsl_window_end_y;
+};
+
/* define the structure of Dynamic Refresh Mode */
struct drr_params {
uint32_t vertical_total_min;
@@ -50,43 +65,6 @@ struct drr_params {
#define LEFT_EYE_3D_PRIMARY_SURFACE 1
#define RIGHT_EYE_3D_PRIMARY_SURFACE 0
-enum test_pattern_dyn_range {
- TEST_PATTERN_DYN_RANGE_VESA = 0,
- TEST_PATTERN_DYN_RANGE_CEA
-};
-
-enum test_pattern_mode {
- TEST_PATTERN_MODE_COLORSQUARES_RGB = 0,
- TEST_PATTERN_MODE_COLORSQUARES_YCBCR601,
- TEST_PATTERN_MODE_COLORSQUARES_YCBCR709,
- TEST_PATTERN_MODE_VERTICALBARS,
- TEST_PATTERN_MODE_HORIZONTALBARS,
- TEST_PATTERN_MODE_SINGLERAMP_RGB,
- TEST_PATTERN_MODE_DUALRAMP_RGB
-};
-
-enum test_pattern_color_format {
- TEST_PATTERN_COLOR_FORMAT_BPC_6 = 0,
- TEST_PATTERN_COLOR_FORMAT_BPC_8,
- TEST_PATTERN_COLOR_FORMAT_BPC_10,
- TEST_PATTERN_COLOR_FORMAT_BPC_12
-};
-
-enum controller_dp_test_pattern {
- CONTROLLER_DP_TEST_PATTERN_D102 = 0,
- CONTROLLER_DP_TEST_PATTERN_SYMBOLERROR,
- CONTROLLER_DP_TEST_PATTERN_PRBS7,
- CONTROLLER_DP_TEST_PATTERN_COLORSQUARES,
- CONTROLLER_DP_TEST_PATTERN_VERTICALBARS,
- CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS,
- CONTROLLER_DP_TEST_PATTERN_COLORRAMP,
- CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
- CONTROLLER_DP_TEST_PATTERN_RESERVED_8,
- CONTROLLER_DP_TEST_PATTERN_RESERVED_9,
- CONTROLLER_DP_TEST_PATTERN_RESERVED_A,
- CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA
-};
-
enum crtc_state {
CRTC_STATE_VBLANK = 0,
CRTC_STATE_VACTIVE
@@ -100,6 +78,12 @@ struct _dlg_otg_param {
enum signal_type signal;
};
+struct vupdate_keepout_params {
+ int start_offset;
+ int end_offset;
+ int enable;
+};
+
struct crtc_stereo_flags {
uint8_t PROGRAM_STEREO : 1;
uint8_t PROGRAM_POLARITY : 1;
@@ -187,6 +171,8 @@ struct timing_generator_funcs {
void (*tg_init)(struct timing_generator *tg);
bool (*is_tg_enabled)(struct timing_generator *tg);
+ bool (*is_optc_underflow_occurred)(struct timing_generator *tg);
+ void (*clear_optc_underflow)(struct timing_generator *tg);
};
#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 5dc4ecf618ff..4c0aa56f7bae 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"
@@ -40,6 +41,7 @@ enum pipe_gating_control {
struct dce_hwseq_wa {
bool blnd_crtc_trigger;
bool DEGVIDCN10_253;
+ bool false_optc_underflow;
};
struct hwseq_wa_state {
@@ -137,10 +139,6 @@ struct hw_sequencer_funcs {
void (*disable_plane)(struct dc *dc, struct pipe_ctx *pipe_ctx);
- void (*enable_plane)(struct dc *dc,
- struct pipe_ctx *pipe,
- struct dc_state *context);
-
void (*update_info_frame)(struct pipe_ctx *pipe_ctx);
void (*enable_stream)(struct pipe_ctx *pipe_ctx);
@@ -198,6 +196,7 @@ struct hw_sequencer_funcs {
void (*edp_backlight_control)(
struct dc_link *link,
bool enable);
+ void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up);
};
@@ -209,4 +208,8 @@ void color_space_to_black_color(
bool hwss_wait_for_blank_complete(
struct timing_generator *tg);
+const uint16_t *find_color_matrix(
+ enum dc_color_space color_space,
+ uint32_t *array_size);
+
#endif /* __DC_HW_SEQUENCER_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/irq/Makefile b/drivers/gpu/drm/amd/display/dc/irq/Makefile
index c7e93f7223bd..498515aad4a5 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/irq/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the 'audio' sub-component of DAL.
# It provides the control and status of HW adapter resources,
# that are global for the ASIC and sharable between pipes.
diff --git a/drivers/gpu/drm/amd/display/dc/os_types.h b/drivers/gpu/drm/amd/display/dc/os_types.h
index a87c0329541f..1fcbc99e63b5 100644
--- a/drivers/gpu/drm/amd/display/dc/os_types.h
+++ b/drivers/gpu/drm/amd/display/dc/os_types.h
@@ -26,8 +26,6 @@
#ifndef _OS_TYPES_H_
#define _OS_TYPES_H_
-#if defined __KERNEL__
-
#include <asm/byteorder.h>
#include <linux/types.h>
#include <drm/drmP.h>
@@ -46,14 +44,12 @@
#undef WRITE
#undef FRAME_SIZE
-#define dm_output_to_console(fmt, ...) DRM_INFO(fmt, ##__VA_ARGS__)
+#define dm_output_to_console(fmt, ...) DRM_DEBUG_KMS(fmt, ##__VA_ARGS__)
#define dm_error(fmt, ...) DRM_ERROR(fmt, ##__VA_ARGS__)
-#define dm_debug(fmt, ...) DRM_DEBUG_KMS(fmt, ##__VA_ARGS__)
-
-#define dm_vlog(fmt, args) vprintk(fmt, args)
-
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
+#include <asm/fpu/api.h>
#endif
/*
@@ -89,8 +85,4 @@
BREAK_TO_DEBUGGER(); \
} while (0)
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
-#include <asm/fpu/api.h>
-#endif
-
#endif /* _OS_TYPES_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/virtual/Makefile b/drivers/gpu/drm/amd/display/dc/virtual/Makefile
index fc0b7318d9cc..07326d244d50 100644
--- a/drivers/gpu/drm/amd/display/dc/virtual/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/virtual/Makefile
@@ -1,4 +1,25 @@
#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
# Makefile for the virtual sub-component of DAL.
# It provides the control and status of HW CRTC block.
OpenPOWER on IntegriCloud