diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index a85d5f783de4..196f74a0834e 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -159,6 +159,8 @@ struct mgag200_pll { struct mgag200_crtc_state { struct drm_crtc_state base; + + struct mgag200_pll_values pixpllc; }; static inline struct mgag200_crtc_state *to_mgag200_crtc_state(struct drm_crtc_state *base) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 6e8b0db1ffa0..6cb24a4b76b8 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -110,23 +110,6 @@ static inline void mga_wait_busy(struct mga_device *mdev) } while ((status & 0x01) && time_before(jiffies, timeout)); } -/* - * PLL setup - */ - -static void mgag200_crtc_set_plls(struct mga_device *mdev, long clock) -{ - struct mgag200_pll *pixpll = &mdev->pixpll; - struct mgag200_pll_values pixpllc; - int ret; - - ret = pixpll->funcs->compute(pixpll, clock, &pixpllc); - if (ret) - return; - - pixpll->funcs->update(pixpll, &pixpllc); -} - static void mgag200_g200wb_hold_bmc(struct mga_device *mdev) { u8 tmp; @@ -881,7 +864,9 @@ mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc *crtc = &pipe->crtc; struct drm_device *dev = crtc->dev; struct mga_device *mdev = to_mga_device(dev); + struct mgag200_pll *pixpll = &mdev->pixpll; struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; + struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); struct drm_framebuffer *fb = plane_state->fb; struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); struct drm_rect fullscreen = { @@ -896,7 +881,8 @@ mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, mgag200_set_format_regs(mdev, fb); mgag200_set_mode_regs(mdev, adjusted_mode); - mgag200_crtc_set_plls(mdev, adjusted_mode->clock); + + pixpll->funcs->update(pixpll, &mgag200_crtc_state->pixpllc); if (mdev->type == G200_ER) mgag200_g200er_reset_tagfifo(mdev); @@ -930,8 +916,13 @@ mgag200_simple_display_pipe_check(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state) { struct drm_plane *plane = plane_state->plane; + struct drm_device *dev = plane->dev; + struct mga_device *mdev = to_mga_device(dev); + struct mgag200_pll *pixpll = &mdev->pixpll; + struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); struct drm_framebuffer *new_fb = plane_state->fb; struct drm_framebuffer *fb = NULL; + int ret; if (!new_fb) return 0; @@ -942,6 +933,13 @@ mgag200_simple_display_pipe_check(struct drm_simple_display_pipe *pipe, if (!fb || (fb->format != new_fb->format)) crtc_state->mode_changed = true; /* update PLL settings */ + if (crtc_state->mode_changed) { + ret = pixpll->funcs->compute(pixpll, crtc_state->mode.clock, + &mgag200_crtc_state->pixpllc); + if (ret) + return ret; + } + return 0; } @@ -969,6 +967,7 @@ mgag200_simple_display_pipe_duplicate_crtc_state(struct drm_simple_display_pipe { struct drm_crtc *crtc = &pipe->crtc; struct drm_crtc_state *crtc_state = crtc->state; + struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); struct mgag200_crtc_state *new_mgag200_crtc_state; if (!crtc_state) @@ -979,6 +978,9 @@ mgag200_simple_display_pipe_duplicate_crtc_state(struct drm_simple_display_pipe return NULL; __drm_atomic_helper_crtc_duplicate_state(crtc, &new_mgag200_crtc_state->base); + memcpy(&new_mgag200_crtc_state->pixpllc, &mgag200_crtc_state->pixpllc, + sizeof(new_mgag200_crtc_state->pixpllc)); + return &new_mgag200_crtc_state->base; }