mirror of https://github.com/torvalds/linux.git
drm/amd/display: Migrate DIO registers access from hwseq to dio component.
[why] Direct DIO registers access in hwseq layer was creating register conflicts. [how] Migrated DIO registers from hwseq to dio component. Reviewed-by: Jun Lei <Jun.Lei@amd.com> Signed-off-by: Bhuvanachandra Pinninti <bpinnint@amd.com> Signed-off-by: Wayne Lin <wayne.lin@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
c2d2ccc85f
commit
b82f075934
|
|
@ -27,7 +27,7 @@ ifdef CONFIG_DRM_AMD_DC_FP
|
|||
###############################################################################
|
||||
# DCN10
|
||||
###############################################################################
|
||||
DIO_DCN10 = dcn10_link_encoder.o dcn10_stream_encoder.o
|
||||
DIO_DCN10 = dcn10_link_encoder.o dcn10_stream_encoder.o dcn10_dio.o
|
||||
|
||||
AMD_DAL_DIO_DCN10 = $(addprefix $(AMDDALPATH)/dc/dio/dcn10/,$(DIO_DCN10))
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright 2025 Advanced Micro Devices, Inc.
|
||||
|
||||
#include "dc_hw_types.h"
|
||||
#include "dm_services.h"
|
||||
#include "reg_helper.h"
|
||||
#include "dcn10_dio.h"
|
||||
|
||||
#define CTX \
|
||||
dio10->base.ctx
|
||||
#define REG(reg)\
|
||||
dio10->regs->reg
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
dio10->shifts->field_name, dio10->masks->field_name
|
||||
|
||||
static void dcn10_dio_mem_pwr_ctrl(struct dio *dio, bool enable_i2c_light_sleep)
|
||||
{
|
||||
struct dcn10_dio *dio10 = TO_DCN10_DIO(dio);
|
||||
|
||||
/* power AFMT HDMI memory */
|
||||
REG_WRITE(DIO_MEM_PWR_CTRL, 0);
|
||||
|
||||
if (enable_i2c_light_sleep)
|
||||
REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1);
|
||||
}
|
||||
|
||||
static const struct dio_funcs dcn10_dio_funcs = {
|
||||
.mem_pwr_ctrl = dcn10_dio_mem_pwr_ctrl,
|
||||
};
|
||||
|
||||
void dcn10_dio_construct(
|
||||
struct dcn10_dio *dio10,
|
||||
struct dc_context *ctx,
|
||||
const struct dcn_dio_registers *regs,
|
||||
const struct dcn_dio_shift *shifts,
|
||||
const struct dcn_dio_mask *masks)
|
||||
{
|
||||
dio10->base.ctx = ctx;
|
||||
dio10->base.funcs = &dcn10_dio_funcs;
|
||||
|
||||
dio10->regs = regs;
|
||||
dio10->shifts = shifts;
|
||||
dio10->masks = masks;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright 2025 Advanced Micro Devices, Inc.
|
||||
|
||||
#ifndef __DCN10_DIO_H__
|
||||
#define __DCN10_DIO_H__
|
||||
|
||||
#include "dio.h"
|
||||
|
||||
#define TO_DCN10_DIO(dio_base) \
|
||||
container_of(dio_base, struct dcn10_dio, base)
|
||||
|
||||
#define DIO_REG_LIST_DCN10()\
|
||||
SR(DIO_MEM_PWR_CTRL)
|
||||
|
||||
struct dcn_dio_registers {
|
||||
uint32_t DIO_MEM_PWR_CTRL;
|
||||
};
|
||||
|
||||
struct dcn_dio_shift {
|
||||
uint8_t I2C_LIGHT_SLEEP_FORCE;
|
||||
};
|
||||
|
||||
struct dcn_dio_mask {
|
||||
uint32_t I2C_LIGHT_SLEEP_FORCE;
|
||||
};
|
||||
|
||||
struct dcn10_dio {
|
||||
struct dio base;
|
||||
const struct dcn_dio_registers *regs;
|
||||
const struct dcn_dio_shift *shifts;
|
||||
const struct dcn_dio_mask *masks;
|
||||
};
|
||||
|
||||
void dcn10_dio_construct(
|
||||
struct dcn10_dio *dio10,
|
||||
struct dc_context *ctx,
|
||||
const struct dcn_dio_registers *regs,
|
||||
const struct dcn_dio_shift *shifts,
|
||||
const struct dcn_dio_mask *masks);
|
||||
|
||||
#endif /* __DCN10_DIO_H__ */
|
||||
|
|
@ -50,6 +50,7 @@
|
|||
#include "link_hwss.h"
|
||||
#include "dpcd_defs.h"
|
||||
#include "dsc.h"
|
||||
#include "dio/dcn10/dcn10_dio.h"
|
||||
#include "dce/dmub_psr.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "dce/dmub_hw_lock_mgr.h"
|
||||
|
|
@ -1881,7 +1882,8 @@ void dcn10_init_hw(struct dc *dc)
|
|||
|
||||
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
|
||||
if (!is_optimized_init_done)
|
||||
REG_WRITE(DIO_MEM_PWR_CTRL, 0);
|
||||
if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
|
||||
dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false);
|
||||
|
||||
if (!dc->debug.disable_clock_gate) {
|
||||
/* enable all DCN clock gating */
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@
|
|||
#include "clk_mgr.h"
|
||||
#include "reg_helper.h"
|
||||
#include "dcn10/dcn10_hubbub.h"
|
||||
#include "dio/dcn10/dcn10_dio.h"
|
||||
|
||||
|
||||
#define CTX \
|
||||
hws->ctx
|
||||
|
|
@ -360,7 +362,8 @@ void dcn201_init_hw(struct dc *dc)
|
|||
}
|
||||
|
||||
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
|
||||
REG_WRITE(DIO_MEM_PWR_CTRL, 0);
|
||||
if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
|
||||
dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false);
|
||||
|
||||
if (!dc->debug.disable_clock_gate) {
|
||||
/* enable all DCN clock gating */
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include "dcn30/dcn30_resource.h"
|
||||
#include "link_service.h"
|
||||
#include "dc_state_priv.h"
|
||||
#include "dio/dcn10/dcn10_dio.h"
|
||||
|
||||
#define TO_DCN_DCCG(dccg)\
|
||||
container_of(dccg, struct dcn_dccg, base)
|
||||
|
|
@ -794,7 +795,8 @@ void dcn30_init_hw(struct dc *dc)
|
|||
}
|
||||
|
||||
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
|
||||
REG_WRITE(DIO_MEM_PWR_CTRL, 0);
|
||||
if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
|
||||
dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false);
|
||||
|
||||
if (!dc->debug.disable_clock_gate) {
|
||||
/* enable all DCN clock gating */
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include "dcn30/dcn30_vpg.h"
|
||||
#include "dce/dce_i2c_hw.h"
|
||||
#include "dce/dmub_abm_lcd.h"
|
||||
#include "dio/dcn10/dcn10_dio.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
|
|
@ -237,12 +238,9 @@ void dcn31_init_hw(struct dc *dc)
|
|||
abms[i]->funcs->abm_init(abms[i], backlight, user_level);
|
||||
}
|
||||
|
||||
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
|
||||
REG_WRITE(DIO_MEM_PWR_CTRL, 0);
|
||||
|
||||
// Set i2c to light sleep until engine is setup
|
||||
if (dc->debug.enable_mem_low_power.bits.i2c)
|
||||
REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1);
|
||||
/* Power on DIO memory (AFMT HDMI) and set I2C to light sleep */
|
||||
if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
|
||||
dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, dc->debug.enable_mem_low_power.bits.i2c);
|
||||
|
||||
if (hws->funcs.setup_hpo_hw_control)
|
||||
hws->funcs.setup_hpo_hw_control(hws, false);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include "link_service.h"
|
||||
#include "../dcn20/dcn20_hwseq.h"
|
||||
#include "dc_state_priv.h"
|
||||
#include "dio/dcn10/dcn10_dio.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
|
|
@ -955,7 +956,8 @@ void dcn32_init_hw(struct dc *dc)
|
|||
}
|
||||
|
||||
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
|
||||
REG_WRITE(DIO_MEM_PWR_CTRL, 0);
|
||||
if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
|
||||
dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false);
|
||||
|
||||
if (!dc->debug.disable_clock_gate) {
|
||||
/* enable all DCN clock gating */
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include "dcn30/dcn30_vpg.h"
|
||||
#include "dce/dce_i2c_hw.h"
|
||||
#include "dsc.h"
|
||||
#include "dio/dcn10/dcn10_dio.h"
|
||||
#include "dcn20/dcn20_optc.h"
|
||||
#include "dcn30/dcn30_cm_common.h"
|
||||
#include "dcn31/dcn31_hwseq.h"
|
||||
|
|
@ -272,12 +273,9 @@ void dcn35_init_hw(struct dc *dc)
|
|||
}
|
||||
}
|
||||
|
||||
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
|
||||
REG_WRITE(DIO_MEM_PWR_CTRL, 0);
|
||||
|
||||
// Set i2c to light sleep until engine is setup
|
||||
if (dc->debug.enable_mem_low_power.bits.i2c)
|
||||
REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 0);
|
||||
/* Power on DIO memory (AFMT HDMI) and optionally disable I2C light sleep */
|
||||
if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
|
||||
dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, !dc->debug.enable_mem_low_power.bits.i2c);
|
||||
|
||||
if (hws->funcs.setup_hpo_hw_control)
|
||||
hws->funcs.setup_hpo_hw_control(hws, false);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "dc_state_priv.h"
|
||||
#include "link_enc_cfg.h"
|
||||
#include "../hw_sequencer.h"
|
||||
#include "dio/dcn10/dcn10_dio.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
|
|
@ -320,7 +321,8 @@ void dcn401_init_hw(struct dc *dc)
|
|||
}
|
||||
|
||||
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
|
||||
REG_WRITE(DIO_MEM_PWR_CTRL, 0);
|
||||
if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
|
||||
dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false);
|
||||
|
||||
if (!dc->debug.disable_clock_gate) {
|
||||
/* enable all DCN clock gating */
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "hubp.h"
|
||||
#include "mpc.h"
|
||||
#include "dwb.h"
|
||||
#include "hw/dio.h"
|
||||
#include "mcif_wb.h"
|
||||
#include "panel_cntl.h"
|
||||
#include "dmub/inc/dmub_cmd.h"
|
||||
|
|
@ -250,6 +251,7 @@ struct resource_pool {
|
|||
struct timing_generator *timing_generators[MAX_PIPES];
|
||||
struct stream_encoder *stream_enc[MAX_PIPES * 2];
|
||||
struct hubbub *hubbub;
|
||||
struct dio *dio;
|
||||
struct mpc *mpc;
|
||||
struct pp_smu_funcs *pp_smu;
|
||||
struct dce_aux *engines[MAX_PIPES];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright 2025 Advanced Micro Devices, Inc.
|
||||
|
||||
#ifndef __DC_DIO_H__
|
||||
#define __DC_DIO_H__
|
||||
|
||||
#include "dc_types.h"
|
||||
|
||||
struct dc_context;
|
||||
struct dio;
|
||||
|
||||
struct dio_funcs {
|
||||
void (*mem_pwr_ctrl)(struct dio *dio, bool enable_i2c_light_sleep);
|
||||
};
|
||||
|
||||
struct dio {
|
||||
const struct dio_funcs *funcs;
|
||||
struct dc_context *ctx;
|
||||
};
|
||||
|
||||
#endif /* __DC_DIO_H__ */
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#include "dcn401/dcn401_hubbub.h"
|
||||
#include "dcn401/dcn401_mpc.h"
|
||||
#include "dcn401/dcn401_hubp.h"
|
||||
#include "dio/dcn10/dcn10_dio.h"
|
||||
#include "irq/dcn401/irq_service_dcn401.h"
|
||||
#include "dcn401/dcn401_dpp.h"
|
||||
#include "dcn401/dcn401_optc.h"
|
||||
|
|
@ -634,6 +635,22 @@ static const struct dcn20_vmid_mask vmid_masks = {
|
|||
DCN20_VMID_MASK_SH_LIST(_MASK)
|
||||
};
|
||||
|
||||
#define dio_regs_init() \
|
||||
DIO_REG_LIST_DCN10()
|
||||
|
||||
static struct dcn_dio_registers dio_regs;
|
||||
|
||||
#define DIO_MASK_SH_LIST_DCN401(mask_sh)\
|
||||
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
|
||||
|
||||
static const struct dcn_dio_shift dio_shift = {
|
||||
DIO_MASK_SH_LIST_DCN401(__SHIFT)
|
||||
};
|
||||
|
||||
static const struct dcn_dio_mask dio_mask = {
|
||||
DIO_MASK_SH_LIST_DCN401(_MASK)
|
||||
};
|
||||
|
||||
static const struct resource_caps res_cap_dcn4_01 = {
|
||||
.num_timing_generator = 4,
|
||||
.num_opp = 4,
|
||||
|
|
@ -881,6 +898,22 @@ static struct hubbub *dcn401_hubbub_create(struct dc_context *ctx)
|
|||
return &hubbub2->base;
|
||||
}
|
||||
|
||||
static struct dio *dcn401_dio_create(struct dc_context *ctx)
|
||||
{
|
||||
struct dcn10_dio *dio10 = kzalloc(sizeof(struct dcn10_dio), GFP_KERNEL);
|
||||
|
||||
if (!dio10)
|
||||
return NULL;
|
||||
|
||||
#undef REG_STRUCT
|
||||
#define REG_STRUCT dio_regs
|
||||
dio_regs_init();
|
||||
|
||||
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
|
||||
|
||||
return &dio10->base;
|
||||
}
|
||||
|
||||
static struct hubp *dcn401_hubp_create(
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst)
|
||||
|
|
@ -2071,6 +2104,14 @@ static bool dcn401_resource_construct(
|
|||
goto create_fail;
|
||||
}
|
||||
|
||||
/* DIO */
|
||||
pool->base.dio = dcn401_dio_create(ctx);
|
||||
if (pool->base.dio == NULL) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
dm_error("DC: failed to create dio!\n");
|
||||
goto create_fail;
|
||||
}
|
||||
|
||||
/* HUBPs, DPPs, OPPs, TGs, ABMs */
|
||||
for (i = 0, j = 0; i < pool->base.res_cap->num_timing_generator; i++) {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue