diff mbox

drm/bochs: convert bochs driver to atomic mode-setting

Message ID 1433920899-23858-1-git-send-email-zhjwpku@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

John Hunter June 10, 2015, 7:21 a.m. UTC
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@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(-)

Comments

Gerd Hoffmann June 10, 2015, 8:04 a.m. UTC | #1
Hi,

> 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.

With fbdev enabled alot initialization happens with some important
console lock taken, which has the effect that you don't see any kernel
messages until it all succeeded.  If it doesn't succeed you are stuck in
the dark.  Guess this is what happened ...

So, configure a serial console for your virtual machine.
Turn off fbdev support (bochs_drm has a module option for that).
That most likely gives you a clue where things blow up.

Then get X11 running.
kmscon is a nice test too.
When all this works try turning fbdev back on.

HTH,
  Gerd
John Hunter June 10, 2015, 8:15 a.m. UTC | #2
Thanks for the information, I will try that : )

On Wed, Jun 10, 2015 at 4:04 PM, Gerd Hoffmann <kraxel@redhat.com> wrote:

>   Hi,
>
> > 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.
>
> With fbdev enabled alot initialization happens with some important
> console lock taken, which has the effect that you don't see any kernel
> messages until it all succeeded.  If it doesn't succeed you are stuck in
> the dark.  Guess this is what happened ...
>
> So, configure a serial console for your virtual machine.
> Turn off fbdev support (bochs_drm has a module option for that).
> That most likely gives you a clue where things blow up.
>
> Then get X11 running.
> kmscon is a nice test too.
> When all this works try turning fbdev back on.
>
> HTH,
>   Gerd
>
>
>
John Hunter June 10, 2015, 11:39 a.m. UTC | #3
Hi Gerd,
I have tried what you told me.
1. Turn off fbdev support:
    static bool enable_fbdev = *false*;
2. configure a serial console:
    - add something like "*console=ttyS0, 9600n8*" to the grub menuentry
    - add a start parameter to qemu when start the virtual machine "*-serial
pty*"
    - got a redirected device like "*char device redirected to /dev/pts/2*"
    - see the vritual machine's kernel messages in a host console by typing
"*cat /dev/pts/2*"

And stuck in dark but got the messages bellow:

saned disabled; edit /etc/default/saned
[ ok ] Starting network connection manager: NetworkManager.
[ ok ] Starting Common Unix Printing System: cupsd.

The serial console messages also stop here, no other output.

I just don't know if I did the right thing, if I did something wrong, I
would be appreaciate if
you show me.

Best Regards,
Zhao


On Wed, Jun 10, 2015 at 4:15 PM, John Hunter <zhjwpku@gmail.com> wrote:

> Thanks for the information, I will try that : )
>
> On Wed, Jun 10, 2015 at 4:04 PM, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
>>   Hi,
>>
>> > 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.
>>
>> With fbdev enabled alot initialization happens with some important
>> console lock taken, which has the effect that you don't see any kernel
>> messages until it all succeeded.  If it doesn't succeed you are stuck in
>> the dark.  Guess this is what happened ...
>>
>> So, configure a serial console for your virtual machine.
>> Turn off fbdev support (bochs_drm has a module option for that).
>> That most likely gives you a clue where things blow up.
>>
>> Then get X11 running.
>> kmscon is a nice test too.
>> When all this works try turning fbdev back on.
>>
>> HTH,
>>   Gerd
>>
>>
>>
>
>
> --
> Best regards
> Junwang Zhao
> Microprocessor Research and Develop Center
> Department of Computer Science &Technology
> Peking University
> Beijing, 100871, PRC
>
Gerd Hoffmann June 10, 2015, 12:20 p.m. UTC | #4
On Mi, 2015-06-10 at 19:39 +0800, John Hunter wrote:
> Hi Gerd,
> I have tried what you told me.
> 1. Turn off fbdev support:
>     static bool enable_fbdev = false;

Good.

> 2. configure a serial console:
>     - add something like "console=ttyS0, 9600n8" to the grub menuentry

Good.

You can use 115200 as line speed to speedup the console a bit.

>     - add a start parameter to qemu when start the virtual machine
> "-serial pty"

'-serial stdio' might be more convenient.

> saned disabled; edit /etc/default/saned
> [ ok ] Starting network connection manager: NetworkManager.
> [ ok ] Starting Common Unix Printing System: cupsd.
> 
> 
> The serial console messages also stop here, no other output.

Which guest is this?  On modern linux distros (anything systemd-based)
you should automatically get a login prompt on the serial line in case
it is configured as console.  Older systems need manual configuration
for that.  Could also be the system simply hangs here.

Try adding "ignore_loglevel" and "drm.debug=0x07" to the kernel command
line.

HTH,
  Gerd
John Hunter June 11, 2015, 3:18 a.m. UTC | #5
Hi Gerd,
Here is what I got:

[  813.137939] [drm:drm_pci_init]
[  813.142780] [drm:drm_get_pci_dev]
[  813.156986] [drm:drm_minor_register]
[  813.212679] [drm:drm_minor_register] new minor registered 64
[  813.213341] [drm:drm_minor_register]
[  813.215081] [drm:drm_minor_register]
[  813.235736] [drm:drm_minor_register] new minor registered 0
[  813.252701] [drm] Found bochs VGA, ID 0xb0c0.
[  813.254993] [drm] Framebuffer size 8192 kB @ 0xfe000000, ioports @ 0x1ce.
[  813.271384] [TTM] Zone  kernel: Available graphics memory: 513150 kiB
[  813.272036] [TTM] Initializing pool allocator
[  813.279538] [TTM] Initializing DMA pool allocator
[  813.299800] [drm:drm_sysfs_connector_add] adding "Virtual-1" to sysfs
[  813.303164] [drm:drm_sysfs_hotplug_event] generating hotplug event
[  813.313079] [drm] Initialized bochs-drm 1.0.0 20130925 for 0000:00:02.0
on minor 0

If I remove the bochs-drm.ko from its place, then boot the virtual machine,
after it runs,
copy the bochs-drm.ko to its original place, depmod the module, and
modprobe
bochs-drm, it give the messages above. Seems like the bochs driver works,
but
if I reboot with the bochs-drm.ko, it goes to dark, and the messages
related to bochs
is same as above.

I guess the problem is because that I take no care of bochs_hw_setbase
after remove
the bochs_crtc_mode_set_base, but I am not sure.

I will be appreciate if you can review the patch a bit and tell me where
the problem
might be, and I will dig more into that.

I really can't get any clue.

If my question is stupid, forgive me, I will try to catch up :)

Best Regards,
Zhao

On Wed, Jun 10, 2015 at 8:20 PM, Gerd Hoffmann <kraxel@redhat.com> wrote:

> On Mi, 2015-06-10 at 19:39 +0800, John Hunter wrote:
> > Hi Gerd,
> > I have tried what you told me.
> > 1. Turn off fbdev support:
> >     static bool enable_fbdev = false;
>
> Good.
>
> > 2. configure a serial console:
> >     - add something like "console=ttyS0, 9600n8" to the grub menuentry
>
> Good.
>
> You can use 115200 as line speed to speedup the console a bit.
>
> >     - add a start parameter to qemu when start the virtual machine
> > "-serial pty"
>
> '-serial stdio' might be more convenient.
>
> > saned disabled; edit /etc/default/saned
> > [ ok ] Starting network connection manager: NetworkManager.
> > [ ok ] Starting Common Unix Printing System: cupsd.
> >
> >
> > The serial console messages also stop here, no other output.
>
> Which guest is this?  On modern linux distros (anything systemd-based)
> you should automatically get a login prompt on the serial line in case
> it is configured as console.  Older systems need manual configuration
> for that.  Could also be the system simply hangs here.
>
> Try adding "ignore_loglevel" and "drm.debug=0x07" to the kernel command
> line.
>
> HTH,
>   Gerd
>
>
>
>
Gerd Hoffmann June 11, 2015, 6:29 a.m. UTC | #6
On Do, 2015-06-11 at 11:18 +0800, John Hunter wrote:
> Hi Gerd,
> Here is what I got:
> 
> 
> [  813.137939] [drm:drm_pci_init] 
> [  813.142780] [drm:drm_get_pci_dev] 
> [  813.156986] [drm:drm_minor_register] 
> [  813.212679] [drm:drm_minor_register] new minor registered 64
> [  813.213341] [drm:drm_minor_register] 
> [  813.215081] [drm:drm_minor_register] 
> [  813.235736] [drm:drm_minor_register] new minor registered 0
> [  813.252701] [drm] Found bochs VGA, ID 0xb0c0.
> [  813.254993] [drm] Framebuffer size 8192 kB @ 0xfe000000, ioports @
> 0x1ce.
> [  813.271384] [TTM] Zone  kernel: Available graphics memory: 513150
> kiB
> [  813.272036] [TTM] Initializing pool allocator
> [  813.279538] [TTM] Initializing DMA pool allocator
> [  813.299800] [drm:drm_sysfs_connector_add] adding "Virtual-1" to
> sysfs
> [  813.303164] [drm:drm_sysfs_hotplug_event] generating hotplug event
> [  813.313079] [drm] Initialized bochs-drm 1.0.0 20130925 for
> 0000:00:02.0 on minor 0

Looks good.

> If I remove the bochs-drm.ko from its place, then boot the virtual
> machine, after it runs,
> copy the bochs-drm.ko to its original place, depmod the module, and
> modprobe 
> bochs-drm, it give the messages above. Seems like the bochs driver
> works, but
> if I reboot with the bochs-drm.ko, it goes to dark, and the messages
> related to bochs
> is same as above.

Hmm, behavior should be the same no matter whenever it is loaded
automatically at boot time or manually later on.

You can blacklist the module in modprobe.conf if you want prevent it
from autoloading btw.

> I guess the problem is because that I take no care of bochs_hw_setbase
> after remove
> the bochs_crtc_mode_set_base, but I am not sure. 

Possibly, programming the hardware needs to happen at some point ...
Stick a printk in there to see whenever it is called or not.

But remember you don't have a framebuffer console because fbcon is
turned off.  So not having VTs is normal (and thats why you need the
serial console ...)

What happens if you start X?

> I will be appreciate if you can review the patch a bit and tell me
> where the problem
> might be, and I will dig more into that.

Well, it's your gsoc project, not mine.

cheers,
  Gerd
John Hunter June 11, 2015, 6:40 a.m. UTC | #7
On Thu, Jun 11, 2015 at 2:29 PM, Gerd Hoffmann <kraxel@redhat.com> wrote:

> On Do, 2015-06-11 at 11:18 +0800, John Hunter wrote:
> > Hi Gerd,
> > Here is what I got:
> >
> >
> > [  813.137939] [drm:drm_pci_init]
> > [  813.142780] [drm:drm_get_pci_dev]
> > [  813.156986] [drm:drm_minor_register]
> > [  813.212679] [drm:drm_minor_register] new minor registered 64
> > [  813.213341] [drm:drm_minor_register]
> > [  813.215081] [drm:drm_minor_register]
> > [  813.235736] [drm:drm_minor_register] new minor registered 0
> > [  813.252701] [drm] Found bochs VGA, ID 0xb0c0.
> > [  813.254993] [drm] Framebuffer size 8192 kB @ 0xfe000000, ioports @
> > 0x1ce.
> > [  813.271384] [TTM] Zone  kernel: Available graphics memory: 513150
> > kiB
> > [  813.272036] [TTM] Initializing pool allocator
> > [  813.279538] [TTM] Initializing DMA pool allocator
> > [  813.299800] [drm:drm_sysfs_connector_add] adding "Virtual-1" to
> > sysfs
> > [  813.303164] [drm:drm_sysfs_hotplug_event] generating hotplug event
> > [  813.313079] [drm] Initialized bochs-drm 1.0.0 20130925 for
> > 0000:00:02.0 on minor 0
>
> Looks good.
>
> > If I remove the bochs-drm.ko from its place, then boot the virtual
> > machine, after it runs,
> > copy the bochs-drm.ko to its original place, depmod the module, and
> > modprobe
> > bochs-drm, it give the messages above. Seems like the bochs driver
> > works, but
> > if I reboot with the bochs-drm.ko, it goes to dark, and the messages
> > related to bochs
> > is same as above.
>
> Hmm, behavior should be the same no matter whenever it is loaded
> automatically at boot time or manually later on.
>
> You can blacklist the module in modprobe.conf if you want prevent it
> from autoloading btw.
>
> Thanks for the information


> > I guess the problem is because that I take no care of bochs_hw_setbase
> > after remove
> > the bochs_crtc_mode_set_base, but I am not sure.
>
> Possibly, programming the hardware needs to happen at some point ...
> Stick a printk in there to see whenever it is called or not.
>
> But remember you don't have a framebuffer console because fbcon is
> turned off.  So not having VTs is normal (and thats why you need the
> serial console ...)
>
> What happens if you start X?
>
> I think in the distro (debian 7) it runs X automatically


> > I will be appreciate if you can review the patch a bit and tell me
> > where the problem
> > might be, and I will dig more into that.
>
> Well, it's your gsoc project, not mine.

I guess I have asked a stupid question :) , sorry about that.
Anyway, I will try to figure it out.

>
>
cheers,
>   Gerd
>
>
>
diff mbox

Patch

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,
 };