From: root <root@localhost.localdomain> convert the bochs driver to atomic mode-setting, referencing the patch serias of drm/exynos sent by Gustavo Padovan Signed-off-by: Zhao Junwang <zhjwpku@xxxxxxxxx> --- Hi all, I am a GSoCer of this year, and my project is to convert bochs driver and cirrus driver to atomic mode-setting. I converted the bochs driver to atomic mode-setting by referencing the patch serias of drm/exynos sent by Gustavo Padovan. As far as I know, the convertion got some problem, and after I add the bochs driver when I boot the qemu VM, it just can not start up, works fine if I delete bochs-drm.ko from it's directory. I am stuck here, I hope some one could review this patch and give some tips, so I can go on with by project. --- drivers/gpu/drm/bochs/bochs.h | 2 + drivers/gpu/drm/bochs/bochs_drv.c | 2 +- drivers/gpu/drm/bochs/bochs_kms.c | 147 ++++++++++++++----------------------- drivers/gpu/drm/bochs/bochs_mm.c | 10 +++ 4 files changed, 68 insertions(+), 93 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h index 71f2687..3e16f63 100644 --- a/drivers/gpu/drm/bochs/bochs.h +++ b/drivers/gpu/drm/bochs/bochs.h @@ -5,6 +5,8 @@ #include <drm/drmP.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_atomic.h> +#include <drm/drm_atomic_helper.h> #include <drm/drm_fb_helper.h> #include <drm/drm_gem.h> diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index 98837bd..fc31643 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -79,7 +79,7 @@ static const struct file_operations bochs_fops = { }; static struct drm_driver bochs_driver = { - .driver_features = DRIVER_GEM | DRIVER_MODESET, + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .load = bochs_load, .unload = bochs_unload, .set_busid = drm_pci_set_busid, diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 26bcd03..1d04615 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -18,16 +18,24 @@ MODULE_PARM_DESC(defy, "default y resolution"); /* ---------------------------------------------------------------------- */ -static void bochs_crtc_dpms(struct drm_crtc *crtc, int mode) +static void bochs_crtc_enable(struct drm_crtc *crtc) { - switch (mode) { - case DRM_MODE_DPMS_ON: - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - default: + if (crtc->enabled) return; - } + + crtc->enabled = true; + + drm_crtc_vblank_on(crtc); +} + +static void bochs_crtc_disable(struct drm_crtc *crtc) +{ + if (!crtc->enabled) + return; + + drm_crtc_vblank_off(crtc); + + crtc->enabled = false; } static bool bochs_crtc_mode_fixup(struct drm_crtc *crtc, @@ -37,109 +45,66 @@ static bool bochs_crtc_mode_fixup(struct drm_crtc *crtc, return true; } -static int bochs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) +static void bochs_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct bochs_device *bochs = container_of(crtc, struct bochs_device, crtc); - struct bochs_framebuffer *bochs_fb; - struct bochs_bo *bo; - u64 gpu_addr = 0; - int ret; - - if (old_fb) { - bochs_fb = to_bochs_framebuffer(old_fb); - bo = gem_to_bochs_bo(bochs_fb->obj); - ret = ttm_bo_reserve(&bo->bo, true, false, false, NULL); - if (ret) { - DRM_ERROR("failed to reserve old_fb bo\n"); - } else { - bochs_bo_unpin(bo); - ttm_bo_unreserve(&bo->bo); - } - } - - if (WARN_ON(crtc->primary->fb == NULL)) - return -EINVAL; - bochs_fb = to_bochs_framebuffer(crtc->primary->fb); - bo = gem_to_bochs_bo(bochs_fb->obj); - ret = ttm_bo_reserve(&bo->bo, true, false, false, NULL); - if (ret) - return ret; - - ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); - if (ret) { - ttm_bo_unreserve(&bo->bo); - return ret; - } + if (WARN_ON(!crtc->state)) + return; - ttm_bo_unreserve(&bo->bo); - bochs_hw_setbase(bochs, x, y, gpu_addr); - return 0; + /* set mode only (no scanout buffer attached), don't need set base */ + bochs_hw_setmode(bochs, &crtc->state->adjusted_mode); } -static int bochs_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, struct drm_framebuffer *old_fb) +static int bochs_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) { - struct bochs_device *bochs = - container_of(crtc, struct bochs_device, crtc); - - bochs_hw_setmode(bochs, mode); - bochs_crtc_mode_set_base(crtc, x, y, old_fb); return 0; } -static void bochs_crtc_prepare(struct drm_crtc *crtc) -{ -} - -static void bochs_crtc_commit(struct drm_crtc *crtc) -{ -} - static void bochs_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, uint32_t start, uint32_t size) { } -static int bochs_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event, - uint32_t page_flip_flags) +static void bochs_crtc_atomic_begin(struct drm_crtc *crtc) { + /* handle the vblank part removed from bochs_crtc_page_flip */ struct bochs_device *bochs = container_of(crtc, struct bochs_device, crtc); - struct drm_framebuffer *old_fb = crtc->primary->fb; unsigned long irqflags; - crtc->primary->fb = fb; - bochs_crtc_mode_set_base(crtc, 0, 0, old_fb); - if (event) { + if (crtc->state->event) { spin_lock_irqsave(&bochs->dev->event_lock, irqflags); - drm_send_vblank_event(bochs->dev, -1, event); + drm_send_vblank_event(bochs->dev, -1, crtc->state->event); spin_unlock_irqrestore(&bochs->dev->event_lock, irqflags); } - return 0; +} + +static void bochs_crtc_atomic_flush(struct drm_crtc *crtc) +{ } /* These provide the minimum set of functions required to handle a CRTC */ static const struct drm_crtc_funcs bochs_crtc_funcs = { .gamma_set = bochs_crtc_gamma_set, - .set_config = drm_crtc_helper_set_config, + .set_config = drm_atomic_helper_set_config, .destroy = drm_crtc_cleanup, - .page_flip = bochs_crtc_page_flip, + .page_flip = drm_atomic_helper_page_flip, + .reset = drm_atomic_helper_crtc_reset, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, }; static const struct drm_crtc_helper_funcs bochs_helper_funcs = { - .dpms = bochs_crtc_dpms, + .enable = bochs_crtc_enable, + .disable = bochs_crtc_disable, .mode_fixup = bochs_crtc_mode_fixup, - .mode_set = bochs_crtc_mode_set, - .mode_set_base = bochs_crtc_mode_set_base, - .prepare = bochs_crtc_prepare, - .commit = bochs_crtc_commit, + .mode_set_nofb = bochs_crtc_mode_set_nofb, + .atomic_check = bochs_crtc_atomic_check, + .atomic_begin = bochs_crtc_atomic_begin, + .atomic_flush = bochs_crtc_atomic_flush, }; static void bochs_crtc_init(struct drm_device *dev) @@ -152,37 +117,32 @@ static void bochs_crtc_init(struct drm_device *dev) drm_crtc_helper_add(crtc, &bochs_helper_funcs); } -static bool bochs_encoder_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - static void bochs_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { } -static void bochs_encoder_dpms(struct drm_encoder *encoder, int state) +static void bochs_encoder_enable(struct drm_encoder *encoder) { } -static void bochs_encoder_prepare(struct drm_encoder *encoder) +static void bochs_encoder_disable(struct drm_encoder *encoder) { } -static void bochs_encoder_commit(struct drm_encoder *encoder) +static int bochs_encoder_atomic_check(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) { + return 0; } static const struct drm_encoder_helper_funcs bochs_encoder_helper_funcs = { - .dpms = bochs_encoder_dpms, - .mode_fixup = bochs_encoder_mode_fixup, .mode_set = bochs_encoder_mode_set, - .prepare = bochs_encoder_prepare, - .commit = bochs_encoder_commit, + .enable = bochs_encoder_enable, + .disable = bochs_encoder_disable, + .atomic_check = bochs_encoder_atomic_check, }; static const struct drm_encoder_funcs bochs_encoder_encoder_funcs = { @@ -252,10 +212,13 @@ struct drm_connector_helper_funcs bochs_connector_connector_helper_funcs = { }; struct drm_connector_funcs bochs_connector_connector_funcs = { - .dpms = drm_helper_connector_dpms, + .dpms = drm_atomic_helper_connector_dpms, .detect = bochs_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = drm_connector_cleanup, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; static void bochs_connector_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c index 66286ff..3cf05ac 100644 --- a/drivers/gpu/drm/bochs/bochs_mm.c +++ b/drivers/gpu/drm/bochs/bochs_mm.c @@ -545,6 +545,16 @@ bochs_user_framebuffer_create(struct drm_device *dev, return &bochs_fb->base; } +static int bochs_atomic_commit(struct drm_device *dev, + struct drm_atomic_state *state, + bool async) +{ + /* no async */ + return drm_atomic_helper_commit(dev, state, false); +} + const struct drm_mode_config_funcs bochs_mode_funcs = { .fb_create = bochs_user_framebuffer_create, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = bochs_atomic_commit, }; -- 1.7.10.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel