Commit 18b4f1a0 authored by Michael Strauss's avatar Michael Strauss Committed by Alex Deucher

drm/amd/display: Add VPG and AFMT low power support for DCN3.1

[WHY]
Power down VPG and AFMT blocks when not in use

[HOW]
Create afmt31 and vpg31 structs and add necessary fields to reg list
Reviewed-by: default avatarEric Yang <eric.yang2@amd.com>
Acked-by: default avatarMikita Lipski <mikita.lipski@amd.com>
Signed-off-by: default avatarMichael Strauss <michael.strauss@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9b3d7652
......@@ -71,6 +71,8 @@
#include "dmub/dmub_srv.h"
#include "dcn30/dcn30_vpg.h"
#include "i2caux_interface.h"
#include "dce/dmub_hw_lock_mgr.h"
......@@ -2555,6 +2557,9 @@ static void commit_planes_do_stream_update(struct dc *dc,
enum surface_update_type update_type,
struct dc_state *context)
{
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct vpg *vpg;
#endif
int j;
// Stream updates
......@@ -2575,6 +2580,11 @@ static void commit_planes_do_stream_update(struct dc *dc,
stream_update->vrr_infopacket ||
stream_update->vsc_infopacket ||
stream_update->vsp_infopacket) {
#if defined(CONFIG_DRM_AMD_DC_DCN)
vpg = pipe_ctx->stream_res.stream_enc->vpg;
if (vpg && vpg->funcs->vpg_poweron)
vpg->funcs->vpg_poweron(vpg);
#endif
resource_build_info_frame(pipe_ctx);
dc->hwss.update_info_frame(pipe_ctx);
}
......
......@@ -51,6 +51,8 @@
#include "inc/link_enc_cfg.h"
#include "inc/link_dpcd.h"
#include "dc/dcn30/dcn30_vpg.h"
#define DC_LOGGER_INIT(logger)
#define LINK_INFO(...) \
......@@ -3608,6 +3610,7 @@ void core_link_enable_stream(
struct link_encoder *link_enc;
#if defined(CONFIG_DRM_AMD_DC_DCN)
enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO;
struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
#endif
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
......@@ -3699,6 +3702,12 @@ void core_link_enable_stream(
pipe_ctx->stream->apply_edp_fast_boot_optimization = false;
#if defined(CONFIG_DRM_AMD_DC_DCN)
// Enable VPG before building infoframe
if (vpg && vpg->funcs->vpg_poweron)
vpg->funcs->vpg_poweron(vpg);
#endif
resource_build_info_frame(pipe_ctx);
dc->hwss.update_info_frame(pipe_ctx);
......@@ -3845,6 +3854,9 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
struct dc *dc = pipe_ctx->stream->ctx->dc;
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->sink->link;
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
#endif
if (!IS_DIAG_DC(dc->ctx->dce_environment) &&
dc_is_virtual_signal(pipe_ctx->stream->signal))
......@@ -3928,6 +3940,11 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, OUT_MUX_DIO);
}
#endif
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (vpg && vpg->funcs->vpg_powerdown)
vpg->funcs->vpg_powerdown(vpg);
#endif
}
void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
......
......@@ -471,6 +471,8 @@ union mem_low_power_enable_options {
bool cm: 1;
bool mpc: 1;
bool optc: 1;
bool vpg: 1;
bool afmt: 1;
} bits;
uint32_t u32All;
};
......
......@@ -31,6 +31,7 @@
#include "hw_shared.h"
#include "inc/link_dpcd.h"
#include "dpcd_defs.h"
#include "dcn30/dcn30_afmt.h"
#define DC_LOGGER \
enc1->base.ctx->logger
......@@ -1401,6 +1402,11 @@ static void enc1_se_disable_dp_audio(
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
uint32_t value = 0;
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (enc->afmt && enc->afmt->funcs->afmt_powerdown)
enc->afmt->funcs->afmt_powerdown(enc->afmt);
#endif
/* Disable Audio packets */
REG_UPDATE_5(DP_SEC_CNTL,
DP_SEC_ASP_ENABLE, 0,
......@@ -1464,6 +1470,10 @@ void enc1_se_hdmi_audio_setup(
void enc1_se_hdmi_audio_disable(
struct stream_encoder *enc)
{
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (enc->afmt && enc->afmt->funcs->afmt_powerdown)
enc->afmt->funcs->afmt_powerdown(enc->afmt);
#endif
enc1_se_enable_audio_clock(enc, false);
}
......
......@@ -44,11 +44,14 @@
afmt3->base.ctx
static void afmt3_setup_hdmi_audio(
void afmt3_setup_hdmi_audio(
struct afmt *afmt)
{
struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
if (afmt->funcs->afmt_poweron)
afmt->funcs->afmt_poweron(afmt);
/* AFMT_AUDIO_PACKET_CONTROL */
REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);
......@@ -113,7 +116,7 @@ static union audio_cea_channels speakers_to_channels(
return cea_channels;
}
static void afmt3_se_audio_setup(
void afmt3_se_audio_setup(
struct afmt *afmt,
unsigned int az_inst,
struct audio_info *audio_info)
......@@ -138,20 +141,24 @@ static void afmt3_se_audio_setup(
REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, channels);
/* Disable forced mem power off */
REG_UPDATE(AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, 0);
if (afmt->funcs->afmt_poweron == NULL)
REG_UPDATE(AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, 0);
}
static void afmt3_audio_mute_control(
void afmt3_audio_mute_control(
struct afmt *afmt,
bool mute)
{
struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
if (mute && afmt->funcs->afmt_powerdown)
afmt->funcs->afmt_powerdown(afmt);
if (!mute && afmt->funcs->afmt_poweron)
afmt->funcs->afmt_poweron(afmt);
/* enable/disable transmission of audio packets */
REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, !mute);
}
static void afmt3_audio_info_immediate_update(
void afmt3_audio_info_immediate_update(
struct afmt *afmt)
{
struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
......@@ -160,11 +167,14 @@ static void afmt3_audio_info_immediate_update(
REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);
}
static void afmt3_setup_dp_audio(
void afmt3_setup_dp_audio(
struct afmt *afmt)
{
struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
if (afmt->funcs->afmt_poweron)
afmt->funcs->afmt_poweron(afmt);
/* AFMT_AUDIO_PACKET_CONTROL */
REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);
......
......@@ -121,6 +121,12 @@ struct afmt_funcs {
void (*setup_dp_audio)(
struct afmt *afmt);
void (*afmt_poweron)(
struct afmt *afmt);
void (*afmt_powerdown)(
struct afmt *afmt);
};
struct afmt {
......@@ -136,6 +142,24 @@ struct dcn30_afmt {
const struct dcn30_afmt_mask *afmt_mask;
};
void afmt3_setup_hdmi_audio(
struct afmt *afmt);
void afmt3_se_audio_setup(
struct afmt *afmt,
unsigned int az_inst,
struct audio_info *audio_info);
void afmt3_audio_mute_control(
struct afmt *afmt,
bool mute);
void afmt3_audio_info_immediate_update(
struct afmt *afmt);
void afmt3_setup_dp_audio(
struct afmt *afmt);
void afmt3_construct(struct dcn30_afmt *afmt3,
struct dc_context *ctx,
uint32_t inst,
......
......@@ -704,6 +704,8 @@ static void enc3_se_setup_dp_audio(
static void enc3_se_dp_audio_enable(
struct stream_encoder *enc)
{
if (enc->afmt->funcs->afmt_poweron)
enc->afmt->funcs->afmt_poweron(enc->afmt);
enc1_se_enable_audio_clock(enc, true);
enc3_se_setup_dp_audio(enc);
enc1_se_enable_dp_audio(enc);
......
......@@ -43,7 +43,7 @@
vpg3->base.ctx
static void vpg3_update_generic_info_packet(
void vpg3_update_generic_info_packet(
struct vpg *vpg,
uint32_t packet_index,
const struct dc_info_packet *info_packet)
......
......@@ -139,6 +139,12 @@ struct vpg_funcs {
struct vpg *vpg,
uint32_t packet_index,
const struct dc_info_packet *info_packet);
void (*vpg_poweron)(
struct vpg *vpg);
void (*vpg_powerdown)(
struct vpg *vpg);
};
struct vpg {
......@@ -154,6 +160,11 @@ struct dcn30_vpg {
const struct dcn30_vpg_mask *vpg_mask;
};
void vpg3_update_generic_info_packet(
struct vpg *vpg,
uint32_t packet_index,
const struct dc_info_packet *info_packet);
void vpg3_construct(struct dcn30_vpg *vpg3,
struct dc_context *ctx,
uint32_t inst,
......
......@@ -12,7 +12,8 @@
DCN31 = dcn31_resource.o dcn31_hubbub.o dcn31_hwseq.o dcn31_init.o dcn31_hubp.o \
dcn31_dccg.o dcn31_optc.o dcn31_dio_link_encoder.o dcn31_panel_cntl.o \
dcn31_apg.o dcn31_hpo_dp_stream_encoder.o dcn31_hpo_dp_link_encoder.o
dcn31_apg.o dcn31_hpo_dp_stream_encoder.o dcn31_hpo_dp_link_encoder.o \
dcn31_afmt.o dcn31_vpg.o
ifdef CONFIG_X86
CFLAGS_$(AMDDALPATH)/dc/dcn31/dcn31_resource.o := -msse
......
/*
* 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 "hw_shared.h"
#include "dcn30/dcn30_afmt.h"
#include "dcn31_afmt.h"
#include "reg_helper.h"
#include "dc/dc.h"
#define DC_LOGGER \
afmt31->base.ctx->logger
#define REG(reg)\
(afmt31->regs->reg)
#undef FN
#define FN(reg_name, field_name) \
afmt31->afmt_shift->field_name, afmt31->afmt_mask->field_name
#define CTX \
afmt31->base.ctx
static struct afmt_funcs dcn31_afmt_funcs = {
.setup_hdmi_audio = afmt3_setup_hdmi_audio,
.se_audio_setup = afmt3_se_audio_setup,
.audio_mute_control = afmt3_audio_mute_control,
.audio_info_immediate_update = afmt3_audio_info_immediate_update,
.setup_dp_audio = afmt3_setup_dp_audio,
.afmt_powerdown = afmt31_powerdown,
.afmt_poweron = afmt31_poweron
};
void afmt31_powerdown(struct afmt *afmt)
{
struct dcn31_afmt *afmt31 = DCN31_AFMT_FROM_AFMT(afmt);
if (afmt->ctx->dc->debug.enable_mem_low_power.bits.afmt == false)
return;
REG_UPDATE_2(AFMT_MEM_PWR, AFMT_MEM_PWR_DIS, 0, AFMT_MEM_PWR_FORCE, 1);
}
void afmt31_poweron(struct afmt *afmt)
{
struct dcn31_afmt *afmt31 = DCN31_AFMT_FROM_AFMT(afmt);
if (afmt->ctx->dc->debug.enable_mem_low_power.bits.afmt == false)
return;
REG_UPDATE_2(AFMT_MEM_PWR, AFMT_MEM_PWR_DIS, 1, AFMT_MEM_PWR_FORCE, 0);
}
void afmt31_construct(struct dcn31_afmt *afmt31,
struct dc_context *ctx,
uint32_t inst,
const struct dcn31_afmt_registers *afmt_regs,
const struct dcn31_afmt_shift *afmt_shift,
const struct dcn31_afmt_mask *afmt_mask)
{
afmt31->base.ctx = ctx;
afmt31->base.inst = inst;
afmt31->base.funcs = &dcn31_afmt_funcs;
afmt31->regs = afmt_regs;
afmt31->afmt_shift = afmt_shift;
afmt31->afmt_mask = afmt_mask;
}
/*
* 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
*
*/
#ifndef __DAL_DCN31_AFMT_H__
#define __DAL_DCN31_AFMT_H__
#define DCN31_AFMT_FROM_AFMT(afmt)\
container_of(afmt, struct dcn31_afmt, base)
#define AFMT_DCN31_REG_LIST(id) \
SRI(AFMT_INFOFRAME_CONTROL0, AFMT, id), \
SRI(AFMT_VBI_PACKET_CONTROL, AFMT, id), \
SRI(AFMT_AUDIO_PACKET_CONTROL, AFMT, id), \
SRI(AFMT_AUDIO_PACKET_CONTROL2, AFMT, id), \
SRI(AFMT_AUDIO_SRC_CONTROL, AFMT, id), \
SRI(AFMT_60958_0, AFMT, id), \
SRI(AFMT_60958_1, AFMT, id), \
SRI(AFMT_60958_2, AFMT, id), \
SRI(AFMT_MEM_PWR, AFMT, id)
struct dcn31_afmt_registers {
uint32_t AFMT_INFOFRAME_CONTROL0;
uint32_t AFMT_VBI_PACKET_CONTROL;
uint32_t AFMT_AUDIO_PACKET_CONTROL;
uint32_t AFMT_AUDIO_PACKET_CONTROL2;
uint32_t AFMT_AUDIO_SRC_CONTROL;
uint32_t AFMT_60958_0;
uint32_t AFMT_60958_1;
uint32_t AFMT_60958_2;
uint32_t AFMT_MEM_PWR;
};
#define DCN31_AFMT_MASK_SH_LIST(mask_sh)\
SE_SF(AFMT0_AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, mask_sh),\
SE_SF(AFMT0_AFMT_AUDIO_SRC_CONTROL, AFMT_AUDIO_SRC_SELECT, mask_sh),\
SE_SF(AFMT0_AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, mask_sh),\
SE_SF(AFMT0_AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, mask_sh),\
SE_SF(AFMT0_AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_LAYOUT_OVRD, mask_sh),\
SE_SF(AFMT0_AFMT_AUDIO_PACKET_CONTROL2, AFMT_60958_OSF_OVRD, mask_sh),\
SE_SF(AFMT0_AFMT_60958_0, AFMT_60958_CS_CHANNEL_NUMBER_L, mask_sh),\
SE_SF(AFMT0_AFMT_60958_0, AFMT_60958_CS_CLOCK_ACCURACY, mask_sh),\
SE_SF(AFMT0_AFMT_60958_1, AFMT_60958_CS_CHANNEL_NUMBER_R, mask_sh),\
SE_SF(AFMT0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_2, mask_sh),\
SE_SF(AFMT0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_3, mask_sh),\
SE_SF(AFMT0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_4, mask_sh),\
SE_SF(AFMT0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_5, mask_sh),\
SE_SF(AFMT0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_6, mask_sh),\
SE_SF(AFMT0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_7, mask_sh),\
SE_SF(AFMT0_AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, mask_sh),\
SE_SF(AFMT0_AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, mask_sh),\
SE_SF(AFMT0_AFMT_MEM_PWR, AFMT_MEM_PWR_DIS, mask_sh),\
SE_SF(AFMT0_AFMT_MEM_PWR, AFMT_MEM_PWR_STATE, mask_sh)
#define AFMT_DCN31_REG_FIELD_LIST(type) \
type AFMT_AUDIO_INFO_UPDATE;\
type AFMT_AUDIO_SRC_SELECT;\
type AFMT_AUDIO_CHANNEL_ENABLE;\
type AFMT_60958_CS_UPDATE;\
type AFMT_AUDIO_LAYOUT_OVRD;\
type AFMT_60958_OSF_OVRD;\
type AFMT_60958_CS_CHANNEL_NUMBER_L;\
type AFMT_60958_CS_CLOCK_ACCURACY;\
type AFMT_60958_CS_CHANNEL_NUMBER_R;\
type AFMT_60958_CS_CHANNEL_NUMBER_2;\
type AFMT_60958_CS_CHANNEL_NUMBER_3;\
type AFMT_60958_CS_CHANNEL_NUMBER_4;\
type AFMT_60958_CS_CHANNEL_NUMBER_5;\
type AFMT_60958_CS_CHANNEL_NUMBER_6;\
type AFMT_60958_CS_CHANNEL_NUMBER_7;\
type AFMT_AUDIO_SAMPLE_SEND;\
type AFMT_MEM_PWR_FORCE;\
type AFMT_MEM_PWR_DIS;\
type AFMT_MEM_PWR_STATE
struct dcn31_afmt_shift {
AFMT_DCN31_REG_FIELD_LIST(uint8_t);
};
struct dcn31_afmt_mask {
AFMT_DCN31_REG_FIELD_LIST(uint32_t);
};
struct dcn31_afmt {
struct afmt base;
const struct dcn31_afmt_registers *regs;
const struct dcn31_afmt_shift *afmt_shift;
const struct dcn31_afmt_mask *afmt_mask;
};
void afmt31_poweron(
struct afmt *afmt);
void afmt31_powerdown(
struct afmt *afmt);
void afmt31_construct(struct dcn31_afmt *afmt31,
struct dc_context *ctx,
uint32_t inst,
const struct dcn31_afmt_registers *afmt_regs,
const struct dcn31_afmt_shift *afmt_shift,
const struct dcn31_afmt_mask *afmt_mask);
#endif
......@@ -56,6 +56,8 @@
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
#include "dcn31/dcn31_apg.h"
#include "dcn31/dcn31_dio_link_encoder.h"
#include "dcn31/dcn31_vpg.h"
#include "dcn31/dcn31_afmt.h"
#include "dce/dce_clock_source.h"
#include "dce/dce_audio.h"
#include "dce/dce_hwseq.h"
......@@ -414,10 +416,10 @@ static const struct dce_audio_mask audio_mask = {
#define vpg_regs(id)\
[id] = {\
VPG_DCN3_REG_LIST(id)\
VPG_DCN31_REG_LIST(id)\
}
static const struct dcn30_vpg_registers vpg_regs[] = {
static const struct dcn31_vpg_registers vpg_regs[] = {
vpg_regs(0),
vpg_regs(1),
vpg_regs(2),
......@@ -430,20 +432,20 @@ static const struct dcn30_vpg_registers vpg_regs[] = {
vpg_regs(9),
};
static const struct dcn30_vpg_shift vpg_shift = {
DCN3_VPG_MASK_SH_LIST(__SHIFT)
static const struct dcn31_vpg_shift vpg_shift = {
DCN31_VPG_MASK_SH_LIST(__SHIFT)
};
static const struct dcn30_vpg_mask vpg_mask = {
DCN3_VPG_MASK_SH_LIST(_MASK)
static const struct dcn31_vpg_mask vpg_mask = {
DCN31_VPG_MASK_SH_LIST(_MASK)
};
#define afmt_regs(id)\
[id] = {\
AFMT_DCN3_REG_LIST(id)\
AFMT_DCN31_REG_LIST(id)\
}
static const struct dcn30_afmt_registers afmt_regs[] = {
static const struct dcn31_afmt_registers afmt_regs[] = {
afmt_regs(0),
afmt_regs(1),
afmt_regs(2),
......@@ -452,12 +454,12 @@ static const struct dcn30_afmt_registers afmt_regs[] = {
afmt_regs(5)
};
static const struct dcn30_afmt_shift afmt_shift = {
DCN3_AFMT_MASK_SH_LIST(__SHIFT)
static const struct dcn31_afmt_shift afmt_shift = {
DCN31_AFMT_MASK_SH_LIST(__SHIFT)
};
static const struct dcn30_afmt_mask afmt_mask = {
DCN3_AFMT_MASK_SH_LIST(_MASK)
static const struct dcn31_afmt_mask afmt_mask = {
DCN31_AFMT_MASK_SH_LIST(_MASK)
};
#define apg_regs(id)\
......@@ -1014,6 +1016,8 @@ static const struct dc_debug_options debug_defaults_drv = {
.cm = false,
.mpc = false,
.optc = false,
.vpg = false,
.afmt = false,
}
},
.optimize_edp_link_rate = true,
......@@ -1298,34 +1302,40 @@ static struct vpg *dcn31_vpg_create(
struct dc_context *ctx,
uint32_t inst)
{
struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL);
struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL);
if (!vpg3)
if (!vpg31)
return NULL;
vpg3_construct(vpg3, ctx, inst,
vpg31_construct(vpg31, ctx, inst,
&vpg_regs[inst],
&vpg_shift,
&vpg_mask);
return &vpg3->base;
// Will re-enable hw block when we enable stream
// Check for enabled stream before powering down?
vpg31_powerdown(&vpg31->base);
return &vpg31->base;
}
static struct afmt *dcn31_afmt_create(
struct dc_context *ctx,
uint32_t inst)
{
struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL);
struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL);
if (!afmt3)
if (!afmt31)
return NULL;
afmt3_construct(afmt3, ctx, inst,
afmt31_construct(afmt31, ctx, inst,
&afmt_regs[inst],
&afmt_shift,
&afmt_mask);
return &afmt3->base;
// Light sleep by default, no need to power down here
return &afmt31->base;
}
static struct apg *dcn31_apg_create(
......
/*
* 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 "dcn30/dcn30_vpg.h"
#include "dcn31_vpg.h"
#include "reg_helper.h"
#include "dc/dc.h"
#define DC_LOGGER \
vpg31->base.ctx->logger
#define REG(reg)\
(vpg31->regs->reg)
#undef FN
#define FN(reg_name, field_name) \
vpg31->vpg_shift->field_name, vpg31->vpg_mask->field_name
#define CTX \
vpg31->base.ctx
static struct vpg_funcs dcn31_vpg_funcs = {
.update_generic_info_packet = vpg3_update_generic_info_packet,
.vpg_poweron = vpg31_poweron,
.vpg_powerdown = vpg31_powerdown,
};
void vpg31_powerdown(struct vpg *vpg)
{
struct dcn31_vpg *vpg31 = DCN31_VPG_FROM_VPG(vpg);
if (vpg->ctx->dc->debug.enable_mem_low_power.bits.vpg == false)
return;
REG_UPDATE_2(VPG_MEM_PWR, VPG_GSP_MEM_LIGHT_SLEEP_DIS, 0, VPG_GSP_LIGHT_SLEEP_FORCE, 1);
}
void vpg31_poweron(struct vpg *vpg)
{
struct dcn31_vpg *vpg31 = DCN31_VPG_FROM_VPG(vpg);
if (vpg->ctx->dc->debug.enable_mem_low_power.bits.vpg == false)
return;
REG_UPDATE_2(VPG_MEM_PWR, VPG_GSP_MEM_LIGHT_SLEEP_DIS, 1, VPG_GSP_LIGHT_SLEEP_FORCE, 0);
}
void vpg31_construct(struct dcn31_vpg *vpg31,
struct dc_context *ctx,
uint32_t inst,
const struct dcn31_vpg_registers *vpg_regs,
const struct dcn31_vpg_shift *vpg_shift,
const struct dcn31_vpg_mask *vpg_mask)
{
vpg31->base.ctx = ctx;
vpg31->base.inst = inst;
vpg31->base.funcs = &dcn31_vpg_funcs;
vpg31->regs = vpg_regs;
vpg31->vpg_shift = vpg_shift;
vpg31->vpg_mask = vpg_mask;
}
/*
* 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
*
*/
#ifndef __DAL_DCN31_VPG_H__
#define __DAL_DCN31_VPG_H__
#define DCN31_VPG_FROM_VPG(vpg)\
container_of(vpg, struct dcn31_vpg, base)
#define VPG_DCN31_REG_LIST(id) \
SRI(VPG_GENERIC_STATUS, VPG, id), \
SRI(VPG_GENERIC_PACKET_ACCESS_CTRL, VPG, id), \
SRI(VPG_GENERIC_PACKET_DATA, VPG, id), \
SRI(VPG_GSP_FRAME_UPDATE_CTRL, VPG, id), \
SRI(VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG, id), \
SRI(VPG_MEM_PWR, VPG, id)
struct dcn31_vpg_registers {
uint32_t VPG_GENERIC_STATUS;
uint32_t VPG_GENERIC_PACKET_ACCESS_CTRL;
uint32_t VPG_GENERIC_PACKET_DATA;
uint32_t VPG_GSP_FRAME_UPDATE_CTRL;
uint32_t VPG_GSP_IMMEDIATE_UPDATE_CTRL;
uint32_t VPG_MEM_PWR;
};
#define DCN31_VPG_MASK_SH_LIST(mask_sh)\
SE_SF(VPG0_VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_OCCURED, mask_sh),\
SE_SF(VPG0_VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_CLR, mask_sh),\
SE_SF(VPG0_VPG_GENERIC_PACKET_ACCESS_CTRL, VPG_GENERIC_DATA_INDEX, mask_sh),\
SE_SF(VPG0_VPG_GENERIC_PACKET_DATA, VPG_GENERIC_DATA_BYTE0, mask_sh),\
SE_SF(VPG0_VPG_GENERIC_PACKET_DATA, VPG_GENERIC_DATA_BYTE1, mask_sh),\
SE_SF(VPG0_VPG_GENERIC_PACKET_DATA, VPG_GENERIC_DATA_BYTE2, mask_sh),\
SE_SF(VPG0_VPG_GENERIC_PACKET_DATA, VPG_GENERIC_DATA_BYTE3, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC0_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC1_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC2_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC3_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC4_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC5_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC6_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC7_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC8_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC9_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC10_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC11_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC12_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC13_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC14_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC0_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC1_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC2_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC3_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC4_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC5_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC6_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC7_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC8_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC9_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC10_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC11_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC12_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC13_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC14_IMMEDIATE_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_MEM_PWR, VPG_GSP_MEM_LIGHT_SLEEP_DIS, mask_sh),\
SE_SF(VPG0_VPG_MEM_PWR, VPG_GSP_LIGHT_SLEEP_FORCE, mask_sh),\
SE_SF(VPG0_VPG_MEM_PWR, VPG_GSP_MEM_PWR_STATE, mask_sh)
#define VPG_DCN31_REG_FIELD_LIST(type) \
type VPG_GENERIC_CONFLICT_OCCURED;\
type VPG_GENERIC_CONFLICT_CLR;\
type VPG_GENERIC_DATA_INDEX;\
type VPG_GENERIC_DATA_BYTE0;\
type VPG_GENERIC_DATA_BYTE1;\
type VPG_GENERIC_DATA_BYTE2;\
type VPG_GENERIC_DATA_BYTE3;\
type VPG_GENERIC0_FRAME_UPDATE;\
type VPG_GENERIC1_FRAME_UPDATE;\
type VPG_GENERIC2_FRAME_UPDATE;\
type VPG_GENERIC3_FRAME_UPDATE;\
type VPG_GENERIC4_FRAME_UPDATE;\
type VPG_GENERIC5_FRAME_UPDATE;\
type VPG_GENERIC6_FRAME_UPDATE;\
type VPG_GENERIC7_FRAME_UPDATE;\
type VPG_GENERIC8_FRAME_UPDATE;\
type VPG_GENERIC9_FRAME_UPDATE;\
type VPG_GENERIC10_FRAME_UPDATE;\
type VPG_GENERIC11_FRAME_UPDATE;\
type VPG_GENERIC12_FRAME_UPDATE;\
type VPG_GENERIC13_FRAME_UPDATE;\
type VPG_GENERIC14_FRAME_UPDATE;\
type VPG_GENERIC0_IMMEDIATE_UPDATE;\
type VPG_GENERIC1_IMMEDIATE_UPDATE;\
type VPG_GENERIC2_IMMEDIATE_UPDATE;\
type VPG_GENERIC3_IMMEDIATE_UPDATE;\
type VPG_GENERIC4_IMMEDIATE_UPDATE;\
type VPG_GENERIC5_IMMEDIATE_UPDATE;\
type VPG_GENERIC6_IMMEDIATE_UPDATE;\
type VPG_GENERIC7_IMMEDIATE_UPDATE;\
type VPG_GENERIC8_IMMEDIATE_UPDATE;\
type VPG_GENERIC9_IMMEDIATE_UPDATE;\
type VPG_GENERIC10_IMMEDIATE_UPDATE;\
type VPG_GENERIC11_IMMEDIATE_UPDATE;\
type VPG_GENERIC12_IMMEDIATE_UPDATE;\
type VPG_GENERIC13_IMMEDIATE_UPDATE;\
type VPG_GENERIC14_IMMEDIATE_UPDATE;\
type VPG_GSP_MEM_LIGHT_SLEEP_DIS;\
type VPG_GSP_LIGHT_SLEEP_FORCE;\
type VPG_GSP_MEM_PWR_STATE
struct dcn31_vpg_shift {
VPG_DCN31_REG_FIELD_LIST(uint8_t);
};
struct dcn31_vpg_mask {
VPG_DCN31_REG_FIELD_LIST(uint32_t);
};
struct dcn31_vpg {
struct vpg base;
const struct dcn31_vpg_registers *regs;
const struct dcn31_vpg_shift *vpg_shift;
const struct dcn31_vpg_mask *vpg_mask;
};
void vpg31_poweron(
struct vpg *vpg);
void vpg31_powerdown(
struct vpg *vpg);
void vpg31_construct(struct dcn31_vpg *vpg31,
struct dc_context *ctx,
uint32_t inst,
const struct dcn31_vpg_registers *vpg_regs,
const struct dcn31_vpg_shift *vpg_shift,
const struct dcn31_vpg_mask *vpg_mask);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment