Commit 9932ca4c authored by Dillon Varone's avatar Dillon Varone Committed by Alex Deucher

drm/amd/display: Add P-State Keepout to dcn401 Global Sync

[WHY&HOW]
OTG has new functionality to allow P-State relative to VStartup. Keepout region
for this should be configured based on DML outputs same as other global sync
params.
Reviewed-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Signed-off-by: default avatarJerry Zuo <jerry.zuo@amd.com>
Signed-off-by: default avatarDillon Varone <dillon.varone@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f8220070
...@@ -1955,6 +1955,7 @@ void dce110_tg_program_timing(struct timing_generator *tg, ...@@ -1955,6 +1955,7 @@ void dce110_tg_program_timing(struct timing_generator *tg,
int vstartup_start, int vstartup_start,
int vupdate_offset, int vupdate_offset,
int vupdate_width, int vupdate_width,
int pstate_keepout,
const enum signal_type signal, const enum signal_type signal,
bool use_vbios) bool use_vbios)
{ {
......
...@@ -261,6 +261,7 @@ void dce110_tg_program_timing(struct timing_generator *tg, ...@@ -261,6 +261,7 @@ void dce110_tg_program_timing(struct timing_generator *tg,
int vstartup_start, int vstartup_start,
int vupdate_offset, int vupdate_offset,
int vupdate_width, int vupdate_width,
int pstate_keepout,
const enum signal_type signal, const enum signal_type signal,
bool use_vbios); bool use_vbios);
......
...@@ -438,6 +438,7 @@ static void dce110_timing_generator_v_program_timing(struct timing_generator *tg ...@@ -438,6 +438,7 @@ static void dce110_timing_generator_v_program_timing(struct timing_generator *tg
int vstartup_start, int vstartup_start,
int vupdate_offset, int vupdate_offset,
int vupdate_width, int vupdate_width,
int pstate_keepout,
const enum signal_type signal, const enum signal_type signal,
bool use_vbios) bool use_vbios)
{ {
......
...@@ -697,6 +697,7 @@ static void dce120_tg_program_timing(struct timing_generator *tg, ...@@ -697,6 +697,7 @@ static void dce120_tg_program_timing(struct timing_generator *tg,
int vstartup_start, int vstartup_start,
int vupdate_offset, int vupdate_offset,
int vupdate_width, int vupdate_width,
int pstate_keepout,
const enum signal_type signal, const enum signal_type signal,
bool use_vbios) bool use_vbios)
{ {
......
...@@ -111,13 +111,14 @@ static void program_timing(struct timing_generator *tg, ...@@ -111,13 +111,14 @@ static void program_timing(struct timing_generator *tg,
int vstartup_start, int vstartup_start,
int vupdate_offset, int vupdate_offset,
int vupdate_width, int vupdate_width,
int pstate_keepout,
const enum signal_type signal, const enum signal_type signal,
bool use_vbios) bool use_vbios)
{ {
if (!use_vbios) if (!use_vbios)
program_pix_dur(tg, timing->pix_clk_100hz); program_pix_dur(tg, timing->pix_clk_100hz);
dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, use_vbios); dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, 0, use_vbios);
} }
static void dce60_timing_generator_enable_advanced_request( static void dce60_timing_generator_enable_advanced_request(
......
...@@ -111,13 +111,14 @@ static void program_timing(struct timing_generator *tg, ...@@ -111,13 +111,14 @@ static void program_timing(struct timing_generator *tg,
int vstartup_start, int vstartup_start,
int vupdate_offset, int vupdate_offset,
int vupdate_width, int vupdate_width,
int pstate_keepout,
const enum signal_type signal, const enum signal_type signal,
bool use_vbios) bool use_vbios)
{ {
if (!use_vbios) if (!use_vbios)
program_pix_dur(tg, timing->pix_clk_100hz); program_pix_dur(tg, timing->pix_clk_100hz);
dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, use_vbios); dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, 0, use_vbios);
} }
static void dce80_timing_generator_enable_advanced_request( static void dce80_timing_generator_enable_advanced_request(
......
...@@ -523,6 +523,7 @@ struct _vcs_dpi_display_pipe_dest_params_st { ...@@ -523,6 +523,7 @@ struct _vcs_dpi_display_pipe_dest_params_st {
unsigned int vupdate_offset; unsigned int vupdate_offset;
unsigned int vupdate_width; unsigned int vupdate_width;
unsigned int vready_offset; unsigned int vready_offset;
unsigned int pstate_keepout;
unsigned char interlaced; unsigned char interlaced;
double pixel_rate_mhz; double pixel_rate_mhz;
unsigned char synchronized_vblank_all_planes; unsigned char synchronized_vblank_all_planes;
......
...@@ -1129,6 +1129,7 @@ void dml21_populate_pipe_ctx_dlg_params(struct dml2_context *dml_ctx, struct dc_ ...@@ -1129,6 +1129,7 @@ void dml21_populate_pipe_ctx_dlg_params(struct dml2_context *dml_ctx, struct dc_
pipe_ctx->pipe_dlg_param.vupdate_offset = global_sync->dcn4.vupdate_offset_pixels; pipe_ctx->pipe_dlg_param.vupdate_offset = global_sync->dcn4.vupdate_offset_pixels;
pipe_ctx->pipe_dlg_param.vupdate_width = global_sync->dcn4.vupdate_vupdate_width_pixels; pipe_ctx->pipe_dlg_param.vupdate_width = global_sync->dcn4.vupdate_vupdate_width_pixels;
pipe_ctx->pipe_dlg_param.vready_offset = global_sync->dcn4.vready_offset_pixels; pipe_ctx->pipe_dlg_param.vready_offset = global_sync->dcn4.vready_offset_pixels;
pipe_ctx->pipe_dlg_param.pstate_keepout = global_sync->dcn4.pstate_keepout_start_lines;
pipe_ctx->pipe_dlg_param.otg_inst = pipe_ctx->stream_res.tg->inst; pipe_ctx->pipe_dlg_param.otg_inst = pipe_ctx->stream_res.tg->inst;
......
...@@ -1549,6 +1549,7 @@ static enum dc_status dce110_enable_stream_timing( ...@@ -1549,6 +1549,7 @@ static enum dc_status dce110_enable_stream_timing(
0, 0,
0, 0,
0, 0,
0,
pipe_ctx->stream->signal, pipe_ctx->stream->signal,
true); true);
} }
......
...@@ -1005,6 +1005,7 @@ enum dc_status dcn10_enable_stream_timing( ...@@ -1005,6 +1005,7 @@ enum dc_status dcn10_enable_stream_timing(
pipe_ctx->pipe_dlg_param.vstartup_start, pipe_ctx->pipe_dlg_param.vstartup_start,
pipe_ctx->pipe_dlg_param.vupdate_offset, pipe_ctx->pipe_dlg_param.vupdate_offset,
pipe_ctx->pipe_dlg_param.vupdate_width, pipe_ctx->pipe_dlg_param.vupdate_width,
pipe_ctx->pipe_dlg_param.pstate_keepout,
pipe_ctx->stream->signal, pipe_ctx->stream->signal,
true); true);
...@@ -2995,7 +2996,8 @@ void dcn10_program_pipe( ...@@ -2995,7 +2996,8 @@ void dcn10_program_pipe(
calculate_vready_offset_for_group(pipe_ctx), calculate_vready_offset_for_group(pipe_ctx),
pipe_ctx->pipe_dlg_param.vstartup_start, pipe_ctx->pipe_dlg_param.vstartup_start,
pipe_ctx->pipe_dlg_param.vupdate_offset, pipe_ctx->pipe_dlg_param.vupdate_offset,
pipe_ctx->pipe_dlg_param.vupdate_width); pipe_ctx->pipe_dlg_param.vupdate_width,
pipe_ctx->pipe_dlg_param.pstate_keepout);
pipe_ctx->stream_res.tg->funcs->set_vtg_params( pipe_ctx->stream_res.tg->funcs->set_vtg_params(
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, true); pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, true);
......
...@@ -909,6 +909,7 @@ enum dc_status dcn20_enable_stream_timing( ...@@ -909,6 +909,7 @@ enum dc_status dcn20_enable_stream_timing(
pipe_ctx->pipe_dlg_param.vstartup_start, pipe_ctx->pipe_dlg_param.vstartup_start,
pipe_ctx->pipe_dlg_param.vupdate_offset, pipe_ctx->pipe_dlg_param.vupdate_offset,
pipe_ctx->pipe_dlg_param.vupdate_width, pipe_ctx->pipe_dlg_param.vupdate_width,
pipe_ctx->pipe_dlg_param.pstate_keepout,
pipe_ctx->stream->signal, pipe_ctx->stream->signal,
true); true);
...@@ -1885,7 +1886,8 @@ static void dcn20_program_pipe( ...@@ -1885,7 +1886,8 @@ static void dcn20_program_pipe(
calculate_vready_offset_for_group(pipe_ctx), calculate_vready_offset_for_group(pipe_ctx),
pipe_ctx->pipe_dlg_param.vstartup_start, pipe_ctx->pipe_dlg_param.vstartup_start,
pipe_ctx->pipe_dlg_param.vupdate_offset, pipe_ctx->pipe_dlg_param.vupdate_offset,
pipe_ctx->pipe_dlg_param.vupdate_width); pipe_ctx->pipe_dlg_param.vupdate_width,
pipe_ctx->pipe_dlg_param.pstate_keepout);
if (dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM) if (dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM)
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE); pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
...@@ -2458,7 +2460,8 @@ bool dcn20_update_bandwidth( ...@@ -2458,7 +2460,8 @@ bool dcn20_update_bandwidth(
calculate_vready_offset_for_group(pipe_ctx), calculate_vready_offset_for_group(pipe_ctx),
pipe_ctx->pipe_dlg_param.vstartup_start, pipe_ctx->pipe_dlg_param.vstartup_start,
pipe_ctx->pipe_dlg_param.vupdate_offset, pipe_ctx->pipe_dlg_param.vupdate_offset,
pipe_ctx->pipe_dlg_param.vupdate_width); pipe_ctx->pipe_dlg_param.vupdate_width,
pipe_ctx->pipe_dlg_param.pstate_keepout);
pipe_ctx->stream_res.tg->funcs->set_vtg_params( pipe_ctx->stream_res.tg->funcs->set_vtg_params(
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, false); pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, false);
......
...@@ -871,6 +871,7 @@ enum dc_status dcn401_enable_stream_timing( ...@@ -871,6 +871,7 @@ enum dc_status dcn401_enable_stream_timing(
pipe_ctx->pipe_dlg_param.vstartup_start, pipe_ctx->pipe_dlg_param.vstartup_start,
pipe_ctx->pipe_dlg_param.vupdate_offset, pipe_ctx->pipe_dlg_param.vupdate_offset,
pipe_ctx->pipe_dlg_param.vupdate_width, pipe_ctx->pipe_dlg_param.vupdate_width,
pipe_ctx->pipe_dlg_param.pstate_keepout,
pipe_ctx->stream->signal, pipe_ctx->stream->signal,
true); true);
......
...@@ -65,6 +65,7 @@ struct optc { ...@@ -65,6 +65,7 @@ struct optc {
int vupdate_offset; int vupdate_offset;
int vupdate_width; int vupdate_width;
int vready_offset; int vready_offset;
int pstate_keepout;
struct dc_crtc_timing orginal_patched_timing; struct dc_crtc_timing orginal_patched_timing;
enum signal_type signal; enum signal_type signal;
}; };
...@@ -110,6 +111,7 @@ void optc1_program_timing(struct timing_generator *optc, ...@@ -110,6 +111,7 @@ void optc1_program_timing(struct timing_generator *optc,
int vstartup_start, int vstartup_start,
int vupdate_offset, int vupdate_offset,
int vupdate_width, int vupdate_width,
int pstate_keepout,
const enum signal_type signal, const enum signal_type signal,
bool use_vbios); bool use_vbios);
...@@ -127,7 +129,8 @@ void optc1_program_global_sync(struct timing_generator *optc, ...@@ -127,7 +129,8 @@ void optc1_program_global_sync(struct timing_generator *optc,
int vready_offset, int vready_offset,
int vstartup_start, int vstartup_start,
int vupdate_offset, int vupdate_offset,
int vupdate_width); int vupdate_width,
int pstate_keepout);
bool optc1_disable_crtc(struct timing_generator *optc); bool optc1_disable_crtc(struct timing_generator *optc);
......
...@@ -172,6 +172,7 @@ struct timing_generator_funcs { ...@@ -172,6 +172,7 @@ struct timing_generator_funcs {
int vstartup_start, int vstartup_start,
int vupdate_offset, int vupdate_offset,
int vupdate_width, int vupdate_width,
int pstate_keepout,
const enum signal_type signal, const enum signal_type signal,
bool use_vbios bool use_vbios
); );
...@@ -256,7 +257,8 @@ struct timing_generator_funcs { ...@@ -256,7 +257,8 @@ struct timing_generator_funcs {
int vready_offset, int vready_offset,
int vstartup_start, int vstartup_start,
int vupdate_offset, int vupdate_offset,
int vupdate_width); int vupdate_width,
int pstate_keepout);
void (*enable_optc_clock)(struct timing_generator *tg, bool enable); void (*enable_optc_clock)(struct timing_generator *tg, bool enable);
void (*program_stereo)(struct timing_generator *tg, void (*program_stereo)(struct timing_generator *tg,
const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags); const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags);
......
...@@ -65,7 +65,8 @@ void optc1_program_global_sync( ...@@ -65,7 +65,8 @@ void optc1_program_global_sync(
int vready_offset, int vready_offset,
int vstartup_start, int vstartup_start,
int vupdate_offset, int vupdate_offset,
int vupdate_width) int vupdate_width,
int pstate_keepout)
{ {
struct optc *optc1 = DCN10TG_FROM_TG(optc); struct optc *optc1 = DCN10TG_FROM_TG(optc);
...@@ -73,6 +74,7 @@ void optc1_program_global_sync( ...@@ -73,6 +74,7 @@ void optc1_program_global_sync(
optc1->vstartup_start = vstartup_start; optc1->vstartup_start = vstartup_start;
optc1->vupdate_offset = vupdate_offset; optc1->vupdate_offset = vupdate_offset;
optc1->vupdate_width = vupdate_width; optc1->vupdate_width = vupdate_width;
optc1->pstate_keepout = pstate_keepout;
if (optc1->vstartup_start == 0) { if (optc1->vstartup_start == 0) {
BREAK_TO_DEBUGGER(); BREAK_TO_DEBUGGER();
...@@ -157,6 +159,7 @@ void optc1_program_timing( ...@@ -157,6 +159,7 @@ void optc1_program_timing(
int vstartup_start, int vstartup_start,
int vupdate_offset, int vupdate_offset,
int vupdate_width, int vupdate_width,
int pstate_keepout,
const enum signal_type signal, const enum signal_type signal,
bool use_vbios) bool use_vbios)
{ {
...@@ -177,6 +180,7 @@ void optc1_program_timing( ...@@ -177,6 +180,7 @@ void optc1_program_timing(
optc1->vstartup_start = vstartup_start; optc1->vstartup_start = vstartup_start;
optc1->vupdate_offset = vupdate_offset; optc1->vupdate_offset = vupdate_offset;
optc1->vupdate_width = vupdate_width; optc1->vupdate_width = vupdate_width;
optc1->pstate_keepout = pstate_keepout;
patched_crtc_timing = *dc_crtc_timing; patched_crtc_timing = *dc_crtc_timing;
apply_front_porch_workaround(&patched_crtc_timing); apply_front_porch_workaround(&patched_crtc_timing);
optc1->orginal_patched_timing = patched_crtc_timing; optc1->orginal_patched_timing = patched_crtc_timing;
...@@ -282,7 +286,8 @@ void optc1_program_timing( ...@@ -282,7 +286,8 @@ void optc1_program_timing(
vready_offset, vready_offset,
vstartup_start, vstartup_start,
vupdate_offset, vupdate_offset,
vupdate_width); vupdate_width,
pstate_keepout);
optc->funcs->set_vtg_params(optc, dc_crtc_timing, true); optc->funcs->set_vtg_params(optc, dc_crtc_timing, true);
......
...@@ -201,6 +201,7 @@ struct dcn_optc_registers { ...@@ -201,6 +201,7 @@ struct dcn_optc_registers {
uint32_t OTG_CRC1_WINDOWB_Y_CONTROL_READBACK; uint32_t OTG_CRC1_WINDOWB_Y_CONTROL_READBACK;
uint32_t OPTC_CLOCK_CONTROL; uint32_t OPTC_CLOCK_CONTROL;
uint32_t OPTC_WIDTH_CONTROL2; uint32_t OPTC_WIDTH_CONTROL2;
uint32_t OTG_PSTATE_REGISTER;
}; };
#define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\ #define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
...@@ -590,7 +591,11 @@ struct dcn_optc_registers { ...@@ -590,7 +591,11 @@ struct dcn_optc_registers {
type OTG_V_COUNT_STOP_TIMER; type OTG_V_COUNT_STOP_TIMER;
#define TG_REG_FIELD_LIST_DCN401(type) \ #define TG_REG_FIELD_LIST_DCN401(type) \
type OPTC_SEGMENT_WIDTH_LAST; type OPTC_SEGMENT_WIDTH_LAST;\
type OTG_PSTATE_KEEPOUT_START;\
type OTG_PSTATE_EXTEND;\
type OTG_UNBLANK;\
type OTG_PSTATE_ALLOW_WIDTH_MIN;
struct dcn_optc_shift { struct dcn_optc_shift {
......
...@@ -396,13 +396,47 @@ void optc401_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, i ...@@ -396,13 +396,47 @@ void optc401_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, i
} }
} }
static void optc401_program_global_sync(
struct timing_generator *optc,
int vready_offset,
int vstartup_start,
int vupdate_offset,
int vupdate_width,
int pstate_keepout)
{
struct optc *optc1 = DCN10TG_FROM_TG(optc);
optc1->vready_offset = vready_offset;
optc1->vstartup_start = vstartup_start;
optc1->vupdate_offset = vupdate_offset;
optc1->vupdate_width = vupdate_width;
optc1->pstate_keepout = pstate_keepout;
if (optc1->vstartup_start == 0) {
BREAK_TO_DEBUGGER();
return;
}
REG_SET(OTG_VSTARTUP_PARAM, 0,
VSTARTUP_START, optc1->vstartup_start);
REG_SET_2(OTG_VUPDATE_PARAM, 0,
VUPDATE_OFFSET, optc1->vupdate_offset,
VUPDATE_WIDTH, optc1->vupdate_width);
REG_SET(OTG_VREADY_PARAM, 0,
VREADY_OFFSET, optc1->vready_offset);
REG_UPDATE(OTG_PSTATE_REGISTER, OTG_PSTATE_KEEPOUT_START, pstate_keepout);
}
static struct timing_generator_funcs dcn401_tg_funcs = { static struct timing_generator_funcs dcn401_tg_funcs = {
.validate_timing = optc1_validate_timing, .validate_timing = optc1_validate_timing,
.program_timing = optc1_program_timing, .program_timing = optc1_program_timing,
.setup_vertical_interrupt0 = optc1_setup_vertical_interrupt0, .setup_vertical_interrupt0 = optc1_setup_vertical_interrupt0,
.setup_vertical_interrupt1 = optc1_setup_vertical_interrupt1, .setup_vertical_interrupt1 = optc1_setup_vertical_interrupt1,
.setup_vertical_interrupt2 = optc1_setup_vertical_interrupt2, .setup_vertical_interrupt2 = optc1_setup_vertical_interrupt2,
.program_global_sync = optc1_program_global_sync, .program_global_sync = optc401_program_global_sync,
.enable_crtc = optc401_enable_crtc, .enable_crtc = optc401_enable_crtc,
.disable_crtc = optc401_disable_crtc, .disable_crtc = optc401_disable_crtc,
.phantom_crtc_post_enable = optc401_phantom_crtc_post_enable, .phantom_crtc_post_enable = optc401_phantom_crtc_post_enable,
......
...@@ -155,7 +155,11 @@ ...@@ -155,7 +155,11 @@
SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE, mask_sh),\ SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE, mask_sh),\
SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE_MANUAL, mask_sh),\ SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE_MANUAL, mask_sh),\
SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_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) SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh),\
SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_KEEPOUT_START, mask_sh),\
SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_EXTEND, mask_sh),\
SF(OTG0_OTG_PSTATE_REGISTER, OTG_UNBLANK, mask_sh),\
SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_ALLOW_WIDTH_MIN, mask_sh)
void dcn401_timing_generator_init(struct optc *optc1); void dcn401_timing_generator_init(struct optc *optc1);
......
...@@ -1163,6 +1163,7 @@ static struct pipe_ctx *dce110_acquire_underlay( ...@@ -1163,6 +1163,7 @@ static struct pipe_ctx *dce110_acquire_underlay(
0, 0,
0, 0,
0, 0,
0,
pipe_ctx->stream->signal, pipe_ctx->stream->signal,
false); false);
......
...@@ -534,7 +534,8 @@ void dcn401_prepare_mcache_programming(struct dc *dc, struct dc_state *context); ...@@ -534,7 +534,8 @@ void dcn401_prepare_mcache_programming(struct dc *dc, struct dc_state *context);
SRI_ARR(OPTC_WIDTH_CONTROL, ODM, inst), \ SRI_ARR(OPTC_WIDTH_CONTROL, ODM, inst), \
SRI_ARR(OPTC_WIDTH_CONTROL2, ODM, inst), \ SRI_ARR(OPTC_WIDTH_CONTROL2, ODM, inst), \
SRI_ARR(OPTC_MEMORY_CONFIG, ODM, inst), \ SRI_ARR(OPTC_MEMORY_CONFIG, ODM, inst), \
SRI_ARR(OTG_DRR_CONTROL, OTG, inst) SRI_ARR(OTG_DRR_CONTROL, OTG, inst), \
SRI_ARR(OTG_PSTATE_REGISTER, OTG, inst)
/* HUBBUB */ /* HUBBUB */
#define HUBBUB_REG_LIST_DCN4_01_RI(id) \ #define HUBBUB_REG_LIST_DCN4_01_RI(id) \
......
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