[PATCH] drm/bochs: convert bochs driver to atomic mode-setting
John Hunter
zhjwpku at gmail.com
Wed Jun 10 00:21:39 PDT 2015
From: root <root at 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 at gmail.com>
---
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
More information about the dri-devel
mailing list