Commit 2e2245ef authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-next-2023-01-26' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for v6.3:

UAPI Changes:

Cross-subsystem Changes:

Core Changes:

 * fbdev-helper: Streamline code in generic fbdev and its helpers

 * TTM: Fixes plus their reverts

Driver Changes:

 * accel/ivpu: Typo fixes

 * i915: TTM-related fixes

 * nouveau: Remove unused return value from disable helper
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/Y9I2nOzHxTxPeTjg@linux-uq9g
parents 68de345e 6ca80b9e
...@@ -608,7 +608,7 @@ static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable) ...@@ -608,7 +608,7 @@ static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable)
ret = REGB_POLL_FLD(MTL_BUTTRESS_VPU_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US); ret = REGB_POLL_FLD(MTL_BUTTRESS_VPU_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
if (ret) { if (ret) {
ivpu_err(vdev, "Failed to sync before D0i3 tansition: %d\n", ret); ivpu_err(vdev, "Failed to sync before D0i3 transition: %d\n", ret);
return ret; return ret;
} }
...@@ -621,7 +621,7 @@ static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable) ...@@ -621,7 +621,7 @@ static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable)
ret = REGB_POLL_FLD(MTL_BUTTRESS_VPU_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US); ret = REGB_POLL_FLD(MTL_BUTTRESS_VPU_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
if (ret) if (ret)
ivpu_err(vdev, "Failed to sync after D0i3 tansition: %d\n", ret); ivpu_err(vdev, "Failed to sync after D0i3 transition: %d\n", ret);
return ret; return ret;
} }
......
...@@ -129,7 +129,7 @@ int armada_fbdev_init(struct drm_device *dev) ...@@ -129,7 +129,7 @@ int armada_fbdev_init(struct drm_device *dev)
priv->fbdev = fbh; priv->fbdev = fbh;
drm_fb_helper_prepare(dev, fbh, &armada_fb_helper_funcs); drm_fb_helper_prepare(dev, fbh, 32, &armada_fb_helper_funcs);
ret = drm_fb_helper_init(dev, fbh); ret = drm_fb_helper_init(dev, fbh);
if (ret) { if (ret) {
...@@ -137,7 +137,7 @@ int armada_fbdev_init(struct drm_device *dev) ...@@ -137,7 +137,7 @@ int armada_fbdev_init(struct drm_device *dev)
goto err_fb_helper; goto err_fb_helper;
} }
ret = drm_fb_helper_initial_config(fbh, 32); ret = drm_fb_helper_initial_config(fbh);
if (ret) { if (ret) {
DRM_ERROR("failed to set initial config\n"); DRM_ERROR("failed to set initial config\n");
goto err_fb_setup; goto err_fb_setup;
......
...@@ -198,13 +198,23 @@ void drm_client_dev_hotplug(struct drm_device *dev) ...@@ -198,13 +198,23 @@ void drm_client_dev_hotplug(struct drm_device *dev)
if (!drm_core_check_feature(dev, DRIVER_MODESET)) if (!drm_core_check_feature(dev, DRIVER_MODESET))
return; return;
if (!dev->mode_config.num_connector) {
drm_dbg_kms(dev, "No connectors found, will not send hotplug events!\n");
return;
}
mutex_lock(&dev->clientlist_mutex); mutex_lock(&dev->clientlist_mutex);
list_for_each_entry(client, &dev->clientlist, list) { list_for_each_entry(client, &dev->clientlist, list) {
if (!client->funcs || !client->funcs->hotplug) if (!client->funcs || !client->funcs->hotplug)
continue; continue;
if (client->hotplug_failed)
continue;
ret = client->funcs->hotplug(client); ret = client->funcs->hotplug(client);
drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret); drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
if (ret)
client->hotplug_failed = true;
} }
mutex_unlock(&dev->clientlist_mutex); mutex_unlock(&dev->clientlist_mutex);
} }
......
...@@ -414,14 +414,30 @@ static void drm_fb_helper_damage_work(struct work_struct *work) ...@@ -414,14 +414,30 @@ static void drm_fb_helper_damage_work(struct work_struct *work)
* drm_fb_helper_prepare - setup a drm_fb_helper structure * drm_fb_helper_prepare - setup a drm_fb_helper structure
* @dev: DRM device * @dev: DRM device
* @helper: driver-allocated fbdev helper structure to set up * @helper: driver-allocated fbdev helper structure to set up
* @preferred_bpp: Preferred bits per pixel for the device.
* @funcs: pointer to structure of functions associate with this helper * @funcs: pointer to structure of functions associate with this helper
* *
* Sets up the bare minimum to make the framebuffer helper usable. This is * Sets up the bare minimum to make the framebuffer helper usable. This is
* useful to implement race-free initialization of the polling helpers. * useful to implement race-free initialization of the polling helpers.
*/ */
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
unsigned int preferred_bpp,
const struct drm_fb_helper_funcs *funcs) const struct drm_fb_helper_funcs *funcs)
{ {
/*
* Pick a preferred bpp of 32 if no value has been given. This
* will select XRGB8888 for the framebuffer formats. All drivers
* have to support XRGB8888 for backwards compatibility with legacy
* userspace, so it's the safe choice here.
*
* TODO: Replace struct drm_mode_config.preferred_depth and this
* bpp value with a preferred format that is given as struct
* drm_format_info. Then derive all other values from the
* format.
*/
if (!preferred_bpp)
preferred_bpp = 32;
INIT_LIST_HEAD(&helper->kernel_fb_list); INIT_LIST_HEAD(&helper->kernel_fb_list);
spin_lock_init(&helper->damage_lock); spin_lock_init(&helper->damage_lock);
INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker); INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker);
...@@ -430,9 +446,22 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, ...@@ -430,9 +446,22 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
mutex_init(&helper->lock); mutex_init(&helper->lock);
helper->funcs = funcs; helper->funcs = funcs;
helper->dev = dev; helper->dev = dev;
helper->preferred_bpp = preferred_bpp;
} }
EXPORT_SYMBOL(drm_fb_helper_prepare); EXPORT_SYMBOL(drm_fb_helper_prepare);
/**
* drm_fb_helper_unprepare - clean up a drm_fb_helper structure
* @fb_helper: driver-allocated fbdev helper structure to set up
*
* Cleans up the framebuffer helper. Inverse of drm_fb_helper_prepare().
*/
void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper)
{
mutex_destroy(&fb_helper->lock);
}
EXPORT_SYMBOL(drm_fb_helper_unprepare);
/** /**
* drm_fb_helper_init - initialize a &struct drm_fb_helper * drm_fb_helper_init - initialize a &struct drm_fb_helper
* @dev: drm device * @dev: drm device
...@@ -559,7 +588,7 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) ...@@ -559,7 +588,7 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
} }
mutex_unlock(&kernel_fb_helper_lock); mutex_unlock(&kernel_fb_helper_lock);
mutex_destroy(&fb_helper->lock); drm_fb_helper_unprepare(fb_helper);
if (!fb_helper->client.funcs) if (!fb_helper->client.funcs)
drm_client_release(&fb_helper->client); drm_client_release(&fb_helper->client);
...@@ -1772,7 +1801,7 @@ static uint32_t drm_fb_helper_find_color_mode_format(struct drm_fb_helper *fb_he ...@@ -1772,7 +1801,7 @@ static uint32_t drm_fb_helper_find_color_mode_format(struct drm_fb_helper *fb_he
return drm_fb_helper_find_format(fb_helper, formats, format_count, bpp, depth); return drm_fb_helper_find_format(fb_helper, formats, format_count, bpp, depth);
} }
static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferred_bpp, static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper,
struct drm_fb_helper_surface_size *sizes) struct drm_fb_helper_surface_size *sizes)
{ {
struct drm_client_dev *client = &fb_helper->client; struct drm_client_dev *client = &fb_helper->client;
...@@ -1817,7 +1846,7 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int prefe ...@@ -1817,7 +1846,7 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int prefe
surface_format = drm_fb_helper_find_color_mode_format(fb_helper, surface_format = drm_fb_helper_find_color_mode_format(fb_helper,
plane->format_types, plane->format_types,
plane->format_count, plane->format_count,
preferred_bpp); fb_helper->preferred_bpp);
if (surface_format != DRM_FORMAT_INVALID) if (surface_format != DRM_FORMAT_INVALID)
break; /* found supported format */ break; /* found supported format */
} }
...@@ -1889,7 +1918,7 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int prefe ...@@ -1889,7 +1918,7 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int prefe
return 0; return 0;
} }
static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferred_bpp, static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper,
struct drm_fb_helper_surface_size *sizes) struct drm_fb_helper_surface_size *sizes)
{ {
struct drm_client_dev *client = &fb_helper->client; struct drm_client_dev *client = &fb_helper->client;
...@@ -1898,7 +1927,7 @@ static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferr ...@@ -1898,7 +1927,7 @@ static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferr
int ret; int ret;
mutex_lock(&client->modeset_mutex); mutex_lock(&client->modeset_mutex);
ret = __drm_fb_helper_find_sizes(fb_helper, preferred_bpp, sizes); ret = __drm_fb_helper_find_sizes(fb_helper, sizes);
mutex_unlock(&client->modeset_mutex); mutex_unlock(&client->modeset_mutex);
if (ret) if (ret)
...@@ -1920,14 +1949,13 @@ static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferr ...@@ -1920,14 +1949,13 @@ static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferr
* Allocates the backing storage and sets up the fbdev info structure through * Allocates the backing storage and sets up the fbdev info structure through
* the ->fb_probe callback. * the ->fb_probe callback.
*/ */
static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, 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_client_dev *client = &fb_helper->client;
struct drm_fb_helper_surface_size sizes; struct drm_fb_helper_surface_size sizes;
int ret; int ret;
ret = drm_fb_helper_find_sizes(fb_helper, preferred_bpp, &sizes); ret = drm_fb_helper_find_sizes(fb_helper, &sizes);
if (ret) { if (ret) {
/* First time: disable all crtc's.. */ /* First time: disable all crtc's.. */
if (!fb_helper->deferred_setup) if (!fb_helper->deferred_setup)
...@@ -2105,8 +2133,7 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper) ...@@ -2105,8 +2133,7 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
/* Note: Drops fb_helper->lock before returning. */ /* Note: Drops fb_helper->lock before returning. */
static int static int
__drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper)
int bpp_sel)
{ {
struct drm_device *dev = fb_helper->dev; struct drm_device *dev = fb_helper->dev;
struct fb_info *info; struct fb_info *info;
...@@ -2117,10 +2144,9 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, ...@@ -2117,10 +2144,9 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
height = dev->mode_config.max_height; height = dev->mode_config.max_height;
drm_client_modeset_probe(&fb_helper->client, width, height); drm_client_modeset_probe(&fb_helper->client, width, height);
ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); ret = drm_fb_helper_single_fb_probe(fb_helper);
if (ret < 0) { if (ret < 0) {
if (ret == -EAGAIN) { if (ret == -EAGAIN) {
fb_helper->preferred_bpp = bpp_sel;
fb_helper->deferred_setup = true; fb_helper->deferred_setup = true;
ret = 0; ret = 0;
} }
...@@ -2166,7 +2192,6 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, ...@@ -2166,7 +2192,6 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
/** /**
* drm_fb_helper_initial_config - setup a sane initial connector configuration * drm_fb_helper_initial_config - setup a sane initial connector configuration
* @fb_helper: fb_helper device struct * @fb_helper: fb_helper device struct
* @bpp_sel: bpp value to use for the framebuffer configuration
* *
* Scans the CRTCs and connectors and tries to put together an initial setup. * Scans the CRTCs and connectors and tries to put together an initial setup.
* At the moment, this is a cloned configuration across all heads with * At the moment, this is a cloned configuration across all heads with
...@@ -2204,7 +2229,7 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, ...@@ -2204,7 +2229,7 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
* RETURNS: * RETURNS:
* Zero if everything went ok, nonzero otherwise. * Zero if everything went ok, nonzero otherwise.
*/ */
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)
{ {
int ret; int ret;
...@@ -2212,7 +2237,7 @@ int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) ...@@ -2212,7 +2237,7 @@ int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
return 0; return 0;
mutex_lock(&fb_helper->lock); mutex_lock(&fb_helper->lock);
ret = __drm_fb_helper_initial_config_and_unlock(fb_helper, bpp_sel); ret = __drm_fb_helper_initial_config_and_unlock(fb_helper);
return ret; return ret;
} }
...@@ -2248,8 +2273,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) ...@@ -2248,8 +2273,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
mutex_lock(&fb_helper->lock); mutex_lock(&fb_helper->lock);
if (fb_helper->deferred_setup) { if (fb_helper->deferred_setup) {
err = __drm_fb_helper_initial_config_and_unlock(fb_helper, err = __drm_fb_helper_initial_config_and_unlock(fb_helper);
fb_helper->preferred_bpp);
return err; return err;
} }
......
...@@ -43,20 +43,18 @@ static int drm_fbdev_fb_release(struct fb_info *info, int user) ...@@ -43,20 +43,18 @@ static int drm_fbdev_fb_release(struct fb_info *info, int user)
return 0; return 0;
} }
static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper) static void drm_fbdev_fb_destroy(struct fb_info *info)
{ {
struct fb_info *fbi = fb_helper->info; struct drm_fb_helper *fb_helper = info->par;
void *shadow = NULL; void *shadow = NULL;
if (!fb_helper->dev) if (!fb_helper->dev)
return; return;
if (fbi) { if (info->fbdefio)
if (fbi->fbdefio) fb_deferred_io_cleanup(info);
fb_deferred_io_cleanup(fbi); if (drm_fbdev_use_shadow_fb(fb_helper))
if (drm_fbdev_use_shadow_fb(fb_helper)) shadow = info->screen_buffer;
shadow = fbi->screen_buffer;
}
drm_fb_helper_fini(fb_helper); drm_fb_helper_fini(fb_helper);
...@@ -66,24 +64,10 @@ static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper) ...@@ -66,24 +64,10 @@ static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper)
drm_client_buffer_vunmap(fb_helper->buffer); drm_client_buffer_vunmap(fb_helper->buffer);
drm_client_framebuffer_delete(fb_helper->buffer); drm_client_framebuffer_delete(fb_helper->buffer);
}
static void drm_fbdev_release(struct drm_fb_helper *fb_helper)
{
drm_fbdev_cleanup(fb_helper);
drm_client_release(&fb_helper->client); drm_client_release(&fb_helper->client);
kfree(fb_helper); kfree(fb_helper);
} }
/*
* fb_ops.fb_destroy is called by the last put_fb_info() call at the end of
* unregister_framebuffer() or fb_release().
*/
static void drm_fbdev_fb_destroy(struct fb_info *info)
{
drm_fbdev_release(info->par);
}
static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{ {
struct drm_fb_helper *fb_helper = info->par; struct drm_fb_helper *fb_helper = info->par;
...@@ -186,7 +170,7 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper, ...@@ -186,7 +170,7 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
struct drm_device *dev = fb_helper->dev; struct drm_device *dev = fb_helper->dev;
struct drm_client_buffer *buffer; struct drm_client_buffer *buffer;
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
struct fb_info *fbi; struct fb_info *info;
u32 format; u32 format;
struct iosys_map map; struct iosys_map map;
int ret; int ret;
...@@ -205,35 +189,35 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper, ...@@ -205,35 +189,35 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
fb_helper->fb = buffer->fb; fb_helper->fb = buffer->fb;
fb = buffer->fb; fb = buffer->fb;
fbi = drm_fb_helper_alloc_info(fb_helper); info = drm_fb_helper_alloc_info(fb_helper);
if (IS_ERR(fbi)) if (IS_ERR(info))
return PTR_ERR(fbi); return PTR_ERR(info);
fbi->fbops = &drm_fbdev_fb_ops; info->fbops = &drm_fbdev_fb_ops;
fbi->screen_size = sizes->surface_height * fb->pitches[0]; info->screen_size = sizes->surface_height * fb->pitches[0];
fbi->fix.smem_len = fbi->screen_size; info->fix.smem_len = info->screen_size;
fbi->flags = FBINFO_DEFAULT; info->flags = FBINFO_DEFAULT;
drm_fb_helper_fill_info(fbi, fb_helper, sizes); drm_fb_helper_fill_info(info, fb_helper, sizes);
if (drm_fbdev_use_shadow_fb(fb_helper)) { if (drm_fbdev_use_shadow_fb(fb_helper)) {
fbi->screen_buffer = vzalloc(fbi->screen_size); info->screen_buffer = vzalloc(info->screen_size);
if (!fbi->screen_buffer) if (!info->screen_buffer)
return -ENOMEM; return -ENOMEM;
fbi->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
fbi->fbdefio = &drm_fbdev_defio; info->fbdefio = &drm_fbdev_defio;
fb_deferred_io_init(fbi); fb_deferred_io_init(info);
} else { } else {
/* buffer is mapped for HW framebuffer */ /* buffer is mapped for HW framebuffer */
ret = drm_client_buffer_vmap(fb_helper->buffer, &map); ret = drm_client_buffer_vmap(fb_helper->buffer, &map);
if (ret) if (ret)
return ret; return ret;
if (map.is_iomem) { if (map.is_iomem) {
fbi->screen_base = map.vaddr_iomem; info->screen_base = map.vaddr_iomem;
} else { } else {
fbi->screen_buffer = map.vaddr; info->screen_buffer = map.vaddr;
fbi->flags |= FBINFO_VIRTFB; info->flags |= FBINFO_VIRTFB;
} }
/* /*
...@@ -242,10 +226,10 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper, ...@@ -242,10 +226,10 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
* case. * case.
*/ */
#if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM) #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM)
if (fb_helper->hint_leak_smem_start && fbi->fix.smem_start == 0 && if (fb_helper->hint_leak_smem_start && info->fix.smem_start == 0 &&
!drm_WARN_ON_ONCE(dev, map.is_iomem)) !drm_WARN_ON_ONCE(dev, map.is_iomem))
fbi->fix.smem_start = info->fix.smem_start =
page_to_phys(virt_to_page(fbi->screen_buffer)); page_to_phys(virt_to_page(info->screen_buffer));
#endif #endif
} }
...@@ -362,11 +346,13 @@ static void drm_fbdev_client_unregister(struct drm_client_dev *client) ...@@ -362,11 +346,13 @@ static void drm_fbdev_client_unregister(struct drm_client_dev *client)
{ {
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
if (fb_helper->info) if (fb_helper->info) {
/* drm_fbdev_fb_destroy() takes care of cleanup */
drm_fb_helper_unregister_info(fb_helper); drm_fb_helper_unregister_info(fb_helper);
else } else {
drm_fbdev_release(fb_helper); drm_client_release(&fb_helper->client);
drm_fb_helper_unprepare(fb_helper);
kfree(fb_helper);
}
} }
static int drm_fbdev_client_restore(struct drm_client_dev *client) static int drm_fbdev_client_restore(struct drm_client_dev *client)
...@@ -382,41 +368,26 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client) ...@@ -382,41 +368,26 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client)
struct drm_device *dev = client->dev; struct drm_device *dev = client->dev;
int ret; int ret;
/* Setup is not retried if it has failed */
if (!fb_helper->dev && fb_helper->funcs)
return 0;
if (dev->fb_helper) if (dev->fb_helper)
return drm_fb_helper_hotplug_event(dev->fb_helper); return drm_fb_helper_hotplug_event(dev->fb_helper);
if (!dev->mode_config.num_connector) {
drm_dbg_kms(dev, "No connectors found, will not create framebuffer!\n");
return 0;
}
drm_fb_helper_prepare(dev, fb_helper, &drm_fb_helper_generic_funcs);
ret = drm_fb_helper_init(dev, fb_helper); ret = drm_fb_helper_init(dev, fb_helper);
if (ret) if (ret)
goto err; goto err_drm_err;
if (!drm_drv_uses_atomic_modeset(dev)) if (!drm_drv_uses_atomic_modeset(dev))
drm_helper_disable_unused_functions(dev); drm_helper_disable_unused_functions(dev);
ret = drm_fb_helper_initial_config(fb_helper, fb_helper->preferred_bpp); ret = drm_fb_helper_initial_config(fb_helper);
if (ret) if (ret)
goto err_cleanup; goto err_drm_fb_helper_fini;
return 0; return 0;
err_cleanup: err_drm_fb_helper_fini:
drm_fbdev_cleanup(fb_helper); drm_fb_helper_fini(fb_helper);
err: err_drm_err:
fb_helper->dev = NULL;
fb_helper->info = NULL;
drm_err(dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret); drm_err(dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret);
return ret; return ret;
} }
...@@ -465,33 +436,25 @@ void drm_fbdev_generic_setup(struct drm_device *dev, ...@@ -465,33 +436,25 @@ void drm_fbdev_generic_setup(struct drm_device *dev,
fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
if (!fb_helper) if (!fb_helper)
return; return;
drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &drm_fb_helper_generic_funcs);
ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs); ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs);
if (ret) { if (ret) {
kfree(fb_helper);
drm_err(dev, "Failed to register client: %d\n", ret); drm_err(dev, "Failed to register client: %d\n", ret);
return; goto err_drm_client_init;
} }
/*
* Pick a preferred bpp of 32 if no value has been given. This
* will select XRGB8888 for the framebuffer formats. All drivers
* have to support XRGB8888 for backwards compatibility with legacy
* userspace, so it's the safe choice here.
*
* TODO: Replace struct drm_mode_config.preferred_depth and this
* bpp value with a preferred format that is given as struct
* drm_format_info. Then derive all other values from the
* format.
*/
if (!preferred_bpp)
preferred_bpp = 32;
fb_helper->preferred_bpp = preferred_bpp;
ret = drm_fbdev_client_hotplug(&fb_helper->client); ret = drm_fbdev_client_hotplug(&fb_helper->client);
if (ret) if (ret)
drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
drm_client_register(&fb_helper->client); drm_client_register(&fb_helper->client);
return;
err_drm_client_init:
drm_fb_helper_unprepare(fb_helper);
kfree(fb_helper);
return;
} }
EXPORT_SYMBOL(drm_fbdev_generic_setup); EXPORT_SYMBOL(drm_fbdev_generic_setup);
...@@ -163,7 +163,7 @@ int exynos_drm_fbdev_init(struct drm_device *dev) ...@@ -163,7 +163,7 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
private->fb_helper = helper = &fbdev->drm_fb_helper; private->fb_helper = helper = &fbdev->drm_fb_helper;
drm_fb_helper_prepare(dev, helper, &exynos_drm_fb_helper_funcs); drm_fb_helper_prepare(dev, helper, PREFERRED_BPP, &exynos_drm_fb_helper_funcs);
ret = drm_fb_helper_init(dev, helper); ret = drm_fb_helper_init(dev, helper);
if (ret < 0) { if (ret < 0) {
...@@ -172,7 +172,7 @@ int exynos_drm_fbdev_init(struct drm_device *dev) ...@@ -172,7 +172,7 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
goto err_init; goto err_init;
} }
ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP); ret = drm_fb_helper_initial_config(helper);
if (ret < 0) { if (ret < 0) {
DRM_DEV_ERROR(dev->dev, DRM_DEV_ERROR(dev->dev,
"failed to set up hw configuration.\n"); "failed to set up hw configuration.\n");
......
...@@ -409,7 +409,7 @@ int psb_fbdev_init(struct drm_device *dev) ...@@ -409,7 +409,7 @@ int psb_fbdev_init(struct drm_device *dev)
dev_priv->fb_helper = fb_helper; dev_priv->fb_helper = fb_helper;
drm_fb_helper_prepare(dev, fb_helper, &psb_fb_helper_funcs); drm_fb_helper_prepare(dev, fb_helper, 32, &psb_fb_helper_funcs);
ret = drm_fb_helper_init(dev, fb_helper); ret = drm_fb_helper_init(dev, fb_helper);
if (ret) if (ret)
...@@ -418,7 +418,7 @@ int psb_fbdev_init(struct drm_device *dev) ...@@ -418,7 +418,7 @@ int psb_fbdev_init(struct drm_device *dev)
/* disable all the possible outputs/crtcs before entering KMS mode */ /* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev); drm_helper_disable_unused_functions(dev);
ret = drm_fb_helper_initial_config(fb_helper, 32); ret = drm_fb_helper_initial_config(fb_helper);
if (ret) if (ret)
goto fini; goto fini;
......
...@@ -520,10 +520,12 @@ int intel_fbdev_init(struct drm_device *dev) ...@@ -520,10 +520,12 @@ int intel_fbdev_init(struct drm_device *dev)
return -ENOMEM; return -ENOMEM;
mutex_init(&ifbdev->hpd_lock); mutex_init(&ifbdev->hpd_lock);
drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs); drm_fb_helper_prepare(dev, &ifbdev->helper, 32, &intel_fb_helper_funcs);
if (!intel_fbdev_init_bios(dev, ifbdev)) if (intel_fbdev_init_bios(dev, ifbdev))
ifbdev->preferred_bpp = 32; ifbdev->helper.preferred_bpp = ifbdev->preferred_bpp;
else
ifbdev->preferred_bpp = ifbdev->helper.preferred_bpp;
ret = drm_fb_helper_init(dev, &ifbdev->helper); ret = drm_fb_helper_init(dev, &ifbdev->helper);
if (ret) { if (ret) {
...@@ -542,8 +544,7 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie) ...@@ -542,8 +544,7 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
struct intel_fbdev *ifbdev = data; struct intel_fbdev *ifbdev = data;
/* Due to peculiar init order wrt to hpd handling this is separate. */ /* Due to peculiar init order wrt to hpd handling this is separate. */
if (drm_fb_helper_initial_config(&ifbdev->helper, if (drm_fb_helper_initial_config(&ifbdev->helper))
ifbdev->preferred_bpp))
intel_fbdev_unregister(to_i915(ifbdev->helper.dev)); intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
} }
......
...@@ -274,8 +274,6 @@ static struct ttm_tt *i915_ttm_tt_create(struct ttm_buffer_object *bo, ...@@ -274,8 +274,6 @@ static struct ttm_tt *i915_ttm_tt_create(struct ttm_buffer_object *bo,
{ {
struct drm_i915_private *i915 = container_of(bo->bdev, typeof(*i915), struct drm_i915_private *i915 = container_of(bo->bdev, typeof(*i915),
bdev); bdev);
struct ttm_resource_manager *man =
ttm_manager_type(bo->bdev, bo->resource->mem_type);
struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo); struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
unsigned long ccs_pages = 0; unsigned long ccs_pages = 0;
enum ttm_caching caching; enum ttm_caching caching;
...@@ -289,8 +287,8 @@ static struct ttm_tt *i915_ttm_tt_create(struct ttm_buffer_object *bo, ...@@ -289,8 +287,8 @@ static struct ttm_tt *i915_ttm_tt_create(struct ttm_buffer_object *bo,
if (!i915_tt) if (!i915_tt)
return NULL; return NULL;
if (obj->flags & I915_BO_ALLOC_CPU_CLEAR && if (obj->flags & I915_BO_ALLOC_CPU_CLEAR && (!bo->resource ||
man->use_tt) ttm_manager_type(bo->bdev, bo->resource->mem_type)->use_tt))
page_flags |= TTM_TT_FLAG_ZERO_ALLOC; page_flags |= TTM_TT_FLAG_ZERO_ALLOC;
caching = i915_ttm_select_tt_caching(obj); caching = i915_ttm_select_tt_caching(obj);
...@@ -1058,7 +1056,26 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf) ...@@ -1058,7 +1056,26 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf)
return VM_FAULT_SIGBUS; return VM_FAULT_SIGBUS;
} }
if (!i915_ttm_resource_mappable(bo->resource)) { /*
* This must be swapped out with shmem ttm_tt (pipeline-gutting).
* Calling ttm_bo_validate() here with TTM_PL_SYSTEM should only go as
* far as far doing a ttm_bo_move_null(), which should skip all the
* other junk.
*/
if (!bo->resource) {
struct ttm_operation_ctx ctx = {
.interruptible = true,
.no_wait_gpu = true, /* should be idle already */
};
GEM_BUG_ON(!bo->ttm || !(bo->ttm->page_flags & TTM_TT_FLAG_SWAPPED));
ret = ttm_bo_validate(bo, i915_ttm_sys_placement(), &ctx);
if (ret) {
dma_resv_unlock(bo->base.resv);
return VM_FAULT_SIGBUS;
}
} else if (!i915_ttm_resource_mappable(bo->resource)) {
int err = -ENODEV; int err = -ENODEV;
int i; int i;
......
...@@ -103,7 +103,27 @@ void i915_ttm_adjust_gem_after_move(struct drm_i915_gem_object *obj) ...@@ -103,7 +103,27 @@ void i915_ttm_adjust_gem_after_move(struct drm_i915_gem_object *obj)
{ {
struct ttm_buffer_object *bo = i915_gem_to_ttm(obj); struct ttm_buffer_object *bo = i915_gem_to_ttm(obj);
unsigned int cache_level; unsigned int cache_level;
unsigned int mem_flags;
unsigned int i; unsigned int i;
int mem_type;
/*
* We might have been purged (or swapped out) if the resource is NULL,
* in which case the SYSTEM placement is the closest match to describe
* the current domain. If the object is ever used in this state then we
* will require moving it again.
*/
if (!bo->resource) {
mem_flags = I915_BO_FLAG_STRUCT_PAGE;
mem_type = I915_PL_SYSTEM;
cache_level = I915_CACHE_NONE;
} else {
mem_flags = i915_ttm_cpu_maps_iomem(bo->resource) ? I915_BO_FLAG_IOMEM :
I915_BO_FLAG_STRUCT_PAGE;
mem_type = bo->resource->mem_type;
cache_level = i915_ttm_cache_level(to_i915(bo->base.dev), bo->resource,
bo->ttm);
}
/* /*
* If object was moved to an allowable region, update the object * If object was moved to an allowable region, update the object
...@@ -111,11 +131,11 @@ void i915_ttm_adjust_gem_after_move(struct drm_i915_gem_object *obj) ...@@ -111,11 +131,11 @@ void i915_ttm_adjust_gem_after_move(struct drm_i915_gem_object *obj)
* in an allowable region, it's evicted and we don't update the * in an allowable region, it's evicted and we don't update the
* object region. * object region.
*/ */
if (intel_region_to_ttm_type(obj->mm.region) != bo->resource->mem_type) { if (intel_region_to_ttm_type(obj->mm.region) != mem_type) {
for (i = 0; i < obj->mm.n_placements; ++i) { for (i = 0; i < obj->mm.n_placements; ++i) {
struct intel_memory_region *mr = obj->mm.placements[i]; struct intel_memory_region *mr = obj->mm.placements[i];
if (intel_region_to_ttm_type(mr) == bo->resource->mem_type && if (intel_region_to_ttm_type(mr) == mem_type &&
mr != obj->mm.region) { mr != obj->mm.region) {
i915_gem_object_release_memory_region(obj); i915_gem_object_release_memory_region(obj);
i915_gem_object_init_memory_region(obj, mr); i915_gem_object_init_memory_region(obj, mr);
...@@ -125,12 +145,8 @@ void i915_ttm_adjust_gem_after_move(struct drm_i915_gem_object *obj) ...@@ -125,12 +145,8 @@ void i915_ttm_adjust_gem_after_move(struct drm_i915_gem_object *obj)
} }
obj->mem_flags &= ~(I915_BO_FLAG_STRUCT_PAGE | I915_BO_FLAG_IOMEM); obj->mem_flags &= ~(I915_BO_FLAG_STRUCT_PAGE | I915_BO_FLAG_IOMEM);
obj->mem_flags |= mem_flags;
obj->mem_flags |= i915_ttm_cpu_maps_iomem(bo->resource) ? I915_BO_FLAG_IOMEM :
I915_BO_FLAG_STRUCT_PAGE;
cache_level = i915_ttm_cache_level(to_i915(bo->base.dev), bo->resource,
bo->ttm);
i915_gem_object_set_cache_coherency(obj, cache_level); i915_gem_object_set_cache_coherency(obj, cache_level);
} }
...@@ -565,6 +581,32 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict, ...@@ -565,6 +581,32 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict,
return 0; return 0;
} }
if (!bo->resource) {
if (dst_mem->mem_type != TTM_PL_SYSTEM) {
hop->mem_type = TTM_PL_SYSTEM;
hop->flags = TTM_PL_FLAG_TEMPORARY;
return -EMULTIHOP;
}
/*
* This is only reached when first creating the object, or if
* the object was purged or swapped out (pipeline-gutting). For
* the former we can safely skip all of the below since we are
* only using a dummy SYSTEM placement here. And with the latter
* we will always re-enter here with bo->resource set correctly
* (as per the above), since this is part of a multi-hop
* sequence, where at the end we can do the move for real.
*
* The special case here is when the dst_mem is TTM_PL_SYSTEM,
* which doens't require any kind of move, so it should be safe
* to skip all the below and call ttm_bo_move_null() here, where
* the caller in __i915_ttm_get_pages() will take care of the
* rest, since we should have a valid ttm_tt.
*/
ttm_bo_move_null(bo, dst_mem);
return 0;
}
ret = i915_ttm_move_notify(bo); ret = i915_ttm_move_notify(bo);
if (ret) if (ret)
return ret; return ret;
......
...@@ -146,7 +146,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev) ...@@ -146,7 +146,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
helper = &fbdev->base; helper = &fbdev->base;
drm_fb_helper_prepare(dev, helper, &msm_fb_helper_funcs); drm_fb_helper_prepare(dev, helper, 32, &msm_fb_helper_funcs);
ret = drm_fb_helper_init(dev, helper); ret = drm_fb_helper_init(dev, helper);
if (ret) { if (ret) {
...@@ -159,7 +159,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev) ...@@ -159,7 +159,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
if (ret) if (ret)
goto fini; goto fini;
ret = drm_fb_helper_initial_config(helper, 32); ret = drm_fb_helper_initial_config(helper);
if (ret) if (ret)
goto fini; goto fini;
......
...@@ -51,7 +51,8 @@ u64 ...@@ -51,7 +51,8 @@ u64
nvkm_devinit_disable(struct nvkm_devinit *init) nvkm_devinit_disable(struct nvkm_devinit *init)
{ {
if (init && init->func->disable) if (init && init->func->disable)
return init->func->disable(init); init->func->disable(init);
return 0; return 0;
} }
......
...@@ -26,13 +26,12 @@ ...@@ -26,13 +26,12 @@
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/init.h> #include <subdev/bios/init.h>
static u64 static void
g84_devinit_disable(struct nvkm_devinit *init) g84_devinit_disable(struct nvkm_devinit *init)
{ {
struct nvkm_device *device = init->subdev.device; struct nvkm_device *device = init->subdev.device;
u32 r001540 = nvkm_rd32(device, 0x001540); u32 r001540 = nvkm_rd32(device, 0x001540);
u32 r00154c = nvkm_rd32(device, 0x00154c); u32 r00154c = nvkm_rd32(device, 0x00154c);
u64 disable = 0ULL;
if (!(r001540 & 0x40000000)) { if (!(r001540 & 0x40000000)) {
nvkm_subdev_disable(device, NVKM_ENGINE_MPEG, 0); nvkm_subdev_disable(device, NVKM_ENGINE_MPEG, 0);
...@@ -47,8 +46,6 @@ g84_devinit_disable(struct nvkm_devinit *init) ...@@ -47,8 +46,6 @@ g84_devinit_disable(struct nvkm_devinit *init)
nvkm_subdev_disable(device, NVKM_ENGINE_BSP, 0); nvkm_subdev_disable(device, NVKM_ENGINE_BSP, 0);
if (!(r00154c & 0x00000040)) if (!(r00154c & 0x00000040))
nvkm_subdev_disable(device, NVKM_ENGINE_CIPHER, 0); nvkm_subdev_disable(device, NVKM_ENGINE_CIPHER, 0);
return disable;
} }
static const struct nvkm_devinit_func static const struct nvkm_devinit_func
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/init.h> #include <subdev/bios/init.h>
static u64 static void
g98_devinit_disable(struct nvkm_devinit *init) g98_devinit_disable(struct nvkm_devinit *init)
{ {
struct nvkm_device *device = init->subdev.device; struct nvkm_device *device = init->subdev.device;
...@@ -45,8 +45,6 @@ g98_devinit_disable(struct nvkm_devinit *init) ...@@ -45,8 +45,6 @@ g98_devinit_disable(struct nvkm_devinit *init)
nvkm_subdev_disable(device, NVKM_ENGINE_MSVLD, 0); nvkm_subdev_disable(device, NVKM_ENGINE_MSVLD, 0);
if (!(r00154c & 0x00000040)) if (!(r00154c & 0x00000040))
nvkm_subdev_disable(device, NVKM_ENGINE_SEC, 0); nvkm_subdev_disable(device, NVKM_ENGINE_SEC, 0);
return 0ULL;
} }
static const struct nvkm_devinit_func static const struct nvkm_devinit_func
......
...@@ -63,7 +63,7 @@ gf100_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) ...@@ -63,7 +63,7 @@ gf100_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq)
return ret; return ret;
} }
static u64 static void
gf100_devinit_disable(struct nvkm_devinit *init) gf100_devinit_disable(struct nvkm_devinit *init)
{ {
struct nvkm_device *device = init->subdev.device; struct nvkm_device *device = init->subdev.device;
...@@ -85,8 +85,6 @@ gf100_devinit_disable(struct nvkm_devinit *init) ...@@ -85,8 +85,6 @@ gf100_devinit_disable(struct nvkm_devinit *init)
nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0); nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0);
if (r022500 & 0x00000200) if (r022500 & 0x00000200)
nvkm_subdev_disable(device, NVKM_ENGINE_CE, 1); nvkm_subdev_disable(device, NVKM_ENGINE_CE, 1);
return 0ULL;
} }
void void
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/init.h> #include <subdev/bios/init.h>
u64 void
gm107_devinit_disable(struct nvkm_devinit *init) gm107_devinit_disable(struct nvkm_devinit *init)
{ {
struct nvkm_device *device = init->subdev.device; struct nvkm_device *device = init->subdev.device;
...@@ -39,8 +39,6 @@ gm107_devinit_disable(struct nvkm_devinit *init) ...@@ -39,8 +39,6 @@ gm107_devinit_disable(struct nvkm_devinit *init)
nvkm_subdev_disable(device, NVKM_ENGINE_CE, 2); nvkm_subdev_disable(device, NVKM_ENGINE_CE, 2);
if (r021c04 & 0x00000001) if (r021c04 & 0x00000001)
nvkm_subdev_disable(device, NVKM_ENGINE_DISP, 0); nvkm_subdev_disable(device, NVKM_ENGINE_DISP, 0);
return 0ULL;
} }
static const struct nvkm_devinit_func static const struct nvkm_devinit_func
......
...@@ -62,7 +62,7 @@ gt215_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) ...@@ -62,7 +62,7 @@ gt215_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq)
return ret; return ret;
} }
static u64 static void
gt215_devinit_disable(struct nvkm_devinit *init) gt215_devinit_disable(struct nvkm_devinit *init)
{ {
struct nvkm_device *device = init->subdev.device; struct nvkm_device *device = init->subdev.device;
...@@ -80,8 +80,6 @@ gt215_devinit_disable(struct nvkm_devinit *init) ...@@ -80,8 +80,6 @@ gt215_devinit_disable(struct nvkm_devinit *init)
nvkm_subdev_disable(device, NVKM_ENGINE_MSVLD, 0); nvkm_subdev_disable(device, NVKM_ENGINE_MSVLD, 0);
if (!(r00154c & 0x00000200)) if (!(r00154c & 0x00000200))
nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0); nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0);
return 0ULL;
} }
static u32 static u32
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/init.h> #include <subdev/bios/init.h>
static u64 static void
mcp89_devinit_disable(struct nvkm_devinit *init) mcp89_devinit_disable(struct nvkm_devinit *init)
{ {
struct nvkm_device *device = init->subdev.device; struct nvkm_device *device = init->subdev.device;
...@@ -46,8 +46,6 @@ mcp89_devinit_disable(struct nvkm_devinit *init) ...@@ -46,8 +46,6 @@ mcp89_devinit_disable(struct nvkm_devinit *init)
nvkm_subdev_disable(device, NVKM_ENGINE_VIC, 0); nvkm_subdev_disable(device, NVKM_ENGINE_VIC, 0);
if (!(r00154c & 0x00000200)) if (!(r00154c & 0x00000200))
nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0); nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0);
return 0;
} }
static const struct nvkm_devinit_func static const struct nvkm_devinit_func
......
...@@ -77,17 +77,14 @@ nv50_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) ...@@ -77,17 +77,14 @@ nv50_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq)
return 0; return 0;
} }
static u64 static void
nv50_devinit_disable(struct nvkm_devinit *init) nv50_devinit_disable(struct nvkm_devinit *init)
{ {
struct nvkm_device *device = init->subdev.device; struct nvkm_device *device = init->subdev.device;
u32 r001540 = nvkm_rd32(device, 0x001540); u32 r001540 = nvkm_rd32(device, 0x001540);
u64 disable = 0ULL;
if (!(r001540 & 0x40000000)) if (!(r001540 & 0x40000000))
nvkm_subdev_disable(device, NVKM_ENGINE_MPEG, 0); nvkm_subdev_disable(device, NVKM_ENGINE_MPEG, 0);
return disable;
} }
void void
......
...@@ -23,7 +23,7 @@ int gf100_devinit_ctor(struct nvkm_object *, struct nvkm_object *, ...@@ -23,7 +23,7 @@ int gf100_devinit_ctor(struct nvkm_object *, struct nvkm_object *,
int gf100_devinit_pll_set(struct nvkm_devinit *, u32, u32); int gf100_devinit_pll_set(struct nvkm_devinit *, u32, u32);
void gf100_devinit_preinit(struct nvkm_devinit *); void gf100_devinit_preinit(struct nvkm_devinit *);
u64 gm107_devinit_disable(struct nvkm_devinit *); void gm107_devinit_disable(struct nvkm_devinit *);
int gm200_devinit_post(struct nvkm_devinit *, bool); int gm200_devinit_post(struct nvkm_devinit *, bool);
void gm200_devinit_preos(struct nv50_devinit *, bool); void gm200_devinit_preos(struct nv50_devinit *, bool);
......
...@@ -12,7 +12,7 @@ struct nvkm_devinit_func { ...@@ -12,7 +12,7 @@ struct nvkm_devinit_func {
u32 (*mmio)(struct nvkm_devinit *, u32); u32 (*mmio)(struct nvkm_devinit *, u32);
void (*meminit)(struct nvkm_devinit *); void (*meminit)(struct nvkm_devinit *);
int (*pll_set)(struct nvkm_devinit *, u32 type, u32 freq); int (*pll_set)(struct nvkm_devinit *, u32 type, u32 freq);
u64 (*disable)(struct nvkm_devinit *); void (*disable)(struct nvkm_devinit *);
}; };
void nvkm_devinit_ctor(const struct nvkm_devinit_func *, struct nvkm_device *, void nvkm_devinit_ctor(const struct nvkm_devinit_func *, struct nvkm_device *,
......
...@@ -239,13 +239,13 @@ void omap_fbdev_init(struct drm_device *dev) ...@@ -239,13 +239,13 @@ void omap_fbdev_init(struct drm_device *dev)
helper = &fbdev->base; helper = &fbdev->base;
drm_fb_helper_prepare(dev, helper, &omap_fb_helper_funcs); drm_fb_helper_prepare(dev, helper, 32, &omap_fb_helper_funcs);
ret = drm_fb_helper_init(dev, helper); ret = drm_fb_helper_init(dev, helper);
if (ret) if (ret)
goto fail; goto fail;
ret = drm_fb_helper_initial_config(helper, 32); ret = drm_fb_helper_initial_config(helper);
if (ret) if (ret)
goto fini; goto fini;
......
...@@ -348,7 +348,7 @@ int radeon_fbdev_init(struct radeon_device *rdev) ...@@ -348,7 +348,7 @@ int radeon_fbdev_init(struct radeon_device *rdev)
rfbdev->rdev = rdev; rfbdev->rdev = rdev;
rdev->mode_info.rfbdev = rfbdev; rdev->mode_info.rfbdev = rfbdev;
drm_fb_helper_prepare(rdev->ddev, &rfbdev->helper, drm_fb_helper_prepare(rdev->ddev, &rfbdev->helper, bpp_sel,
&radeon_fb_helper_funcs); &radeon_fb_helper_funcs);
ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper); ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper);
...@@ -358,7 +358,7 @@ int radeon_fbdev_init(struct radeon_device *rdev) ...@@ -358,7 +358,7 @@ int radeon_fbdev_init(struct radeon_device *rdev)
/* disable all the possible outputs/crtcs before entering KMS mode */ /* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(rdev->ddev); drm_helper_disable_unused_functions(rdev->ddev);
ret = drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); ret = drm_fb_helper_initial_config(&rfbdev->helper);
if (ret) if (ret)
goto fini; goto fini;
......
...@@ -308,7 +308,7 @@ static struct tegra_fbdev *tegra_fbdev_create(struct drm_device *drm) ...@@ -308,7 +308,7 @@ static struct tegra_fbdev *tegra_fbdev_create(struct drm_device *drm)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
drm_fb_helper_prepare(drm, &fbdev->base, &tegra_fb_helper_funcs); drm_fb_helper_prepare(drm, &fbdev->base, 32, &tegra_fb_helper_funcs);
return fbdev; return fbdev;
} }
...@@ -319,7 +319,6 @@ static void tegra_fbdev_free(struct tegra_fbdev *fbdev) ...@@ -319,7 +319,6 @@ static void tegra_fbdev_free(struct tegra_fbdev *fbdev)
} }
static int tegra_fbdev_init(struct tegra_fbdev *fbdev, static int tegra_fbdev_init(struct tegra_fbdev *fbdev,
unsigned int preferred_bpp,
unsigned int num_crtc, unsigned int num_crtc,
unsigned int max_connectors) unsigned int max_connectors)
{ {
...@@ -333,7 +332,7 @@ static int tegra_fbdev_init(struct tegra_fbdev *fbdev, ...@@ -333,7 +332,7 @@ static int tegra_fbdev_init(struct tegra_fbdev *fbdev,
return err; return err;
} }
err = drm_fb_helper_initial_config(&fbdev->base, preferred_bpp); err = drm_fb_helper_initial_config(&fbdev->base);
if (err < 0) { if (err < 0) {
dev_err(drm->dev, "failed to set initial configuration: %d\n", dev_err(drm->dev, "failed to set initial configuration: %d\n",
err); err);
...@@ -396,7 +395,7 @@ int tegra_drm_fb_init(struct drm_device *drm) ...@@ -396,7 +395,7 @@ int tegra_drm_fb_init(struct drm_device *drm)
struct tegra_drm *tegra = drm->dev_private; struct tegra_drm *tegra = drm->dev_private;
int err; int err;
err = tegra_fbdev_init(tegra->fbdev, 32, drm->mode_config.num_crtc, err = tegra_fbdev_init(tegra->fbdev, drm->mode_config.num_crtc,
drm->mode_config.num_connector); drm->mode_config.num_connector);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -106,6 +106,14 @@ struct drm_client_dev { ...@@ -106,6 +106,14 @@ struct drm_client_dev {
* @modesets: CRTC configurations * @modesets: CRTC configurations
*/ */
struct drm_mode_set *modesets; struct drm_mode_set *modesets;
/**
* @hotplug failed:
*
* Set by client hotplug helpers if the hotplugging failed
* before. It is usually not tried again.
*/
bool hotplug_failed;
}; };
int drm_client_init(struct drm_device *dev, struct drm_client_dev *client, int drm_client_init(struct drm_device *dev, struct drm_client_dev *client,
......
...@@ -229,7 +229,9 @@ drm_fb_helper_from_client(struct drm_client_dev *client) ...@@ -229,7 +229,9 @@ drm_fb_helper_from_client(struct drm_client_dev *client)
#ifdef CONFIG_DRM_FBDEV_EMULATION #ifdef CONFIG_DRM_FBDEV_EMULATION
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
unsigned int preferred_bpp,
const struct drm_fb_helper_funcs *funcs); const struct drm_fb_helper_funcs *funcs);
void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper);
int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *helper); int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *helper);
void drm_fb_helper_fini(struct drm_fb_helper *helper); void drm_fb_helper_fini(struct drm_fb_helper *helper);
int drm_fb_helper_blank(int blank, struct fb_info *info); int drm_fb_helper_blank(int blank, struct fb_info *info);
...@@ -283,7 +285,7 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, ...@@ -283,7 +285,7 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg); unsigned long arg);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel); int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper);
int drm_fb_helper_debug_enter(struct fb_info *info); int drm_fb_helper_debug_enter(struct fb_info *info);
int drm_fb_helper_debug_leave(struct fb_info *info); int drm_fb_helper_debug_leave(struct fb_info *info);
...@@ -291,8 +293,13 @@ void drm_fb_helper_lastclose(struct drm_device *dev); ...@@ -291,8 +293,13 @@ void drm_fb_helper_lastclose(struct drm_device *dev);
void drm_fb_helper_output_poll_changed(struct drm_device *dev); void drm_fb_helper_output_poll_changed(struct drm_device *dev);
#else #else
static inline void drm_fb_helper_prepare(struct drm_device *dev, static inline void drm_fb_helper_prepare(struct drm_device *dev,
struct drm_fb_helper *helper, struct drm_fb_helper *helper,
const struct drm_fb_helper_funcs *funcs) unsigned int preferred_bpp,
const struct drm_fb_helper_funcs *funcs)
{
}
static inline void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper)
{ {
} }
...@@ -450,8 +457,7 @@ static inline int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) ...@@ -450,8 +457,7 @@ static inline int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
return 0; return 0;
} }
static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)
int bpp_sel)
{ {
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment