Skip to content

Commit 6ee9b4d

Browse files
ycchen0221gregkh
authored andcommitted
drm/ast: fixed reading monitor EDID not stable issue
[ Upstream commit 3006256 ] v1: over-sample data to increase the stability with some specific monitors v2: refine to avoid infinite loop v3: remove un-necessary "volatile" declaration [airlied: fix two checkpatch warnings] Signed-off-by: Y.C. Chen <[email protected]> Signed-off-by: Dave Airlie <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Signed-off-by: Sasha Levin <[email protected]>
1 parent cc92ade commit 6ee9b4d

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

drivers/gpu/drm/ast/ast_mode.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -973,19 +973,43 @@ static int get_clock(void *i2c_priv)
973973
{
974974
struct ast_i2c_chan *i2c = i2c_priv;
975975
struct ast_private *ast = i2c->dev->dev_private;
976-
uint32_t val;
976+
uint32_t val, val2, count, pass;
977+
978+
count = 0;
979+
pass = 0;
980+
val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
981+
do {
982+
val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
983+
if (val == val2) {
984+
pass++;
985+
} else {
986+
pass = 0;
987+
val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
988+
}
989+
} while ((pass < 5) && (count++ < 0x10000));
977990

978-
val = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4;
979991
return val & 1 ? 1 : 0;
980992
}
981993

982994
static int get_data(void *i2c_priv)
983995
{
984996
struct ast_i2c_chan *i2c = i2c_priv;
985997
struct ast_private *ast = i2c->dev->dev_private;
986-
uint32_t val;
998+
uint32_t val, val2, count, pass;
999+
1000+
count = 0;
1001+
pass = 0;
1002+
val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
1003+
do {
1004+
val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
1005+
if (val == val2) {
1006+
pass++;
1007+
} else {
1008+
pass = 0;
1009+
val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
1010+
}
1011+
} while ((pass < 5) && (count++ < 0x10000));
9871012

988-
val = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5;
9891013
return val & 1 ? 1 : 0;
9901014
}
9911015

@@ -998,7 +1022,7 @@ static void set_clock(void *i2c_priv, int clock)
9981022

9991023
for (i = 0; i < 0x10000; i++) {
10001024
ujcrb7 = ((clock & 0x01) ? 0 : 1);
1001-
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xfe, ujcrb7);
1025+
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7);
10021026
jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01);
10031027
if (ujcrb7 == jtemp)
10041028
break;
@@ -1014,7 +1038,7 @@ static void set_data(void *i2c_priv, int data)
10141038

10151039
for (i = 0; i < 0x10000; i++) {
10161040
ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
1017-
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xfb, ujcrb7);
1041+
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7);
10181042
jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04);
10191043
if (ujcrb7 == jtemp)
10201044
break;

0 commit comments

Comments
 (0)