Skip to content

Commit bed61c8

Browse files
jammyaspeedThomas Zimmermann
authored andcommitted
drm/ast: Fix long time waiting on s3/s4 resume
In resume, DP's launch function, ast_dp_launch, could wait at most 30 seconds before timeout to check if DP is enabled. It could lead to 'DPM device timeout' and trigger unrecoverable kernel panic. To avoid this problem, we check if DP enable or not at driver probe only. Reported-and-tested-by: Wendy Wang <[email protected]> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217278 Acked-by: Thomas Zimmermann <[email protected]> Signed-off-by: Jammy Huang <[email protected]> Signed-off-by: Thomas Zimmermann <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent e79d85c commit bed61c8

File tree

4 files changed

+29
-45
lines changed

4 files changed

+29
-45
lines changed

drivers/gpu/drm/ast/ast_dp.c

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -119,53 +119,32 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
119119
/*
120120
* Launch Aspeed DP
121121
*/
122-
void ast_dp_launch(struct drm_device *dev, u8 bPower)
122+
void ast_dp_launch(struct drm_device *dev)
123123
{
124-
u32 i = 0, j = 0, WaitCount = 1;
125-
u8 bDPTX = 0;
124+
u32 i = 0;
126125
u8 bDPExecute = 1;
127-
128126
struct ast_device *ast = to_ast_device(dev);
129-
// S3 come back, need more time to wait BMC ready.
130-
if (bPower)
131-
WaitCount = 300;
132-
133-
134-
// Wait total count by different condition.
135-
for (j = 0; j < WaitCount; j++) {
136-
bDPTX = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, TX_TYPE_MASK);
137-
138-
if (bDPTX)
139-
break;
140127

128+
// Wait one second then timeout.
129+
while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) !=
130+
ASTDP_MCU_FW_EXECUTING) {
131+
i++;
132+
// wait 100 ms
141133
msleep(100);
142-
}
143134

144-
// 0xE : ASTDP with DPMCU FW handling
145-
if (bDPTX == ASTDP_DPMCU_TX) {
146-
// Wait one second then timeout.
147-
i = 0;
148-
149-
while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, COPROCESSOR_LAUNCH) !=
150-
COPROCESSOR_LAUNCH) {
151-
i++;
152-
// wait 100 ms
153-
msleep(100);
154-
155-
if (i >= 10) {
156-
// DP would not be ready.
157-
bDPExecute = 0;
158-
break;
159-
}
135+
if (i >= 10) {
136+
// DP would not be ready.
137+
bDPExecute = 0;
138+
break;
160139
}
140+
}
161141

162-
if (bDPExecute)
163-
ast->tx_chip_types |= BIT(AST_TX_ASTDP);
142+
if (!bDPExecute)
143+
drm_err(dev, "Wait DPMCU executing timeout\n");
164144

165-
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
166-
(u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
167-
ASTDP_HOST_EDID_READ_DONE);
168-
}
145+
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
146+
(u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
147+
ASTDP_HOST_EDID_READ_DONE);
169148
}
170149

171150

drivers/gpu/drm/ast/ast_drv.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,6 @@ int ast_mode_config_init(struct ast_device *ast);
350350
#define AST_DP501_LINKRATE 0xf014
351351
#define AST_DP501_EDID_DATA 0xf020
352352

353-
/* Define for Soc scratched reg */
354-
#define COPROCESSOR_LAUNCH BIT(5)
355-
356353
/*
357354
* Display Transmitter Type:
358355
*/
@@ -480,7 +477,7 @@ struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev);
480477

481478
/* aspeed DP */
482479
int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata);
483-
void ast_dp_launch(struct drm_device *dev, u8 bPower);
480+
void ast_dp_launch(struct drm_device *dev);
484481
void ast_dp_power_on_off(struct drm_device *dev, bool no);
485482
void ast_dp_set_on_off(struct drm_device *dev, bool no);
486483
void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode);

drivers/gpu/drm/ast/ast_main.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,13 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
254254
case 0x0c:
255255
ast->tx_chip_types = AST_TX_DP501_BIT;
256256
}
257-
} else if (ast->chip == AST2600)
258-
ast_dp_launch(&ast->base, 0);
257+
} else if (ast->chip == AST2600) {
258+
if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, TX_TYPE_MASK) ==
259+
ASTDP_DPMCU_TX) {
260+
ast->tx_chip_types = AST_TX_ASTDP_BIT;
261+
ast_dp_launch(&ast->base);
262+
}
263+
}
259264

260265
/* Print stuff for diagnostic purposes */
261266
if (ast->tx_chip_types & AST_TX_NONE_BIT)
@@ -264,6 +269,8 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
264269
drm_info(dev, "Using Sil164 TMDS transmitter\n");
265270
if (ast->tx_chip_types & AST_TX_DP501_BIT)
266271
drm_info(dev, "Using DP501 DisplayPort transmitter\n");
272+
if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
273+
drm_info(dev, "Using ASPEED DisplayPort transmitter\n");
267274

268275
return 0;
269276
}

drivers/gpu/drm/ast/ast_post.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,8 @@ void ast_post_gpu(struct drm_device *dev)
380380
ast_set_def_ext_reg(dev);
381381

382382
if (ast->chip == AST2600) {
383-
ast_dp_launch(dev, 1);
383+
if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
384+
ast_dp_launch(dev);
384385
} else if (ast->config_mode == ast_use_p2a) {
385386
if (ast->chip == AST2500)
386387
ast_post_chip_2500(dev);

0 commit comments

Comments
 (0)