summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc/dce112/dce112_opp_formatter.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dce112/dce112_opp_formatter.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce112/dce112_opp_formatter.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_opp_formatter.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_opp_formatter.c
new file mode 100644
index 000000000000..2d9072138834
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_opp_formatter.c
@@ -0,0 +1,215 @@
+/*
+ * 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 "dce/dce_11_2_d.h"
+#include "dce/dce_11_2_sh_mask.h"
+
+#include "dce112_opp.h"
+
+#define FMT_REG(reg)\
+ (reg + opp110->offsets.fmt_offset)
+#define FMT_MEM_REG(reg)\
+ (reg + opp110->offsets.fmt_mem_offset)
+
+/**
+ * Set Clamping
+ * 1) Set clamping format based on bpc - 0 for 6bpc (No clamping)
+ * 1 for 8 bpc
+ * 2 for 10 bpc
+ * 3 for 12 bpc
+ * 7 for programable
+ * 2) Enable clamp if Limited range requested
+ */
+
+/**
+ * set_pixel_encoding
+ *
+ * Set Pixel Encoding
+ * 0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly
+ * 1: YCbCr 4:2:2
+ * 2: YCbCr 4:2:0
+ */
+static void set_pixel_encoding(
+ struct dce110_opp *opp110,
+ const struct clamping_and_pixel_encoding_params *params)
+{
+ uint32_t fmt_cntl_value;
+ uint32_t addr = FMT_REG(mmFMT_CONTROL);
+
+ /*RGB 4:4:4 or YCbCr 4:4:4 - 0; YCbCr 4:2:2 -1.*/
+ fmt_cntl_value = dm_read_reg(opp110->base.ctx, addr);
+
+ set_reg_field_value(fmt_cntl_value,
+ 0,
+ FMT_CONTROL,
+ FMT_PIXEL_ENCODING);
+
+ /*00 - Pixels drop mode HW default*/
+ set_reg_field_value(fmt_cntl_value,
+ 0,
+ FMT_CONTROL,
+ FMT_SUBSAMPLING_MODE);
+
+ /* By default no bypass*/
+ set_reg_field_value(fmt_cntl_value,
+ 0,
+ FMT_CONTROL,
+ FMT_CBCR_BIT_REDUCTION_BYPASS);
+
+ if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
+ set_reg_field_value(fmt_cntl_value,
+ 1,
+ FMT_CONTROL,
+ FMT_PIXEL_ENCODING);
+
+ /*00 - Cb before Cr ,01 - Cr before Cb*/
+ set_reg_field_value(fmt_cntl_value,
+ 0,
+ FMT_CONTROL,
+ FMT_SUBSAMPLING_ORDER);
+ }
+
+ if (params->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
+ set_reg_field_value(fmt_cntl_value,
+ 2,
+ FMT_CONTROL,
+ FMT_PIXEL_ENCODING);
+
+ /* 02 - Subsampling mode, 3 taps*/
+ set_reg_field_value(fmt_cntl_value,
+ 2,
+ FMT_CONTROL,
+ FMT_SUBSAMPLING_MODE);
+
+ /* 00 - Enable CbCr bit reduction bypass to preserve precision*/
+ set_reg_field_value(fmt_cntl_value,
+ 1,
+ FMT_CONTROL,
+ FMT_CBCR_BIT_REDUCTION_BYPASS);
+ }
+ dm_write_reg(opp110->base.ctx, addr, fmt_cntl_value);
+
+}
+
+void dce112_opp_program_clamping_and_pixel_encoding(
+ struct output_pixel_processor *opp,
+ const struct clamping_and_pixel_encoding_params *params)
+{
+ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
+
+ dce110_opp_set_clamping(opp110, params);
+ set_pixel_encoding(opp110, params);
+}
+
+static void program_formatter_420_memory(struct output_pixel_processor *opp)
+{
+ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
+ uint32_t fmt_cntl_value;
+ uint32_t fmt_mem_cntl_value;
+ uint32_t fmt_cntl_addr = FMT_REG(mmFMT_CONTROL);
+ uint32_t fmt_mem_cntl_addr = FMT_MEM_REG(mmFMT_MEMORY0_CONTROL);
+
+ fmt_mem_cntl_value = dm_read_reg(opp110->base.ctx, fmt_mem_cntl_addr);
+ fmt_cntl_value = dm_read_reg(opp110->base.ctx, fmt_cntl_addr);
+ /* Program source select*/
+ /* Use HW default source select for FMT_MEMORYx_CONTROL */
+ /* Use that value for FMT_SRC_SELECT as well*/
+ set_reg_field_value(fmt_cntl_value,
+ get_reg_field_value(fmt_mem_cntl_value, FMT_MEMORY0_CONTROL, FMT420_MEM0_SOURCE_SEL),
+ FMT_CONTROL,
+ FMT_SRC_SELECT);
+ dm_write_reg(opp110->base.ctx, fmt_cntl_addr, fmt_cntl_value);
+
+ /* Turn on the memory */
+ set_reg_field_value(fmt_mem_cntl_value,
+ 0,
+ FMT_MEMORY0_CONTROL,
+ FMT420_MEM0_PWR_FORCE);
+ dm_write_reg(opp110->base.ctx, fmt_mem_cntl_addr, fmt_mem_cntl_value);
+}
+
+static void program_formatter_reset_dig_resync_fifo(struct output_pixel_processor *opp)
+{
+ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
+ uint32_t value;
+ uint32_t addr = FMT_REG(mmFMT_CONTROL);
+ uint8_t counter = 10;
+
+
+ value = dm_read_reg(opp110->base.ctx, addr);
+
+ /* clear previous phase lock status*/
+ set_reg_field_value(value,
+ 1,
+ FMT_CONTROL,
+ FMT_420_PIXEL_PHASE_LOCKED_CLEAR);
+ dm_write_reg(opp110->base.ctx, addr, value);
+
+ /* poll until FMT_420_PIXEL_PHASE_LOCKED become 1*/
+ while (counter > 0) {
+ value = dm_read_reg(opp110->base.ctx, addr);
+
+ if (get_reg_field_value(
+ value,
+ FMT_CONTROL,
+ FMT_420_PIXEL_PHASE_LOCKED) == 1)
+ break;
+
+ msleep(10);
+ counter--;
+ }
+
+ if (counter == 0)
+ dm_logger_write(opp->ctx->logger, LOG_ERROR,
+ "%s:opp program formattter reset dig resync info time out.\n",
+ __func__);
+}
+
+void dce112_opp_program_fmt(
+ struct output_pixel_processor *opp,
+ struct bit_depth_reduction_params *fmt_bit_depth,
+ struct clamping_and_pixel_encoding_params *clamping)
+{
+ /* dithering is affected by <CrtcSourceSelect>, hence should be
+ * programmed afterwards */
+
+ if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
+ program_formatter_420_memory(opp);
+
+ dce110_opp_program_bit_depth_reduction(
+ opp,
+ fmt_bit_depth);
+
+ dce112_opp_program_clamping_and_pixel_encoding(
+ opp,
+ clamping);
+
+ if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
+ program_formatter_reset_dig_resync_fifo(opp);
+
+ return;
+}