Skip to content

Commit 1f192b9

Browse files
committed
Merge tag 'drm-misc-fixes-2022-06-09' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
two fixes for panel self-refresh handling, and one to fix multiple output support on AST. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <maxime@cerno.tech> Link: https://patchwork.freedesktop.org/patch/msgid/20220609100754.kvrkjy67gqabjuee@houat
2 parents 88bfb6d + 477277c commit 1f192b9

8 files changed

Lines changed: 92 additions & 43 deletions

File tree

drivers/gpu/drm/ast/ast_dp.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,12 @@ void ast_dp_launch(struct drm_device *dev, u8 bPower)
160160
}
161161

162162
if (bDPExecute)
163-
ast->tx_chip_type = AST_TX_ASTDP;
163+
ast->tx_chip_types |= BIT(AST_TX_ASTDP);
164164

165165
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
166166
(u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
167167
ASTDP_HOST_EDID_READ_DONE);
168-
} else
169-
ast->tx_chip_type = AST_TX_NONE;
168+
}
170169
}
171170

172171

drivers/gpu/drm/ast/ast_dp501.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ void ast_init_3rdtx(struct drm_device *dev)
450450
ast_init_dvo(dev);
451451
break;
452452
default:
453-
if (ast->tx_chip_type == AST_TX_SIL164)
453+
if (ast->tx_chip_types & BIT(AST_TX_SIL164))
454454
ast_init_dvo(dev);
455455
else
456456
ast_init_analog(dev);

drivers/gpu/drm/ast/ast_drv.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ enum ast_tx_chip {
7373
AST_TX_ASTDP,
7474
};
7575

76+
#define AST_TX_NONE_BIT BIT(AST_TX_NONE)
77+
#define AST_TX_SIL164_BIT BIT(AST_TX_SIL164)
78+
#define AST_TX_DP501_BIT BIT(AST_TX_DP501)
79+
#define AST_TX_ASTDP_BIT BIT(AST_TX_ASTDP)
80+
7681
#define AST_DRAM_512Mx16 0
7782
#define AST_DRAM_1Gx16 1
7883
#define AST_DRAM_512Mx32 2
@@ -173,7 +178,7 @@ struct ast_private {
173178
struct drm_plane primary_plane;
174179
struct ast_cursor_plane cursor_plane;
175180
struct drm_crtc crtc;
176-
union {
181+
struct {
177182
struct {
178183
struct drm_encoder encoder;
179184
struct ast_vga_connector vga_connector;
@@ -199,7 +204,7 @@ struct ast_private {
199204
ast_use_defaults
200205
} config_mode;
201206

202-
enum ast_tx_chip tx_chip_type;
207+
unsigned long tx_chip_types; /* bitfield of enum ast_chip_type */
203208
u8 *dp501_fw_addr;
204209
const struct firmware *dp501_fw; /* dp501 fw */
205210
};

drivers/gpu/drm/ast/ast_main.c

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
216216
}
217217

218218
/* Check 3rd Tx option (digital output afaik) */
219-
ast->tx_chip_type = AST_TX_NONE;
219+
ast->tx_chip_types |= AST_TX_NONE_BIT;
220220

221221
/*
222222
* VGACRA3 Enhanced Color Mode Register, check if DVO is already
@@ -229,7 +229,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
229229
if (!*need_post) {
230230
jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff);
231231
if (jreg & 0x80)
232-
ast->tx_chip_type = AST_TX_SIL164;
232+
ast->tx_chip_types = AST_TX_SIL164_BIT;
233233
}
234234

235235
if ((ast->chip == AST2300) || (ast->chip == AST2400) || (ast->chip == AST2500)) {
@@ -241,7 +241,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
241241
jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
242242
switch (jreg) {
243243
case 0x04:
244-
ast->tx_chip_type = AST_TX_SIL164;
244+
ast->tx_chip_types = AST_TX_SIL164_BIT;
245245
break;
246246
case 0x08:
247247
ast->dp501_fw_addr = drmm_kzalloc(dev, 32*1024, GFP_KERNEL);
@@ -254,22 +254,19 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
254254
}
255255
fallthrough;
256256
case 0x0c:
257-
ast->tx_chip_type = AST_TX_DP501;
257+
ast->tx_chip_types = AST_TX_DP501_BIT;
258258
}
259259
} else if (ast->chip == AST2600)
260260
ast_dp_launch(&ast->base, 0);
261261

262262
/* Print stuff for diagnostic purposes */
263-
switch(ast->tx_chip_type) {
264-
case AST_TX_SIL164:
263+
if (ast->tx_chip_types & AST_TX_NONE_BIT)
264+
drm_info(dev, "Using analog VGA\n");
265+
if (ast->tx_chip_types & AST_TX_SIL164_BIT)
265266
drm_info(dev, "Using Sil164 TMDS transmitter\n");
266-
break;
267-
case AST_TX_DP501:
267+
if (ast->tx_chip_types & AST_TX_DP501_BIT)
268268
drm_info(dev, "Using DP501 DisplayPort transmitter\n");
269-
break;
270-
default:
271-
drm_info(dev, "Analog VGA only\n");
272-
}
269+
273270
return 0;
274271
}
275272

drivers/gpu/drm/ast/ast_mode.c

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -997,10 +997,10 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
997997
case DRM_MODE_DPMS_ON:
998998
ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0);
999999
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, 0);
1000-
if (ast->tx_chip_type == AST_TX_DP501)
1000+
if (ast->tx_chip_types & AST_TX_DP501_BIT)
10011001
ast_set_dp501_video_output(crtc->dev, 1);
10021002

1003-
if (ast->tx_chip_type == AST_TX_ASTDP) {
1003+
if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
10041004
ast_dp_power_on_off(crtc->dev, AST_DP_POWER_ON);
10051005
ast_wait_for_vretrace(ast);
10061006
ast_dp_set_on_off(crtc->dev, 1);
@@ -1012,17 +1012,17 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
10121012
case DRM_MODE_DPMS_SUSPEND:
10131013
case DRM_MODE_DPMS_OFF:
10141014
ch = mode;
1015-
if (ast->tx_chip_type == AST_TX_DP501)
1015+
if (ast->tx_chip_types & AST_TX_DP501_BIT)
10161016
ast_set_dp501_video_output(crtc->dev, 0);
1017-
break;
10181017

1019-
if (ast->tx_chip_type == AST_TX_ASTDP) {
1018+
if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
10201019
ast_dp_set_on_off(crtc->dev, 0);
10211020
ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF);
10221021
}
10231022

10241023
ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0x20);
10251024
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, ch);
1025+
break;
10261026
}
10271027
}
10281028

@@ -1155,7 +1155,7 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
11551155
ast_crtc_load_lut(ast, crtc);
11561156

11571157
//Set Aspeed Display-Port
1158-
if (ast->tx_chip_type == AST_TX_ASTDP)
1158+
if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
11591159
ast_dp_set_mode(crtc, vbios_mode_info);
11601160

11611161
mutex_unlock(&ast->ioregs_lock);
@@ -1739,22 +1739,26 @@ int ast_mode_config_init(struct ast_private *ast)
17391739

17401740
ast_crtc_init(dev);
17411741

1742-
switch (ast->tx_chip_type) {
1743-
case AST_TX_NONE:
1742+
if (ast->tx_chip_types & AST_TX_NONE_BIT) {
17441743
ret = ast_vga_output_init(ast);
1745-
break;
1746-
case AST_TX_SIL164:
1744+
if (ret)
1745+
return ret;
1746+
}
1747+
if (ast->tx_chip_types & AST_TX_SIL164_BIT) {
17471748
ret = ast_sil164_output_init(ast);
1748-
break;
1749-
case AST_TX_DP501:
1749+
if (ret)
1750+
return ret;
1751+
}
1752+
if (ast->tx_chip_types & AST_TX_DP501_BIT) {
17501753
ret = ast_dp501_output_init(ast);
1751-
break;
1752-
case AST_TX_ASTDP:
1754+
if (ret)
1755+
return ret;
1756+
}
1757+
if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
17531758
ret = ast_astdp_output_init(ast);
1754-
break;
1759+
if (ret)
1760+
return ret;
17551761
}
1756-
if (ret)
1757-
return ret;
17581762

17591763
drm_mode_config_reset(dev);
17601764

drivers/gpu/drm/ast/ast_post.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ void ast_post_gpu(struct drm_device *dev)
391391

392392
ast_init_3rdtx(dev);
393393
} else {
394-
if (ast->tx_chip_type != AST_TX_NONE)
394+
if (ast->tx_chip_types & AST_TX_SIL164_BIT)
395395
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); /* Enable DVO */
396396
}
397397
}

drivers/gpu/drm/bridge/analogix/analogix_dp_core.c

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,25 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
12661266
return 0;
12671267
}
12681268

1269+
static
1270+
struct drm_crtc *analogix_dp_get_old_crtc(struct analogix_dp_device *dp,
1271+
struct drm_atomic_state *state)
1272+
{
1273+
struct drm_encoder *encoder = dp->encoder;
1274+
struct drm_connector *connector;
1275+
struct drm_connector_state *conn_state;
1276+
1277+
connector = drm_atomic_get_old_connector_for_encoder(state, encoder);
1278+
if (!connector)
1279+
return NULL;
1280+
1281+
conn_state = drm_atomic_get_old_connector_state(state, connector);
1282+
if (!conn_state)
1283+
return NULL;
1284+
1285+
return conn_state->crtc;
1286+
}
1287+
12691288
static
12701289
struct drm_crtc *analogix_dp_get_new_crtc(struct analogix_dp_device *dp,
12711290
struct drm_atomic_state *state)
@@ -1446,14 +1465,16 @@ analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge,
14461465
{
14471466
struct drm_atomic_state *old_state = old_bridge_state->base.state;
14481467
struct analogix_dp_device *dp = bridge->driver_private;
1449-
struct drm_crtc *crtc;
1468+
struct drm_crtc *old_crtc, *new_crtc;
1469+
struct drm_crtc_state *old_crtc_state = NULL;
14501470
struct drm_crtc_state *new_crtc_state = NULL;
1471+
int ret;
14511472

1452-
crtc = analogix_dp_get_new_crtc(dp, old_state);
1453-
if (!crtc)
1473+
new_crtc = analogix_dp_get_new_crtc(dp, old_state);
1474+
if (!new_crtc)
14541475
goto out;
14551476

1456-
new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc);
1477+
new_crtc_state = drm_atomic_get_new_crtc_state(old_state, new_crtc);
14571478
if (!new_crtc_state)
14581479
goto out;
14591480

@@ -1462,6 +1483,19 @@ analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge,
14621483
return;
14631484

14641485
out:
1486+
old_crtc = analogix_dp_get_old_crtc(dp, old_state);
1487+
if (old_crtc) {
1488+
old_crtc_state = drm_atomic_get_old_crtc_state(old_state,
1489+
old_crtc);
1490+
1491+
/* When moving from PSR to fully disabled, exit PSR first. */
1492+
if (old_crtc_state && old_crtc_state->self_refresh_active) {
1493+
ret = analogix_dp_disable_psr(dp);
1494+
if (ret)
1495+
DRM_ERROR("Failed to disable psr (%d)\n", ret);
1496+
}
1497+
}
1498+
14651499
analogix_dp_bridge_disable(bridge);
14661500
}
14671501

drivers/gpu/drm/drm_atomic_helper.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,9 +1011,19 @@ crtc_needs_disable(struct drm_crtc_state *old_state,
10111011
return drm_atomic_crtc_effectively_active(old_state);
10121012

10131013
/*
1014-
* We need to run through the crtc_funcs->disable() function if the CRTC
1015-
* is currently on, if it's transitioning to self refresh mode, or if
1016-
* it's in self refresh mode and needs to be fully disabled.
1014+
* We need to disable bridge(s) and CRTC if we're transitioning out of
1015+
* self-refresh and changing CRTCs at the same time, because the
1016+
* bridge tracks self-refresh status via CRTC state.
1017+
*/
1018+
if (old_state->self_refresh_active &&
1019+
old_state->crtc != new_state->crtc)
1020+
return true;
1021+
1022+
/*
1023+
* We also need to run through the crtc_funcs->disable() function if
1024+
* the CRTC is currently on, if it's transitioning to self refresh
1025+
* mode, or if it's in self refresh mode and needs to be fully
1026+
* disabled.
10171027
*/
10181028
return old_state->active ||
10191029
(old_state->self_refresh_active && !new_state->active) ||

0 commit comments

Comments
 (0)