Merge tag 'topic/drm-misc-2015-08-13' of git://anongit.freedesktop.org/drm-intel into drm-next

Final drm-misc pull for 4.3:
- fbdev emulation Kconfig option for everyone thanks to Archit. It's not
  everything yet bit this is fairly tricky since it spawns all drivers.
- vgaarb & vgaswitcheroo polish from Thierry
- some drm_irq.c cleanups (Thierry)
- struct_mutex crusade from me
- more fbdev panic handling removal
- various things all over in drm core&helpers

* tag 'topic/drm-misc-2015-08-13' of git://anongit.freedesktop.org/drm-intel: (65 commits)
  drm/atomic: Use KMS VBLANK API
  drm/irq: Document return values more consistently
  drm/irq: Make pipe unsigned and name consistent
  drm/irq: Check for valid VBLANK before dereference
  drm/irq: Remove negative CRTC index special-case
  drm/plane: Remove redundant extern
  drm/plane: Use consistent data types for format count
  vga_switcheroo: Remove unnecessary checks
  vga_switcheroo: Wrap overly long lines
  vga_switcheroo: Use pr_fmt()
  vga_switcheroo: Cleanup header comment
  vga_switcheroo: Use pr_*() instead of printk()
  vgaarb: Fix a few checkpatch errors and warnings
  vgaarb: Use vgaarb: prefix consistently in messages
  vgaarb: Stop complaining about absent devices
  drm/atomic: fix null pointer access to mode_fixup callback
  drm/i915: Use CONFIG_DRM_FBDEV_EMULATION
  drm/core: Set mode to NULL when connectors in a set drops to 0.
  drm/atomic: Call ww_acquire_done after check phase is complete
  drm/atomic: Paper over locking WARN in default_state_clear
  ...
This commit is contained in:
Dave Airlie
2015-08-14 10:02:21 +10:00
61 changed files with 1163 additions and 1107 deletions
+20
View File
@@ -37,9 +37,29 @@ config DRM_KMS_FB_HELPER
select FB
select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
select FB_SYS_FOPS
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
help
FBDEV helpers for KMS drivers.
config DRM_FBDEV_EMULATION
bool "Enable legacy fbdev support for your modesetting driver"
depends on DRM
select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER
default y
help
Choose this option if you have a need for the legacy fbdev
support. Note that this support also provides the linux console
support on top of your modesetting driver.
If in doubt, say "Y".
config DRM_LOAD_EDID_FIRMWARE
bool "Allow to specify an EDID data set instead of probing for it"
depends on DRM_KMS_HELPER
+1 -1
View File
@@ -23,7 +23,7 @@ drm-$(CONFIG_OF) += drm_of.o
drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
+14 -31
View File
@@ -53,9 +53,9 @@ static struct fb_ops amdgpufb_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_fillrect = drm_fb_helper_cfb_fillrect,
.fb_copyarea = drm_fb_helper_cfb_copyarea,
.fb_imageblit = drm_fb_helper_cfb_imageblit,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
@@ -179,7 +179,6 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
struct drm_mode_fb_cmd2 mode_cmd;
struct drm_gem_object *gobj = NULL;
struct amdgpu_bo *rbo = NULL;
struct device *device = &adev->pdev->dev;
int ret;
unsigned long tmp;
@@ -201,9 +200,9 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
rbo = gem_to_amdgpu_bo(gobj);
/* okay we have an object now allocate the framebuffer */
info = framebuffer_alloc(0, device);
if (info == NULL) {
ret = -ENOMEM;
info = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(info)) {
ret = PTR_ERR(info);
goto out_unref;
}
@@ -212,14 +211,13 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
ret = amdgpu_framebuffer_init(adev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
if (ret) {
DRM_ERROR("failed to initialize framebuffer %d\n", ret);
goto out_unref;
goto out_destroy_fbi;
}
fb = &rfbdev->rfb.base;
/* setup helper */
rfbdev->helper.fb = fb;
rfbdev->helper.fbdev = info;
memset_io(rbo->kptr, 0x0, amdgpu_bo_size(rbo));
@@ -239,11 +237,6 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
/* setup aperture base/size for vesafb takeover */
info->apertures = alloc_apertures(1);
if (!info->apertures) {
ret = -ENOMEM;
goto out_unref;
}
info->apertures->ranges[0].base = adev->ddev->mode_config.fb_base;
info->apertures->ranges[0].size = adev->mc.aper_size;
@@ -251,13 +244,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
if (info->screen_base == NULL) {
ret = -ENOSPC;
goto out_unref;
}
ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret) {
ret = -ENOMEM;
goto out_unref;
goto out_destroy_fbi;
}
DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start);
@@ -269,6 +256,8 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
vga_switcheroo_client_fb_set(adev->ddev->pdev, info);
return 0;
out_destroy_fbi:
drm_fb_helper_release_fbi(helper);
out_unref:
if (rbo) {
@@ -290,17 +279,10 @@ void amdgpu_fb_output_poll_changed(struct amdgpu_device *adev)
static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfbdev)
{
struct fb_info *info;
struct amdgpu_framebuffer *rfb = &rfbdev->rfb;
if (rfbdev->helper.fbdev) {
info = rfbdev->helper.fbdev;
unregister_framebuffer(info);
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
drm_fb_helper_unregister_fbi(&rfbdev->helper);
drm_fb_helper_release_fbi(&rfbdev->helper);
if (rfb->obj) {
amdgpufb_destroy_pinned_object(rfb->obj);
@@ -395,7 +377,8 @@ void amdgpu_fbdev_fini(struct amdgpu_device *adev)
void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state)
{
if (adev->mode_info.rfbdev)
fb_set_suspend(adev->mode_info.rfbdev->helper.fbdev, state);
drm_fb_helper_set_suspend(&adev->mode_info.rfbdev->helper,
state);
}
int amdgpu_fbdev_total_size(struct amdgpu_device *adev)
+10 -23
View File
@@ -22,9 +22,9 @@ static /*const*/ struct fb_ops armada_fb_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_fillrect = drm_fb_helper_cfb_fillrect,
.fb_copyarea = drm_fb_helper_cfb_copyarea,
.fb_imageblit = drm_fb_helper_cfb_imageblit,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
@@ -80,18 +80,12 @@ static int armada_fb_create(struct drm_fb_helper *fbh,
if (IS_ERR(dfb))
return PTR_ERR(dfb);
info = framebuffer_alloc(0, dev->dev);
if (!info) {
ret = -ENOMEM;
info = drm_fb_helper_alloc_fbi(fbh);
if (IS_ERR(info)) {
ret = PTR_ERR(info);
goto err_fballoc;
}
ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret) {
ret = -ENOMEM;
goto err_fbcmap;
}
strlcpy(info->fix.id, "armada-drmfb", sizeof(info->fix.id));
info->par = fbh;
info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
@@ -101,7 +95,7 @@ static int armada_fb_create(struct drm_fb_helper *fbh,
info->screen_size = obj->obj.size;
info->screen_base = ptr;
fbh->fb = &dfb->fb;
fbh->fbdev = info;
drm_fb_helper_fill_fix(info, dfb->fb.pitches[0], dfb->fb.depth);
drm_fb_helper_fill_var(info, fbh, sizes->fb_width, sizes->fb_height);
@@ -111,8 +105,6 @@ static int armada_fb_create(struct drm_fb_helper *fbh,
return 0;
err_fbcmap:
framebuffer_release(info);
err_fballoc:
dfb->fb.funcs->destroy(&dfb->fb);
return ret;
@@ -171,6 +163,7 @@ int armada_fbdev_init(struct drm_device *dev)
return 0;
err_fb_setup:
drm_fb_helper_release_fbi(fbh);
drm_fb_helper_fini(fbh);
err_fb_helper:
priv->fbdev = NULL;
@@ -191,14 +184,8 @@ void armada_fbdev_fini(struct drm_device *dev)
struct drm_fb_helper *fbh = priv->fbdev;
if (fbh) {
struct fb_info *info = fbh->fbdev;
if (info) {
unregister_framebuffer(info);
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
drm_fb_helper_unregister_fbi(fbh);
drm_fb_helper_release_fbi(fbh);
drm_fb_helper_fini(fbh);
+17 -31
View File
@@ -125,7 +125,7 @@ static void ast_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
{
struct ast_fbdev *afbdev = info->par;
sys_fillrect(info, rect);
drm_fb_helper_sys_fillrect(info, rect);
ast_dirty_update(afbdev, rect->dx, rect->dy, rect->width,
rect->height);
}
@@ -134,7 +134,7 @@ static void ast_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
struct ast_fbdev *afbdev = info->par;
sys_copyarea(info, area);
drm_fb_helper_sys_copyarea(info, area);
ast_dirty_update(afbdev, area->dx, area->dy, area->width,
area->height);
}
@@ -143,7 +143,7 @@ static void ast_imageblit(struct fb_info *info,
const struct fb_image *image)
{
struct ast_fbdev *afbdev = info->par;
sys_imageblit(info, image);
drm_fb_helper_sys_imageblit(info, image);
ast_dirty_update(afbdev, image->dx, image->dy, image->width,
image->height);
}
@@ -193,7 +193,6 @@ static int astfb_create(struct drm_fb_helper *helper,
struct drm_framebuffer *fb;
struct fb_info *info;
int size, ret;
struct device *device = &dev->pdev->dev;
void *sysram;
struct drm_gem_object *gobj = NULL;
struct ast_bo *bo = NULL;
@@ -217,40 +216,28 @@ static int astfb_create(struct drm_fb_helper *helper,
if (!sysram)
return -ENOMEM;
info = framebuffer_alloc(0, device);
if (!info) {
ret = -ENOMEM;
goto out;
info = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(info)) {
ret = PTR_ERR(info);
goto err_free_vram;
}
info->par = afbdev;
ret = ast_framebuffer_init(dev, &afbdev->afb, &mode_cmd, gobj);
if (ret)
goto out;
goto err_release_fbi;
afbdev->sysram = sysram;
afbdev->size = size;
fb = &afbdev->afb.base;
afbdev->helper.fb = fb;
afbdev->helper.fbdev = info;
strcpy(info->fix.id, "astdrmfb");
info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &astfb_ops;
ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret) {
ret = -ENOMEM;
goto out;
}
info->apertures = alloc_apertures(1);
if (!info->apertures) {
ret = -ENOMEM;
goto out;
}
info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0);
info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0);
@@ -266,7 +253,11 @@ static int astfb_create(struct drm_fb_helper *helper,
fb->width, fb->height);
return 0;
out:
err_release_fbi:
drm_fb_helper_release_fbi(helper);
err_free_vram:
vfree(afbdev->sysram);
return ret;
}
@@ -297,15 +288,10 @@ static const struct drm_fb_helper_funcs ast_fb_helper_funcs = {
static void ast_fbdev_destroy(struct drm_device *dev,
struct ast_fbdev *afbdev)
{
struct fb_info *info;
struct ast_framebuffer *afb = &afbdev->afb;
if (afbdev->helper.fbdev) {
info = afbdev->helper.fbdev;
unregister_framebuffer(info);
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
drm_fb_helper_unregister_fbi(&afbdev->helper);
drm_fb_helper_release_fbi(&afbdev->helper);
if (afb->obj) {
drm_gem_object_unreference_unlocked(afb->obj);
@@ -377,5 +363,5 @@ void ast_fbdev_set_suspend(struct drm_device *dev, int state)
if (!ast->fbdev)
return;
fb_set_suspend(ast->fbdev->helper.fbdev, state);
drm_fb_helper_set_suspend(&ast->fbdev->helper, state);
}
+5 -11
View File
@@ -571,24 +571,18 @@ ast_dumb_mmap_offset(struct drm_file *file,
uint64_t *offset)
{
struct drm_gem_object *obj;
int ret;
struct ast_bo *bo;
mutex_lock(&dev->struct_mutex);
obj = drm_gem_object_lookup(dev, file, handle);
if (obj == NULL) {
ret = -ENOENT;
goto out_unlock;
}
if (obj == NULL)
return -ENOENT;
bo = gem_to_ast_bo(obj);
*offset = ast_bo_mmap_offset(bo);
drm_gem_object_unreference(obj);
ret = 0;
out_unlock:
mutex_unlock(&dev->struct_mutex);
return ret;
drm_gem_object_unreference_unlocked(obj);
return 0;
}
+2 -2
View File
@@ -109,7 +109,7 @@ static int bochs_pm_suspend(struct device *dev)
if (bochs->fb.initialized) {
console_lock();
fb_set_suspend(bochs->fb.helper.fbdev, 1);
drm_fb_helper_set_suspend(&bochs->fb.helper, 1);
console_unlock();
}
@@ -126,7 +126,7 @@ static int bochs_pm_resume(struct device *dev)
if (bochs->fb.initialized) {
console_lock();
fb_set_suspend(bochs->fb.helper.fbdev, 0);
drm_fb_helper_set_suspend(&bochs->fb.helper, 0);
console_unlock();
}
+11 -25
View File
@@ -24,9 +24,9 @@ static struct fb_ops bochsfb_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_fillrect = sys_fillrect,
.fb_copyarea = sys_copyarea,
.fb_imageblit = sys_imageblit,
.fb_fillrect = drm_fb_helper_sys_fillrect,
.fb_copyarea = drm_fb_helper_sys_copyarea,
.fb_imageblit = drm_fb_helper_sys_imageblit,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
@@ -56,11 +56,9 @@ static int bochsfb_create(struct drm_fb_helper *helper,
{
struct bochs_device *bochs =
container_of(helper, struct bochs_device, fb.helper);
struct drm_device *dev = bochs->dev;
struct fb_info *info;
struct drm_framebuffer *fb;
struct drm_mode_fb_cmd2 mode_cmd;
struct device *device = &dev->pdev->dev;
struct drm_gem_object *gobj = NULL;
struct bochs_bo *bo = NULL;
int size, ret;
@@ -106,22 +104,23 @@ static int bochsfb_create(struct drm_fb_helper *helper,
ttm_bo_unreserve(&bo->bo);
/* init fb device */
info = framebuffer_alloc(0, device);
if (info == NULL)
return -ENOMEM;
info = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(info))
return PTR_ERR(info);
info->par = &bochs->fb.helper;
ret = bochs_framebuffer_init(bochs->dev, &bochs->fb.gfb, &mode_cmd, gobj);
if (ret)
if (ret) {
drm_fb_helper_release_fbi(helper);
return ret;
}
bochs->fb.size = size;
/* setup helper */
fb = &bochs->fb.gfb.base;
bochs->fb.helper.fb = fb;
bochs->fb.helper.fbdev = info;
strcpy(info->fix.id, "bochsdrmfb");
@@ -139,30 +138,17 @@ static int bochsfb_create(struct drm_fb_helper *helper,
info->fix.smem_start = 0;
info->fix.smem_len = size;
ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret) {
DRM_ERROR("%s: can't allocate color map\n", info->fix.id);
return -ENOMEM;
}
return 0;
}
static int bochs_fbdev_destroy(struct bochs_device *bochs)
{
struct bochs_framebuffer *gfb = &bochs->fb.gfb;
struct fb_info *info;
DRM_DEBUG_DRIVER("\n");
if (bochs->fb.helper.fbdev) {
info = bochs->fb.helper.fbdev;
unregister_framebuffer(info);
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
drm_fb_helper_unregister_fbi(&bochs->fb.helper);
drm_fb_helper_release_fbi(&bochs->fb.helper);
if (gfb->obj) {
drm_gem_object_unreference_unlocked(gfb->obj);
+4 -12
View File
@@ -454,25 +454,17 @@ int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
uint32_t handle, uint64_t *offset)
{
struct drm_gem_object *obj;
int ret;
struct bochs_bo *bo;
mutex_lock(&dev->struct_mutex);
obj = drm_gem_object_lookup(dev, file, handle);
if (obj == NULL) {
ret = -ENOENT;
goto out_unlock;
}
if (obj == NULL)
return -ENOENT;
bo = gem_to_bochs_bo(obj);
*offset = bochs_bo_mmap_offset(bo);
drm_gem_object_unreference(obj);
ret = 0;
out_unlock:
mutex_unlock(&dev->struct_mutex);
return ret;
drm_gem_object_unreference_unlocked(obj);
return 0;
}
/* ---------------------------------------------------------------------- */
+2 -2
View File
@@ -92,7 +92,7 @@ static int cirrus_pm_suspend(struct device *dev)
if (cdev->mode_info.gfbdev) {
console_lock();
fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 1);
drm_fb_helper_set_suspend(&cdev->mode_info.gfbdev->helper, 1);
console_unlock();
}
@@ -109,7 +109,7 @@ static int cirrus_pm_resume(struct device *dev)
if (cdev->mode_info.gfbdev) {
console_lock();
fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0);
drm_fb_helper_set_suspend(&cdev->mode_info.gfbdev->helper, 0);
console_unlock();
}
+8 -33
View File
@@ -98,7 +98,7 @@ static void cirrus_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
{
struct cirrus_fbdev *afbdev = info->par;
sys_fillrect(info, rect);
drm_fb_helper_sys_fillrect(info, rect);
cirrus_dirty_update(afbdev, rect->dx, rect->dy, rect->width,
rect->height);
}
@@ -107,7 +107,7 @@ static void cirrus_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
struct cirrus_fbdev *afbdev = info->par;
sys_copyarea(info, area);
drm_fb_helper_sys_copyarea(info, area);
cirrus_dirty_update(afbdev, area->dx, area->dy, area->width,
area->height);
}
@@ -116,7 +116,7 @@ static void cirrus_imageblit(struct fb_info *info,
const struct fb_image *image)
{
struct cirrus_fbdev *afbdev = info->par;
sys_imageblit(info, image);
drm_fb_helper_sys_imageblit(info, image);
cirrus_dirty_update(afbdev, image->dx, image->dy, image->width,
image->height);
}
@@ -165,12 +165,10 @@ static int cirrusfb_create(struct drm_fb_helper *helper,
{
struct cirrus_fbdev *gfbdev =
container_of(helper, struct cirrus_fbdev, helper);
struct drm_device *dev = gfbdev->helper.dev;
struct cirrus_device *cdev = gfbdev->helper.dev->dev_private;
struct fb_info *info;
struct drm_framebuffer *fb;
struct drm_mode_fb_cmd2 mode_cmd;
struct device *device = &dev->pdev->dev;
void *sysram;
struct drm_gem_object *gobj = NULL;
struct cirrus_bo *bo = NULL;
@@ -195,9 +193,9 @@ static int cirrusfb_create(struct drm_fb_helper *helper,
if (!sysram)
return -ENOMEM;
info = framebuffer_alloc(0, device);
if (info == NULL)
return -ENOMEM;
info = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(info))
return PTR_ERR(info);
info->par = gfbdev;
@@ -216,11 +214,9 @@ static int cirrusfb_create(struct drm_fb_helper *helper,
/* setup helper */
gfbdev->helper.fb = fb;
gfbdev->helper.fbdev = info;
strcpy(info->fix.id, "cirrusdrmfb");
info->flags = FBINFO_DEFAULT;
info->fbops = &cirrusfb_ops;
@@ -229,11 +225,6 @@ static int cirrusfb_create(struct drm_fb_helper *helper,
sizes->fb_height);
/* setup aperture base/size for vesafb takeover */
info->apertures = alloc_apertures(1);
if (!info->apertures) {
ret = -ENOMEM;
goto out_iounmap;
}
info->apertures->ranges[0].base = cdev->dev->mode_config.fb_base;
info->apertures->ranges[0].size = cdev->mc.vram_size;
@@ -246,13 +237,6 @@ static int cirrusfb_create(struct drm_fb_helper *helper,
info->fix.mmio_start = 0;
info->fix.mmio_len = 0;
ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret) {
DRM_ERROR("%s: can't allocate color map\n", info->fix.id);
ret = -ENOMEM;
goto out_iounmap;
}
DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start);
DRM_INFO("vram aper at 0x%lX\n", (unsigned long)info->fix.smem_start);
DRM_INFO("size %lu\n", (unsigned long)info->fix.smem_len);
@@ -260,24 +244,15 @@ static int cirrusfb_create(struct drm_fb_helper *helper,
DRM_INFO(" pitch is %d\n", fb->pitches[0]);
return 0;
out_iounmap:
return ret;
}
static int cirrus_fbdev_destroy(struct drm_device *dev,
struct cirrus_fbdev *gfbdev)
{
struct fb_info *info;
struct cirrus_framebuffer *gfb = &gfbdev->gfb;
if (gfbdev->helper.fbdev) {
info = gfbdev->helper.fbdev;
unregister_framebuffer(info);
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
drm_fb_helper_unregister_fbi(&gfbdev->helper);
drm_fb_helper_release_fbi(&gfbdev->helper);
if (gfb->obj) {
drm_gem_object_unreference_unlocked(gfb->obj);
+4 -11
View File
@@ -293,25 +293,18 @@ cirrus_dumb_mmap_offset(struct drm_file *file,
uint64_t *offset)
{
struct drm_gem_object *obj;
int ret;
struct cirrus_bo *bo;
mutex_lock(&dev->struct_mutex);
obj = drm_gem_object_lookup(dev, file, handle);
if (obj == NULL) {
ret = -ENOENT;
goto out_unlock;
}
if (obj == NULL)
return -ENOENT;
bo = gem_to_cirrus_bo(obj);
*offset = cirrus_bo_mmap_offset(bo);
drm_gem_object_unreference(obj);
ret = 0;
out_unlock:
mutex_unlock(&dev->struct_mutex);
return ret;
drm_gem_object_unreference_unlocked(obj);
return 0;
}
bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height,
+12 -3
View File
@@ -153,9 +153,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
if (!connector)
continue;
WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
connector->funcs->atomic_destroy_state(connector,
/*
* FIXME: Async commits can race with connector unplugging and
* there's currently nothing that prevents cleanup up state for
* deleted connectors. As long as the callback doesn't look at
* the connector we'll be fine though, so make sure that's the
* case by setting all connector pointers to NULL.
*/
state->connector_states[i]->connector = NULL;
connector->funcs->atomic_destroy_state(NULL,
state->connector_states[i]);
state->connectors[i] = NULL;
state->connector_states[i] = NULL;
@@ -1224,6 +1230,9 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
}
}
if (ret == 0)
ww_acquire_done(&state->acquire_ctx->ww_ctx);
return ret;
}
EXPORT_SYMBOL(drm_atomic_check_only);
+3 -3
View File
@@ -299,7 +299,7 @@ mode_fixup(struct drm_atomic_state *state)
encoder->base.id, encoder->name);
return ret;
}
} else {
} else if (funcs->mode_fixup) {
ret = funcs->mode_fixup(encoder, &crtc_state->mode,
&crtc_state->adjusted_mode);
if (!ret) {
@@ -958,7 +958,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
continue;
old_crtc_state->enable = true;
old_crtc_state->last_vblank_count = drm_vblank_count(dev, i);
old_crtc_state->last_vblank_count = drm_crtc_vblank_count(crtc);
}
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
@@ -967,7 +967,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
ret = wait_event_timeout(dev->vblank[i].queue,
old_crtc_state->last_vblank_count !=
drm_vblank_count(dev, i),
drm_crtc_vblank_count(crtc),
msecs_to_jiffies(50));
drm_crtc_vblank_put(crtc);
+4 -2
View File
@@ -1151,7 +1151,7 @@ EXPORT_SYMBOL(drm_encoder_cleanup);
int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
unsigned long possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats, uint32_t format_count,
const uint32_t *formats, unsigned int format_count,
enum drm_plane_type type)
{
struct drm_mode_config *config = &dev->mode_config;
@@ -1225,7 +1225,7 @@ EXPORT_SYMBOL(drm_universal_plane_init);
int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
unsigned long possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats, uint32_t format_count,
const uint32_t *formats, unsigned int format_count,
bool is_primary)
{
enum drm_plane_type type;
@@ -5273,12 +5273,14 @@ void drm_mode_config_reset(struct drm_device *dev)
if (encoder->funcs->reset)
encoder->funcs->reset(encoder);
mutex_lock(&dev->mode_config.mutex);
drm_for_each_connector(connector, dev) {
connector->status = connector_status_unknown;
if (connector->funcs->reset)
connector->funcs->reset(connector);
}
mutex_unlock(&dev->mode_config.mutex);
}
EXPORT_SYMBOL(drm_mode_config_reset);
+1 -1
View File
@@ -3802,7 +3802,7 @@ int drm_add_modes_noedid(struct drm_connector *connector,
struct drm_display_mode *mode;
struct drm_device *dev = connector->dev;
count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
count = ARRAY_SIZE(drm_dmt_modes);
if (hdisplay < 0)
hdisplay = 0;
if (vdisplay < 0)
+11 -34
View File
@@ -222,9 +222,9 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_debugfs_show);
static struct fb_ops drm_fbdev_cma_ops = {
.owner = THIS_MODULE,
.fb_fillrect = sys_fillrect,
.fb_copyarea = sys_copyarea,
.fb_imageblit = sys_imageblit,
.fb_fillrect = drm_fb_helper_sys_fillrect,
.fb_copyarea = drm_fb_helper_sys_copyarea,
.fb_imageblit = drm_fb_helper_sys_imageblit,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_blank = drm_fb_helper_blank,
@@ -263,10 +263,9 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
if (IS_ERR(obj))
return -ENOMEM;
fbi = framebuffer_alloc(0, dev->dev);
if (!fbi) {
dev_err(dev->dev, "Failed to allocate framebuffer info.\n");
ret = -ENOMEM;
fbi = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(fbi)) {
ret = PTR_ERR(fbi);
goto err_drm_gem_cma_free_object;
}
@@ -274,23 +273,16 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
if (IS_ERR(fbdev_cma->fb)) {
dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n");
ret = PTR_ERR(fbdev_cma->fb);
goto err_framebuffer_release;
goto err_fb_info_destroy;
}
fb = &fbdev_cma->fb->fb;
helper->fb = fb;
helper->fbdev = fbi;
fbi->par = helper;
fbi->flags = FBINFO_FLAG_DEFAULT;
fbi->fbops = &drm_fbdev_cma_ops;
ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
if (ret) {
dev_err(dev->dev, "Failed to allocate color map.\n");
goto err_drm_fb_cma_destroy;
}
drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
@@ -305,11 +297,8 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
return 0;
err_drm_fb_cma_destroy:
drm_framebuffer_unregister_private(fb);
drm_fb_cma_destroy(fb);
err_framebuffer_release:
framebuffer_release(fbi);
err_fb_info_destroy:
drm_fb_helper_release_fbi(helper);
err_drm_gem_cma_free_object:
drm_gem_cma_free_object(&obj->base);
return ret;
@@ -385,20 +374,8 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_init);
*/
void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma)
{
if (fbdev_cma->fb_helper.fbdev) {
struct fb_info *info;
int ret;
info = fbdev_cma->fb_helper.fbdev;
ret = unregister_framebuffer(info);
if (ret < 0)
DRM_DEBUG_KMS("failed unregister_framebuffer()\n");
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
drm_fb_helper_unregister_fbi(&fbdev_cma->fb_helper);
drm_fb_helper_release_fbi(&fbdev_cma->fb_helper);
if (fbdev_cma->fb) {
drm_framebuffer_unregister_private(&fbdev_cma->fb->fb);
+269 -67
View File
@@ -56,8 +56,8 @@ static LIST_HEAD(kernel_fb_helper_list);
* Teardown is done with drm_fb_helper_fini().
*
* At runtime drivers should restore the fbdev console by calling
* drm_fb_helper_restore_fbdev_mode() from their ->lastclose callback. They
* should also notify the fb helper code from updates to the output
* drm_fb_helper_restore_fbdev_mode_unlocked() from their ->lastclose callback.
* They should also notify the fb helper code from updates to the output
* configuration by calling drm_fb_helper_hotplug_event(). For easier
* integration with the output polling code in drm_crtc_helper.c the modeset
* code provides a ->output_poll_changed callback.
@@ -168,11 +168,14 @@ static void remove_from_modeset(struct drm_mode_set *set,
}
set->num_connectors--;
/* because i915 is pissy about this..
/*
* TODO maybe need to makes sure we set it back to !=NULL somewhere?
*/
if (set->num_connectors == 0)
if (set->num_connectors == 0) {
set->fb = NULL;
drm_mode_destroy(connector->dev, set->mode);
set->mode = NULL;
}
}
int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
@@ -354,21 +357,6 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
}
return error;
}
/**
* drm_fb_helper_restore_fbdev_mode - restore fbdev configuration
* @fb_helper: fbcon to restore
*
* This should be called from driver's drm ->lastclose callback
* when implementing an fbcon on top of kms using this helper. This ensures that
* the user isn't greeted with a black screen when e.g. X dies.
*
* Use this variant if you need to bypass locking (panic), or already
* hold all modeset locks. Otherwise use drm_fb_helper_restore_fbdev_mode_unlocked()
*/
static bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper)
{
return restore_fbdev_mode(fb_helper);
}
/**
* drm_fb_helper_restore_fbdev_mode_unlocked - restore fbdev configuration
@@ -398,42 +386,6 @@ bool drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
}
EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked);
/*
* restore fbcon display for all kms driver's using this helper, used for sysrq
* and panic handling.
*/
static bool drm_fb_helper_force_kernel_mode(void)
{
bool ret, error = false;
struct drm_fb_helper *helper;
if (list_empty(&kernel_fb_helper_list))
return false;
list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
struct drm_device *dev = helper->dev;
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
continue;
/*
* NOTE: Use trylock mode to avoid deadlocks and sleeping in
* panic context.
*/
if (__drm_modeset_lock_all(dev, true) != 0) {
error = true;
continue;
}
ret = drm_fb_helper_restore_fbdev_mode(helper);
if (ret)
error = true;
drm_modeset_unlock_all(dev);
}
return error;
}
static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper)
{
struct drm_device *dev = fb_helper->dev;
@@ -459,6 +411,33 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper)
}
#ifdef CONFIG_MAGIC_SYSRQ
/*
* restore fbcon display for all kms driver's using this helper, used for sysrq
* and panic handling.
*/
static bool drm_fb_helper_force_kernel_mode(void)
{
bool ret, error = false;
struct drm_fb_helper *helper;
if (list_empty(&kernel_fb_helper_list))
return false;
list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
struct drm_device *dev = helper->dev;
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
continue;
drm_modeset_lock_all(dev);
ret = restore_fbdev_mode(helper);
if (ret)
error = true;
drm_modeset_unlock_all(dev);
}
return error;
}
static void drm_fb_helper_restore_work_fn(struct work_struct *ignored)
{
bool ret;
@@ -490,14 +469,6 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
struct drm_connector *connector;
int i, j;
/*
* fbdev->blank can be called from irq context in case of a panic.
* Since we already have our own special panic handler which will
* restore the fbdev console mode completely, just bail out early.
*/
if (oops_in_progress)
return;
/*
* For each CRTC in this fb, turn the connectors on/off.
*/
@@ -531,6 +502,9 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
*/
int drm_fb_helper_blank(int blank, struct fb_info *info)
{
if (oops_in_progress)
return -EBUSY;
switch (blank) {
/* Display: On; HSync: On, VSync: On */
case FB_BLANK_UNBLANK:
@@ -654,6 +628,86 @@ out_free:
}
EXPORT_SYMBOL(drm_fb_helper_init);
/**
* drm_fb_helper_alloc_fbi - allocate fb_info and some of its members
* @fb_helper: driver-allocated fbdev helper
*
* A helper to alloc fb_info and the members cmap and apertures. Called
* by the driver within the fb_probe fb_helper callback function.
*
* RETURNS:
* fb_info pointer if things went okay, pointer containing error code
* otherwise
*/
struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper)
{
struct device *dev = fb_helper->dev->dev;
struct fb_info *info;
int ret;
info = framebuffer_alloc(0, dev);
if (!info)
return ERR_PTR(-ENOMEM);
ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret)
goto err_release;
info->apertures = alloc_apertures(1);
if (!info->apertures) {
ret = -ENOMEM;
goto err_free_cmap;
}
fb_helper->fbdev = info;
return info;
err_free_cmap:
fb_dealloc_cmap(&info->cmap);
err_release:
framebuffer_release(info);
return ERR_PTR(ret);
}
EXPORT_SYMBOL(drm_fb_helper_alloc_fbi);
/**
* drm_fb_helper_unregister_fbi - unregister fb_info framebuffer device
* @fb_helper: driver-allocated fbdev helper
*
* A wrapper around unregister_framebuffer, to release the fb_info
* framebuffer device
*/
void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper)
{
if (fb_helper && fb_helper->fbdev)
unregister_framebuffer(fb_helper->fbdev);
}
EXPORT_SYMBOL(drm_fb_helper_unregister_fbi);
/**
* drm_fb_helper_release_fbi - dealloc fb_info and its members
* @fb_helper: driver-allocated fbdev helper
*
* A helper to free memory taken by fb_info and the members cmap and
* apertures
*/
void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper)
{
if (fb_helper) {
struct fb_info *info = fb_helper->fbdev;
if (info) {
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
fb_helper->fbdev = NULL;
}
}
EXPORT_SYMBOL(drm_fb_helper_release_fbi);
void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
{
if (!list_empty(&fb_helper->kernel_fb_list)) {
@@ -668,6 +722,149 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
}
EXPORT_SYMBOL(drm_fb_helper_fini);
/**
* drm_fb_helper_unlink_fbi - wrapper around unlink_framebuffer
* @fb_helper: driver-allocated fbdev helper
*
* A wrapper around unlink_framebuffer implemented by fbdev core
*/
void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper)
{
if (fb_helper && fb_helper->fbdev)
unlink_framebuffer(fb_helper->fbdev);
}
EXPORT_SYMBOL(drm_fb_helper_unlink_fbi);
/**
* drm_fb_helper_sys_read - wrapper around fb_sys_read
* @info: fb_info struct pointer
* @buf: userspace buffer to read from framebuffer memory
* @count: number of bytes to read from framebuffer memory
* @ppos: read offset within framebuffer memory
*
* A wrapper around fb_sys_read implemented by fbdev core
*/
ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos)
{
return fb_sys_read(info, buf, count, ppos);
}
EXPORT_SYMBOL(drm_fb_helper_sys_read);
/**
* drm_fb_helper_sys_write - wrapper around fb_sys_write
* @info: fb_info struct pointer
* @buf: userspace buffer to write to framebuffer memory
* @count: number of bytes to write to framebuffer memory
* @ppos: write offset within framebuffer memory
*
* A wrapper around fb_sys_write implemented by fbdev core
*/
ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos)
{
return fb_sys_write(info, buf, count, ppos);
}
EXPORT_SYMBOL(drm_fb_helper_sys_write);
/**
* drm_fb_helper_sys_fillrect - wrapper around sys_fillrect
* @info: fbdev registered by the helper
* @rect: info about rectangle to fill
*
* A wrapper around sys_fillrect implemented by fbdev core
*/
void drm_fb_helper_sys_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
{
sys_fillrect(info, rect);
}
EXPORT_SYMBOL(drm_fb_helper_sys_fillrect);
/**
* drm_fb_helper_sys_copyarea - wrapper around sys_copyarea
* @info: fbdev registered by the helper
* @area: info about area to copy
*
* A wrapper around sys_copyarea implemented by fbdev core
*/
void drm_fb_helper_sys_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
sys_copyarea(info, area);
}
EXPORT_SYMBOL(drm_fb_helper_sys_copyarea);
/**
* drm_fb_helper_sys_imageblit - wrapper around sys_imageblit
* @info: fbdev registered by the helper
* @image: info about image to blit
*
* A wrapper around sys_imageblit implemented by fbdev core
*/
void drm_fb_helper_sys_imageblit(struct fb_info *info,
const struct fb_image *image)
{
sys_imageblit(info, image);
}
EXPORT_SYMBOL(drm_fb_helper_sys_imageblit);
/**
* drm_fb_helper_cfb_fillrect - wrapper around cfb_fillrect
* @info: fbdev registered by the helper
* @rect: info about rectangle to fill
*
* A wrapper around cfb_imageblit implemented by fbdev core
*/
void drm_fb_helper_cfb_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
{
cfb_fillrect(info, rect);
}
EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect);
/**
* drm_fb_helper_cfb_copyarea - wrapper around cfb_copyarea
* @info: fbdev registered by the helper
* @area: info about area to copy
*
* A wrapper around cfb_copyarea implemented by fbdev core
*/
void drm_fb_helper_cfb_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
cfb_copyarea(info, area);
}
EXPORT_SYMBOL(drm_fb_helper_cfb_copyarea);
/**
* drm_fb_helper_cfb_imageblit - wrapper around cfb_imageblit
* @info: fbdev registered by the helper
* @image: info about image to blit
*
* A wrapper around cfb_imageblit implemented by fbdev core
*/
void drm_fb_helper_cfb_imageblit(struct fb_info *info,
const struct fb_image *image)
{
cfb_imageblit(info, image);
}
EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit);
/**
* drm_fb_helper_set_suspend - wrapper around fb_set_suspend
* @fb_helper: driver-allocated fbdev helper
* @state: desired state, zero to resume, non-zero to suspend
*
* A wrapper around fb_set_suspend implemented by fbdev core
*/
void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state)
{
if (fb_helper && fb_helper->fbdev)
fb_set_suspend(fb_helper->fbdev, state);
}
EXPORT_SYMBOL(drm_fb_helper_set_suspend);
static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, u16 regno, struct fb_info *info)
{
@@ -755,9 +952,10 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
int i, j, rc = 0;
int start;
if (__drm_modeset_lock_all(dev, !!oops_in_progress)) {
if (oops_in_progress)
return -EBUSY;
}
drm_modeset_lock_all(dev);
if (!drm_fb_helper_is_bound(fb_helper)) {
drm_modeset_unlock_all(dev);
return -EBUSY;
@@ -906,6 +1104,9 @@ int drm_fb_helper_set_par(struct fb_info *info)
struct drm_fb_helper *fb_helper = info->par;
struct fb_var_screeninfo *var = &info->var;
if (oops_in_progress)
return -EBUSY;
if (var->pixclock != 0) {
DRM_ERROR("PIXEL CLOCK SET\n");
return -EINVAL;
@@ -931,9 +1132,10 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
int ret = 0;
int i;
if (__drm_modeset_lock_all(dev, !!oops_in_progress)) {
if (oops_in_progress)
return -EBUSY;
}
drm_modeset_lock_all(dev);
if (!drm_fb_helper_is_bound(fb_helper)) {
drm_modeset_unlock_all(dev);
return -EBUSY;
+1 -1
View File
@@ -766,7 +766,7 @@ drm_gem_object_free(struct kref *kref)
struct drm_gem_object *obj = (struct drm_gem_object *) kref;
struct drm_device *dev = obj->dev;
BUG_ON(!mutex_is_locked(&dev->struct_mutex));
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
if (dev->driver->gem_free_object != NULL)
dev->driver->gem_free_object(obj);
+1 -6
View File
@@ -289,20 +289,15 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv,
{
struct drm_gem_object *gem_obj;
mutex_lock(&drm->struct_mutex);
gem_obj = drm_gem_object_lookup(drm, file_priv, handle);
if (!gem_obj) {
dev_err(drm->dev, "failed to lookup GEM object\n");
mutex_unlock(&drm->struct_mutex);
return -EINVAL;
}
*offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
drm_gem_object_unreference(gem_obj);
mutex_unlock(&drm->struct_mutex);
drm_gem_object_unreference_unlocked(gem_obj);
return 0;
}

Some files were not shown because too many files have changed in this diff Show More