Skip to content

Commit d75e45b

Browse files
Timur Kristófalexdeucher
authored andcommitted
drm/amd/display: Add DAC_LoadDetection to BIOS parser (v2)
DAC_LoadDetection can be used to determine whether something is connected to an analog connector by determining if there is an analog load. This causes visible flickering on displays, so we only resort to using this when the connected display doesn't have an EDID. For reference, see the legacy display code: amdgpu_atombios_encoder_dac_load_detect v2: Only clear corresponding bit from BIOS_SCRATCH_0. Signed-off-by: Timur Kristóf <timur.kristof@gmail.com> Reviewed-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent 7f1d1c2 commit d75e45b

5 files changed

Lines changed: 155 additions & 0 deletions

File tree

drivers/gpu/drm/amd/display/dc/bios/bios_parser.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,54 @@ static enum bp_result bios_parser_encoder_control(
780780
return bp->cmd_tbl.dig_encoder_control(bp, cntl);
781781
}
782782

783+
static enum bp_result bios_parser_dac_load_detection(
784+
struct dc_bios *dcb,
785+
enum engine_id engine_id,
786+
enum dal_device_type device_type,
787+
uint32_t enum_id)
788+
{
789+
struct bios_parser *bp = BP_FROM_DCB(dcb);
790+
struct dc_context *ctx = dcb->ctx;
791+
struct bp_load_detection_parameters bp_params = {0};
792+
enum bp_result bp_result;
793+
uint32_t bios_0_scratch;
794+
uint32_t device_id_mask = 0;
795+
796+
bp_params.engine_id = engine_id;
797+
bp_params.device_id = get_support_mask_for_device_id(device_type, enum_id);
798+
799+
if (engine_id != ENGINE_ID_DACA &&
800+
engine_id != ENGINE_ID_DACB)
801+
return BP_RESULT_UNSUPPORTED;
802+
803+
if (!bp->cmd_tbl.dac_load_detection)
804+
return BP_RESULT_UNSUPPORTED;
805+
806+
if (bp_params.device_id == ATOM_DEVICE_CRT1_SUPPORT)
807+
device_id_mask = ATOM_S0_CRT1_MASK;
808+
else if (bp_params.device_id == ATOM_DEVICE_CRT1_SUPPORT)
809+
device_id_mask = ATOM_S0_CRT2_MASK;
810+
else
811+
return BP_RESULT_UNSUPPORTED;
812+
813+
/* BIOS will write the detected devices to BIOS_SCRATCH_0, clear corresponding bit */
814+
bios_0_scratch = dm_read_reg(ctx, bp->base.regs->BIOS_SCRATCH_0);
815+
bios_0_scratch &= ~device_id_mask;
816+
dm_write_reg(ctx, bp->base.regs->BIOS_SCRATCH_0, bios_0_scratch);
817+
818+
bp_result = bp->cmd_tbl.dac_load_detection(bp, &bp_params);
819+
820+
if (bp_result != BP_RESULT_OK)
821+
return bp_result;
822+
823+
bios_0_scratch = dm_read_reg(ctx, bp->base.regs->BIOS_SCRATCH_0);
824+
825+
if (bios_0_scratch & device_id_mask)
826+
return BP_RESULT_OK;
827+
828+
return BP_RESULT_FAILURE;
829+
}
830+
783831
static enum bp_result bios_parser_adjust_pixel_clock(
784832
struct dc_bios *dcb,
785833
struct bp_adjust_pixel_clock_parameters *bp_params)
@@ -2864,6 +2912,8 @@ static const struct dc_vbios_funcs vbios_funcs = {
28642912

28652913
.encoder_control = bios_parser_encoder_control,
28662914

2915+
.dac_load_detection = bios_parser_dac_load_detection,
2916+
28672917
.transmitter_control = bios_parser_transmitter_control,
28682918

28692919
.enable_crtc = bios_parser_enable_crtc,

drivers/gpu/drm/amd/display/dc/bios/command_table.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);
5454
static void init_adjust_display_pll(struct bios_parser *bp);
5555
static void init_select_crtc_source(struct bios_parser *bp);
5656
static void init_dac_encoder_control(struct bios_parser *bp);
57+
static void init_dac_load_detection(struct bios_parser *bp);
5758
static void init_dac_output_control(struct bios_parser *bp);
5859
static void init_set_crtc_timing(struct bios_parser *bp);
5960
static void init_enable_crtc(struct bios_parser *bp);
@@ -72,6 +73,7 @@ void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp)
7273
init_adjust_display_pll(bp);
7374
init_select_crtc_source(bp);
7475
init_dac_encoder_control(bp);
76+
init_dac_load_detection(bp);
7577
init_dac_output_control(bp);
7678
init_set_crtc_timing(bp);
7779
init_enable_crtc(bp);
@@ -1902,6 +1904,96 @@ static enum bp_result dac2_encoder_control_v1(
19021904
return result;
19031905
}
19041906

1907+
/*******************************************************************************
1908+
********************************************************************************
1909+
**
1910+
** DAC LOAD DETECTION
1911+
**
1912+
********************************************************************************
1913+
*******************************************************************************/
1914+
1915+
static enum bp_result dac_load_detection_v1(
1916+
struct bios_parser *bp,
1917+
struct bp_load_detection_parameters *bp_params);
1918+
1919+
static enum bp_result dac_load_detection_v3(
1920+
struct bios_parser *bp,
1921+
struct bp_load_detection_parameters *bp_params);
1922+
1923+
static void init_dac_load_detection(struct bios_parser *bp)
1924+
{
1925+
switch (BIOS_CMD_TABLE_PARA_REVISION(DAC_LoadDetection)) {
1926+
case 1:
1927+
case 2:
1928+
bp->cmd_tbl.dac_load_detection = dac_load_detection_v1;
1929+
break;
1930+
case 3:
1931+
default:
1932+
bp->cmd_tbl.dac_load_detection = dac_load_detection_v3;
1933+
break;
1934+
}
1935+
}
1936+
1937+
static void dac_load_detect_prepare_params(
1938+
struct _DAC_LOAD_DETECTION_PS_ALLOCATION *params,
1939+
enum engine_id engine_id,
1940+
uint16_t device_id,
1941+
uint8_t misc)
1942+
{
1943+
uint8_t dac_type = ENGINE_ID_DACA;
1944+
1945+
if (engine_id == ENGINE_ID_DACB)
1946+
dac_type = ATOM_DAC_B;
1947+
1948+
params->sDacload.usDeviceID = cpu_to_le16(device_id);
1949+
params->sDacload.ucDacType = dac_type;
1950+
params->sDacload.ucMisc = misc;
1951+
}
1952+
1953+
static enum bp_result dac_load_detection_v1(
1954+
struct bios_parser *bp,
1955+
struct bp_load_detection_parameters *bp_params)
1956+
{
1957+
enum bp_result result = BP_RESULT_FAILURE;
1958+
DAC_LOAD_DETECTION_PS_ALLOCATION params;
1959+
1960+
dac_load_detect_prepare_params(
1961+
&params,
1962+
bp_params->engine_id,
1963+
bp_params->device_id,
1964+
0);
1965+
1966+
if (EXEC_BIOS_CMD_TABLE(DAC_LoadDetection, params))
1967+
result = BP_RESULT_OK;
1968+
1969+
return result;
1970+
}
1971+
1972+
static enum bp_result dac_load_detection_v3(
1973+
struct bios_parser *bp,
1974+
struct bp_load_detection_parameters *bp_params)
1975+
{
1976+
enum bp_result result = BP_RESULT_FAILURE;
1977+
DAC_LOAD_DETECTION_PS_ALLOCATION params;
1978+
1979+
uint8_t misc = 0;
1980+
1981+
if (bp_params->device_id == ATOM_DEVICE_CV_SUPPORT ||
1982+
bp_params->device_id == ATOM_DEVICE_TV1_SUPPORT)
1983+
misc = DAC_LOAD_MISC_YPrPb;
1984+
1985+
dac_load_detect_prepare_params(
1986+
&params,
1987+
bp_params->engine_id,
1988+
bp_params->device_id,
1989+
misc);
1990+
1991+
if (EXEC_BIOS_CMD_TABLE(DAC_LoadDetection, params))
1992+
result = BP_RESULT_OK;
1993+
1994+
return result;
1995+
}
1996+
19051997
/*******************************************************************************
19061998
********************************************************************************
19071999
**

drivers/gpu/drm/amd/display/dc/bios/command_table.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ struct cmd_tbl {
7171
enum bp_result (*dac2_output_control)(
7272
struct bios_parser *bp,
7373
bool enable);
74+
enum bp_result (*dac_load_detection)(
75+
struct bios_parser *bp,
76+
struct bp_load_detection_parameters *bp_params);
7477
enum bp_result (*set_crtc_timing)(
7578
struct bios_parser *bp,
7679
struct bp_hw_crtc_timing_parameters *bp_params);

drivers/gpu/drm/amd/display/dc/dc_bios_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ struct dc_vbios_funcs {
9797
enum bp_result (*encoder_control)(
9898
struct dc_bios *bios,
9999
struct bp_encoder_control *cntl);
100+
enum bp_result (*dac_load_detection)(
101+
struct dc_bios *bios,
102+
enum engine_id engine_id,
103+
enum dal_device_type device_type,
104+
uint32_t enum_id);
100105
enum bp_result (*transmitter_control)(
101106
struct dc_bios *bios,
102107
struct bp_transmitter_control *cntl);

drivers/gpu/drm/amd/display/include/bios_parser_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ struct bp_transmitter_control {
162162
bool single_pll_mode;
163163
};
164164

165+
struct bp_load_detection_parameters {
166+
enum engine_id engine_id;
167+
uint16_t device_id;
168+
};
169+
165170
struct bp_hw_crtc_timing_parameters {
166171
enum controller_id controller_id;
167172
/* horizontal part */

0 commit comments

Comments
 (0)