drm/amd/display: add DCN32/321 specific files for Display Core
Add core DC support for DCN 3.2.x. v2: squash in fixup (Alex) Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
265280b998
commit
235c676342
37
drivers/gpu/drm/amd/display/dc/dcn32/Makefile
Normal file
37
drivers/gpu/drm/amd/display/dc/dcn32/Makefile
Normal file
@ -0,0 +1,37 @@
|
||||
#
|
||||
# (c) Copyright 2022 Advanced Micro Devices, Inc. All the rights reserved
|
||||
#
|
||||
# All rights reserved. This notice is intended as a precaution against
|
||||
# inadvertent publication and does not imply publication or any waiver
|
||||
# of confidentiality. The year included in the foregoing notice is the
|
||||
# year of creation of the work.
|
||||
#
|
||||
# Authors: AMD
|
||||
#
|
||||
# Makefile for dcn32.
|
||||
|
||||
DCN32 = dcn32_resource.o dcn32_hubbub.o dcn32_hwseq.o dcn32_init.o \
|
||||
dcn32_dccg.o dcn32_optc.o dcn32_mmhubbub.o dcn32_hubp.o dcn32_dpp.o \
|
||||
dcn32_dio_stream_encoder.o dcn32_dio_link_encoder.o dcn32_hpo_dp_link_encoder.o \
|
||||
dcn32_mpc.o
|
||||
|
||||
CFLAGS_$(AMDDALPATH)/dc/dcn32/dcn32_resource.o := -mhard-float -msse
|
||||
|
||||
ifdef CONFIG_CC_IS_GCC
|
||||
ifeq ($(call cc-ifversion, -lt, 0701, y), y)
|
||||
IS_OLD_GCC = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef IS_OLD_GCC
|
||||
# Stack alignment mismatch, proceed with caution.
|
||||
# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3
|
||||
# (8B stack alignment).
|
||||
CFLAGS_$(AMDDALPATH)/dc/dcn32/dcn32_resource.o += -mpreferred-stack-boundary=4
|
||||
else
|
||||
CFLAGS_$(AMDDALPATH)/dc/dcn32/dcn32_resource.o += -msse2
|
||||
endif
|
||||
|
||||
AMD_DAL_DCN32 = $(addprefix $(AMDDALPATH)/dc/dcn32/,$(DCN32))
|
||||
|
||||
AMD_DISPLAY_FILES += $(AMD_DAL_DCN32)
|
299
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
Normal file
299
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
Normal file
@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "reg_helper.h"
|
||||
#include "core_types.h"
|
||||
#include "dcn32_dccg.h"
|
||||
|
||||
#define TO_DCN_DCCG(dccg)\
|
||||
container_of(dccg, struct dcn_dccg, base)
|
||||
|
||||
#define REG(reg) \
|
||||
(dccg_dcn->regs->reg)
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name
|
||||
|
||||
#define CTX \
|
||||
dccg_dcn->base.ctx
|
||||
#define DC_LOGGER \
|
||||
dccg->ctx->logger
|
||||
|
||||
enum pixel_rate_div {
|
||||
PIXEL_RATE_DIV_BY_1 = 0,
|
||||
PIXEL_RATE_DIV_BY_2 = 1,
|
||||
PIXEL_RATE_DIV_BY_4 = 3
|
||||
};
|
||||
|
||||
static void dccg32_set_pixel_rate_div(
|
||||
struct dccg *dccg,
|
||||
uint32_t otg_inst,
|
||||
enum pixel_rate_div k1,
|
||||
enum pixel_rate_div k2)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
switch (otg_inst) {
|
||||
case 0:
|
||||
REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
|
||||
OTG0_PIXEL_RATE_DIVK1, k1,
|
||||
OTG0_PIXEL_RATE_DIVK2, k2);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
|
||||
OTG1_PIXEL_RATE_DIVK1, k1,
|
||||
OTG1_PIXEL_RATE_DIVK2, k2);
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
|
||||
OTG2_PIXEL_RATE_DIVK1, k1,
|
||||
OTG2_PIXEL_RATE_DIVK2, k2);
|
||||
break;
|
||||
case 3:
|
||||
REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
|
||||
OTG3_PIXEL_RATE_DIVK1, k1,
|
||||
OTG3_PIXEL_RATE_DIVK2, k2);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void dccg32_set_dtbclk_p_src(
|
||||
struct dccg *dccg,
|
||||
enum streamclk_source src,
|
||||
uint32_t otg_inst)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
uint32_t p_src_sel = 0; /* selects dprefclk */
|
||||
if (src == DTBCLK0)
|
||||
p_src_sel = 2; /* selects dtbclk0 */
|
||||
|
||||
switch (otg_inst) {
|
||||
case 0:
|
||||
if (src == REFCLK)
|
||||
REG_UPDATE(DTBCLK_P_CNTL,
|
||||
DTBCLK_P0_EN, 0);
|
||||
else
|
||||
REG_UPDATE_2(DTBCLK_P_CNTL,
|
||||
DTBCLK_P0_SRC_SEL, p_src_sel,
|
||||
DTBCLK_P0_EN, 1);
|
||||
break;
|
||||
case 1:
|
||||
if (src == REFCLK)
|
||||
REG_UPDATE(DTBCLK_P_CNTL,
|
||||
DTBCLK_P1_EN, 0);
|
||||
else
|
||||
REG_UPDATE_2(DTBCLK_P_CNTL,
|
||||
DTBCLK_P1_SRC_SEL, p_src_sel,
|
||||
DTBCLK_P1_EN, 1);
|
||||
break;
|
||||
case 2:
|
||||
if (src == REFCLK)
|
||||
REG_UPDATE(DTBCLK_P_CNTL,
|
||||
DTBCLK_P2_EN, 0);
|
||||
else
|
||||
REG_UPDATE_2(DTBCLK_P_CNTL,
|
||||
DTBCLK_P2_SRC_SEL, p_src_sel,
|
||||
DTBCLK_P2_EN, 1);
|
||||
break;
|
||||
case 3:
|
||||
if (src == REFCLK)
|
||||
REG_UPDATE(DTBCLK_P_CNTL,
|
||||
DTBCLK_P3_EN, 0);
|
||||
else
|
||||
REG_UPDATE_2(DTBCLK_P_CNTL,
|
||||
DTBCLK_P3_SRC_SEL, p_src_sel,
|
||||
DTBCLK_P3_EN, 1);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
|
||||
void dccg32_set_dtbclk_dto(
|
||||
struct dccg *dccg,
|
||||
int otg_inst,
|
||||
int pixclk_khz,
|
||||
int num_odm_segments,
|
||||
const struct dc_crtc_timing *timing)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
/* DTO Output Rate / Pixel Rate = 1/4 */
|
||||
int req_dtbclk_khz = pixclk_khz / 4;
|
||||
|
||||
if (dccg->ref_dtbclk_khz && req_dtbclk_khz) {
|
||||
uint32_t modulo, phase;
|
||||
|
||||
// phase / modulo = dtbclk / dtbclk ref
|
||||
modulo = 0xffffffff;
|
||||
phase = (((unsigned long long)modulo * req_dtbclk_khz) + dccg->ref_dtbclk_khz - 1) / dccg->ref_dtbclk_khz;
|
||||
|
||||
REG_WRITE(DTBCLK_DTO_MODULO[otg_inst], modulo);
|
||||
REG_WRITE(DTBCLK_DTO_PHASE[otg_inst], phase);
|
||||
|
||||
REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
|
||||
DTBCLK_DTO_ENABLE[otg_inst], 1);
|
||||
|
||||
REG_WAIT(OTG_PIXEL_RATE_CNTL[otg_inst],
|
||||
DTBCLKDTO_ENABLE_STATUS[otg_inst], 1,
|
||||
1, 100);
|
||||
|
||||
/* program OTG_PIXEL_RATE_DIV for DIVK1 and DIVK2 fields */
|
||||
dccg32_set_pixel_rate_div(dccg, otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
|
||||
|
||||
/* The recommended programming sequence to enable DTBCLK DTO to generate
|
||||
* valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
|
||||
* be set only after DTO is enabled
|
||||
*/
|
||||
REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
|
||||
PIPE_DTO_SRC_SEL[otg_inst], 2);
|
||||
|
||||
dccg->dtbclk_khz[otg_inst] = req_dtbclk_khz;
|
||||
} else {
|
||||
REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[otg_inst],
|
||||
DTBCLK_DTO_ENABLE[otg_inst], 0,
|
||||
PIPE_DTO_SRC_SEL[otg_inst], 1);
|
||||
|
||||
REG_WRITE(DTBCLK_DTO_MODULO[otg_inst], 0);
|
||||
REG_WRITE(DTBCLK_DTO_PHASE[otg_inst], 0);
|
||||
|
||||
dccg->dtbclk_khz[otg_inst] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void dccg32_get_dccg_ref_freq(struct dccg *dccg,
|
||||
unsigned int xtalin_freq_inKhz,
|
||||
unsigned int *dccg_ref_freq_inKhz)
|
||||
{
|
||||
/*
|
||||
* Assume refclk is sourced from xtalin
|
||||
* expect 100MHz
|
||||
*/
|
||||
*dccg_ref_freq_inKhz = xtalin_freq_inKhz;
|
||||
return;
|
||||
}
|
||||
|
||||
void dccg32_set_dpstreamclk(
|
||||
struct dccg *dccg,
|
||||
enum streamclk_source src,
|
||||
int otg_inst)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
/* set the dtbclk_p source */
|
||||
dccg32_set_dtbclk_p_src(dccg, src, otg_inst);
|
||||
|
||||
/* enabled to select one of the DTBCLKs for pipe */
|
||||
switch (otg_inst)
|
||||
{
|
||||
case 0:
|
||||
REG_UPDATE_2(DPSTREAMCLK_CNTL,
|
||||
DPSTREAMCLK0_EN,
|
||||
(src == REFCLK) ? 0 : 1, DPSTREAMCLK0_SRC_SEL, 0);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK1_EN,
|
||||
(src == REFCLK) ? 0 : 1, DPSTREAMCLK1_SRC_SEL, 1);
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK2_EN,
|
||||
(src == REFCLK) ? 0 : 1, DPSTREAMCLK2_SRC_SEL, 2);
|
||||
break;
|
||||
case 3:
|
||||
REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK3_EN,
|
||||
(src == REFCLK) ? 0 : 1, DPSTREAMCLK3_SRC_SEL, 3);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void dccg32_otg_add_pixel(struct dccg *dccg,
|
||||
uint32_t otg_inst)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
|
||||
OTG_ADD_PIXEL[otg_inst], 1);
|
||||
}
|
||||
|
||||
void dccg32_otg_drop_pixel(struct dccg *dccg,
|
||||
uint32_t otg_inst)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
|
||||
OTG_DROP_PIXEL[otg_inst], 1);
|
||||
}
|
||||
|
||||
static const struct dccg_funcs dccg32_funcs = {
|
||||
.update_dpp_dto = dccg2_update_dpp_dto,
|
||||
.get_dccg_ref_freq = dccg32_get_dccg_ref_freq,
|
||||
.dccg_init = dccg31_init,
|
||||
.set_dpstreamclk = dccg32_set_dpstreamclk,
|
||||
.enable_symclk32_se = dccg31_enable_symclk32_se,
|
||||
.disable_symclk32_se = dccg31_disable_symclk32_se,
|
||||
.enable_symclk32_le = dccg31_enable_symclk32_le,
|
||||
.disable_symclk32_le = dccg31_disable_symclk32_le,
|
||||
.set_physymclk = dccg31_set_physymclk,
|
||||
.set_dtbclk_dto = dccg32_set_dtbclk_dto,
|
||||
.set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
|
||||
.set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
|
||||
.otg_add_pixel = dccg32_otg_add_pixel,
|
||||
.otg_drop_pixel = dccg32_otg_drop_pixel,
|
||||
};
|
||||
|
||||
struct dccg *dccg32_create(
|
||||
struct dc_context *ctx,
|
||||
const struct dccg_registers *regs,
|
||||
const struct dccg_shift *dccg_shift,
|
||||
const struct dccg_mask *dccg_mask)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
|
||||
struct dccg *base;
|
||||
|
||||
if (dccg_dcn == NULL) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
base = &dccg_dcn->base;
|
||||
base->ctx = ctx;
|
||||
base->funcs = &dccg32_funcs;
|
||||
|
||||
dccg_dcn->regs = regs;
|
||||
dccg_dcn->dccg_shift = dccg_shift;
|
||||
dccg_dcn->dccg_mask = dccg_mask;
|
||||
|
||||
return &dccg_dcn->base;
|
||||
}
|
155
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h
Normal file
155
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DCN32_DCCG_H__
|
||||
#define __DCN32_DCCG_H__
|
||||
|
||||
#include "dcn31/dcn31_dccg.h"
|
||||
|
||||
#define DCCG_SFII(block, reg_name, field_prefix, field_name, inst, post_fix)\
|
||||
.field_prefix ## _ ## field_name[inst] = block ## inst ## _ ## reg_name ## __ ## field_prefix ## inst ## _ ## field_name ## post_fix
|
||||
|
||||
|
||||
#define DCCG_REG_LIST_DCN32() \
|
||||
SR(DPPCLK_DTO_CTRL),\
|
||||
DCCG_SRII(DTO_PARAM, DPPCLK, 0),\
|
||||
DCCG_SRII(DTO_PARAM, DPPCLK, 1),\
|
||||
DCCG_SRII(DTO_PARAM, DPPCLK, 2),\
|
||||
DCCG_SRII(DTO_PARAM, DPPCLK, 3),\
|
||||
DCCG_SRII(CLOCK_CNTL, HDMICHARCLK, 0),\
|
||||
SR(PHYASYMCLK_CLOCK_CNTL),\
|
||||
SR(PHYBSYMCLK_CLOCK_CNTL),\
|
||||
SR(PHYCSYMCLK_CLOCK_CNTL),\
|
||||
SR(PHYDSYMCLK_CLOCK_CNTL),\
|
||||
SR(PHYESYMCLK_CLOCK_CNTL),\
|
||||
SR(DPSTREAMCLK_CNTL),\
|
||||
SR(SYMCLK32_SE_CNTL),\
|
||||
SR(SYMCLK32_LE_CNTL),\
|
||||
DCCG_SRII(PIXEL_RATE_CNTL, OTG, 0),\
|
||||
DCCG_SRII(PIXEL_RATE_CNTL, OTG, 1),\
|
||||
DCCG_SRII(PIXEL_RATE_CNTL, OTG, 2),\
|
||||
DCCG_SRII(PIXEL_RATE_CNTL, OTG, 3),\
|
||||
DCCG_SRII(MODULO, DTBCLK_DTO, 0),\
|
||||
DCCG_SRII(MODULO, DTBCLK_DTO, 1),\
|
||||
DCCG_SRII(MODULO, DTBCLK_DTO, 2),\
|
||||
DCCG_SRII(MODULO, DTBCLK_DTO, 3),\
|
||||
DCCG_SRII(PHASE, DTBCLK_DTO, 0),\
|
||||
DCCG_SRII(PHASE, DTBCLK_DTO, 1),\
|
||||
DCCG_SRII(PHASE, DTBCLK_DTO, 2),\
|
||||
DCCG_SRII(PHASE, DTBCLK_DTO, 3),\
|
||||
SR(DCCG_AUDIO_DTBCLK_DTO_MODULO),\
|
||||
SR(DCCG_AUDIO_DTBCLK_DTO_PHASE),\
|
||||
SR(OTG_PIXEL_RATE_DIV),\
|
||||
SR(DTBCLK_P_CNTL),\
|
||||
SR(DCCG_AUDIO_DTO_SOURCE)
|
||||
|
||||
|
||||
#define DCCG_MASK_SH_LIST_DCN32(mask_sh) \
|
||||
DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 0, mask_sh),\
|
||||
DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 0, mask_sh),\
|
||||
DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 1, mask_sh),\
|
||||
DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 1, mask_sh),\
|
||||
DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 2, mask_sh),\
|
||||
DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 2, mask_sh),\
|
||||
DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 3, mask_sh),\
|
||||
DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 3, mask_sh),\
|
||||
DCCG_SF(DPPCLK0_DTO_PARAM, DPPCLK0_DTO_PHASE, mask_sh),\
|
||||
DCCG_SF(DPPCLK0_DTO_PARAM, DPPCLK0_DTO_MODULO, mask_sh),\
|
||||
DCCG_SF(HDMICHARCLK0_CLOCK_CNTL, HDMICHARCLK0_EN, mask_sh),\
|
||||
DCCG_SF(HDMICHARCLK0_CLOCK_CNTL, HDMICHARCLK0_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(PHYASYMCLK_CLOCK_CNTL, PHYASYMCLK_FORCE_EN, mask_sh),\
|
||||
DCCG_SF(PHYASYMCLK_CLOCK_CNTL, PHYASYMCLK_FORCE_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(PHYBSYMCLK_CLOCK_CNTL, PHYBSYMCLK_FORCE_EN, mask_sh),\
|
||||
DCCG_SF(PHYBSYMCLK_CLOCK_CNTL, PHYBSYMCLK_FORCE_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(PHYCSYMCLK_CLOCK_CNTL, PHYCSYMCLK_FORCE_EN, mask_sh),\
|
||||
DCCG_SF(PHYCSYMCLK_CLOCK_CNTL, PHYCSYMCLK_FORCE_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(PHYDSYMCLK_CLOCK_CNTL, PHYDSYMCLK_FORCE_EN, mask_sh),\
|
||||
DCCG_SF(PHYDSYMCLK_CLOCK_CNTL, PHYDSYMCLK_FORCE_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(PHYESYMCLK_CLOCK_CNTL, PHYESYMCLK_FORCE_EN, mask_sh),\
|
||||
DCCG_SF(PHYESYMCLK_CLOCK_CNTL, PHYESYMCLK_FORCE_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK0_EN, mask_sh),\
|
||||
DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK1_EN, mask_sh),\
|
||||
DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK2_EN, mask_sh),\
|
||||
DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK3_EN, mask_sh),\
|
||||
DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK0_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK1_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK2_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK3_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(HDMISTREAMCLK_CNTL, HDMISTREAMCLK0_EN, mask_sh),\
|
||||
DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE0_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE1_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE2_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE3_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE0_EN, mask_sh),\
|
||||
DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE1_EN, mask_sh),\
|
||||
DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE2_EN, mask_sh),\
|
||||
DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE3_EN, mask_sh),\
|
||||
DCCG_SF(SYMCLK32_LE_CNTL, SYMCLK32_LE0_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(SYMCLK32_LE_CNTL, SYMCLK32_LE1_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(SYMCLK32_LE_CNTL, SYMCLK32_LE0_EN, mask_sh),\
|
||||
DCCG_SF(SYMCLK32_LE_CNTL, SYMCLK32_LE1_EN, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLK_DTO, ENABLE, 0, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLK_DTO, ENABLE, 1, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLK_DTO, ENABLE, 2, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLK_DTO, ENABLE, 3, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLKDTO, ENABLE_STATUS, 0, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLKDTO, ENABLE_STATUS, 1, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLKDTO, ENABLE_STATUS, 2, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLKDTO, ENABLE_STATUS, 3, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, PIPE, DTO_SRC_SEL, 0, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, PIPE, DTO_SRC_SEL, 1, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, PIPE, DTO_SRC_SEL, 2, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, PIPE, DTO_SRC_SEL, 3, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 0, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 1, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 2, mask_sh),\
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 3, mask_sh),\
|
||||
DCCG_SF(OTG_PIXEL_RATE_DIV, OTG0_PIXEL_RATE_DIVK1, mask_sh),\
|
||||
DCCG_SF(OTG_PIXEL_RATE_DIV, OTG0_PIXEL_RATE_DIVK2, mask_sh),\
|
||||
DCCG_SF(OTG_PIXEL_RATE_DIV, OTG1_PIXEL_RATE_DIVK1, mask_sh),\
|
||||
DCCG_SF(OTG_PIXEL_RATE_DIV, OTG1_PIXEL_RATE_DIVK2, mask_sh),\
|
||||
DCCG_SF(OTG_PIXEL_RATE_DIV, OTG2_PIXEL_RATE_DIVK1, mask_sh),\
|
||||
DCCG_SF(OTG_PIXEL_RATE_DIV, OTG2_PIXEL_RATE_DIVK2, mask_sh),\
|
||||
DCCG_SF(OTG_PIXEL_RATE_DIV, OTG3_PIXEL_RATE_DIVK1, mask_sh),\
|
||||
DCCG_SF(OTG_PIXEL_RATE_DIV, OTG3_PIXEL_RATE_DIVK2, mask_sh),\
|
||||
DCCG_SF(OTG_PIXEL_RATE_DIV, OTG3_PIXEL_RATE_DIVK2, mask_sh),\
|
||||
DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P0_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P0_EN, mask_sh),\
|
||||
DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P1_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P1_EN, mask_sh),\
|
||||
DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P2_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P2_EN, mask_sh),\
|
||||
DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_SRC_SEL, mask_sh),\
|
||||
DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_EN, mask_sh),\
|
||||
DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh)
|
||||
|
||||
|
||||
struct dccg *dccg32_create(
|
||||
struct dc_context *ctx,
|
||||
const struct dccg_registers *regs,
|
||||
const struct dccg_shift *dccg_shift,
|
||||
const struct dccg_mask *dccg_mask);
|
||||
|
||||
#endif //__DCN32_DCCG_H__
|
283
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
Normal file
283
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "reg_helper.h"
|
||||
|
||||
#include "core_types.h"
|
||||
#include "link_encoder.h"
|
||||
#include "dcn31/dcn31_dio_link_encoder.h"
|
||||
#include "dcn32_dio_link_encoder.h"
|
||||
#include "stream_encoder.h"
|
||||
#include "i2caux_interface.h"
|
||||
#include "dc_bios_types.h"
|
||||
|
||||
#include "gpio_service_interface.h"
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
|
||||
#endif
|
||||
|
||||
#define CTX \
|
||||
enc10->base.ctx
|
||||
#define DC_LOGGER \
|
||||
enc10->base.ctx->logger
|
||||
|
||||
#define REG(reg)\
|
||||
(enc10->link_regs->reg)
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
enc10->link_shift->field_name, enc10->link_mask->field_name
|
||||
|
||||
#define AUX_REG(reg)\
|
||||
(enc10->aux_regs->reg)
|
||||
|
||||
#define AUX_REG_READ(reg_name) \
|
||||
dm_read_reg(CTX, AUX_REG(reg_name))
|
||||
|
||||
#define AUX_REG_WRITE(reg_name, val) \
|
||||
dm_write_reg(CTX, AUX_REG(reg_name), val)
|
||||
|
||||
|
||||
void enc32_hw_init(struct link_encoder *enc)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
|
||||
/*
|
||||
00 - DP_AUX_DPHY_RX_DETECTION_THRESHOLD__1to2 : 1/2
|
||||
01 - DP_AUX_DPHY_RX_DETECTION_THRESHOLD__3to4 : 3/4
|
||||
02 - DP_AUX_DPHY_RX_DETECTION_THRESHOLD__7to8 : 7/8
|
||||
03 - DP_AUX_DPHY_RX_DETECTION_THRESHOLD__15to16 : 15/16
|
||||
04 - DP_AUX_DPHY_RX_DETECTION_THRESHOLD__31to32 : 31/32
|
||||
05 - DP_AUX_DPHY_RX_DETECTION_THRESHOLD__63to64 : 63/64
|
||||
06 - DP_AUX_DPHY_RX_DETECTION_THRESHOLD__127to128 : 127/128
|
||||
07 - DP_AUX_DPHY_RX_DETECTION_THRESHOLD__255to256 : 255/256
|
||||
*/
|
||||
|
||||
/*
|
||||
AUX_REG_UPDATE_5(AUX_DPHY_RX_CONTROL0,
|
||||
AUX_RX_START_WINDOW = 1 [6:4]
|
||||
AUX_RX_RECEIVE_WINDOW = 1 default is 2 [10:8]
|
||||
AUX_RX_HALF_SYM_DETECT_LEN = 1 [13:12] default is 1
|
||||
AUX_RX_TRANSITION_FILTER_EN = 1 [16] default is 1
|
||||
AUX_RX_ALLOW_BELOW_THRESHOLD_PHASE_DETECT [17] is 0 default is 0
|
||||
AUX_RX_ALLOW_BELOW_THRESHOLD_START [18] is 1 default is 1
|
||||
AUX_RX_ALLOW_BELOW_THRESHOLD_STOP [19] is 1 default is 1
|
||||
AUX_RX_PHASE_DETECT_LEN, [21,20] = 0x3 default is 3
|
||||
AUX_RX_DETECTION_THRESHOLD [30:28] = 1
|
||||
*/
|
||||
AUX_REG_WRITE(AUX_DPHY_RX_CONTROL0, 0x103d1110);
|
||||
|
||||
AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c7a);
|
||||
|
||||
//AUX_DPHY_TX_REF_CONTROL'AUX_TX_REF_DIV HW default is 0x32;
|
||||
// Set AUX_TX_REF_DIV Divider to generate 2 MHz reference from refclk
|
||||
// 27MHz -> 0xd
|
||||
// 100MHz -> 0x32
|
||||
// 48MHz -> 0x18
|
||||
|
||||
// Set TMDS_CTL0 to 1. This is a legacy setting.
|
||||
REG_UPDATE(TMDS_CTL_BITS, TMDS_CTL0, 1);
|
||||
|
||||
dcn10_aux_initialize(enc10);
|
||||
}
|
||||
|
||||
|
||||
void dcn32_link_encoder_enable_dp_output(
|
||||
struct link_encoder *enc,
|
||||
const struct dc_link_settings *link_settings,
|
||||
enum clock_source_id clock_source)
|
||||
{
|
||||
if (!enc->ctx->dc->debug.avoid_vbios_exec_table) {
|
||||
dcn10_link_encoder_enable_dp_output(enc, link_settings, clock_source);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
uint32_t dp_alt_mode_disable = 0;
|
||||
bool is_usb_c_alt_mode = false;
|
||||
|
||||
if (enc->features.flags.bits.DP_IS_USB_C) {
|
||||
/* if value == 1 alt mode is disabled, otherwise it is enabled */
|
||||
//REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
|
||||
is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
|
||||
}
|
||||
|
||||
return is_usb_c_alt_mode;
|
||||
}
|
||||
|
||||
void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
uint32_t is_in_usb_c_dp4_mode = 0;
|
||||
|
||||
dcn10_link_encoder_get_max_link_cap(enc, link_settings);
|
||||
|
||||
/* in usb c dp2 mode, max lane count is 2 */
|
||||
if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) {
|
||||
// REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
|
||||
if (!is_in_usb_c_dp4_mode)
|
||||
link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static const struct link_encoder_funcs dcn32_link_enc_funcs = {
|
||||
.read_state = link_enc2_read_state,
|
||||
.validate_output_with_stream =
|
||||
dcn30_link_encoder_validate_output_with_stream,
|
||||
.hw_init = enc32_hw_init,
|
||||
.setup = dcn10_link_encoder_setup,
|
||||
.enable_tmds_output = dcn10_link_encoder_enable_tmds_output,
|
||||
.enable_dp_output = dcn32_link_encoder_enable_dp_output,
|
||||
.enable_dp_mst_output = dcn10_link_encoder_enable_dp_mst_output,
|
||||
.disable_output = dcn10_link_encoder_disable_output,
|
||||
.dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings,
|
||||
.dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern,
|
||||
.update_mst_stream_allocation_table =
|
||||
dcn10_link_encoder_update_mst_stream_allocation_table,
|
||||
.psr_program_dp_dphy_fast_training =
|
||||
dcn10_psr_program_dp_dphy_fast_training,
|
||||
.psr_program_secondary_packet = dcn10_psr_program_secondary_packet,
|
||||
.connect_dig_be_to_fe = dcn10_link_encoder_connect_dig_be_to_fe,
|
||||
.enable_hpd = dcn10_link_encoder_enable_hpd,
|
||||
.disable_hpd = dcn10_link_encoder_disable_hpd,
|
||||
.is_dig_enabled = dcn10_is_dig_enabled,
|
||||
.destroy = dcn10_link_encoder_destroy,
|
||||
.fec_set_enable = enc2_fec_set_enable,
|
||||
.fec_set_ready = enc2_fec_set_ready,
|
||||
.fec_is_active = enc2_fec_is_active,
|
||||
.get_dig_frontend = dcn10_get_dig_frontend,
|
||||
.get_dig_mode = dcn10_get_dig_mode,
|
||||
.is_in_alt_mode = dcn32_link_encoder_is_in_alt_mode,
|
||||
.get_max_link_cap = dcn32_link_encoder_get_max_link_cap,
|
||||
.set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
|
||||
};
|
||||
|
||||
void dcn32_link_encoder_construct(
|
||||
struct dcn20_link_encoder *enc20,
|
||||
const struct encoder_init_data *init_data,
|
||||
const struct encoder_feature_support *enc_features,
|
||||
const struct dcn10_link_enc_registers *link_regs,
|
||||
const struct dcn10_link_enc_aux_registers *aux_regs,
|
||||
const struct dcn10_link_enc_hpd_registers *hpd_regs,
|
||||
const struct dcn10_link_enc_shift *link_shift,
|
||||
const struct dcn10_link_enc_mask *link_mask)
|
||||
{
|
||||
struct bp_connector_speed_cap_info bp_cap_info = {0};
|
||||
const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
|
||||
enum bp_result result = BP_RESULT_OK;
|
||||
struct dcn10_link_encoder *enc10 = &enc20->enc10;
|
||||
|
||||
enc10->base.funcs = &dcn32_link_enc_funcs;
|
||||
enc10->base.ctx = init_data->ctx;
|
||||
enc10->base.id = init_data->encoder;
|
||||
|
||||
enc10->base.hpd_source = init_data->hpd_source;
|
||||
enc10->base.connector = init_data->connector;
|
||||
|
||||
enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
|
||||
|
||||
enc10->base.features = *enc_features;
|
||||
|
||||
enc10->base.transmitter = init_data->transmitter;
|
||||
|
||||
/* set the flag to indicate whether driver poll the I2C data pin
|
||||
* while doing the DP sink detect
|
||||
*/
|
||||
|
||||
/* if (dal_adapter_service_is_feature_supported(as,
|
||||
FEATURE_DP_SINK_DETECT_POLL_DATA_PIN))
|
||||
enc10->base.features.flags.bits.
|
||||
DP_SINK_DETECT_POLL_DATA_PIN = true;*/
|
||||
|
||||
enc10->base.output_signals =
|
||||
SIGNAL_TYPE_DVI_SINGLE_LINK |
|
||||
SIGNAL_TYPE_DVI_DUAL_LINK |
|
||||
SIGNAL_TYPE_LVDS |
|
||||
SIGNAL_TYPE_DISPLAY_PORT |
|
||||
SIGNAL_TYPE_DISPLAY_PORT_MST |
|
||||
SIGNAL_TYPE_EDP |
|
||||
SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
|
||||
enc10->link_regs = link_regs;
|
||||
enc10->aux_regs = aux_regs;
|
||||
enc10->hpd_regs = hpd_regs;
|
||||
enc10->link_shift = link_shift;
|
||||
enc10->link_mask = link_mask;
|
||||
|
||||
switch (enc10->base.transmitter) {
|
||||
case TRANSMITTER_UNIPHY_A:
|
||||
enc10->base.preferred_engine = ENGINE_ID_DIGA;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_B:
|
||||
enc10->base.preferred_engine = ENGINE_ID_DIGB;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_C:
|
||||
enc10->base.preferred_engine = ENGINE_ID_DIGC;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_D:
|
||||
enc10->base.preferred_engine = ENGINE_ID_DIGD;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_E:
|
||||
enc10->base.preferred_engine = ENGINE_ID_DIGE;
|
||||
break;
|
||||
default:
|
||||
ASSERT_CRITICAL(false);
|
||||
enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
|
||||
}
|
||||
|
||||
/* default to one to mirror Windows behavior */
|
||||
enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
|
||||
|
||||
if (bp_funcs->get_connector_speed_cap_info)
|
||||
result = bp_funcs->get_connector_speed_cap_info(enc10->base.ctx->dc_bios,
|
||||
enc10->base.connector, &bp_cap_info);
|
||||
|
||||
/* Override features with DCE-specific values */
|
||||
if (result == BP_RESULT_OK) {
|
||||
enc10->base.features.flags.bits.IS_HBR2_CAPABLE =
|
||||
bp_cap_info.DP_HBR2_EN;
|
||||
enc10->base.features.flags.bits.IS_HBR3_CAPABLE =
|
||||
bp_cap_info.DP_HBR3_EN;
|
||||
enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
|
||||
enc10->base.features.flags.bits.IS_DP2_CAPABLE = 1;
|
||||
enc10->base.features.flags.bits.IS_UHBR10_CAPABLE = bp_cap_info.DP_UHBR10_EN;
|
||||
enc10->base.features.flags.bits.IS_UHBR13_5_CAPABLE = bp_cap_info.DP_UHBR13_5_EN;
|
||||
enc10->base.features.flags.bits.IS_UHBR20_CAPABLE = bp_cap_info.DP_UHBR20_EN;
|
||||
} else {
|
||||
DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
|
||||
__func__,
|
||||
result);
|
||||
}
|
||||
if (enc10->base.ctx->dc->debug.hdmi20_disable) {
|
||||
enc10->base.features.flags.bits.HDMI_6GB_EN = 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_LINK_ENCODER__DCN32_H__
|
||||
#define __DC_LINK_ENCODER__DCN32_H__
|
||||
|
||||
#include "dcn30/dcn30_dio_link_encoder.h"
|
||||
|
||||
void dcn32_link_encoder_construct(
|
||||
struct dcn20_link_encoder *enc20,
|
||||
const struct encoder_init_data *init_data,
|
||||
const struct encoder_feature_support *enc_features,
|
||||
const struct dcn10_link_enc_registers *link_regs,
|
||||
const struct dcn10_link_enc_aux_registers *aux_regs,
|
||||
const struct dcn10_link_enc_hpd_registers *hpd_regs,
|
||||
const struct dcn10_link_enc_shift *link_shift,
|
||||
const struct dcn10_link_enc_mask *link_mask);
|
||||
|
||||
|
||||
#endif /* __DC_LINK_ENCODER__DCN32_H__ */
|
427
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c
Normal file
427
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c
Normal file
@ -0,0 +1,427 @@
|
||||
/*
|
||||
* Copyright 2021 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 "dc_bios_types.h"
|
||||
#include "dcn30/dcn30_dio_stream_encoder.h"
|
||||
#include "dcn32_dio_stream_encoder.h"
|
||||
#include "reg_helper.h"
|
||||
#include "hw_shared.h"
|
||||
#include "inc/link_dpcd.h"
|
||||
#include "dpcd_defs.h"
|
||||
|
||||
#define DC_LOGGER \
|
||||
enc1->base.ctx->logger
|
||||
|
||||
#define REG(reg)\
|
||||
(enc1->regs->reg)
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
enc1->se_shift->field_name, enc1->se_mask->field_name
|
||||
|
||||
#define VBI_LINE_0 0
|
||||
#define HDMI_CLOCK_CHANNEL_RATE_MORE_340M 340000
|
||||
|
||||
#define CTX \
|
||||
enc1->base.ctx
|
||||
|
||||
|
||||
|
||||
static void enc32_dp_set_odm_combine(
|
||||
struct stream_encoder *enc,
|
||||
bool odm_combine)
|
||||
{
|
||||
//struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
|
||||
|
||||
//TODO: REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_COMBINE, odm_combine);
|
||||
}
|
||||
|
||||
/* setup stream encoder in dvi mode */
|
||||
void enc32_stream_encoder_dvi_set_stream_attribute(
|
||||
struct stream_encoder *enc,
|
||||
struct dc_crtc_timing *crtc_timing,
|
||||
bool is_dual_link)
|
||||
{
|
||||
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
|
||||
|
||||
if (!enc->ctx->dc->debug.avoid_vbios_exec_table) {
|
||||
struct bp_encoder_control cntl = {0};
|
||||
|
||||
cntl.action = ENCODER_CONTROL_SETUP;
|
||||
cntl.engine_id = enc1->base.id;
|
||||
cntl.signal = is_dual_link ?
|
||||
SIGNAL_TYPE_DVI_DUAL_LINK : SIGNAL_TYPE_DVI_SINGLE_LINK;
|
||||
cntl.enable_dp_audio = false;
|
||||
cntl.pixel_clock = crtc_timing->pix_clk_100hz / 10;
|
||||
cntl.lanes_number = (is_dual_link) ? LANE_COUNT_EIGHT : LANE_COUNT_FOUR;
|
||||
|
||||
if (enc1->base.bp->funcs->encoder_control(
|
||||
enc1->base.bp, &cntl) != BP_RESULT_OK)
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
//Set pattern for clock channel, default vlue 0x63 does not work
|
||||
REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F);
|
||||
|
||||
//DIG_BE_TMDS_DVI_MODE : TMDS-DVI mode is already set in link_encoder_setup
|
||||
|
||||
//DIG_SOURCE_SELECT is already set in dig_connect_to_otg
|
||||
|
||||
/* DIG_START is removed from the register spec */
|
||||
}
|
||||
|
||||
ASSERT(crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB);
|
||||
ASSERT(crtc_timing->display_color_depth == COLOR_DEPTH_888);
|
||||
enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing);
|
||||
}
|
||||
|
||||
/* setup stream encoder in hdmi mode */
|
||||
static void enc32_stream_encoder_hdmi_set_stream_attribute(
|
||||
struct stream_encoder *enc,
|
||||
struct dc_crtc_timing *crtc_timing,
|
||||
int actual_pix_clk_khz,
|
||||
bool enable_audio)
|
||||
{
|
||||
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
|
||||
|
||||
if (!enc->ctx->dc->debug.avoid_vbios_exec_table) {
|
||||
struct bp_encoder_control cntl = {0};
|
||||
|
||||
cntl.action = ENCODER_CONTROL_SETUP;
|
||||
cntl.engine_id = enc1->base.id;
|
||||
cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
cntl.enable_dp_audio = enable_audio;
|
||||
cntl.pixel_clock = actual_pix_clk_khz;
|
||||
cntl.lanes_number = LANE_COUNT_FOUR;
|
||||
|
||||
if (enc1->base.bp->funcs->encoder_control(
|
||||
enc1->base.bp, &cntl) != BP_RESULT_OK)
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
//Set pattern for clock channel, default vlue 0x63 does not work
|
||||
REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F);
|
||||
|
||||
//DIG_BE_TMDS_HDMI_MODE : TMDS-HDMI mode is already set in link_encoder_setup
|
||||
|
||||
//DIG_SOURCE_SELECT is already set in dig_connect_to_otg
|
||||
|
||||
/* DIG_START is removed from the register spec */
|
||||
}
|
||||
|
||||
/* Configure pixel encoding */
|
||||
enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing);
|
||||
|
||||
/* setup HDMI engine */
|
||||
REG_UPDATE_6(HDMI_CONTROL,
|
||||
HDMI_PACKET_GEN_VERSION, 1,
|
||||
HDMI_KEEPOUT_MODE, 1,
|
||||
HDMI_DEEP_COLOR_ENABLE, 0,
|
||||
HDMI_DATA_SCRAMBLE_EN, 0,
|
||||
HDMI_NO_EXTRA_NULL_PACKET_FILLED, 1,
|
||||
HDMI_CLOCK_CHANNEL_RATE, 0);
|
||||
|
||||
/* Configure color depth */
|
||||
switch (crtc_timing->display_color_depth) {
|
||||
case COLOR_DEPTH_888:
|
||||
REG_UPDATE(HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, 0);
|
||||
break;
|
||||
case COLOR_DEPTH_101010:
|
||||
if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
|
||||
REG_UPDATE_2(HDMI_CONTROL,
|
||||
HDMI_DEEP_COLOR_DEPTH, 1,
|
||||
HDMI_DEEP_COLOR_ENABLE, 0);
|
||||
} else {
|
||||
REG_UPDATE_2(HDMI_CONTROL,
|
||||
HDMI_DEEP_COLOR_DEPTH, 1,
|
||||
HDMI_DEEP_COLOR_ENABLE, 1);
|
||||
}
|
||||
break;
|
||||
case COLOR_DEPTH_121212:
|
||||
if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
|
||||
REG_UPDATE_2(HDMI_CONTROL,
|
||||
HDMI_DEEP_COLOR_DEPTH, 2,
|
||||
HDMI_DEEP_COLOR_ENABLE, 0);
|
||||
} else {
|
||||
REG_UPDATE_2(HDMI_CONTROL,
|
||||
HDMI_DEEP_COLOR_DEPTH, 2,
|
||||
HDMI_DEEP_COLOR_ENABLE, 1);
|
||||
}
|
||||
break;
|
||||
case COLOR_DEPTH_161616:
|
||||
REG_UPDATE_2(HDMI_CONTROL,
|
||||
HDMI_DEEP_COLOR_DEPTH, 3,
|
||||
HDMI_DEEP_COLOR_ENABLE, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (actual_pix_clk_khz >= HDMI_CLOCK_CHANNEL_RATE_MORE_340M) {
|
||||
/* enable HDMI data scrambler
|
||||
* HDMI_CLOCK_CHANNEL_RATE_MORE_340M
|
||||
* Clock channel frequency is 1/4 of character rate.
|
||||
*/
|
||||
REG_UPDATE_2(HDMI_CONTROL,
|
||||
HDMI_DATA_SCRAMBLE_EN, 1,
|
||||
HDMI_CLOCK_CHANNEL_RATE, 1);
|
||||
} else if (crtc_timing->flags.LTE_340MCSC_SCRAMBLE) {
|
||||
|
||||
/* TODO: New feature for DCE11, still need to implement */
|
||||
|
||||
/* enable HDMI data scrambler
|
||||
* HDMI_CLOCK_CHANNEL_FREQ_EQUAL_TO_CHAR_RATE
|
||||
* Clock channel frequency is the same
|
||||
* as character rate
|
||||
*/
|
||||
REG_UPDATE_2(HDMI_CONTROL,
|
||||
HDMI_DATA_SCRAMBLE_EN, 1,
|
||||
HDMI_CLOCK_CHANNEL_RATE, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Enable transmission of General Control packet on every frame */
|
||||
REG_UPDATE_3(HDMI_VBI_PACKET_CONTROL,
|
||||
HDMI_GC_CONT, 1,
|
||||
HDMI_GC_SEND, 1,
|
||||
HDMI_NULL_SEND, 1);
|
||||
|
||||
/* Disable Audio Content Protection packet transmission */
|
||||
REG_UPDATE(HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, 0);
|
||||
|
||||
/* following belongs to audio */
|
||||
/* Enable Audio InfoFrame packet transmission. */
|
||||
REG_UPDATE(HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, 1);
|
||||
|
||||
/* update double-buffered AUDIO_INFO registers immediately */
|
||||
ASSERT(enc->afmt);
|
||||
enc->afmt->funcs->audio_info_immediate_update(enc->afmt);
|
||||
|
||||
/* Select line number on which to send Audio InfoFrame packets */
|
||||
REG_UPDATE(HDMI_INFOFRAME_CONTROL1, HDMI_AUDIO_INFO_LINE,
|
||||
VBI_LINE_0 + 2);
|
||||
|
||||
/* set HDMI GC AVMUTE */
|
||||
REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool is_two_pixels_per_containter(const struct dc_crtc_timing *timing)
|
||||
{
|
||||
bool two_pix = timing->pixel_encoding == PIXEL_ENCODING_YCBCR420;
|
||||
|
||||
two_pix = two_pix || (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
|
||||
&& !timing->dsc_cfg.ycbcr422_simple);
|
||||
return two_pix;
|
||||
}
|
||||
|
||||
static void enc32_stream_encoder_dp_unblank(
|
||||
struct dc_link *link,
|
||||
struct stream_encoder *enc,
|
||||
const struct encoder_unblank_param *param)
|
||||
{
|
||||
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
|
||||
|
||||
if (param->link_settings.link_rate != LINK_RATE_UNKNOWN) {
|
||||
uint32_t n_vid = 0x8000;
|
||||
uint32_t m_vid;
|
||||
uint32_t n_multiply = 0;
|
||||
uint64_t m_vid_l = n_vid;
|
||||
|
||||
/* YCbCr 4:2:0 : Computed VID_M will be 2X the input rate */
|
||||
if (is_two_pixels_per_containter(¶m->timing) || param->opp_cnt > 1) {
|
||||
/*this logic should be the same in get_pixel_clock_parameters() */
|
||||
n_multiply = 1;
|
||||
}
|
||||
/* M / N = Fstream / Flink
|
||||
* m_vid / n_vid = pixel rate / link rate
|
||||
*/
|
||||
|
||||
m_vid_l *= param->timing.pix_clk_100hz / 10;
|
||||
m_vid_l = div_u64(m_vid_l,
|
||||
param->link_settings.link_rate
|
||||
* LINK_RATE_REF_FREQ_IN_KHZ);
|
||||
|
||||
m_vid = (uint32_t) m_vid_l;
|
||||
|
||||
/* enable auto measurement */
|
||||
|
||||
REG_UPDATE(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 0);
|
||||
|
||||
/* auto measurement need 1 full 0x8000 symbol cycle to kick in,
|
||||
* therefore program initial value for Mvid and Nvid
|
||||
*/
|
||||
|
||||
REG_UPDATE(DP_VID_N, DP_VID_N, n_vid);
|
||||
|
||||
REG_UPDATE(DP_VID_M, DP_VID_M, m_vid);
|
||||
|
||||
REG_UPDATE_2(DP_VID_TIMING,
|
||||
DP_VID_M_N_GEN_EN, 1,
|
||||
DP_VID_N_MUL, n_multiply);
|
||||
}
|
||||
|
||||
/* make sure stream is disabled before resetting steer fifo */
|
||||
REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, false);
|
||||
REG_WAIT(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, 0, 10, 5000);
|
||||
|
||||
/* DIG_START is removed from the register spec */
|
||||
|
||||
/* switch DP encoder to CRTC data, but reset it the fifo first. It may happen
|
||||
* that it overflows during mode transition, and sometimes doesn't recover.
|
||||
*/
|
||||
REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 1);
|
||||
udelay(10);
|
||||
|
||||
REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0);
|
||||
|
||||
/* wait 100us for DIG/DP logic to prime
|
||||
* (i.e. a few video lines)
|
||||
*/
|
||||
udelay(100);
|
||||
|
||||
/* the hardware would start sending video at the start of the next DP
|
||||
* frame (i.e. rising edge of the vblank).
|
||||
* NOTE: We used to program DP_VID_STREAM_DIS_DEFER = 2 here, but this
|
||||
* register has no effect on enable transition! HW always guarantees
|
||||
* VID_STREAM enable at start of next frame, and this is not
|
||||
* programmable
|
||||
*/
|
||||
|
||||
REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);
|
||||
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
|
||||
}
|
||||
|
||||
/* Set DSC-related configuration.
|
||||
* dsc_mode: 0 disables DSC, other values enable DSC in specified format
|
||||
* sc_bytes_per_pixel: DP_DSC_BYTES_PER_PIXEL removed in DCN32
|
||||
* dsc_slice_width: DP_DSC_SLICE_WIDTH removed in DCN32
|
||||
*/
|
||||
static void enc32_dp_set_dsc_config(struct stream_encoder *enc,
|
||||
enum optc_dsc_mode dsc_mode,
|
||||
uint32_t dsc_bytes_per_pixel,
|
||||
uint32_t dsc_slice_width)
|
||||
{
|
||||
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
|
||||
|
||||
REG_UPDATE(DP_DSC_CNTL, DP_DSC_MODE, dsc_mode);
|
||||
}
|
||||
|
||||
/* this function read dsc related register fields to be logged later in dcn10_log_hw_state
|
||||
* into a dcn_dsc_state struct.
|
||||
*/
|
||||
static void enc32_read_state(struct stream_encoder *enc, struct enc_state *s)
|
||||
{
|
||||
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
|
||||
|
||||
//if dsc is enabled, continue to read
|
||||
REG_GET(DP_DSC_CNTL, DP_DSC_MODE, &s->dsc_mode);
|
||||
if (s->dsc_mode) {
|
||||
REG_GET(DP_GSP11_CNTL, DP_SEC_GSP11_LINE_NUM, &s->sec_gsp_pps_line_num);
|
||||
|
||||
REG_GET(DP_MSA_VBID_MISC, DP_VBID6_LINE_REFERENCE, &s->vbid6_line_reference);
|
||||
REG_GET(DP_MSA_VBID_MISC, DP_VBID6_LINE_NUM, &s->vbid6_line_num);
|
||||
|
||||
REG_GET(DP_GSP11_CNTL, DP_SEC_GSP11_ENABLE, &s->sec_gsp_pps_enable);
|
||||
REG_GET(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, &s->sec_stream_enable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const struct stream_encoder_funcs dcn32_str_enc_funcs = {
|
||||
.dp_set_odm_combine =
|
||||
enc32_dp_set_odm_combine,
|
||||
.dp_set_stream_attribute =
|
||||
enc2_stream_encoder_dp_set_stream_attribute,
|
||||
.hdmi_set_stream_attribute =
|
||||
enc32_stream_encoder_hdmi_set_stream_attribute,
|
||||
.dvi_set_stream_attribute =
|
||||
enc32_stream_encoder_dvi_set_stream_attribute,
|
||||
.set_throttled_vcp_size =
|
||||
enc1_stream_encoder_set_throttled_vcp_size,
|
||||
.update_hdmi_info_packets =
|
||||
enc3_stream_encoder_update_hdmi_info_packets,
|
||||
.stop_hdmi_info_packets =
|
||||
enc3_stream_encoder_stop_hdmi_info_packets,
|
||||
.update_dp_info_packets =
|
||||
enc3_stream_encoder_update_dp_info_packets,
|
||||
.stop_dp_info_packets =
|
||||
enc1_stream_encoder_stop_dp_info_packets,
|
||||
.reset_fifo =
|
||||
enc1_stream_encoder_reset_fifo,
|
||||
.dp_blank =
|
||||
enc1_stream_encoder_dp_blank,
|
||||
.dp_unblank =
|
||||
enc32_stream_encoder_dp_unblank,
|
||||
.audio_mute_control = enc3_audio_mute_control,
|
||||
|
||||
.dp_audio_setup = enc3_se_dp_audio_setup,
|
||||
.dp_audio_enable = enc3_se_dp_audio_enable,
|
||||
.dp_audio_disable = enc1_se_dp_audio_disable,
|
||||
|
||||
.hdmi_audio_setup = enc3_se_hdmi_audio_setup,
|
||||
.hdmi_audio_disable = enc1_se_hdmi_audio_disable,
|
||||
.setup_stereo_sync = enc1_setup_stereo_sync,
|
||||
.set_avmute = enc1_stream_encoder_set_avmute,
|
||||
.dig_connect_to_otg = enc1_dig_connect_to_otg,
|
||||
.dig_source_otg = enc1_dig_source_otg,
|
||||
|
||||
.dp_get_pixel_format = enc1_stream_encoder_dp_get_pixel_format,
|
||||
|
||||
.enc_read_state = enc32_read_state,
|
||||
.dp_set_dsc_config = enc32_dp_set_dsc_config,
|
||||
.dp_set_dsc_pps_info_packet = enc3_dp_set_dsc_pps_info_packet,
|
||||
.set_dynamic_metadata = enc2_set_dynamic_metadata,
|
||||
.hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
|
||||
};
|
||||
|
||||
void dcn32_dio_stream_encoder_construct(
|
||||
struct dcn10_stream_encoder *enc1,
|
||||
struct dc_context *ctx,
|
||||
struct dc_bios *bp,
|
||||
enum engine_id eng_id,
|
||||
struct vpg *vpg,
|
||||
struct afmt *afmt,
|
||||
const struct dcn10_stream_enc_registers *regs,
|
||||
const struct dcn10_stream_encoder_shift *se_shift,
|
||||
const struct dcn10_stream_encoder_mask *se_mask)
|
||||
{
|
||||
enc1->base.funcs = &dcn32_str_enc_funcs;
|
||||
enc1->base.ctx = ctx;
|
||||
enc1->base.id = eng_id;
|
||||
enc1->base.bp = bp;
|
||||
enc1->base.vpg = vpg;
|
||||
enc1->base.afmt = afmt;
|
||||
enc1->regs = regs;
|
||||
enc1->se_shift = se_shift;
|
||||
enc1->se_mask = se_mask;
|
||||
enc1->base.stream_enc_inst = vpg->inst;
|
||||
}
|
||||
|
254
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h
Normal file
254
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h
Normal file
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright 2021 - Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_DIO_STREAM_ENCODER_DCN32_H__
|
||||
#define __DC_DIO_STREAM_ENCODER_DCN32_H__
|
||||
|
||||
#include "dcn30/dcn30_vpg.h"
|
||||
#include "dcn30/dcn30_afmt.h"
|
||||
#include "stream_encoder.h"
|
||||
#include "dcn20/dcn20_stream_encoder.h"
|
||||
|
||||
#define SE_DCN32_REG_LIST(id)\
|
||||
SRI(AFMT_CNTL, DIG, id), \
|
||||
SRI(DIG_FE_CNTL, DIG, id), \
|
||||
SRI(HDMI_CONTROL, DIG, id), \
|
||||
SRI(HDMI_DB_CONTROL, DIG, id), \
|
||||
SRI(HDMI_GC, DIG, id), \
|
||||
SRI(HDMI_GENERIC_PACKET_CONTROL0, DIG, id), \
|
||||
SRI(HDMI_GENERIC_PACKET_CONTROL1, DIG, id), \
|
||||
SRI(HDMI_GENERIC_PACKET_CONTROL2, DIG, id), \
|
||||
SRI(HDMI_GENERIC_PACKET_CONTROL3, DIG, id), \
|
||||
SRI(HDMI_GENERIC_PACKET_CONTROL4, DIG, id), \
|
||||
SRI(HDMI_GENERIC_PACKET_CONTROL5, DIG, id), \
|
||||
SRI(HDMI_GENERIC_PACKET_CONTROL6, DIG, id), \
|
||||
SRI(HDMI_GENERIC_PACKET_CONTROL7, DIG, id), \
|
||||
SRI(HDMI_GENERIC_PACKET_CONTROL8, DIG, id), \
|
||||
SRI(HDMI_GENERIC_PACKET_CONTROL9, DIG, id), \
|
||||
SRI(HDMI_GENERIC_PACKET_CONTROL10, DIG, id), \
|
||||
SRI(HDMI_INFOFRAME_CONTROL0, DIG, id), \
|
||||
SRI(HDMI_INFOFRAME_CONTROL1, DIG, id), \
|
||||
SRI(HDMI_VBI_PACKET_CONTROL, DIG, id), \
|
||||
SRI(HDMI_AUDIO_PACKET_CONTROL, DIG, id),\
|
||||
SRI(HDMI_ACR_PACKET_CONTROL, DIG, id),\
|
||||
SRI(HDMI_ACR_32_0, DIG, id),\
|
||||
SRI(HDMI_ACR_32_1, DIG, id),\
|
||||
SRI(HDMI_ACR_44_0, DIG, id),\
|
||||
SRI(HDMI_ACR_44_1, DIG, id),\
|
||||
SRI(HDMI_ACR_48_0, DIG, id),\
|
||||
SRI(HDMI_ACR_48_1, DIG, id),\
|
||||
SRI(DP_DB_CNTL, DP, id), \
|
||||
SRI(DP_MSA_MISC, DP, id), \
|
||||
SRI(DP_MSA_VBID_MISC, DP, id), \
|
||||
SRI(DP_MSA_COLORIMETRY, DP, id), \
|
||||
SRI(DP_MSA_TIMING_PARAM1, DP, id), \
|
||||
SRI(DP_MSA_TIMING_PARAM2, DP, id), \
|
||||
SRI(DP_MSA_TIMING_PARAM3, DP, id), \
|
||||
SRI(DP_MSA_TIMING_PARAM4, DP, id), \
|
||||
SRI(DP_MSE_RATE_CNTL, DP, id), \
|
||||
SRI(DP_MSE_RATE_UPDATE, DP, id), \
|
||||
SRI(DP_PIXEL_FORMAT, DP, id), \
|
||||
SRI(DP_SEC_CNTL, DP, id), \
|
||||
SRI(DP_SEC_CNTL2, DP, id), \
|
||||
SRI(DP_SEC_CNTL6, DP, id), \
|
||||
SRI(DP_STEER_FIFO, DP, id), \
|
||||
SRI(DP_VID_M, DP, id), \
|
||||
SRI(DP_VID_N, DP, id), \
|
||||
SRI(DP_VID_STREAM_CNTL, DP, id), \
|
||||
SRI(DP_VID_TIMING, DP, id), \
|
||||
SRI(DP_SEC_AUD_N, DP, id), \
|
||||
SRI(DP_SEC_TIMESTAMP, DP, id), \
|
||||
SRI(DP_DSC_CNTL, DP, id), \
|
||||
SRI(DP_SEC_METADATA_TRANSMISSION, DP, id), \
|
||||
SRI(HDMI_METADATA_PACKET_CONTROL, DIG, id), \
|
||||
SRI(DP_SEC_FRAMING4, DP, id), \
|
||||
SRI(DP_GSP11_CNTL, DP, id), \
|
||||
SRI(DME_CONTROL, DME, id),\
|
||||
SRI(DP_SEC_METADATA_TRANSMISSION, DP, id), \
|
||||
SRI(HDMI_METADATA_PACKET_CONTROL, DIG, id), \
|
||||
SRI(DIG_FE_CNTL, DIG, id), \
|
||||
SRI(DIG_CLOCK_PATTERN, DIG, id)
|
||||
|
||||
|
||||
#define SE_COMMON_MASK_SH_LIST_DCN32_BASE(mask_sh)\
|
||||
SE_SF(DP0_DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, mask_sh),\
|
||||
SE_SF(DP0_DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_CONTROL, HDMI_PACKET_GEN_VERSION, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_CONTROL, HDMI_KEEPOUT_MODE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_CONTROL, HDMI_DEEP_COLOR_ENABLE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_CONTROL, HDMI_DATA_SCRAMBLE_EN, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_CONTROL, HDMI_NO_EXTRA_NULL_PACKET_FILLED, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_GC_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_GC_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_NULL_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_INFOFRAME_CONTROL1, HDMI_AUDIO_INFO_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GC, HDMI_GC_AVMUTE, mask_sh),\
|
||||
SE_SF(DP0_DP_MSE_RATE_CNTL, DP_MSE_RATE_X, mask_sh),\
|
||||
SE_SF(DP0_DP_MSE_RATE_CNTL, DP_MSE_RATE_Y, mask_sh),\
|
||||
SE_SF(DP0_DP_MSE_RATE_UPDATE, DP_MSE_RATE_UPDATE_PENDING, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP0_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP1_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP2_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP3_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_MPG_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL1, DP_SEC_GSP5_LINE_REFERENCE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP4_SEND, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP4_SEND_PENDING, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL4, DP_SEC_GSP4_LINE_NUM, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL5, DP_SEC_GSP5_LINE_NUM, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP4_SEND_ANY_LINE, mask_sh),\
|
||||
SE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_DIS_DEFER, mask_sh),\
|
||||
SE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, mask_sh),\
|
||||
SE_SF(DP0_DP_STEER_FIFO, DP_STEER_FIFO_RESET, mask_sh),\
|
||||
SE_SF(DP0_DP_VID_TIMING, DP_VID_M_N_GEN_EN, mask_sh),\
|
||||
SE_SF(DP0_DP_VID_N, DP_VID_N, mask_sh),\
|
||||
SE_SF(DP0_DP_VID_M, DP_VID_M, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_AUDIO_PACKET_CONTROL, HDMI_AUDIO_DELAY_EN, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_ACR_PACKET_CONTROL, HDMI_ACR_AUTO_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_ACR_PACKET_CONTROL, HDMI_ACR_SOURCE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_ACR_PACKET_CONTROL, HDMI_ACR_AUDIO_PRIORITY, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_ACR_32_0, HDMI_ACR_CTS_32, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_ACR_32_1, HDMI_ACR_N_32, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_ACR_44_0, HDMI_ACR_CTS_44, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_ACR_44_1, HDMI_ACR_N_44, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_ACR_48_0, HDMI_ACR_CTS_48, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_ACR_48_1, HDMI_ACR_N_48, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_AUD_N, DP_SEC_AUD_N, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_TIMESTAMP, DP_SEC_TIMESTAMP_MODE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ASP_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ATP_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_AIP_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ACM_ENABLE, mask_sh),\
|
||||
SE_SF(DIG0_AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_CONTROL, HDMI_CLOCK_CHANNEL_RATE, mask_sh),\
|
||||
SE_SF(DIG0_DIG_FE_CNTL, TMDS_PIXEL_ENCODING, mask_sh),\
|
||||
SE_SF(DIG0_DIG_FE_CNTL, TMDS_COLOR_FORMAT, mask_sh),\
|
||||
SE_SF(DIG0_DIG_FE_CNTL, DIG_STEREOSYNC_SELECT, mask_sh),\
|
||||
SE_SF(DIG0_DIG_FE_CNTL, DIG_STEREOSYNC_GATE_EN, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP4_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP5_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP6_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP7_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP7_SEND, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL6, DP_SEC_GSP7_LINE_NUM, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP11_PPS, mask_sh),\
|
||||
SE_SF(DP0_DP_GSP11_CNTL, DP_SEC_GSP11_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_GSP11_CNTL, DP_SEC_GSP11_LINE_NUM, mask_sh),\
|
||||
SE_SF(DP0_DP_DB_CNTL, DP_DB_DISABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_COLORIMETRY, DP_MSA_MISC0, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_TIMING_PARAM1, DP_MSA_HTOTAL, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_TIMING_PARAM1, DP_MSA_VTOTAL, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_TIMING_PARAM2, DP_MSA_HSTART, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_TIMING_PARAM2, DP_MSA_VSTART, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_HSYNCWIDTH, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_HSYNCPOLARITY, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_VSYNCWIDTH, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_VSYNCPOLARITY, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_TIMING_PARAM4, DP_MSA_HWIDTH, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_TIMING_PARAM4, DP_MSA_VHEIGHT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_DB_CONTROL, HDMI_DB_DISABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_VID_TIMING, DP_VID_N_MUL, mask_sh),\
|
||||
SE_SF(DIG0_DIG_FE_CNTL, DIG_SOURCE_SELECT, mask_sh), \
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC0_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC0_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC1_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC1_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC2_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC2_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC3_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC3_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC4_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC4_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC5_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC5_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC6_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC6_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC7_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC7_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC8_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC8_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC9_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC9_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC10_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC10_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC11_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC11_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC12_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC12_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC13_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC13_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC14_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC14_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL1, HDMI_GENERIC0_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL1, HDMI_GENERIC1_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL2, HDMI_GENERIC2_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL2, HDMI_GENERIC3_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL3, HDMI_GENERIC4_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL3, HDMI_GENERIC5_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL4, HDMI_GENERIC6_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL4, HDMI_GENERIC7_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL7, HDMI_GENERIC8_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL7, HDMI_GENERIC9_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL8, HDMI_GENERIC10_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL8, HDMI_GENERIC11_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL9, HDMI_GENERIC12_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL9, HDMI_GENERIC13_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL10, HDMI_GENERIC14_LINE, mask_sh),\
|
||||
SE_SF(DP0_DP_DSC_CNTL, DP_DSC_MODE, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_VBID_MISC, DP_VBID6_LINE_REFERENCE, mask_sh),\
|
||||
SE_SF(DP0_DP_MSA_VBID_MISC, DP_VBID6_LINE_NUM, mask_sh),\
|
||||
SE_SF(DME0_DME_CONTROL, METADATA_ENGINE_EN, mask_sh),\
|
||||
SE_SF(DME0_DME_CONTROL, METADATA_HUBP_REQUESTOR_ID, mask_sh),\
|
||||
SE_SF(DME0_DME_CONTROL, METADATA_STREAM_TYPE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_METADATA_TRANSMISSION, DP_SEC_METADATA_PACKET_ENABLE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_METADATA_TRANSMISSION, DP_SEC_METADATA_PACKET_LINE_REFERENCE, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_METADATA_TRANSMISSION, DP_SEC_METADATA_PACKET_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_METADATA_PACKET_CONTROL, HDMI_METADATA_PACKET_ENABLE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_METADATA_PACKET_CONTROL, HDMI_METADATA_PACKET_LINE_REFERENCE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_METADATA_PACKET_CONTROL, HDMI_METADATA_PACKET_LINE, mask_sh),\
|
||||
SE_SF(DIG0_DIG_FE_CNTL, DOLBY_VISION_EN, mask_sh),\
|
||||
SE_SF(DP0_DP_SEC_FRAMING4, DP_SST_SDP_SPLITTING, mask_sh),\
|
||||
SE_SF(DIG0_DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, mask_sh)
|
||||
|
||||
#define SE_COMMON_MASK_SH_LIST_DCN32(mask_sh)\
|
||||
SE_COMMON_MASK_SH_LIST_DCN32_BASE(mask_sh),\
|
||||
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, mask_sh)
|
||||
|
||||
void dcn32_dio_stream_encoder_construct(
|
||||
struct dcn10_stream_encoder *enc1,
|
||||
struct dc_context *ctx,
|
||||
struct dc_bios *bp,
|
||||
enum engine_id eng_id,
|
||||
struct vpg *vpg,
|
||||
struct afmt *afmt,
|
||||
const struct dcn10_stream_enc_registers *regs,
|
||||
const struct dcn10_stream_encoder_shift *se_shift,
|
||||
const struct dcn10_stream_encoder_mask *se_mask);
|
||||
|
||||
#endif /* __DC_DIO_STREAM_ENCODER_DCN32_H__ */
|
164
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dpp.c
Normal file
164
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dpp.c
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "core_types.h"
|
||||
#include "reg_helper.h"
|
||||
#include "dcn32_dpp.h"
|
||||
#include "basics/conversion.h"
|
||||
#include "dcn30/dcn30_cm_common.h"
|
||||
|
||||
/* Compute the maximum number of lines that we can fit in the line buffer */
|
||||
void dscl32_calc_lb_num_partitions(
|
||||
const struct scaler_data *scl_data,
|
||||
enum lb_memory_config lb_config,
|
||||
int *num_part_y,
|
||||
int *num_part_c)
|
||||
{
|
||||
int memory_line_size_y, memory_line_size_c, memory_line_size_a,
|
||||
lb_memory_size, lb_memory_size_c, lb_memory_size_a, num_partitions_a;
|
||||
|
||||
int line_size = scl_data->viewport.width < scl_data->recout.width ?
|
||||
scl_data->viewport.width : scl_data->recout.width;
|
||||
int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ?
|
||||
scl_data->viewport_c.width : scl_data->recout.width;
|
||||
|
||||
if (line_size == 0)
|
||||
line_size = 1;
|
||||
|
||||
if (line_size_c == 0)
|
||||
line_size_c = 1;
|
||||
|
||||
memory_line_size_y = (line_size + 5) / 6; /* +5 to ceil */
|
||||
memory_line_size_c = (line_size_c + 5) / 6; /* +5 to ceil */
|
||||
memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */
|
||||
|
||||
if (lb_config == LB_MEMORY_CONFIG_1) {
|
||||
lb_memory_size = 970;
|
||||
lb_memory_size_c = 970;
|
||||
lb_memory_size_a = 970;
|
||||
} else if (lb_config == LB_MEMORY_CONFIG_2) {
|
||||
lb_memory_size = 1290;
|
||||
lb_memory_size_c = 1290;
|
||||
lb_memory_size_a = 1290;
|
||||
} else if (lb_config == LB_MEMORY_CONFIG_3) {
|
||||
if (scl_data->viewport.width == scl_data->h_active &&
|
||||
scl_data->viewport.height == scl_data->v_active) {
|
||||
/* 420 mode: luma using all 3 mem from Y, plus 3rd mem from Cr and Cb */
|
||||
/* use increased LB size for calculation only if Scaler not enabled */
|
||||
lb_memory_size = 970 + 1290 + 1170 + 1170 + 1170;
|
||||
lb_memory_size_c = 970 + 1290;
|
||||
lb_memory_size_a = 970 + 1290 + 1170;
|
||||
} else {
|
||||
/* 420 mode: luma using all 3 mem from Y, plus 3rd mem from Cr and Cb */
|
||||
lb_memory_size = 970 + 1290 + 484 + 484 + 484;
|
||||
lb_memory_size_c = 970 + 1290;
|
||||
lb_memory_size_a = 970 + 1290 + 484;
|
||||
}
|
||||
} else {
|
||||
if (scl_data->viewport.width == scl_data->h_active &&
|
||||
scl_data->viewport.height == scl_data->v_active) {
|
||||
/* use increased LB size for calculation only if Scaler not enabled */
|
||||
lb_memory_size = 970 + 1290 + 1170;
|
||||
lb_memory_size_c = 970 + 1290 + 1170;
|
||||
lb_memory_size_a = 970 + 1290 + 1170;
|
||||
} else {
|
||||
lb_memory_size = 970 + 1290 + 484;
|
||||
lb_memory_size_c = 970 + 1290 + 484;
|
||||
lb_memory_size_a = 970 + 1290 + 484;
|
||||
}
|
||||
}
|
||||
*num_part_y = lb_memory_size / memory_line_size_y;
|
||||
*num_part_c = lb_memory_size_c / memory_line_size_c;
|
||||
num_partitions_a = lb_memory_size_a / memory_line_size_a;
|
||||
|
||||
if (scl_data->lb_params.alpha_en
|
||||
&& (num_partitions_a < *num_part_y))
|
||||
*num_part_y = num_partitions_a;
|
||||
|
||||
if (*num_part_y > 32)
|
||||
*num_part_y = 32;
|
||||
if (*num_part_c > 32)
|
||||
*num_part_c = 32;
|
||||
}
|
||||
|
||||
static struct dpp_funcs dcn32_dpp_funcs = {
|
||||
.dpp_program_gamcor_lut = dpp3_program_gamcor_lut,
|
||||
.dpp_read_state = dpp30_read_state,
|
||||
.dpp_reset = dpp_reset,
|
||||
.dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
|
||||
.dpp_get_optimal_number_of_taps = dpp3_get_optimal_number_of_taps,
|
||||
.dpp_set_gamut_remap = dpp3_cm_set_gamut_remap,
|
||||
.dpp_set_csc_adjustment = NULL,
|
||||
.dpp_set_csc_default = NULL,
|
||||
.dpp_program_regamma_pwl = NULL,
|
||||
.dpp_set_pre_degam = dpp3_set_pre_degam,
|
||||
.dpp_program_input_lut = NULL,
|
||||
.dpp_full_bypass = dpp1_full_bypass,
|
||||
.dpp_setup = dpp3_cnv_setup,
|
||||
.dpp_program_degamma_pwl = NULL,
|
||||
.dpp_program_cm_dealpha = dpp3_program_cm_dealpha,
|
||||
.dpp_program_cm_bias = dpp3_program_cm_bias,
|
||||
|
||||
.dpp_program_blnd_lut = NULL, // BLNDGAM is removed completely in DCN3.2 DPP
|
||||
.dpp_program_shaper_lut = NULL, // CM SHAPER block is removed in DCN3.2 DPP, (it is in MPCC, programmable before or after BLND)
|
||||
.dpp_program_3dlut = NULL, // CM 3DLUT block is removed in DCN3.2 DPP, (it is in MPCC, programmable before or after BLND)
|
||||
|
||||
.dpp_program_bias_and_scale = NULL,
|
||||
.dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer,
|
||||
.set_cursor_attributes = dpp3_set_cursor_attributes,
|
||||
.set_cursor_position = dpp1_set_cursor_position,
|
||||
.set_optional_cursor_attributes = dpp1_cnv_set_optional_cursor_attributes,
|
||||
.dpp_dppclk_control = dpp1_dppclk_control,
|
||||
.dpp_set_hdr_multiplier = dpp3_set_hdr_multiplier,
|
||||
};
|
||||
|
||||
|
||||
static struct dpp_caps dcn32_dpp_cap = {
|
||||
.dscl_data_proc_format = DSCL_DATA_PRCESSING_FLOAT_FORMAT,
|
||||
.max_lb_partitions = 31,
|
||||
.dscl_calc_lb_num_partitions = dscl32_calc_lb_num_partitions,
|
||||
};
|
||||
|
||||
bool dpp32_construct(
|
||||
struct dcn3_dpp *dpp,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dcn3_dpp_registers *tf_regs,
|
||||
const struct dcn3_dpp_shift *tf_shift,
|
||||
const struct dcn3_dpp_mask *tf_mask)
|
||||
{
|
||||
dpp->base.ctx = ctx;
|
||||
|
||||
dpp->base.inst = inst;
|
||||
dpp->base.funcs = &dcn32_dpp_funcs;
|
||||
dpp->base.caps = &dcn32_dpp_cap;
|
||||
|
||||
dpp->tf_regs = tf_regs;
|
||||
dpp->tf_shift = tf_shift;
|
||||
dpp->tf_mask = tf_mask;
|
||||
|
||||
return true;
|
||||
}
|
38
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dpp.h
Normal file
38
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dpp.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DCN32_DPP_H__
|
||||
#define __DCN32_DPP_H__
|
||||
|
||||
#include "dcn20/dcn20_dpp.h"
|
||||
#include "dcn30/dcn30_dpp.h"
|
||||
|
||||
bool dpp32_construct(struct dcn3_dpp *dpp3,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dcn3_dpp_registers *tf_regs,
|
||||
const struct dcn3_dpp_shift *tf_shift,
|
||||
const struct dcn3_dpp_mask *tf_mask);
|
||||
|
||||
#endif /* __DCN32_DPP_H__ */
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2019 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 "dc_bios_types.h"
|
||||
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
|
||||
#include "dcn32_hpo_dp_link_encoder.h"
|
||||
#include "reg_helper.h"
|
||||
#include "dc_link.h"
|
||||
#include "stream_encoder.h"
|
||||
|
||||
#define DC_LOGGER \
|
||||
enc3->base.ctx->logger
|
||||
|
||||
#define REG(reg)\
|
||||
(enc3->regs->reg)
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
enc3->hpo_le_shift->field_name, enc3->hpo_le_mask->field_name
|
||||
|
||||
#define CTX \
|
||||
enc3->base.ctx
|
||||
|
||||
static bool dcn32_hpo_dp_link_enc_is_in_alt_mode(
|
||||
struct hpo_dp_link_encoder *enc)
|
||||
{
|
||||
struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
|
||||
uint32_t dp_alt_mode_disable = 0;
|
||||
|
||||
ASSERT((enc->transmitter >= TRANSMITTER_UNIPHY_A) && (enc->transmitter <= TRANSMITTER_UNIPHY_E));
|
||||
|
||||
/* if value == 1 alt mode is disabled, otherwise it is enabled */
|
||||
REG_GET(RDPCSTX_PHY_CNTL6[enc->transmitter], RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
|
||||
return (dp_alt_mode_disable == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct hpo_dp_link_encoder_funcs dcn32_hpo_dp_link_encoder_funcs = {
|
||||
.enable_link_phy = dcn31_hpo_dp_link_enc_enable_dp_output,
|
||||
.disable_link_phy = dcn31_hpo_dp_link_enc_disable_output,
|
||||
.link_enable = dcn31_hpo_dp_link_enc_enable,
|
||||
.link_disable = dcn31_hpo_dp_link_enc_disable,
|
||||
.set_link_test_pattern = dcn31_hpo_dp_link_enc_set_link_test_pattern,
|
||||
.update_stream_allocation_table = dcn31_hpo_dp_link_enc_update_stream_allocation_table,
|
||||
.set_throttled_vcp_size = dcn31_hpo_dp_link_enc_set_throttled_vcp_size,
|
||||
.is_in_alt_mode = dcn32_hpo_dp_link_enc_is_in_alt_mode,
|
||||
.read_state = dcn31_hpo_dp_link_enc_read_state,
|
||||
.set_ffe = dcn31_hpo_dp_link_enc_set_ffe,
|
||||
};
|
||||
|
||||
void hpo_dp_link_encoder32_construct(struct dcn31_hpo_dp_link_encoder *enc31,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dcn31_hpo_dp_link_encoder_registers *hpo_le_regs,
|
||||
const struct dcn31_hpo_dp_link_encoder_shift *hpo_le_shift,
|
||||
const struct dcn31_hpo_dp_link_encoder_mask *hpo_le_mask)
|
||||
{
|
||||
enc31->base.ctx = ctx;
|
||||
|
||||
enc31->base.inst = inst;
|
||||
enc31->base.funcs = &dcn32_hpo_dp_link_encoder_funcs;
|
||||
enc31->base.hpd_source = HPD_SOURCEID_UNKNOWN;
|
||||
enc31->base.transmitter = TRANSMITTER_UNKNOWN;
|
||||
|
||||
enc31->regs = hpo_le_regs;
|
||||
enc31->hpo_le_shift = hpo_le_shift;
|
||||
enc31->hpo_le_mask = hpo_le_mask;
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DAL_DCN32_HPO_DP_LINK_ENCODER_H__
|
||||
#define __DAL_DCN32_HPO_DP_LINK_ENCODER_H__
|
||||
|
||||
#include "link_encoder.h"
|
||||
|
||||
#define DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(mask_sh)\
|
||||
SE_SF(DP_LINK_ENC0_DP_LINK_ENC_CLOCK_CONTROL, DP_LINK_ENC_CLOCK_EN, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_CONTROL, DPHY_RESET, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_CONTROL, DPHY_ENABLE, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_CONTROL, PRECODER_ENABLE, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_CONTROL, MODE, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_CONTROL, NUM_LANES, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_STATUS, STATUS, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_STATUS, SAT_UPDATE_PENDING, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_STATUS, RATE_UPDATE_PENDING, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM0, TP_CUSTOM, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG, TP_SELECT0, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG, TP_SELECT1, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG, TP_SELECT2, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG, TP_SELECT3, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG, TP_PRBS_SEL0, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG, TP_PRBS_SEL1, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG, TP_PRBS_SEL2, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG, TP_PRBS_SEL3, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC0, SAT_STREAM_SOURCE, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC0, SAT_SLOT_COUNT, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_VC_RATE_CNTL0, STREAM_VC_RATE_X, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_VC_RATE_CNTL0, STREAM_VC_RATE_Y, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_SAT_UPDATE, SAT_UPDATE, mask_sh)
|
||||
|
||||
void hpo_dp_link_encoder32_construct(struct dcn31_hpo_dp_link_encoder *enc31,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dcn31_hpo_dp_link_encoder_registers *hpo_le_regs,
|
||||
const struct dcn31_hpo_dp_link_encoder_shift *hpo_le_shift,
|
||||
const struct dcn31_hpo_dp_link_encoder_mask *hpo_le_mask);
|
||||
|
||||
#endif // __DAL_DCN32_HPO_DP_LINK_ENCODER_H__
|
964
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c
Normal file
964
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c
Normal file
@ -0,0 +1,964 @@
|
||||
/*
|
||||
* Copyright 2021 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 "dcn30/dcn30_hubbub.h"
|
||||
#include "dcn32_hubbub.h"
|
||||
#include "dm_services.h"
|
||||
#include "reg_helper.h"
|
||||
|
||||
|
||||
#define CTX \
|
||||
hubbub2->base.ctx
|
||||
#define DC_LOGGER \
|
||||
hubbub2->base.ctx->logger
|
||||
#define REG(reg)\
|
||||
hubbub2->regs->reg
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
hubbub2->shifts->field_name, hubbub2->masks->field_name
|
||||
|
||||
#define DCN32_CRB_SEGMENT_SIZE_KB 64
|
||||
|
||||
static void dcn32_init_crb(struct hubbub *hubbub)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
|
||||
|
||||
REG_GET(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT,
|
||||
&hubbub2->det0_size);
|
||||
|
||||
REG_GET(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT,
|
||||
&hubbub2->det1_size);
|
||||
|
||||
REG_GET(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT,
|
||||
&hubbub2->det2_size);
|
||||
|
||||
REG_GET(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT,
|
||||
&hubbub2->det3_size);
|
||||
|
||||
REG_GET(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE_CURRENT,
|
||||
&hubbub2->compbuf_size_segments);
|
||||
|
||||
REG_SET_2(COMPBUF_RESERVED_SPACE, 0,
|
||||
COMPBUF_RESERVED_SPACE_64B, hubbub2->pixel_chunk_size / 32,
|
||||
COMPBUF_RESERVED_SPACE_ZS, hubbub2->pixel_chunk_size / 128);
|
||||
REG_UPDATE(DCHUBBUB_DEBUG_CTRL_0, DET_DEPTH, 0x17F);
|
||||
}
|
||||
|
||||
static void dcn32_program_det_size(struct hubbub *hubbub, int hubp_inst, unsigned int det_buffer_size_in_kbyte)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
|
||||
|
||||
unsigned int det_size_segments = (det_buffer_size_in_kbyte + DCN32_CRB_SEGMENT_SIZE_KB - 1) / DCN32_CRB_SEGMENT_SIZE_KB;
|
||||
|
||||
switch (hubp_inst) {
|
||||
case 0:
|
||||
REG_UPDATE(DCHUBBUB_DET0_CTRL,
|
||||
DET0_SIZE, det_size_segments);
|
||||
hubbub2->det0_size = det_size_segments;
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE(DCHUBBUB_DET1_CTRL,
|
||||
DET1_SIZE, det_size_segments);
|
||||
hubbub2->det1_size = det_size_segments;
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE(DCHUBBUB_DET2_CTRL,
|
||||
DET2_SIZE, det_size_segments);
|
||||
hubbub2->det2_size = det_size_segments;
|
||||
break;
|
||||
case 3:
|
||||
REG_UPDATE(DCHUBBUB_DET3_CTRL,
|
||||
DET3_SIZE, det_size_segments);
|
||||
hubbub2->det3_size = det_size_segments;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* Should never be hit, if it is we have an erroneous hw config*/
|
||||
ASSERT(hubbub2->det0_size + hubbub2->det1_size + hubbub2->det2_size
|
||||
+ hubbub2->det3_size + hubbub2->compbuf_size_segments <= hubbub2->crb_size_segs);
|
||||
}
|
||||
|
||||
static void dcn32_program_compbuf_size(struct hubbub *hubbub, unsigned int compbuf_size_kb, bool safe_to_increase)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
|
||||
unsigned int compbuf_size_segments = (compbuf_size_kb + DCN32_CRB_SEGMENT_SIZE_KB - 1) / DCN32_CRB_SEGMENT_SIZE_KB;
|
||||
|
||||
if (safe_to_increase || compbuf_size_segments <= hubbub2->compbuf_size_segments) {
|
||||
if (compbuf_size_segments > hubbub2->compbuf_size_segments) {
|
||||
REG_WAIT(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT, hubbub2->det0_size, 1, 100);
|
||||
REG_WAIT(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT, hubbub2->det1_size, 1, 100);
|
||||
REG_WAIT(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT, hubbub2->det2_size, 1, 100);
|
||||
REG_WAIT(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT, hubbub2->det3_size, 1, 100);
|
||||
}
|
||||
/* Should never be hit, if it is we have an erroneous hw config*/
|
||||
ASSERT(hubbub2->det0_size + hubbub2->det1_size + hubbub2->det2_size
|
||||
+ hubbub2->det3_size + compbuf_size_segments <= hubbub2->crb_size_segs);
|
||||
REG_UPDATE(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE, compbuf_size_segments);
|
||||
REG_WAIT(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE_CURRENT, compbuf_size_segments, 1, 100);
|
||||
hubbub2->compbuf_size_segments = compbuf_size_segments;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t convert_and_clamp(
|
||||
uint32_t wm_ns,
|
||||
uint32_t refclk_mhz,
|
||||
uint32_t clamp_value)
|
||||
{
|
||||
uint32_t ret_val = 0;
|
||||
ret_val = wm_ns * refclk_mhz;
|
||||
|
||||
ret_val /= 1000;
|
||||
|
||||
if (ret_val > clamp_value)
|
||||
ret_val = clamp_value;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static bool hubbub32_program_urgent_watermarks(
|
||||
struct hubbub *hubbub,
|
||||
struct dcn_watermark_set *watermarks,
|
||||
unsigned int refclk_mhz,
|
||||
bool safe_to_lower)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
|
||||
uint32_t prog_wm_value;
|
||||
bool wm_pending = false;
|
||||
|
||||
/* Repeat for water mark set A, B, C and D. */
|
||||
/* clock state A */
|
||||
if (safe_to_lower || watermarks->a.urgent_ns > hubbub2->watermarks.a.urgent_ns) {
|
||||
hubbub2->watermarks.a.urgent_ns = watermarks->a.urgent_ns;
|
||||
prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
|
||||
|
||||
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->a.urgent_ns, prog_wm_value);
|
||||
} else if (watermarks->a.urgent_ns < hubbub2->watermarks.a.urgent_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* determine the transfer time for a quantity of data for a particular requestor.*/
|
||||
if (safe_to_lower || watermarks->a.frac_urg_bw_flip
|
||||
> hubbub2->watermarks.a.frac_urg_bw_flip) {
|
||||
hubbub2->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, watermarks->a.frac_urg_bw_flip);
|
||||
} else if (watermarks->a.frac_urg_bw_flip
|
||||
< hubbub2->watermarks.a.frac_urg_bw_flip)
|
||||
wm_pending = true;
|
||||
|
||||
if (safe_to_lower || watermarks->a.frac_urg_bw_nom
|
||||
> hubbub2->watermarks.a.frac_urg_bw_nom) {
|
||||
hubbub2->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom);
|
||||
} else if (watermarks->a.frac_urg_bw_nom
|
||||
< hubbub2->watermarks.a.frac_urg_bw_nom)
|
||||
wm_pending = true;
|
||||
|
||||
if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub2->watermarks.a.urgent_latency_ns) {
|
||||
hubbub2->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns;
|
||||
prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0,
|
||||
DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value);
|
||||
} else if (watermarks->a.urgent_latency_ns < hubbub2->watermarks.a.urgent_latency_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state B */
|
||||
if (safe_to_lower || watermarks->b.urgent_ns > hubbub2->watermarks.b.urgent_ns) {
|
||||
hubbub2->watermarks.b.urgent_ns = watermarks->b.urgent_ns;
|
||||
prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
|
||||
|
||||
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->b.urgent_ns, prog_wm_value);
|
||||
} else if (watermarks->b.urgent_ns < hubbub2->watermarks.b.urgent_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* determine the transfer time for a quantity of data for a particular requestor.*/
|
||||
if (safe_to_lower || watermarks->b.frac_urg_bw_flip
|
||||
> hubbub2->watermarks.b.frac_urg_bw_flip) {
|
||||
hubbub2->watermarks.b.frac_urg_bw_flip = watermarks->b.frac_urg_bw_flip;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, watermarks->b.frac_urg_bw_flip);
|
||||
} else if (watermarks->b.frac_urg_bw_flip
|
||||
< hubbub2->watermarks.b.frac_urg_bw_flip)
|
||||
wm_pending = true;
|
||||
|
||||
if (safe_to_lower || watermarks->b.frac_urg_bw_nom
|
||||
> hubbub2->watermarks.b.frac_urg_bw_nom) {
|
||||
hubbub2->watermarks.b.frac_urg_bw_nom = watermarks->b.frac_urg_bw_nom;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->b.frac_urg_bw_nom);
|
||||
} else if (watermarks->b.frac_urg_bw_nom
|
||||
< hubbub2->watermarks.b.frac_urg_bw_nom)
|
||||
wm_pending = true;
|
||||
|
||||
if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub2->watermarks.b.urgent_latency_ns) {
|
||||
hubbub2->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns;
|
||||
prog_wm_value = convert_and_clamp(watermarks->b.urgent_latency_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0,
|
||||
DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value);
|
||||
} else if (watermarks->b.urgent_latency_ns < hubbub2->watermarks.b.urgent_latency_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state C */
|
||||
if (safe_to_lower || watermarks->c.urgent_ns > hubbub2->watermarks.c.urgent_ns) {
|
||||
hubbub2->watermarks.c.urgent_ns = watermarks->c.urgent_ns;
|
||||
prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
|
||||
|
||||
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->c.urgent_ns, prog_wm_value);
|
||||
} else if (watermarks->c.urgent_ns < hubbub2->watermarks.c.urgent_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* determine the transfer time for a quantity of data for a particular requestor.*/
|
||||
if (safe_to_lower || watermarks->c.frac_urg_bw_flip
|
||||
> hubbub2->watermarks.c.frac_urg_bw_flip) {
|
||||
hubbub2->watermarks.c.frac_urg_bw_flip = watermarks->c.frac_urg_bw_flip;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, watermarks->c.frac_urg_bw_flip);
|
||||
} else if (watermarks->c.frac_urg_bw_flip
|
||||
< hubbub2->watermarks.c.frac_urg_bw_flip)
|
||||
wm_pending = true;
|
||||
|
||||
if (safe_to_lower || watermarks->c.frac_urg_bw_nom
|
||||
> hubbub2->watermarks.c.frac_urg_bw_nom) {
|
||||
hubbub2->watermarks.c.frac_urg_bw_nom = watermarks->c.frac_urg_bw_nom;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->c.frac_urg_bw_nom);
|
||||
} else if (watermarks->c.frac_urg_bw_nom
|
||||
< hubbub2->watermarks.c.frac_urg_bw_nom)
|
||||
wm_pending = true;
|
||||
|
||||
if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub2->watermarks.c.urgent_latency_ns) {
|
||||
hubbub2->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns;
|
||||
prog_wm_value = convert_and_clamp(watermarks->c.urgent_latency_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0,
|
||||
DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value);
|
||||
} else if (watermarks->c.urgent_latency_ns < hubbub2->watermarks.c.urgent_latency_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state D */
|
||||
if (safe_to_lower || watermarks->d.urgent_ns > hubbub2->watermarks.d.urgent_ns) {
|
||||
hubbub2->watermarks.d.urgent_ns = watermarks->d.urgent_ns;
|
||||
prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
|
||||
|
||||
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->d.urgent_ns, prog_wm_value);
|
||||
} else if (watermarks->d.urgent_ns < hubbub2->watermarks.d.urgent_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* determine the transfer time for a quantity of data for a particular requestor.*/
|
||||
if (safe_to_lower || watermarks->d.frac_urg_bw_flip
|
||||
> hubbub2->watermarks.d.frac_urg_bw_flip) {
|
||||
hubbub2->watermarks.d.frac_urg_bw_flip = watermarks->d.frac_urg_bw_flip;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, watermarks->d.frac_urg_bw_flip);
|
||||
} else if (watermarks->d.frac_urg_bw_flip
|
||||
< hubbub2->watermarks.d.frac_urg_bw_flip)
|
||||
wm_pending = true;
|
||||
|
||||
if (safe_to_lower || watermarks->d.frac_urg_bw_nom
|
||||
> hubbub2->watermarks.d.frac_urg_bw_nom) {
|
||||
hubbub2->watermarks.d.frac_urg_bw_nom = watermarks->d.frac_urg_bw_nom;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->d.frac_urg_bw_nom);
|
||||
} else if (watermarks->d.frac_urg_bw_nom
|
||||
< hubbub2->watermarks.d.frac_urg_bw_nom)
|
||||
wm_pending = true;
|
||||
|
||||
if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub2->watermarks.d.urgent_latency_ns) {
|
||||
hubbub2->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns;
|
||||
prog_wm_value = convert_and_clamp(watermarks->d.urgent_latency_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0,
|
||||
DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value);
|
||||
} else if (watermarks->d.urgent_latency_ns < hubbub2->watermarks.d.urgent_latency_ns)
|
||||
wm_pending = true;
|
||||
|
||||
return wm_pending;
|
||||
}
|
||||
|
||||
static bool hubbub32_program_stutter_watermarks(
|
||||
struct hubbub *hubbub,
|
||||
struct dcn_watermark_set *watermarks,
|
||||
unsigned int refclk_mhz,
|
||||
bool safe_to_lower)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
|
||||
uint32_t prog_wm_value;
|
||||
bool wm_pending = false;
|
||||
|
||||
/* clock state A */
|
||||
if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
|
||||
> hubbub2->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) {
|
||||
hubbub2->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
|
||||
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
|
||||
} else if (watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
|
||||
< hubbub2->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns)
|
||||
wm_pending = true;
|
||||
|
||||
if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns
|
||||
> hubbub2->watermarks.a.cstate_pstate.cstate_exit_ns) {
|
||||
hubbub2->watermarks.a.cstate_pstate.cstate_exit_ns =
|
||||
watermarks->a.cstate_pstate.cstate_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->a.cstate_pstate.cstate_exit_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
|
||||
} else if (watermarks->a.cstate_pstate.cstate_exit_ns
|
||||
< hubbub2->watermarks.a.cstate_pstate.cstate_exit_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state B */
|
||||
if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
|
||||
> hubbub2->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) {
|
||||
hubbub2->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns =
|
||||
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
|
||||
} else if (watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
|
||||
< hubbub2->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns)
|
||||
wm_pending = true;
|
||||
|
||||
if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns
|
||||
> hubbub2->watermarks.b.cstate_pstate.cstate_exit_ns) {
|
||||
hubbub2->watermarks.b.cstate_pstate.cstate_exit_ns =
|
||||
watermarks->b.cstate_pstate.cstate_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->b.cstate_pstate.cstate_exit_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
|
||||
} else if (watermarks->b.cstate_pstate.cstate_exit_ns
|
||||
< hubbub2->watermarks.b.cstate_pstate.cstate_exit_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state C */
|
||||
if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
|
||||
> hubbub2->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) {
|
||||
hubbub2->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns =
|
||||
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
|
||||
} else if (watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
|
||||
< hubbub2->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns)
|
||||
wm_pending = true;
|
||||
|
||||
if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns
|
||||
> hubbub2->watermarks.c.cstate_pstate.cstate_exit_ns) {
|
||||
hubbub2->watermarks.c.cstate_pstate.cstate_exit_ns =
|
||||
watermarks->c.cstate_pstate.cstate_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->c.cstate_pstate.cstate_exit_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
|
||||
} else if (watermarks->c.cstate_pstate.cstate_exit_ns
|
||||
< hubbub2->watermarks.c.cstate_pstate.cstate_exit_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state D */
|
||||
if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
|
||||
> hubbub2->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) {
|
||||
hubbub2->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns =
|
||||
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
|
||||
} else if (watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
|
||||
< hubbub2->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns)
|
||||
wm_pending = true;
|
||||
|
||||
if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns
|
||||
> hubbub2->watermarks.d.cstate_pstate.cstate_exit_ns) {
|
||||
hubbub2->watermarks.d.cstate_pstate.cstate_exit_ns =
|
||||
watermarks->d.cstate_pstate.cstate_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->d.cstate_pstate.cstate_exit_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
|
||||
} else if (watermarks->d.cstate_pstate.cstate_exit_ns
|
||||
< hubbub2->watermarks.d.cstate_pstate.cstate_exit_ns)
|
||||
wm_pending = true;
|
||||
|
||||
return wm_pending;
|
||||
}
|
||||
|
||||
|
||||
static bool hubbub32_program_pstate_watermarks(
|
||||
struct hubbub *hubbub,
|
||||
struct dcn_watermark_set *watermarks,
|
||||
unsigned int refclk_mhz,
|
||||
bool safe_to_lower)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
|
||||
uint32_t prog_wm_value;
|
||||
|
||||
bool wm_pending = false;
|
||||
|
||||
/* Section for UCLK_PSTATE_CHANGE_WATERMARKS */
|
||||
/* clock state A */
|
||||
if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns
|
||||
> hubbub2->watermarks.a.cstate_pstate.pstate_change_ns) {
|
||||
hubbub2->watermarks.a.cstate_pstate.pstate_change_ns =
|
||||
watermarks->a.cstate_pstate.pstate_change_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->a.cstate_pstate.pstate_change_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, 0,
|
||||
DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
|
||||
} else if (watermarks->a.cstate_pstate.pstate_change_ns
|
||||
< hubbub2->watermarks.a.cstate_pstate.pstate_change_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state B */
|
||||
if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns
|
||||
> hubbub2->watermarks.b.cstate_pstate.pstate_change_ns) {
|
||||
hubbub2->watermarks.b.cstate_pstate.pstate_change_ns =
|
||||
watermarks->b.cstate_pstate.pstate_change_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->b.cstate_pstate.pstate_change_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, 0,
|
||||
DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
|
||||
} else if (watermarks->b.cstate_pstate.pstate_change_ns
|
||||
< hubbub2->watermarks.b.cstate_pstate.pstate_change_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state C */
|
||||
if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns
|
||||
> hubbub2->watermarks.c.cstate_pstate.pstate_change_ns) {
|
||||
hubbub2->watermarks.c.cstate_pstate.pstate_change_ns =
|
||||
watermarks->c.cstate_pstate.pstate_change_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->c.cstate_pstate.pstate_change_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C, 0,
|
||||
DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
|
||||
} else if (watermarks->c.cstate_pstate.pstate_change_ns
|
||||
< hubbub2->watermarks.c.cstate_pstate.pstate_change_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state D */
|
||||
if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns
|
||||
> hubbub2->watermarks.d.cstate_pstate.pstate_change_ns) {
|
||||
hubbub2->watermarks.d.cstate_pstate.pstate_change_ns =
|
||||
watermarks->d.cstate_pstate.pstate_change_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->d.cstate_pstate.pstate_change_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D, 0,
|
||||
DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
|
||||
} else if (watermarks->d.cstate_pstate.pstate_change_ns
|
||||
< hubbub2->watermarks.d.cstate_pstate.pstate_change_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* Section for FCLK_PSTATE_CHANGE_WATERMARKS */
|
||||
/* clock state A */
|
||||
if (safe_to_lower || watermarks->a.cstate_pstate.fclk_pstate_change_ns
|
||||
> hubbub2->watermarks.a.cstate_pstate.fclk_pstate_change_ns) {
|
||||
hubbub2->watermarks.a.cstate_pstate.fclk_pstate_change_ns =
|
||||
watermarks->a.cstate_pstate.fclk_pstate_change_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->a.cstate_pstate.fclk_pstate_change_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, 0,
|
||||
DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("FCLK_CHANGE_WATERMARK_A calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->a.cstate_pstate.fclk_pstate_change_ns, prog_wm_value);
|
||||
} else if (watermarks->a.cstate_pstate.fclk_pstate_change_ns
|
||||
< hubbub2->watermarks.a.cstate_pstate.fclk_pstate_change_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state B */
|
||||
if (safe_to_lower || watermarks->b.cstate_pstate.fclk_pstate_change_ns
|
||||
> hubbub2->watermarks.b.cstate_pstate.fclk_pstate_change_ns) {
|
||||
hubbub2->watermarks.b.cstate_pstate.fclk_pstate_change_ns =
|
||||
watermarks->b.cstate_pstate.fclk_pstate_change_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->b.cstate_pstate.fclk_pstate_change_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, 0,
|
||||
DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("FCLK_CHANGE_WATERMARK_B calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->b.cstate_pstate.fclk_pstate_change_ns, prog_wm_value);
|
||||
} else if (watermarks->b.cstate_pstate.fclk_pstate_change_ns
|
||||
< hubbub2->watermarks.b.cstate_pstate.fclk_pstate_change_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state C */
|
||||
if (safe_to_lower || watermarks->c.cstate_pstate.fclk_pstate_change_ns
|
||||
> hubbub2->watermarks.c.cstate_pstate.fclk_pstate_change_ns) {
|
||||
hubbub2->watermarks.c.cstate_pstate.fclk_pstate_change_ns =
|
||||
watermarks->c.cstate_pstate.fclk_pstate_change_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->c.cstate_pstate.fclk_pstate_change_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C, 0,
|
||||
DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("FCLK_CHANGE_WATERMARK_C calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->c.cstate_pstate.fclk_pstate_change_ns, prog_wm_value);
|
||||
} else if (watermarks->c.cstate_pstate.fclk_pstate_change_ns
|
||||
< hubbub2->watermarks.c.cstate_pstate.fclk_pstate_change_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state D */
|
||||
if (safe_to_lower || watermarks->d.cstate_pstate.fclk_pstate_change_ns
|
||||
> hubbub2->watermarks.d.cstate_pstate.fclk_pstate_change_ns) {
|
||||
hubbub2->watermarks.d.cstate_pstate.fclk_pstate_change_ns =
|
||||
watermarks->d.cstate_pstate.fclk_pstate_change_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->d.cstate_pstate.fclk_pstate_change_ns,
|
||||
refclk_mhz, 0xffff);
|
||||
REG_SET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D, 0,
|
||||
DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("FCLK_CHANGE_WATERMARK_D calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->d.cstate_pstate.fclk_pstate_change_ns, prog_wm_value);
|
||||
} else if (watermarks->d.cstate_pstate.fclk_pstate_change_ns
|
||||
< hubbub2->watermarks.d.cstate_pstate.fclk_pstate_change_ns)
|
||||
wm_pending = true;
|
||||
|
||||
return wm_pending;
|
||||
}
|
||||
|
||||
|
||||
static bool hubbub32_program_usr_watermarks(
|
||||
struct hubbub *hubbub,
|
||||
struct dcn_watermark_set *watermarks,
|
||||
unsigned int refclk_mhz,
|
||||
bool safe_to_lower)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
|
||||
uint32_t prog_wm_value;
|
||||
|
||||
bool wm_pending = false;
|
||||
|
||||
/* clock state A */
|
||||
if (safe_to_lower || watermarks->a.usr_retraining_ns
|
||||
> hubbub2->watermarks.a.usr_retraining_ns) {
|
||||
hubbub2->watermarks.a.usr_retraining_ns = watermarks->a.usr_retraining_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->a.usr_retraining_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
REG_SET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, 0,
|
||||
DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("USR_RETRAINING_WATERMARK_A calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->a.usr_retraining_ns, prog_wm_value);
|
||||
} else if (watermarks->a.usr_retraining_ns
|
||||
< hubbub2->watermarks.a.usr_retraining_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state B */
|
||||
if (safe_to_lower || watermarks->b.usr_retraining_ns
|
||||
> hubbub2->watermarks.b.usr_retraining_ns) {
|
||||
hubbub2->watermarks.b.usr_retraining_ns = watermarks->b.usr_retraining_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->b.usr_retraining_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
REG_SET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, 0,
|
||||
DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("USR_RETRAINING_WATERMARK_B calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->b.usr_retraining_ns, prog_wm_value);
|
||||
} else if (watermarks->b.usr_retraining_ns
|
||||
< hubbub2->watermarks.b.usr_retraining_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state C */
|
||||
if (safe_to_lower || watermarks->c.usr_retraining_ns
|
||||
> hubbub2->watermarks.c.usr_retraining_ns) {
|
||||
hubbub2->watermarks.c.usr_retraining_ns =
|
||||
watermarks->c.usr_retraining_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->c.usr_retraining_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
REG_SET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C, 0,
|
||||
DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("USR_RETRAINING_WATERMARK_C calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->c.usr_retraining_ns, prog_wm_value);
|
||||
} else if (watermarks->c.usr_retraining_ns
|
||||
< hubbub2->watermarks.c.usr_retraining_ns)
|
||||
wm_pending = true;
|
||||
|
||||
/* clock state D */
|
||||
if (safe_to_lower || watermarks->d.usr_retraining_ns
|
||||
> hubbub2->watermarks.d.usr_retraining_ns) {
|
||||
hubbub2->watermarks.d.usr_retraining_ns =
|
||||
watermarks->d.usr_retraining_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->d.usr_retraining_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
REG_SET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D, 0,
|
||||
DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("USR_RETRAINING_WATERMARK_D calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->d.usr_retraining_ns, prog_wm_value);
|
||||
} else if (watermarks->d.usr_retraining_ns
|
||||
< hubbub2->watermarks.d.usr_retraining_ns)
|
||||
wm_pending = true;
|
||||
|
||||
return wm_pending;
|
||||
}
|
||||
|
||||
void hubbub32_force_usr_retraining_allow(struct hubbub *hubbub, bool allow)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
|
||||
|
||||
/*
|
||||
* DCHUBBUB_ARB_ALLOW_USR_RETRAINING_FORCE_ENABLE = 1 means enabling forcing value
|
||||
* DCHUBBUB_ARB_ALLOW_USR_RETRAINING_FORCE_VALUE = 1 or 0, means value to be forced when force enable
|
||||
*/
|
||||
|
||||
REG_UPDATE_2(DCHUBBUB_ARB_USR_RETRAINING_CNTL,
|
||||
DCHUBBUB_ARB_ALLOW_USR_RETRAINING_FORCE_VALUE, allow,
|
||||
DCHUBBUB_ARB_ALLOW_USR_RETRAINING_FORCE_ENABLE, allow);
|
||||
}
|
||||
|
||||
static bool hubbub32_program_watermarks(
|
||||
struct hubbub *hubbub,
|
||||
struct dcn_watermark_set *watermarks,
|
||||
unsigned int refclk_mhz,
|
||||
bool safe_to_lower)
|
||||
{
|
||||
bool wm_pending = false;
|
||||
|
||||
if (hubbub32_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
|
||||
wm_pending = true;
|
||||
|
||||
if (hubbub32_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
|
||||
wm_pending = true;
|
||||
|
||||
if (hubbub32_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
|
||||
wm_pending = true;
|
||||
|
||||
if (hubbub32_program_usr_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
|
||||
wm_pending = true;
|
||||
|
||||
/*
|
||||
* The DCHub arbiter has a mechanism to dynamically rate limit the DCHub request stream to the fabric.
|
||||
* If the memory controller is fully utilized and the DCHub requestors are
|
||||
* well ahead of their amortized schedule, then it is safe to prevent the next winner
|
||||
* from being committed and sent to the fabric.
|
||||
* The utilization of the memory controller is approximated by ensuring that
|
||||
* the number of outstanding requests is greater than a threshold specified
|
||||
* by the ARB_MIN_REQ_OUTSTANDING. To determine that the DCHub requestors are well ahead of the amortized schedule,
|
||||
* the slack of the next winner is compared with the ARB_SAT_LEVEL in DLG RefClk cycles.
|
||||
*
|
||||
* TODO: Revisit request limit after figure out right number. request limit for RM isn't decided yet, set maximum value (0x1FF)
|
||||
* to turn off it for now.
|
||||
*/
|
||||
/*REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0,
|
||||
DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
|
||||
REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
|
||||
DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0x1FF);*/
|
||||
|
||||
hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
|
||||
|
||||
hubbub32_force_usr_retraining_allow(hubbub, hubbub->ctx->dc->debug.force_usr_allow);
|
||||
|
||||
return wm_pending;
|
||||
}
|
||||
|
||||
/* Copy values from WM set A to all other sets */
|
||||
void hubbub32_init_watermarks(struct hubbub *hubbub)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
|
||||
uint32_t reg;
|
||||
|
||||
reg = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A);
|
||||
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, reg);
|
||||
|
||||
reg = REG_READ(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A);
|
||||
REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, reg);
|
||||
|
||||
reg = REG_READ(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A);
|
||||
REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, reg);
|
||||
|
||||
reg = REG_READ(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A);
|
||||
REG_WRITE(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, reg);
|
||||
|
||||
reg = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A);
|
||||
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, reg);
|
||||
|
||||
reg = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A);
|
||||
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, reg);
|
||||
|
||||
reg = REG_READ(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A);
|
||||
REG_WRITE(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D, reg);
|
||||
|
||||
reg = REG_READ(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A);
|
||||
REG_WRITE(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D, reg);
|
||||
|
||||
reg = REG_READ(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A);
|
||||
REG_WRITE(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C, reg);
|
||||
REG_WRITE(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D, reg);
|
||||
}
|
||||
|
||||
void hubbub32_wm_read_state(struct hubbub *hubbub,
|
||||
struct dcn_hubbub_wm *wm)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
|
||||
struct dcn_hubbub_wm_set *s;
|
||||
|
||||
memset(wm, 0, sizeof(struct dcn_hubbub_wm));
|
||||
|
||||
s = &wm->sets[0];
|
||||
s->wm_set = 0;
|
||||
REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, &s->data_urgent);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, &s->sr_enter);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, &s->sr_exit);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A,
|
||||
DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, &s->dram_clk_chanage);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A,
|
||||
DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, &s->usr_retrain);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A,
|
||||
DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, &s->fclk_pstate_change);
|
||||
|
||||
s = &wm->sets[1];
|
||||
s->wm_set = 1;
|
||||
REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, &s->data_urgent);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, &s->sr_enter);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, &s->sr_exit);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B,
|
||||
DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, &s->dram_clk_chanage);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B,
|
||||
DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, &s->usr_retrain);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B,
|
||||
DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, &s->fclk_pstate_change);
|
||||
|
||||
s = &wm->sets[2];
|
||||
s->wm_set = 2;
|
||||
REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, &s->data_urgent);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, &s->sr_enter);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, &s->sr_exit);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C,
|
||||
DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C, &s->dram_clk_chanage);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C,
|
||||
DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C, &s->usr_retrain);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C,
|
||||
DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C, &s->fclk_pstate_change);
|
||||
|
||||
s = &wm->sets[3];
|
||||
s->wm_set = 3;
|
||||
REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, &s->data_urgent);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, &s->sr_enter);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, &s->sr_exit);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D,
|
||||
DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D, &s->dram_clk_chanage);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D,
|
||||
DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D, &s->usr_retrain);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D,
|
||||
DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D, &s->fclk_pstate_change);
|
||||
}
|
||||
|
||||
void hubbub32_force_wm_propagate_to_pipes(struct hubbub *hubbub)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
|
||||
uint32_t refclk_mhz = hubbub->ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000;
|
||||
uint32_t prog_wm_value = convert_and_clamp(hubbub2->watermarks.a.urgent_ns,
|
||||
refclk_mhz, 0x3fff);
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
|
||||
}
|
||||
|
||||
static const struct hubbub_funcs hubbub32_funcs = {
|
||||
.update_dchub = hubbub2_update_dchub,
|
||||
.init_dchub_sys_ctx = hubbub3_init_dchub_sys_ctx,
|
||||
.init_vm_ctx = hubbub2_init_vm_ctx,
|
||||
.dcc_support_swizzle = hubbub3_dcc_support_swizzle,
|
||||
.dcc_support_pixel_format = hubbub2_dcc_support_pixel_format,
|
||||
.get_dcc_compression_cap = hubbub3_get_dcc_compression_cap,
|
||||
.wm_read_state = hubbub32_wm_read_state,
|
||||
.get_dchub_ref_freq = hubbub2_get_dchub_ref_freq,
|
||||
.program_watermarks = hubbub32_program_watermarks,
|
||||
.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
|
||||
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
|
||||
.force_wm_propagate_to_pipes = hubbub32_force_wm_propagate_to_pipes,
|
||||
.force_pstate_change_control = hubbub3_force_pstate_change_control,
|
||||
.init_watermarks = hubbub32_init_watermarks,
|
||||
.program_det_size = dcn32_program_det_size,
|
||||
.program_compbuf_size = dcn32_program_compbuf_size,
|
||||
.init_crb = dcn32_init_crb,
|
||||
.hubbub_read_state = hubbub2_read_state,
|
||||
.force_usr_retraining_allow = hubbub32_force_usr_retraining_allow,
|
||||
};
|
||||
|
||||
void hubbub32_construct(struct dcn20_hubbub *hubbub2,
|
||||
struct dc_context *ctx,
|
||||
const struct dcn_hubbub_registers *hubbub_regs,
|
||||
const struct dcn_hubbub_shift *hubbub_shift,
|
||||
const struct dcn_hubbub_mask *hubbub_mask,
|
||||
int det_size_kb,
|
||||
int pixel_chunk_size_kb,
|
||||
int config_return_buffer_size_kb)
|
||||
{
|
||||
hubbub2->base.ctx = ctx;
|
||||
hubbub2->base.funcs = &hubbub32_funcs;
|
||||
hubbub2->regs = hubbub_regs;
|
||||
hubbub2->shifts = hubbub_shift;
|
||||
hubbub2->masks = hubbub_mask;
|
||||
|
||||
hubbub2->debug_test_index_pstate = 0xB;
|
||||
hubbub2->detile_buf_size = det_size_kb * 1024;
|
||||
hubbub2->pixel_chunk_size = pixel_chunk_size_kb * 1024;
|
||||
hubbub2->crb_size_segs = config_return_buffer_size_kb / DCN32_CRB_SEGMENT_SIZE_KB;
|
||||
}
|
172
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.h
Normal file
172
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.h
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright 2016 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_HUBBUB_DCN32_H__
|
||||
#define __DC_HUBBUB_DCN32_H__
|
||||
|
||||
#include "dcn21/dcn21_hubbub.h"
|
||||
|
||||
#define HUBBUB_REG_LIST_DCN32(id)\
|
||||
SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\
|
||||
SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B),\
|
||||
SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C),\
|
||||
SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D),\
|
||||
SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL),\
|
||||
SR(DCHUBBUB_ARB_DRAM_STATE_CNTL),\
|
||||
SR(DCHUBBUB_ARB_SAT_LEVEL),\
|
||||
SR(DCHUBBUB_ARB_DF_REQ_OUTSTAND),\
|
||||
SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
|
||||
SR(DCHUBBUB_SOFT_RESET),\
|
||||
SR(DCHUBBUB_CRC_CTRL), \
|
||||
SR(DCN_VM_FB_LOCATION_BASE),\
|
||||
SR(DCN_VM_FB_LOCATION_TOP),\
|
||||
SR(DCN_VM_FB_OFFSET),\
|
||||
SR(DCN_VM_AGP_BOT),\
|
||||
SR(DCN_VM_AGP_TOP),\
|
||||
SR(DCN_VM_AGP_BASE),\
|
||||
HUBBUB_SR_WATERMARK_REG_LIST(), \
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D),\
|
||||
SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A),\
|
||||
SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B),\
|
||||
SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C),\
|
||||
SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D),\
|
||||
SR(DCHUBBUB_DET0_CTRL),\
|
||||
SR(DCHUBBUB_DET1_CTRL),\
|
||||
SR(DCHUBBUB_DET2_CTRL),\
|
||||
SR(DCHUBBUB_DET3_CTRL),\
|
||||
SR(DCHUBBUB_COMPBUF_CTRL),\
|
||||
SR(COMPBUF_RESERVED_SPACE),\
|
||||
SR(DCHUBBUB_ARB_USR_RETRAINING_CNTL),\
|
||||
SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A),\
|
||||
SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B),\
|
||||
SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C),\
|
||||
SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D),\
|
||||
SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A),\
|
||||
SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B),\
|
||||
SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C),\
|
||||
SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D),\
|
||||
SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A),\
|
||||
SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B),\
|
||||
SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C),\
|
||||
SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D),\
|
||||
SR(DCN_VM_FAULT_ADDR_MSB),\
|
||||
SR(DCN_VM_FAULT_ADDR_LSB),\
|
||||
SR(DCN_VM_FAULT_CNTL),\
|
||||
SR(DCN_VM_FAULT_STATUS)
|
||||
|
||||
#define HUBBUB_MASK_SH_LIST_DCN32(mask_sh)\
|
||||
HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_SOFT_RESET, DCHUBBUB_GLOBAL_SOFT_RESET, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, mask_sh), \
|
||||
HUBBUB_MASK_SH_LIST_STUTTER(mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FB_LOCATION_BASE, FB_BASE, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FB_LOCATION_TOP, FB_TOP, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FB_OFFSET, FB_OFFSET, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_AGP_BOT, AGP_BOT, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_AGP_TOP, AGP_TOP, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_AGP_BASE, AGP_BASE, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_DET0_CTRL, DET0_SIZE, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_DET1_CTRL, DET1_SIZE, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_DET2_CTRL, DET2_SIZE, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_DET3_CTRL, DET3_SIZE, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE_CURRENT, mask_sh),\
|
||||
HUBBUB_SF(COMPBUF_RESERVED_SPACE, COMPBUF_RESERVED_SPACE_64B, mask_sh),\
|
||||
HUBBUB_SF(COMPBUF_RESERVED_SPACE, COMPBUF_RESERVED_SPACE_ZS, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_CNTL, DCHUBBUB_ARB_ALLOW_USR_RETRAINING_FORCE_VALUE, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_CNTL, DCHUBBUB_ARB_ALLOW_USR_RETRAINING_FORCE_ENABLE, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_CNTL, DCHUBBUB_ARB_DO_NOT_FORCE_ALLOW_USR_RETRAINING_DURING_PSTATE_CHANGE_REQUEST, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_CNTL, DCHUBBUB_ARB_DO_NOT_FORCE_ALLOW_USR_RETRAINING_DURING_PRE_CSTATE, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C, DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D, DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C, DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D, DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C, DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C, mask_sh),\
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D, DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FAULT_ADDR_MSB, DCN_VM_FAULT_ADDR_MSB, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FAULT_ADDR_LSB, DCN_VM_FAULT_ADDR_LSB, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FAULT_CNTL, DCN_VM_ERROR_STATUS_CLEAR, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FAULT_CNTL, DCN_VM_ERROR_STATUS_MODE, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FAULT_CNTL, DCN_VM_ERROR_INTERRUPT_ENABLE, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FAULT_CNTL, DCN_VM_RANGE_FAULT_DISABLE, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FAULT_CNTL, DCN_VM_PRQ_FAULT_DISABLE, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FAULT_STATUS, DCN_VM_ERROR_STATUS, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FAULT_STATUS, DCN_VM_ERROR_VMID, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FAULT_STATUS, DCN_VM_ERROR_TABLE_LEVEL, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FAULT_STATUS, DCN_VM_ERROR_PIPE, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FAULT_STATUS, DCN_VM_ERROR_INTERRUPT_STATUS, mask_sh)
|
||||
|
||||
|
||||
void hubbub32_construct(struct dcn20_hubbub *hubbub2,
|
||||
struct dc_context *ctx,
|
||||
const struct dcn_hubbub_registers *hubbub_regs,
|
||||
const struct dcn_hubbub_shift *hubbub_shift,
|
||||
const struct dcn_hubbub_mask *hubbub_mask,
|
||||
int det_size_kb,
|
||||
int pixel_chunk_size_kb,
|
||||
int config_return_buffer_size_kb);
|
||||
|
||||
#endif
|
148
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c
Normal file
148
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2012-20 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_calcs.h"
|
||||
#include "reg_helper.h"
|
||||
#include "basics/conversion.h"
|
||||
#include "dcn32_hubp.h"
|
||||
|
||||
#define REG(reg)\
|
||||
hubp2->hubp_regs->reg
|
||||
|
||||
#define CTX \
|
||||
hubp2->base.ctx
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
hubp2->hubp_shift->field_name, hubp2->hubp_mask->field_name
|
||||
|
||||
void hubp32_update_force_pstate_disallow(struct hubp *hubp, bool pstate_disallow)
|
||||
{
|
||||
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
|
||||
REG_UPDATE_2(UCLK_PSTATE_FORCE,
|
||||
DATA_UCLK_PSTATE_FORCE_EN, pstate_disallow,
|
||||
DATA_UCLK_PSTATE_FORCE_VALUE, 0);
|
||||
}
|
||||
|
||||
void hubp32_update_mall_sel(struct hubp *hubp, uint32_t mall_sel)
|
||||
{
|
||||
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
|
||||
|
||||
// Also cache cursor in MALL if using MALL for SS
|
||||
REG_UPDATE_2(DCHUBP_MALL_CONFIG, USE_MALL_SEL, mall_sel,
|
||||
USE_MALL_FOR_CURSOR, mall_sel == 2 ? 1 : 0);
|
||||
}
|
||||
|
||||
void hubp32_prepare_subvp_buffering(struct hubp *hubp, bool enable)
|
||||
{
|
||||
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
|
||||
REG_UPDATE(DCHUBP_VMPG_CONFIG, FORCE_ONE_ROW_FOR_FRAME, enable);
|
||||
|
||||
/* Programming guide suggests CURSOR_REQ_MODE = 1 for SubVP:
|
||||
* For Pstate change using the MALL with sub-viewport buffering,
|
||||
* the cursor does not use the MALL (USE_MALL_FOR_CURSOR is ignored)
|
||||
* and sub-viewport positioning by Display FW has to avoid the cursor
|
||||
* requests to DRAM (set CURSOR_REQ_MODE = 1 to minimize this exclusion).
|
||||
*
|
||||
* CURSOR_REQ_MODE = 1 begins fetching cursor data at the beginning of display prefetch.
|
||||
* Setting this should allow the sub-viewport position to always avoid the cursor because
|
||||
* we do not allow the sub-viewport region to overlap with display prefetch (i.e. during blank).
|
||||
*/
|
||||
REG_UPDATE(CURSOR_CONTROL, CURSOR_REQ_MODE, enable);
|
||||
}
|
||||
|
||||
void hubp32_phantom_hubp_post_enable(struct hubp *hubp)
|
||||
{
|
||||
uint32_t reg_val;
|
||||
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
|
||||
|
||||
REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, 1);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static struct hubp_funcs dcn32_hubp_funcs = {
|
||||
.hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
|
||||
.hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled,
|
||||
.hubp_program_surface_flip_and_addr = hubp3_program_surface_flip_and_addr,
|
||||
.hubp_program_surface_config = hubp3_program_surface_config,
|
||||
.hubp_is_flip_pending = hubp2_is_flip_pending,
|
||||
.hubp_setup = hubp3_setup,
|
||||
.hubp_setup_interdependent = hubp2_setup_interdependent,
|
||||
.hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings,
|
||||
.set_blank = hubp2_set_blank,
|
||||
.dcc_control = hubp3_dcc_control,
|
||||
.mem_program_viewport = min_set_viewport,
|
||||
.set_cursor_attributes = hubp2_cursor_set_attributes,
|
||||
.set_cursor_position = hubp2_cursor_set_position,
|
||||
.hubp_clk_cntl = hubp2_clk_cntl,
|
||||
.hubp_vtg_sel = hubp2_vtg_sel,
|
||||
.dmdata_set_attributes = hubp3_dmdata_set_attributes,
|
||||
.dmdata_load = hubp2_dmdata_load,
|
||||
.dmdata_status_done = hubp2_dmdata_status_done,
|
||||
.hubp_read_state = hubp3_read_state,
|
||||
.hubp_clear_underflow = hubp2_clear_underflow,
|
||||
.hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl,
|
||||
.hubp_init = hubp3_init,
|
||||
.set_unbounded_requesting = hubp31_set_unbounded_requesting,
|
||||
.hubp_soft_reset = hubp31_soft_reset,
|
||||
.hubp_in_blank = hubp1_in_blank,
|
||||
.hubp_update_force_pstate_disallow = hubp32_update_force_pstate_disallow,
|
||||
.phantom_hubp_post_enable = hubp32_phantom_hubp_post_enable,
|
||||
.hubp_update_mall_sel = hubp32_update_mall_sel,
|
||||
.hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
|
||||
.hubp_set_flip_int = hubp1_set_flip_int
|
||||
};
|
||||
|
||||
bool hubp32_construct(
|
||||
struct dcn20_hubp *hubp2,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dcn_hubp2_registers *hubp_regs,
|
||||
const struct dcn_hubp2_shift *hubp_shift,
|
||||
const struct dcn_hubp2_mask *hubp_mask)
|
||||
{
|
||||
hubp2->base.funcs = &dcn32_hubp_funcs;
|
||||
hubp2->base.ctx = ctx;
|
||||
hubp2->hubp_regs = hubp_regs;
|
||||
hubp2->hubp_shift = hubp_shift;
|
||||
hubp2->hubp_mask = hubp_mask;
|
||||
hubp2->base.inst = inst;
|
||||
hubp2->base.opp_id = OPP_ID_INVALID;
|
||||
hubp2->base.mpcc_id = 0xf;
|
||||
|
||||
return true;
|
||||
}
|
69
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.h
Normal file
69
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2012-20 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_HUBP_DCN32_H__
|
||||
#define __DC_HUBP_DCN32_H__
|
||||
|
||||
#include "dcn20/dcn20_hubp.h"
|
||||
#include "dcn21/dcn21_hubp.h"
|
||||
#include "dcn30/dcn30_hubp.h"
|
||||
#include "dcn31/dcn31_hubp.h"
|
||||
|
||||
#define HUBP_REG_LIST_DCN32(id)\
|
||||
HUBP_REG_LIST_DCN30(id),\
|
||||
SRI(DCHUBP_MALL_CONFIG, HUBP, id),\
|
||||
SRI(DCHUBP_VMPG_CONFIG, HUBP, id),\
|
||||
SRI(UCLK_PSTATE_FORCE, HUBPREQ, id)
|
||||
|
||||
#define HUBP_MASK_SH_LIST_DCN32(mask_sh)\
|
||||
HUBP_MASK_SH_LIST_DCN31(mask_sh),\
|
||||
HUBP_SF(HUBP0_DCHUBP_MALL_CONFIG, USE_MALL_SEL, mask_sh),\
|
||||
HUBP_SF(HUBP0_DCHUBP_MALL_CONFIG, USE_MALL_FOR_CURSOR, mask_sh),\
|
||||
HUBP_SF(HUBP0_DCHUBP_VMPG_CONFIG, VMPG_SIZE, mask_sh),\
|
||||
HUBP_SF(HUBP0_DCHUBP_VMPG_CONFIG, PTE_BUFFER_MODE, mask_sh),\
|
||||
HUBP_SF(HUBP0_DCHUBP_VMPG_CONFIG, BIGK_FRAGMENT_SIZE, mask_sh),\
|
||||
HUBP_SF(HUBP0_DCHUBP_VMPG_CONFIG, FORCE_ONE_ROW_FOR_FRAME, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_UCLK_PSTATE_FORCE, DATA_UCLK_PSTATE_FORCE_EN, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_UCLK_PSTATE_FORCE, DATA_UCLK_PSTATE_FORCE_VALUE, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_UCLK_PSTATE_FORCE, CURSOR_UCLK_PSTATE_FORCE_EN, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_UCLK_PSTATE_FORCE, CURSOR_UCLK_PSTATE_FORCE_VALUE, mask_sh)
|
||||
|
||||
void hubp32_update_force_pstate_disallow(struct hubp *hubp, bool pstate_disallow);
|
||||
|
||||
void hubp32_update_mall_sel(struct hubp *hubp, uint32_t mall_sel);
|
||||
|
||||
void hubp32_prepare_subvp_buffering(struct hubp *hubp, bool enable);
|
||||
|
||||
void hubp32_phantom_hubp_post_enable(struct hubp *hubp);
|
||||
|
||||
bool hubp32_construct(
|
||||
struct dcn20_hubp *hubp2,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dcn_hubp2_registers *hubp_regs,
|
||||
const struct dcn_hubp2_shift *hubp_shift,
|
||||
const struct dcn_hubp2_mask *hubp_mask);
|
||||
|
||||
#endif /* __DC_HUBP_DCN32_H__ */
|
891
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
Normal file
891
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
Normal file
@ -0,0 +1,891 @@
|
||||
/*
|
||||
* Copyright 2016 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "dm_helpers.h"
|
||||
#include "core_types.h"
|
||||
#include "resource.h"
|
||||
#include "dccg.h"
|
||||
#include "dce/dce_hwseq.h"
|
||||
#include "dcn30/dcn30_cm_common.h"
|
||||
#include "reg_helper.h"
|
||||
#include "abm.h"
|
||||
#include "hubp.h"
|
||||
#include "dchubbub.h"
|
||||
#include "timing_generator.h"
|
||||
#include "opp.h"
|
||||
#include "ipp.h"
|
||||
#include "mpc.h"
|
||||
#include "mcif_wb.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "link_hwss.h"
|
||||
#include "dpcd_defs.h"
|
||||
#include "dcn32_hwseq.h"
|
||||
#include "clk_mgr.h"
|
||||
#include "dsc.h"
|
||||
#include "dcn20/dcn20_optc.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
#define CTX \
|
||||
hws->ctx
|
||||
#define REG(reg)\
|
||||
hws->regs->reg
|
||||
#define DC_LOGGER \
|
||||
dc->ctx->logger
|
||||
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
hws->shifts->field_name, hws->masks->field_name
|
||||
|
||||
void dcn32_dsc_pg_control(
|
||||
struct dce_hwseq *hws,
|
||||
unsigned int dsc_inst,
|
||||
bool power_on)
|
||||
{
|
||||
uint32_t power_gate = power_on ? 0 : 1;
|
||||
uint32_t pwr_status = power_on ? 0 : 2;
|
||||
uint32_t org_ip_request_cntl = 0;
|
||||
|
||||
if (hws->ctx->dc->debug.disable_dsc_power_gate)
|
||||
return;
|
||||
|
||||
REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
|
||||
if (org_ip_request_cntl == 0)
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
|
||||
|
||||
switch (dsc_inst) {
|
||||
case 0: /* DSC0 */
|
||||
REG_UPDATE(DOMAIN16_PG_CONFIG,
|
||||
DOMAIN_POWER_GATE, power_gate);
|
||||
|
||||
REG_WAIT(DOMAIN16_PG_STATUS,
|
||||
DOMAIN_PGFSM_PWR_STATUS, pwr_status,
|
||||
1, 1000);
|
||||
break;
|
||||
case 1: /* DSC1 */
|
||||
REG_UPDATE(DOMAIN17_PG_CONFIG,
|
||||
DOMAIN_POWER_GATE, power_gate);
|
||||
|
||||
REG_WAIT(DOMAIN17_PG_STATUS,
|
||||
DOMAIN_PGFSM_PWR_STATUS, pwr_status,
|
||||
1, 1000);
|
||||
break;
|
||||
case 2: /* DSC2 */
|
||||
REG_UPDATE(DOMAIN18_PG_CONFIG,
|
||||
DOMAIN_POWER_GATE, power_gate);
|
||||
|
||||
REG_WAIT(DOMAIN18_PG_STATUS,
|
||||
DOMAIN_PGFSM_PWR_STATUS, pwr_status,
|
||||
1, 1000);
|
||||
break;
|
||||
case 3: /* DSC3 */
|
||||
REG_UPDATE(DOMAIN19_PG_CONFIG,
|
||||
DOMAIN_POWER_GATE, power_gate);
|
||||
|
||||
REG_WAIT(DOMAIN19_PG_STATUS,
|
||||
DOMAIN_PGFSM_PWR_STATUS, pwr_status,
|
||||
1, 1000);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
break;
|
||||
}
|
||||
|
||||
if (org_ip_request_cntl == 0)
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
|
||||
}
|
||||
|
||||
|
||||
void dcn32_enable_power_gating_plane(
|
||||
struct dce_hwseq *hws,
|
||||
bool enable)
|
||||
{
|
||||
bool force_on = true; /* disable power gating */
|
||||
|
||||
if (enable)
|
||||
force_on = false;
|
||||
|
||||
/* DCHUBP0/1/2/3 */
|
||||
REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
|
||||
REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
|
||||
REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
|
||||
REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
|
||||
|
||||
/* DCS0/1/2/3 */
|
||||
REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
|
||||
REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
|
||||
REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
|
||||
REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
|
||||
}
|
||||
|
||||
void dcn32_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
|
||||
{
|
||||
uint32_t power_gate = power_on ? 0 : 1;
|
||||
uint32_t pwr_status = power_on ? 0 : 2;
|
||||
|
||||
if (hws->ctx->dc->debug.disable_hubp_power_gate)
|
||||
return;
|
||||
|
||||
if (REG(DOMAIN0_PG_CONFIG) == 0)
|
||||
return;
|
||||
|
||||
switch (hubp_inst) {
|
||||
case 0:
|
||||
REG_SET(DOMAIN0_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
|
||||
REG_WAIT(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
|
||||
break;
|
||||
case 1:
|
||||
REG_SET(DOMAIN1_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
|
||||
REG_WAIT(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
|
||||
break;
|
||||
case 2:
|
||||
REG_SET(DOMAIN2_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
|
||||
REG_WAIT(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
|
||||
break;
|
||||
case 3:
|
||||
REG_SET(DOMAIN3_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
|
||||
REG_WAIT(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool dcn32_check_no_memory_request_for_cab(struct dc *dc)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* First, check no-memory-request case */
|
||||
for (i = 0; i < dc->current_state->stream_count; i++) {
|
||||
if (dc->current_state->stream_status[i].plane_count)
|
||||
/* Fail eligibility on a visible stream */
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == dc->current_state->stream_count)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* This function takes in the start address and surface size to be cached in CAB
|
||||
* and calculates the total number of cache lines required to store the surface.
|
||||
* The number of cache lines used for each surface is calculated independently of
|
||||
* one another. For example, if there is a primary surface(1), meta surface(2), and
|
||||
* cursor(3), this function should be called 3 times to calculate the number of cache
|
||||
* lines used for each of those surfaces.
|
||||
*/
|
||||
static uint32_t dcn32_cache_lines_for_surface(struct dc *dc, uint32_t surface_size, uint64_t start_address)
|
||||
{
|
||||
uint32_t lines_used = 1;
|
||||
uint32_t num_cached_bytes = 0;
|
||||
uint32_t remaining_size = 0;
|
||||
uint32_t cache_line_size = dc->caps.cache_line_size;
|
||||
|
||||
/* 1. Calculate surface size minus the number of bytes stored
|
||||
* in the first cache line (all bytes in first cache line might
|
||||
* not be fully used).
|
||||
*/
|
||||
num_cached_bytes = cache_line_size - (start_address % cache_line_size);
|
||||
remaining_size = surface_size - num_cached_bytes;
|
||||
|
||||
/* 2. Calculate number of cache lines that will be fully used with
|
||||
* the remaining number of bytes to be stored.
|
||||
*/
|
||||
lines_used += (remaining_size / cache_line_size);
|
||||
|
||||
/* 3. Check if we need an extra line due to the remaining size not being
|
||||
* a multiple of CACHE_LINE_SIZE.
|
||||
*/
|
||||
if (remaining_size % cache_line_size > 0)
|
||||
lines_used++;
|
||||
|
||||
return lines_used;
|
||||
}
|
||||
|
||||
/* This function loops through every surface that needs to be cached in CAB for SS,
|
||||
* and calculates the total number of ways required to store all surfaces (primary,
|
||||
* meta, cursor).
|
||||
*/
|
||||
static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *ctx)
|
||||
{
|
||||
uint8_t i, j;
|
||||
struct dc_stream_state *stream = NULL;
|
||||
struct dc_plane_state *plane = NULL;
|
||||
uint32_t surface_size = 0;
|
||||
uint32_t cursor_size = 0;
|
||||
uint32_t cache_lines_used = 0;
|
||||
uint32_t total_lines = 0;
|
||||
uint32_t lines_per_way = 0;
|
||||
uint32_t num_ways = 0;
|
||||
|
||||
for (i = 0; i < ctx->stream_count; i++) {
|
||||
stream = ctx->streams[i];
|
||||
|
||||
// Don't include PSR surface in the total surface size for CAB allocation
|
||||
if (stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED)
|
||||
continue;
|
||||
|
||||
if (ctx->stream_status[i].plane_count == 0)
|
||||
continue;
|
||||
|
||||
// For each stream, loop through each plane to calculate the number of cache
|
||||
// lines required to store the surface in CAB
|
||||
for (j = 0; j < ctx->stream_status[i].plane_count; j++) {
|
||||
plane = ctx->stream_status[i].plane_states[j];
|
||||
|
||||
// Calculate total surface size
|
||||
surface_size = plane->plane_size.surface_pitch *
|
||||
plane->plane_size.surface_size.height *
|
||||
(plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4);
|
||||
|
||||
// Convert surface size + starting address to number of cache lines required
|
||||
// (alignment accounted for)
|
||||
cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
|
||||
plane->address.grph.addr.quad_part);
|
||||
|
||||
if (plane->address.grph.meta_addr.quad_part) {
|
||||
// Meta surface
|
||||
cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
|
||||
plane->address.grph.meta_addr.quad_part);
|
||||
}
|
||||
}
|
||||
|
||||
// Include cursor size for CAB allocation
|
||||
if (stream->cursor_position.enable && plane->address.grph.cursor_cache_addr.quad_part) {
|
||||
cursor_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size;
|
||||
switch (stream->cursor_attributes.color_format) {
|
||||
case CURSOR_MODE_MONO:
|
||||
cursor_size /= 2;
|
||||
break;
|
||||
case CURSOR_MODE_COLOR_1BIT_AND:
|
||||
case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
|
||||
case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
|
||||
cursor_size *= 4;
|
||||
break;
|
||||
|
||||
case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
|
||||
case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
|
||||
cursor_size *= 8;
|
||||
break;
|
||||
}
|
||||
cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
|
||||
plane->address.grph.cursor_cache_addr.quad_part);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert number of cache lines required to number of ways
|
||||
total_lines = dc->caps.max_cab_allocation_bytes / dc->caps.cache_line_size;
|
||||
lines_per_way = total_lines / dc->caps.cache_num_ways;
|
||||
num_ways = cache_lines_used / lines_per_way;
|
||||
|
||||
if (cache_lines_used % lines_per_way > 0)
|
||||
num_ways++;
|
||||
|
||||
return num_ways;
|
||||
}
|
||||
|
||||
bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
uint8_t ways;
|
||||
|
||||
if (!dc->ctx->dmub_srv)
|
||||
return false;
|
||||
|
||||
if (enable) {
|
||||
if (dc->current_state) {
|
||||
|
||||
/* 1. Check no memory request case for CAB.
|
||||
* If no memory request case, send CAB_ACTION NO_DF_REQ DMUB message
|
||||
*/
|
||||
if (dcn32_check_no_memory_request_for_cab(dc)) {
|
||||
/* Enable no-memory-requests case */
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
|
||||
cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_DCN_REQ;
|
||||
cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* 2. Check if all surfaces can fit in CAB.
|
||||
* If surfaces can fit into CAB, send CAB_ACTION_ALLOW DMUB message
|
||||
* and configure HUBP's to fetch from MALL
|
||||
*/
|
||||
ways = dcn32_calculate_cab_allocation(dc, dc->current_state);
|
||||
if (ways <= dc->caps.cache_num_ways) {
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
|
||||
cmd.cab.header.sub_type = DMUB_CMD__CAB_DCN_SS_FIT_IN_CAB;
|
||||
cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
|
||||
cmd.cab.cab_alloc_ways = ways;
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Disable CAB */
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
|
||||
cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_IDLE_OPTIMIZATION;
|
||||
cmd.cab.header.payload_bytes =
|
||||
sizeof(cmd.cab) - sizeof(cmd.cab.header);
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Send DMCUB message with SubVP pipe info
|
||||
* - For each pipe in context, populate payload with required SubVP information
|
||||
* if the pipe is using SubVP for MCLK switch
|
||||
* - This function must be called while the DMUB HW lock is acquired by driver
|
||||
*/
|
||||
void dcn32_commit_subvp_config(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
/*
|
||||
int i;
|
||||
bool enable_subvp = false;
|
||||
|
||||
if (!dc->ctx || !dc->ctx->dmub_srv)
|
||||
return;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe_ctx->stream && pipe_ctx->stream->mall_stream_config.paired_stream &&
|
||||
pipe_ctx->stream->mall_stream_config.type == SUBVP_MAIN) {
|
||||
// There is at least 1 SubVP pipe, so enable SubVP
|
||||
enable_subvp = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dc_dmub_setup_subvp_dmub_command(dc, context, enable_subvp);
|
||||
*/
|
||||
}
|
||||
|
||||
static bool dcn32_set_mpc_shaper_3dlut(
|
||||
struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream)
|
||||
{
|
||||
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
|
||||
int mpcc_id = pipe_ctx->plane_res.hubp->inst;
|
||||
struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
|
||||
bool result = false;
|
||||
|
||||
const struct pwl_params *shaper_lut = NULL;
|
||||
//get the shaper lut params
|
||||
if (stream->func_shaper) {
|
||||
if (stream->func_shaper->type == TF_TYPE_HWPWL)
|
||||
shaper_lut = &stream->func_shaper->pwl;
|
||||
else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
|
||||
cm_helper_translate_curve_to_hw_format(
|
||||
stream->func_shaper,
|
||||
&dpp_base->shaper_params, true);
|
||||
shaper_lut = &dpp_base->shaper_params;
|
||||
}
|
||||
}
|
||||
|
||||
if (stream->lut3d_func &&
|
||||
stream->lut3d_func->state.bits.initialized == 1) {
|
||||
|
||||
result = mpc->funcs->program_3dlut(mpc,
|
||||
&stream->lut3d_func->lut_3d,
|
||||
mpcc_id);
|
||||
|
||||
result = mpc->funcs->program_shaper(mpc,
|
||||
shaper_lut,
|
||||
mpcc_id);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
bool dcn32_set_output_transfer_func(struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
const struct dc_stream_state *stream)
|
||||
{
|
||||
int mpcc_id = pipe_ctx->plane_res.hubp->inst;
|
||||
struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
|
||||
struct pwl_params *params = NULL;
|
||||
bool ret = false;
|
||||
|
||||
/* program OGAM or 3DLUT only for the top pipe*/
|
||||
if (pipe_ctx->top_pipe == NULL) {
|
||||
/*program shaper and 3dlut in MPC*/
|
||||
ret = dcn32_set_mpc_shaper_3dlut(pipe_ctx, stream);
|
||||
if (ret == false && mpc->funcs->set_output_gamma && stream->out_transfer_func) {
|
||||
if (stream->out_transfer_func->type == TF_TYPE_HWPWL)
|
||||
params = &stream->out_transfer_func->pwl;
|
||||
else if (pipe_ctx->stream->out_transfer_func->type ==
|
||||
TF_TYPE_DISTRIBUTED_POINTS &&
|
||||
cm3_helper_translate_curve_to_hw_format(
|
||||
stream->out_transfer_func,
|
||||
&mpc->blender_params, false))
|
||||
params = &mpc->blender_params;
|
||||
/* there are no ROM LUTs in OUTGAM */
|
||||
if (stream->out_transfer_func->type == TF_TYPE_PREDEFINED)
|
||||
BREAK_TO_DEBUGGER();
|
||||
}
|
||||
}
|
||||
|
||||
mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Program P-State force value according to if pipe is using SubVP or not:
|
||||
* 1. Reset P-State force on all pipes first
|
||||
* 2. For each main pipe, force P-State disallow (P-State allow moderated by DMUB)
|
||||
*/
|
||||
void dcn32_subvp_update_force_pstate(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
int i;
|
||||
int num_subvp = 0;
|
||||
/* Unforce p-state for each pipe
|
||||
*/
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
struct hubp *hubp = pipe->plane_res.hubp;
|
||||
|
||||
if (hubp && hubp->funcs->hubp_update_force_pstate_disallow)
|
||||
hubp->funcs->hubp_update_force_pstate_disallow(hubp, false);
|
||||
if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN)
|
||||
num_subvp++;
|
||||
}
|
||||
|
||||
if (num_subvp == 0)
|
||||
return;
|
||||
|
||||
/* Loop through each pipe -- for each subvp main pipe force p-state allow equal to false.
|
||||
*/
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe->stream && pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
|
||||
struct hubp *hubp = pipe->plane_res.hubp;
|
||||
|
||||
if (hubp && hubp->funcs->hubp_update_force_pstate_disallow)
|
||||
hubp->funcs->hubp_update_force_pstate_disallow(hubp, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update MALL_SEL register based on if pipe / plane
|
||||
* is a phantom pipe, main pipe, and if using MALL
|
||||
* for SS.
|
||||
*/
|
||||
void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
int i;
|
||||
unsigned int num_ways = dcn32_calculate_cab_allocation(dc, context);
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
struct hubp *hubp = pipe->plane_res.hubp;
|
||||
|
||||
if (pipe->stream && pipe->plane_state && hubp && hubp->funcs->hubp_update_mall_sel) {
|
||||
if (pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
|
||||
hubp->funcs->hubp_update_mall_sel(hubp, 1);
|
||||
} else {
|
||||
hubp->funcs->hubp_update_mall_sel(hubp,
|
||||
num_ways <= dc->caps.cache_num_ways &&
|
||||
pipe->stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED ? 2 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Program the sub-viewport pipe configuration after the main / phantom pipes
|
||||
* have been programmed in hardware.
|
||||
* 1. Update force P-State for all the main pipes (disallow P-state)
|
||||
* 2. Update MALL_SEL register
|
||||
* 3. Program FORCE_ONE_ROW_FOR_FRAME for main subvp pipes
|
||||
*/
|
||||
void dcn32_program_mall_pipe_config(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
int i;
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
// Update force P-state for each pipe accordingly
|
||||
if (hws && hws->funcs.subvp_update_force_pstate)
|
||||
hws->funcs.subvp_update_force_pstate(dc, context);
|
||||
|
||||
// Update MALL_SEL register for each pipe
|
||||
if (hws && hws->funcs.update_mall_sel)
|
||||
hws->funcs.update_mall_sel(dc, context);
|
||||
|
||||
// Program FORCE_ONE_ROW_FOR_FRAME and CURSOR_REQ_MODE for main subvp pipes
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
struct hubp *hubp = pipe->plane_res.hubp;
|
||||
|
||||
if (pipe->stream && hubp && hubp->funcs->hubp_prepare_subvp_buffering) {
|
||||
if (pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
|
||||
hubp->funcs->hubp_prepare_subvp_buffering(hubp, true);
|
||||
} else {
|
||||
hubp->funcs->hubp_prepare_subvp_buffering(hubp, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dcn32_init_hw(struct dc *dc)
|
||||
{
|
||||
struct abm **abms = dc->res_pool->multiple_abms;
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
struct dc_bios *dcb = dc->ctx->dc_bios;
|
||||
struct resource_pool *res_pool = dc->res_pool;
|
||||
int i;
|
||||
int edp_num;
|
||||
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
|
||||
|
||||
dc->debug.disable_idle_power_optimizations = true;
|
||||
if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
|
||||
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
|
||||
|
||||
// Initialize the dccg
|
||||
if (res_pool->dccg->funcs->dccg_init)
|
||||
res_pool->dccg->funcs->dccg_init(res_pool->dccg);
|
||||
|
||||
if (!dcb->funcs->is_accelerated_mode(dcb)) {
|
||||
hws->funcs.bios_golden_init(dc);
|
||||
hws->funcs.disable_vga(dc->hwseq);
|
||||
}
|
||||
|
||||
// Set default OPTC memory power states
|
||||
if (dc->debug.enable_mem_low_power.bits.optc) {
|
||||
// Shutdown when unassigned and light sleep in VBLANK
|
||||
REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
|
||||
}
|
||||
|
||||
if (dc->debug.enable_mem_low_power.bits.vga) {
|
||||
// Power down VGA memory
|
||||
REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
|
||||
}
|
||||
|
||||
if (dc->ctx->dc_bios->fw_info_valid) {
|
||||
res_pool->ref_clocks.xtalin_clock_inKhz =
|
||||
dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
|
||||
|
||||
if (res_pool->dccg && res_pool->hubbub) {
|
||||
(res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
|
||||
dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
|
||||
&res_pool->ref_clocks.dccg_ref_clock_inKhz);
|
||||
|
||||
(res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
|
||||
res_pool->ref_clocks.dccg_ref_clock_inKhz,
|
||||
&res_pool->ref_clocks.dchub_ref_clock_inKhz);
|
||||
} else {
|
||||
// Not all ASICs have DCCG sw component
|
||||
res_pool->ref_clocks.dccg_ref_clock_inKhz =
|
||||
res_pool->ref_clocks.xtalin_clock_inKhz;
|
||||
res_pool->ref_clocks.dchub_ref_clock_inKhz =
|
||||
res_pool->ref_clocks.xtalin_clock_inKhz;
|
||||
}
|
||||
} else
|
||||
ASSERT_CRITICAL(false);
|
||||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
/* Power up AND update implementation according to the
|
||||
* required signal (which may be different from the
|
||||
* default signal on connector).
|
||||
*/
|
||||
struct dc_link *link = dc->links[i];
|
||||
|
||||
link->link_enc->funcs->hw_init(link->link_enc);
|
||||
|
||||
/* Check for enabled DIG to identify enabled display */
|
||||
if (link->link_enc->funcs->is_dig_enabled &&
|
||||
link->link_enc->funcs->is_dig_enabled(link->link_enc))
|
||||
link->link_status.link_active = true;
|
||||
}
|
||||
|
||||
/* Power gate DSCs */
|
||||
for (i = 0; i < res_pool->res_cap->num_dsc; i++)
|
||||
if (hws->funcs.dsc_pg_control != NULL)
|
||||
hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
|
||||
|
||||
/* we want to turn off all dp displays before doing detection */
|
||||
dc_link_blank_all_dp_displays(dc);
|
||||
|
||||
/* If taking control over from VBIOS, we may want to optimize our first
|
||||
* mode set, so we need to skip powering down pipes until we know which
|
||||
* pipes we want to use.
|
||||
* Otherwise, if taking control is not possible, we need to power
|
||||
* everything down.
|
||||
*/
|
||||
if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.power_down_display_on_boot) {
|
||||
hws->funcs.init_pipes(dc, dc->current_state);
|
||||
if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
|
||||
dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
|
||||
!dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
|
||||
}
|
||||
|
||||
/* In headless boot cases, DIG may be turned
|
||||
* on which causes HW/SW discrepancies.
|
||||
* To avoid this, power down hardware on boot
|
||||
* if DIG is turned on and seamless boot not enabled
|
||||
*/
|
||||
if (dc->config.power_down_display_on_boot) {
|
||||
struct dc_link *edp_links[MAX_NUM_EDP];
|
||||
struct dc_link *edp_link;
|
||||
|
||||
get_edp_links(dc, edp_links, &edp_num);
|
||||
if (edp_num) {
|
||||
for (i = 0; i < edp_num; i++) {
|
||||
edp_link = edp_links[i];
|
||||
if (edp_link->link_enc->funcs->is_dig_enabled &&
|
||||
edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
|
||||
dc->hwss.edp_backlight_control &&
|
||||
dc->hwss.power_down &&
|
||||
dc->hwss.edp_power_control) {
|
||||
dc->hwss.edp_backlight_control(edp_link, false);
|
||||
dc->hwss.power_down(dc);
|
||||
dc->hwss.edp_power_control(edp_link, false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
struct dc_link *link = dc->links[i];
|
||||
|
||||
if (link->link_enc->funcs->is_dig_enabled &&
|
||||
link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
|
||||
dc->hwss.power_down) {
|
||||
dc->hwss.power_down(dc);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < res_pool->audio_count; i++) {
|
||||
struct audio *audio = res_pool->audios[i];
|
||||
|
||||
audio->funcs->hw_init(audio);
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
struct dc_link *link = dc->links[i];
|
||||
|
||||
if (link->panel_cntl)
|
||||
backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
if (abms[i] != NULL && abms[i]->funcs != NULL)
|
||||
abms[i]->funcs->abm_init(abms[i], backlight);
|
||||
}
|
||||
|
||||
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
|
||||
REG_WRITE(DIO_MEM_PWR_CTRL, 0);
|
||||
|
||||
if (!dc->debug.disable_clock_gate) {
|
||||
/* enable all DCN clock gating */
|
||||
REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
|
||||
|
||||
REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
|
||||
|
||||
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
|
||||
}
|
||||
if (hws->funcs.enable_power_gating_plane)
|
||||
hws->funcs.enable_power_gating_plane(dc->hwseq, true);
|
||||
|
||||
if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
|
||||
dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
|
||||
|
||||
if (dc->clk_mgr->funcs->notify_wm_ranges)
|
||||
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
|
||||
|
||||
if (dc->clk_mgr->funcs->set_hard_max_memclk)
|
||||
dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
|
||||
|
||||
if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
|
||||
dc->res_pool->hubbub->funcs->force_pstate_change_control(
|
||||
dc->res_pool->hubbub, false, false);
|
||||
|
||||
if (dc->res_pool->hubbub->funcs->init_crb)
|
||||
dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
|
||||
|
||||
// Get DMCUB capabilities
|
||||
if (dc->ctx->dmub_srv) {
|
||||
dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv->dmub);
|
||||
dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
|
||||
}
|
||||
}
|
||||
|
||||
static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
|
||||
int opp_cnt)
|
||||
{
|
||||
bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
|
||||
int flow_ctrl_cnt;
|
||||
|
||||
if (opp_cnt >= 2)
|
||||
hblank_halved = true;
|
||||
|
||||
flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
|
||||
stream->timing.h_border_left -
|
||||
stream->timing.h_border_right;
|
||||
|
||||
if (hblank_halved)
|
||||
flow_ctrl_cnt /= 2;
|
||||
|
||||
/* ODM combine 4:1 case */
|
||||
if (opp_cnt == 4)
|
||||
flow_ctrl_cnt /= 2;
|
||||
|
||||
return flow_ctrl_cnt;
|
||||
}
|
||||
|
||||
static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
|
||||
{
|
||||
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct pipe_ctx *odm_pipe;
|
||||
int opp_cnt = 1;
|
||||
|
||||
ASSERT(dsc);
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
|
||||
opp_cnt++;
|
||||
|
||||
if (enable) {
|
||||
struct dsc_config dsc_cfg;
|
||||
struct dsc_optc_config dsc_optc_cfg;
|
||||
enum optc_dsc_mode optc_dsc_mode;
|
||||
|
||||
/* Enable DSC hw block */
|
||||
dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
|
||||
dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
|
||||
dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
|
||||
dsc_cfg.color_depth = stream->timing.display_color_depth;
|
||||
dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
|
||||
dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
|
||||
ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
|
||||
dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
|
||||
|
||||
dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
|
||||
dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
|
||||
struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
|
||||
|
||||
ASSERT(odm_dsc);
|
||||
odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
|
||||
odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
|
||||
}
|
||||
dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
|
||||
dsc_cfg.pic_width *= opp_cnt;
|
||||
|
||||
optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
|
||||
|
||||
/* Enable DSC in OPTC */
|
||||
DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
|
||||
pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
|
||||
optc_dsc_mode,
|
||||
dsc_optc_cfg.bytes_per_pixel,
|
||||
dsc_optc_cfg.slice_width);
|
||||
} else {
|
||||
/* disable DSC in OPTC */
|
||||
pipe_ctx->stream_res.tg->funcs->set_dsc_config(
|
||||
pipe_ctx->stream_res.tg,
|
||||
OPTC_DSC_DISABLED, 0, 0);
|
||||
|
||||
/* disable DSC block */
|
||||
dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
|
||||
ASSERT(odm_pipe->stream_res.dsc);
|
||||
odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct pipe_ctx *odm_pipe;
|
||||
int opp_cnt = 1;
|
||||
int opp_inst[MAX_PIPES] = { pipe_ctx->stream_res.opp->inst };
|
||||
bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
|
||||
struct mpc_dwb_flow_control flow_control;
|
||||
struct mpc *mpc = dc->res_pool->mpc;
|
||||
int i;
|
||||
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
|
||||
opp_inst[opp_cnt] = odm_pipe->stream_res.opp->inst;
|
||||
opp_cnt++;
|
||||
}
|
||||
|
||||
if (opp_cnt > 1)
|
||||
pipe_ctx->stream_res.tg->funcs->set_odm_combine(
|
||||
pipe_ctx->stream_res.tg,
|
||||
opp_inst, opp_cnt,
|
||||
&pipe_ctx->stream->timing);
|
||||
else
|
||||
pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
|
||||
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
|
||||
|
||||
rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
|
||||
flow_control.flow_ctrl_mode = 0;
|
||||
flow_control.flow_ctrl_cnt0 = 0x80;
|
||||
flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
|
||||
if (mpc->funcs->set_out_rate_control) {
|
||||
for (i = 0; i < opp_cnt; ++i) {
|
||||
mpc->funcs->set_out_rate_control(
|
||||
mpc, opp_inst[i],
|
||||
true,
|
||||
rate_control_2x_pclk,
|
||||
&flow_control);
|
||||
}
|
||||
}
|
||||
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
|
||||
odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
|
||||
odm_pipe->stream_res.opp,
|
||||
true);
|
||||
}
|
||||
|
||||
// Don't program pixel clock after link is already enabled
|
||||
/* if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
|
||||
pipe_ctx->clock_source,
|
||||
&pipe_ctx->stream_res.pix_clk_params,
|
||||
&pipe_ctx->pll_settings)) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
}*/
|
||||
|
||||
if (pipe_ctx->stream_res.dsc)
|
||||
update_dsc_on_stream(pipe_ctx, pipe_ctx->stream->timing.flags.DSC);
|
||||
}
|
||||
|
64
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h
Normal file
64
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2016 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_HWSS_DCN32_H__
|
||||
#define __DC_HWSS_DCN32_H__
|
||||
|
||||
#include "hw_sequencer_private.h"
|
||||
|
||||
struct dc;
|
||||
|
||||
void dcn32_dsc_pg_control(
|
||||
struct dce_hwseq *hws,
|
||||
unsigned int dsc_inst,
|
||||
bool power_on);
|
||||
|
||||
void dcn32_enable_power_gating_plane(
|
||||
struct dce_hwseq *hws,
|
||||
bool enable);
|
||||
|
||||
void dcn32_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
|
||||
|
||||
bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable);
|
||||
|
||||
void dcn32_cab_for_ss_control(struct dc *dc, bool enable);
|
||||
|
||||
void dcn32_commit_subvp_config(struct dc *dc, struct dc_state *context);
|
||||
|
||||
bool dcn32_set_output_transfer_func(struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
const struct dc_stream_state *stream);
|
||||
|
||||
void dcn32_init_hw(struct dc *dc);
|
||||
|
||||
void dcn32_program_mall_pipe_config(struct dc *dc, struct dc_state *context);
|
||||
|
||||
void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context);
|
||||
|
||||
void dcn32_subvp_update_force_pstate(struct dc *dc, struct dc_state *context);
|
||||
|
||||
void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx);
|
||||
|
||||
#endif /* __DC_HWSS_DCN32_H__ */
|
155
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
Normal file
155
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2022 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dce110/dce110_hw_sequencer.h"
|
||||
#include "dcn10/dcn10_hw_sequencer.h"
|
||||
#include "dcn20/dcn20_hwseq.h"
|
||||
#include "dcn21/dcn21_hwseq.h"
|
||||
#include "dcn30/dcn30_hwseq.h"
|
||||
#include "dcn31/dcn31_hwseq.h"
|
||||
#include "dcn32_hwseq.h"
|
||||
|
||||
static const struct hw_sequencer_funcs dcn32_funcs = {
|
||||
.program_gamut_remap = dcn10_program_gamut_remap,
|
||||
.init_hw = dcn32_init_hw,
|
||||
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
|
||||
.apply_ctx_for_surface = NULL,
|
||||
.program_front_end_for_ctx = dcn20_program_front_end_for_ctx,
|
||||
.wait_for_pending_cleared = dcn10_wait_for_pending_cleared,
|
||||
.post_unlock_program_front_end = dcn20_post_unlock_program_front_end,
|
||||
.update_plane_addr = dcn20_update_plane_addr,
|
||||
.update_dchub = dcn10_update_dchub,
|
||||
.update_pending_status = dcn10_update_pending_status,
|
||||
.program_output_csc = dcn20_program_output_csc,
|
||||
.enable_accelerated_mode = dce110_enable_accelerated_mode,
|
||||
.enable_timing_synchronization = dcn10_enable_timing_synchronization,
|
||||
.enable_per_frame_crtc_position_reset = dcn10_enable_per_frame_crtc_position_reset,
|
||||
.update_info_frame = dcn31_update_info_frame,
|
||||
.send_immediate_sdp_message = dcn10_send_immediate_sdp_message,
|
||||
.enable_stream = dcn20_enable_stream,
|
||||
.disable_stream = dce110_disable_stream,
|
||||
.unblank_stream = dcn20_unblank_stream,
|
||||
.blank_stream = dce110_blank_stream,
|
||||
.enable_audio_stream = dce110_enable_audio_stream,
|
||||
.disable_audio_stream = dce110_disable_audio_stream,
|
||||
.disable_plane = dcn20_disable_plane,
|
||||
.pipe_control_lock = dcn20_pipe_control_lock,
|
||||
.interdependent_update_lock = dcn10_lock_all_pipes,
|
||||
.cursor_lock = dcn10_cursor_lock,
|
||||
.prepare_bandwidth = dcn20_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn20_optimize_bandwidth,
|
||||
.update_bandwidth = dcn20_update_bandwidth,
|
||||
.set_drr = dcn10_set_drr,
|
||||
.get_position = dcn10_get_position,
|
||||
.set_static_screen_control = dcn10_set_static_screen_control,
|
||||
.setup_stereo = dcn10_setup_stereo,
|
||||
.set_avmute = dcn30_set_avmute,
|
||||
.log_hw_state = dcn10_log_hw_state,
|
||||
.get_hw_state = dcn10_get_hw_state,
|
||||
.clear_status_bits = dcn10_clear_status_bits,
|
||||
.wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect,
|
||||
.edp_backlight_control = dce110_edp_backlight_control,
|
||||
.edp_power_control = dce110_edp_power_control,
|
||||
.edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
|
||||
.edp_wait_for_T12 = dce110_edp_wait_for_T12,
|
||||
.set_cursor_position = dcn10_set_cursor_position,
|
||||
.set_cursor_attribute = dcn10_set_cursor_attribute,
|
||||
.set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level,
|
||||
.setup_periodic_interrupt = dcn10_setup_periodic_interrupt,
|
||||
.set_clock = dcn10_set_clock,
|
||||
.get_clock = dcn10_get_clock,
|
||||
.program_triplebuffer = dcn20_program_triple_buffer,
|
||||
.enable_writeback = dcn30_enable_writeback,
|
||||
.disable_writeback = dcn30_disable_writeback,
|
||||
.update_writeback = dcn30_update_writeback,
|
||||
.mmhubbub_warmup = dcn30_mmhubbub_warmup,
|
||||
.dmdata_status_done = dcn20_dmdata_status_done,
|
||||
.program_dmdata_engine = dcn30_program_dmdata_engine,
|
||||
.set_dmdata_attributes = dcn20_set_dmdata_attributes,
|
||||
.init_sys_ctx = dcn20_init_sys_ctx,
|
||||
.init_vm_ctx = dcn20_init_vm_ctx,
|
||||
.set_flip_control_gsl = dcn20_set_flip_control_gsl,
|
||||
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
|
||||
.calc_vupdate_position = dcn10_calc_vupdate_position,
|
||||
.apply_idle_power_optimizations = dcn32_apply_idle_power_optimizations,
|
||||
.does_plane_fit_in_mall = dcn30_does_plane_fit_in_mall,
|
||||
.set_backlight_level = dcn21_set_backlight_level,
|
||||
.set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
|
||||
.hardware_release = dcn30_hardware_release,
|
||||
.set_pipe = dcn21_set_pipe,
|
||||
.set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
|
||||
.get_dcc_en_bits = dcn10_get_dcc_en_bits,
|
||||
.commit_subvp_config = dcn32_commit_subvp_config,
|
||||
.update_visual_confirm_color = dcn20_update_visual_confirm_color,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn32_private_funcs = {
|
||||
.init_pipes = dcn10_init_pipes,
|
||||
.update_plane_addr = dcn20_update_plane_addr,
|
||||
.plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
|
||||
.update_mpcc = dcn20_update_mpcc,
|
||||
.set_input_transfer_func = dcn30_set_input_transfer_func,
|
||||
.set_output_transfer_func = dcn32_set_output_transfer_func,
|
||||
.power_down = dce110_power_down,
|
||||
.enable_display_power_gating = dcn10_dummy_display_power_gating,
|
||||
.blank_pixel_data = dcn20_blank_pixel_data,
|
||||
.reset_hw_ctx_wrap = dcn20_reset_hw_ctx_wrap,
|
||||
.enable_stream_timing = dcn20_enable_stream_timing,
|
||||
.edp_backlight_control = dce110_edp_backlight_control,
|
||||
.disable_stream_gating = dcn20_disable_stream_gating,
|
||||
.enable_stream_gating = dcn20_enable_stream_gating,
|
||||
.setup_vupdate_interrupt = dcn20_setup_vupdate_interrupt,
|
||||
.did_underflow_occur = dcn10_did_underflow_occur,
|
||||
.init_blank = dcn20_init_blank,
|
||||
.disable_vga = dcn20_disable_vga,
|
||||
.bios_golden_init = dcn10_bios_golden_init,
|
||||
.plane_atomic_disable = dcn20_plane_atomic_disable,
|
||||
.plane_atomic_power_down = dcn10_plane_atomic_power_down,
|
||||
.enable_power_gating_plane = dcn32_enable_power_gating_plane,
|
||||
.hubp_pg_control = dcn32_hubp_pg_control,
|
||||
.program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree,
|
||||
.update_odm = dcn32_update_odm,
|
||||
.dsc_pg_control = dcn32_dsc_pg_control,
|
||||
.set_hdr_multiplier = dcn10_set_hdr_multiplier,
|
||||
.verify_allow_pstate_change_high = dcn10_verify_allow_pstate_change_high,
|
||||
.wait_for_blank_complete = dcn20_wait_for_blank_complete,
|
||||
.dccg_init = dcn20_dccg_init,
|
||||
.set_blend_lut = dcn30_set_blend_lut,
|
||||
.set_shaper_3dlut = dcn20_set_shaper_3dlut,
|
||||
.program_mall_pipe_config = dcn32_program_mall_pipe_config,
|
||||
.subvp_update_force_pstate = dcn32_subvp_update_force_pstate,
|
||||
.update_mall_sel = dcn32_update_mall_sel,
|
||||
};
|
||||
|
||||
void dcn32_hw_sequencer_init_functions(struct dc *dc)
|
||||
{
|
||||
dc->hwss = dcn32_funcs;
|
||||
dc->hwseq->funcs = dcn32_private_funcs;
|
||||
|
||||
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
dc->hwss.init_hw = dcn20_fpga_init_hw;
|
||||
dc->hwseq->funcs.init_pipes = NULL;
|
||||
}
|
||||
}
|
33
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.h
Normal file
33
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2022 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_DCN32_INIT_H__
|
||||
#define __DC_DCN32_INIT_H__
|
||||
|
||||
struct dc;
|
||||
|
||||
void dcn32_hw_sequencer_init_functions(struct dc *dc);
|
||||
|
||||
#endif /* __DC_DCN32_INIT_H__ */
|
239
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mmhubbub.c
Normal file
239
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mmhubbub.c
Normal file
@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright 2022 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "reg_helper.h"
|
||||
#include "resource.h"
|
||||
#include "mcif_wb.h"
|
||||
#include "dcn32_mmhubbub.h"
|
||||
|
||||
|
||||
#define REG(reg)\
|
||||
mcif_wb30->mcif_wb_regs->reg
|
||||
|
||||
#define CTX \
|
||||
mcif_wb30->base.ctx
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
mcif_wb30->mcif_wb_shift->field_name, mcif_wb30->mcif_wb_mask->field_name
|
||||
|
||||
#define MCIF_ADDR(addr) (((unsigned long long)addr & 0xffffffffff) + 0xFE) >> 8
|
||||
#define MCIF_ADDR_HIGH(addr) (unsigned long long)addr >> 40
|
||||
|
||||
/* wbif programming guide:
|
||||
* 1. set up wbif parameter:
|
||||
* unsigned long long luma_address[4]; //4 frame buffer
|
||||
* unsigned long long chroma_address[4];
|
||||
* unsigned int luma_pitch;
|
||||
* unsigned int chroma_pitch;
|
||||
* unsigned int warmup_pitch=0x10; //256B align, the page size is 4KB when it is 0x10
|
||||
* unsigned int slice_lines; //slice size
|
||||
* unsigned int time_per_pixel; // time per pixel, in ns
|
||||
* unsigned int arbitration_slice; // 0: 2048 bytes 1: 4096 bytes 2: 8192 Bytes
|
||||
* unsigned int max_scaled_time; // used for QOS generation
|
||||
* unsigned int swlock=0x0;
|
||||
* unsigned int cli_watermark[4]; //4 group urgent watermark
|
||||
* unsigned int pstate_watermark[4]; //4 group pstate watermark
|
||||
* unsigned int sw_int_en; // Software interrupt enable, frame end and overflow
|
||||
* unsigned int sw_slice_int_en; // slice end interrupt enable
|
||||
* unsigned int sw_overrun_int_en; // overrun error interrupt enable
|
||||
* unsigned int vce_int_en; // VCE interrupt enable, frame end and overflow
|
||||
* unsigned int vce_slice_int_en; // VCE slice end interrupt enable, frame end and overflow
|
||||
*
|
||||
* 2. configure wbif register
|
||||
* a. call mmhubbub_config_wbif()
|
||||
*
|
||||
* 3. Enable wbif
|
||||
* call set_wbif_bufmgr_enable();
|
||||
*
|
||||
* 4. wbif_dump_status(), option, for debug purpose
|
||||
* the bufmgr status can show the progress of write back, can be used for debug purpose
|
||||
*/
|
||||
|
||||
static void mmhubbub32_warmup_mcif(struct mcif_wb *mcif_wb,
|
||||
struct mcif_warmup_params *params)
|
||||
{
|
||||
struct dcn30_mmhubbub *mcif_wb30 = TO_DCN30_MMHUBBUB(mcif_wb);
|
||||
union large_integer start_address_shift = {.quad_part = params->start_address.quad_part >> 5};
|
||||
|
||||
/* Set base address and region size for warmup */
|
||||
REG_SET(MMHUBBUB_WARMUP_BASE_ADDR_HIGH, 0, MMHUBBUB_WARMUP_BASE_ADDR_HIGH, start_address_shift.high_part);
|
||||
REG_SET(MMHUBBUB_WARMUP_BASE_ADDR_LOW, 0, MMHUBBUB_WARMUP_BASE_ADDR_LOW, start_address_shift.low_part);
|
||||
REG_SET(MMHUBBUB_WARMUP_ADDR_REGION, 0, MMHUBBUB_WARMUP_ADDR_REGION, params->region_size >> 5);
|
||||
// REG_SET(MMHUBBUB_WARMUP_P_VMID, 0, MMHUBBUB_WARMUP_P_VMID, params->p_vmid);
|
||||
|
||||
/* Set address increment and enable warmup */
|
||||
REG_SET_3(MMHUBBUB_WARMUP_CONTROL_STATUS, 0, MMHUBBUB_WARMUP_EN, true,
|
||||
MMHUBBUB_WARMUP_SW_INT_EN, true,
|
||||
MMHUBBUB_WARMUP_INC_ADDR, params->address_increment >> 5);
|
||||
|
||||
/* Wait for an interrupt to signal warmup is completed */
|
||||
REG_WAIT(MMHUBBUB_WARMUP_CONTROL_STATUS, MMHUBBUB_WARMUP_SW_INT_STATUS, 1, 20, 100);
|
||||
|
||||
/* Acknowledge interrupt */
|
||||
REG_UPDATE(MMHUBBUB_WARMUP_CONTROL_STATUS, MMHUBBUB_WARMUP_SW_INT_ACK, 1);
|
||||
|
||||
/* Disable warmup */
|
||||
REG_UPDATE(MMHUBBUB_WARMUP_CONTROL_STATUS, MMHUBBUB_WARMUP_EN, false);
|
||||
}
|
||||
|
||||
void mmhubbub32_config_mcif_buf(struct mcif_wb *mcif_wb,
|
||||
struct mcif_buf_params *params,
|
||||
unsigned int dest_height)
|
||||
{
|
||||
struct dcn30_mmhubbub *mcif_wb30 = TO_DCN30_MMHUBBUB(mcif_wb);
|
||||
|
||||
/* buffer address for packing mode or Luma in planar mode */
|
||||
REG_UPDATE(MCIF_WB_BUF_1_ADDR_Y, MCIF_WB_BUF_1_ADDR_Y, MCIF_ADDR(params->luma_address[0]));
|
||||
REG_UPDATE(MCIF_WB_BUF_1_ADDR_Y_HIGH, MCIF_WB_BUF_1_ADDR_Y_HIGH, MCIF_ADDR_HIGH(params->luma_address[0]));
|
||||
|
||||
/* buffer address for Chroma in planar mode (unused in packing mode) */
|
||||
REG_UPDATE(MCIF_WB_BUF_1_ADDR_C, MCIF_WB_BUF_1_ADDR_C, MCIF_ADDR(params->chroma_address[0]));
|
||||
REG_UPDATE(MCIF_WB_BUF_1_ADDR_C_HIGH, MCIF_WB_BUF_1_ADDR_C_HIGH, MCIF_ADDR_HIGH(params->chroma_address[0]));
|
||||
|
||||
/* buffer address for packing mode or Luma in planar mode */
|
||||
REG_UPDATE(MCIF_WB_BUF_2_ADDR_Y, MCIF_WB_BUF_2_ADDR_Y, MCIF_ADDR(params->luma_address[1]));
|
||||
REG_UPDATE(MCIF_WB_BUF_2_ADDR_Y_HIGH, MCIF_WB_BUF_2_ADDR_Y_HIGH, MCIF_ADDR_HIGH(params->luma_address[1]));
|
||||
|
||||
/* buffer address for Chroma in planar mode (unused in packing mode) */
|
||||
REG_UPDATE(MCIF_WB_BUF_2_ADDR_C, MCIF_WB_BUF_2_ADDR_C, MCIF_ADDR(params->chroma_address[1]));
|
||||
REG_UPDATE(MCIF_WB_BUF_2_ADDR_C_HIGH, MCIF_WB_BUF_2_ADDR_C_HIGH, MCIF_ADDR_HIGH(params->chroma_address[1]));
|
||||
|
||||
/* buffer address for packing mode or Luma in planar mode */
|
||||
REG_UPDATE(MCIF_WB_BUF_3_ADDR_Y, MCIF_WB_BUF_3_ADDR_Y, MCIF_ADDR(params->luma_address[2]));
|
||||
REG_UPDATE(MCIF_WB_BUF_3_ADDR_Y_HIGH, MCIF_WB_BUF_3_ADDR_Y_HIGH, MCIF_ADDR_HIGH(params->luma_address[2]));
|
||||
|
||||
/* buffer address for Chroma in planar mode (unused in packing mode) */
|
||||
REG_UPDATE(MCIF_WB_BUF_3_ADDR_C, MCIF_WB_BUF_3_ADDR_C, MCIF_ADDR(params->chroma_address[2]));
|
||||
REG_UPDATE(MCIF_WB_BUF_3_ADDR_C_HIGH, MCIF_WB_BUF_3_ADDR_C_HIGH, MCIF_ADDR_HIGH(params->chroma_address[2]));
|
||||
|
||||
/* buffer address for packing mode or Luma in planar mode */
|
||||
REG_UPDATE(MCIF_WB_BUF_4_ADDR_Y, MCIF_WB_BUF_4_ADDR_Y, MCIF_ADDR(params->luma_address[3]));
|
||||
REG_UPDATE(MCIF_WB_BUF_4_ADDR_Y_HIGH, MCIF_WB_BUF_4_ADDR_Y_HIGH, MCIF_ADDR_HIGH(params->luma_address[3]));
|
||||
|
||||
/* buffer address for Chroma in planar mode (unused in packing mode) */
|
||||
REG_UPDATE(MCIF_WB_BUF_4_ADDR_C, MCIF_WB_BUF_4_ADDR_C, MCIF_ADDR(params->chroma_address[3]));
|
||||
REG_UPDATE(MCIF_WB_BUF_4_ADDR_C_HIGH, MCIF_WB_BUF_4_ADDR_C_HIGH, MCIF_ADDR_HIGH(params->chroma_address[3]));
|
||||
|
||||
/* setup luma & chroma size
|
||||
* should be enough to contain a whole frame Luma data,
|
||||
* the programmed value is frame buffer size [27:8], 256-byte aligned
|
||||
*/
|
||||
REG_UPDATE(MCIF_WB_BUF_LUMA_SIZE, MCIF_WB_BUF_LUMA_SIZE, (params->luma_pitch>>8) * dest_height);
|
||||
REG_UPDATE(MCIF_WB_BUF_CHROMA_SIZE, MCIF_WB_BUF_CHROMA_SIZE, (params->chroma_pitch>>8) * dest_height);
|
||||
|
||||
/* enable address fence */
|
||||
REG_UPDATE(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUF_ADDR_FENCE_EN, 1);
|
||||
|
||||
/* setup pitch, the programmed value is [15:8], 256B align */
|
||||
REG_UPDATE_2(MCIF_WB_BUF_PITCH, MCIF_WB_BUF_LUMA_PITCH, params->luma_pitch >> 8,
|
||||
MCIF_WB_BUF_CHROMA_PITCH, params->chroma_pitch >> 8);
|
||||
}
|
||||
|
||||
static void mmhubbub32_config_mcif_arb(struct mcif_wb *mcif_wb,
|
||||
struct mcif_arb_params *params)
|
||||
{
|
||||
struct dcn30_mmhubbub *mcif_wb30 = TO_DCN30_MMHUBBUB(mcif_wb);
|
||||
|
||||
/* Programmed by the video driver based on the CRTC timing (for DWB) */
|
||||
REG_UPDATE(MCIF_WB_ARBITRATION_CONTROL, MCIF_WB_TIME_PER_PIXEL, params->time_per_pixel);
|
||||
|
||||
/* Programming dwb watermark */
|
||||
/* Watermark to generate urgent in MCIF_WB_CLI, value is determined by MCIF_WB_CLI_WATERMARK_MASK. */
|
||||
/* Program in ns. A formula will be provided in the pseudo code to calculate the value. */
|
||||
REG_UPDATE(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK_MASK, 0x0);
|
||||
/* urgent_watermarkA */
|
||||
REG_UPDATE(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK, params->cli_watermark[0]);
|
||||
REG_UPDATE(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK_MASK, 0x1);
|
||||
/* urgent_watermarkB */
|
||||
REG_UPDATE(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK, params->cli_watermark[1]);
|
||||
REG_UPDATE(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK_MASK, 0x2);
|
||||
/* urgent_watermarkC */
|
||||
REG_UPDATE(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK, params->cli_watermark[2]);
|
||||
REG_UPDATE(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK_MASK, 0x3);
|
||||
/* urgent_watermarkD */
|
||||
REG_UPDATE(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK, params->cli_watermark[3]);
|
||||
|
||||
/* Programming nb pstate watermark */
|
||||
/* nbp_state_change_watermarkA */
|
||||
REG_UPDATE(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK, NB_PSTATE_CHANGE_WATERMARK_MASK, 0x0);
|
||||
REG_UPDATE(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK,
|
||||
NB_PSTATE_CHANGE_REFRESH_WATERMARK, params->pstate_watermark[0]);
|
||||
/* nbp_state_change_watermarkB */
|
||||
REG_UPDATE(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK, NB_PSTATE_CHANGE_WATERMARK_MASK, 0x1);
|
||||
REG_UPDATE(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK,
|
||||
NB_PSTATE_CHANGE_REFRESH_WATERMARK, params->pstate_watermark[1]);
|
||||
/* nbp_state_change_watermarkC */
|
||||
REG_UPDATE(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK, NB_PSTATE_CHANGE_WATERMARK_MASK, 0x2);
|
||||
REG_UPDATE(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK,
|
||||
NB_PSTATE_CHANGE_REFRESH_WATERMARK, params->pstate_watermark[2]);
|
||||
/* nbp_state_change_watermarkD */
|
||||
REG_UPDATE(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK, NB_PSTATE_CHANGE_WATERMARK_MASK, 0x3);
|
||||
REG_UPDATE(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK,
|
||||
NB_PSTATE_CHANGE_REFRESH_WATERMARK, params->pstate_watermark[3]);
|
||||
|
||||
/* dram_speed_change_duration - register removed */
|
||||
//REG_UPDATE(MCIF_WB_DRAM_SPEED_CHANGE_DURATION_VBI,
|
||||
// MCIF_WB_DRAM_SPEED_CHANGE_DURATION_VBI, params->dram_speed_change_duration);
|
||||
|
||||
/* max_scaled_time */
|
||||
REG_UPDATE(MULTI_LEVEL_QOS_CTRL, MAX_SCALED_TIME_TO_URGENT, params->max_scaled_time);
|
||||
|
||||
/* slice_lines */
|
||||
REG_UPDATE(MCIF_WB_BUFMGR_VCE_CONTROL, MCIF_WB_BUFMGR_SLICE_SIZE, params->slice_lines-1);
|
||||
|
||||
/* Set arbitration unit for Luma/Chroma */
|
||||
/* arb_unit=2 should be chosen for more efficiency */
|
||||
/* Arbitration size, 0: 2048 bytes 1: 4096 bytes 2: 8192 Bytes */
|
||||
REG_UPDATE(MCIF_WB_ARBITRATION_CONTROL, MCIF_WB_CLIENT_ARBITRATION_SLICE, params->arbitration_slice);
|
||||
}
|
||||
|
||||
const struct mcif_wb_funcs dcn32_mmhubbub_funcs = {
|
||||
.warmup_mcif = mmhubbub32_warmup_mcif,
|
||||
.enable_mcif = mmhubbub2_enable_mcif,
|
||||
.disable_mcif = mmhubbub2_disable_mcif,
|
||||
.config_mcif_buf = mmhubbub32_config_mcif_buf,
|
||||
.config_mcif_arb = mmhubbub32_config_mcif_arb,
|
||||
.config_mcif_irq = mmhubbub2_config_mcif_irq,
|
||||
.dump_frame = mcifwb2_dump_frame,
|
||||
};
|
||||
|
||||
void dcn32_mmhubbub_construct(struct dcn30_mmhubbub *mcif_wb30,
|
||||
struct dc_context *ctx,
|
||||
const struct dcn30_mmhubbub_registers *mcif_wb_regs,
|
||||
const struct dcn30_mmhubbub_shift *mcif_wb_shift,
|
||||
const struct dcn30_mmhubbub_mask *mcif_wb_mask,
|
||||
int inst)
|
||||
{
|
||||
mcif_wb30->base.ctx = ctx;
|
||||
|
||||
mcif_wb30->base.inst = inst;
|
||||
mcif_wb30->base.funcs = &dcn32_mmhubbub_funcs;
|
||||
|
||||
mcif_wb30->mcif_wb_regs = mcif_wb_regs;
|
||||
mcif_wb30->mcif_wb_shift = mcif_wb_shift;
|
||||
mcif_wb30->mcif_wb_mask = mcif_wb_mask;
|
||||
}
|
225
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mmhubbub.h
Normal file
225
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mmhubbub.h
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_MCIF_WB_DCN32_H__
|
||||
#define __DC_MCIF_WB_DCN32_H__
|
||||
|
||||
#include "dcn20/dcn20_mmhubbub.h"
|
||||
#include "dcn30/dcn30_mmhubbub.h"
|
||||
|
||||
#define MCIF_WB_COMMON_REG_LIST_DCN32(inst) \
|
||||
SRI2(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUFMGR_STATUS, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_PITCH, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_1_STATUS, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_1_STATUS2, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_2_STATUS, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_2_STATUS2, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_3_STATUS, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_3_STATUS2, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_4_STATUS, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_4_STATUS2, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_ARBITRATION_CONTROL, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_SCLK_CHANGE, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_TEST_DEBUG_INDEX, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_TEST_DEBUG_DATA, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_1_ADDR_Y, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_1_ADDR_C, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_2_ADDR_Y, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_2_ADDR_C, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_3_ADDR_Y, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_3_ADDR_C, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_4_ADDR_Y, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_4_ADDR_C, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUFMGR_VCE_CONTROL, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK, MMHUBBUB, inst),\
|
||||
SRI2(MCIF_WB_NB_PSTATE_CONTROL, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_WATERMARK, MMHUBBUB, inst),\
|
||||
SRI2(MCIF_WB_CLOCK_GATER_CONTROL, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_SELF_REFRESH_CONTROL, MCIF_WB, inst),\
|
||||
SRI2(MULTI_LEVEL_QOS_CTRL, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_SECURITY_LEVEL, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_LUMA_SIZE, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_CHROMA_SIZE, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_1_ADDR_Y_HIGH, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_1_ADDR_C_HIGH, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_2_ADDR_Y_HIGH, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_2_ADDR_C_HIGH, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_3_ADDR_Y_HIGH, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_3_ADDR_C_HIGH, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_4_ADDR_Y_HIGH, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_4_ADDR_C_HIGH, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_1_RESOLUTION, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_2_RESOLUTION, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_3_RESOLUTION, MCIF_WB, inst),\
|
||||
SRI2(MCIF_WB_BUF_4_RESOLUTION, MCIF_WB, inst),\
|
||||
SRI2(MMHUBBUB_MEM_PWR_CNTL, MMHUBBUB, inst),\
|
||||
SRI2(MMHUBBUB_WARMUP_ADDR_REGION, MMHUBBUB, inst),\
|
||||
SRI2(MMHUBBUB_WARMUP_BASE_ADDR_HIGH, MMHUBBUB, inst),\
|
||||
SRI2(MMHUBBUB_WARMUP_BASE_ADDR_LOW, MMHUBBUB, inst),\
|
||||
SRI2(MMHUBBUB_WARMUP_CONTROL_STATUS, MMHUBBUB, inst)
|
||||
|
||||
|
||||
#define MCIF_WB_COMMON_MASK_SH_LIST_DCN32(mask_sh) \
|
||||
SF(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_ENABLE, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_INT_EN, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_INT_ACK, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_SLICE_INT_EN, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_OVERRUN_INT_EN, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_LOCK, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUF_ADDR_FENCE_EN, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_STATUS, MCIF_WB_BUFMGR_VCE_INT_STATUS, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_STATUS, MCIF_WB_BUFMGR_SW_INT_STATUS, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_STATUS, MCIF_WB_BUFMGR_SW_OVERRUN_INT_STATUS, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_STATUS, MCIF_WB_BUFMGR_CUR_BUF, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_STATUS, MCIF_WB_BUFMGR_BUFTAG, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_STATUS, MCIF_WB_BUFMGR_CUR_LINE_L, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_STATUS, MCIF_WB_BUFMGR_NEXT_BUF, mask_sh),\
|
||||
SF(MCIF_WB_BUF_PITCH, MCIF_WB_BUF_LUMA_PITCH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_PITCH, MCIF_WB_BUF_CHROMA_PITCH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS, MCIF_WB_BUF_1_ACTIVE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS, MCIF_WB_BUF_1_SW_LOCKED, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS, MCIF_WB_BUF_1_VCE_LOCKED, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS, MCIF_WB_BUF_1_OVERFLOW, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS, MCIF_WB_BUF_1_DISABLE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS, MCIF_WB_BUF_1_MODE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS, MCIF_WB_BUF_1_BUFTAG, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS, MCIF_WB_BUF_1_NXT_BUF, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS, MCIF_WB_BUF_1_CUR_LINE_L, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS2, MCIF_WB_BUF_1_NEW_CONTENT, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS2, MCIF_WB_BUF_1_COLOR_DEPTH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS2, MCIF_WB_BUF_1_TMZ_BLACK_PIXEL, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS2, MCIF_WB_BUF_1_TMZ, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS2, MCIF_WB_BUF_1_Y_OVERRUN, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_STATUS2, MCIF_WB_BUF_1_C_OVERRUN, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS, MCIF_WB_BUF_2_ACTIVE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS, MCIF_WB_BUF_2_SW_LOCKED, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS, MCIF_WB_BUF_2_VCE_LOCKED, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS, MCIF_WB_BUF_2_OVERFLOW, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS, MCIF_WB_BUF_2_DISABLE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS, MCIF_WB_BUF_2_MODE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS, MCIF_WB_BUF_2_BUFTAG, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS, MCIF_WB_BUF_2_NXT_BUF, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS, MCIF_WB_BUF_2_CUR_LINE_L, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS2, MCIF_WB_BUF_2_NEW_CONTENT, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS2, MCIF_WB_BUF_2_COLOR_DEPTH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS2, MCIF_WB_BUF_2_TMZ_BLACK_PIXEL, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS2, MCIF_WB_BUF_2_TMZ, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS2, MCIF_WB_BUF_2_Y_OVERRUN, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_STATUS2, MCIF_WB_BUF_2_C_OVERRUN, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS, MCIF_WB_BUF_3_ACTIVE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS, MCIF_WB_BUF_3_SW_LOCKED, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS, MCIF_WB_BUF_3_VCE_LOCKED, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS, MCIF_WB_BUF_3_OVERFLOW, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS, MCIF_WB_BUF_3_DISABLE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS, MCIF_WB_BUF_3_MODE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS, MCIF_WB_BUF_3_BUFTAG, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS, MCIF_WB_BUF_3_NXT_BUF, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS, MCIF_WB_BUF_3_CUR_LINE_L, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS2, MCIF_WB_BUF_3_NEW_CONTENT, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS2, MCIF_WB_BUF_3_COLOR_DEPTH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS2, MCIF_WB_BUF_3_TMZ_BLACK_PIXEL, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS2, MCIF_WB_BUF_3_TMZ, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS2, MCIF_WB_BUF_3_Y_OVERRUN, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_STATUS2, MCIF_WB_BUF_3_C_OVERRUN, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS, MCIF_WB_BUF_4_ACTIVE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS, MCIF_WB_BUF_4_SW_LOCKED, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS, MCIF_WB_BUF_4_VCE_LOCKED, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS, MCIF_WB_BUF_4_OVERFLOW, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS, MCIF_WB_BUF_4_DISABLE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS, MCIF_WB_BUF_4_MODE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS, MCIF_WB_BUF_4_BUFTAG, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS, MCIF_WB_BUF_4_NXT_BUF, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS, MCIF_WB_BUF_4_CUR_LINE_L, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS2, MCIF_WB_BUF_4_NEW_CONTENT, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS2, MCIF_WB_BUF_4_COLOR_DEPTH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS2, MCIF_WB_BUF_4_TMZ_BLACK_PIXEL, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS2, MCIF_WB_BUF_4_TMZ, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS2, MCIF_WB_BUF_4_Y_OVERRUN, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_STATUS2, MCIF_WB_BUF_4_C_OVERRUN, mask_sh),\
|
||||
SF(MCIF_WB_ARBITRATION_CONTROL, MCIF_WB_CLIENT_ARBITRATION_SLICE, mask_sh),\
|
||||
SF(MCIF_WB_ARBITRATION_CONTROL, MCIF_WB_TIME_PER_PIXEL, mask_sh),\
|
||||
SF(MCIF_WB_SCLK_CHANGE, WM_CHANGE_ACK_FORCE_ON, mask_sh),\
|
||||
SF(MCIF_WB_TEST_DEBUG_INDEX, MCIF_WB_TEST_DEBUG_INDEX, mask_sh),\
|
||||
SF(MCIF_WB_TEST_DEBUG_DATA, MCIF_WB_TEST_DEBUG_DATA, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_ADDR_Y, MCIF_WB_BUF_1_ADDR_Y, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_ADDR_C, MCIF_WB_BUF_1_ADDR_C, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_ADDR_Y, MCIF_WB_BUF_2_ADDR_Y, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_ADDR_C, MCIF_WB_BUF_2_ADDR_C, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_ADDR_Y, MCIF_WB_BUF_3_ADDR_Y, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_ADDR_C, MCIF_WB_BUF_3_ADDR_C, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_ADDR_Y, MCIF_WB_BUF_4_ADDR_Y, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_ADDR_C, MCIF_WB_BUF_4_ADDR_C, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_VCE_CONTROL, MCIF_WB_BUFMGR_VCE_LOCK_IGNORE, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_VCE_CONTROL, MCIF_WB_BUFMGR_VCE_INT_EN, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_VCE_CONTROL, MCIF_WB_BUFMGR_VCE_INT_ACK, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_VCE_CONTROL, MCIF_WB_BUFMGR_VCE_SLICE_INT_EN, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_VCE_CONTROL, MCIF_WB_BUFMGR_VCE_LOCK, mask_sh),\
|
||||
SF(MCIF_WB_BUFMGR_VCE_CONTROL, MCIF_WB_BUFMGR_SLICE_SIZE, mask_sh),\
|
||||
SF(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK, NB_PSTATE_CHANGE_REFRESH_WATERMARK, mask_sh),\
|
||||
SF(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK, NB_PSTATE_CHANGE_WATERMARK_MASK, mask_sh),\
|
||||
SF(MCIF_WB_NB_PSTATE_CONTROL, NB_PSTATE_CHANGE_FORCE_ON, mask_sh),\
|
||||
SF(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK, mask_sh),\
|
||||
SF(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK_MASK, mask_sh),\
|
||||
SF(MCIF_WB_CLOCK_GATER_CONTROL, MCIF_WB_CLI_CLOCK_GATER_OVERRIDE, mask_sh),\
|
||||
SF(MCIF_WB_SELF_REFRESH_CONTROL, PERFRAME_SELF_REFRESH, mask_sh),\
|
||||
SF(MULTI_LEVEL_QOS_CTRL, MAX_SCALED_TIME_TO_URGENT, mask_sh),\
|
||||
SF(MCIF_WB_SECURITY_LEVEL, MCIF_WB_SECURITY_LEVEL, mask_sh),\
|
||||
SF(MCIF_WB_BUF_LUMA_SIZE, MCIF_WB_BUF_LUMA_SIZE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_CHROMA_SIZE, MCIF_WB_BUF_CHROMA_SIZE, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_ADDR_Y_HIGH, MCIF_WB_BUF_1_ADDR_Y_HIGH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_ADDR_C_HIGH, MCIF_WB_BUF_1_ADDR_C_HIGH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_ADDR_Y_HIGH, MCIF_WB_BUF_2_ADDR_Y_HIGH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_ADDR_C_HIGH, MCIF_WB_BUF_2_ADDR_C_HIGH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_ADDR_Y_HIGH, MCIF_WB_BUF_3_ADDR_Y_HIGH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_ADDR_C_HIGH, MCIF_WB_BUF_3_ADDR_C_HIGH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_ADDR_Y_HIGH, MCIF_WB_BUF_4_ADDR_Y_HIGH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_ADDR_C_HIGH, MCIF_WB_BUF_4_ADDR_C_HIGH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_RESOLUTION, MCIF_WB_BUF_1_RESOLUTION_WIDTH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_1_RESOLUTION, MCIF_WB_BUF_1_RESOLUTION_HEIGHT, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_RESOLUTION, MCIF_WB_BUF_2_RESOLUTION_WIDTH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_2_RESOLUTION, MCIF_WB_BUF_2_RESOLUTION_HEIGHT, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_RESOLUTION, MCIF_WB_BUF_3_RESOLUTION_WIDTH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_3_RESOLUTION, MCIF_WB_BUF_3_RESOLUTION_HEIGHT, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_RESOLUTION, MCIF_WB_BUF_4_RESOLUTION_WIDTH, mask_sh),\
|
||||
SF(MCIF_WB_BUF_4_RESOLUTION, MCIF_WB_BUF_4_RESOLUTION_HEIGHT, mask_sh),\
|
||||
SF(MMHUBBUB_WARMUP_ADDR_REGION, MMHUBBUB_WARMUP_ADDR_REGION, mask_sh),\
|
||||
SF(MMHUBBUB_WARMUP_BASE_ADDR_HIGH, MMHUBBUB_WARMUP_BASE_ADDR_HIGH, mask_sh),\
|
||||
SF(MMHUBBUB_WARMUP_BASE_ADDR_LOW, MMHUBBUB_WARMUP_BASE_ADDR_LOW, mask_sh),\
|
||||
SF(MMHUBBUB_WARMUP_CONTROL_STATUS, MMHUBBUB_WARMUP_EN, mask_sh),\
|
||||
SF(MMHUBBUB_WARMUP_CONTROL_STATUS, MMHUBBUB_WARMUP_SW_INT_EN, mask_sh),\
|
||||
SF(MMHUBBUB_WARMUP_CONTROL_STATUS, MMHUBBUB_WARMUP_SW_INT_STATUS, mask_sh),\
|
||||
SF(MMHUBBUB_WARMUP_CONTROL_STATUS, MMHUBBUB_WARMUP_SW_INT_ACK, mask_sh),\
|
||||
SF(MMHUBBUB_WARMUP_CONTROL_STATUS, MMHUBBUB_WARMUP_INC_ADDR, mask_sh)
|
||||
|
||||
|
||||
void dcn32_mmhubbub_construct(struct dcn30_mmhubbub *mcif_wb30,
|
||||
struct dc_context *ctx,
|
||||
const struct dcn30_mmhubbub_registers *mcif_wb_regs,
|
||||
const struct dcn30_mmhubbub_shift *mcif_wb_shift,
|
||||
const struct dcn30_mmhubbub_mask *mcif_wb_mask,
|
||||
int inst);
|
||||
|
||||
#endif //__DC_MCIF_WB_DCN32_H__
|
810
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
Normal file
810
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
Normal file
@ -0,0 +1,810 @@
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "reg_helper.h"
|
||||
#include "dcn30/dcn30_mpc.h"
|
||||
#include "dcn30/dcn30_cm_common.h"
|
||||
#include "dcn30/dcn30_mpc.h"
|
||||
#include "basics/conversion.h"
|
||||
#include "dcn10/dcn10_cm_common.h"
|
||||
#include "dc.h"
|
||||
|
||||
#define REG(reg)\
|
||||
mpc30->mpc_regs->reg
|
||||
|
||||
#define CTX \
|
||||
mpc30->base.ctx
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
mpc30->mpc_shift->field_name, mpc30->mpc_mask->field_name
|
||||
|
||||
|
||||
static void mpc32_mpc_init(struct mpc *mpc)
|
||||
{
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
int mpcc_id;
|
||||
|
||||
mpc1_mpc_init(mpc);
|
||||
|
||||
if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
|
||||
if (mpc30->mpc_mask->MPCC_MCM_SHAPER_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPCC_MCM_3DLUT_MEM_LOW_PWR_MODE) {
|
||||
for (mpcc_id = 0; mpcc_id < mpc30->num_mpcc; mpcc_id++) {
|
||||
REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_LOW_PWR_MODE, 3);
|
||||
REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_LOW_PWR_MODE, 3);
|
||||
REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_LOW_PWR_MODE, 3);
|
||||
}
|
||||
}
|
||||
if (mpc30->mpc_mask->MPCC_OGAM_MEM_LOW_PWR_MODE) {
|
||||
for (mpcc_id = 0; mpcc_id < mpc30->num_mpcc; mpcc_id++)
|
||||
REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_LOW_PWR_MODE, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static enum dc_lut_mode mpc32_get_shaper_current(struct mpc *mpc, uint32_t mpcc_id)
|
||||
{
|
||||
enum dc_lut_mode mode;
|
||||
uint32_t state_mode;
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
|
||||
REG_GET(MPCC_MCM_SHAPER_CONTROL[mpcc_id],
|
||||
MPCC_MCM_SHAPER_MODE_CURRENT, &state_mode);
|
||||
|
||||
switch (state_mode) {
|
||||
case 0:
|
||||
mode = LUT_BYPASS;
|
||||
break;
|
||||
case 1:
|
||||
mode = LUT_RAM_A;
|
||||
break;
|
||||
case 2:
|
||||
mode = LUT_RAM_B;
|
||||
break;
|
||||
default:
|
||||
mode = LUT_BYPASS;
|
||||
break;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
||||
static void mpc32_configure_shaper_lut(
|
||||
struct mpc *mpc,
|
||||
bool is_ram_a,
|
||||
uint32_t mpcc_id)
|
||||
{
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
|
||||
REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id],
|
||||
MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK, 7);
|
||||
REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id],
|
||||
MPCC_MCM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
|
||||
REG_SET(MPCC_MCM_SHAPER_LUT_INDEX[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_INDEX, 0);
|
||||
}
|
||||
|
||||
|
||||
static void mpc32_program_shaper_luta_settings(
|
||||
struct mpc *mpc,
|
||||
const struct pwl_params *params,
|
||||
uint32_t mpcc_id)
|
||||
{
|
||||
const struct gamma_curve *curve;
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
|
||||
REG_SET_2(MPCC_MCM_SHAPER_RAMA_START_CNTL_B[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
|
||||
REG_SET_2(MPCC_MCM_SHAPER_RAMA_START_CNTL_G[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
|
||||
REG_SET_2(MPCC_MCM_SHAPER_RAMA_START_CNTL_R[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
|
||||
|
||||
REG_SET_2(MPCC_MCM_SHAPER_RAMA_END_CNTL_B[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
|
||||
REG_SET_2(MPCC_MCM_SHAPER_RAMA_END_CNTL_G[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y);
|
||||
REG_SET_2(MPCC_MCM_SHAPER_RAMA_END_CNTL_R[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y);
|
||||
|
||||
curve = params->arr_curve_points;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_0_1[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_2_3[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_4_5[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_6_7[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_8_9[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_10_11[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_12_13[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_14_15[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_16_17[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_18_19[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_20_21[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_22_23[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_24_25[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_26_27[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_28_29[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_30_31[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_32_33[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
}
|
||||
|
||||
|
||||
static void mpc32_program_shaper_lutb_settings(
|
||||
struct mpc *mpc,
|
||||
const struct pwl_params *params,
|
||||
uint32_t mpcc_id)
|
||||
{
|
||||
const struct gamma_curve *curve;
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
|
||||
REG_SET_2(MPCC_MCM_SHAPER_RAMB_START_CNTL_B[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
|
||||
REG_SET_2(MPCC_MCM_SHAPER_RAMB_START_CNTL_G[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
|
||||
REG_SET_2(MPCC_MCM_SHAPER_RAMB_START_CNTL_R[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
|
||||
|
||||
REG_SET_2(MPCC_MCM_SHAPER_RAMB_END_CNTL_B[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
|
||||
REG_SET_2(MPCC_MCM_SHAPER_RAMB_END_CNTL_G[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y);
|
||||
REG_SET_2(MPCC_MCM_SHAPER_RAMB_END_CNTL_R[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y);
|
||||
|
||||
curve = params->arr_curve_points;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_0_1[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_2_3[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_4_5[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_6_7[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_8_9[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_10_11[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_12_13[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_14_15[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_16_17[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_18_19[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_20_21[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_22_23[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_24_25[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_26_27[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_28_29[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_30_31[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
curve += 2;
|
||||
REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_32_33[mpcc_id], 0,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
}
|
||||
|
||||
|
||||
static void mpc32_program_shaper_lut(
|
||||
struct mpc *mpc,
|
||||
const struct pwl_result_data *rgb,
|
||||
uint32_t num,
|
||||
uint32_t mpcc_id)
|
||||
{
|
||||
uint32_t i, red, green, blue;
|
||||
uint32_t red_delta, green_delta, blue_delta;
|
||||
uint32_t red_value, green_value, blue_value;
|
||||
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
|
||||
for (i = 0 ; i < num; i++) {
|
||||
|
||||
red = rgb[i].red_reg;
|
||||
green = rgb[i].green_reg;
|
||||
blue = rgb[i].blue_reg;
|
||||
|
||||
red_delta = rgb[i].delta_red_reg;
|
||||
green_delta = rgb[i].delta_green_reg;
|
||||
blue_delta = rgb[i].delta_blue_reg;
|
||||
|
||||
red_value = ((red_delta & 0x3ff) << 14) | (red & 0x3fff);
|
||||
green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
|
||||
blue_value = ((blue_delta & 0x3ff) << 14) | (blue & 0x3fff);
|
||||
|
||||
REG_SET(MPCC_MCM_SHAPER_LUT_DATA[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_DATA, red_value);
|
||||
REG_SET(MPCC_MCM_SHAPER_LUT_DATA[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_DATA, green_value);
|
||||
REG_SET(MPCC_MCM_SHAPER_LUT_DATA[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_DATA, blue_value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void mpc32_power_on_shaper_3dlut(
|
||||
struct mpc *mpc,
|
||||
uint32_t mpcc_id,
|
||||
bool power_on)
|
||||
{
|
||||
uint32_t power_status_shaper = 2;
|
||||
uint32_t power_status_3dlut = 2;
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
int max_retries = 10;
|
||||
|
||||
REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
|
||||
MPCC_MCM_3DLUT_MEM_PWR_DIS, power_on == true ? 1:0);
|
||||
/* wait for memory to fully power up */
|
||||
if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
|
||||
REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
|
||||
REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
|
||||
}
|
||||
|
||||
/*read status is not mandatory, it is just for debugging*/
|
||||
REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, &power_status_shaper);
|
||||
REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, &power_status_3dlut);
|
||||
|
||||
if (power_status_shaper != 0 && power_on == true)
|
||||
BREAK_TO_DEBUGGER();
|
||||
|
||||
if (power_status_3dlut != 0 && power_on == true)
|
||||
BREAK_TO_DEBUGGER();
|
||||
}
|
||||
|
||||
|
||||
bool mpc32_program_shaper(
|
||||
struct mpc *mpc,
|
||||
const struct pwl_params *params,
|
||||
uint32_t mpcc_id)
|
||||
{
|
||||
enum dc_lut_mode current_mode;
|
||||
enum dc_lut_mode next_mode;
|
||||
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
|
||||
if (params == NULL) {
|
||||
REG_SET(MPCC_MCM_SHAPER_CONTROL[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_MODE, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
|
||||
mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true);
|
||||
|
||||
current_mode = mpc32_get_shaper_current(mpc, mpcc_id);
|
||||
|
||||
if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
|
||||
next_mode = LUT_RAM_B;
|
||||
else
|
||||
next_mode = LUT_RAM_A;
|
||||
|
||||
mpc32_configure_shaper_lut(mpc, next_mode == LUT_RAM_A ? true:false, mpcc_id);
|
||||
|
||||
if (next_mode == LUT_RAM_A)
|
||||
mpc32_program_shaper_luta_settings(mpc, params, mpcc_id);
|
||||
else
|
||||
mpc32_program_shaper_lutb_settings(mpc, params, mpcc_id);
|
||||
|
||||
mpc32_program_shaper_lut(
|
||||
mpc, params->rgb_resulted, params->hw_points_num, mpcc_id);
|
||||
|
||||
REG_SET(MPCC_MCM_SHAPER_CONTROL[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
|
||||
mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static enum dc_lut_mode get3dlut_config(
|
||||
struct mpc *mpc,
|
||||
bool *is_17x17x17,
|
||||
bool *is_12bits_color_channel,
|
||||
int mpcc_id)
|
||||
{
|
||||
uint32_t i_mode, i_enable_10bits, lut_size;
|
||||
enum dc_lut_mode mode;
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
|
||||
REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
|
||||
MPCC_MCM_3DLUT_MODE_CURRENT, &i_mode);
|
||||
|
||||
REG_GET(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
|
||||
MPCC_MCM_3DLUT_30BIT_EN, &i_enable_10bits);
|
||||
|
||||
switch (i_mode) {
|
||||
case 0:
|
||||
mode = LUT_BYPASS;
|
||||
break;
|
||||
case 1:
|
||||
mode = LUT_RAM_A;
|
||||
break;
|
||||
case 2:
|
||||
mode = LUT_RAM_B;
|
||||
break;
|
||||
default:
|
||||
mode = LUT_BYPASS;
|
||||
break;
|
||||
}
|
||||
if (i_enable_10bits > 0)
|
||||
*is_12bits_color_channel = false;
|
||||
else
|
||||
*is_12bits_color_channel = true;
|
||||
|
||||
REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &lut_size);
|
||||
|
||||
if (lut_size == 0)
|
||||
*is_17x17x17 = true;
|
||||
else
|
||||
*is_17x17x17 = false;
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
||||
static void mpc32_select_3dlut_ram(
|
||||
struct mpc *mpc,
|
||||
enum dc_lut_mode mode,
|
||||
bool is_color_channel_12bits,
|
||||
uint32_t mpcc_id)
|
||||
{
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
|
||||
REG_UPDATE_2(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
|
||||
MPCC_MCM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
|
||||
MPCC_MCM_3DLUT_30BIT_EN, is_color_channel_12bits == true ? 0:1);
|
||||
}
|
||||
|
||||
|
||||
static void mpc32_select_3dlut_ram_mask(
|
||||
struct mpc *mpc,
|
||||
uint32_t ram_selection_mask,
|
||||
uint32_t mpcc_id)
|
||||
{
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
|
||||
REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_WRITE_EN_MASK,
|
||||
ram_selection_mask);
|
||||
REG_SET(MPCC_MCM_3DLUT_INDEX[mpcc_id], 0, MPCC_MCM_3DLUT_INDEX, 0);
|
||||
}
|
||||
|
||||
|
||||
static void mpc32_set3dlut_ram12(
|
||||
struct mpc *mpc,
|
||||
const struct dc_rgb *lut,
|
||||
uint32_t entries,
|
||||
uint32_t mpcc_id)
|
||||
{
|
||||
uint32_t i, red, green, blue, red1, green1, blue1;
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
|
||||
for (i = 0 ; i < entries; i += 2) {
|
||||
red = lut[i].red<<4;
|
||||
green = lut[i].green<<4;
|
||||
blue = lut[i].blue<<4;
|
||||
red1 = lut[i+1].red<<4;
|
||||
green1 = lut[i+1].green<<4;
|
||||
blue1 = lut[i+1].blue<<4;
|
||||
|
||||
REG_SET_2(MPCC_MCM_3DLUT_DATA[mpcc_id], 0,
|
||||
MPCC_MCM_3DLUT_DATA0, red,
|
||||
MPCC_MCM_3DLUT_DATA1, red1);
|
||||
|
||||
REG_SET_2(MPCC_MCM_3DLUT_DATA[mpcc_id], 0,
|
||||
MPCC_MCM_3DLUT_DATA0, green,
|
||||
MPCC_MCM_3DLUT_DATA1, green1);
|
||||
|
||||
REG_SET_2(MPCC_MCM_3DLUT_DATA[mpcc_id], 0,
|
||||
MPCC_MCM_3DLUT_DATA0, blue,
|
||||
MPCC_MCM_3DLUT_DATA1, blue1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void mpc32_set3dlut_ram10(
|
||||
struct mpc *mpc,
|
||||
const struct dc_rgb *lut,
|
||||
uint32_t entries,
|
||||
uint32_t mpcc_id)
|
||||
{
|
||||
uint32_t i, red, green, blue, value;
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
|
||||
for (i = 0; i < entries; i++) {
|
||||
red = lut[i].red;
|
||||
green = lut[i].green;
|
||||
blue = lut[i].blue;
|
||||
//should we shift red 22bit and green 12?
|
||||
value = (red<<20) | (green<<10) | blue;
|
||||
|
||||
REG_SET(MPCC_MCM_3DLUT_DATA_30BIT[mpcc_id], 0, MPCC_MCM_3DLUT_DATA_30BIT, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void mpc32_set_3dlut_mode(
|
||||
struct mpc *mpc,
|
||||
enum dc_lut_mode mode,
|
||||
bool is_color_channel_12bits,
|
||||
bool is_lut_size17x17x17,
|
||||
uint32_t mpcc_id)
|
||||
{
|
||||
uint32_t lut_mode;
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
|
||||
if (mode == LUT_BYPASS)
|
||||
lut_mode = 0;
|
||||
else if (mode == LUT_RAM_A)
|
||||
lut_mode = 1;
|
||||
else
|
||||
lut_mode = 2;
|
||||
|
||||
REG_UPDATE_2(MPCC_MCM_3DLUT_MODE[mpcc_id],
|
||||
MPCC_MCM_3DLUT_MODE, lut_mode,
|
||||
MPCC_MCM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
|
||||
}
|
||||
|
||||
|
||||
bool mpc32_program_3dlut(
|
||||
struct mpc *mpc,
|
||||
const struct tetrahedral_params *params,
|
||||
int mpcc_id)
|
||||
{
|
||||
enum dc_lut_mode mode;
|
||||
bool is_17x17x17;
|
||||
bool is_12bits_color_channel;
|
||||
const struct dc_rgb *lut0;
|
||||
const struct dc_rgb *lut1;
|
||||
const struct dc_rgb *lut2;
|
||||
const struct dc_rgb *lut3;
|
||||
int lut_size0;
|
||||
int lut_size;
|
||||
|
||||
if (params == NULL) {
|
||||
mpc32_set_3dlut_mode(mpc, LUT_BYPASS, false, false, mpcc_id);
|
||||
return false;
|
||||
}
|
||||
mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true);
|
||||
|
||||
mode = get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, mpcc_id);
|
||||
|
||||
if (mode == LUT_BYPASS || mode == LUT_RAM_B)
|
||||
mode = LUT_RAM_A;
|
||||
else
|
||||
mode = LUT_RAM_B;
|
||||
|
||||
is_17x17x17 = !params->use_tetrahedral_9;
|
||||
is_12bits_color_channel = params->use_12bits;
|
||||
if (is_17x17x17) {
|
||||
lut0 = params->tetrahedral_17.lut0;
|
||||
lut1 = params->tetrahedral_17.lut1;
|
||||
lut2 = params->tetrahedral_17.lut2;
|
||||
lut3 = params->tetrahedral_17.lut3;
|
||||
lut_size0 = sizeof(params->tetrahedral_17.lut0)/
|
||||
sizeof(params->tetrahedral_17.lut0[0]);
|
||||
lut_size = sizeof(params->tetrahedral_17.lut1)/
|
||||
sizeof(params->tetrahedral_17.lut1[0]);
|
||||
} else {
|
||||
lut0 = params->tetrahedral_9.lut0;
|
||||
lut1 = params->tetrahedral_9.lut1;
|
||||
lut2 = params->tetrahedral_9.lut2;
|
||||
lut3 = params->tetrahedral_9.lut3;
|
||||
lut_size0 = sizeof(params->tetrahedral_9.lut0)/
|
||||
sizeof(params->tetrahedral_9.lut0[0]);
|
||||
lut_size = sizeof(params->tetrahedral_9.lut1)/
|
||||
sizeof(params->tetrahedral_9.lut1[0]);
|
||||
}
|
||||
|
||||
mpc32_select_3dlut_ram(mpc, mode,
|
||||
is_12bits_color_channel, mpcc_id);
|
||||
mpc32_select_3dlut_ram_mask(mpc, 0x1, mpcc_id);
|
||||
if (is_12bits_color_channel)
|
||||
mpc32_set3dlut_ram12(mpc, lut0, lut_size0, mpcc_id);
|
||||
else
|
||||
mpc32_set3dlut_ram10(mpc, lut0, lut_size0, mpcc_id);
|
||||
|
||||
mpc32_select_3dlut_ram_mask(mpc, 0x2, mpcc_id);
|
||||
if (is_12bits_color_channel)
|
||||
mpc32_set3dlut_ram12(mpc, lut1, lut_size, mpcc_id);
|
||||
else
|
||||
mpc32_set3dlut_ram10(mpc, lut1, lut_size, mpcc_id);
|
||||
|
||||
mpc32_select_3dlut_ram_mask(mpc, 0x4, mpcc_id);
|
||||
if (is_12bits_color_channel)
|
||||
mpc32_set3dlut_ram12(mpc, lut2, lut_size, mpcc_id);
|
||||
else
|
||||
mpc32_set3dlut_ram10(mpc, lut2, lut_size, mpcc_id);
|
||||
|
||||
mpc32_select_3dlut_ram_mask(mpc, 0x8, mpcc_id);
|
||||
if (is_12bits_color_channel)
|
||||
mpc32_set3dlut_ram12(mpc, lut3, lut_size, mpcc_id);
|
||||
else
|
||||
mpc32_set3dlut_ram10(mpc, lut3, lut_size, mpcc_id);
|
||||
|
||||
mpc32_set_3dlut_mode(mpc, mode, is_12bits_color_channel,
|
||||
is_17x17x17, mpcc_id);
|
||||
|
||||
if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
|
||||
mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct mpc_funcs dcn32_mpc_funcs = {
|
||||
.read_mpcc_state = mpc1_read_mpcc_state,
|
||||
.insert_plane = mpc1_insert_plane,
|
||||
.remove_mpcc = mpc1_remove_mpcc,
|
||||
.mpc_init = mpc32_mpc_init,
|
||||
.mpc_init_single_inst = mpc1_mpc_init_single_inst,
|
||||
.update_blending = mpc2_update_blending,
|
||||
.cursor_lock = mpc1_cursor_lock,
|
||||
.get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
|
||||
.wait_for_idle = mpc2_assert_idle_mpcc,
|
||||
.assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect,
|
||||
.init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
|
||||
.set_denorm = mpc3_set_denorm,
|
||||
.set_denorm_clamp = mpc3_set_denorm_clamp,
|
||||
.set_output_csc = mpc3_set_output_csc,
|
||||
.set_ocsc_default = mpc3_set_ocsc_default,
|
||||
.set_output_gamma = mpc3_set_output_gamma,
|
||||
.insert_plane_to_secondary = NULL,
|
||||
.remove_mpcc_from_secondary = NULL,
|
||||
.set_dwb_mux = mpc3_set_dwb_mux,
|
||||
.disable_dwb_mux = mpc3_disable_dwb_mux,
|
||||
.is_dwb_idle = mpc3_is_dwb_idle,
|
||||
.set_out_rate_control = mpc3_set_out_rate_control,
|
||||
.set_gamut_remap = mpc3_set_gamut_remap,
|
||||
.program_shaper = mpc32_program_shaper,
|
||||
.program_3dlut = mpc32_program_3dlut,
|
||||
.acquire_rmu = NULL,
|
||||
.release_rmu = NULL,
|
||||
.power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut,
|
||||
.get_mpc_out_mux = mpc1_get_mpc_out_mux,
|
||||
.set_bg_color = mpc1_set_bg_color,
|
||||
};
|
||||
|
||||
|
||||
void dcn32_mpc_construct(struct dcn30_mpc *mpc30,
|
||||
struct dc_context *ctx,
|
||||
const struct dcn30_mpc_registers *mpc_regs,
|
||||
const struct dcn30_mpc_shift *mpc_shift,
|
||||
const struct dcn30_mpc_mask *mpc_mask,
|
||||
int num_mpcc,
|
||||
int num_rmu)
|
||||
{
|
||||
int i;
|
||||
|
||||
mpc30->base.ctx = ctx;
|
||||
|
||||
mpc30->base.funcs = &dcn32_mpc_funcs;
|
||||
|
||||
mpc30->mpc_regs = mpc_regs;
|
||||
mpc30->mpc_shift = mpc_shift;
|
||||
mpc30->mpc_mask = mpc_mask;
|
||||
|
||||
mpc30->mpcc_in_use_mask = 0;
|
||||
mpc30->num_mpcc = num_mpcc;
|
||||
mpc30->num_rmu = num_rmu;
|
||||
|
||||
for (i = 0; i < MAX_MPCC; i++)
|
||||
mpc3_init_mpcc(&mpc30->base.mpcc_array[i], i);
|
||||
}
|
213
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.h
Normal file
213
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.h
Normal file
@ -0,0 +1,213 @@
|
||||
/* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_MPCC_DCN32_H__
|
||||
#define __DC_MPCC_DCN32_H__
|
||||
|
||||
#include "dcn20/dcn20_mpc.h"
|
||||
#include "dcn30/dcn30_mpc.h"
|
||||
|
||||
#define MPC_MCM_REG_LIST_DCN32(inst) \
|
||||
SRII(MPCC_MCM_SHAPER_CONTROL, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_OFFSET_R, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_OFFSET_G, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_OFFSET_B, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_SCALE_R, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_SCALE_G_B, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_LUT_INDEX, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_LUT_DATA, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_START_CNTL_B, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_START_CNTL_G, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_START_CNTL_R, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_END_CNTL_B, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_END_CNTL_G, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_END_CNTL_R, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_0_1, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_2_3, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_4_5, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_6_7, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_8_9, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_10_11, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_12_13, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_14_15, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_16_17, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_18_19, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_20_21, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_22_23, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_24_25, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_26_27, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_28_29, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_30_31, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMA_REGION_32_33, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_START_CNTL_B, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_START_CNTL_G, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_START_CNTL_R, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_END_CNTL_B, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_END_CNTL_G, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_END_CNTL_R, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_0_1, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_2_3, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_4_5, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_6_7, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_8_9, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_10_11, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_12_13, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_14_15, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_16_17, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_18_19, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_20_21, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_22_23, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_24_25, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_26_27, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_28_29, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_30_31, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_SHAPER_RAMB_REGION_32_33, MPCC_MCM, inst), \
|
||||
SRII(MPCC_MCM_3DLUT_MODE, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_3DLUT_INDEX, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_3DLUT_DATA, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_3DLUT_DATA_30BIT, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_3DLUT_READ_WRITE_CONTROL, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_3DLUT_OUT_NORM_FACTOR, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_3DLUT_OUT_OFFSET_R, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_3DLUT_OUT_OFFSET_G, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_3DLUT_OUT_OFFSET_B, MPCC_MCM, inst),\
|
||||
SRII(MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM, inst)
|
||||
|
||||
|
||||
#define MPC_COMMON_MASK_SH_LIST_DCN32(mask_sh) \
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh),\
|
||||
SF(MPCC0_MPCC_CONTROL, MPCC_BG_BPC, mask_sh),\
|
||||
SF(MPCC0_MPCC_CONTROL, MPCC_BOT_GAIN_MODE, mask_sh),\
|
||||
SF(MPCC0_MPCC_TOP_GAIN, MPCC_TOP_GAIN, mask_sh),\
|
||||
SF(MPCC0_MPCC_BOT_GAIN_INSIDE, MPCC_BOT_GAIN_INSIDE, mask_sh),\
|
||||
SF(MPCC0_MPCC_BOT_GAIN_OUTSIDE, MPCC_BOT_GAIN_OUTSIDE, mask_sh),\
|
||||
SF(MPC_OUT0_CSC_MODE, MPC_OCSC_MODE, mask_sh),\
|
||||
SF(MPC_OUT0_CSC_C11_C12_A, MPC_OCSC_C11_A, mask_sh),\
|
||||
SF(MPC_OUT0_CSC_C11_C12_A, MPC_OCSC_C12_A, mask_sh),\
|
||||
SF(MPCC0_MPCC_STATUS, MPCC_DISABLED, mask_sh),\
|
||||
SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_FORCE, mask_sh),\
|
||||
SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_DIS, mask_sh),\
|
||||
SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_LOW_PWR_MODE, mask_sh),\
|
||||
SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_STATE, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_MODE, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MAX_R_CR, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MIN_R_CR, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MAX_G_Y, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MIN_G_Y, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MAX_B_CB, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_GAMUT_REMAP_MODE, MPCC_GAMUT_REMAP_MODE, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_GAMUT_REMAP_MODE, MPCC_GAMUT_REMAP_MODE_CURRENT, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_GAMUT_REMAP_COEF_FORMAT, MPCC_GAMUT_REMAP_COEF_FORMAT, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPC_GAMUT_REMAP_C11_C12_A, MPCC_GAMUT_REMAP_C11_A, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPC_GAMUT_REMAP_C11_C12_A, MPCC_GAMUT_REMAP_C12_A, mask_sh),\
|
||||
SF(MPC_DWB0_MUX, MPC_DWB0_MUX, mask_sh),\
|
||||
SF(MPC_DWB0_MUX, MPC_DWB0_MUX_STATUS, mask_sh),\
|
||||
SF(MPC_OUT0_MUX, MPC_OUT_RATE_CONTROL, mask_sh),\
|
||||
SF(MPC_OUT0_MUX, MPC_OUT_RATE_CONTROL_DISABLE, mask_sh),\
|
||||
SF(MPC_OUT0_MUX, MPC_OUT_FLOW_CONTROL_MODE, mask_sh),\
|
||||
SF(MPC_OUT0_MUX, MPC_OUT_FLOW_CONTROL_COUNT, mask_sh), \
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_REGION_0_1, MPCC_OGAM_RAMA_EXP_REGION0_LUT_OFFSET, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_REGION_0_1, MPCC_OGAM_RAMA_EXP_REGION0_NUM_SEGMENTS, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_REGION_0_1, MPCC_OGAM_RAMA_EXP_REGION1_LUT_OFFSET, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_REGION_0_1, MPCC_OGAM_RAMA_EXP_REGION1_NUM_SEGMENTS, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL2_B, MPCC_OGAM_RAMA_EXP_REGION_END_SLOPE_B, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL2_B, MPCC_OGAM_RAMA_EXP_REGION_END_B, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL1_B, MPCC_OGAM_RAMA_EXP_REGION_END_BASE_B, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_START_SLOPE_CNTL_B, MPCC_OGAM_RAMA_EXP_REGION_START_SLOPE_B, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_START_BASE_CNTL_B, MPCC_OGAM_RAMA_EXP_REGION_START_BASE_B, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_START_CNTL_B, MPCC_OGAM_RAMA_EXP_REGION_START_B, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_START_CNTL_B, MPCC_OGAM_RAMA_EXP_REGION_START_SEGMENT_B, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_OFFSET_B, MPCC_OGAM_RAMA_OFFSET_B, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_OFFSET_G, MPCC_OGAM_RAMA_OFFSET_G, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_RAMA_OFFSET_R, MPCC_OGAM_RAMA_OFFSET_R, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_LUT_INDEX, MPCC_OGAM_LUT_INDEX, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_CONTROL, MPCC_OGAM_MODE, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_CONTROL, MPCC_OGAM_SELECT, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_CONTROL, MPCC_OGAM_PWL_DISABLE, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_CONTROL, MPCC_OGAM_MODE_CURRENT, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_CONTROL, MPCC_OGAM_SELECT_CURRENT, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_LUT_CONTROL, MPCC_OGAM_LUT_WRITE_COLOR_MASK, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_LUT_CONTROL, MPCC_OGAM_LUT_READ_COLOR_SEL, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_LUT_CONTROL, MPCC_OGAM_LUT_READ_DBG, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_LUT_CONTROL, MPCC_OGAM_LUT_HOST_SEL, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_LUT_CONTROL, MPCC_OGAM_LUT_CONFIG_MODE, mask_sh),\
|
||||
SF(MPCC_OGAM0_MPCC_OGAM_LUT_DATA, MPCC_OGAM_LUT_DATA, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_3DLUT_MODE, MPCC_MCM_3DLUT_MODE, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_3DLUT_MODE, MPCC_MCM_3DLUT_SIZE, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_3DLUT_MODE, MPCC_MCM_3DLUT_MODE_CURRENT, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_3DLUT_READ_WRITE_CONTROL, MPCC_MCM_3DLUT_WRITE_EN_MASK, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_3DLUT_READ_WRITE_CONTROL, MPCC_MCM_3DLUT_RAM_SEL, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_3DLUT_READ_WRITE_CONTROL, MPCC_MCM_3DLUT_30BIT_EN, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_3DLUT_READ_WRITE_CONTROL, MPCC_MCM_3DLUT_READ_SEL, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_3DLUT_INDEX, MPCC_MCM_3DLUT_INDEX, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_3DLUT_DATA, MPCC_MCM_3DLUT_DATA0, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_3DLUT_DATA, MPCC_MCM_3DLUT_DATA1, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_3DLUT_DATA_30BIT, MPCC_MCM_3DLUT_DATA_30BIT, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_CONTROL, MPCC_MCM_SHAPER_LUT_MODE, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_CONTROL, MPCC_MCM_SHAPER_MODE_CURRENT, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_OFFSET_R, MPCC_MCM_SHAPER_OFFSET_R, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_OFFSET_G, MPCC_MCM_SHAPER_OFFSET_G, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_OFFSET_B, MPCC_MCM_SHAPER_OFFSET_B, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_SCALE_R, MPCC_MCM_SHAPER_SCALE_R, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_SCALE_G_B, MPCC_MCM_SHAPER_SCALE_G, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_SCALE_G_B, MPCC_MCM_SHAPER_SCALE_B, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_LUT_INDEX, MPCC_MCM_SHAPER_LUT_INDEX, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_LUT_DATA, MPCC_MCM_SHAPER_LUT_DATA, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK, MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK, MPCC_MCM_SHAPER_LUT_WRITE_SEL, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_RAMA_START_CNTL_B, MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_RAMA_START_CNTL_B, MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_RAMA_END_CNTL_B, MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_RAMA_END_CNTL_B, MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_RAMA_REGION_0_1, MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_RAMA_REGION_0_1, MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_RAMA_REGION_0_1, MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_RAMA_REGION_0_1, MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM_SHAPER_MEM_PWR_FORCE, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM_SHAPER_MEM_PWR_DIS, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM_SHAPER_MEM_LOW_PWR_MODE, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM_3DLUT_MEM_PWR_FORCE, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM_3DLUT_MEM_PWR_DIS, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM_3DLUT_MEM_LOW_PWR_MODE, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM_1DLUT_MEM_PWR_FORCE, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM_1DLUT_MEM_PWR_DIS, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM_1DLUT_MEM_LOW_PWR_MODE, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM_SHAPER_MEM_PWR_STATE, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM_3DLUT_MEM_PWR_STATE, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM_1DLUT_MEM_PWR_STATE, mask_sh),\
|
||||
SF(MPCC_MCM0_MPCC_MCM_SHAPER_CONTROL, MPCC_MCM_SHAPER_MODE_CURRENT, mask_sh),\
|
||||
SF(CUR_VUPDATE_LOCK_SET0, CUR_VUPDATE_LOCK_SET, mask_sh)
|
||||
|
||||
|
||||
void dcn32_mpc_construct(struct dcn30_mpc *mpc30,
|
||||
struct dc_context *ctx,
|
||||
const struct dcn30_mpc_registers *mpc_regs,
|
||||
const struct dcn30_mpc_shift *mpc_shift,
|
||||
const struct dcn30_mpc_mask *mpc_mask,
|
||||
int num_mpcc,
|
||||
int num_rmu);
|
||||
|
||||
#endif //__DC_MPCC_DCN32_H__
|
236
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
Normal file
236
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
Normal file
@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright 2022 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 "dcn32_optc.h"
|
||||
|
||||
#include "dcn30/dcn30_optc.h"
|
||||
#include "reg_helper.h"
|
||||
#include "dc.h"
|
||||
#include "dcn_calc_math.h"
|
||||
|
||||
#define REG(reg)\
|
||||
optc1->tg_regs->reg
|
||||
|
||||
#define CTX \
|
||||
optc1->base.ctx
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
optc1->tg_shift->field_name, optc1->tg_mask->field_name
|
||||
|
||||
static void optc32_set_odm_combine(struct timing_generator *optc, int *opp_id, int opp_cnt,
|
||||
struct dc_crtc_timing *timing)
|
||||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
uint32_t memory_mask = 0;
|
||||
int h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right;
|
||||
int mpcc_hactive = h_active / opp_cnt;
|
||||
/* Each memory instance is 2048x(32x2) bits to support half line of 4096 */
|
||||
int odm_mem_count = (h_active + 2047) / 2048;
|
||||
|
||||
/*
|
||||
* display <= 4k : 2 memories + 2 pipes
|
||||
* 4k < display <= 8k : 4 memories + 2 pipes
|
||||
* 8k < display <= 12k : 6 memories + 4 pipes
|
||||
*/
|
||||
if (opp_cnt == 4) {
|
||||
if (odm_mem_count <= 2)
|
||||
memory_mask = 0x3;
|
||||
else if (odm_mem_count <= 4)
|
||||
memory_mask = 0xf;
|
||||
else
|
||||
memory_mask = 0x3f;
|
||||
} else {
|
||||
if (odm_mem_count <= 2)
|
||||
memory_mask = 0x1 << (opp_id[0] * 2) | 0x1 << (opp_id[1] * 2);
|
||||
else if (odm_mem_count <= 4)
|
||||
memory_mask = 0x3 << (opp_id[0] * 2) | 0x3 << (opp_id[1] * 2);
|
||||
else
|
||||
memory_mask = 0x77;
|
||||
}
|
||||
|
||||
REG_SET(OPTC_MEMORY_CONFIG, 0,
|
||||
OPTC_MEM_SEL, memory_mask);
|
||||
|
||||
if (opp_cnt == 2) {
|
||||
REG_SET_3(OPTC_DATA_SOURCE_SELECT, 0,
|
||||
OPTC_NUM_OF_INPUT_SEGMENT, 1,
|
||||
OPTC_SEG0_SRC_SEL, opp_id[0],
|
||||
OPTC_SEG1_SRC_SEL, opp_id[1]);
|
||||
} else if (opp_cnt == 4) {
|
||||
REG_SET_5(OPTC_DATA_SOURCE_SELECT, 0,
|
||||
OPTC_NUM_OF_INPUT_SEGMENT, 3,
|
||||
OPTC_SEG0_SRC_SEL, opp_id[0],
|
||||
OPTC_SEG1_SRC_SEL, opp_id[1],
|
||||
OPTC_SEG2_SRC_SEL, opp_id[2],
|
||||
OPTC_SEG3_SRC_SEL, opp_id[3]);
|
||||
}
|
||||
|
||||
REG_UPDATE(OPTC_WIDTH_CONTROL,
|
||||
OPTC_SEGMENT_WIDTH, mpcc_hactive);
|
||||
|
||||
REG_SET(OTG_H_TIMING_CNTL, 0, OTG_H_TIMING_DIV_MODE, opp_cnt - 1);
|
||||
optc1->opp_count = opp_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable CRTC
|
||||
* Enable CRTC - call ASIC Control Object to enable Timing generator.
|
||||
*/
|
||||
static bool optc32_enable_crtc(struct timing_generator *optc)
|
||||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
|
||||
/* opp instance for OTG, 1 to 1 mapping and odm will adjust */
|
||||
REG_UPDATE(OPTC_DATA_SOURCE_SELECT,
|
||||
OPTC_SEG0_SRC_SEL, optc->inst);
|
||||
|
||||
/* VTG enable first is for HW workaround */
|
||||
REG_UPDATE(CONTROL,
|
||||
VTG0_ENABLE, 1);
|
||||
|
||||
REG_SEQ_START();
|
||||
|
||||
/* Enable CRTC */
|
||||
REG_UPDATE_2(OTG_CONTROL,
|
||||
OTG_DISABLE_POINT_CNTL, 2,
|
||||
OTG_MASTER_EN, 1);
|
||||
|
||||
REG_SEQ_SUBMIT();
|
||||
REG_SEQ_WAIT_DONE();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* disable_crtc */
|
||||
static bool optc32_disable_crtc(struct timing_generator *optc)
|
||||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
|
||||
/* disable otg request until end of the first line
|
||||
* in the vertical blank region
|
||||
*/
|
||||
REG_UPDATE(OTG_CONTROL,
|
||||
OTG_MASTER_EN, 0);
|
||||
|
||||
REG_UPDATE(CONTROL,
|
||||
VTG0_ENABLE, 0);
|
||||
|
||||
/* CRTC disabled, so disable clock. */
|
||||
REG_WAIT(OTG_CLOCK_CONTROL,
|
||||
OTG_BUSY, 0,
|
||||
1, 100000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void optc32_phantom_crtc_post_enable(struct timing_generator *optc)
|
||||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
|
||||
/* Disable immediately. */
|
||||
REG_UPDATE_2(OTG_CONTROL, OTG_DISABLE_POINT_CNTL, 0, OTG_MASTER_EN, 0);
|
||||
|
||||
/* CRTC disabled, so disable clock. */
|
||||
REG_WAIT(OTG_CLOCK_CONTROL, OTG_BUSY, 0, 1, 100000);
|
||||
}
|
||||
|
||||
|
||||
static struct timing_generator_funcs dcn32_tg_funcs = {
|
||||
.validate_timing = optc1_validate_timing,
|
||||
.program_timing = optc1_program_timing,
|
||||
.setup_vertical_interrupt0 = optc1_setup_vertical_interrupt0,
|
||||
.setup_vertical_interrupt1 = optc1_setup_vertical_interrupt1,
|
||||
.setup_vertical_interrupt2 = optc1_setup_vertical_interrupt2,
|
||||
.program_global_sync = optc1_program_global_sync,
|
||||
.enable_crtc = optc32_enable_crtc,
|
||||
.disable_crtc = optc32_disable_crtc,
|
||||
.phantom_crtc_post_enable = optc32_phantom_crtc_post_enable,
|
||||
/* used by enable_timing_synchronization. Not need for FPGA */
|
||||
.is_counter_moving = optc1_is_counter_moving,
|
||||
.get_position = optc1_get_position,
|
||||
.get_frame_count = optc1_get_vblank_counter,
|
||||
.get_scanoutpos = optc1_get_crtc_scanoutpos,
|
||||
.get_otg_active_size = optc1_get_otg_active_size,
|
||||
.set_early_control = optc1_set_early_control,
|
||||
/* used by enable_timing_synchronization. Not need for FPGA */
|
||||
.wait_for_state = optc1_wait_for_state,
|
||||
.set_blank_color = optc3_program_blank_color,
|
||||
.did_triggered_reset_occur = optc1_did_triggered_reset_occur,
|
||||
.triplebuffer_lock = optc3_triplebuffer_lock,
|
||||
.triplebuffer_unlock = optc2_triplebuffer_unlock,
|
||||
.enable_reset_trigger = optc1_enable_reset_trigger,
|
||||
.enable_crtc_reset = optc1_enable_crtc_reset,
|
||||
.disable_reset_trigger = optc1_disable_reset_trigger,
|
||||
.lock = optc3_lock,
|
||||
.unlock = optc1_unlock,
|
||||
.lock_doublebuffer_enable = optc3_lock_doublebuffer_enable,
|
||||
.lock_doublebuffer_disable = optc3_lock_doublebuffer_disable,
|
||||
.enable_optc_clock = optc1_enable_optc_clock,
|
||||
.set_vrr_m_const = optc3_set_vrr_m_const,
|
||||
.set_drr = optc1_set_drr,
|
||||
.get_last_used_drr_vtotal = optc2_get_last_used_drr_vtotal,
|
||||
.set_vtotal_min_max = optc1_set_vtotal_min_max,
|
||||
.set_static_screen_control = optc1_set_static_screen_control,
|
||||
.program_stereo = optc1_program_stereo,
|
||||
.is_stereo_left_eye = optc1_is_stereo_left_eye,
|
||||
.tg_init = optc3_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,
|
||||
.setup_global_swap_lock = NULL,
|
||||
.get_crc = optc1_get_crc,
|
||||
.configure_crc = optc1_configure_crc,
|
||||
.set_dsc_config = optc3_set_dsc_config,
|
||||
.get_dsc_status = optc2_get_dsc_status,
|
||||
.set_dwb_source = NULL,
|
||||
.set_odm_bypass = optc3_set_odm_bypass,
|
||||
.set_odm_combine = optc32_set_odm_combine,
|
||||
.get_optc_source = optc2_get_optc_source,
|
||||
.set_out_mux = optc3_set_out_mux,
|
||||
.set_drr_trigger_window = optc3_set_drr_trigger_window,
|
||||
.set_vtotal_change_limit = optc3_set_vtotal_change_limit,
|
||||
.set_gsl = optc2_set_gsl,
|
||||
.set_gsl_source_select = optc2_set_gsl_source_select,
|
||||
.set_vtg_params = optc1_set_vtg_params,
|
||||
.program_manual_trigger = optc2_program_manual_trigger,
|
||||
.setup_manual_trigger = optc2_setup_manual_trigger,
|
||||
.get_hw_timing = optc1_get_hw_timing,
|
||||
};
|
||||
|
||||
void dcn32_timing_generator_init(struct optc *optc1)
|
||||
{
|
||||
optc1->base.funcs = &dcn32_tg_funcs;
|
||||
|
||||
optc1->max_h_total = optc1->tg_mask->OTG_H_TOTAL + 1;
|
||||
optc1->max_v_total = optc1->tg_mask->OTG_V_TOTAL + 1;
|
||||
|
||||
optc1->min_h_blank = 32;
|
||||
optc1->min_v_blank = 3;
|
||||
optc1->min_v_blank_interlace = 5;
|
||||
optc1->min_h_sync_width = 4;
|
||||
optc1->min_v_sync_width = 1;
|
||||
}
|
||||
|
253
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.h
Normal file
253
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.h
Normal file
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_OPTC_DCN32_H__
|
||||
#define __DC_OPTC_DCN32_H__
|
||||
|
||||
#include "dcn10/dcn10_optc.h"
|
||||
|
||||
#define OPTC_COMMON_REG_LIST_DCN3_2(inst) \
|
||||
SRI(OTG_VSTARTUP_PARAM, OTG, inst),\
|
||||
SRI(OTG_VUPDATE_PARAM, OTG, inst),\
|
||||
SRI(OTG_VREADY_PARAM, OTG, inst),\
|
||||
SRI(OTG_MASTER_UPDATE_LOCK, OTG, inst),\
|
||||
SRI(OTG_GLOBAL_CONTROL0, OTG, inst),\
|
||||
SRI(OTG_GLOBAL_CONTROL1, OTG, inst),\
|
||||
SRI(OTG_GLOBAL_CONTROL2, OTG, inst),\
|
||||
SRI(OTG_GLOBAL_CONTROL4, OTG, inst),\
|
||||
SRI(OTG_DOUBLE_BUFFER_CONTROL, OTG, inst),\
|
||||
SRI(OTG_H_TOTAL, OTG, inst),\
|
||||
SRI(OTG_H_BLANK_START_END, OTG, inst),\
|
||||
SRI(OTG_H_SYNC_A, OTG, inst),\
|
||||
SRI(OTG_H_SYNC_A_CNTL, OTG, inst),\
|
||||
SRI(OTG_H_TIMING_CNTL, OTG, inst),\
|
||||
SRI(OTG_V_TOTAL, OTG, inst),\
|
||||
SRI(OTG_V_BLANK_START_END, OTG, inst),\
|
||||
SRI(OTG_V_SYNC_A, OTG, inst),\
|
||||
SRI(OTG_V_SYNC_A_CNTL, OTG, inst),\
|
||||
SRI(OTG_CONTROL, OTG, inst),\
|
||||
SRI(OTG_STEREO_CONTROL, OTG, inst),\
|
||||
SRI(OTG_3D_STRUCTURE_CONTROL, OTG, inst),\
|
||||
SRI(OTG_STEREO_STATUS, OTG, inst),\
|
||||
SRI(OTG_V_TOTAL_MAX, OTG, inst),\
|
||||
SRI(OTG_V_TOTAL_MIN, OTG, inst),\
|
||||
SRI(OTG_V_TOTAL_CONTROL, OTG, inst),\
|
||||
SRI(OTG_TRIGA_CNTL, OTG, inst),\
|
||||
SRI(OTG_FORCE_COUNT_NOW_CNTL, OTG, inst),\
|
||||
SRI(OTG_STATIC_SCREEN_CONTROL, OTG, inst),\
|
||||
SRI(OTG_STATUS_FRAME_COUNT, OTG, inst),\
|
||||
SRI(OTG_STATUS, OTG, inst),\
|
||||
SRI(OTG_STATUS_POSITION, OTG, inst),\
|
||||
SRI(OTG_NOM_VERT_POSITION, OTG, inst),\
|
||||
SRI(OTG_M_CONST_DTO0, OTG, inst),\
|
||||
SRI(OTG_M_CONST_DTO1, OTG, inst),\
|
||||
SRI(OTG_CLOCK_CONTROL, OTG, inst),\
|
||||
SRI(OTG_VERTICAL_INTERRUPT0_CONTROL, OTG, inst),\
|
||||
SRI(OTG_VERTICAL_INTERRUPT0_POSITION, OTG, inst),\
|
||||
SRI(OTG_VERTICAL_INTERRUPT1_CONTROL, OTG, inst),\
|
||||
SRI(OTG_VERTICAL_INTERRUPT1_POSITION, OTG, inst),\
|
||||
SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\
|
||||
SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\
|
||||
SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\
|
||||
SRI(OPTC_DATA_SOURCE_SELECT, ODM, inst),\
|
||||
SRI(OPTC_INPUT_GLOBAL_CONTROL, ODM, inst),\
|
||||
SRI(CONTROL, VTG, inst),\
|
||||
SRI(OTG_VERT_SYNC_CONTROL, OTG, inst),\
|
||||
SRI(OTG_GSL_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC_CNTL, OTG, inst),\
|
||||
SRI(OTG_CRC0_DATA_RG, OTG, inst),\
|
||||
SRI(OTG_CRC0_DATA_B, OTG, inst),\
|
||||
SRI(OTG_CRC0_WINDOWA_X_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC0_WINDOWA_Y_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC0_WINDOWB_X_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC0_WINDOWB_Y_CONTROL, OTG, inst),\
|
||||
SR(GSL_SOURCE_SELECT),\
|
||||
SRI(OTG_TRIGA_MANUAL_TRIG, OTG, inst),\
|
||||
SRI(OTG_GLOBAL_CONTROL1, OTG, inst),\
|
||||
SRI(OTG_GLOBAL_CONTROL2, OTG, inst),\
|
||||
SRI(OTG_GSL_WINDOW_X, OTG, inst),\
|
||||
SRI(OTG_GSL_WINDOW_Y, OTG, inst),\
|
||||
SRI(OTG_VUPDATE_KEEPOUT, OTG, inst),\
|
||||
SRI(OTG_DSC_START_POSITION, OTG, inst),\
|
||||
SRI(OTG_DRR_TRIGGER_WINDOW, OTG, inst),\
|
||||
SRI(OTG_DRR_V_TOTAL_CHANGE, OTG, inst),\
|
||||
SRI(OPTC_DATA_FORMAT_CONTROL, ODM, inst),\
|
||||
SRI(OPTC_BYTES_PER_PIXEL, ODM, inst),\
|
||||
SRI(OPTC_WIDTH_CONTROL, ODM, inst),\
|
||||
SRI(OPTC_MEMORY_CONFIG, ODM, inst),\
|
||||
SRI(OTG_DRR_CONTROL, OTG, inst)
|
||||
|
||||
#define OPTC_COMMON_MASK_SH_LIST_DCN3_2(mask_sh)\
|
||||
SF(OTG0_OTG_VSTARTUP_PARAM, VSTARTUP_START, mask_sh),\
|
||||
SF(OTG0_OTG_VUPDATE_PARAM, VUPDATE_OFFSET, mask_sh),\
|
||||
SF(OTG0_OTG_VUPDATE_PARAM, VUPDATE_WIDTH, mask_sh),\
|
||||
SF(OTG0_OTG_VREADY_PARAM, VREADY_OFFSET, mask_sh),\
|
||||
SF(OTG0_OTG_MASTER_UPDATE_LOCK, OTG_MASTER_UPDATE_LOCK, mask_sh),\
|
||||
SF(OTG0_OTG_MASTER_UPDATE_LOCK, UPDATE_LOCK_STATUS, mask_sh),\
|
||||
SF(OTG0_OTG_GLOBAL_CONTROL0, MASTER_UPDATE_LOCK_DB_START_X, mask_sh),\
|
||||
SF(OTG0_OTG_GLOBAL_CONTROL0, MASTER_UPDATE_LOCK_DB_END_X, mask_sh),\
|
||||
SF(OTG0_OTG_GLOBAL_CONTROL0, MASTER_UPDATE_LOCK_DB_EN, mask_sh),\
|
||||
SF(OTG0_OTG_GLOBAL_CONTROL1, MASTER_UPDATE_LOCK_DB_START_Y, mask_sh),\
|
||||
SF(OTG0_OTG_GLOBAL_CONTROL1, MASTER_UPDATE_LOCK_DB_END_Y, mask_sh),\
|
||||
SF(OTG0_OTG_GLOBAL_CONTROL2, OTG_MASTER_UPDATE_LOCK_SEL, mask_sh),\
|
||||
SF(OTG0_OTG_GLOBAL_CONTROL4, DIG_UPDATE_POSITION_X, mask_sh),\
|
||||
SF(OTG0_OTG_GLOBAL_CONTROL4, DIG_UPDATE_POSITION_Y, mask_sh),\
|
||||
SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_UPDATE_PENDING, mask_sh),\
|
||||
SF(OTG0_OTG_H_TOTAL, OTG_H_TOTAL, mask_sh),\
|
||||
SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_START, mask_sh),\
|
||||
SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_END, mask_sh),\
|
||||
SF(OTG0_OTG_H_SYNC_A, OTG_H_SYNC_A_START, mask_sh),\
|
||||
SF(OTG0_OTG_H_SYNC_A, OTG_H_SYNC_A_END, mask_sh),\
|
||||
SF(OTG0_OTG_H_SYNC_A_CNTL, OTG_H_SYNC_A_POL, mask_sh),\
|
||||
SF(OTG0_OTG_V_TOTAL, OTG_V_TOTAL, mask_sh),\
|
||||
SF(OTG0_OTG_V_BLANK_START_END, OTG_V_BLANK_START, mask_sh),\
|
||||
SF(OTG0_OTG_V_BLANK_START_END, OTG_V_BLANK_END, mask_sh),\
|
||||
SF(OTG0_OTG_V_SYNC_A, OTG_V_SYNC_A_START, mask_sh),\
|
||||
SF(OTG0_OTG_V_SYNC_A, OTG_V_SYNC_A_END, mask_sh),\
|
||||
SF(OTG0_OTG_V_SYNC_A_CNTL, OTG_V_SYNC_A_POL, mask_sh),\
|
||||
SF(OTG0_OTG_V_SYNC_A_CNTL, OTG_V_SYNC_MODE, mask_sh),\
|
||||
SF(OTG0_OTG_CONTROL, OTG_MASTER_EN, mask_sh),\
|
||||
SF(OTG0_OTG_CONTROL, OTG_START_POINT_CNTL, mask_sh),\
|
||||
SF(OTG0_OTG_CONTROL, OTG_DISABLE_POINT_CNTL, mask_sh),\
|
||||
SF(OTG0_OTG_CONTROL, OTG_FIELD_NUMBER_CNTL, mask_sh),\
|
||||
SF(OTG0_OTG_CONTROL, OTG_OUT_MUX, mask_sh),\
|
||||
SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_EN, mask_sh),\
|
||||
SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_SYNC_OUTPUT_LINE_NUM, mask_sh),\
|
||||
SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_SYNC_OUTPUT_POLARITY, mask_sh),\
|
||||
SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_EYE_FLAG_POLARITY, mask_sh),\
|
||||
SF(OTG0_OTG_STEREO_CONTROL, OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, mask_sh),\
|
||||
SF(OTG0_OTG_STEREO_STATUS, OTG_STEREO_CURRENT_EYE, mask_sh),\
|
||||
SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_EN, mask_sh),\
|
||||
SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_V_UPDATE_MODE, mask_sh),\
|
||||
SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_STEREO_SEL_OVR, mask_sh),\
|
||||
SF(OTG0_OTG_V_TOTAL_MAX, OTG_V_TOTAL_MAX, mask_sh),\
|
||||
SF(OTG0_OTG_V_TOTAL_MIN, OTG_V_TOTAL_MIN, mask_sh),\
|
||||
SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_V_TOTAL_MIN_SEL, mask_sh),\
|
||||
SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_V_TOTAL_MAX_SEL, mask_sh),\
|
||||
SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_FORCE_LOCK_ON_EVENT, mask_sh),\
|
||||
SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_SET_V_TOTAL_MIN_MASK, mask_sh),\
|
||||
SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_VTOTAL_MID_REPLACING_MIN_EN, mask_sh),\
|
||||
SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_VTOTAL_MID_REPLACING_MAX_EN, mask_sh),\
|
||||
SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_CLEAR, mask_sh),\
|
||||
SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_MODE, mask_sh),\
|
||||
SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_OCCURRED, mask_sh),\
|
||||
SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_SOURCE_SELECT, mask_sh),\
|
||||
SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_SOURCE_PIPE_SELECT, mask_sh),\
|
||||
SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_RISING_EDGE_DETECT_CNTL, mask_sh),\
|
||||
SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, mask_sh),\
|
||||
SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_POLARITY_SELECT, mask_sh),\
|
||||
SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_FREQUENCY_SELECT, mask_sh),\
|
||||
SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_DELAY, mask_sh),\
|
||||
SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_CLEAR, mask_sh),\
|
||||
SF(OTG0_OTG_STATIC_SCREEN_CONTROL, OTG_STATIC_SCREEN_EVENT_MASK, mask_sh),\
|
||||
SF(OTG0_OTG_STATIC_SCREEN_CONTROL, OTG_STATIC_SCREEN_FRAME_COUNT, mask_sh),\
|
||||
SF(OTG0_OTG_STATUS_FRAME_COUNT, OTG_FRAME_COUNT, mask_sh),\
|
||||
SF(OTG0_OTG_STATUS, OTG_V_BLANK, mask_sh),\
|
||||
SF(OTG0_OTG_STATUS, OTG_V_ACTIVE_DISP, mask_sh),\
|
||||
SF(OTG0_OTG_STATUS_POSITION, OTG_HORZ_COUNT, mask_sh),\
|
||||
SF(OTG0_OTG_STATUS_POSITION, OTG_VERT_COUNT, mask_sh),\
|
||||
SF(OTG0_OTG_NOM_VERT_POSITION, OTG_VERT_COUNT_NOM, mask_sh),\
|
||||
SF(OTG0_OTG_M_CONST_DTO0, OTG_M_CONST_DTO_PHASE, mask_sh),\
|
||||
SF(OTG0_OTG_M_CONST_DTO1, OTG_M_CONST_DTO_MODULO, mask_sh),\
|
||||
SF(OTG0_OTG_CLOCK_CONTROL, OTG_BUSY, mask_sh),\
|
||||
SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\
|
||||
SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\
|
||||
SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, mask_sh),\
|
||||
SF(OTG0_OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE, mask_sh),\
|
||||
SF(OTG0_OTG_VERTICAL_INTERRUPT0_POSITION, OTG_VERTICAL_INTERRUPT0_LINE_START, mask_sh),\
|
||||
SF(OTG0_OTG_VERTICAL_INTERRUPT0_POSITION, OTG_VERTICAL_INTERRUPT0_LINE_END, mask_sh),\
|
||||
SF(OTG0_OTG_VERTICAL_INTERRUPT1_CONTROL, OTG_VERTICAL_INTERRUPT1_INT_ENABLE, mask_sh),\
|
||||
SF(OTG0_OTG_VERTICAL_INTERRUPT1_POSITION, OTG_VERTICAL_INTERRUPT1_LINE_START, mask_sh),\
|
||||
SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\
|
||||
SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\
|
||||
SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\
|
||||
SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_ON, mask_sh),\
|
||||
SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_GATE_DIS, mask_sh),\
|
||||
SF(ODM0_OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_OCCURRED_STATUS, mask_sh),\
|
||||
SF(ODM0_OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, mask_sh),\
|
||||
SF(VTG0_CONTROL, VTG0_ENABLE, mask_sh),\
|
||||
SF(VTG0_CONTROL, VTG0_FP2, mask_sh),\
|
||||
SF(VTG0_CONTROL, VTG0_VCOUNT_INIT, mask_sh),\
|
||||
SF(OTG0_OTG_VERT_SYNC_CONTROL, OTG_FORCE_VSYNC_NEXT_LINE_OCCURRED, mask_sh),\
|
||||
SF(OTG0_OTG_VERT_SYNC_CONTROL, OTG_FORCE_VSYNC_NEXT_LINE_CLEAR, mask_sh),\
|
||||
SF(OTG0_OTG_VERT_SYNC_CONTROL, OTG_AUTO_FORCE_VSYNC_MODE, mask_sh),\
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL0_EN, mask_sh),\
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL1_EN, mask_sh),\
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL2_EN, mask_sh),\
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_MASTER_EN, mask_sh),\
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_FORCE_DELAY, mask_sh),\
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh),\
|
||||
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_CONT_EN, mask_sh),\
|
||||
SF(OTG0_OTG_CRC_CNTL, OTG_CRC0_SELECT, mask_sh),\
|
||||
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_EN, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_DATA_RG, CRC0_R_CR, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_DATA_RG, CRC0_G_Y, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_DATA_B, CRC0_B_CB, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWA_X_CONTROL, OTG_CRC0_WINDOWA_X_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWA_X_CONTROL, OTG_CRC0_WINDOWA_X_END, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWA_Y_CONTROL, OTG_CRC0_WINDOWA_Y_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWA_Y_CONTROL, OTG_CRC0_WINDOWA_Y_END, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWB_X_CONTROL, OTG_CRC0_WINDOWB_X_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWB_X_CONTROL, OTG_CRC0_WINDOWB_X_END, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_END, mask_sh),\
|
||||
SF(OTG0_OTG_TRIGA_MANUAL_TRIG, OTG_TRIGA_MANUAL_TRIG, mask_sh),\
|
||||
SF(GSL_SOURCE_SELECT, GSL0_READY_SOURCE_SEL, mask_sh),\
|
||||
SF(GSL_SOURCE_SELECT, GSL1_READY_SOURCE_SEL, mask_sh),\
|
||||
SF(GSL_SOURCE_SELECT, GSL2_READY_SOURCE_SEL, mask_sh),\
|
||||
SF(OTG0_OTG_GLOBAL_CONTROL2, MANUAL_FLOW_CONTROL_SEL, mask_sh),\
|
||||
SF(OTG0_OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, mask_sh),\
|
||||
SF(OTG0_OTG_GSL_WINDOW_X, OTG_GSL_WINDOW_START_X, mask_sh),\
|
||||
SF(OTG0_OTG_GSL_WINDOW_X, OTG_GSL_WINDOW_END_X, mask_sh), \
|
||||
SF(OTG0_OTG_GSL_WINDOW_Y, OTG_GSL_WINDOW_START_Y, mask_sh),\
|
||||
SF(OTG0_OTG_GSL_WINDOW_Y, OTG_GSL_WINDOW_END_Y, mask_sh),\
|
||||
SF(OTG0_OTG_VUPDATE_KEEPOUT, OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, mask_sh), \
|
||||
SF(OTG0_OTG_VUPDATE_KEEPOUT, MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, mask_sh), \
|
||||
SF(OTG0_OTG_VUPDATE_KEEPOUT, MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, mask_sh), \
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_MASTER_MODE, mask_sh), \
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_MASTER_UPDATE_LOCK_GSL_EN, mask_sh), \
|
||||
SF(OTG0_OTG_DSC_START_POSITION, OTG_DSC_START_POSITION_X, mask_sh), \
|
||||
SF(OTG0_OTG_DSC_START_POSITION, OTG_DSC_START_POSITION_LINE_NUM, mask_sh),\
|
||||
SF(ODM0_OPTC_DATA_SOURCE_SELECT, OPTC_SEG0_SRC_SEL, mask_sh),\
|
||||
SF(ODM0_OPTC_DATA_SOURCE_SELECT, OPTC_SEG1_SRC_SEL, mask_sh),\
|
||||
SF(ODM0_OPTC_DATA_SOURCE_SELECT, OPTC_SEG2_SRC_SEL, mask_sh),\
|
||||
SF(ODM0_OPTC_DATA_SOURCE_SELECT, OPTC_SEG3_SRC_SEL, mask_sh),\
|
||||
SF(ODM0_OPTC_DATA_SOURCE_SELECT, OPTC_NUM_OF_INPUT_SEGMENT, mask_sh),\
|
||||
SF(ODM0_OPTC_MEMORY_CONFIG, OPTC_MEM_SEL, mask_sh),\
|
||||
SF(ODM0_OPTC_DATA_FORMAT_CONTROL, OPTC_DATA_FORMAT, mask_sh),\
|
||||
SF(ODM0_OPTC_DATA_FORMAT_CONTROL, OPTC_DSC_MODE, mask_sh),\
|
||||
SF(ODM0_OPTC_BYTES_PER_PIXEL, OPTC_DSC_BYTES_PER_PIXEL, mask_sh),\
|
||||
SF(ODM0_OPTC_WIDTH_CONTROL, OPTC_DSC_SLICE_WIDTH, mask_sh),\
|
||||
SF(ODM0_OPTC_WIDTH_CONTROL, OPTC_SEGMENT_WIDTH, mask_sh),\
|
||||
SF(OTG0_OTG_DRR_TRIGGER_WINDOW, OTG_DRR_TRIGGER_WINDOW_START_X, mask_sh),\
|
||||
SF(OTG0_OTG_DRR_TRIGGER_WINDOW, OTG_DRR_TRIGGER_WINDOW_END_X, mask_sh),\
|
||||
SF(OTG0_OTG_DRR_V_TOTAL_CHANGE, OTG_DRR_V_TOTAL_CHANGE_LIMIT, mask_sh),\
|
||||
SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE, mask_sh),\
|
||||
SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_MODE, mask_sh),\
|
||||
SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh)
|
||||
|
||||
void dcn32_timing_generator_init(struct optc *optc1);
|
||||
|
||||
#endif /* __DC_OPTC_DCN32_H__ */
|
3976
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
Normal file
3976
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
Normal file
File diff suppressed because it is too large
Load Diff
88
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h
Normal file
88
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DCN32_RESOURCE_H_
|
||||
#define _DCN32_RESOURCE_H_
|
||||
|
||||
#include "core_types.h"
|
||||
|
||||
#define TO_DCN32_RES_POOL(pool)\
|
||||
container_of(pool, struct dcn32_resource_pool, base)
|
||||
|
||||
struct dcn32_resource_pool {
|
||||
struct resource_pool base;
|
||||
};
|
||||
|
||||
struct resource_pool *dcn32_create_resource_pool(
|
||||
const struct dc_init_data *init_data,
|
||||
struct dc *dc);
|
||||
|
||||
void dcn32_calculate_dlg_params(
|
||||
struct dc *dc, struct dc_state *context,
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
int pipe_cnt,
|
||||
int vlevel);
|
||||
|
||||
struct panel_cntl *dcn32_panel_cntl_create(
|
||||
const struct panel_cntl_init_data *init_data);
|
||||
|
||||
bool dcn32_acquire_post_bldn_3dlut(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
int mpcc_id,
|
||||
struct dc_3dlut **lut,
|
||||
struct dc_transfer_func **shaper);
|
||||
|
||||
bool dcn32_release_post_bldn_3dlut(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
struct dc_3dlut **lut,
|
||||
struct dc_transfer_func **shaper);
|
||||
|
||||
void dcn32_remove_phantom_pipes(struct dc *dc,
|
||||
struct dc_state *context);
|
||||
|
||||
void dcn32_add_phantom_pipes(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
unsigned int pipe_cnt,
|
||||
unsigned int index);
|
||||
|
||||
bool dcn32_validate_bandwidth(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
bool fast_validate);
|
||||
|
||||
int dcn32_populate_dml_pipes_from_context(
|
||||
struct dc *dc, struct dc_state *context,
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
bool fast_validate);
|
||||
|
||||
void dcn32_calculate_wm_and_dlg(
|
||||
struct dc *dc, struct dc_state *context,
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
int pipe_cnt,
|
||||
int vlevel);
|
||||
|
||||
#endif /* _DCN32_RESOURCE_H_ */
|
34
drivers/gpu/drm/amd/display/dc/dcn321/Makefile
Normal file
34
drivers/gpu/drm/amd/display/dc/dcn321/Makefile
Normal file
@ -0,0 +1,34 @@
|
||||
#
|
||||
# (c) Copyright 2020 Advanced Micro Devices, Inc. All the rights reserved
|
||||
#
|
||||
# All rights reserved. This notice is intended as a precaution against
|
||||
# inadvertent publication and does not imply publication or any waiver
|
||||
# of confidentiality. The year included in the foregoing notice is the
|
||||
# year of creation of the work.
|
||||
#
|
||||
# Authors: AMD
|
||||
#
|
||||
# Makefile for dcn321.
|
||||
|
||||
DCN321 = dcn321_resource.o
|
||||
|
||||
CFLAGS_$(AMDDALPATH)/dc/dcn321/dcn321_resource.o := -mhard-float -msse
|
||||
|
||||
ifdef CONFIG_CC_IS_GCC
|
||||
ifeq ($(call cc-ifversion, -lt, 0701, y), y)
|
||||
IS_OLD_GCC = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef IS_OLD_GCC
|
||||
# Stack alignment mismatch, proceed with caution.
|
||||
# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3
|
||||
# (8B stack alignment).
|
||||
CFLAGS_$(AMDDALPATH)/dc/dcn321/dcn321_resource.o += -mpreferred-stack-boundary=4
|
||||
else
|
||||
CFLAGS_$(AMDDALPATH)/dc/dcn321/dcn321_resource.o += -msse2
|
||||
endif
|
||||
|
||||
AMD_DAL_DCN321 = $(addprefix $(AMDDALPATH)/dc/dcn321/,$(DCN321))
|
||||
|
||||
AMD_DISPLAY_FILES += $(AMD_DAL_DCN321)
|
@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright 2019 Advanced Micro Devices, Inc.
|
||||
*
|
||||
@ -23,7 +24,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "dc.h"
|
||||
|
||||
@ -98,28 +98,25 @@
|
||||
#define MAX_INSTANCE 8
|
||||
#define MAX_SEGMENT 6
|
||||
|
||||
|
||||
struct IP_BASE_INSTANCE
|
||||
{
|
||||
unsigned int segment[MAX_SEGMENT];
|
||||
struct IP_BASE_INSTANCE {
|
||||
unsigned int segment[MAX_SEGMENT];
|
||||
};
|
||||
|
||||
struct IP_BASE
|
||||
{
|
||||
struct IP_BASE_INSTANCE instance[MAX_INSTANCE];
|
||||
struct IP_BASE {
|
||||
struct IP_BASE_INSTANCE instance[MAX_INSTANCE];
|
||||
};
|
||||
|
||||
static const struct IP_BASE DCN_BASE = { { { { 0x00000012, 0x000000C0, 0x000034C0, 0x00009000, 0x02403C00, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } } } };
|
||||
{ { 0, 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0, 0 } } } };
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
#define fixed16_to_double(x) (((double) x) / ((double) (1 << 16)))
|
||||
#define fixed16_to_double(x) (((double)x) / ((double) (1 << 16)))
|
||||
#define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x))
|
||||
|
||||
#define DCN3_2_DEFAULT_DET_SIZE 256
|
||||
@ -1534,9 +1531,8 @@ static void dcn321_resource_destruct(struct dcn321_resource_pool *pool)
|
||||
pool->base.hubps[i] = NULL;
|
||||
}
|
||||
|
||||
if (pool->base.irqs != NULL) {
|
||||
if (pool->base.irqs != NULL)
|
||||
dal_irq_service_destroy(&pool->base.irqs);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
|
||||
|
42
drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.h
Normal file
42
drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DCN321_RESOURCE_H_
|
||||
#define _DCN321_RESOURCE_H_
|
||||
|
||||
#include "core_types.h"
|
||||
|
||||
#define TO_DCN321_RES_POOL(pool)\
|
||||
container_of(pool, struct dcn321_resource_pool, base)
|
||||
|
||||
struct dcn321_resource_pool {
|
||||
struct resource_pool base;
|
||||
};
|
||||
|
||||
struct resource_pool *dcn321_create_resource_pool(
|
||||
const struct dc_init_data *init_data,
|
||||
struct dc *dc);
|
||||
|
||||
#endif /* _DCN321_RESOURCE_H_ */
|
Loading…
x
Reference in New Issue
Block a user