Skip to content

Commit f6d9f39

Browse files
committed
drm/ast: Move code for physical outputs into separate files
Move the modesetting code for the various transmitter chips into their own source files before adding BMC support. No functional changes. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240815151953.184679-2-tzimmermann@suse.de
1 parent 04b5b36 commit f6d9f39

7 files changed

Lines changed: 530 additions & 493 deletions

File tree

drivers/gpu/drm/ast/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ ast-y := \
1111
ast_main.o \
1212
ast_mm.o \
1313
ast_mode.o \
14-
ast_post.o
14+
ast_post.o \
15+
ast_sil164.o \
16+
ast_vga.o
1517

1618
obj-$(CONFIG_DRM_AST) := ast.o

drivers/gpu/drm/ast/ast_dp.c

Lines changed: 207 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,23 @@
44

55
#include <linux/firmware.h>
66
#include <linux/delay.h>
7+
8+
#include <drm/drm_atomic_state_helper.h>
9+
#include <drm/drm_edid.h>
10+
#include <drm/drm_modeset_helper_vtables.h>
711
#include <drm/drm_print.h>
12+
#include <drm/drm_probe_helper.h>
13+
814
#include "ast_drv.h"
915

10-
bool ast_astdp_is_connected(struct ast_device *ast)
16+
static bool ast_astdp_is_connected(struct ast_device *ast)
1117
{
1218
if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, AST_IO_VGACRDF_HPD))
1319
return false;
1420
return true;
1521
}
1622

17-
int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
23+
static int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
1824
{
1925
struct ast_device *ast = to_ast_device(dev);
2026
int ret = 0;
@@ -120,7 +126,7 @@ int ast_dp_launch(struct ast_device *ast)
120126
return 0;
121127
}
122128

123-
bool ast_dp_power_is_on(struct ast_device *ast)
129+
static bool ast_dp_power_is_on(struct ast_device *ast)
124130
{
125131
u8 vgacre3;
126132

@@ -129,7 +135,7 @@ bool ast_dp_power_is_on(struct ast_device *ast)
129135
return !(vgacre3 & AST_DP_PHY_SLEEP);
130136
}
131137

132-
void ast_dp_power_on_off(struct drm_device *dev, bool on)
138+
static void ast_dp_power_on_off(struct drm_device *dev, bool on)
133139
{
134140
struct ast_device *ast = to_ast_device(dev);
135141
// Read and Turn off DP PHY sleep
@@ -143,7 +149,7 @@ void ast_dp_power_on_off(struct drm_device *dev, bool on)
143149
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3);
144150
}
145151

146-
void ast_dp_link_training(struct ast_device *ast)
152+
static void ast_dp_link_training(struct ast_device *ast)
147153
{
148154
struct drm_device *dev = &ast->base;
149155
int i;
@@ -161,7 +167,7 @@ void ast_dp_link_training(struct ast_device *ast)
161167
drm_err(dev, "Link training failed\n");
162168
}
163169

164-
void ast_dp_set_on_off(struct drm_device *dev, bool on)
170+
static void ast_dp_set_on_off(struct drm_device *dev, bool on)
165171
{
166172
struct ast_device *ast = to_ast_device(dev);
167173
u8 video_on_off = on;
@@ -180,7 +186,7 @@ void ast_dp_set_on_off(struct drm_device *dev, bool on)
180186
}
181187
}
182188

183-
void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode)
189+
static void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode)
184190
{
185191
struct ast_device *ast = to_ast_device(crtc->dev);
186192

@@ -253,3 +259,197 @@ void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mo
253259
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE1, ASTDP_AND_CLEAR_MASK, ASTDP_MISC1);
254260
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE2, ASTDP_AND_CLEAR_MASK, ModeIdx);
255261
}
262+
263+
static void ast_wait_for_vretrace(struct ast_device *ast)
264+
{
265+
unsigned long timeout = jiffies + HZ;
266+
u8 vgair1;
267+
268+
do {
269+
vgair1 = ast_io_read8(ast, AST_IO_VGAIR1_R);
270+
} while (!(vgair1 & AST_IO_VGAIR1_VREFRESH) && time_before(jiffies, timeout));
271+
}
272+
273+
/*
274+
* Encoder
275+
*/
276+
277+
static const struct drm_encoder_funcs ast_astdp_encoder_funcs = {
278+
.destroy = drm_encoder_cleanup,
279+
};
280+
281+
static void ast_astdp_encoder_helper_atomic_mode_set(struct drm_encoder *encoder,
282+
struct drm_crtc_state *crtc_state,
283+
struct drm_connector_state *conn_state)
284+
{
285+
struct drm_crtc *crtc = crtc_state->crtc;
286+
struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
287+
struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
288+
289+
ast_dp_set_mode(crtc, vbios_mode_info);
290+
}
291+
292+
static void ast_astdp_encoder_helper_atomic_enable(struct drm_encoder *encoder,
293+
struct drm_atomic_state *state)
294+
{
295+
struct drm_device *dev = encoder->dev;
296+
struct ast_device *ast = to_ast_device(dev);
297+
298+
ast_dp_power_on_off(dev, AST_DP_POWER_ON);
299+
ast_dp_link_training(ast);
300+
301+
ast_wait_for_vretrace(ast);
302+
ast_dp_set_on_off(dev, 1);
303+
}
304+
305+
static void ast_astdp_encoder_helper_atomic_disable(struct drm_encoder *encoder,
306+
struct drm_atomic_state *state)
307+
{
308+
struct drm_device *dev = encoder->dev;
309+
310+
ast_dp_set_on_off(dev, 0);
311+
ast_dp_power_on_off(dev, AST_DP_POWER_OFF);
312+
}
313+
314+
static const struct drm_encoder_helper_funcs ast_astdp_encoder_helper_funcs = {
315+
.atomic_mode_set = ast_astdp_encoder_helper_atomic_mode_set,
316+
.atomic_enable = ast_astdp_encoder_helper_atomic_enable,
317+
.atomic_disable = ast_astdp_encoder_helper_atomic_disable,
318+
};
319+
320+
/*
321+
* Connector
322+
*/
323+
324+
static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
325+
{
326+
void *edid;
327+
struct drm_device *dev = connector->dev;
328+
struct ast_device *ast = to_ast_device(dev);
329+
330+
int succ;
331+
int count;
332+
333+
edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
334+
if (!edid)
335+
goto err_drm_connector_update_edid_property;
336+
337+
/*
338+
* Protect access to I/O registers from concurrent modesetting
339+
* by acquiring the I/O-register lock.
340+
*/
341+
mutex_lock(&ast->modeset_lock);
342+
343+
succ = ast_astdp_read_edid(connector->dev, edid);
344+
if (succ < 0)
345+
goto err_mutex_unlock;
346+
347+
mutex_unlock(&ast->modeset_lock);
348+
349+
drm_connector_update_edid_property(connector, edid);
350+
count = drm_add_edid_modes(connector, edid);
351+
kfree(edid);
352+
353+
return count;
354+
355+
err_mutex_unlock:
356+
mutex_unlock(&ast->modeset_lock);
357+
kfree(edid);
358+
err_drm_connector_update_edid_property:
359+
drm_connector_update_edid_property(connector, NULL);
360+
return 0;
361+
}
362+
363+
static int ast_astdp_connector_helper_detect_ctx(struct drm_connector *connector,
364+
struct drm_modeset_acquire_ctx *ctx,
365+
bool force)
366+
{
367+
struct drm_device *dev = connector->dev;
368+
struct ast_device *ast = to_ast_device(connector->dev);
369+
enum drm_connector_status status = connector_status_disconnected;
370+
struct drm_connector_state *connector_state = connector->state;
371+
bool is_active = false;
372+
373+
mutex_lock(&ast->modeset_lock);
374+
375+
if (connector_state && connector_state->crtc) {
376+
struct drm_crtc_state *crtc_state = connector_state->crtc->state;
377+
378+
if (crtc_state && crtc_state->active)
379+
is_active = true;
380+
}
381+
382+
if (!is_active && !ast_dp_power_is_on(ast)) {
383+
ast_dp_power_on_off(dev, true);
384+
msleep(50);
385+
}
386+
387+
if (ast_astdp_is_connected(ast))
388+
status = connector_status_connected;
389+
390+
if (!is_active && status == connector_status_disconnected)
391+
ast_dp_power_on_off(dev, false);
392+
393+
mutex_unlock(&ast->modeset_lock);
394+
395+
return status;
396+
}
397+
398+
static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs = {
399+
.get_modes = ast_astdp_connector_helper_get_modes,
400+
.detect_ctx = ast_astdp_connector_helper_detect_ctx,
401+
};
402+
403+
static const struct drm_connector_funcs ast_astdp_connector_funcs = {
404+
.reset = drm_atomic_helper_connector_reset,
405+
.fill_modes = drm_helper_probe_single_connector_modes,
406+
.destroy = drm_connector_cleanup,
407+
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
408+
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
409+
};
410+
411+
static int ast_astdp_connector_init(struct drm_device *dev, struct drm_connector *connector)
412+
{
413+
int ret;
414+
415+
ret = drm_connector_init(dev, connector, &ast_astdp_connector_funcs,
416+
DRM_MODE_CONNECTOR_DisplayPort);
417+
if (ret)
418+
return ret;
419+
420+
drm_connector_helper_add(connector, &ast_astdp_connector_helper_funcs);
421+
422+
connector->interlace_allowed = 0;
423+
connector->doublescan_allowed = 0;
424+
425+
connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
426+
427+
return 0;
428+
}
429+
430+
int ast_astdp_output_init(struct ast_device *ast)
431+
{
432+
struct drm_device *dev = &ast->base;
433+
struct drm_crtc *crtc = &ast->crtc;
434+
struct drm_encoder *encoder = &ast->output.astdp.encoder;
435+
struct drm_connector *connector = &ast->output.astdp.connector;
436+
int ret;
437+
438+
ret = drm_encoder_init(dev, encoder, &ast_astdp_encoder_funcs,
439+
DRM_MODE_ENCODER_TMDS, NULL);
440+
if (ret)
441+
return ret;
442+
drm_encoder_helper_add(encoder, &ast_astdp_encoder_helper_funcs);
443+
444+
encoder->possible_crtcs = drm_crtc_mask(crtc);
445+
446+
ret = ast_astdp_connector_init(dev, connector);
447+
if (ret)
448+
return ret;
449+
450+
ret = drm_connector_attach_encoder(connector, encoder);
451+
if (ret)
452+
return ret;
453+
454+
return 0;
455+
}

0 commit comments

Comments
 (0)