mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-17 05:45:20 +00:00
drm/radeon: Run DRM default client setup
Rework fbdev probing to support fbdev_probe in struct drm_driver and remove the old fb_probe callback. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The radeon driver specifies a preferred color mode depending on the available video memory, with a default of 32. Adapt this for the new client interface. v5: - select DRM_CLIENT_SELECTION v2: - style changes Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: "Christian König" <christian.koenig@amd.com> Cc: Xinhui Pan <Xinhui.Pan@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-78-tzimmermann@suse.de
This commit is contained in:
parent
fe96a73ae5
commit
41d48e557e
@ -5,6 +5,7 @@ config DRM_RADEON
|
||||
depends on DRM && PCI && MMU
|
||||
depends on AGP || !AGP
|
||||
select FW_LOADER
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_DISPLAY_DP_HELPER
|
||||
select DRM_DISPLAY_HELPER
|
||||
select DRM_KMS_HELPER
|
||||
|
@ -38,8 +38,10 @@
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <drm/drm_aperture.h>
|
||||
#include <drm/drm_client_setup.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_file.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_gem.h>
|
||||
#include <drm/drm_ioctl.h>
|
||||
#include <drm/drm_pciids.h>
|
||||
@ -261,6 +263,7 @@ static int radeon_pci_probe(struct pci_dev *pdev,
|
||||
unsigned long flags = 0;
|
||||
struct drm_device *ddev;
|
||||
struct radeon_device *rdev;
|
||||
const struct drm_format_info *format;
|
||||
int ret;
|
||||
|
||||
if (!ent)
|
||||
@ -324,7 +327,14 @@ static int radeon_pci_probe(struct pci_dev *pdev,
|
||||
if (ret)
|
||||
goto err_agp;
|
||||
|
||||
radeon_fbdev_setup(ddev->dev_private);
|
||||
if (rdev->mc.real_vram_size <= (8 * 1024 * 1024))
|
||||
format = drm_format_info(DRM_FORMAT_C8);
|
||||
else if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32 * 1024 * 1024))
|
||||
format = drm_format_info(DRM_FORMAT_RGB565);
|
||||
else
|
||||
format = NULL;
|
||||
|
||||
drm_client_setup(ddev, format);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -590,6 +600,8 @@ static const struct drm_driver kms_driver = {
|
||||
|
||||
.gem_prime_import_sg_table = radeon_gem_prime_import_sg_table,
|
||||
|
||||
RADEON_FBDEV_DRIVER_OPS,
|
||||
|
||||
.name = DRIVER_NAME,
|
||||
.desc = DRIVER_DESC,
|
||||
.date = DRIVER_DATE,
|
||||
|
@ -198,12 +198,11 @@ static const struct fb_ops radeon_fbdev_fb_ops = {
|
||||
.fb_destroy = radeon_fbdev_fb_destroy,
|
||||
};
|
||||
|
||||
/*
|
||||
* Fbdev helpers and struct drm_fb_helper_funcs
|
||||
*/
|
||||
static const struct drm_fb_helper_funcs radeon_fbdev_fb_helper_funcs = {
|
||||
};
|
||||
|
||||
static int radeon_fbdev_fb_helper_fb_probe(struct drm_fb_helper *fb_helper,
|
||||
struct drm_fb_helper_surface_size *sizes)
|
||||
int radeon_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
|
||||
struct drm_fb_helper_surface_size *sizes)
|
||||
{
|
||||
struct radeon_device *rdev = fb_helper->dev->dev_private;
|
||||
struct drm_mode_fb_cmd2 mode_cmd = { };
|
||||
@ -243,6 +242,7 @@ static int radeon_fbdev_fb_helper_fb_probe(struct drm_fb_helper *fb_helper,
|
||||
}
|
||||
|
||||
/* setup helper */
|
||||
fb_helper->funcs = &radeon_fbdev_fb_helper_funcs;
|
||||
fb_helper->fb = fb;
|
||||
|
||||
/* okay we have an object now allocate the framebuffer */
|
||||
@ -288,110 +288,6 @@ err_radeon_fbdev_destroy_pinned_object:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct drm_fb_helper_funcs radeon_fbdev_fb_helper_funcs = {
|
||||
.fb_probe = radeon_fbdev_fb_helper_fb_probe,
|
||||
};
|
||||
|
||||
/*
|
||||
* Fbdev client and struct drm_client_funcs
|
||||
*/
|
||||
|
||||
static void radeon_fbdev_client_unregister(struct drm_client_dev *client)
|
||||
{
|
||||
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
|
||||
struct drm_device *dev = fb_helper->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
||||
if (fb_helper->info) {
|
||||
vga_switcheroo_client_fb_set(rdev->pdev, NULL);
|
||||
drm_helper_force_disable_all(dev);
|
||||
drm_fb_helper_unregister_info(fb_helper);
|
||||
} else {
|
||||
drm_client_release(&fb_helper->client);
|
||||
drm_fb_helper_unprepare(fb_helper);
|
||||
kfree(fb_helper);
|
||||
}
|
||||
}
|
||||
|
||||
static int radeon_fbdev_client_restore(struct drm_client_dev *client)
|
||||
{
|
||||
drm_fb_helper_lastclose(client->dev);
|
||||
vga_switcheroo_process_delayed_switch();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_fbdev_client_hotplug(struct drm_client_dev *client)
|
||||
{
|
||||
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
|
||||
struct drm_device *dev = client->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
int ret;
|
||||
|
||||
if (dev->fb_helper)
|
||||
return drm_fb_helper_hotplug_event(dev->fb_helper);
|
||||
|
||||
ret = drm_fb_helper_init(dev, fb_helper);
|
||||
if (ret)
|
||||
goto err_drm_err;
|
||||
|
||||
if (!drm_drv_uses_atomic_modeset(dev))
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
|
||||
ret = drm_fb_helper_initial_config(fb_helper);
|
||||
if (ret)
|
||||
goto err_drm_fb_helper_fini;
|
||||
|
||||
vga_switcheroo_client_fb_set(rdev->pdev, fb_helper->info);
|
||||
|
||||
return 0;
|
||||
|
||||
err_drm_fb_helper_fini:
|
||||
drm_fb_helper_fini(fb_helper);
|
||||
err_drm_err:
|
||||
drm_err(dev, "Failed to setup radeon fbdev emulation (ret=%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct drm_client_funcs radeon_fbdev_client_funcs = {
|
||||
.owner = THIS_MODULE,
|
||||
.unregister = radeon_fbdev_client_unregister,
|
||||
.restore = radeon_fbdev_client_restore,
|
||||
.hotplug = radeon_fbdev_client_hotplug,
|
||||
};
|
||||
|
||||
void radeon_fbdev_setup(struct radeon_device *rdev)
|
||||
{
|
||||
struct drm_fb_helper *fb_helper;
|
||||
int bpp_sel = 32;
|
||||
int ret;
|
||||
|
||||
if (rdev->mc.real_vram_size <= (8 * 1024 * 1024))
|
||||
bpp_sel = 8;
|
||||
else if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32 * 1024 * 1024))
|
||||
bpp_sel = 16;
|
||||
|
||||
fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
|
||||
if (!fb_helper)
|
||||
return;
|
||||
drm_fb_helper_prepare(rdev_to_drm(rdev), fb_helper, bpp_sel, &radeon_fbdev_fb_helper_funcs);
|
||||
|
||||
ret = drm_client_init(rdev_to_drm(rdev), &fb_helper->client, "radeon-fbdev",
|
||||
&radeon_fbdev_client_funcs);
|
||||
if (ret) {
|
||||
drm_err(rdev_to_drm(rdev), "Failed to register client: %d\n", ret);
|
||||
goto err_drm_client_init;
|
||||
}
|
||||
|
||||
drm_client_register(&fb_helper->client);
|
||||
|
||||
return;
|
||||
|
||||
err_drm_client_init:
|
||||
drm_fb_helper_unprepare(fb_helper);
|
||||
kfree(fb_helper);
|
||||
}
|
||||
|
||||
void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state)
|
||||
{
|
||||
if (rdev_to_drm(rdev)->fb_helper)
|
||||
|
@ -38,6 +38,9 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-algo-bit.h>
|
||||
|
||||
struct drm_fb_helper;
|
||||
struct drm_fb_helper_surface_size;
|
||||
|
||||
struct edid;
|
||||
struct drm_edid;
|
||||
struct radeon_bo;
|
||||
@ -935,12 +938,15 @@ void dce8_program_fmt(struct drm_encoder *encoder);
|
||||
|
||||
/* fbdev layer */
|
||||
#if defined(CONFIG_DRM_FBDEV_EMULATION)
|
||||
void radeon_fbdev_setup(struct radeon_device *rdev);
|
||||
int radeon_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
|
||||
struct drm_fb_helper_surface_size *sizes);
|
||||
#define RADEON_FBDEV_DRIVER_OPS \
|
||||
.fbdev_probe = radeon_fbdev_driver_fbdev_probe
|
||||
void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state);
|
||||
bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj);
|
||||
#else
|
||||
static inline void radeon_fbdev_setup(struct radeon_device *rdev)
|
||||
{ }
|
||||
#define RADEON_FBDEV_DRIVER_OPS \
|
||||
.fbdev_probe = NULL
|
||||
static inline void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state)
|
||||
{ }
|
||||
static inline bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
|
||||
|
Loading…
x
Reference in New Issue
Block a user