sun60iw2: keep HDMI active during kernel handoff

This commit is contained in:
Qubot 2026-06-05 11:25:12 +08:00
parent 9b50609ee2
commit 8206ab8f22
4 changed files with 77 additions and 2 deletions

View File

@ -900,7 +900,7 @@ void reset_misc(void)
void board_quiesce_devices(void)
{
#ifdef CONFIG_SUNXI_DRM_SUPPORT
sunxi_drm_disable();
sunxi_drm_handoff_to_kernel();
#endif
sunxi_flash_flush();
/*modify 2 for nor to finally exit*/

View File

@ -38,6 +38,7 @@
#define to_sunxi_plane(x) container_of(x, struct sunxi_drm_plane, plane)
static void sunxi_plane_atomic_update(struct drm_plane *plane);
int sunxi_drm_crtc_get_hw_id(struct sunxi_drm_crtc *scrtc)
{
@ -51,6 +52,19 @@ int sunxi_drm_crtc_get_hw_id(struct sunxi_drm_crtc *scrtc)
int sunxi_plane_disable_plane(struct drm_plane *plane)
{
struct drm_plane_state *plane_state = plane->state;
struct sunxi_drm_plane *sunxi_plane = to_sunxi_plane(plane);
struct sunxi_drm_crtc *crtc = sunxi_plane->crtc;
struct display_channel_state *old_ch_state;
struct display_channel_state *ch_state;
struct display_state *state;
if (!plane_state) {
plane->funcs->reset(plane);
plane_state = plane->state;
if (!plane_state)
return -ENOMEM;
}
plane_state->fb = NULL;
plane_state->crtc_x = 0;
plane_state->crtc_y = 0;
@ -60,7 +74,16 @@ int sunxi_plane_disable_plane(struct drm_plane *plane)
plane_state->src_y = 0;
plane_state->src_w = 0;
plane_state->src_h = 0;
//tigger commit
sunxi_plane_atomic_update(plane);
state = display_state_get_by_crtc(crtc);
if (state && crtc->funcs->flush)
crtc->funcs->flush(state);
ch_state = to_display_channel_state(plane_state);
old_ch_state = to_display_channel_state(plane->old_state);
memcpy(old_ch_state, ch_state, sizeof(struct display_channel_state));
return 0;
}

View File

@ -1047,6 +1047,37 @@ static int display_set_plane(struct display_state *state)
}
static int display_clear_plane_for_handoff(struct display_state *state)
{
struct crtc_state *crtc_state = &state->crtc_state;
struct drm_mode_set_plane plane_req;
int ret;
if (!state->is_init || !state->is_enable)
return 0;
memset(&plane_req, 0, sizeof(plane_req));
plane_req.crtc_id = crtc_state->crtc_id;
plane_req.fb_id = -1;
plane_req.plane_id = drm_get_primary_plane_id(state->drm,
plane_req.crtc_id);
if (plane_req.plane_id < 0) {
DRM_ERROR("Failed to get primary plane for crtc %d\n",
plane_req.crtc_id);
return -ENODEV;
}
ret = drm_mode_setplane(state->drm, &plane_req);
if (ret) {
DRM_ERROR("Failed to clear plane %d on crtc %d: %d\n",
plane_req.plane_id, plane_req.crtc_id, ret);
return ret;
}
return 0;
}
static int display_enable(struct display_state *state)
{
struct crtc_state *crtc_state = &state->crtc_state;
@ -1511,6 +1542,26 @@ int sunxi_drm_disable(void)
return 0;
}
int sunxi_drm_handoff_to_kernel(void)
{
struct display_state *state;
struct sunxi_drm_device *drm = sunxi_drm_device_get();
int ret = 0;
if (!drm || list_empty(&drm->display_list))
return -1;
sunxi_drm_for_each_display(state, drm) {
if (state->is_enable) {
ret = display_clear_plane_for_handoff(state);
if (ret)
return ret;
}
}
return 0;
}
int sunxi_show_bmp(char *bmp)
{
struct display_state *s;

View File

@ -26,6 +26,7 @@ int sunxi_show_bmp(char *name);
int sunxi_show_bmp_and_backlight(char *name, char *reg);
int sunxi_backlight_ctrl(char *reg);
int sunxi_drm_disable(void);
int sunxi_drm_handoff_to_kernel(void);
#ifdef __cplusplus
}
#endif