On Wed, Jan 11, 2023 at 04:38:13PM +0100, Thomas Zimmermann wrote: > Set the framebuffer info for drivers that support VGA switcheroo. Only > affects the amdgpu driver, which uses VGA switcheroo and generic fbdev > emulation. For other drivers, this does nothing. > > Amdgpu's lastclose helper called vga_switcheroo_process_delayed_switch(). > But as amdgpu uses generic fbdev emulation, it's better to call the helper > from drm_lastclose(), after the kernel client's screen has been restored. > So all drivers and clients can benefit. Radeon and nouveau with modernized > fbdev code are possible candidates. > > There was an earlier patchset to do something similar. [1] > > Suggested-by: Alexander Deucher <Alexander.Deucher@xxxxxxx> > Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> > Link: https://lore.kernel.org/amd-gfx/20221020143603.563929-1-alexander.deucher@xxxxxxx/ # 1 Indeed, vga_switcheroo_client_fb_set is a no-op if no client is registered on that pdev. Reviewed-by: Daniel Vetter <daniel.vetter@xxxxxxxx> t-b/ack from amd would be still good I think (or maybe they'll pick this one up so it goes through their CI). -Daniel > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 - > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 - > drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 12 ------------ > drivers/gpu/drm/drm_fb_helper.c | 8 ++++++++ > drivers/gpu/drm/drm_file.c | 3 +++ > 5 files changed, 11 insertions(+), 14 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index 63c921c55fb9..7120b9b6e580 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -1330,7 +1330,6 @@ extern const int amdgpu_max_kms_ioctl; > > int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags); > void amdgpu_driver_unload_kms(struct drm_device *dev); > -void amdgpu_driver_lastclose_kms(struct drm_device *dev); > int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv); > void amdgpu_driver_postclose_kms(struct drm_device *dev, > struct drm_file *file_priv); > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > index ebc6e6cbe2ab..02d636f781a2 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > @@ -2784,7 +2784,6 @@ static const struct drm_driver amdgpu_kms_driver = { > DRIVER_SYNCOBJ_TIMELINE, > .open = amdgpu_driver_open_kms, > .postclose = amdgpu_driver_postclose_kms, > - .lastclose = amdgpu_driver_lastclose_kms, > .ioctls = amdgpu_ioctls_kms, > .num_ioctls = ARRAY_SIZE(amdgpu_ioctls_kms), > .dumb_create = amdgpu_mode_dumb_create, > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > index 7aa7e52ca784..886739576d3d 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > @@ -1104,18 +1104,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) > /* > * Outdated mess for old drm with Xorg being in charge (void function now). > */ > -/** > - * amdgpu_driver_lastclose_kms - drm callback for last close > - * > - * @dev: drm dev pointer > - * > - * Switch vga_switcheroo state after last close (all asics). > - */ > -void amdgpu_driver_lastclose_kms(struct drm_device *dev) > -{ > - drm_fb_helper_lastclose(dev); > - vga_switcheroo_process_delayed_switch(); > -} > > /** > * amdgpu_driver_open_kms - drm callback for open > diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c > index 427631706128..5e445c61252d 100644 > --- a/drivers/gpu/drm/drm_fb_helper.c > +++ b/drivers/gpu/drm/drm_fb_helper.c > @@ -30,7 +30,9 @@ > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > > #include <linux/console.h> > +#include <linux/pci.h> > #include <linux/sysrq.h> > +#include <linux/vga_switcheroo.h> > > #include <drm/drm_atomic.h> > #include <drm/drm_drv.h> > @@ -1940,6 +1942,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, > int preferred_bpp) > { > struct drm_client_dev *client = &fb_helper->client; > + struct drm_device *dev = fb_helper->dev; > struct drm_fb_helper_surface_size sizes; > int ret; > > @@ -1961,6 +1964,11 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, > return ret; > > strcpy(fb_helper->fb->comm, "[fbcon]"); > + > + /* Set the fb info for vgaswitcheroo clients. Does nothing otherwise. */ > + if (dev_is_pci(dev->dev)) > + vga_switcheroo_client_fb_set(to_pci_dev(dev->dev), fb_helper->info); > + > return 0; > } > > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c > index a51ff8cee049..314c309db9a3 100644 > --- a/drivers/gpu/drm/drm_file.c > +++ b/drivers/gpu/drm/drm_file.c > @@ -38,6 +38,7 @@ > #include <linux/pci.h> > #include <linux/poll.h> > #include <linux/slab.h> > +#include <linux/vga_switcheroo.h> > > #include <drm/drm_client.h> > #include <drm/drm_drv.h> > @@ -460,6 +461,8 @@ void drm_lastclose(struct drm_device * dev) > drm_legacy_dev_reinit(dev); > > drm_client_dev_restore(dev); > + > + vga_switcheroo_process_delayed_switch(); > } > > /** > -- > 2.39.0 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch